diff --git a/DEPS b/DEPS
index ffddb65f..49314c84 100644
--- a/DEPS
+++ b/DEPS
@@ -209,11 +209,11 @@
   # 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': '66125eac158dc6594c46749bfc4ef2a241dcd606',
+  'skia_revision': '9e42ec30586dabd7afa3cd5cacf3b234c35b8d24',
   # 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': '4ceb4961cb95d6c7e91b2ac86cf18ed70ce1fc66',
+  'v8_revision': '99437251b0a727233fc455893463c16097b8f45a',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
@@ -256,7 +256,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling NaCl
   # and whatever else without interference from each other.
-  'nacl_revision': '3b97fe83377a2034b2aa4dd34164da2e6c0df1c1',
+  'nacl_revision': 'f6b283b6fb56c02a7f87add0c7df9772650bbc6a',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling freetype
   # and whatever else without interference from each other.
@@ -946,7 +946,7 @@
   # Tools used when building Chrome for Chrome OS. This affects both the Simple
   # Chrome workflow, as well as the chromeos-chrome ebuild.
   'src/third_party/chromite': {
-      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '43fb45ddbabad4db4abaa0102858561166d1546e',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'cf00f242bb4633987002e39c64c7e46ef651ebf3',
       'condition': 'checkout_chromeos',
   },
 
@@ -966,7 +966,7 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'fe7d709f053dc0d0fe7e577a0236c6cfc2c27908',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '8c9a5b84cba7e5ebce5d97bea447c9662b1d43e9',
 
   'src/third_party/devtools-frontend/src':
     Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'),
@@ -1349,7 +1349,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + '9109f50a742ab7b4cb70717308281137a8734b2b',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + 'f96c36dc3cf3507a03dfeb416c8b5d75abcea85e',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
@@ -1457,7 +1457,7 @@
   },
 
   'src/third_party/re2/src':
-    Var('chromium_git') + '/external/github.com/google/re2.git' + '@' + 'aa4563370444e604995ff5fba93e25858f266b79',
+    Var('chromium_git') + '/external/github.com/google/re2.git' + '@' + 'bc423653fdf28618554da96e1532662d1e33eaca',
 
   'src/third_party/r8': {
       'packages': [
@@ -1635,7 +1635,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@a9f25d3e722671adc08f9b10b111b29f2794789c',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@0a9e379f114a73a7356a1b70713348034d3bccec',
     'condition': 'checkout_src_internal',
   },
 
@@ -1654,7 +1654,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/help_app/app',
-        'version': 'GvdmzgeWm9j6mzEbiDY1GkBbdltro2BSUry8LqZT85wC',
+        'version': '5DqEAt2sUuCsgNCCKZJptjiD7q3wMT02i-SkhH7wRMAC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -1665,7 +1665,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/media_app/app',
-        'version': 'Pk63zhzkn94Fa5RUsMnhQ3w8J_YTqWVO0HPEReE5YxsC',
+        'version': 'HyHhySYWLEoRLGTd_7K3mlmG2-DW2AYoHfBpKjDQkmsC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -3614,7 +3614,7 @@
     'pattern': '.',
     'condition': 'checkout_ios and checkout_src_internal',
     'action': [
-        'python',
+        'python3',
         'src/build/landmines.py',
         '--landmine-scripts',
         'src/ios_internal/build/get_landmines.py',
@@ -3628,7 +3628,7 @@
     'name': 'disable_depot_tools_selfupdate',
     'pattern': '.',
     'action': [
-        'python',
+        'python3',
         'src/third_party/depot_tools/update_depot_tools_toggle.py',
         '--disable',
     ],
@@ -3662,7 +3662,7 @@
     'pattern': '.',
     'condition': 'checkout_nacl',
     'action': [
-        'python',
+        'python3',
         'src/build/download_nacl_toolchains.py',
         '--mode', 'nacl_core_sdk',
         'sync', '--extract',
@@ -3672,35 +3672,35 @@
     'name': 'sysroot_arm',
     'pattern': '.',
     'condition': 'checkout_linux and checkout_arm',
-    'action': ['python', 'src/build/linux/sysroot_scripts/install-sysroot.py',
+    'action': ['python3', 'src/build/linux/sysroot_scripts/install-sysroot.py',
                '--arch=arm'],
   },
   {
     'name': 'sysroot_arm64',
     'pattern': '.',
     'condition': 'checkout_linux and checkout_arm64',
-    'action': ['python', 'src/build/linux/sysroot_scripts/install-sysroot.py',
+    'action': ['python3', 'src/build/linux/sysroot_scripts/install-sysroot.py',
                '--arch=arm64'],
   },
   {
     'name': 'sysroot_x86',
     'pattern': '.',
     'condition': 'checkout_linux and (checkout_x86 or checkout_x64)',
-    'action': ['python', 'src/build/linux/sysroot_scripts/install-sysroot.py',
+    'action': ['python3', 'src/build/linux/sysroot_scripts/install-sysroot.py',
                '--arch=x86'],
   },
   {
     'name': 'sysroot_mips',
     'pattern': '.',
     'condition': 'checkout_linux and checkout_mips',
-    'action': ['python', 'src/build/linux/sysroot_scripts/install-sysroot.py',
+    'action': ['python3', 'src/build/linux/sysroot_scripts/install-sysroot.py',
                '--arch=mips'],
   },
   {
     'name': 'sysroot_mips64',
     'pattern': '.',
     'condition': 'checkout_linux and checkout_mips64',
-    'action': ['python', 'src/build/linux/sysroot_scripts/install-sysroot.py',
+    'action': ['python3', 'src/build/linux/sysroot_scripts/install-sysroot.py',
                '--arch=mips64el'],
   },
 
@@ -3708,7 +3708,7 @@
     'name': 'sysroot_x64',
     'pattern': '.',
     'condition': 'checkout_linux and checkout_x64',
-    'action': ['python', 'src/build/linux/sysroot_scripts/install-sysroot.py',
+    'action': ['python3', 'src/build/linux/sysroot_scripts/install-sysroot.py',
                '--arch=x64'],
   },
   {
@@ -3729,7 +3729,7 @@
     'name': 'win_toolchain',
     'pattern': '.',
     'condition': 'checkout_win',
-    'action': ['python', 'src/build/vs_toolchain.py', 'update', '--force'],
+    'action': ['python3', 'src/build/vs_toolchain.py', 'update', '--force'],
   },
   {
     # Update the Mac toolchain if necessary.
@@ -3744,7 +3744,7 @@
     'pattern': '.',
     'condition': 'checkout_fuchsia',
     'action': [
-      'python',
+      'python3',
       'src/build/fuchsia/update_sdk.py',
       '--default-bucket={fuchsia_sdk_bucket}',
     ],
@@ -3763,7 +3763,7 @@
     'name': 'clang_tot',
     'pattern': '.',
     'condition': 'llvm_force_head_revision',
-    'action': ['python', 'src/tools/clang/scripts/build.py',
+    'action': ['python3', 'src/tools/clang/scripts/build.py',
                '--llvm-force-head-revision',
                '--with-android={checkout_android}',
                '--with-fuchsia={checkout_fuchsia}'],
@@ -3773,7 +3773,7 @@
     'name': 'clang_coverage',
     'pattern': '.',
     'condition': 'checkout_clang_coverage_tools',
-    'action': ['python', 'src/tools/clang/scripts/update.py',
+    'action': ['python3', 'src/tools/clang/scripts/update.py',
                '--package=coverage_tools'],
   },
   {
@@ -3782,7 +3782,7 @@
     'name': 'clang_tidy',
     'pattern': '.',
     'condition': 'checkout_clang_tidy',
-    'action': ['python', 'src/tools/clang/scripts/update.py',
+    'action': ['python3', 'src/tools/clang/scripts/update.py',
                '--package=clang-tidy'],
   },
   {
@@ -3792,7 +3792,7 @@
     'name': 'lld/mac',
     'pattern': '.',
     'condition': 'host_os == "mac" and (checkout_win or checkout_fuchsia)',
-    'action': ['python', 'src/tools/clang/scripts/update.py',
+    'action': ['python3', 'src/tools/clang/scripts/update.py',
                '--package=lld_mac'],
   },
   {
@@ -3800,7 +3800,7 @@
     'name': 'objdump/mac',
     'pattern': '.',
     'condition': 'checkout_mac and host_os != "mac"',
-    'action': ['python', 'src/tools/clang/scripts/update.py',
+    'action': ['python3', 'src/tools/clang/scripts/update.py',
                '--package=objdump'],
   },
   {
@@ -4067,7 +4067,8 @@
     'name': 'checkout_telemetry_binary_dependencies',
     'condition': 'checkout_telemetry_dependencies',
     'pattern': '.',
-    'action': [ 'python',
+    # TODO(1208648): Flip to vpython3 when that is working.
+    'action': [ 'vpython',
                 'src/third_party/catapult/telemetry/bin/fetch_telemetry_binary_dependencies',
     ],
   },
@@ -4077,7 +4078,8 @@
     'name': 'checkout_telemetry_benchmark_deps',
     'condition': 'checkout_telemetry_dependencies and checkout_linux and not checkout_android and not skip_wpr_archives_download',
     'pattern': '.',
-    'action': [ 'python',
+    # TODO(1208648): Flip to vpython3 when that is working.
+    'action': [ 'vpython',
                 'src/tools/perf/fetch_benchmark_deps.py',
                 '-f',
                 '-p',
@@ -4088,7 +4090,8 @@
     'name': 'checkout_telemetry_benchmark_deps',
     'condition': 'checkout_telemetry_dependencies and checkout_win and not skip_wpr_archives_download',
     'pattern': '.',
-    'action': [ 'python',
+    # TODO(1208648): Flip to vpython3 when that is working.
+    'action': [ 'vpython',
                 'src/tools/perf/fetch_benchmark_deps.py',
                 '-f',
                 '-p',
@@ -4099,7 +4102,8 @@
     'name': 'checkout_telemetry_benchmark_deps',
     'condition': 'checkout_telemetry_dependencies and checkout_mac and not skip_wpr_archives_download',
     'pattern': '.',
-    'action': [ 'python',
+    # TODO(1208648): Flip to vpython3 when that is working.
+    'action': [ 'vpython',
                 'src/tools/perf/fetch_benchmark_deps.py',
                 '-f',
                 '-p',
@@ -4110,7 +4114,8 @@
     'name': 'checkout_telemetry_benchmark_deps',
     'condition': 'checkout_telemetry_dependencies and checkout_android and not skip_wpr_archives_download',
     'pattern': '.',
-    'action': [ 'python',
+    # TODO(1208648): Flip to vpython3 when that is working.
+    'action': [ 'vpython',
                 'src/tools/perf/fetch_benchmark_deps.py',
                 '-f',
                 '-p',
@@ -4170,7 +4175,7 @@
     'name': 'Fetch WPR archive files',
     'pattern': '.',
     'condition': 'checkout_android and (checkout_wpr_archives or checkout_src_internal)',
-    'action': [ 'python',
+    'action': [ 'python3',
                 'src/chrome/test/data/android/manage_wpr_archives.py',
                 'download',
     ],
@@ -4179,7 +4184,7 @@
     'name': 'Fetch Android AFDO profile',
     'pattern': '.',
     'condition': 'checkout_android or checkout_linux',
-    'action': [ 'python',
+    'action': [ 'python3',
                 'src/tools/download_optimization_profile.py',
                 '--newest_state=src/chrome/android/profiles/newest.txt',
                 '--local_state=src/chrome/android/profiles/local.txt',
@@ -4260,7 +4265,7 @@
     'name': 'vr_test_apks',
     'pattern': '.',
     'condition': 'checkout_android',
-    'action': [ 'python',
+    'action': [ 'python3',
                 'src/third_party/gvr-android-sdk/test-apks/update.py',
     ],
   },
@@ -4269,7 +4274,7 @@
     'name': 'ar_test_apks',
     'pattern': '.',
     'condition': 'checkout_android',
-    'action': [ 'python',
+    'action': [ 'python3',
                 'src/third_party/arcore-android-sdk/test-apks/update.py',
     ],
   },
@@ -4288,7 +4293,7 @@
     'name': 'Fetch ChromeOS-specific orderfile for Chrome',
     'pattern': '.',
     'condition': 'checkout_chromeos or checkout_simplechrome',
-    'action': [ 'python',
+    'action': [ 'python3',
                 'src/tools/download_optimization_profile.py',
                 '--newest_state=src/chromeos/profiles/orderfile.newest.txt',
                 '--local_state=src/chromeos/profiles/orderfile.local.txt',
@@ -4301,7 +4306,7 @@
     'name': 'Fetch Chrome OS AFDO profiles (from Intel Atom cores)',
     'pattern': '.',
     'condition': 'checkout_chromeos or checkout_simplechrome',
-    'action': [ 'python',
+    'action': [ 'python3',
                 'src/tools/download_optimization_profile.py',
                 '--newest_state=src/chromeos/profiles/atom.afdo.newest.txt',
                 '--local_state=src/chromeos/profiles/atom.afdo.local.txt',
@@ -4313,7 +4318,7 @@
     'name': 'Fetch Chrome OS AFDO profiles (from Intel big cores)',
     'pattern': '.',
     'condition': 'checkout_chromeos or checkout_simplechrome',
-    'action': [ 'python',
+    'action': [ 'python3',
                 'src/tools/download_optimization_profile.py',
                 '--newest_state=src/chromeos/profiles/bigcore.afdo.newest.txt',
                 '--local_state=src/chromeos/profiles/bigcore.afdo.local.txt',
@@ -4326,7 +4331,7 @@
     'name': 'doclava',
     'pattern': '.',
     'condition': 'checkout_android',
-    'action': [ 'python',
+    'action': [ 'python3',
                 'src/build/android/download_doclava.py',
     ],
   },
@@ -4336,7 +4341,7 @@
     'pattern': '.',
     'condition': 'checkout_fuchsia',
     'action': [
-      'python',
+      'python3',
       'src/build/fuchsia/update_images.py',
       '--boot-images={checkout_fuchsia_boot_images}',
       '--default-bucket={fuchsia_images_bucket}',
@@ -4419,7 +4424,7 @@
     'name': 'Fetch PGO profiles for win32',
     'pattern': '.',
     'condition': 'checkout_pgo_profiles and checkout_win',
-    'action': [ 'python',
+    'action': [ 'python3',
                 'src/tools/update_pgo_profiles.py',
                 '--target=win32',
                 'update',
@@ -4430,7 +4435,7 @@
     'name': 'Fetch PGO profiles for win64',
     'pattern': '.',
     'condition': 'checkout_pgo_profiles and checkout_win',
-    'action': [ 'python',
+    'action': [ 'python3',
                 'src/tools/update_pgo_profiles.py',
                 '--target=win64',
                 'update',
@@ -4441,7 +4446,7 @@
     'name': 'Fetch PGO profiles for mac',
     'pattern': '.',
     'condition': 'checkout_pgo_profiles and checkout_mac',
-    'action': [ 'python',
+    'action': [ 'python3',
                 'src/tools/update_pgo_profiles.py',
                 '--target=mac',
                 'update',
@@ -4452,7 +4457,7 @@
     'name': 'Fetch PGO profiles for linux',
     'pattern': '.',
     'condition': 'checkout_pgo_profiles and checkout_linux',
-    'action': [ 'python',
+    'action': [ 'python3',
                 'src/tools/update_pgo_profiles.py',
                 '--target=linux',
                 'update',
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index ecec493..032995cb 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -9,6 +9,10 @@
 """
 PRESUBMIT_VERSION = '2.0.0'
 
+# This line is 'magic' in that git-cl looks for it to decide whether to
+# use Python3 instead of Python2 when running the code in this file.
+USE_PYTHON3 = True
+
 _EXCLUDED_PATHS = (
     # Generated file.
     (r"^components[\\/]variations[\\/]proto[\\/]devtools[\\/]"
@@ -1929,7 +1933,7 @@
     for f in input_api.AffectedFiles():
       # checkperms.py file/directory arguments must be relative to the
       # repository.
-      file_list.write(f.LocalPath() + '\n')
+      file_list.write((f.LocalPath() + '\n').encode('utf8'))
     file_list.close()
     args += ['--file-list', file_list.name]
     try:
@@ -2142,7 +2146,7 @@
       if rule.startswith('+') or rule.startswith('!')
   ])
   for _, rules in parsed_deps.get('specific_include_rules',
-                                              {}).iteritems():
+                                              {}).items():
     add_rules.update([
         rule[1:] for rule in rules
         if rule.startswith('+') or rule.startswith('!')
@@ -2171,12 +2175,7 @@
       'Str': str,
   }
 
-  # TODO(crbug.com/1207012): We need to strip the BOM because it isn't
-  # legal in Python source files. We can remove this check once the CL
-  # that actually removes the BOM from //third_party/crashpad/DEPS lands.
-  if contents.startswith(u'\ufeff'):
-      contents = contents[1:]
-  exec contents in global_scope, local_scope
+  exec(contents, global_scope, local_scope)
   return local_scope
 
 
@@ -2907,9 +2906,9 @@
 
   # Go through the OWNERS files to check, filtering out rules that are already
   # present in that OWNERS file.
-  for owners_file, patterns in to_check.iteritems():
+  for owners_file, patterns in to_check.items():
     try:
-      with file(owners_file) as f:
+      with open(owners_file) as f:
         lines = set(f.read().splitlines())
         for entry in patterns.values():
           entry['rules'] = [rule for rule in entry['rules'] if rule not in lines
@@ -2920,10 +2919,10 @@
 
   # All the remaining lines weren't found in OWNERS files, so emit an error.
   errors = []
-  for owners_file, patterns in to_check.iteritems():
+  for owners_file, patterns in to_check.items():
     missing_lines = []
     files = []
-    for _, entry in patterns.iteritems():
+    for _, entry in patterns.items():
       missing_lines.extend(entry['rules'])
       files.extend(['  %s' % f.LocalPath() for f in entry['files']])
     if missing_lines:
@@ -3739,7 +3738,7 @@
     return []
 
   error_descriptions = []
-  for file_path, bad_lines in bad_files.iteritems():
+  for file_path, bad_lines in bad_files.items():
     error_description = file_path
     for line in bad_lines:
       error_description += '\n    ' + line
@@ -4290,9 +4289,16 @@
         # The PRESUBMIT.py file (and the directory containing it) might
         # have been affected by being moved or removed, so only try to
         # run the tests if they still exist.
+        use_python3 = False
+        with open(f.LocalPath()) as fp:
+            use_python3 = any(line.startswith('USE_PYTHON3 = True')
+                              for line in fp.readlines())
+
         results.extend(input_api.canned_checks.RunUnitTestsInDirectory(
             input_api, output_api, full_path,
-            files_to_check=[r'^PRESUBMIT_test\.py$']))
+            files_to_check=[r'^PRESUBMIT_test\.py$'],
+            run_on_python2=not use_python3,
+            run_on_python3=use_python3))
   return results
 
 
@@ -5032,18 +5038,18 @@
     if file_path.endswith('.grdp'):
       if f.OldContents():
         old_id_to_msg_map = grd_helper.GetGrdpMessagesFromString(
-          unicode('\n'.join(f.OldContents())))
+          '\n'.join(f.OldContents()))
       if f.NewContents():
         new_id_to_msg_map = grd_helper.GetGrdpMessagesFromString(
-          unicode('\n'.join(f.NewContents())))
+          '\n'.join(f.NewContents()))
     else:
       file_dir = input_api.os_path.dirname(file_path) or '.'
       if f.OldContents():
         old_id_to_msg_map = grd_helper.GetGrdMessages(
-          StringIO(unicode('\n'.join(f.OldContents()))), file_dir)
+          StringIO('\n'.join(f.OldContents())), file_dir)
       if f.NewContents():
         new_id_to_msg_map = grd_helper.GetGrdMessages(
-          StringIO(unicode('\n'.join(f.NewContents()))), file_dir)
+          StringIO('\n'.join(f.NewContents())), file_dir)
 
     grd_name, ext = input_api.os_path.splitext(
         input_api.os_path.basename(file_path))
@@ -5161,7 +5167,7 @@
   # ui/webui/resoucres/tools/generate_grd.py.
   ignore_path = input_api.os_path.join(
       'ui', 'webui', 'resources', 'tools', 'tests')
-  grd_files = filter(lambda p: ignore_path not in p, grd_files)
+  grd_files = [p for p in grd_files if ignore_path not in p]
 
   try:
     translation_helper.get_translatable_grds(repo_root, grd_files,
diff --git a/PRESUBMIT_test.py b/PRESUBMIT_test.py
index 11e8f69..b490d2a 100755
--- a/PRESUBMIT_test.py
+++ b/PRESUBMIT_test.py
@@ -290,17 +290,17 @@
     test_data = [
       ('invalid_json_1.json',
        ['{ x }'],
-       'Expecting property name:'),
+       'Expecting property name'),
       ('invalid_json_2.json',
        ['// Hello world!',
         '{ "hello": "world }'],
        'Unterminated string starting at:'),
       ('invalid_json_3.json',
        ['{ "a": "b", "c": "d", }'],
-       'Expecting property name:'),
+       'Expecting property name'),
       ('invalid_json_4.json',
        ['{ "a": "b" "c": "d" }'],
-       'Expecting , delimiter:'),
+       "Expecting ',' delimiter:"),
     ]
 
     input_api.files = [MockFile(filename, contents)
@@ -330,10 +330,10 @@
                        MockFile(file_without_comments,
                                 contents_without_comments)]
 
-    self.assertEqual('No JSON object could be decoded',
-                     str(PRESUBMIT._GetJSONParseError(input_api,
-                                                      file_with_comments,
-                                                      eat_comments=False)))
+    self.assertNotEqual(None,
+                        str(PRESUBMIT._GetJSONParseError(input_api,
+                                                         file_with_comments,
+                                                         eat_comments=False)))
     self.assertEqual(None,
                      PRESUBMIT._GetJSONParseError(input_api,
                                                   file_without_comments,
@@ -2218,9 +2218,9 @@
     self._mockChangeOwnerAndReviewers(
         mock_input_api, 'owner@chromium.org', ['banana@chromium.org'])
     result = PRESUBMIT.CheckSecurityChanges(mock_input_api, mock_output_api)
-    self.assertEquals(1, len(result))
-    self.assertEquals(result[0].type, 'notify')
-    self.assertEquals(result[0].message,
+    self.assertEqual(1, len(result))
+    self.assertEqual(result[0].type, 'notify')
+    self.assertEqual(result[0].message,
         'The following files change calls to security-sensive functions\n' \
         'that need to be reviewed by ipc/SECURITY_OWNERS.\n'
         '  file.cc\n'
@@ -2237,9 +2237,9 @@
     self._mockChangeOwnerAndReviewers(
         mock_input_api, 'owner@chromium.org', ['banana@chromium.org'])
     result = PRESUBMIT.CheckSecurityChanges(mock_input_api, mock_output_api)
-    self.assertEquals(1, len(result))
-    self.assertEquals(result[0].type, 'error')
-    self.assertEquals(result[0].message,
+    self.assertEqual(1, len(result))
+    self.assertEqual(result[0].type, 'error')
+    self.assertEqual(result[0].message,
         'The following files change calls to security-sensive functions\n' \
         'that need to be reviewed by ipc/SECURITY_OWNERS.\n'
         '  file.cc\n'
@@ -2256,7 +2256,7 @@
         mock_input_api, 'owner@chromium.org',
         ['apple@chromium.org', 'banana@chromium.org'])
     result = PRESUBMIT.CheckSecurityChanges(mock_input_api, mock_output_api)
-    self.assertEquals(0, len(result))
+    self.assertEqual(0, len(result))
 
   def testChangeOwnerIsSecurityOwner(self):
     mock_input_api = MockInputApi()
@@ -2268,7 +2268,7 @@
     self._mockChangeOwnerAndReviewers(
         mock_input_api, 'orange@chromium.org', ['pear@chromium.org'])
     result = PRESUBMIT.CheckSecurityChanges(mock_input_api, mock_output_api)
-    self.assertEquals(1, len(result))
+    self.assertEqual(1, len(result))
 
 
 class BannedTypeCheckTest(unittest.TestCase):
@@ -2674,8 +2674,8 @@
       MockFile('dir/jumbo.h', ['#include "sphelper.h"']),
     ]
     results = PRESUBMIT._CheckNoStrCatRedefines(mock_input_api, MockOutputApi())
-    self.assertEquals(1, len(results))
-    self.assertEquals(4, len(results[0].items))
+    self.assertEqual(1, len(results))
+    self.assertEqual(4, len(results[0].items))
     self.assertTrue('StrCat' in results[0].message)
     self.assertTrue('foo_win.cc' in results[0].items[0])
     self.assertTrue('bar.h' in results[0].items[1])
@@ -2689,7 +2689,7 @@
       MockFile('dir/baz-win.h', ['#include "base/win/atl.h"']),
     ]
     results = PRESUBMIT._CheckNoStrCatRedefines(mock_input_api, MockOutputApi())
-    self.assertEquals(0, len(results))
+    self.assertEqual(0, len(results))
 
   def testAllowsToCreateWrapper(self):
     mock_input_api = MockInputApi()
@@ -2699,7 +2699,7 @@
         '#include "base/win/windows_defines.inc"']),
     ]
     results = PRESUBMIT._CheckNoStrCatRedefines(mock_input_api, MockOutputApi())
-    self.assertEquals(0, len(results))
+    self.assertEqual(0, len(results))
 
 
 class StringTest(unittest.TestCase):
diff --git a/PRESUBMIT_test_mocks.py b/PRESUBMIT_test_mocks.py
index f8143ae..eb78f61 100644
--- a/PRESUBMIT_test_mocks.py
+++ b/PRESUBMIT_test_mocks.py
@@ -126,7 +126,7 @@
       if file_.LocalPath() == filename:
         return '\n'.join(file_.NewContents())
     # Otherwise, file is not in our mock API.
-    raise IOError, "No such file or directory: '%s'" % filename
+    raise IOError("No such file or directory: '%s'" % filename)
 
 
 class MockOutputApi(object):
diff --git a/WATCHLISTS b/WATCHLISTS
index 2f223b87..18b16d4f5 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -1088,7 +1088,9 @@
     'holding_space': {
       'filepath': 'ash/public/cpp/holding_space|'\
                   'ash/system/holding_space|'\
-                  'chrome/browser/ui/ash/holding_space'
+                  'chrome/browser/lacros/.*holding_space.*|'\
+                  'chrome/browser/ui/ash/holding_space|'\
+                  'chromeos/crosapi/mojom/.*holding_space.*'
     },
     'i18n': {
       'filepath': 'base/i18n/|base/string|l10n|icu|'\
diff --git a/android_webview/common/aw_content_client.cc b/android_webview/common/aw_content_client.cc
index 4569105..41011ec 100644
--- a/android_webview/common/aw_content_client.cc
+++ b/android_webview/common/aw_content_client.cc
@@ -33,6 +33,8 @@
   schemes->local_schemes.push_back(url::kContentScheme);
   schemes->secure_schemes.push_back(
       android_webview::kAndroidWebViewVideoPosterScheme);
+  schemes->csp_bypassing_schemes.push_back(
+      android_webview::kAndroidWebViewVideoPosterScheme);
   schemes->allow_non_standard_schemes_in_origins = true;
 }
 
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientGetDefaultVideoPosterTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientGetDefaultVideoPosterTest.java
index 39a0a465..b919fc6 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientGetDefaultVideoPosterTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientGetDefaultVideoPosterTest.java
@@ -85,6 +85,24 @@
     @Test
     @Feature({"AndroidWebView"})
     @SmallTest
+    public void testDefaultVideoPosterCSP() throws Throwable {
+        DefaultVideoPosterClient contentsClient = new DefaultVideoPosterClient(
+                InstrumentationRegistry.getInstrumentation().getContext());
+        AwTestContainerView testContainerView =
+                mActivityTestRule.createAwTestContainerViewOnMainSync(contentsClient);
+        // Even though this content security policy does not allow loading from
+        // android-webview-video-poster: this should still work as it's exempt from CSP.
+        String data = "<html><head>"
+                + "<meta http-equiv='Content-Security-Policy' content=\"default-src 'self';\">"
+                + "<body><video id='video' control src='' /> </body></html>";
+        mActivityTestRule.loadDataAsync(
+                testContainerView.getAwContents(), data, "text/html", false);
+        contentsClient.waitForGetDefaultVideoPosterCalled();
+    }
+
+    @Test
+    @Feature({"AndroidWebView"})
+    @SmallTest
     public void testInterceptDefaultVidoePosterURL() {
         DefaultVideoPosterClient contentsClient = new DefaultVideoPosterClient(
                 InstrumentationRegistry.getInstrumentation().getTargetContext());
diff --git a/ash/accelerators/accelerator_controller_impl.cc b/ash/accelerators/accelerator_controller_impl.cc
index 6f67e3d2..0aa44df 100644
--- a/ash/accelerators/accelerator_controller_impl.cc
+++ b/ash/accelerators/accelerator_controller_impl.cc
@@ -1971,7 +1971,6 @@
     case DEBUG_PRINT_VIEW_HIERARCHY:
     case DEBUG_PRINT_WINDOW_HIERARCHY:
     case DEBUG_SHOW_TOAST:
-    case DEBUG_TOGGLE_DEVICE_SCALE_FACTOR:
     case DEBUG_TOGGLE_SHOW_DEBUG_BORDERS:
     case DEBUG_TOGGLE_SHOW_FPS_COUNTER:
     case DEBUG_TOGGLE_SHOW_PAINT_RECTS:
@@ -2185,7 +2184,6 @@
     case DEBUG_PRINT_VIEW_HIERARCHY:
     case DEBUG_PRINT_WINDOW_HIERARCHY:
     case DEBUG_SHOW_TOAST:
-    case DEBUG_TOGGLE_DEVICE_SCALE_FACTOR:
       debug::PerformDebugActionIfEnabled(action);
       break;
     case DEBUG_TOGGLE_SHOW_DEBUG_BORDERS:
diff --git a/ash/accelerators/accelerator_table.cc b/ash/accelerators/accelerator_table.cc
index 1edac72f..75dbfffb1 100644
--- a/ash/accelerators/accelerator_table.cc
+++ b/ash/accelerators/accelerator_table.cc
@@ -73,7 +73,6 @@
     {true, ui::VKEY_L, kDebugModifier, DEBUG_PRINT_LAYER_HIERARCHY},
     {true, ui::VKEY_V, kDebugModifier, DEBUG_PRINT_VIEW_HIERARCHY},
     {true, ui::VKEY_W, kDebugModifier, DEBUG_PRINT_WINDOW_HIERARCHY},
-    {true, ui::VKEY_D, kDebugModifier, DEBUG_TOGGLE_DEVICE_SCALE_FACTOR},
     {true, ui::VKEY_B, kDebugModifier, DEBUG_TOGGLE_SHOW_DEBUG_BORDERS},
     {true, ui::VKEY_F, kDebugModifier, DEBUG_TOGGLE_SHOW_FPS_COUNTER},
     {true, ui::VKEY_P, kDebugModifier, DEBUG_TOGGLE_SHOW_PAINT_RECTS},
diff --git a/ash/accelerators/debug_commands.cc b/ash/accelerators/debug_commands.cc
index f73cd03..be757b2 100644
--- a/ash/accelerators/debug_commands.cc
+++ b/ash/accelerators/debug_commands.cc
@@ -164,9 +164,6 @@
       Shell::Get()->toast_manager()->Show(
           ToastData("id", u"Toast", 5000 /* duration_ms */, u"Dismiss"));
       break;
-    case DEBUG_TOGGLE_DEVICE_SCALE_FACTOR:
-      Shell::Get()->display_manager()->ToggleDisplayScaleFactor();
-      break;
     case DEBUG_TOGGLE_TOUCH_PAD:
       HandleToggleTouchpad();
       break;
diff --git a/ash/accessibility/autoclick/autoclick_controller.h b/ash/accessibility/autoclick/autoclick_controller.h
index 1798e08..ce829cb 100644
--- a/ash/accessibility/autoclick/autoclick_controller.h
+++ b/ash/accessibility/autoclick/autoclick_controller.h
@@ -11,6 +11,7 @@
 #include "base/time/time.h"
 #include "ui/aura/client/cursor_client_observer.h"
 #include "ui/aura/window_observer.h"
+#include "ui/events/event_constants.h"
 #include "ui/events/event_handler.h"
 #include "ui/gfx/geometry/point.h"
 #include "ui/gfx/native_widget_types.h"
diff --git a/ash/accessibility/switch_access/point_scan_controller.h b/ash/accessibility/switch_access/point_scan_controller.h
index 62d2aab..56526b9 100644
--- a/ash/accessibility/switch_access/point_scan_controller.h
+++ b/ash/accessibility/switch_access/point_scan_controller.h
@@ -8,6 +8,7 @@
 #include "ash/accessibility/switch_access/point_scan_layer_animation_info.h"
 #include "ash/accessibility/ui/accessibility_layer.h"
 #include "ash/ash_export.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/geometry/point_f.h"
 
 namespace ash {
diff --git a/ash/content/scanning/resources/scanning_app.js b/ash/content/scanning/resources/scanning_app.js
index 79735ff..7d2ddaac 100644
--- a/ash/content/scanning/resources/scanning_app.js
+++ b/ash/content/scanning/resources/scanning_app.js
@@ -296,6 +296,17 @@
 
     /** @private {string} */
     lastUsedScannerId_: String,
+
+    /**
+     * Used to track the number of completed scans during a single session of
+     * the Scan app being open. This value is recorded whenever the app window
+     * is closed or refreshed.
+     * @private {number}
+     */
+    numCompletedScansInSession_: {
+      type: Number,
+      value: 0,
+    },
   },
 
   observers:
@@ -328,6 +339,9 @@
   /** @override */
   ready() {
     window.addEventListener('beforeunload', event => {
+      this.browserProxy_.recordNumCompletedScans(
+          this.numCompletedScansInSession_);
+
       // When the user tries to close the app while a scan is in progress,
       // show the 'Leave site' dialog.
       if (this.appState_ === AppState.SCANNING) {
@@ -387,6 +401,7 @@
       return;
     }
 
+    ++this.numCompletedScansInSession_;
     this.scannedFilePaths_ = scannedFilePaths;
     this.setAppState_(AppState.DONE);
   },
diff --git a/ash/content/scanning/resources/scanning_browser_proxy.js b/ash/content/scanning/resources/scanning_browser_proxy.js
index 634bdab..73faf99 100644
--- a/ash/content/scanning/resources/scanning_browser_proxy.js
+++ b/ash/content/scanning/resources/scanning_browser_proxy.js
@@ -106,6 +106,13 @@
    * @return {!Promise<!SelectedPath>}
    */
   ensureValidFilePath(filePath) {}
+
+  /**
+   * Records the number of completed scans during a session of the Scan app
+   * being open.
+   * @param {number} numCompletedScans
+   */
+  recordNumCompletedScans(numCompletedScans) {}
 }
 
 /** @implements {ScanningBrowserProxy} */
@@ -169,6 +176,11 @@
   ensureValidFilePath(filePath) {
     return sendWithPromise('ensureValidFilePath', filePath);
   }
+
+  /** @override */
+  recordNumCompletedScans(numCompletedScans) {
+    chrome.send('recordNumCompletedScans', [numCompletedScans]);
+  }
 }
 
 // The singleton instance_ can be replaced with a test version of this wrapper
diff --git a/ash/content/scanning/scanning_metrics_handler.cc b/ash/content/scanning/scanning_metrics_handler.cc
index 99fd470d..45910fa 100644
--- a/ash/content/scanning/scanning_metrics_handler.cc
+++ b/ash/content/scanning/scanning_metrics_handler.cc
@@ -46,6 +46,11 @@
       "recordScanJobSettings",
       base::BindRepeating(&ScanningMetricsHandler::HandleRecordScanJobSettings,
                           base::Unretained(this)));
+  web_ui()->RegisterMessageCallback(
+      "recordNumCompletedScans",
+      base::BindRepeating(
+          &ScanningMetricsHandler::HandleRecordNumCompletedScans,
+          base::Unretained(this)));
 }
 
 void ScanningMetricsHandler::HandleRecordNumScanSettingChanges(
@@ -100,4 +105,13 @@
   }
 }
 
+void ScanningMetricsHandler::HandleRecordNumCompletedScans(
+    const base::ListValue* args) {
+  AllowJavascript();
+
+  CHECK_EQ(1U, args->GetSize());
+  base::UmaHistogramCounts100("Scanning.NumCompletedScanScansInSession",
+                              args->GetList()[0].GetInt());
+}
+
 }  // namespace ash
diff --git a/ash/content/scanning/scanning_metrics_handler.h b/ash/content/scanning/scanning_metrics_handler.h
index a7e8a2ca..7b5de29 100644
--- a/ash/content/scanning/scanning_metrics_handler.h
+++ b/ash/content/scanning/scanning_metrics_handler.h
@@ -34,6 +34,9 @@
 
   // Records the settings for a scan job.
   void HandleRecordScanJobSettings(const base::ListValue* args);
+
+  // Records the number of completed scans in a Scan app session.
+  void HandleRecordNumCompletedScans(const base::ListValue* args);
 };
 
 }  // namespace ash
diff --git a/ash/display/display_manager_unittest.cc b/ash/display/display_manager_unittest.cc
index e79e33f..96267e0 100644
--- a/ash/display/display_manager_unittest.cc
+++ b/ash/display/display_manager_unittest.cc
@@ -291,14 +291,6 @@
             display_manager()->GetDisplayAt(1).bounds().ToString());
 }
 
-TEST_F(DisplayManagerTest, ScaleOnlyChange) {
-  display_manager()->ToggleDisplayScaleFactor();
-  EXPECT_TRUE(changed_metrics() &
-              display::DisplayObserver::DISPLAY_METRIC_BOUNDS);
-  EXPECT_TRUE(changed_metrics() &
-              display::DisplayObserver::DISPLAY_METRIC_WORK_AREA);
-}
-
 // Test in emulation mode (use_fullscreen_host_window=false)
 TEST_F(DisplayManagerTest, EmulatorTest) {
   EXPECT_EQ(1U, display_manager()->GetNumDisplays());
diff --git a/ash/frame/wide_frame_view.cc b/ash/frame/wide_frame_view.cc
index 77eec7b..d7f6997 100644
--- a/ash/frame/wide_frame_view.cc
+++ b/ash/frame/wide_frame_view.cc
@@ -200,12 +200,14 @@
 
 void WideFrameView::OnImmersiveFullscreenEntered() {
   header_view_->OnImmersiveFullscreenEntered();
+  widget_->GetNativeWindow()->SetTransparent(true);
   if (target_)
     GetTargetHeaderView()->OnImmersiveFullscreenEntered();
 }
 
 void WideFrameView::OnImmersiveFullscreenExited() {
   header_view_->OnImmersiveFullscreenExited();
+  widget_->GetNativeWindow()->SetTransparent(false);
   if (target_)
     GetTargetHeaderView()->OnImmersiveFullscreenExited();
   Layout();
diff --git a/ash/public/cpp/accelerators.h b/ash/public/cpp/accelerators.h
index fb81043f9..7c1aa4d 100644
--- a/ash/public/cpp/accelerators.h
+++ b/ash/public/cpp/accelerators.h
@@ -132,7 +132,6 @@
   DEBUG_PRINT_VIEW_HIERARCHY,
   DEBUG_PRINT_WINDOW_HIERARCHY,
   DEBUG_SHOW_TOAST,
-  DEBUG_TOGGLE_DEVICE_SCALE_FACTOR,
   DEBUG_TOGGLE_SHOW_DEBUG_BORDERS,
   DEBUG_TOGGLE_SHOW_FPS_COUNTER,
   DEBUG_TOGGLE_SHOW_PAINT_RECTS,
diff --git a/ash/public/cpp/projector/projector_controller.h b/ash/public/cpp/projector/projector_controller.h
index e1039025..df31259 100644
--- a/ash/public/cpp/projector/projector_controller.h
+++ b/ash/public/cpp/projector/projector_controller.h
@@ -9,6 +9,7 @@
 
 #include "ash/public/cpp/ash_public_export.h"
 #include "base/time/time.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace ash {
 
diff --git a/ash/public/cpp/tablet_mode.h b/ash/public/cpp/tablet_mode.h
index ea923c1..d419257 100644
--- a/ash/public/cpp/tablet_mode.h
+++ b/ash/public/cpp/tablet_mode.h
@@ -8,6 +8,7 @@
 #include "ash/public/cpp/ash_public_export.h"
 #include "ash/public/cpp/tablet_mode_observer.h"
 #include "base/run_loop.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace ash {
 
diff --git a/ash/shelf/hotseat_widget_unittest.cc b/ash/shelf/hotseat_widget_unittest.cc
index a863762..e051d08 100644
--- a/ash/shelf/hotseat_widget_unittest.cc
+++ b/ash/shelf/hotseat_widget_unittest.cc
@@ -2599,7 +2599,9 @@
 
 // The test to verify the hotseat transition animation from the extended state
 // to the home launcher state.
-TEST_P(HotseatWidgetRTLTest, VerifyTransitionFromExtendedModeToHomeLauncher) {
+// TODO(https://crbug.com/1210530): Disable this test due to flakiness.
+TEST_P(HotseatWidgetRTLTest,
+       DISABLED_VerifyTransitionFromExtendedModeToHomeLauncher) {
   TabletModeControllerTestApi().EnterTabletMode();
   const auto app_id =
       ShelfTestUtil::AddAppShortcut("fake_app", TYPE_PINNED_APP);
diff --git a/ash/shell.cc b/ash/shell.cc
index 8563fc8..dfff6c0 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -561,9 +561,6 @@
       shutdown_controller_(std::make_unique<ShutdownControllerImpl>()),
       system_tray_notifier_(std::make_unique<SystemTrayNotifier>()),
       native_cursor_manager_(nullptr) {
-  // Ash doesn't properly remove pre-target-handlers.
-  ui::EventHandler::DisableCheckTargets();
-
   AccelerometerReader::GetInstance()->Initialize();
 
   login_screen_controller_ =
diff --git a/ash/system/power/peripheral_battery_listener.cc b/ash/system/power/peripheral_battery_listener.cc
index ebf443a..b9cb31f 100644
--- a/ash/system/power/peripheral_battery_listener.cc
+++ b/ash/system/power/peripheral_battery_listener.cc
@@ -172,6 +172,7 @@
   garage_charge_timer_.Stop();
   if (bluetooth_adapter_)
     bluetooth_adapter_->RemoveObserver(this);
+  ui::DeviceDataManager::GetInstance()->RemoveObserver(this);
   if (chromeos::PowerManagerClient::Get())
     chromeos::PowerManagerClient::Get()->RemoveObserver(this);
 }
diff --git a/ash/system/power/peripheral_battery_listener_unittest.cc b/ash/system/power/peripheral_battery_listener_unittest.cc
index 36b8ce52..ffa049a 100644
--- a/ash/system/power/peripheral_battery_listener_unittest.cc
+++ b/ash/system/power/peripheral_battery_listener_unittest.cc
@@ -87,10 +87,6 @@
   ~PeripheralBatteryListenerTest() override = default;
 
   void SetUp() override {
-    // NOTE: We sometimes get crashes in the middle of DDM setup
-    // we don't reconstruct the instance -- presumably something
-    // isn't fully reset between tests.
-    ui::DeviceDataManager::CreateInstance();
     chromeos::PowerManagerClient::InitializeFake();
     AshTestBase::SetUp();
     ASSERT_TRUE(ui::DeviceDataManager::HasInstance());
@@ -112,14 +108,10 @@
   }
 
   void TearDown() override {
-    // NOTE: We get crash on teardown inside the DDM if we don't let
-    // all events run out in this scope.
-    base::RunLoop().RunUntilIdle();
 
     battery_listener_.reset();
     AshTestBase::TearDown();
     chromeos::PowerManagerClient::Shutdown();
-    ui::DeviceDataManager::DeleteInstance();
   }
 
   base::TimeTicks GetTestingClock() { return base::TimeTicks::Now(); }
diff --git a/ash/system/power/peripheral_battery_notifier_listener_integration_test.cc b/ash/system/power/peripheral_battery_notifier_listener_integration_test.cc
index 8912a4d..8b6c6bd0 100644
--- a/ash/system/power/peripheral_battery_notifier_listener_integration_test.cc
+++ b/ash/system/power/peripheral_battery_notifier_listener_integration_test.cc
@@ -61,8 +61,6 @@
   ~PeripheralBatteryNotifierListenerTest() override = default;
 
   void SetUp() override {
-    ui::DeviceDataManager::CreateInstance();
-    chromeos::PowerManagerClient::InitializeFake();
     AshTestBase::SetUp();
     ASSERT_TRUE(ui::DeviceDataManager::HasInstance());
 
@@ -89,11 +87,9 @@
   }
 
   void TearDown() override {
-    AshTestBase::TearDown();
     battery_notifier_.reset();
     battery_listener_.reset();
-    chromeos::PowerManagerClient::Shutdown();
-    ui::DeviceDataManager::DeleteInstance();
+    AshTestBase::TearDown();
   }
 
   void SendBatteryUpdate(const std::string& path,
diff --git a/ash/system/update/update_notification_controller.h b/ash/system/update/update_notification_controller.h
index 2d80b00..1cf08206 100644
--- a/ash/system/update/update_notification_controller.h
+++ b/ash/system/update/update_notification_controller.h
@@ -9,6 +9,7 @@
 #include "ash/system/model/update_model.h"
 #include "base/files/file_path.h"
 #include "base/macros.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace ash {
 
diff --git a/ash/wm/tablet_mode/tablet_mode_toggle_fullscreen_event_handler.h b/ash/wm/tablet_mode/tablet_mode_toggle_fullscreen_event_handler.h
index 00abe66..45771ec 100644
--- a/ash/wm/tablet_mode/tablet_mode_toggle_fullscreen_event_handler.h
+++ b/ash/wm/tablet_mode/tablet_mode_toggle_fullscreen_event_handler.h
@@ -5,6 +5,7 @@
 #ifndef ASH_WM_TABLET_MODE_TABLET_MODE_TOGGLE_FULLSCREEN_EVENT_HANDLER_H_
 #define ASH_WM_TABLET_MODE_TABLET_MODE_TOGGLE_FULLSCREEN_EVENT_HANDLER_H_
 
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/aura/window_observer.h"
 #include "ui/events/event_handler.h"
 
diff --git a/base/allocator/allocator_shim_default_dispatch_to_partition_alloc.cc b/base/allocator/allocator_shim_default_dispatch_to_partition_alloc.cc
index a6b7dac6c..91d0ad3 100644
--- a/base/allocator/allocator_shim_default_dispatch_to_partition_alloc.cc
+++ b/base/allocator/allocator_shim_default_dispatch_to_partition_alloc.cc
@@ -123,19 +123,12 @@
     !BUILDFLAG(ENABLE_RUNTIME_BACKUP_REF_PTR_CONTROL)
           base::PartitionOptions::ThreadCache::kEnabled,
 #elif BUILDFLAG(ENABLE_RUNTIME_BACKUP_REF_PTR_CONTROL)
-          // With ENABLE_RUNTIME_BACKUP_REF_PTR_CONTROL, if GigaCage is enabled,
-          // this partition is only temporary until BackupRefPtr is
-          // re-configured at run-time. Leave the ability to have a thread cache
-          // to the main partition. (Note that
-          // ENABLE_RUNTIME_BACKUP_REF_PTR_CONTROL implies that
+          // With ENABLE_RUNTIME_BACKUP_REF_PTR_CONTROL, this partition is only
+          // temporary until BackupRefPtr is re-configured at run-time. Leave
+          // the ability to have a thread cache to the main partition. (Note
+          // that ENABLE_RUNTIME_BACKUP_REF_PTR_CONTROL implies that
           // USE_BACKUP_REF_PTR is true.)
-          //
-          // Note that it is ok to use RefCount::kEnabled below regardless of
-          // the GigaCage check, because the constructor will disable ref-count
-          // if GigaCage is disabled.
-          base::features::IsPartitionAllocGigaCageEnabled()
-              ? base::PartitionOptions::ThreadCache::kDisabled
-              : base::PartitionOptions::ThreadCache::kEnabled,
+          base::PartitionOptions::ThreadCache::kDisabled,
 #else
       // Other tests, such as the ThreadCache tests create a thread cache, and
       // only one is supported at a time.
@@ -459,13 +452,6 @@
         base::ThreadSafePartitionRoot)];
 
 void ConfigurePartitionRefCountSupport(bool enable_ref_count) {
-  // If GigaCage is disabled, don't configure a new partition with ref-count
-  // enabled, as it'll be ineffective thus wasteful (increased fragmentation).
-  // Furthermore, in this case, the main partition has thread cache enabled, so
-  // creating one more here simply wouldn't work.
-  if (!base::features::IsPartitionAllocGigaCageEnabled())
-    return;
-
   auto* current_root = g_root.Get();
   current_root->PurgeMemory(PartitionPurgeDecommitEmptySlotSpans |
                             PartitionPurgeDiscardUnusedSystemPages);
diff --git a/base/allocator/allocator_shim_override_mac_default_zone.h b/base/allocator/allocator_shim_override_mac_default_zone.h
index 62e2493..e2e55d0 100644
--- a/base/allocator/allocator_shim_override_mac_default_zone.h
+++ b/base/allocator/allocator_shim_override_mac_default_zone.h
@@ -11,6 +11,8 @@
 #error This header must be included iff PartitionAlloc-Everywhere is enabled.
 #endif
 
+#include "base/notreached.h"
+
 namespace base {
 namespace allocator {
 
diff --git a/base/allocator/partition_allocator/partition_address_space.h b/base/allocator/partition_allocator/partition_address_space.h
index fc203c1..f53ed1a1 100644
--- a/base/allocator/partition_allocator/partition_address_space.h
+++ b/base/allocator/partition_allocator/partition_address_space.h
@@ -151,17 +151,10 @@
 };
 
 ALWAYS_INLINE internal::pool_handle GetNonBRPPool() {
-  // This file is included from checked_ptr.h. This will result in a cycle if it
-  // includes partition_alloc_features.h where IsPartitionAllocGigaCageEnabled
-  // resides, because it includes Finch headers which may include checked_ptr.h.
-  // TODO(bartekn): Uncomment once Finch is no longer used there.
-  // PA_DCHECK(IsPartitionAllocGigaCageEnabled());
   return PartitionAddressSpace::GetNonBRPPool();
 }
 
 ALWAYS_INLINE internal::pool_handle GetBRPPool() {
-  // TODO(bartekn): Uncomment once Finch is no longer used there (see above).
-  // PA_DCHECK(IsPartitionAllocGigaCageEnabled());
   return PartitionAddressSpace::GetBRPPool();
 }
 
diff --git a/base/allocator/partition_allocator/partition_alloc.cc b/base/allocator/partition_allocator/partition_alloc.cc
index 6ec69645..882b6ba6 100644
--- a/base/allocator/partition_allocator/partition_alloc.cc
+++ b/base/allocator/partition_allocator/partition_alloc.cc
@@ -69,13 +69,11 @@
 void PartitionAllocGlobalUninitForTesting() {
   internal::PCScan::UninitForTesting();  // IN-TEST
 #if !BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
-  if (features::IsPartitionAllocGigaCageEnabled()) {
 #if defined(PA_HAS_64_BITS_POINTERS)
-    internal::PartitionAddressSpace::UninitForTesting();
+  internal::PartitionAddressSpace::UninitForTesting();
 #else
-    internal::AddressPoolManager::GetInstance()->ResetForTesting();
+  internal::AddressPoolManager::GetInstance()->ResetForTesting();
 #endif  // defined(PA_HAS_64_BITS_POINTERS)
-  }
 #endif  // !BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
   internal::g_oom_handling_function = nullptr;
 }
diff --git a/base/allocator/partition_allocator/partition_alloc_features.h b/base/allocator/partition_allocator/partition_alloc_features.h
index 756ec1f..d4f290da 100644
--- a/base/allocator/partition_allocator/partition_alloc_features.h
+++ b/base/allocator/partition_allocator/partition_alloc_features.h
@@ -31,11 +31,6 @@
 
 extern const BASE_EXPORT Feature kPartitionAllocLazyCommit;
 
-// TODO(bartekn): Clean up.
-ALWAYS_INLINE bool IsPartitionAllocGigaCageEnabled() {
-  return true;
-}
-
 }  // namespace features
 }  // namespace base
 
diff --git a/base/allocator/partition_allocator/partition_alloc_unittest.cc b/base/allocator/partition_allocator/partition_alloc_unittest.cc
index 97ed054..11fadd7 100644
--- a/base/allocator/partition_allocator/partition_alloc_unittest.cc
+++ b/base/allocator/partition_allocator/partition_alloc_unittest.cc
@@ -894,11 +894,9 @@
   EXPECT_EQ(predicted_capacity, actual_capacity);
   EXPECT_LT(requested_size, actual_capacity);
 #if BUILDFLAG(USE_BACKUP_REF_PTR)
-  if (features::IsPartitionAllocGigaCageEnabled()) {
-    for (size_t offset = 0; offset < requested_size; ++offset) {
-      EXPECT_EQ(PartitionAllocGetSlotStart(static_cast<char*>(ptr) + offset),
-                slot_start);
-    }
+  for (size_t offset = 0; offset < requested_size; ++offset) {
+    EXPECT_EQ(PartitionAllocGetSlotStart(static_cast<char*>(ptr) + offset),
+              slot_start);
   }
 #endif  // BUILDFLAG(USE_BACKUP_REF_PTR)
   allocator.root()->Free(ptr);
@@ -915,11 +913,9 @@
   EXPECT_EQ(predicted_capacity, actual_capacity);
   EXPECT_EQ(requested_size, actual_capacity);
 #if BUILDFLAG(USE_BACKUP_REF_PTR)
-  if (features::IsPartitionAllocGigaCageEnabled()) {
-    for (size_t offset = 0; offset < requested_size; offset += 877) {
-      EXPECT_EQ(PartitionAllocGetSlotStart(static_cast<char*>(ptr) + offset),
-                slot_start);
-    }
+  for (size_t offset = 0; offset < requested_size; offset += 877) {
+    EXPECT_EQ(PartitionAllocGetSlotStart(static_cast<char*>(ptr) + offset),
+              slot_start);
   }
 #endif  // BUILDFLAG(USE_BACKUP_REF_PTR)
   allocator.root()->Free(ptr);
@@ -941,11 +937,9 @@
   EXPECT_EQ(predicted_capacity, actual_capacity);
   EXPECT_EQ(requested_size + SystemPageSize(), actual_capacity);
 #if BUILDFLAG(USE_BACKUP_REF_PTR)
-  if (features::IsPartitionAllocGigaCageEnabled()) {
-    for (size_t offset = 0; offset < requested_size; offset += 4999) {
-      EXPECT_EQ(PartitionAllocGetSlotStart(static_cast<char*>(ptr) + offset),
-                slot_start);
-    }
+  for (size_t offset = 0; offset < requested_size; offset += 4999) {
+    EXPECT_EQ(PartitionAllocGetSlotStart(static_cast<char*>(ptr) + offset),
+              slot_start);
   }
 #endif  // BUILDFLAG(USE_BACKUP_REF_PTR)
 
@@ -960,11 +954,9 @@
   EXPECT_EQ(predicted_capacity, actual_capacity);
   EXPECT_EQ(requested_size, actual_capacity);
 #if BUILDFLAG(USE_BACKUP_REF_PTR)
-  if (features::IsPartitionAllocGigaCageEnabled()) {
-    for (size_t offset = 0; offset < requested_size; offset += 4999) {
-      EXPECT_EQ(PartitionAllocGetSlotStart(static_cast<char*>(ptr) + offset),
-                slot_start);
-    }
+  for (size_t offset = 0; offset < requested_size; offset += 4999) {
+    EXPECT_EQ(PartitionAllocGetSlotStart(static_cast<char*>(ptr) + offset),
+              slot_start);
   }
 #endif  // BUILDFLAG(USE_BACKUP_REF_PTR)
 
@@ -998,9 +990,6 @@
 
 #if BUILDFLAG(USE_BACKUP_REF_PTR)
 TEST_F(PartitionAllocTest, GetSlotStartMultiplePages) {
-  if (!features::IsPartitionAllocGigaCageEnabled())
-    return;
-
   const size_t real_size = 80;
   const size_t requested_size = real_size - kExtraAllocSize;
   // Double check we don't end up with 0 or negative size.
@@ -2883,8 +2872,7 @@
         PartitionRoot<ThreadSafe>::GetDirectMapMetadataAndGuardPagesSize();
     size_t alignment = PageAllocationGranularity();
 #if defined(PA_HAS_64_BITS_POINTERS)
-    if (features::IsPartitionAllocGigaCageEnabled())
-      alignment = kSuperPageSize;
+    alignment = kSuperPageSize;
 #endif
     size_t expected_direct_map_size =
         bits::AlignUp(aligned_size + surrounding_pages_size, alignment);
diff --git a/base/allocator/partition_allocator/partition_bucket.cc b/base/allocator/partition_allocator/partition_bucket.cc
index 06bd955e..f658a731 100644
--- a/base/allocator/partition_allocator/partition_bucket.cc
+++ b/base/allocator/partition_allocator/partition_bucket.cc
@@ -98,17 +98,11 @@
     PA_DCHECK(slot_size <= map_size);
 
     char* ptr = nullptr;
-    // Allocate from GigaCage, if enabled. In this case, use non-BRP pool,
-    // because BackupRefPtr isn't supported in direct maps.
-    const bool with_giga_cage = features::IsPartitionAllocGigaCageEnabled();
-    if (with_giga_cage) {
-      ptr = internal::AddressPoolManager::GetInstance()->Reserve(
-          GetNonBRPPool(), nullptr, reserved_size);
-    } else {
-      ptr = reinterpret_cast<char*>(
-          AllocPages(nullptr, reserved_size, kSuperPageAlignment,
-                     PageInaccessible, PageTag::kPartitionAlloc));
-    }
+    // Allocate from GigaCage, from the non-BRP pool, because BackupRefPtr isn't
+    // supported in direct maps.
+    ptr = internal::AddressPoolManager::GetInstance()->Reserve(
+        GetNonBRPPool(), nullptr, reserved_size);
+
     if (UNLIKELY(!ptr)) {
       if (return_null)
         return nullptr;
@@ -145,12 +139,8 @@
         IMMEDIATE_CRASH();  // Not required, kept as documentation.
       }
 
-      if (with_giga_cage) {
-        internal::AddressPoolManager::GetInstance()->UnreserveAndDecommit(
-            GetNonBRPPool(), ptr, reserved_size);
-      } else {
-        FreePages(ptr, reserved_size);
-      }
+      internal::AddressPoolManager::GetInstance()->UnreserveAndDecommit(
+          GetNonBRPPool(), ptr, reserved_size);
       return nullptr;
     }
 
@@ -346,57 +336,51 @@
   // architectures.
   char* requested_address = root->next_super_page;
   char* super_page = nullptr;
-  // Allocate from GigaCage, if enabled. Route to the appropriate GigaCage pool
-  // based on BackupRefPtr support.
-  if (features::IsPartitionAllocGigaCageEnabled()) {
-    super_page = AddressPoolManager::GetInstance()->Reserve(
-        root->UseBRPPool() ? GetBRPPool() : GetNonBRPPool(), requested_address,
-        kSuperPageSize);
+  // Allocate from GigaCage. Route to the appropriate GigaCage pool based on
+  // BackupRefPtr support.
+  super_page = AddressPoolManager::GetInstance()->Reserve(
+      root->UseBRPPool() ? GetBRPPool() : GetNonBRPPool(), requested_address,
+      kSuperPageSize);
 
 #if !defined(PA_HAS_64_BITS_POINTERS) && BUILDFLAG(USE_BRP_POOL_BLOCKLIST)
-    if (root->UseBRPPool()) {
-      constexpr int kMaxRandomAddressTries = 10;
-      for (int i = 0; i < kMaxRandomAddressTries; ++i) {
-        if (!super_page ||
-            AddressPoolManagerBitmap::IsAllowedSuperPageForBRPPool(super_page))
-          break;
-        AddressPoolManager::GetInstance()->UnreserveAndDecommit(
-            GetBRPPool(), super_page, kSuperPageSize);
-        super_page = AddressPoolManager::GetInstance()->Reserve(
-            GetBRPPool(), nullptr, kSuperPageSize);
-      }
-
-      // If the allocation attempt succeeds, we will break out of the following
-      // loop immediately.
-      //
-      // Last resort: sequentially scan the whole 32-bit address space. The
-      // number of blocked super-pages should be very small, so we expect to
-      // practically never need to run the following code. Note that it may fail
-      // to find an available page, e.g., when it becomes available after the
-      // scan passes through it, but we accept the risk.
-      for (uintptr_t ptr = kSuperPageSize; ptr != 0; ptr += kSuperPageSize) {
-        if (!super_page ||
-            AddressPoolManagerBitmap::IsAllowedSuperPageForBRPPool(super_page))
-          break;
-        AddressPoolManager::GetInstance()->UnreserveAndDecommit(
-            GetBRPPool(), super_page, kSuperPageSize);
-        super_page = AddressPoolManager::GetInstance()->Reserve(
-            GetBRPPool(), reinterpret_cast<void*>(ptr), kSuperPageSize);
-      }
-
-      if (super_page &&
-          !AddressPoolManagerBitmap::IsAllowedSuperPageForBRPPool(super_page)) {
-        AddressPoolManager::GetInstance()->UnreserveAndDecommit(
-            GetBRPPool(), super_page, kSuperPageSize);
-        super_page = nullptr;
-      }
+  if (root->UseBRPPool()) {
+    constexpr int kMaxRandomAddressTries = 10;
+    for (int i = 0; i < kMaxRandomAddressTries; ++i) {
+      if (!super_page ||
+          AddressPoolManagerBitmap::IsAllowedSuperPageForBRPPool(super_page))
+        break;
+      AddressPoolManager::GetInstance()->UnreserveAndDecommit(
+          GetBRPPool(), super_page, kSuperPageSize);
+      super_page = AddressPoolManager::GetInstance()->Reserve(
+          GetBRPPool(), nullptr, kSuperPageSize);
     }
-#endif
-  } else {
-    super_page = reinterpret_cast<char*>(
-        AllocPages(requested_address, kSuperPageSize, kSuperPageAlignment,
-                   PageInaccessible, PageTag::kPartitionAlloc));
+
+    // If the allocation attempt succeeds, we will break out of the following
+    // loop immediately.
+    //
+    // Last resort: sequentially scan the whole 32-bit address space. The number
+    // of blocked super-pages should be very small, so we expect to practically
+    // never need to run the following code. Note that it may fail to find an
+    // available page, e.g., when it becomes available after the scan passes
+    // through it, but we accept the risk.
+    for (uintptr_t ptr = kSuperPageSize; ptr != 0; ptr += kSuperPageSize) {
+      if (!super_page ||
+          AddressPoolManagerBitmap::IsAllowedSuperPageForBRPPool(super_page))
+        break;
+      AddressPoolManager::GetInstance()->UnreserveAndDecommit(
+          GetBRPPool(), super_page, kSuperPageSize);
+      super_page = AddressPoolManager::GetInstance()->Reserve(
+          GetBRPPool(), reinterpret_cast<void*>(ptr), kSuperPageSize);
+    }
+
+    if (super_page &&
+        !AddressPoolManagerBitmap::IsAllowedSuperPageForBRPPool(super_page)) {
+      AddressPoolManager::GetInstance()->UnreserveAndDecommit(
+          GetBRPPool(), super_page, kSuperPageSize);
+      super_page = nullptr;
+    }
   }
+#endif
   if (UNLIKELY(!super_page))
     return nullptr;
 
diff --git a/base/allocator/partition_allocator/partition_page.cc b/base/allocator/partition_allocator/partition_page.cc
index b7c5814..0e36927 100644
--- a/base/allocator/partition_allocator/partition_page.cc
+++ b/base/allocator/partition_allocator/partition_page.cc
@@ -211,16 +211,12 @@
 
 void DeferredUnmap::Unmap() {
   PA_DCHECK(ptr && size > 0);
-  if (features::IsPartitionAllocGigaCageEnabled()) {
-    // Currently this function is only called for direct-mapped allocations,
-    // which always belong to the non-BRP pool, provided that GigaCage is used.
-    // TODO(bartekn): Add a !"is in normal buckets" DCHECK.
-    PA_DCHECK(IsManagedByPartitionAllocNonBRPPool(ptr));
-    internal::AddressPoolManager::GetInstance()->UnreserveAndDecommit(
-        internal::GetNonBRPPool(), ptr, size);
-  } else {
-    FreePages(ptr, size);
-  }
+  // Currently this function is only called for direct-mapped allocations,
+  // which always belong to the non-BRP pool.
+  // TODO(bartekn): Add a !"is in normal buckets" DCHECK.
+  PA_DCHECK(IsManagedByPartitionAllocNonBRPPool(ptr));
+  internal::AddressPoolManager::GetInstance()->UnreserveAndDecommit(
+      internal::GetNonBRPPool(), ptr, size);
 }
 
 template struct SlotSpanMetadata<ThreadSafe>;
diff --git a/base/allocator/partition_allocator/partition_root.cc b/base/allocator/partition_allocator/partition_root.cc
index dca2e728..5057cd1 100644
--- a/base/allocator/partition_allocator/partition_root.cc
+++ b/base/allocator/partition_allocator/partition_root.cc
@@ -477,18 +477,13 @@
 
 #if defined(PA_HAS_64_BITS_POINTERS)
     // Reserve address space for partition alloc.
-    if (features::IsPartitionAllocGigaCageEnabled())
-      internal::PartitionAddressSpace::Init();
+    internal::PartitionAddressSpace::Init();
 #endif
 
     allow_aligned_alloc =
         opts.aligned_alloc == PartitionOptions::AlignedAlloc::kAllowed;
     allow_cookies = opts.cookies == PartitionOptions::Cookies::kAllowed;
-    // Allow ref-count if it's expressly allowed *and* GigaCage is enabled.
-    // Without GigaCage it'd be unused, thus wasteful.
-    allow_ref_count =
-        (opts.ref_count == PartitionOptions::RefCount::kAllowed) &&
-        features::IsPartitionAllocGigaCageEnabled();
+    allow_ref_count = opts.ref_count == PartitionOptions::RefCount::kAllowed;
 
     // Cookies and ref-count mess up alignment needed for AlignedAlloc, making
     // those options incompatible. However, ref-count is acceptable in the
@@ -734,7 +729,6 @@
     void* slot_start = AdjustPointerForExtrasSubtract(ptr);
     internal::PartitionRefCount* old_ref_count;
     if (allow_ref_count) {
-      PA_DCHECK(features::IsPartitionAllocGigaCageEnabled());
       old_ref_count = internal::PartitionRefCountPointer(slot_start);
     }
 #endif  // BUILDFLAG(PUT_REF_COUNT_IN_PREVIOUS_SLOT)
diff --git a/base/allocator/partition_allocator/partition_root.h b/base/allocator/partition_allocator/partition_root.h
index e7f05bd..319d572d 100644
--- a/base/allocator/partition_allocator/partition_root.h
+++ b/base/allocator/partition_allocator/partition_root.h
@@ -405,13 +405,11 @@
     // limit before calling. This also guards against integer overflow in the
     // calculation here.
     PA_DCHECK(raw_size <= MaxDirectMapped());
-    // Align to allocation granularity. However, when 64-bit GigaCage is used,
-    // the granularity is super page size.
+    // Align to allocation granularity. However, in 64-bit mode, the granularity
+    // is super page size.
     size_t alignment = PageAllocationGranularity();
 #if defined(PA_HAS_64_BITS_POINTERS)
-    if (features::IsPartitionAllocGigaCageEnabled()) {
-      alignment = kSuperPageSize;
-    }
+    alignment = kSuperPageSize;
 #endif
     return bits::AlignUp(raw_size + GetDirectMapMetadataAndGuardPagesSize(),
                          alignment);
@@ -442,11 +440,10 @@
     // DCHECK_IS_ON(), but we prefer not to change codepaths between Release and
     // Debug.
     //
-    // In theory, this can be further refined using run-time checks. No need
-    // for this adjustment if |!extras_offset || (extras_size - extras_offset)|,
-    // or IsPartitionAllocGigaCageEnabled() is false (because BackupRefPtr is
-    // effectively disabled without GigaCage), but we prefer not to add more
-    // checks, as this function may be called on hot paths.
+    // In theory, this can be further refined using run-time checks. No need for
+    // this adjustment if |!extras_offset || (extras_size - extras_offset)|, but
+    // we prefer not to add more checks, as this function may be called on hot
+    // paths.
     //
     // We use this technique in another situation. When putting refcount in the
     // previous slot, the previous slot may be free. In this case, the slot
@@ -984,8 +981,6 @@
   // forward allocations we don't own to the system malloc() implementation in
   // these rare cases, assuming that some remain.
 #if defined(OS_ANDROID) && BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
-  // GigaCage is always enabled on Android and is needed for PA_CHECK below.
-  PA_DCHECK(features::IsPartitionAllocGigaCageEnabled());
   PA_CHECK(IsManagedByPartitionAlloc(ptr));
 #endif
 
@@ -1072,7 +1067,6 @@
 
 #if BUILDFLAG(USE_BACKUP_REF_PTR)
   if (allow_ref_count) {
-    PA_DCHECK(features::IsPartitionAllocGigaCageEnabled());
     if (LIKELY(!IsDirectMappedBucket(slot_span->bucket))) {
       auto* ref_count = internal::PartitionRefCountPointer(slot_start);
       // If there are no more references to the allocation, it can be freed
@@ -1476,7 +1470,6 @@
   bool is_direct_mapped = raw_size > kMaxBucketed;
   // LIKELY: Direct mapped allocations are large and rare.
   if (allow_ref_count && LIKELY(!is_direct_mapped)) {
-    PA_DCHECK(features::IsPartitionAllocGigaCageEnabled());
     new (internal::PartitionRefCountPointer(slot_start))
         internal::PartitionRefCount();
   }
diff --git a/base/allocator/partition_allocator/starscan/pcscan_internal.cc b/base/allocator/partition_allocator/starscan/pcscan_internal.cc
index 104e7849..1467042e 100644
--- a/base/allocator/partition_allocator/starscan/pcscan_internal.cc
+++ b/base/allocator/partition_allocator/starscan/pcscan_internal.cc
@@ -211,14 +211,12 @@
 
 void CommitCardTable() {
 #if defined(PA_HAS_64_BITS_POINTERS)
-  if (features::IsPartitionAllocGigaCageEnabled()) {
-    // First, make sure that GigaCage is initialized.
-    PartitionAddressSpace::Init();
-    // Then, commit the card table.
-    RecommitSystemPages(
-        reinterpret_cast<void*>(PartitionAddressSpace::BRPPoolBase()),
-        sizeof(QuarantineCardTable), PageReadWrite, PageUpdatePermissions);
-  }
+  // First, make sure that GigaCage is initialized.
+  PartitionAddressSpace::Init();
+  // Then, commit the card table.
+  RecommitSystemPages(
+      reinterpret_cast<void*>(PartitionAddressSpace::BRPPoolBase()),
+      sizeof(QuarantineCardTable), PageReadWrite, PageUpdatePermissions);
 #endif
 }
 
@@ -409,16 +407,6 @@
     [[maybe_unused]] const PCScanSnapshot& snapshot;
   };
 
-  struct NoGigaCageLookupPolicy {
-    ALWAYS_INLINE bool TestOnHeapPointer(uintptr_t maybe_ptr) const {
-      const auto super_page_base = maybe_ptr & kSuperPageBaseMask;
-      const auto& super_pages = snapshot.quarantinable_super_pages();
-      auto it = super_pages.lower_bound(super_page_base);
-      return it != super_pages.end() && *it == super_page_base;
-    }
-    const PCScanSnapshot& snapshot;
-  };
-
   // This is used:
   // - to synchronize all scanning threads (mutators and the scanner);
   // - for the scanner, to transition through the state machine
@@ -594,19 +582,17 @@
 void PCScanTask::ClearQuarantinedObjectsAndPrepareCardTable() {
   using AccessType = QuarantineBitmap::AccessType;
 
-  const bool giga_cage_enabled = features::IsPartitionAllocGigaCageEnabled();
   const PCScan::ClearType clear_type = pcscan_.clear_type_;
 
   PCScanSnapshot::SuperPagesWorklist::RandomizedView super_pages(
       snapshot_.quarantinable_super_pages_worklist());
-  super_pages.Visit([this, giga_cage_enabled,
-                     clear_type](uintptr_t super_page_base) {
+  super_pages.Visit([this, clear_type](uintptr_t super_page_base) {
     auto* bitmap = QuarantineBitmapFromPointer(
         QuarantineBitmapType::kScanner, pcscan_epoch_,
         reinterpret_cast<char*>(super_page_base));
     auto* root = Root::FromSuperPage(reinterpret_cast<char*>(super_page_base));
     bitmap->template Iterate<AccessType::kNonAtomic>(
-        [root, giga_cage_enabled, clear_type](uintptr_t ptr) {
+        [root, clear_type](uintptr_t ptr) {
           auto* object = reinterpret_cast<void*>(ptr);
           auto* slot_span = SlotSpan::FromSlotInnerPtr(object);
           // Use zero as a zapping value to speed up the fast bailout check in
@@ -615,12 +601,8 @@
           if (clear_type == PCScan::ClearType::kLazy)
             memset(object, 0, size);
 #if defined(PA_HAS_64_BITS_POINTERS)
-          if (giga_cage_enabled) {
-            // Set card(s) for this quarantined object.
-            QuarantineCardTable::GetFrom(ptr).Quarantine(ptr, size);
-          }
-#else
-          (void)giga_cage_enabled;
+          // Set card(s) for this quarantined object.
+          QuarantineCardTable::GetFrom(ptr).Quarantine(ptr, size);
 #endif
         });
   });
@@ -641,9 +623,6 @@
   size_t quarantine_size() const { return quarantine_size_; }
 
  private:
-  ALWAYS_INLINE bool WithCage() const {
-    return features::IsPartitionAllocGigaCageEnabled();
-  }
   ALWAYS_INLINE uintptr_t CageBase() const { return giga_cage_base_; }
   ALWAYS_INLINE static constexpr uintptr_t CageMask() {
 #if defined(PA_HAS_64_BITS_POINTERS)
@@ -659,12 +638,6 @@
             maybe_ptr);
   }
 
-  ALWAYS_INLINE void CheckPointerNoGigaCage(uintptr_t maybe_ptr) {
-    quarantine_size_ +=
-        task_.TryMarkObjectInNormalBuckets<PCScanTask::NoGigaCageLookupPolicy>(
-            maybe_ptr);
-  }
-
   const uintptr_t giga_cage_base_ = 0;
   const PCScanTask& task_;
   size_t quarantine_size_ = 0;
@@ -759,7 +732,6 @@
 void PCScanTask::SweepQuarantine() {
   using AccessType = QuarantineBitmap::AccessType;
 
-  const bool giga_cage_enabled = features::IsPartitionAllocGigaCageEnabled();
   size_t swept_bytes = 0;
 
   for (uintptr_t super_page : snapshot_.quarantinable_super_pages()) {
@@ -768,23 +740,19 @@
         reinterpret_cast<char*>(super_page));
     auto* root = Root::FromSuperPage(reinterpret_cast<char*>(super_page));
     bitmap->template IterateAndClear<AccessType::kNonAtomic>(
-        [root, giga_cage_enabled, &swept_bytes](uintptr_t ptr) {
+        [root, &swept_bytes](uintptr_t ptr) {
           auto* object = reinterpret_cast<void*>(ptr);
           auto* slot_span = SlotSpan::FromSlotInnerPtr(object);
           swept_bytes += slot_span->bucket->slot_size;
           root->FreeNoHooksImmediate(object, slot_span);
 #if defined(PA_HAS_64_BITS_POINTERS)
-          if (giga_cage_enabled) {
-            // Reset card(s) for this quarantined object. Please note that the
-            // cards may still contain quarantined objects (which were promoted
-            // in this scan cycle), but
-            // ClearQuarantinedObjectsAndFilterSuperPages() will set them again
-            // in the next PCScan cycle.
-            QuarantineCardTable::GetFrom(ptr).Unquarantine(
-                ptr, slot_span->GetUsableSize(root));
-          }
-#else
-          (void)giga_cage_enabled;
+          // Reset card(s) for this quarantined object. Please note that the
+          // cards may still contain quarantined objects (which were promoted
+          // in this scan cycle), but
+          // ClearQuarantinedObjectsAndFilterSuperPages() will set them again
+          // in the next PCScan cycle.
+          QuarantineCardTable::GetFrom(ptr).Unquarantine(
+              ptr, slot_span->GetUsableSize(root));
 #endif
         });
   }
diff --git a/base/allocator/partition_allocator/starscan/scan_loop.h b/base/allocator/partition_allocator/starscan/scan_loop.h
index 63c2dc18..25b5b0d 100644
--- a/base/allocator/partition_allocator/starscan/scan_loop.h
+++ b/base/allocator/partition_allocator/starscan/scan_loop.h
@@ -66,15 +66,12 @@
 #endif
 
   void RunUnvectorized(uintptr_t*, uintptr_t*);
-  void RunUnvectorizedNoCage(uintptr_t*, uintptr_t*);
 
   SimdSupport simd_type_;
 };
 
 template <typename Derived>
 void ScanLoop<Derived>::Run(uintptr_t* begin, uintptr_t* end) {
-  if (UNLIKELY(!derived().WithCage()))
-    return RunUnvectorizedNoCage(begin, end);
 // We allow vectorization only for 64bit since they require support of the
 // 64bit cage, and only for x86 because a special instruction set is required.
 #if defined(ARCH_CPU_X86_64)
@@ -109,18 +106,6 @@
   }
 }
 
-template <typename Derived>
-void ScanLoop<Derived>::RunUnvectorizedNoCage(uintptr_t* begin,
-                                              uintptr_t* end) {
-  PA_DCHECK(!(reinterpret_cast<uintptr_t>(begin) % sizeof(uintptr_t)));
-  for (; begin < end; ++begin) {
-    const uintptr_t maybe_ptr = *begin;
-    if (!maybe_ptr)
-      continue;
-    derived().CheckPointerNoGigaCage(maybe_ptr);
-  }
-}
-
 #if defined(ARCH_CPU_X86_64)
 template <typename Derived>
 __attribute__((target("avx2"))) void ScanLoop<Derived>::RunAVX2(
diff --git a/base/allocator/partition_allocator/starscan/scan_loop_unittest.cc b/base/allocator/partition_allocator/starscan/scan_loop_unittest.cc
index 18401a2..243d98d 100644
--- a/base/allocator/partition_allocator/starscan/scan_loop_unittest.cc
+++ b/base/allocator/partition_allocator/starscan/scan_loop_unittest.cc
@@ -17,14 +17,11 @@
 
 namespace {
 
-enum class Cage { kOn, kOff };
-
 class TestScanLoop final : public ScanLoop<TestScanLoop> {
   friend class ScanLoop<TestScanLoop>;
 
  public:
-  TestScanLoop(SimdSupport ss, Cage cage)
-      : ScanLoop(ss), with_cage_(cage == Cage::kOn) {}
+  TestScanLoop(SimdSupport ss) : ScanLoop(ss) {}
 
   size_t visited() const { return visited_; }
 
@@ -34,15 +31,12 @@
   static constexpr uintptr_t kCageMask = 0xffffff0000000000;
   static constexpr uintptr_t kBasePtr = 0x1234560000000000;
 
-  bool WithCage() const { return with_cage_; }
   uintptr_t CageBase() const { return kBasePtr; }
   static constexpr uintptr_t CageMask() { return kCageMask; }
 
   void CheckPointer(uintptr_t maybe_ptr) { ++visited_; }
-  void CheckPointerNoGigaCage(uintptr_t maybe_ptr) { ++visited_; }
 
   size_t visited_ = 0;
-  bool with_cage_ = false;
 };
 
 static constexpr uintptr_t kValidPtr = 0x123456789abcdef0;
@@ -67,64 +61,43 @@
 
 TEST(ScanLoopTest, UnvectorizedWithCage) {
   {
-    TestScanLoop sl(SimdSupport::kUnvectorized, Cage::kOn);
+    TestScanLoop sl(SimdSupport::kUnvectorized);
     TestOnRangeWithAlignment<8>(sl, 0u, kInvalidPtr, kInvalidPtr, kInvalidPtr);
   }
   {
-    TestScanLoop sl(SimdSupport::kUnvectorized, Cage::kOn);
+    TestScanLoop sl(SimdSupport::kUnvectorized);
     TestOnRangeWithAlignment<8>(sl, 1u, kValidPtr, kInvalidPtr, kInvalidPtr);
   }
   {
-    TestScanLoop sl(SimdSupport::kUnvectorized, Cage::kOn);
+    TestScanLoop sl(SimdSupport::kUnvectorized);
     TestOnRangeWithAlignment<8>(sl, 2u, kValidPtr, kValidPtr, kInvalidPtr);
   }
   {
     // Make sure zeros are skipped.
-    TestScanLoop sl(SimdSupport::kUnvectorized, Cage::kOn);
+    TestScanLoop sl(SimdSupport::kUnvectorized);
     TestOnRangeWithAlignment<8>(sl, 1u, kValidPtr, kInvalidPtr, kZeroPtr);
   }
 }
 
-TEST(ScanLoopTest, UnvectorizedNoCage) {
-  // Without the cage all non-zero pointers are visited.
-  {
-    TestScanLoop sl(SimdSupport::kUnvectorized, Cage::kOff);
-    TestOnRangeWithAlignment<8>(sl, 3u, kInvalidPtr, kInvalidPtr, kInvalidPtr);
-  }
-  {
-    TestScanLoop sl(SimdSupport::kUnvectorized, Cage::kOff);
-    TestOnRangeWithAlignment<8>(sl, 3u, kValidPtr, kInvalidPtr, kInvalidPtr);
-  }
-  {
-    // Make sure zeros are skipped.
-    TestScanLoop sl(SimdSupport::kUnvectorized, Cage::kOff);
-    TestOnRangeWithAlignment<8>(sl, 2u, kValidPtr, kInvalidPtr, kZeroPtr);
-  }
-}
-
-// The vectorized tests try to test the part that can be scanned with vectorized
-// instructions (aligned by the vector size) and also the residual part, which
-// is scanned wwithout vectorization.
-
 #if defined(ARCH_CPU_X86_64)
 TEST(ScanLoopTest, VectorizedSSE4) {
   base::CPU cpu;
   if (!cpu.has_sse41())
     return;
   {
-    TestScanLoop sl(SimdSupport::kSSE41, Cage::kOn);
+    TestScanLoop sl(SimdSupport::kSSE41);
     TestOnRangeWithAlignment<16>(sl, 0u, kInvalidPtr, kInvalidPtr, kInvalidPtr);
   }
   {
-    TestScanLoop sl(SimdSupport::kSSE41, Cage::kOn);
+    TestScanLoop sl(SimdSupport::kSSE41);
     TestOnRangeWithAlignment<16>(sl, 1u, kValidPtr, kInvalidPtr, kInvalidPtr);
   }
   {
-    TestScanLoop sl(SimdSupport::kSSE41, Cage::kOn);
+    TestScanLoop sl(SimdSupport::kSSE41);
     TestOnRangeWithAlignment<16>(sl, 2u, kValidPtr, kValidPtr, kInvalidPtr);
   }
   {
-    TestScanLoop sl(SimdSupport::kSSE41, Cage::kOn);
+    TestScanLoop sl(SimdSupport::kSSE41);
     TestOnRangeWithAlignment<16>(sl, 3u, kValidPtr, kValidPtr, kValidPtr);
   }
 }
@@ -134,33 +107,33 @@
   if (!cpu.has_avx2())
     return;
   {
-    TestScanLoop sl(SimdSupport::kAVX2, Cage::kOn);
+    TestScanLoop sl(SimdSupport::kAVX2);
     TestOnRangeWithAlignment<32>(sl, 0u, kInvalidPtr, kInvalidPtr, kInvalidPtr,
                                  kInvalidPtr, kInvalidPtr);
   }
   {
-    TestScanLoop sl(SimdSupport::kAVX2, Cage::kOn);
+    TestScanLoop sl(SimdSupport::kAVX2);
     TestOnRangeWithAlignment<32>(sl, 1u, kValidPtr, kInvalidPtr, kInvalidPtr,
                                  kInvalidPtr, kInvalidPtr);
   }
   {
-    TestScanLoop sl(SimdSupport::kAVX2, Cage::kOn);
+    TestScanLoop sl(SimdSupport::kAVX2);
     TestOnRangeWithAlignment<32>(sl, 2u, kValidPtr, kValidPtr, kInvalidPtr,
                                  kInvalidPtr, kInvalidPtr);
   }
   {
-    TestScanLoop sl(SimdSupport::kAVX2, Cage::kOn);
+    TestScanLoop sl(SimdSupport::kAVX2);
     TestOnRangeWithAlignment<32>(sl, 3u, kValidPtr, kValidPtr, kValidPtr,
                                  kInvalidPtr, kInvalidPtr);
   }
   {
-    TestScanLoop sl(SimdSupport::kAVX2, Cage::kOn);
+    TestScanLoop sl(SimdSupport::kAVX2);
     TestOnRangeWithAlignment<32>(sl, 4u, kValidPtr, kValidPtr, kValidPtr,
                                  kValidPtr, kInvalidPtr);
   }
   {
     // Check that the residual pointer is also visited.
-    TestScanLoop sl(SimdSupport::kAVX2, Cage::kOn);
+    TestScanLoop sl(SimdSupport::kAVX2);
     TestOnRangeWithAlignment<32>(sl, 5u, kValidPtr, kValidPtr, kValidPtr,
                                  kValidPtr, kValidPtr);
   }
@@ -170,24 +143,24 @@
 #if defined(PA_STARSCAN_NEON_SUPPORTED)
 TEST(ScanLoopTest, VectorizedNEON) {
   {
-    TestScanLoop sl(SimdSupport::kNEON, Cage::kOn);
+    TestScanLoop sl(SimdSupport::kNEON);
     TestOnRangeWithAlignment<16>(sl, 0u, kInvalidPtr, kInvalidPtr, kInvalidPtr);
   }
   {
-    TestScanLoop sl(SimdSupport::kNEON, Cage::kOn);
+    TestScanLoop sl(SimdSupport::kNEON);
     TestOnRangeWithAlignment<16>(sl, 1u, kValidPtr, kInvalidPtr, kInvalidPtr);
   }
   {
-    TestScanLoop sl(SimdSupport::kNEON, Cage::kOn);
+    TestScanLoop sl(SimdSupport::kNEON);
     TestOnRangeWithAlignment<16>(sl, 2u, kValidPtr, kValidPtr, kInvalidPtr);
   }
   {
-    TestScanLoop sl(SimdSupport::kNEON, Cage::kOn);
+    TestScanLoop sl(SimdSupport::kNEON);
     TestOnRangeWithAlignment<16>(sl, 3u, kValidPtr, kValidPtr, kValidPtr);
   }
   {
     // Don't visit zeroes.
-    TestScanLoop sl(SimdSupport::kNEON, Cage::kOn);
+    TestScanLoop sl(SimdSupport::kNEON);
     TestOnRangeWithAlignment<16>(sl, 1u, kInvalidPtr, kValidPtr, kZeroPtr);
   }
 }
diff --git a/base/memory/checked_ptr.cc b/base/memory/checked_ptr.cc
index f94488f..44c9d77c 100644
--- a/base/memory/checked_ptr.cc
+++ b/base/memory/checked_ptr.cc
@@ -12,36 +12,31 @@
 #if BUILDFLAG(USE_BACKUP_REF_PTR)
 
 #include "base/allocator/partition_allocator/partition_alloc.h"
-#include "base/allocator/partition_allocator/partition_alloc_features.h"
 
 namespace base {
 
 namespace internal {
 
 void BackupRefPtrImpl::AcquireInternal(void* ptr) {
-  DCHECK(features::IsPartitionAllocGigaCageEnabled() &&
-         IsManagedByPartitionAllocBRPPool(ptr));
+  DCHECK(IsManagedByPartitionAllocBRPPool(ptr));
   void* slot_start = PartitionAllocGetSlotStart(ptr);
   PartitionRefCountPointer(slot_start)->Acquire();
 }
 
 void BackupRefPtrImpl::ReleaseInternal(void* ptr) {
-  DCHECK(features::IsPartitionAllocGigaCageEnabled() &&
-         IsManagedByPartitionAllocBRPPool(ptr));
+  DCHECK(IsManagedByPartitionAllocBRPPool(ptr));
   void* slot_start = PartitionAllocGetSlotStart(ptr);
   if (PartitionRefCountPointer(slot_start)->Release())
     PartitionAllocFreeForRefCounting(slot_start);
 }
 
 bool BackupRefPtrImpl::IsPointeeAlive(void* ptr) {
-  DCHECK(features::IsPartitionAllocGigaCageEnabled() &&
-         IsManagedByPartitionAllocBRPPool(ptr));
+  DCHECK(IsManagedByPartitionAllocBRPPool(ptr));
   void* slot_start = PartitionAllocGetSlotStart(ptr);
   return PartitionRefCountPointer(slot_start)->IsAlive();
 }
 
 bool BackupRefPtrImpl::IsValidDelta(void* ptr, ptrdiff_t delta) {
-  DCHECK(features::IsPartitionAllocGigaCageEnabled());
   return PartitionAllocIsValidPtrDelta(ptr, delta);
 }
 
diff --git a/base/memory/checked_ptr_unittest.cc b/base/memory/checked_ptr_unittest.cc
index 5451983..9a4bb04 100644
--- a/base/memory/checked_ptr_unittest.cc
+++ b/base/memory/checked_ptr_unittest.cc
@@ -11,7 +11,6 @@
 #include <utility>
 
 #include "base/allocator/partition_allocator/partition_alloc.h"
-#include "base/allocator/partition_allocator/partition_alloc_features.h"
 #include "base/logging.h"
 #include "base/partition_alloc_buildflags.h"
 #include "build/build_config.h"
@@ -732,10 +731,6 @@
     PartitionOptions::Cookies::kAllowed, PartitionOptions::RefCount::kAllowed};
 
 TEST(BackupRefPtrImpl, Basic) {
-  // This test works only if GigaCage is enabled. Bail out otherwise.
-  if (!features::IsPartitionAllocGigaCageEnabled())
-    return;
-
   // TODO(bartekn): Avoid using PartitionAlloc API directly. Switch to
   // new/delete once PartitionAlloc Everywhere is fully enabled.
   PartitionAllocGlobalInit(HandleOOM);
@@ -772,10 +767,6 @@
 }
 
 TEST(BackupRefPtrImpl, ZeroSized) {
-  // This test works only if GigaCage is enabled. Bail out otherwise.
-  if (!features::IsPartitionAllocGigaCageEnabled())
-    return;
-
   // TODO(bartekn): Avoid using PartitionAlloc API directly. Switch to
   // new/delete once PartitionAlloc Everywhere is fully enabled.
   PartitionAllocGlobalInit(HandleOOM);
@@ -792,10 +783,6 @@
 }
 
 TEST(BackupRefPtrImpl, EndPointer) {
-  // This test works only if GigaCage is enabled. Bail out otherwise.
-  if (!features::IsPartitionAllocGigaCageEnabled())
-    return;
-
   // This test requires a fresh partition with an empty free list.
   PartitionAllocGlobalInit(HandleOOM);
   PartitionAllocator<ThreadSafe> allocator;
@@ -832,10 +819,6 @@
 
 #if DCHECK_IS_ON() || BUILDFLAG(ENABLE_BACKUP_REF_PTR_SLOW_CHECKS)
 TEST(BackupRefPtrImpl, ReinterpretCast) {
-  // This test works only if GigaCage is enabled. Bail out otherwise.
-  if (!features::IsPartitionAllocGigaCageEnabled())
-    return;
-
   // TODO(bartekn): Avoid using PartitionAlloc API directly. Switch to
   // new/delete once PartitionAlloc Everywhere is fully enabled.
   PartitionAllocGlobalInit(HandleOOM);
diff --git a/base/threading/thread.cc b/base/threading/thread.cc
index e437edb..8834896 100644
--- a/base/threading/thread.cc
+++ b/base/threading/thread.cc
@@ -119,7 +119,7 @@
       stack_size(std::move(other.stack_size)),
       priority(std::move(other.priority)),
       joinable(std::move(other.joinable)) {
-  other.moved_from_ = true;
+  other.moved_from = true;
 }
 
 Thread::Options::~Options() = default;
diff --git a/base/threading/thread.h b/base/threading/thread.h
index 39dc5d1..72af7e3 100644
--- a/base/threading/thread.h
+++ b/base/threading/thread.h
@@ -122,12 +122,12 @@
     // user-after-frees (proposal @ https://crbug.com/629139#c14)
     bool joinable = true;
 
-    bool IsValid() const { return !moved_from_; }
+    bool IsValid() const { return !moved_from; }
 
    private:
     // Set to true when the object is moved into another. Use to prevent reuse
     // of a moved-from object.
-    bool moved_from_ = false;
+    bool moved_from = false;
   };
 
   // Constructor.
diff --git a/base/tracing/protos/chrome_track_event.proto b/base/tracing/protos/chrome_track_event.proto
index a46f239..54e11ce 100644
--- a/base/tracing/protos/chrome_track_event.proto
+++ b/base/tracing/protos/chrome_track_event.proto
@@ -135,9 +135,16 @@
   optional string mark = 4;
 }
 
+// These IDs are generated at compile time and differ for each chrome version.
+// IDs are stable on for a given chrome version but are changing when resources
+// are added or removed to chrome.
+message ResourceBundle {
+  optional uint32 resource_id = 1;
+}
+
 message ChromeTrackEvent {
   // Extension range for Chrome: 1000-1999
-  // Next ID: 1012
+  // Next ID: 1017
   extend TrackEvent {
     optional ChromeAppState chrome_app_state = 1000;
 
@@ -165,5 +172,9 @@
     optional FrameTreeNodeInfo frame_tree_node_info = 1010;
 
     optional ChromeHashedPerformanceMark chrome_hashed_performance_mark = 1011;
+
+    // reserved 1012 to 1015.
+
+    optional ResourceBundle resource_bundle = 1016;
   }
 }
diff --git a/build/fuchsia/update_sdk.py b/build/fuchsia/update_sdk.py
index 086fac8..a1c9621 100755
--- a/build/fuchsia/update_sdk.py
+++ b/build/fuchsia/update_sdk.py
@@ -40,7 +40,8 @@
 
 def GetSdkHash(bucket):
   hashes = GetSdkHashList()
-  return max(hashes, key=lambda sdk:GetSdkGeneration(bucket, sdk)) if hashes else None
+  return (max(hashes, key=lambda sdk: GetSdkGeneration(bucket, sdk))
+          if hashes else None)
 
 
 def GetSdkHashList():
@@ -65,7 +66,7 @@
       sdk_path
   ]
   logging.debug("Running '%s'", " ".join(cmd))
-  sdk_details = subprocess.check_output(cmd)
+  sdk_details = subprocess.check_output(cmd).decode('utf-8')
   m = re.search('Generation:\s*(\d*)', sdk_details)
   if not m:
     raise RuntimeError('Could not find SDK generation for {sdk_path}'.format(
diff --git a/cc/animation/animation_delegate.h b/cc/animation/animation_delegate.h
index 881ca080..bf4f8a6 100644
--- a/cc/animation/animation_delegate.h
+++ b/cc/animation/animation_delegate.h
@@ -9,6 +9,7 @@
 
 #include "base/time/time.h"
 #include "cc/animation/animation_export.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/animation/keyframe/animation_curve.h"
 
 namespace cc {
diff --git a/cc/animation/scroll_offset_animation_curve.h b/cc/animation/scroll_offset_animation_curve.h
index 2e19420..e1ec50f 100644
--- a/cc/animation/scroll_offset_animation_curve.h
+++ b/cc/animation/scroll_offset_animation_curve.h
@@ -9,6 +9,7 @@
 
 #include "base/time/time.h"
 #include "cc/animation/animation_export.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/animation/keyframe/animation_curve.h"
 #include "ui/gfx/geometry/scroll_offset.h"
 
diff --git a/cc/metrics/compositor_frame_reporter.cc b/cc/metrics/compositor_frame_reporter.cc
index e2dc1a8..7d2bd0f 100644
--- a/cc/metrics/compositor_frame_reporter.cc
+++ b/cc/metrics/compositor_frame_reporter.cc
@@ -1070,6 +1070,7 @@
         reporter->set_state(state);
         reporter->set_frame_source(args_.frame_id.source_id);
         reporter->set_frame_sequence(args_.frame_id.sequence_number);
+        reporter->set_layer_tree_host_id(layer_tree_host_id_);
         reporter->set_has_missing_content(has_missing_content_);
         if (IsDroppedFrameAffectingSmoothness()) {
           DCHECK(state == ChromeFrameReporter::STATE_DROPPED ||
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/shared/FeedFeatures.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/shared/FeedFeatures.java
index 25253e7c..65994f91 100644
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/shared/FeedFeatures.java
+++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/shared/FeedFeatures.java
@@ -32,8 +32,7 @@
      * @return Whether the WebFeed UI is enabled.
      */
     public static boolean isWebFeedUIEnabled() {
-        return ChromeFeatureList.isEnabled(ChromeFeatureList.WEB_FEED)
-                && getPrefService().getBoolean(Pref.ENABLE_WEB_FEED_UI);
+        return ChromeFeatureList.isEnabled(ChromeFeatureList.WEB_FEED);
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
index 3b2abd5..a3da89d5 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -1588,7 +1588,8 @@
                 mTabModelProfileSupplier, mBookmarkBridgeSupplier,
                 getOverviewModeBehaviorSupplier(), this::getContextualSearchManager,
                 getTabModelSelectorSupplier(), mStartSurfaceSupplier,
-                mLayoutStateProviderOneshotSupplier, mStartSurfaceParentTabSupplier);
+                mLayoutStateProviderOneshotSupplier, mStartSurfaceParentTabSupplier,
+                getBrowserControlsManager());
     }
 
     @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
index 99c0997..2d5a304 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
@@ -109,6 +109,7 @@
 import org.chromium.chrome.browser.flags.ChromeSessionState;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.browser.fullscreen.BrowserControlsManager;
+import org.chromium.chrome.browser.fullscreen.BrowserControlsManagerSupplier;
 import org.chromium.chrome.browser.fullscreen.FullscreenManager;
 import org.chromium.chrome.browser.gsa.ContextReporter;
 import org.chromium.chrome.browser.gsa.GSAAccountChangeListener;
@@ -268,6 +269,9 @@
             new TabCreatorManagerSupplier();
     private final UnownedUserDataSupplier<ManualFillingComponent> mManualFillingComponentSupplier =
             new ManualFillingComponentSupplier();
+    // TODO(crbug.com/1209864): Move ownership to RootUiCoordinator.
+    private final UnownedUserDataSupplier<BrowserControlsManager> mBrowserControlsManagerSupplier =
+            new BrowserControlsManagerSupplier();
 
     protected TabModelSelectorProfileSupplier mTabModelProfileSupplier =
             new TabModelSelectorProfileSupplier(mTabModelSelectorSupplier);
@@ -436,6 +440,10 @@
         mTabModelSelectorSupplier.attach(getWindowAndroid().getUnownedUserDataHost());
         mTabCreatorManagerSupplier.attach(getWindowAndroid().getUnownedUserDataHost());
         mManualFillingComponentSupplier.attach(getWindowAndroid().getUnownedUserDataHost());
+        mBrowserControlsManagerSupplier.attach(getWindowAndroid().getUnownedUserDataHost());
+        // BrowserControlsManager is ready immediately.
+        mBrowserControlsManagerSupplier.set(
+                new BrowserControlsManager(this, BrowserControlsManager.ControlsPosition.TOP));
     }
 
     protected RootUiCoordinator createRootUiCoordinator() {
@@ -448,7 +456,7 @@
                 getActivityTabProvider(), mTabModelProfileSupplier, mBookmarkBridgeSupplier,
                 this::getContextualSearchManager, getTabModelSelectorSupplier(),
                 new OneshotSupplierImpl<>(), new OneshotSupplierImpl<>(),
-                new OneshotSupplierImpl<>(), () -> null);
+                new OneshotSupplierImpl<>(), () -> null, mBrowserControlsManagerSupplier.get());
     }
 
     private NotificationManagerProxy getNotificationManagerProxy() {
@@ -1416,9 +1424,15 @@
             mTabContentManagerSupplier = null;
         }
 
-        ManualFillingComponent manualFillingComponent = mManualFillingComponentSupplier.get();
+        if (mManualFillingComponentSupplier.hasValue()) {
+            mManualFillingComponentSupplier.get().destroy();
+        }
         mManualFillingComponentSupplier.destroy();
-        if (manualFillingComponent != null) manualFillingComponent.destroy();
+
+        if (mBrowserControlsManagerSupplier.hasValue()) {
+            mBrowserControlsManagerSupplier.get().destroy();
+        }
+        mBrowserControlsManagerSupplier.destroy();
 
         if (mActivityTabStartupMetricsTracker != null) {
             mActivityTabStartupMetricsTracker.destroy();
@@ -1904,10 +1918,19 @@
 
     /**
      * Gets the browser controls manager, creates it unless already created.
+     * @deprecated Instead, inject this directly to your constructor. If that's not possible, then
+     *         use {@link BrowserControlsManagerSupplier}.
      */
     @NonNull
+    @Deprecated
     public BrowserControlsManager getBrowserControlsManager() {
-        return mRootUiCoordinator.getBrowserControlsManager();
+        if (!mBrowserControlsManagerSupplier.hasValue() && isActivityFinishingOrDestroyed()) {
+            // BrowserControlsManagerSupplier should always have a value unless it's in the process
+            // of destruction (and in that case, nothing should be called this method).
+            throw new IllegalStateException();
+        }
+        assert mBrowserControlsManagerSupplier.hasValue();
+        return mBrowserControlsManagerSupplier.get();
     }
 
     /**
@@ -1944,16 +1967,6 @@
     }
 
     /**
-     * Create a browser controls manager to be used by this activity.
-     * Note: This may be called before native code is initialized.
-     * @return A {@link BrowserControlsManager} instance that's been created.
-     */
-    @NonNull
-    protected BrowserControlsManager createBrowserControlsManager() {
-        return new BrowserControlsManager(this, BrowserControlsManager.ControlsPosition.TOP);
-    }
-
-    /**
      * Exits the fullscreen mode, if any. Does nothing if no fullscreen is present.
      * @return Whether the fullscreen mode is currently showing.
      */
@@ -1979,7 +1992,7 @@
         compositorViewHolder.setLayoutManager(layoutManager);
         compositorViewHolder.setFocusable(false);
         compositorViewHolder.setControlContainer(controlContainer);
-        compositorViewHolder.setBrowserControlsManager(getBrowserControlsManager());
+        compositorViewHolder.setBrowserControlsManager(mBrowserControlsManagerSupplier.get());
         compositorViewHolder.setUrlBar(urlBar);
         compositorViewHolder.setInsetObserverView(getInsetObserverView());
         compositorViewHolder.setTopUiThemeColorProvider(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java
index 221f603b..555ee73 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java
@@ -40,8 +40,6 @@
 import org.chromium.base.TraceEvent;
 import org.chromium.base.compat.ApiHelperForN;
 import org.chromium.base.compat.ApiHelperForO;
-import org.chromium.base.supplier.ObservableSupplier;
-import org.chromium.base.supplier.ObservableSupplierImpl;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider;
 import org.chromium.chrome.browser.browser_controls.BrowserControlsUtils;
@@ -164,8 +162,6 @@
 
     private TabModelSelector mTabModelSelector;
     private @Nullable BrowserControlsManager mBrowserControlsManager;
-    private ObservableSupplierImpl<BrowserControlsManager> mBrowserControlsManagerSupplier =
-            new ObservableSupplierImpl<>();
     private View mAccessibilityView;
     private CompositorAccessibilityProvider mNodeProvider;
 
@@ -1232,11 +1228,6 @@
     }
 
     @Override
-    public ObservableSupplier<BrowserControlsManager> getBrowserControlsManagerSupplier() {
-        return mBrowserControlsManagerSupplier;
-    }
-
-    @Override
     public FullscreenManager getFullscreenManager() {
         return mBrowserControlsManager.getFullscreenManager();
     }
@@ -1248,7 +1239,6 @@
     public void setBrowserControlsManager(BrowserControlsManager manager) {
         mBrowserControlsManager = manager;
         mBrowserControlsManager.addObserver(this);
-        mBrowserControlsManagerSupplier.set(mBrowserControlsManager);
         onViewportChanged();
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java
index 2e01063..3839a19 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java
@@ -124,8 +124,6 @@
                         TabManagementModuleProvider.getDelegate();
                 assert tabManagementDelegate != null;
 
-                final ObservableSupplier<? extends BrowserControlsStateProvider>
-                        browserControlsSupplier = mHost.getBrowserControlsManagerSupplier();
                 mOverviewLayout = tabManagementDelegate.createStartSurfaceLayout(
                         context, this, renderHost, startSurface);
             }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerHost.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerHost.java
index cfdf682..78f690b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerHost.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerHost.java
@@ -8,7 +8,6 @@
 import android.graphics.RectF;
 import android.view.View;
 
-import org.chromium.base.supplier.ObservableSupplier;
 import org.chromium.chrome.browser.compositor.TitleCache;
 import org.chromium.chrome.browser.fullscreen.BrowserControlsManager;
 import org.chromium.chrome.browser.fullscreen.FullscreenManager;
@@ -112,11 +111,6 @@
     BrowserControlsManager getBrowserControlsManager();
 
     /**
-     * @return An {@link ObservableSupplier} supplier for the {@link BrowserControlsManager}.
-     */
-    ObservableSupplier<BrowserControlsManager> getBrowserControlsManagerSupplier();
-
-    /**
      * @return The manager in charge of handling fullscreen changes.
      */
     FullscreenManager getFullscreenManager();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java
index db8d5ac..b7577fdd 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java
@@ -151,7 +151,8 @@
                 ()
                         -> mNavigationController,
                 getActivityTabProvider(), mTabModelProfileSupplier, mBookmarkBridgeSupplier,
-                this::getContextualSearchManager, getTabModelSelectorSupplier());
+                this::getContextualSearchManager, getTabModelSelectorSupplier(),
+                getBrowserControlsManager());
     }
 
     @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabRootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabRootUiCoordinator.java
index 50a85b9..6b982920 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabRootUiCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabRootUiCoordinator.java
@@ -17,6 +17,7 @@
 import org.chromium.chrome.browser.customtabs.features.toolbar.CustomTabToolbarCoordinator;
 import org.chromium.chrome.browser.feature_engagement.TrackerFactory;
 import org.chromium.chrome.browser.flags.ActivityType;
+import org.chromium.chrome.browser.fullscreen.BrowserControlsManager;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.reengagement.ReengagementNotificationController;
 import org.chromium.chrome.browser.share.ShareDelegate;
@@ -38,11 +39,12 @@
             ActivityTabProvider tabProvider, ObservableSupplier<Profile> profileSupplier,
             ObservableSupplier<BookmarkBridge> bookmarkBridgeSupplier,
             Supplier<ContextualSearchManager> contextualSearchManagerSupplier,
-            ObservableSupplier<TabModelSelector> tabModelSelectorSupplier) {
+            ObservableSupplier<TabModelSelector> tabModelSelectorSupplier,
+            BrowserControlsManager browserControlsManager) {
         super(activity, null, shareDelegateSupplier, tabProvider, profileSupplier,
                 bookmarkBridgeSupplier, contextualSearchManagerSupplier, tabModelSelectorSupplier,
                 new OneshotSupplierImpl<>(), new OneshotSupplierImpl<>(),
-                new OneshotSupplierImpl<>(), () -> null);
+                new OneshotSupplierImpl<>(), () -> null, browserControlsManager);
         mToolbarCoordinator = customTabToolbarCoordinator;
         mNavigationController = customTabNavigationController;
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java
index d3eeaba..5257d82 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java
@@ -7,6 +7,7 @@
 import android.view.ViewGroup;
 import android.view.ViewStub;
 
+import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 
@@ -150,11 +151,13 @@
             ObservableSupplier<TabModelSelector> tabModelSelectorSupplier,
             OneshotSupplier<StartSurface> startSurfaceSupplier,
             OneshotSupplier<LayoutStateProvider> layoutStateProviderOneshotSupplier,
-            Supplier<Tab> startSurfaceParentTabSupplier) {
+            Supplier<Tab> startSurfaceParentTabSupplier,
+            @NonNull BrowserControlsManager browserControlsManager) {
         super(activity, onOmniboxFocusChangedListener, shareDelegateSupplier, tabProvider,
                 profileSupplier, bookmarkBridgeSupplier, contextualSearchManagerSupplier,
                 tabModelSelectorSupplier, startSurfaceSupplier, intentMetadataOneshotSupplier,
-                layoutStateProviderOneshotSupplier, startSurfaceParentTabSupplier);
+                layoutStateProviderOneshotSupplier, startSurfaceParentTabSupplier,
+                browserControlsManager);
         mEphemeralTabCoordinatorSupplier = ephemeralTabCoordinatorSupplier;
         mCanAnimateBrowserControls = () -> {
             // These null checks prevent any exceptions that may be caused by callbacks after
@@ -163,6 +166,9 @@
             final Tab tab = mActivity.getActivityTabProvider().get();
             return tab != null && tab.isUserInteractable() && !tab.isNativePage();
         };
+
+        getAppBrowserControlsVisibilityDelegate().addDelegate(
+                browserControlsManager.getBrowserVisibilityDelegate());
     }
 
     @Override
@@ -559,14 +565,6 @@
         getTabObscuringHandler().addObserver(mContinuousSearchTabObscuringHandlerObserver);
     }
 
-    @Override
-    protected BrowserControlsManager createBrowserControlsManager() {
-        BrowserControlsManager manager = super.createBrowserControlsManager();
-        getAppBrowserControlsVisibilityDelegate().addDelegate(
-                manager.getBrowserVisibilityDelegate());
-        return manager;
-    }
-
     /**
      * @return {@link ComposedBrowserControlsVisibilityDelegate} object for tabbed activity.
      */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java
index f55e328..0a716aa4 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java
@@ -180,8 +180,7 @@
     private BottomSheetObserver mContextualSearchSuppressor;
     private final Supplier<ContextualSearchManager> mContextualSearchManagerSupplier;
     protected final CallbackController mCallbackController;
-    @Nullable
-    private BrowserControlsManager mBrowserControlsManager;
+    private final BrowserControlsManager mBrowserControlsManager;
     private ObservableSupplier<TabModelSelector> mTabModelSelectorSupplier;
     private final OneshotSupplier<StartSurface> mStartSurfaceSupplier;
     @Nullable
@@ -215,6 +214,8 @@
      * @param startSurfaceSupplier Supplier of the {@link StartSurface}.
      * @param intentMetadataOneshotSupplier Supplier with information about the launching intent.
      * @param layoutStateProviderOneshotSupplier Supplier of the {@link LayoutStateProvider}.
+     * @param startSurfaceParentTabSupplier Supplies the parent tab for the StartSurface.
+     * @param browserControlsManager Manages the browser controls.
      */
     public RootUiCoordinator(ChromeActivity activity,
             @Nullable Callback<Boolean> onOmniboxFocusChangedListener,
@@ -226,10 +227,12 @@
             OneshotSupplier<StartSurface> startSurfaceSupplier,
             OneshotSupplier<ToolbarIntentMetadata> intentMetadataOneshotSupplier,
             OneshotSupplier<LayoutStateProvider> layoutStateProviderOneshotSupplier,
-            @NonNull Supplier<Tab> startSurfaceParentTabSupplier) {
+            @NonNull Supplier<Tab> startSurfaceParentTabSupplier,
+            @NonNull BrowserControlsManager browserControlsManager) {
         mCallbackController = new CallbackController();
         mActivity = activity;
         mOnOmniboxFocusChangedListener = onOmniboxFocusChangedListener;
+        mBrowserControlsManager = browserControlsManager;
         mActivity.getLifecycleDispatcher().register(this);
 
         mMenuOrKeyboardActionController = mActivity.getMenuOrKeyboardActionController();
@@ -366,11 +369,6 @@
             mBottomSheetController.destroy();
         }
 
-        if (mBrowserControlsManager != null) {
-            mBrowserControlsManager.destroy();
-            mBrowserControlsManager = null;
-        }
-
         if (mButtonDataProviders != null) {
             for (ButtonDataProvider provider : mButtonDataProviders) {
                 provider.destroy();
@@ -477,7 +475,7 @@
         if (ChromeFeatureList.isEnabled(ChromeFeatureList.MESSAGES_FOR_ANDROID_INFRASTRUCTURE)) {
             MessageContainer container = mActivity.findViewById(R.id.message_container);
             mMessageContainerCoordinator =
-                    new MessageContainerCoordinator(container, getBrowserControlsManager());
+                    new MessageContainerCoordinator(container, mBrowserControlsManager);
             long autodismissDurationMs = ChromeFeatureList.getFieldTrialParamByFeatureAsInt(
                     ChromeFeatureList.MESSAGES_FOR_ANDROID_INFRASTRUCTURE,
                     "autodismiss_duration_ms", 10 * (int) DateUtils.SECOND_IN_MILLIS);
@@ -500,11 +498,10 @@
                     mMessageContainerCoordinator::getMessageMaxTranslation,
                     autodismissDurationSupplier,
                     mActivity.getWindowAndroid()::startAnimationOverContent);
-            mMessageQueueMediator =
-                    new ChromeMessageQueueMediator(mActivity.getBrowserControlsManager(),
-                            mMessageContainerCoordinator, mActivity.getFullscreenManager(),
-                            mActivityTabProvider, mLayoutStateProviderOneShotSupplier,
-                            mActivity.getModalDialogManagerSupplier(), mMessageDispatcher);
+            mMessageQueueMediator = new ChromeMessageQueueMediator(mBrowserControlsManager,
+                    mMessageContainerCoordinator, mActivity.getFullscreenManager(),
+                    mActivityTabProvider, mLayoutStateProviderOneShotSupplier,
+                    mActivity.getModalDialogManagerSupplier(), mMessageDispatcher);
             mMessageDispatcher.setDelegate(mMessageQueueMediator);
             MessagesFactory.attachMessageDispatcher(
                     mActivity.getWindowAndroid(), mMessageDispatcher);
@@ -722,7 +719,7 @@
                 mButtonDataProviders = Arrays.asList(mIdentityDiscController, shareButtonController,
                         voiceToolbarButtonController);
             }
-            mToolbarManager = new ToolbarManager(mActivity, mActivity.getBrowserControlsManager(),
+            mToolbarManager = new ToolbarManager(mActivity, mBrowserControlsManager,
                     mActivity.getFullscreenManager(), toolbarContainer,
                     mActivity.getCompositorViewHolder(), urlFocusChangedCallback,
                     mTopUiThemeColorProvider, mTabObscuringHandler, mShareDelegateSupplier,
@@ -928,7 +925,7 @@
         BottomSheetControllerFactory.attach(mActivity.getWindowAndroid(), mBottomSheetController);
 
         mBottomSheetManager = new BottomSheetManager(mBottomSheetController, mActivityTabProvider,
-                mActivity.getBrowserControlsManager(), mActivity::getModalDialogManager,
+                mBrowserControlsManager, mActivity::getModalDialogManager,
                 this::getBottomSheetSnackbarManager, mTabObscuringHandler,
                 mOmniboxFocusStateSupplier, panelManagerSupplier, mStartSurfaceSupplier);
     }
@@ -948,31 +945,15 @@
 
     /**
      * Gets the browser controls manager, creates it unless already created.
+     * @deprecated Instead, inject this directly to your constructor. If that's not possible, then
+     *         use {@link BrowserControlsManagerSupplier}.
      */
     @NonNull
+    @Deprecated
     public BrowserControlsManager getBrowserControlsManager() {
-        if (mBrowserControlsManager == null) {
-            // When finish()ing, getBrowserControlsManager() is required to perform cleanup logic.
-            // It should never be called when it results in creating a new manager though.
-            if (mActivity.isActivityFinishingOrDestroyed()) {
-                throw new IllegalStateException();
-            }
-            mBrowserControlsManager = createBrowserControlsManager();
-            assert mBrowserControlsManager != null;
-        }
         return mBrowserControlsManager;
     }
 
-    /**
-     * Create a browser controls manager to be used by ChromeActivity.
-     * Note: This may be called before native code is initialized.
-     * @return A {@link BrowserControlsManager} instance that's been created.
-     */
-    @NonNull
-    protected BrowserControlsManager createBrowserControlsManager() {
-        return new BrowserControlsManager(mActivity, BrowserControlsManager.ControlsPosition.TOP);
-    }
-
     /** @return The {@link ScrimCoordinator} to control activity's primary scrim. */
     // TODO(crbug.com/1064140): This method is used to pass ScrimCoordinator to StartSurface. We
     // should be able to create StartSurface in this class so that we don't need to expose this
@@ -991,7 +972,7 @@
         int activityType = mActivity.getActivityType();
         mDirectActionInitializer = new DirectActionInitializer(mActivity, activityType, mActivity,
                 mActivity::onBackPressed, mTabModelSelectorSupplier.get(), mFindToolbarManager,
-                getBottomSheetController(), mActivity.getBrowserControlsManager(),
+                getBottomSheetController(), mBrowserControlsManager,
                 mActivity.getCompositorViewHolder(), mActivity.getActivityTabProvider());
         mActivity.getLifecycleDispatcher().register(mDirectActionInitializer);
     }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ShareIntentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ShareIntentTest.java
index ea74798..071f87c6 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/ShareIntentTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ShareIntentTest.java
@@ -29,6 +29,7 @@
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.chrome.browser.app.ChromeActivity;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
+import org.chromium.chrome.browser.fullscreen.BrowserControlsManager;
 import org.chromium.chrome.browser.share.ShareDelegate;
 import org.chromium.chrome.browser.share.ShareDelegateImpl;
 import org.chromium.chrome.browser.share.ShareHelper;
@@ -189,7 +190,11 @@
             return new RootUiCoordinator(mockActivity, null,
                     mockActivity.getShareDelegateSupplier(), mockActivity.getActivityTabProvider(),
                     null, null, null, null, new OneshotSupplierImpl<>(),
-                    new OneshotSupplierImpl<>(), new OneshotSupplierImpl<>(), () -> null);
+                    new OneshotSupplierImpl<>(), new OneshotSupplierImpl<>(),
+                    ()
+                            -> null,
+                    new BrowserControlsManager(
+                            mockActivity, BrowserControlsManager.ControlsPosition.TOP));
         });
         ShareHelper.setLastShareComponentName(new ComponentName("test.package", "test.activity"));
         // Skips the capture of screenshot and notifies with an empty file.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/MockLayoutHost.java b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/MockLayoutHost.java
index a53bff2..9db9031 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/MockLayoutHost.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/MockLayoutHost.java
@@ -9,8 +9,6 @@
 import android.graphics.Rect;
 import android.graphics.RectF;
 
-import org.chromium.base.supplier.ObservableSupplier;
-import org.chromium.base.supplier.ObservableSupplierImpl;
 import org.chromium.chrome.browser.compositor.TitleCache;
 import org.chromium.chrome.browser.fullscreen.BrowserControlsManager;
 import org.chromium.chrome.browser.fullscreen.FullscreenManager;
@@ -29,7 +27,6 @@
     private final Context mContext;
     private boolean mPortrait = true;
     private final BrowserControlsManager mBrowserControlsManager;
-    private final ObservableSupplierImpl<BrowserControlsManager> mBrowserControlsManagerSupplier;
 
     static class MockTitleCache implements TitleCache {
         @Override
@@ -50,8 +47,6 @@
         mContext = context;
         mBrowserControlsManager =
                 new BrowserControlsManager(null, BrowserControlsManager.ControlsPosition.TOP);
-        mBrowserControlsManagerSupplier = new ObservableSupplierImpl<>();
-        mBrowserControlsManagerSupplier.set(mBrowserControlsManager);
     }
 
     public void setOrientation(boolean portrait) {
@@ -147,11 +142,6 @@
     }
 
     @Override
-    public ObservableSupplier<BrowserControlsManager> getBrowserControlsManagerSupplier() {
-        return mBrowserControlsManagerSupplier;
-    }
-
-    @Override
     public FullscreenManager getFullscreenManager() {
         return null;
     }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutTestRule.java b/chrome/android/javatests/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutTestRule.java
index b1f7d80..64c7e31 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutTestRule.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutTestRule.java
@@ -181,10 +181,9 @@
 
         TestThreadUtils.runOnUiThreadBlocking(() -> {
             setDisplayCutoutController(TestDisplayCutoutController.create(mTab, null));
+            mListener = new FullscreenToggleObserver();
+            getActivity().getFullscreenManager().addObserver(mListener);
         });
-
-        mListener = new FullscreenToggleObserver();
-        getActivity().getFullscreenManager().addObserver(mListener);
     }
 
     protected void setDisplayCutoutController(TestDisplayCutoutController controller) {
@@ -193,9 +192,11 @@
     }
 
     protected void tearDown() {
-        if (!getActivity().isActivityFinishingOrDestroyed()) {
-            getActivity().getFullscreenManager().removeObserver(mListener);
-        }
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            if (!getActivity().isActivityFinishingOrDestroyed()) {
+                getActivity().getFullscreenManager().removeObserver(mListener);
+            }
+        });
         mTestServer.stopAndDestroyServer();
     }
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreTest.java
index 6752f66..e8d857d3 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreTest.java
@@ -43,7 +43,6 @@
 import org.chromium.chrome.browser.flags.CachedFeatureFlags;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
-import org.chromium.chrome.browser.fullscreen.BrowserControlsManager;
 import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
 import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
 import org.chromium.chrome.browser.profiles.Profile;
@@ -302,11 +301,6 @@
                 protected void destroyTabModels() {}
 
                 @Override
-                protected BrowserControlsManager createBrowserControlsManager() {
-                    return null;
-                }
-
-                @Override
                 protected LaunchCauseMetrics createLaunchCauseMetrics() {
                     return null;
                 }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateUnitTest.java
index 276b7c5..4bb7401 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateUnitTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateUnitTest.java
@@ -151,7 +151,6 @@
         mJniMocker.mock(UserPrefsJni.TEST_HOOKS, mUserPrefsJniMock);
         Profile.setLastUsedProfileForTesting(mProfile);
         Mockito.when(mUserPrefsJniMock.get(mProfile)).thenReturn(mPrefService);
-        Mockito.when(mPrefService.getBoolean(Pref.ENABLE_WEB_FEED_UI)).thenReturn(true);
         FeatureList.setTestCanUseDefaultsForTesting();
 
         mAppMenuPropertiesDelegate = Mockito.spy(new AppMenuPropertiesDelegateImpl(
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/firstrun/SkipTosDialogPolicyListenerUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/firstrun/SkipTosDialogPolicyListenerUnitTest.java
index 74e5dc4..96a8384 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/firstrun/SkipTosDialogPolicyListenerUnitTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/firstrun/SkipTosDialogPolicyListenerUnitTest.java
@@ -24,6 +24,7 @@
 import org.robolectric.annotation.Config;
 import org.robolectric.annotation.Implementation;
 import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.LooperMode;
 import org.robolectric.shadows.ShadowLooper;
 
 import org.chromium.base.Callback;
@@ -46,6 +47,8 @@
 @Config(manifest = Config.NONE,
         shadows = {SkipTosDialogPolicyListenerUnitTest.ShadowFirstRunUtils.class,
                 ShadowRecordHistogram.class})
+//TODO(crbug.com/1210371): Rewrite using paused loop. See crbug for details.
+@LooperMode(LooperMode.Mode.LEGACY)
 public class SkipTosDialogPolicyListenerUnitTest {
     private static final String HIST_IS_DEVICE_OWNED_DETECTED =
             "histogramRecorded.OnIsDeviceOwnedDetected";
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegateUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegateUnitTest.java
index f68aff3..ed16558ba 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegateUnitTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegateUnitTest.java
@@ -49,7 +49,6 @@
 import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings;
 import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettingsJni;
 import org.chromium.chrome.browser.offlinepages.OfflinePageUtils;
-import org.chromium.chrome.browser.preferences.Pref;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.profiles.ProfileJni;
 import org.chromium.chrome.browser.tab.Tab;
@@ -61,9 +60,6 @@
 import org.chromium.chrome.browser.ui.appmenu.AppMenuDelegate;
 import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager;
 import org.chromium.chrome.test.util.browser.Features;
-import org.chromium.components.prefs.PrefService;
-import org.chromium.components.user_prefs.UserPrefs;
-import org.chromium.components.user_prefs.UserPrefsJni;
 import org.chromium.components.webapps.AppBannerManager;
 import org.chromium.content.browser.ContentFeatureListImpl;
 import org.chromium.content.browser.ContentFeatureListImplJni;
@@ -117,10 +113,6 @@
     @Mock
     Profile mProfileMock;
     @Mock
-    private UserPrefs.Natives mUserPrefsJniMock;
-    @Mock
-    private PrefService mPrefServiceMock;
-    @Mock
     private DataReductionProxySettings.Natives mDataReductionJniMock;
     @Mock
     private ContentFeatureListImpl.Natives mContentFeatureListJniMock;
@@ -170,10 +162,7 @@
         when(mTabModelFilterProvider.getCurrentTabModelFilter()).thenReturn(mTabModelFilter);
         when(mTabModelFilter.getTabModel()).thenReturn(mTabModel);
         jniMocker.mock(ProfileJni.TEST_HOOKS, mProfileJniMock);
-        jniMocker.mock(UserPrefsJni.TEST_HOOKS, mUserPrefsJniMock);
         when(mProfileJniMock.fromWebContents(any(WebContents.class))).thenReturn(mProfileMock);
-        when(mUserPrefsJniMock.get(mProfile)).thenReturn(mPrefServiceMock);
-        when(mPrefServiceMock.getBoolean(Pref.ENABLE_WEB_FEED_UI)).thenReturn(true);
         jniMocker.mock(ManagedBrowserUtilsJni.TEST_HOOKS, mManagedBrowserUtilsJniMock);
         Profile.setLastUsedProfileForTesting(mProfile);
         jniMocker.mock(DataReductionProxySettingsJni.TEST_HOOKS, mDataReductionJniMock);
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 72ec36f..8aaa2c8 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -6152,6 +6152,9 @@
       <message name="IDS_DESKTOP_PWA_INSTALL_PROMO" desc="Text shown on promotional UI appearing next to the PWA install icon">
         To get back here quickly, install <ph name="APP_NAME">$1<ex>Google Maps</ex></ph> by clicking the install button
       </message>
+      <message name="IDS_UPDATED_CONNECTION_SECURITY_INDICATORS_PROMO" desc="Text shown on promotional UI appearing next to the new omnibox connection security icon">
+        Your connection is always secure unless Chrome tells you otherwise
+      </message>
       <message name="IDS_REOPEN_TAB_PROMO_SCREENREADER" desc="Text announced encouraging users to reopen a tab with the given shortcut">
         <ph name="SHORTCUT">$1<ex>CTRL+SHIFT+T</ex></ph> can reopen accidentally closed tabs
       </message>
diff --git a/chrome/app/generated_resources_grd/IDS_UPDATED_CONNECTION_SECURITY_INDICATORS_PROMO.png.sha1 b/chrome/app/generated_resources_grd/IDS_UPDATED_CONNECTION_SECURITY_INDICATORS_PROMO.png.sha1
new file mode 100644
index 0000000..1b3c84f
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_UPDATED_CONNECTION_SECURITY_INDICATORS_PROMO.png.sha1
@@ -0,0 +1 @@
+18dc8149cff4dd2fc45076218363ec56ced419d7
\ No newline at end of file
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 3340601..96578742 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -1481,7 +1481,9 @@
     {ntp_features::kNtpChromeCartModuleDataParam, "fake"},
     {ntp_features::kNtpChromeCartModuleAbandonedCartDiscountParam, "true"}};
 const FeatureEntry::FeatureParam kNtpChromeCartModuleAbandonedCartDiscount[] = {
-    {ntp_features::kNtpChromeCartModuleAbandonedCartDiscountParam, "true"}};
+    {ntp_features::kNtpChromeCartModuleAbandonedCartDiscountParam, "true"},
+    {"partner-merchant-pattern",
+     "(electronicexpress.com|zazzle.com|wish.com|homesquare.com)"}};
 const FeatureEntry::FeatureVariation kNtpChromeCartModuleVariations[] = {
     {"- Fake Data And Discount", kNtpChromeCartModuleFakeData,
      base::size(kNtpChromeCartModuleFakeData), nullptr},
@@ -7219,9 +7221,15 @@
     {"link-doctor-deprecation-android",
      flag_descriptions::kLinkDoctorDeprecationAndroidName,
      flag_descriptions::kLinkDoctorDeprecationAndroidDescription, kOsAndroid,
-     FEATURE_VALUE_TYPE(features::kLinkDoctorDeprecationAndroid)}
+     FEATURE_VALUE_TYPE(features::kLinkDoctorDeprecationAndroid)},
 #endif
 
+#if defined(TOOLKIT_VIEWS)
+    {"download-shelf-webui", flag_descriptions::kDownloadShelfWebUI,
+     flag_descriptions::kDownloadShelfWebUIDescription, kOsDesktop,
+     FEATURE_VALUE_TYPE(features::kWebUIDownloadShelf)},
+#endif  // defined(TOOLKIT_VIEWS)
+
     // NOTE: Adding a new flag requires adding a corresponding entry to enum
     // "LoginCustomFlags" in tools/metrics/histograms/enums.xml. See "Flag
     // Histograms" in tools/metrics/histograms/README.md (run the
diff --git a/chrome/browser/apps/platform_apps/api/media_galleries/media_galleries_api.cc b/chrome/browser/apps/platform_apps/api/media_galleries/media_galleries_api.cc
index 2e28252d..5c9c90d 100644
--- a/chrome/browser/apps/platform_apps/api/media_galleries/media_galleries_api.cc
+++ b/chrome/browser/apps/platform_apps/api/media_galleries/media_galleries_api.cc
@@ -344,7 +344,7 @@
     const std::string& extension_id,
     extensions::events::HistogramValue histogram_value,
     const std::string& event_name,
-    std::unique_ptr<base::ListValue> event_args) {
+    std::vector<base::Value> event_args) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   extensions::EventRouter* router = extensions::EventRouter::Get(profile_);
diff --git a/chrome/browser/apps/platform_apps/api/media_galleries/media_galleries_api.h b/chrome/browser/apps/platform_apps/api/media_galleries/media_galleries_api.h
index 670adeb..80889b6 100644
--- a/chrome/browser/apps/platform_apps/api/media_galleries/media_galleries_api.h
+++ b/chrome/browser/apps/platform_apps/api/media_galleries/media_galleries_api.h
@@ -65,7 +65,7 @@
       const std::string& extension_id,
       extensions::events::HistogramValue histogram_value,
       const std::string& event_name,
-      std::unique_ptr<base::ListValue> event_args);
+      std::vector<base::Value> event_args);
 
   explicit MediaGalleriesEventRouter(content::BrowserContext* context);
   ~MediaGalleriesEventRouter() override;
diff --git a/chrome/browser/apps/platform_apps/api/sync_file_system/extension_sync_event_observer.cc b/chrome/browser/apps/platform_apps/api/sync_file_system/extension_sync_event_observer.cc
index 51ff9e4..ca3b0df 100644
--- a/chrome/browser/apps/platform_apps/api/sync_file_system/extension_sync_event_observer.cc
+++ b/chrome/browser/apps/platform_apps/api/sync_file_system/extension_sync_event_observer.cc
@@ -92,13 +92,13 @@
     ::sync_file_system::SyncFileStatus status,
     ::sync_file_system::SyncAction action,
     ::sync_file_system::SyncDirection direction) {
-  std::unique_ptr<base::ListValue> params(new base::ListValue());
+  std::vector<base::Value> params;
 
   std::unique_ptr<base::DictionaryValue> entry =
       CreateDictionaryValueForFileSystemEntry(url, file_type);
   if (!entry)
     return;
-  params->Append(std::move(entry));
+  params.push_back(base::Value::FromUniquePtrValue(std::move(entry)));
 
   // Status, SyncAction and any optional notes to go here.
   sync_file_system::FileStatus status_enum =
@@ -106,9 +106,9 @@
   sync_file_system::SyncAction action_enum = SyncActionToExtensionEnum(action);
   sync_file_system::SyncDirection direction_enum =
       SyncDirectionToExtensionEnum(direction);
-  params->AppendString(sync_file_system::ToString(status_enum));
-  params->AppendString(sync_file_system::ToString(action_enum));
-  params->AppendString(sync_file_system::ToString(direction_enum));
+  params.push_back(base::Value(sync_file_system::ToString(status_enum)));
+  params.push_back(base::Value(sync_file_system::ToString(action_enum)));
+  params.push_back(base::Value(sync_file_system::ToString(direction_enum)));
 
   BroadcastOrDispatchEvent(
       url.origin().GetURL(),
@@ -120,7 +120,7 @@
     const GURL& app_origin,
     extensions::events::HistogramValue histogram_value,
     const std::string& event_name,
-    std::unique_ptr<base::ListValue> values) {
+    std::vector<base::Value> values) {
   // Check to see whether the event should be broadcasted to all listening
   // extensions or sent to a specific extension ID.
   bool broadcast_mode = app_origin.is_empty();
diff --git a/chrome/browser/apps/platform_apps/api/sync_file_system/extension_sync_event_observer.h b/chrome/browser/apps/platform_apps/api/sync_file_system/extension_sync_event_observer.h
index dd861cc..e46dc33d 100644
--- a/chrome/browser/apps/platform_apps/api/sync_file_system/extension_sync_event_observer.h
+++ b/chrome/browser/apps/platform_apps/api/sync_file_system/extension_sync_event_observer.h
@@ -5,8 +5,8 @@
 #ifndef CHROME_BROWSER_APPS_PLATFORM_APPS_API_SYNC_FILE_SYSTEM_EXTENSION_SYNC_EVENT_OBSERVER_H_
 #define CHROME_BROWSER_APPS_PLATFORM_APPS_API_SYNC_FILE_SYSTEM_EXTENSION_SYNC_EVENT_OBSERVER_H_
 
-#include <memory>
 #include <string>
+#include <vector>
 
 #include "base/compiler_specific.h"
 #include "base/values.h"
@@ -76,7 +76,7 @@
       const GURL& app_origin,
       extensions::events::HistogramValue histogram_value,
       const std::string& event_name,
-      std::unique_ptr<base::ListValue> value);
+      std::vector<base::Value> value);
 };
 
 }  // namespace api
diff --git a/chrome/browser/ash/arc/enterprise/arc_snapshot_reboot_notification_impl.h b/chrome/browser/ash/arc/enterprise/arc_snapshot_reboot_notification_impl.h
index 4fab65e..d5acf7a 100644
--- a/chrome/browser/ash/arc/enterprise/arc_snapshot_reboot_notification_impl.h
+++ b/chrome/browser/ash/arc/enterprise/arc_snapshot_reboot_notification_impl.h
@@ -8,6 +8,7 @@
 #include "base/callback.h"
 #include "base/memory/weak_ptr.h"
 #include "components/arc/enterprise/arc_snapshot_reboot_notification.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace arc {
 namespace data_snapshotd {
diff --git a/chrome/browser/ash/crosapi/keystore_service_ash.cc b/chrome/browser/ash/crosapi/keystore_service_ash.cc
index 1bd7721f..30b14f4 100644
--- a/chrome/browser/ash/crosapi/keystore_service_ash.cc
+++ b/chrome/browser/ash/crosapi/keystore_service_ash.cc
@@ -572,16 +572,16 @@
 void KeystoreServiceAsh::DidExtensionSign(
     ExtensionSignCallback callback,
     const std::string& signature,
-    chromeos::platform_keys::Status status) {
+    absl::optional<mojom::KeystoreError> error) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
-  if (status == chromeos::platform_keys::Status::kSuccess) {
+  if (!error) {
     std::move(callback).Run(mojom::ExtensionKeystoreBinaryResult::NewBlob(
         std::vector<uint8_t>(signature.begin(), signature.end())));
   } else {
     std::move(callback).Run(
         mojom::ExtensionKeystoreBinaryResult::NewErrorMessage(
-            chromeos::platform_keys::StatusToString(status)));
+            chromeos::platform_keys::KeystoreErrorToString(error.value())));
   }
 }
 
@@ -643,4 +643,69 @@
   std::move(callback).Run(std::move(result_ptr));
 }
 
+//------------------------------------------------------------------------------
+
+void KeystoreServiceAsh::Sign(bool is_keystore_provided,
+                              KeystoreType keystore,
+                              const std::vector<uint8_t>& public_key,
+                              SigningScheme scheme,
+                              const std::vector<uint8_t>& data,
+                              SignCallback callback) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+  absl::optional<TokenId> token_id;
+  if (is_keystore_provided) {
+    token_id = KeystoreToToken(keystore);
+    if (!token_id) {
+      std::move(callback).Run(mojom::KeystoreBinaryResult::NewError(
+          mojom::KeystoreError::kUnsupportedKeystoreType));
+      return;
+    }
+  }
+
+  chromeos::platform_keys::KeyType key_type;
+  chromeos::platform_keys::HashAlgorithm hash_algorithm;
+  if (!UnpackSigningScheme(scheme, &key_type, &hash_algorithm)) {
+    std::move(callback).Run(mojom::KeystoreBinaryResult::NewError(
+        mojom::KeystoreError::kUnsupportedAlgorithmType));
+    return;
+  }
+
+  PlatformKeysService* service = GetPlatformKeys();
+  std::string data_str(data.begin(), data.end());
+  std::string public_key_str(public_key.begin(), public_key.end());
+  auto cb = base::BindOnce(&KeystoreServiceAsh::DidSign, std::move(callback));
+
+  switch (key_type) {
+    case chromeos::platform_keys::KeyType::kRsassaPkcs1V15:
+      if (hash_algorithm == chromeos::platform_keys::HASH_ALGORITHM_NONE) {
+        service->SignRSAPKCS1Raw(token_id, data_str, public_key_str,
+                                 std::move(cb));
+        return;
+      }
+      service->SignRSAPKCS1Digest(token_id, data_str, public_key_str,
+                                  hash_algorithm, std::move(cb));
+      return;
+    case chromeos::platform_keys::KeyType::kEcdsa:
+      service->SignECDSADigest(token_id, data_str, public_key_str,
+                               hash_algorithm, std::move(cb));
+      return;
+  }
+}
+
+// static
+void KeystoreServiceAsh::DidSign(SignCallback callback,
+                                 const std::string& signature,
+                                 chromeos::platform_keys::Status status) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+  if (status == chromeos::platform_keys::Status::kSuccess) {
+    std::move(callback).Run(mojom::KeystoreBinaryResult::NewBlob(
+        std::vector<uint8_t>(signature.begin(), signature.end())));
+  } else {
+    std::move(callback).Run(mojom::KeystoreBinaryResult::NewError(
+        chromeos::platform_keys::StatusToKeystoreError(status)));
+  }
+}
+
 }  // namespace crosapi
diff --git a/chrome/browser/ash/crosapi/keystore_service_ash.h b/chrome/browser/ash/crosapi/keystore_service_ash.h
index 0d13fc5b..d815c1b6a 100644
--- a/chrome/browser/ash/crosapi/keystore_service_ash.h
+++ b/chrome/browser/ash/crosapi/keystore_service_ash.h
@@ -69,6 +69,12 @@
   void GenerateKey(mojom::KeystoreType keystore,
                    mojom::KeystoreSigningAlgorithmPtr algorithm,
                    GenerateKeyCallback callback) override;
+  void Sign(bool is_keystore_provided,
+            KeystoreType keystore,
+            const std::vector<uint8_t>& public_key,
+            SigningScheme scheme,
+            const std::vector<uint8_t>& data,
+            SignCallback callback) override;
 
  private:
   // |challenge| is used as a opaque identifier to match against the unique_ptr
@@ -95,10 +101,13 @@
       absl::optional<crosapi::mojom::KeystoreError> error);
   static void DidExtensionSign(ExtensionSignCallback callback,
                                const std::string& signature,
-                               chromeos::platform_keys::Status status);
+                               absl::optional<mojom::KeystoreError> error);
   static void DidGenerateKey(GenerateKeyCallback callback,
                              const std::string& public_key,
                              chromeos::platform_keys::Status status);
+  static void DidSign(SignCallback callback,
+                      const std::string& signature,
+                      chromeos::platform_keys::Status status);
 
   // Container to keep outstanding challenges alive.
   std::vector<std::unique_ptr<ash::attestation::TpmChallengeKey>>
diff --git a/chrome/browser/ash/file_system_provider/operations/operation.cc b/chrome/browser/ash/file_system_provider/operations/operation.cc
index bec9f5f..ade245c7 100644
--- a/chrome/browser/ash/file_system_provider/operations/operation.cc
+++ b/chrome/browser/ash/file_system_provider/operations/operation.cc
@@ -49,7 +49,7 @@
 bool Operation::SendEvent(int request_id,
                           extensions::events::HistogramValue histogram_value,
                           const std::string& event_name,
-                          std::unique_ptr<base::ListValue> event_args) {
+                          std::vector<base::Value> event_args) {
   return dispatch_event_impl_.Run(std::make_unique<extensions::Event>(
       histogram_value, event_name, std::move(event_args)));
 }
diff --git a/chrome/browser/ash/file_system_provider/operations/operation.h b/chrome/browser/ash/file_system_provider/operations/operation.h
index 7755e75f..e673b8c 100644
--- a/chrome/browser/ash/file_system_provider/operations/operation.h
+++ b/chrome/browser/ash/file_system_provider/operations/operation.h
@@ -7,18 +7,16 @@
 
 #include <memory>
 #include <string>
+#include <vector>
 
 #include "base/files/file.h"
 #include "base/macros.h"
+#include "base/values.h"
 #include "chrome/browser/ash/file_system_provider/provided_file_system_info.h"
 #include "chrome/browser/ash/file_system_provider/request_manager.h"
 #include "extensions/browser/extension_event_histogram_value.h"
 #include "storage/browser/file_system/async_file_util.h"
 
-namespace base {
-class ListValue;
-}  // namespace base
-
 namespace extensions {
 struct Event;
 class EventRouter;
@@ -57,7 +55,7 @@
   bool SendEvent(int request_id,
                  extensions::events::HistogramValue histogram_value,
                  const std::string& event_name,
-                 std::unique_ptr<base::ListValue> event_args);
+                 std::vector<base::Value> event_args);
 
   ProvidedFileSystemInfo file_system_info_;
 
diff --git a/chrome/browser/ash/file_system_provider/operations/write_file.cc b/chrome/browser/ash/file_system_provider/operations/write_file.cc
index 359743bd..2b363944 100644
--- a/chrome/browser/ash/file_system_provider/operations/write_file.cc
+++ b/chrome/browser/ash/file_system_provider/operations/write_file.cc
@@ -56,15 +56,14 @@
       "data",
       base::Value(base::as_bytes(base::make_span(buffer_->data(), length_))));
 
-  base::Value event_args(base::Value::Type::LIST);
-  event_args.Append(std::move(options_as_value));
+  std::vector<base::Value> event_args;
+  event_args.push_back(std::move(options_as_value));
 
   return SendEvent(
       request_id,
       extensions::events::FILE_SYSTEM_PROVIDER_ON_WRITE_FILE_REQUESTED,
       extensions::api::file_system_provider::OnWriteFileRequested::kEventName,
-      base::ListValue::From(
-          base::Value::ToUniquePtrValue(std::move(event_args))));
+      std::move(event_args));
 }
 
 void WriteFile::OnSuccess(int /* request_id */,
diff --git a/chrome/browser/ash/plugin_vm/plugin_vm_image_download_client.h b/chrome/browser/ash/plugin_vm/plugin_vm_image_download_client.h
index 283b7b6c..0f2bd79 100644
--- a/chrome/browser/ash/plugin_vm/plugin_vm_image_download_client.h
+++ b/chrome/browser/ash/plugin_vm/plugin_vm_image_download_client.h
@@ -10,6 +10,7 @@
 
 #include "base/macros.h"
 #include "components/download/public/background_service/client.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace download {
 struct CompletionInfo;
diff --git a/chrome/browser/autofill/android/save_address_profile_prompt_controller.cc b/chrome/browser/autofill/android/save_address_profile_prompt_controller.cc
index 860ecdb..7caface 100644
--- a/chrome/browser/autofill/android/save_address_profile_prompt_controller.cc
+++ b/chrome/browser/autofill/android/save_address_profile_prompt_controller.cc
@@ -162,7 +162,7 @@
                                                             &edited_profile);
   profile_ = edited_profile;
   RunSaveAddressProfileCallback(
-      AutofillClient::SaveAddressProfileOfferUserDecision::kEdited);
+      AutofillClient::SaveAddressProfileOfferUserDecision::kEditAccepted);
 }
 
 void SaveAddressProfilePromptController::OnPromptDismissed(
diff --git a/chrome/browser/autofill/android/save_address_profile_prompt_controller_unittest.cc b/chrome/browser/autofill/android/save_address_profile_prompt_controller_unittest.cc
index 4cbcf0bc..7ee6028 100644
--- a/chrome/browser/autofill/android/save_address_profile_prompt_controller_unittest.cc
+++ b/chrome/browser/autofill/android/save_address_profile_prompt_controller_unittest.cc
@@ -138,9 +138,10 @@
   controller_->DisplayPrompt();
 
   AutofillProfile edited_profile = GetFullProfileNoStatus();
-  EXPECT_CALL(decision_callback_,
-              Run(AutofillClient::SaveAddressProfileOfferUserDecision::kEdited,
-                  edited_profile));
+  EXPECT_CALL(
+      decision_callback_,
+      Run(AutofillClient::SaveAddressProfileOfferUserDecision::kEditAccepted,
+          edited_profile));
   base::android::ScopedJavaLocalRef<jobject> edited_profile_java =
       PersonalDataManagerAndroid::CreateJavaProfileFromNative(env_,
                                                               edited_profile);
diff --git a/chrome/browser/bitmap_fetcher/bitmap_fetcher_service.cc b/chrome/browser/bitmap_fetcher/bitmap_fetcher_service.cc
index 56dc8de..838c52de 100644
--- a/chrome/browser/bitmap_fetcher/bitmap_fetcher_service.cc
+++ b/chrome/browser/bitmap_fetcher/bitmap_fetcher_service.cc
@@ -85,7 +85,8 @@
 
   int idle_timeout = base::GetFieldTrialParamByFeatureAsInt(
       omnibox::kEntitySuggestionsReduceLatency,
-      OmniboxFieldTrial::kEntitySuggestionsReduceLatencyDecoderTimeoutParam, 0);
+      OmniboxFieldTrial::kEntitySuggestionsReduceLatencyDecoderTimeoutParam,
+      405);
 
   return idle_timeout > 0 ? std::make_unique<data_decoder::DataDecoder>(
                                 base::TimeDelta::FromSeconds(idle_timeout))
diff --git a/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller.h b/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller.h
index 80e7c32..5822edbd 100644
--- a/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller.h
+++ b/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller.h
@@ -8,6 +8,7 @@
 #include "base/callback_forward.h"
 #include "base/macros.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 namespace chromeos {
diff --git a/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router.h b/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router.h
index 360d95df..4b4b790e 100644
--- a/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router.h
+++ b/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router.h
@@ -6,12 +6,12 @@
 #define CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_MANAGER_DRIVEFS_EVENT_ROUTER_H_
 
 #include <map>
-#include <memory>
 #include <set>
 #include <string>
 #include <vector>
 
 #include "base/macros.h"
+#include "base/values.h"
 #include "chromeos/components/drivefs/drivefs_host_observer.h"
 #include "chromeos/components/drivefs/mojom/drivefs.mojom.h"
 #include "extensions/browser/extension_event_histogram_value.h"
@@ -19,7 +19,6 @@
 
 namespace base {
 class FilePath;
-class ListValue;
 }
 
 namespace extensions {
@@ -99,7 +98,7 @@
       const std::string& extension_id,
       extensions::events::HistogramValue histogram_value,
       const std::string& event_name,
-      std::unique_ptr<base::ListValue> event_args) = 0;
+      std::vector<base::Value> event_args) = 0;
 
   static extensions::api::file_manager_private::FileTransferStatus
   CreateFileTransferStatus(
diff --git a/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router_unittest.cc b/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router_unittest.cc
index 15b1a58..7446723 100644
--- a/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router_unittest.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router_unittest.cc
@@ -29,13 +29,12 @@
 
 namespace {
 
-class ListValueMatcher
-    : public testing::MatcherInterface<const base::ListValue&> {
+class ValueMatcher : public testing::MatcherInterface<const base::Value&> {
  public:
-  explicit ListValueMatcher(base::ListValue expected)
+  explicit ValueMatcher(base::Value expected)
       : expected_(std::move(expected)) {}
 
-  bool MatchAndExplain(const base::ListValue& actual,
+  bool MatchAndExplain(const base::Value& actual,
                        testing::MatchResultListener* listener) const override {
     *listener << actual;
     return actual == expected_;
@@ -44,10 +43,10 @@
   void DescribeTo(::std::ostream* os) const override { *os << expected_; }
 
  private:
-  base::ListValue expected_;
+  base::Value expected_;
 };
 
-testing::Matcher<const base::ListValue&> MatchFileTransferStatus(
+testing::Matcher<const base::Value&> MatchFileTransferStatus(
     std::string file_url,
     file_manager_private::TransferState transfer_state,
     double processed,
@@ -60,14 +59,14 @@
   status.total = total;
   status.num_total_jobs = num_total_jobs;
   status.hide_when_zero_jobs = true;
-  return testing::MakeMatcher(new ListValueMatcher(std::move(
-      *file_manager_private::OnFileTransfersUpdated::Create(status))));
+  return testing::MakeMatcher(new ValueMatcher(base::Value(
+      file_manager_private::OnFileTransfersUpdated::Create(status))));
 }
 
-testing::Matcher<const base::ListValue&> MatchFileWatchEvent(
+testing::Matcher<const base::Value&> MatchFileWatchEvent(
     const FileWatchEvent& event) {
-  return testing::MakeMatcher(new ListValueMatcher(
-      std::move(*file_manager_private::OnDirectoryChanged::Create(event))));
+  return testing::MakeMatcher(new ValueMatcher(
+      base::Value(file_manager_private::OnDirectoryChanged::Create(event))));
 }
 
 class TestDriveFsEventRouter : public DriveFsEventRouter {
@@ -83,15 +82,16 @@
       const std::string& extension_id,
       extensions::events::HistogramValue histogram_value,
       const std::string& event_name,
-      std::unique_ptr<base::ListValue> event_args) override {
-    DispatchEventToExtensionImpl(extension_id, event_name, *event_args);
+      std::vector<base::Value> event_args) override {
+    DispatchEventToExtensionImpl(extension_id, event_name,
+                                 base::Value(std::move(event_args)));
   }
 
   MOCK_METHOD(void,
               DispatchEventToExtensionImpl,
               (const std::string& extension_id,
                const std::string& name,
-               const base::ListValue& event));
+               const base::Value& event));
   MOCK_METHOD(bool, IsPathWatched, (const base::FilePath&));
 
   GURL ConvertDrivePathToFileSystemUrl(const base::FilePath& file_path,
@@ -767,8 +767,8 @@
       mock(),
       DispatchEventToExtensionImpl(
           "ext", file_manager_private::OnDriveSyncError::kEventName,
-          testing::MakeMatcher(new ListValueMatcher(std::move(
-              *file_manager_private::OnDriveSyncError::Create(event))))));
+          testing::MakeMatcher(new ValueMatcher(base::Value(
+              file_manager_private::OnDriveSyncError::Create(event))))));
 
   observer().OnError({drivefs::mojom::DriveError::Type::kCantUploadStorageFull,
                       base::FilePath("/a")});
@@ -782,8 +782,8 @@
       mock(),
       DispatchEventToExtensionImpl(
           "ext", file_manager_private::OnDriveSyncError::kEventName,
-          testing::MakeMatcher(new ListValueMatcher(std::move(
-              *file_manager_private::OnDriveSyncError::Create(event))))));
+          testing::MakeMatcher(new ValueMatcher(base::Value(
+              file_manager_private::OnDriveSyncError::Create(event))))));
 
   observer().OnError({drivefs::mojom::DriveError::Type::kPinningFailedDiskFull,
                       base::FilePath("a")});
@@ -797,8 +797,8 @@
   EXPECT_CALL(mock(),
               DispatchEventToExtensionImpl(
                   "ext", file_manager_private::OnDriveConfirmDialog::kEventName,
-                  testing::MakeMatcher(new ListValueMatcher(std::move(
-                      *file_manager_private::OnDriveConfirmDialog::Create(
+                  testing::MakeMatcher(new ValueMatcher(base::Value(
+                      file_manager_private::OnDriveConfirmDialog::Create(
                           expected_event))))));
 
   drivefs::mojom::DialogReason reason;
@@ -824,8 +824,8 @@
   EXPECT_CALL(mock(),
               DispatchEventToExtensionImpl(
                   "ext", file_manager_private::OnDriveConfirmDialog::kEventName,
-                  testing::MakeMatcher(new ListValueMatcher(std::move(
-                      *file_manager_private::OnDriveConfirmDialog::Create(
+                  testing::MakeMatcher(new ValueMatcher(base::Value(
+                      file_manager_private::OnDriveConfirmDialog::Create(
                           expected_event))))));
 
   drivefs::mojom::DialogReason reason;
@@ -860,8 +860,8 @@
   EXPECT_CALL(mock(),
               DispatchEventToExtensionImpl(
                   "ext", file_manager_private::OnDriveConfirmDialog::kEventName,
-                  testing::MakeMatcher(new ListValueMatcher(std::move(
-                      *file_manager_private::OnDriveConfirmDialog::Create(
+                  testing::MakeMatcher(new ValueMatcher(base::Value(
+                      file_manager_private::OnDriveConfirmDialog::Create(
                           expected_event))))))
       .Times(2);
 
diff --git a/chrome/browser/chromeos/extensions/file_manager/event_router.cc b/chrome/browser/chromeos/extensions/file_manager/event_router.cc
index e6274ba8..a83c342 100644
--- a/chrome/browser/chromeos/extensions/file_manager/event_router.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/event_router.cc
@@ -101,7 +101,7 @@
 void BroadcastEvent(Profile* profile,
                     extensions::events::HistogramValue histogram_value,
                     const std::string& event_name,
-                    std::unique_ptr<base::ListValue> event_args) {
+                    std::vector<base::Value> event_args) {
   extensions::EventRouter::Get(profile)->BroadcastEvent(
       std::make_unique<extensions::Event>(histogram_value, event_name,
                                           std::move(event_args)));
@@ -114,7 +114,7 @@
     const std::string& extension_id,
     extensions::events::HistogramValue histogram_value,
     const std::string& event_name,
-    std::unique_ptr<base::ListValue> event_args) {
+    std::vector<base::Value> event_args) {
   extensions::EventRouter::Get(profile)->DispatchEventToExtension(
       extension_id, std::make_unique<extensions::Event>(
                         histogram_value, event_name, std::move(event_args)));
@@ -409,7 +409,7 @@
       const std::string& extension_id,
       extensions::events::HistogramValue histogram_value,
       const std::string& event_name,
-      std::unique_ptr<base::ListValue> event_args) override {
+      std::vector<base::Value> event_args) override {
     extensions::EventRouter::Get(profile_)->DispatchEventToExtension(
         extension_id, std::make_unique<extensions::Event>(
                           histogram_value, event_name, std::move(event_args)));
diff --git a/chrome/browser/chromeos/platform_keys/extension_platform_keys_service.cc b/chrome/browser/chromeos/platform_keys/extension_platform_keys_service.cc
index f4a9216..c8e149b 100644
--- a/chrome/browser/chromeos/platform_keys/extension_platform_keys_service.cc
+++ b/chrome/browser/chromeos/platform_keys/extension_platform_keys_service.cc
@@ -45,6 +45,7 @@
 using crosapi::mojom::KeystoreBinaryResultPtr;
 using crosapi::mojom::KeystoreECDSAParams;
 using crosapi::mojom::KeystoreECDSAParamsPtr;
+using crosapi::mojom::KeystoreError;
 using crosapi::mojom::KeystorePKCS115Params;
 using crosapi::mojom::KeystorePKCS115ParamsPtr;
 using crosapi::mojom::KeystoreService;
@@ -84,6 +85,44 @@
   }
 }
 
+KeystoreSigningScheme GetKeystoreSigningScheme(
+    platform_keys::KeyType key_type,
+    platform_keys::HashAlgorithm hash_algorithm) {
+  switch (key_type) {
+    case platform_keys::KeyType::kRsassaPkcs1V15: {
+      switch (hash_algorithm) {
+        case platform_keys::HASH_ALGORITHM_NONE:
+          return KeystoreSigningScheme::kRsassaPkcs1V15None;
+        case platform_keys::HASH_ALGORITHM_SHA1:
+          return KeystoreSigningScheme::kRsassaPkcs1V15Sha1;
+        case platform_keys::HASH_ALGORITHM_SHA256:
+          return KeystoreSigningScheme::kRsassaPkcs1V15Sha256;
+        case platform_keys::HASH_ALGORITHM_SHA384:
+          return KeystoreSigningScheme::kRsassaPkcs1V15Sha384;
+        case platform_keys::HASH_ALGORITHM_SHA512:
+          return KeystoreSigningScheme::kRsassaPkcs1V15Sha512;
+      }
+    }
+    case platform_keys::KeyType::kEcdsa: {
+      switch (hash_algorithm) {
+        case platform_keys::HASH_ALGORITHM_NONE:
+          // This combination is not supported.
+          return KeystoreSigningScheme::kUnknown;
+        case platform_keys::HASH_ALGORITHM_SHA1:
+          return KeystoreSigningScheme::kEcdsaSha1;
+        case platform_keys::HASH_ALGORITHM_SHA256:
+          return KeystoreSigningScheme::kEcdsaSha256;
+        case platform_keys::HASH_ALGORITHM_SHA384:
+          return KeystoreSigningScheme::kEcdsaSha384;
+        case platform_keys::HASH_ALGORITHM_SHA512:
+          return KeystoreSigningScheme::kEcdsaSha512;
+      }
+    }
+  }
+  NOTREACHED();
+  return KeystoreSigningScheme::kUnknown;
+}
+
 }  // namespace
 
 class ExtensionPlatformKeysService::Task {
@@ -333,13 +372,14 @@
            SignCallback callback,
            ExtensionPlatformKeysService* service)
       : token_id_(token_id),
-        data_(data),
+        data_(data.begin(), data.end()),
         public_key_spki_der_(public_key_spki_der),
-        key_type_(key_type),
-        hash_algorithm_(hash_algorithm),
         extension_id_(extension_id),
         callback_(std::move(callback)),
-        service_(service) {}
+        service_(service) {
+    signing_scheme_ = GetKeystoreSigningScheme(key_type, hash_algorithm);
+    DCHECK(signing_scheme_ != KeystoreSigningScheme::kUnknown);
+  }
 
   ~SignTask() override {}
 
@@ -410,9 +450,8 @@
 
   void OnCanUseKeyForSigningKnown(bool allowed) {
     if (!allowed) {
-      std::move(callback_).Run(
-          std::string() /* no signature */,
-          platform_keys::Status::kErrorKeyNotAllowedForSigning);
+      std::move(callback_).Run(std::string() /* no signature */,
+                               KeystoreError::kKeyNotAllowedForSigning);
       next_step_ = Step::DONE;
       DoStep();
       return;
@@ -434,7 +473,8 @@
       LOG(ERROR) << "Marking a key used for signing failed: "
                  << platform_keys::StatusToString(status);
       next_step_ = Step::DONE;
-      std::move(callback_).Run(std::string() /* no signature */, status);
+      std::move(callback_).Run(std::string() /* no signature */,
+                               platform_keys::StatusToKeystoreError(status));
       DoStep();
       return;
     }
@@ -445,42 +485,45 @@
   // Starts the actual signing operation and afterwards passes the signature (or
   // error) to |callback_|.
   void Sign() {
-    switch (key_type_) {
-      case platform_keys::KeyType::kRsassaPkcs1V15: {
-        if (hash_algorithm_ ==
-            platform_keys::HashAlgorithm::HASH_ALGORITHM_NONE) {
-          service_->platform_keys_service_->SignRSAPKCS1Raw(
-              token_id_, data_, public_key_spki_der_,
-              base::BindOnce(&SignTask::DidSign, weak_factory_.GetWeakPtr()));
-        } else {
-          service_->platform_keys_service_->SignRSAPKCS1Digest(
-              token_id_, data_, public_key_spki_der_, hash_algorithm_,
-              base::BindOnce(&SignTask::DidSign, weak_factory_.GetWeakPtr()));
-        }
-        break;
-      }
-      case platform_keys::KeyType::kEcdsa: {
-        service_->platform_keys_service_->SignECDSADigest(
-            token_id_, data_, public_key_spki_der_, hash_algorithm_,
-            base::BindOnce(&SignTask::DidSign, weak_factory_.GetWeakPtr()));
-        break;
-      }
+    // TODO(crbug.com/657632): This can be simplified when mojo supports
+    // optional enums.
+    bool is_keystore_provided = false;
+    KeystoreType keystore = KeystoreType::kUser;
+    if (token_id_.has_value()) {
+      is_keystore_provided = true;
+      keystore = KeystoreTypeFromTokenId(token_id_.value());
     }
+    std::vector<uint8_t> public_key(public_key_spki_der_.begin(),
+                                    public_key_spki_der_.end());
+
+    service_->keystore_service_->Sign(
+        is_keystore_provided, keystore, std::move(public_key), signing_scheme_,
+        data_, base::BindOnce(&SignTask::DidSign, weak_factory_.GetWeakPtr()));
   }
 
-  void DidSign(const std::string& signature, platform_keys::Status status) {
-    std::move(callback_).Run(signature, status);
+  void DidSign(KeystoreBinaryResultPtr result) {
+    switch (result->which()) {
+      case KeystoreBinaryResult::Tag::ERROR:
+        std::move(callback_).Run(/*signature=*/std::string(),
+                                 result->get_error());
+        break;
+      case KeystoreBinaryResult::Tag::BLOB:
+        const std::vector<uint8_t>& blob = result->get_blob();
+        std::move(callback_).Run(
+            /*signature=*/std::string(blob.begin(), blob.end()),
+            /*error=*/absl::nullopt);
+        break;
+    }
     DoStep();
   }
 
   Step next_step_ = Step::GET_EXTENSION_PERMISSIONS;
 
   absl::optional<platform_keys::TokenId> token_id_;
-  const std::string data_;
+  const std::vector<uint8_t> data_;
   const std::string public_key_spki_der_;
 
-  const platform_keys::KeyType key_type_;
-  const platform_keys::HashAlgorithm hash_algorithm_;
+  KeystoreSigningScheme signing_scheme_;
   const std::string extension_id_;
   SignCallback callback_;
   std::unique_ptr<platform_keys::ExtensionKeyPermissionsService>
diff --git a/chrome/browser/chromeos/platform_keys/extension_platform_keys_service.h b/chrome/browser/chromeos/platform_keys/extension_platform_keys_service.h
index 3238dfde5..0e1e1ed6 100644
--- a/chrome/browser/chromeos/platform_keys/extension_platform_keys_service.h
+++ b/chrome/browser/chromeos/platform_keys/extension_platform_keys_service.h
@@ -111,8 +111,9 @@
 
   // If signing was successful, |signature| will contain the signature. If it
   // failed, |signature| will be empty.
-  using SignCallback = base::OnceCallback<void(const std::string& signature,
-                                               platform_keys::Status status)>;
+  using SignCallback = base::OnceCallback<void(
+      const std::string& signature,
+      absl::optional<crosapi::mojom::KeystoreError> error)>;
 
   // Digests |data|, applies PKCS1 padding if specified by |hash_algorithm| and
   // chooses the signature algorithm according to |key_type| and signs the data
diff --git a/chrome/browser/chromeos/platform_keys/mock_platform_keys_service.h b/chrome/browser/chromeos/platform_keys/mock_platform_keys_service.h
index 560e51b..b0e9a3f 100644
--- a/chrome/browser/chromeos/platform_keys/mock_platform_keys_service.h
+++ b/chrome/browser/chromeos/platform_keys/mock_platform_keys_service.h
@@ -77,7 +77,7 @@
 
   MOCK_METHOD(void,
               SelectClientCertificates,
-              (const std::vector<std::string>& certificate_authorities,
+              (std::vector<std::string> certificate_authorities,
                SelectCertificatesCallback callback),
               (override));
 
diff --git a/chrome/browser/chromeos/platform_keys/platform_keys.cc b/chrome/browser/chromeos/platform_keys/platform_keys.cc
index 81d531e..10d9b03 100644
--- a/chrome/browser/chromeos/platform_keys/platform_keys.cc
+++ b/chrome/browser/chromeos/platform_keys/platform_keys.cc
@@ -142,6 +142,7 @@
       // Keystore specific errors shouldn't be passed here.
     case KeystoreError::kUnknown:
     case KeystoreError::kUnsupportedKeystoreType:
+    case KeystoreError::kUnsupportedAlgorithmType:
       DCHECK(false);
       return Status::kErrorInternal;
 
@@ -189,6 +190,8 @@
       return "Unknown keystore error.";
     case KeystoreError::kUnsupportedKeystoreType:
       return "The token is not valid.";
+    case KeystoreError::kUnsupportedAlgorithmType:
+      return "Algorithm type is not supported.";
     default:
       break;
   }
diff --git a/chrome/browser/chromeos/platform_keys/platform_keys_service.h b/chrome/browser/chromeos/platform_keys/platform_keys_service.h
index 8f11d97..82750510 100644
--- a/chrome/browser/chromeos/platform_keys/platform_keys_service.h
+++ b/chrome/browser/chromeos/platform_keys/platform_keys_service.h
@@ -183,7 +183,7 @@
   // certificates will be returned. |callback| will be invoked with the matches
   // or an error status.
   virtual void SelectClientCertificates(
-      const std::vector<std::string>& certificate_authorities,
+      std::vector<std::string> certificate_authorities,
       const SelectCertificatesCallback callback) = 0;
 
   // Returns the list of all certificates with stored private key available from
@@ -347,7 +347,7 @@
                        HashAlgorithm hash_algorithm,
                        SignCallback callback) override;
   void SelectClientCertificates(
-      const std::vector<std::string>& certificate_authorities,
+      std::vector<std::string> certificate_authorities,
       SelectCertificatesCallback callback) override;
   void GetCertificates(TokenId token_id,
                        GetCertificatesCallback callback) override;
diff --git a/chrome/browser/chromeos/platform_keys/platform_keys_service_nss.cc b/chrome/browser/chromeos/platform_keys/platform_keys_service_nss.cc
index 3259effc..80c4c86b1 100644
--- a/chrome/browser/chromeos/platform_keys/platform_keys_service_nss.cc
+++ b/chrome/browser/chromeos/platform_keys/platform_keys_service_nss.cc
@@ -1605,7 +1605,7 @@
 }
 
 void PlatformKeysServiceImpl::SelectClientCertificates(
-    const std::vector<std::string>& certificate_authorities,
+    std::vector<std::string> certificate_authorities,
     SelectCertificatesCallback callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
@@ -1615,7 +1615,7 @@
   // layer, as it does not support filtering certificates by type. Rather, we
   // do not constrain the certificate type here, instead the caller has to apply
   // filtering afterwards.
-  cert_request_info->cert_authorities = certificate_authorities;
+  cert_request_info->cert_authorities = std::move(certificate_authorities);
 
   auto state = std::make_unique<SelectCertificatesState>(
       weak_factory_.GetWeakPtr(), cert_request_info, std::move(callback));
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_histogram_helper.h b/chrome/browser/chromeos/policy/dlp/dlp_histogram_helper.h
index 892dca2..bb4f835c 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_histogram_helper.h
+++ b/chrome/browser/chromeos/policy/dlp/dlp_histogram_helper.h
@@ -28,6 +28,11 @@
 constexpr char kScreenshotBlockedUMA[] = "ScreenshotBlocked";
 constexpr char kVideoCaptureInterruptedUMA[] = "VideoCaptureInterrupted";
 constexpr char kVideoCaptureBlockedUMA[] = "VideoCaptureBlocked";
+constexpr char kReportedBlockLevelRestriction[] =
+    "ReportedBlockLevelRestriction";
+constexpr char kReportedReportLevelRestriction[] =
+    "ReportedReportLevelRestriction";
+constexpr char kReportedEventStatus[] = "ReportedEventStatus";
 
 }  // namespace dlp
 
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_policy_event.proto b/chrome/browser/chromeos/policy/dlp/dlp_policy_event.proto
index 3eeb6963..95085f5d 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_policy_event.proto
+++ b/chrome/browser/chromeos/policy/dlp/dlp_policy_event.proto
@@ -40,6 +40,7 @@
   enum Mode {
     UNDEFINED_MODE = 0;
     BLOCK = 1;
+    REPORT = 2;
   }
 
   optional DlpPolicyEventSource source = 1;
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_reporting_manager.cc b/chrome/browser/chromeos/policy/dlp/dlp_reporting_manager.cc
index bfb6edf..8c57268 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_reporting_manager.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_reporting_manager.cc
@@ -8,6 +8,8 @@
 
 #include "base/bind.h"
 #include "base/callback_helpers.h"
+#include "base/metrics/histogram_functions.h"
+#include "chrome/browser/chromeos/policy/dlp/dlp_histogram_helper.h"
 #include "chrome/browser/chromeos/policy/dlp/dlp_policy_event.pb.h"
 #include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager.h"
 #include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager_factory.h"
@@ -15,7 +17,6 @@
 #include "chrome/browser/profiles/profile_manager.h"
 #include "components/reporting/client/report_queue.h"
 #include "components/reporting/util/status.h"
-#include "content/public/browser/browser_thread.h"
 #include "url/gurl.h"
 
 namespace policy {
@@ -27,9 +28,10 @@
       return DlpPolicyEvent_Mode_BLOCK;
     case DlpRulesManager::Level::kWarn:
       return DlpPolicyEvent_Mode_BLOCK;
+    case DlpRulesManager::Level::kReport:
+      return DlpPolicyEvent_Mode_REPORT;
     case DlpRulesManager::Level::kNotSet:
-      return DlpPolicyEvent_Mode_UNDEFINED_MODE;
-    default:
+    case DlpRulesManager::Level::kAllow:
       return DlpPolicyEvent_Mode_UNDEFINED_MODE;
   }
 }
@@ -48,11 +50,31 @@
       return DlpPolicyEvent_Restriction_EPRIVACY;
     case DlpRulesManager::Restriction::kClipboard:
       return DlpPolicyEvent_Restriction_CLIPBOARD;
-    default:
+    case DlpRulesManager::Restriction::kFiles:
+    case DlpRulesManager::Restriction::kUnknownRestriction:
       return DlpPolicyEvent_Restriction_UNDEFINED_RESTRICTION;
   }
 }
 
+// TODO(1187477, marcgrimme): revisit if this should be refactored.
+DlpRulesManager::Restriction DlpEventRestriction2DlpRulesManagerRestriction(
+    DlpPolicyEvent_Restriction restriction) {
+  switch (restriction) {
+    case DlpPolicyEvent_Restriction_PRINTING:
+      return DlpRulesManager::Restriction::kPrinting;
+    case DlpPolicyEvent_Restriction_SCREENSHOT:
+      return DlpRulesManager::Restriction::kScreenshot;
+    case DlpPolicyEvent_Restriction_SCREENCAST:
+      return DlpRulesManager::Restriction::kScreenShare;
+    case DlpPolicyEvent_Restriction_EPRIVACY:
+      return DlpRulesManager::Restriction::kPrivacyScreen;
+    case DlpPolicyEvent_Restriction_CLIPBOARD:
+      return DlpRulesManager::Restriction::kClipboard;
+    case DlpPolicyEvent_Restriction_UNDEFINED_RESTRICTION:
+      return DlpRulesManager::Restriction::kUnknownRestriction;
+  }
+}
+
 DlpPolicyEvent CreateDlpPolicyEvent(const std::string& src_pattern,
                                     DlpRulesManager::Restriction restriction,
                                     DlpRulesManager::Level level) {
@@ -117,22 +139,19 @@
 
 DlpReportingManager::ReportQueueSetterCallback
 DlpReportingManager::GetReportQueueSetter() {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   return base::BindOnce(&DlpReportingManager::SetReportQueue,
                         weak_factory_.GetWeakPtr());
 }
 
 void DlpReportingManager::SetReportQueue(
     std::unique_ptr<reporting::ReportQueue> report_queue) {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   report_queue_ = std::move(report_queue);
 }
 
 void DlpReportingManager::ReportEvent(const std::string& src_pattern,
                                       DlpRulesManager::Restriction restriction,
                                       DlpRulesManager::Level level) const {
-  auto event = CreateDlpPolicyEvent(
-      src_pattern, DlpRulesManager::Restriction::kPrinting, level);
+  auto event = CreateDlpPolicyEvent(src_pattern, restriction, level);
   ReportEvent(std::move(event));
 }
 
@@ -160,6 +179,9 @@
     VLOG(1) << "Could not enqueue event to DLP reporting queue because of "
             << status;
   }
+  base::UmaHistogramEnumeration(
+      GetDlpHistogramPrefix() + dlp::kReportedEventStatus, status.code(),
+      reporting::error::Code::MAX_VALUE);
 }
 
 void DlpReportingManager::ReportEvent(DlpPolicyEvent event) const {
@@ -174,6 +196,22 @@
       &DlpReportingManager::OnEventEnqueued, base::Unretained(this));
   report_queue_->Enqueue(&event, reporting::Priority::IMMEDIATE,
                          std::move(callback));
+
+  switch (event.mode()) {
+    case DlpPolicyEvent_Mode_BLOCK:
+      base::UmaHistogramEnumeration(
+          GetDlpHistogramPrefix() + dlp::kReportedBlockLevelRestriction,
+          DlpEventRestriction2DlpRulesManagerRestriction(event.restriction()));
+      break;
+    case DlpPolicyEvent_Mode_REPORT:
+      base::UmaHistogramEnumeration(
+          GetDlpHistogramPrefix() + dlp::kReportedReportLevelRestriction,
+          DlpEventRestriction2DlpRulesManagerRestriction(event.restriction()));
+      break;
+    case DlpPolicyEvent_Mode_UNDEFINED_MODE:
+      NOTREACHED();
+      break;
+  }
 }
 
 }  // namespace policy
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_reporting_manager_test_helper.cc b/chrome/browser/chromeos/policy/dlp/dlp_reporting_manager_test_helper.cc
index 73d0ce5..4fe0227 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_reporting_manager_test_helper.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_reporting_manager_test_helper.cc
@@ -54,9 +54,10 @@
                     reporting::ReportQueue::EnqueueCallback callback) {
             DlpPolicyEvent event;
             event.ParseFromString(std::string(record));
-            // Don't use this code in a multithreaded env as it can course
+            // Don't use this code in a multithreaded env as it can cause
             // concurrency issues with the events in the vector.
             events.push_back(event);
+            std::move(callback).Run(reporting::Status::StatusOK());
           });
   manager->GetReportQueueSetter().Run(std::move(report_queue));
 }
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_reporting_manager_unittest.cc b/chrome/browser/chromeos/policy/dlp/dlp_reporting_manager_unittest.cc
index 964d3852..3111ed08 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_reporting_manager_unittest.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_reporting_manager_unittest.cc
@@ -6,15 +6,12 @@
 
 #include <memory>
 
+#include "base/test/metrics/histogram_tester.h"
+#include "chrome/browser/chromeos/policy/dlp/dlp_histogram_helper.h"
 #include "chrome/browser/chromeos/policy/dlp/dlp_policy_event.pb.h"
 #include "chrome/browser/chromeos/policy/dlp/dlp_reporting_manager_test_helper.h"
 #include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager.h"
-#include "chrome/test/base/testing_profile.h"
-#include "chromeos/dbus/dlp/dlp_service.pb.h"
-#include "components/reporting/client/mock_report_queue.h"
-#include "content/public/browser/web_contents.h"
-#include "content/public/test/browser_task_environment.h"
-#include "content/public/test/web_contents_tester.h"
+#include "components/reporting/util/status.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -33,20 +30,10 @@
 
   void SetUp() override {
     testing::Test::SetUp();
-    profile_ = std::make_unique<TestingProfile>();
     SetReportQueueForReportingManager(&manager_, events_);
   }
 
-  std::unique_ptr<content::WebContents> CreateWebContents() const {
-    return content::WebContentsTester::CreateTestWebContents(profile_.get(),
-                                                             nullptr);
-  }
-
  protected:
-  // BrowserTaskEnvironment needs to be destroyed before TestEnvironment
-  // so that tasks on other threads don't run after they are destroyed.
-  content::BrowserTaskEnvironment task_environment_;
-  std::unique_ptr<TestingProfile> profile_;
   DlpReportingManager manager_;
   std::vector<DlpPolicyEvent> events_;
 };
@@ -87,4 +74,24 @@
                               DlpRulesManager::Level::kBlock)));
 }
 
+TEST_F(DlpReportingManagerTest, MetricsReported) {
+  base::HistogramTester histogram_tester;
+  manager_.ReportEvent(kCompanyPattern, DlpRulesManager::Restriction::kPrinting,
+                       DlpRulesManager::Level::kBlock);
+  manager_.ReportEvent(kCompanyPattern,
+                       DlpRulesManager::Restriction::kScreenshot,
+                       DlpRulesManager::Level::kReport);
+
+  EXPECT_EQ(events_.size(), 2);
+  histogram_tester.ExpectUniqueSample(
+      GetDlpHistogramPrefix() + dlp::kReportedEventStatus,
+      reporting::error::Code::OK, 2);
+  histogram_tester.ExpectUniqueSample(
+      GetDlpHistogramPrefix() + dlp::kReportedBlockLevelRestriction,
+      DlpRulesManager::Restriction::kPrinting, 1);
+  histogram_tester.ExpectUniqueSample(
+      GetDlpHistogramPrefix() + dlp::kReportedReportLevelRestriction,
+      DlpRulesManager::Restriction::kScreenshot, 1);
+}
+
 }  // namespace policy
diff --git a/chrome/browser/chromeos/printing/print_servers_provider.h b/chrome/browser/chromeos/printing/print_servers_provider.h
index c89252a..f305ab20 100644
--- a/chrome/browser/chromeos/printing/print_servers_provider.h
+++ b/chrome/browser/chromeos/printing/print_servers_provider.h
@@ -13,6 +13,7 @@
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "chrome/browser/chromeos/printing/print_server.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class PrefRegistrySimple;
 class PrefService;
diff --git a/chrome/browser/extensions/api/alarms/alarms_apitest.cc b/chrome/browser/extensions/api/alarms/alarms_apitest.cc
index 76e4ec1..e7fa6bbb 100644
--- a/chrome/browser/extensions/api/alarms/alarms_apitest.cc
+++ b/chrome/browser/extensions/api/alarms/alarms_apitest.cc
@@ -26,8 +26,7 @@
     ASSERT_TRUE(StartEmbeddedTestServer());
   }
 
-  static std::unique_ptr<base::ListValue> BuildEventArguments(
-      const bool last_message) {
+  static std::vector<base::Value> BuildEventArguments(const bool last_message) {
     api::test::OnMessage::Info info;
     info.data = "";
     info.last_message = last_message;
diff --git a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc
index 451ad182..7fd31af 100644
--- a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc
+++ b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc
@@ -188,7 +188,7 @@
 void BookmarkManagerPrivateEventRouter::DispatchEvent(
     events::HistogramValue histogram_value,
     const std::string& event_name,
-    std::unique_ptr<base::ListValue> event_args) {
+    std::vector<base::Value> event_args) {
   EventRouter::Get(browser_context_)
       ->BroadcastEvent(std::make_unique<Event>(histogram_value, event_name,
                                                std::move(event_args)));
@@ -251,7 +251,7 @@
 void BookmarkManagerPrivateDragEventRouter::DispatchEvent(
     events::HistogramValue histogram_value,
     const std::string& event_name,
-    std::unique_ptr<base::ListValue> args) {
+    std::vector<base::Value> args) {
   EventRouter* event_router = EventRouter::Get(profile_);
   if (!event_router)
     return;
diff --git a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.h b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.h
index 4067dd53..fe9ab4c 100644
--- a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.h
+++ b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.h
@@ -49,7 +49,7 @@
   // Helper to actually dispatch an event to extension listeners.
   void DispatchEvent(events::HistogramValue histogram_value,
                      const std::string& event_name,
-                     std::unique_ptr<base::ListValue> event_args);
+                     std::vector<base::Value> event_args);
 
   // Remembers the previous meta info of a node before it was changed.
   bookmarks::BookmarkNode::MetaInfoMap prev_meta_info_;
@@ -121,7 +121,7 @@
   // Helper to actually dispatch an event to extension listeners.
   void DispatchEvent(events::HistogramValue histogram_value,
                      const std::string& event_name,
-                     std::unique_ptr<base::ListValue> args);
+                     std::vector<base::Value> args);
 
   content::WebContents* web_contents_;
   Profile* profile_;
diff --git a/chrome/browser/extensions/api/bookmarks/bookmarks_api.cc b/chrome/browser/extensions/api/bookmarks/bookmarks_api.cc
index b851825a..11e9357 100644
--- a/chrome/browser/extensions/api/bookmarks/bookmarks_api.cc
+++ b/chrome/browser/extensions/api/bookmarks/bookmarks_api.cc
@@ -251,10 +251,9 @@
   }
 }
 
-void BookmarkEventRouter::DispatchEvent(
-    events::HistogramValue histogram_value,
-    const std::string& event_name,
-    std::unique_ptr<base::ListValue> event_args) {
+void BookmarkEventRouter::DispatchEvent(events::HistogramValue histogram_value,
+                                        const std::string& event_name,
+                                        std::vector<base::Value> event_args) {
   EventRouter* event_router = EventRouter::Get(browser_context_);
   if (event_router) {
     event_router->BroadcastEvent(std::make_unique<extensions::Event>(
diff --git a/chrome/browser/extensions/api/bookmarks/bookmarks_api.h b/chrome/browser/extensions/api/bookmarks/bookmarks_api.h
index d0a1c66..386683d5 100644
--- a/chrome/browser/extensions/api/bookmarks/bookmarks_api.h
+++ b/chrome/browser/extensions/api/bookmarks/bookmarks_api.h
@@ -14,6 +14,7 @@
 #include <vector>
 
 #include "base/memory/ref_counted.h"
+#include "base/values.h"
 #include "components/bookmarks/browser/base_bookmark_model_observer.h"
 #include "components/bookmarks/browser/bookmark_node.h"
 #include "extensions/browser/browser_context_keyed_api_factory.h"
@@ -25,7 +26,6 @@
 
 namespace base {
 class FilePath;
-class ListValue;
 }
 
 namespace bookmarks {
@@ -88,7 +88,7 @@
   // Helper to actually dispatch an event to extension listeners.
   void DispatchEvent(events::HistogramValue histogram_value,
                      const std::string& event_name,
-                     std::unique_ptr<base::ListValue> event_args);
+                     std::vector<base::Value> event_args);
 
   content::BrowserContext* browser_context_;
   bookmarks::BookmarkModel* model_;
diff --git a/chrome/browser/extensions/api/dashboard_private/dashboard_private_api.cc b/chrome/browser/extensions/api/dashboard_private/dashboard_private_api.cc
index 1cdaca8..2e246fc6 100644
--- a/chrome/browser/extensions/api/dashboard_private/dashboard_private_api.cc
+++ b/chrome/browser/extensions/api/dashboard_private/dashboard_private_api.cc
@@ -175,15 +175,11 @@
 DashboardPrivateShowPermissionPromptForDelegatedInstallFunction::BuildResponse(
     api::dashboard_private::Result result, const std::string& error) {
   // The web store expects an empty string on success.
+  std::vector<base::Value> args =
+      ShowPermissionPromptForDelegatedInstall::Results::Create(result);
   if (result == api::dashboard_private::RESULT_EMPTY_STRING)
-    return ArgumentList(CreateResults(result));
-  return ErrorWithArguments(CreateResults(result), error);
-}
-
-std::unique_ptr<base::ListValue>
-DashboardPrivateShowPermissionPromptForDelegatedInstallFunction::CreateResults(
-    api::dashboard_private::Result result) const {
-  return ShowPermissionPromptForDelegatedInstall::Results::Create(result);
+    return ArgumentList(std::move(args));
+  return ErrorWithArguments(std::move(args), error);
 }
 
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/dashboard_private/dashboard_private_api.h b/chrome/browser/extensions/api/dashboard_private/dashboard_private_api.h
index 93a75ad..08091ee 100644
--- a/chrome/browser/extensions/api/dashboard_private/dashboard_private_api.h
+++ b/chrome/browser/extensions/api/dashboard_private/dashboard_private_api.h
@@ -55,8 +55,6 @@
   ExtensionFunction::ResponseValue BuildResponse(
       api::dashboard_private::Result result,
       const std::string& error);
-  std::unique_ptr<base::ListValue> CreateResults(
-      api::dashboard_private::Result result) const;
 
   const Params::Details& details() const { return params_->details; }
 
diff --git a/chrome/browser/extensions/api/history/history_api.cc b/chrome/browser/extensions/api/history/history_api.cc
index 5ae732d..9fba6ee 100644
--- a/chrome/browser/extensions/api/history/history_api.cc
+++ b/chrome/browser/extensions/api/history/history_api.cc
@@ -168,11 +168,10 @@
                 api::history::OnVisitRemoved::kEventName, std::move(args));
 }
 
-void HistoryEventRouter::DispatchEvent(
-    Profile* profile,
-    events::HistogramValue histogram_value,
-    const std::string& event_name,
-    std::unique_ptr<base::ListValue> event_args) {
+void HistoryEventRouter::DispatchEvent(Profile* profile,
+                                       events::HistogramValue histogram_value,
+                                       const std::string& event_name,
+                                       std::vector<base::Value> event_args) {
   if (profile && EventRouter::Get(profile)) {
     auto event = std::make_unique<Event>(histogram_value, event_name,
                                          std::move(event_args), profile);
diff --git a/chrome/browser/extensions/api/history/history_api.h b/chrome/browser/extensions/api/history/history_api.h
index a140cb8..93a3ace9 100644
--- a/chrome/browser/extensions/api/history/history_api.h
+++ b/chrome/browser/extensions/api/history/history_api.h
@@ -12,6 +12,7 @@
 #include "base/macros.h"
 #include "base/scoped_observation.h"
 #include "base/task/cancelable_task_tracker.h"
+#include "base/values.h"
 #include "chrome/common/extensions/api/history.h"
 #include "components/history/core/browser/history_service.h"
 #include "components/history/core/browser/history_service_observer.h"
@@ -21,10 +22,6 @@
 
 class Profile;
 
-namespace base {
-class ListValue;
-}
-
 namespace extensions {
 
 // Observes History service and routes the notifications as events to the
@@ -48,7 +45,7 @@
   void DispatchEvent(Profile* profile,
                      events::HistogramValue histogram_value,
                      const std::string& event_name,
-                     std::unique_ptr<base::ListValue> event_args);
+                     std::vector<base::Value> event_args);
 
   Profile* profile_;
   base::ScopedObservation<history::HistoryService,
diff --git a/chrome/browser/extensions/api/identity/identity_apitest.cc b/chrome/browser/extensions/api/identity/identity_apitest.cc
index a4b046d..fbd5287 100644
--- a/chrome/browser/extensions/api/identity/identity_apitest.cc
+++ b/chrome/browser/extensions/api/identity/identity_apitest.cc
@@ -3520,7 +3520,7 @@
   // been added. This is because the order of multiple events firing due to the
   // same underlying state change is undefined in the
   // chrome.identity.onSignInEventChanged() API.
-  void AddExpectedEvent(std::unique_ptr<base::ListValue> args) {
+  void AddExpectedEvent(std::vector<base::Value> args) {
     expected_events_.insert(
         std::make_unique<Event>(events::IDENTITY_ON_SIGN_IN_CHANGED,
                                 api::identity::OnSignInChanged::kEventName,
diff --git a/chrome/browser/extensions/api/input_ime/input_ime_api.h b/chrome/browser/extensions/api/input_ime/input_ime_api.h
index 518e0d5..77b33c8 100644
--- a/chrome/browser/extensions/api/input_ime/input_ime_api.h
+++ b/chrome/browser/extensions/api/input_ime/input_ime_api.h
@@ -73,7 +73,7 @@
   virtual void DispatchEventToExtension(
       extensions::events::HistogramValue histogram_value,
       const std::string& event_name,
-      std::unique_ptr<base::ListValue> args) = 0;
+      std::vector<base::Value> args) = 0;
 
   // Returns the type of the current screen.
   virtual std::string GetCurrentScreenType() = 0;
diff --git a/chrome/browser/extensions/api/input_ime/input_ime_api_chromeos.cc b/chrome/browser/extensions/api/input_ime/input_ime_api_chromeos.cc
index e12b07b3..0fc30e2 100644
--- a/chrome/browser/extensions/api/input_ime/input_ime_api_chromeos.cc
+++ b/chrome/browser/extensions/api/input_ime/input_ime_api_chromeos.cc
@@ -213,8 +213,8 @@
       return;
     }
     // Note: this is a private API event.
-    std::unique_ptr<base::ListValue> args(new base::ListValue());
-    args->Append(std::make_unique<base::Value>(is_projected));
+    std::vector<base::Value> args;
+    args.push_back(base::Value(is_projected));
 
     DispatchEventToExtension(
         extensions::events::INPUT_METHOD_PRIVATE_ON_SCREEN_PROJECTION_CHANGED,
@@ -223,31 +223,29 @@
 
   void OnCompositionBoundsChanged(
       const std::vector<gfx::Rect>& bounds) override {
-    if (extension_id_.empty() ||
-        !HasListener(OnCompositionBoundsChanged::kEventName))
+    if (bounds.empty() || extension_id_.empty() ||
+        !HasListener(OnCompositionBoundsChanged::kEventName)) {
       return;
-
-    // Note: this is a private API event.
-    auto bounds_list = std::make_unique<base::ListValue>();
-    for (auto bound : bounds) {
-      auto bounds_value = std::make_unique<base::DictionaryValue>();
-      bounds_value->SetInteger("x", bound.x());
-      bounds_value->SetInteger("y", bound.y());
-      bounds_value->SetInteger("w", bound.width());
-      bounds_value->SetInteger("h", bound.height());
-      bounds_list->Append(std::move(bounds_value));
     }
 
-    if (bounds_list->GetSize() <= 0)
-      return;
-    std::unique_ptr<base::ListValue> args(new base::ListValue());
+    // Note: this is a private API event.
+    std::vector<base::Value> bounds_list;
+    bounds_list.reserve(bounds.size());
+    for (const auto& bound : bounds) {
+      base::Value bounds_value(base::Value::Type::DICTIONARY);
+      bounds_value.SetIntKey("x", bound.x());
+      bounds_value.SetIntKey("y", bound.y());
+      bounds_value.SetIntKey("w", bound.width());
+      bounds_value.SetIntKey("h", bound.height());
+      bounds_list.push_back(std::move(bounds_value));
+    }
+
+    std::vector<base::Value> args;
 
     // The old extension code uses the first parameter to get the bounds of the
     // first composition character, so for backward compatibility, add it here.
-    base::Value* first_value = NULL;
-    if (bounds_list->Get(0, &first_value))
-      args->Append(first_value->Clone());
-    args->Append(std::move(bounds_list));
+    args.push_back(bounds_list[0].Clone());
+    args.push_back(base::Value(std::move(bounds_list)));
 
     DispatchEventToExtension(
         extensions::events::INPUT_METHOD_PRIVATE_ON_COMPOSITION_BOUNDS_CHANGED,
@@ -337,7 +335,7 @@
   void DispatchEventToExtension(
       extensions::events::HistogramValue histogram_value,
       const std::string& event_name,
-      std::unique_ptr<base::ListValue> args) override {
+      std::vector<base::Value> args) override {
     if (event_name == input_ime::OnActivate::kEventName) {
       // Send onActivate event regardless of it's listened by the IME.
       auto event = std::make_unique<extensions::Event>(
diff --git a/chrome/browser/extensions/api/passwords_private/passwords_private_event_router.cc b/chrome/browser/extensions/api/passwords_private/passwords_private_event_router.cc
index 100d75d0..efb17bf 100644
--- a/chrome/browser/extensions/api/passwords_private/passwords_private_event_router.cc
+++ b/chrome/browser/extensions/api/passwords_private/passwords_private_event_router.cc
@@ -38,14 +38,14 @@
 }
 
 void PasswordsPrivateEventRouter::SendSavedPasswordListToListeners() {
-  if (!cached_saved_password_parameters_.get())
+  if (!cached_saved_password_parameters_.has_value())
     // If there is nothing to send, return early.
     return;
 
   auto extension_event = std::make_unique<Event>(
       events::PASSWORDS_PRIVATE_ON_SAVED_PASSWORDS_LIST_CHANGED,
       api::passwords_private::OnSavedPasswordsListChanged::kEventName,
-      cached_saved_password_parameters_->CreateDeepCopy());
+      base::Value(cached_saved_password_parameters_.value()).TakeList());
   event_router_->BroadcastEvent(std::move(extension_event));
 }
 
@@ -58,14 +58,14 @@
 }
 
 void PasswordsPrivateEventRouter::SendPasswordExceptionListToListeners() {
-  if (!cached_password_exception_parameters_.get())
+  if (!cached_password_exception_parameters_.has_value())
     // If there is nothing to send, return early.
     return;
 
   auto extension_event = std::make_unique<Event>(
       events::PASSWORDS_PRIVATE_ON_PASSWORD_EXCEPTIONS_LIST_CHANGED,
       api::passwords_private::OnPasswordExceptionsListChanged::kEventName,
-      cached_password_exception_parameters_->CreateDeepCopy());
+      base::Value(cached_password_exception_parameters_.value()).TakeList());
   event_router_->BroadcastEvent(std::move(extension_event));
 }
 
diff --git a/chrome/browser/extensions/api/passwords_private/passwords_private_event_router.h b/chrome/browser/extensions/api/passwords_private/passwords_private_event_router.h
index 6d23e9e2..af834e8 100644
--- a/chrome/browser/extensions/api/passwords_private/passwords_private_event_router.h
+++ b/chrome/browser/extensions/api/passwords_private/passwords_private_event_router.h
@@ -5,14 +5,15 @@
 #ifndef CHROME_BROWSER_EXTENSIONS_API_PASSWORDS_PRIVATE_PASSWORDS_PRIVATE_EVENT_ROUTER_H_
 #define CHROME_BROWSER_EXTENSIONS_API_PASSWORDS_PRIVATE_PASSWORDS_PRIVATE_EVENT_ROUTER_H_
 
-#include <memory>
 #include <string>
 #include <vector>
 
 #include "base/macros.h"
+#include "base/values.h"
 #include "chrome/common/extensions/api/passwords_private.h"
 #include "components/keyed_service/core/keyed_service.h"
 #include "extensions/browser/event_router.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace content {
 class BrowserContext;
@@ -85,8 +86,9 @@
 
   // Cached parameters which are saved so that when new listeners are added, the
   // most up-to-date lists can be sent to them immediately.
-  std::unique_ptr<base::ListValue> cached_saved_password_parameters_;
-  std::unique_ptr<base::ListValue> cached_password_exception_parameters_;
+  absl::optional<std::vector<base::Value>> cached_saved_password_parameters_;
+  absl::optional<std::vector<base::Value>>
+      cached_password_exception_parameters_;
 
   DISALLOW_COPY_AND_ASSIGN(PasswordsPrivateEventRouter);
 };
diff --git a/chrome/browser/extensions/api/platform_keys/platform_keys_api_ash.cc b/chrome/browser/extensions/api/platform_keys/platform_keys_api_ash.cc
index 582568f..e39d7de 100644
--- a/chrome/browser/extensions/api/platform_keys/platform_keys_api_ash.cc
+++ b/chrome/browser/extensions/api/platform_keys/platform_keys_api_ash.cc
@@ -22,6 +22,7 @@
 #include "chrome/browser/extensions/api/platform_keys/verify_trust_api.h"
 #include "chrome/common/extensions/api/platform_keys_internal.h"
 #include "chromeos/crosapi/cpp/keystore_service_util.h"
+#include "chromeos/crosapi/mojom/keystore_error.mojom.h"
 #include "components/web_modal/web_contents_modal_dialog_manager.h"
 #include "content/public/browser/browser_thread.h"
 #include "net/base/net_errors.h"
@@ -348,14 +349,16 @@
 
 void PlatformKeysInternalSignFunction::OnSigned(
     const std::string& signature,
-    chromeos::platform_keys::Status status) {
+    absl::optional<crosapi::mojom::KeystoreError> error) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
-  if (status == chromeos::platform_keys::Status::kSuccess)
+  if (!error) {
     Respond(ArgumentList(api_pki::Sign::Results::Create(
         std::vector<uint8_t>(signature.begin(), signature.end()))));
-  else
-    Respond(Error(chromeos::platform_keys::StatusToString(status)));
+  } else {
+    Respond(
+        Error(chromeos::platform_keys::KeystoreErrorToString(error.value())));
+  }
 }
 
 PlatformKeysVerifyTLSServerCertificateFunction::
diff --git a/chrome/browser/extensions/api/platform_keys/platform_keys_api_ash.h b/chrome/browser/extensions/api/platform_keys/platform_keys_api_ash.h
index f32909b..9bae32ee 100644
--- a/chrome/browser/extensions/api/platform_keys/platform_keys_api_ash.h
+++ b/chrome/browser/extensions/api/platform_keys/platform_keys_api_ash.h
@@ -9,6 +9,7 @@
 #include <vector>
 
 #include "chrome/browser/chromeos/platform_keys/platform_keys.h"
+#include "chromeos/crosapi/mojom/keystore_error.mojom.h"
 #include "extensions/browser/extension_function.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
@@ -77,7 +78,7 @@
   // Called when the signature was generated. If an error occurred,
   // |signature| will be empty.
   void OnSigned(const std::string& signature,
-                chromeos::platform_keys::Status status);
+                absl::optional<crosapi::mojom::KeystoreError> error);
 
   DECLARE_EXTENSION_FUNCTION("platformKeysInternal.sign",
                              PLATFORMKEYSINTERNAL_SIGN)
diff --git a/chrome/browser/extensions/api/processes/processes_api.cc b/chrome/browser/extensions/api/processes/processes_api.cc
index 133eaa8..5465a7c 100644
--- a/chrome/browser/extensions/api/processes/processes_api.cc
+++ b/chrome/browser/extensions/api/processes/processes_api.cc
@@ -342,7 +342,7 @@
 void ProcessesEventRouter::DispatchEvent(
     events::HistogramValue histogram_value,
     const std::string& event_name,
-    std::unique_ptr<base::ListValue> event_args) const {
+    std::vector<base::Value> event_args) const {
   EventRouter* event_router = EventRouter::Get(browser_context_);
   if (event_router) {
     std::unique_ptr<Event> event(
diff --git a/chrome/browser/extensions/api/processes/processes_api.h b/chrome/browser/extensions/api/processes/processes_api.h
index f72d0525..0f389faa 100644
--- a/chrome/browser/extensions/api/processes/processes_api.h
+++ b/chrome/browser/extensions/api/processes/processes_api.h
@@ -8,6 +8,7 @@
 #include <vector>
 
 #include "base/macros.h"
+#include "base/values.h"
 #include "chrome/browser/task_manager/task_manager_observer.h"
 #include "extensions/browser/browser_context_keyed_api_factory.h"
 #include "extensions/browser/event_router.h"
@@ -44,7 +45,7 @@
 
   void DispatchEvent(events::HistogramValue histogram_value,
                      const std::string& event_name,
-                     std::unique_ptr<base::ListValue> event_args) const;
+                     std::vector<base::Value> event_args) const;
 
   // Determines whether there is a registered listener for the specified event.
   // It helps to avoid collecting data if no one is interested in it.
diff --git a/chrome/browser/extensions/api/tab_groups/tab_groups_event_router.cc b/chrome/browser/extensions/api/tab_groups/tab_groups_event_router.cc
index 22cdf8c9..efc4e7b 100644
--- a/chrome/browser/extensions/api/tab_groups/tab_groups_event_router.cc
+++ b/chrome/browser/extensions/api/tab_groups/tab_groups_event_router.cc
@@ -92,10 +92,9 @@
                 api::tab_groups::OnUpdated::kEventName, std::move(args));
 }
 
-void TabGroupsEventRouter::DispatchEvent(
-    events::HistogramValue histogram_value,
-    const std::string& event_name,
-    std::unique_ptr<base::ListValue> args) {
+void TabGroupsEventRouter::DispatchEvent(events::HistogramValue histogram_value,
+                                         const std::string& event_name,
+                                         std::vector<base::Value> args) {
   // |event_router_| can be null in tests.
   if (!event_router_)
     return;
diff --git a/chrome/browser/extensions/api/tab_groups/tab_groups_event_router.h b/chrome/browser/extensions/api/tab_groups/tab_groups_event_router.h
index 0b6ecff..1c1bbd2f 100644
--- a/chrome/browser/extensions/api/tab_groups/tab_groups_event_router.h
+++ b/chrome/browser/extensions/api/tab_groups/tab_groups_event_router.h
@@ -5,9 +5,10 @@
 #ifndef CHROME_BROWSER_EXTENSIONS_API_TAB_GROUPS_TAB_GROUPS_EVENT_ROUTER_H_
 #define CHROME_BROWSER_EXTENSIONS_API_TAB_GROUPS_TAB_GROUPS_EVENT_ROUTER_H_
 
-#include <memory>
 #include <string>
+#include <vector>
 
+#include "base/values.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser_list_observer.h"
 #include "chrome/browser/ui/browser_tab_strip_tracker.h"
@@ -46,7 +47,7 @@
 
   void DispatchEvent(events::HistogramValue histogram_value,
                      const std::string& event_name,
-                     std::unique_ptr<base::ListValue> args);
+                     std::vector<base::Value> args);
 
   Profile* const profile_;
   EventRouter* const event_router_ = nullptr;
diff --git a/chrome/browser/extensions/api/tabs/tabs_api.cc b/chrome/browser/extensions/api/tabs/tabs_api.cc
index 44546d5..c91d8c49 100644
--- a/chrome/browser/extensions/api/tabs/tabs_api.cc
+++ b/chrome/browser/extensions/api/tabs/tabs_api.cc
@@ -1264,12 +1264,12 @@
   // Return the caller, if it's a tab. If not the result isn't an error but an
   // empty tab (hence returning true).
   WebContents* caller_contents = GetSenderWebContents();
-  std::unique_ptr<base::ListValue> results;
   if (caller_contents && ExtensionTabUtil::GetTabId(caller_contents) >= 0) {
-    results = tabs::Get::Results::Create(*CreateTabObjectHelper(
-        caller_contents, extension(), source_context_type(), nullptr, -1));
+    return RespondNow(ArgumentList(tabs::Get::Results::Create(
+        *CreateTabObjectHelper(caller_contents, extension(),
+                               source_context_type(), nullptr, -1))));
   }
-  return RespondNow(results ? ArgumentList(std::move(results)) : NoArguments());
+  return RespondNow(NoArguments());
 }
 
 ExtensionFunction::ResponseAction TabsHighlightFunction::Run() {
diff --git a/chrome/browser/extensions/api/tabs/tabs_event_router.cc b/chrome/browser/extensions/api/tabs/tabs_event_router.cc
index fe6486e..1f9012a 100644
--- a/chrome/browser/extensions/api/tabs/tabs_event_router.cc
+++ b/chrome/browser/extensions/api/tabs/tabs_event_router.cc
@@ -290,7 +290,8 @@
       Profile::FromBrowserContext(data.web_contents->GetBrowserContext());
   DispatchEvent(profile, events::TABS_ON_ZOOM_CHANGE,
                 api::tabs::OnZoomChange::kEventName,
-                api::tabs::OnZoomChange::Create(zoom_change_info),
+                std::make_unique<base::ListValue>(
+                    api::tabs::OnZoomChange::Create(zoom_change_info)),
                 EventRouter::USER_GESTURE_UNKNOWN);
 }
 
diff --git a/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc b/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc
index eefa450..26e69a0 100644
--- a/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc
+++ b/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc
@@ -814,19 +814,15 @@
 WebstorePrivateBeginInstallWithManifest3Function::BuildResponse(
     api::webstore_private::Result result,
     const std::string& error) {
-  if (result != api::webstore_private::RESULT_SUCCESS)
-    return ErrorWithArguments(CreateResults(result), error);
+  if (result != api::webstore_private::RESULT_SUCCESS) {
+    return ErrorWithArguments(
+        BeginInstallWithManifest3::Results::Create(result), error);
+  }
 
   // The web store expects an empty string on success, so don't use
   // RESULT_SUCCESS here.
-  return ArgumentList(
-      CreateResults(api::webstore_private::RESULT_EMPTY_STRING));
-}
-
-std::unique_ptr<base::ListValue>
-WebstorePrivateBeginInstallWithManifest3Function::CreateResults(
-    api::webstore_private::Result result) const {
-  return BeginInstallWithManifest3::Results::Create(result);
+  return ArgumentList(BeginInstallWithManifest3::Results::Create(
+      api::webstore_private::RESULT_EMPTY_STRING));
 }
 
 bool WebstorePrivateBeginInstallWithManifest3Function::ShouldShowFrictionDialog(
diff --git a/chrome/browser/extensions/api/webstore_private/webstore_private_api.h b/chrome/browser/extensions/api/webstore_private/webstore_private_api.h
index d21e0bc2..9f9477c 100644
--- a/chrome/browser/extensions/api/webstore_private/webstore_private_api.h
+++ b/chrome/browser/extensions/api/webstore_private/webstore_private_api.h
@@ -112,8 +112,6 @@
   ExtensionFunction::ResponseValue BuildResponse(
       api::webstore_private::Result result,
       const std::string& error);
-  std::unique_ptr<base::ListValue> CreateResults(
-      api::webstore_private::Result result) const;
 
   bool ShouldShowFrictionDialog(Profile* profile);
   void ShowInstallFrictionDialog(content::WebContents* contents);
diff --git a/chrome/browser/federated_learning/floc_eligibility_browsertest.cc b/chrome/browser/federated_learning/floc_eligibility_browsertest.cc
index cb89a7b..d08d1a5 100644
--- a/chrome/browser/federated_learning/floc_eligibility_browsertest.cc
+++ b/chrome/browser/federated_learning/floc_eligibility_browsertest.cc
@@ -46,6 +46,10 @@
   }
 
   void MaybeRecordFlocToUkm(ukm::SourceId source_id) override {}
+
+  base::Time GetApproximateNextComputeTime() const override {
+    return base::Time();
+  }
 };
 
 }  // namespace
diff --git a/chrome/browser/federated_learning/floc_id_provider.h b/chrome/browser/federated_learning/floc_id_provider.h
index ce4a6991..164e92e2 100644
--- a/chrome/browser/federated_learning/floc_id_provider.h
+++ b/chrome/browser/federated_learning/floc_id_provider.h
@@ -32,6 +32,12 @@
   // recorded to UKM before.
   virtual void MaybeRecordFlocToUkm(ukm::SourceId source_id) = 0;
 
+  // Returns the approximate time the floc will be next computed. This is not
+  // a guaranetee that floc computation will run at the returned time. The
+  // accuracy of the return value also cannot be guaranteed, for example it will
+  // return current time if a computation is currently in progress.
+  virtual base::Time GetApproximateNextComputeTime() const = 0;
+
   ~FlocIdProvider() override = default;
 };
 
diff --git a/chrome/browser/federated_learning/floc_id_provider_impl.cc b/chrome/browser/federated_learning/floc_id_provider_impl.cc
index 568a5c5..6df8d8f 100644
--- a/chrome/browser/federated_learning/floc_id_provider_impl.cc
+++ b/chrome/browser/federated_learning/floc_id_provider_impl.cc
@@ -164,6 +164,15 @@
   need_ukm_recording_ = false;
 }
 
+base::Time FlocIdProviderImpl::GetApproximateNextComputeTime() const {
+  if (!compute_floc_timer_.IsRunning())
+    return base::Time::Now();
+
+  // Convert the TimeTicks type the timer provides to base::Time.
+  return base::Time::Now() +
+         (compute_floc_timer_.desired_run_time() - base::TimeTicks::Now());
+}
+
 void FlocIdProviderImpl::OnComputeFlocCompleted(ComputeFlocResult result) {
   DCHECK(floc_computation_in_progress_);
   floc_computation_in_progress_ = false;
diff --git a/chrome/browser/federated_learning/floc_id_provider_impl.h b/chrome/browser/federated_learning/floc_id_provider_impl.h
index 9b0c25788..6be5b4b3 100644
--- a/chrome/browser/federated_learning/floc_id_provider_impl.h
+++ b/chrome/browser/federated_learning/floc_id_provider_impl.h
@@ -96,6 +96,8 @@
 
   void MaybeRecordFlocToUkm(ukm::SourceId source_id) override;
 
+  base::Time GetApproximateNextComputeTime() const override;
+
  protected:
   // protected virtual for testing.
   virtual void OnComputeFlocCompleted(ComputeFlocResult result);
diff --git a/chrome/browser/federated_learning/floc_id_provider_unittest.cc b/chrome/browser/federated_learning/floc_id_provider_unittest.cc
index 67af0b5..60e8b6e 100644
--- a/chrome/browser/federated_learning/floc_id_provider_unittest.cc
+++ b/chrome/browser/federated_learning/floc_id_provider_unittest.cc
@@ -344,17 +344,23 @@
   InitializeFlocIdProvider();
   EXPECT_FALSE(floc_computation_in_progress());
   EXPECT_FALSE(floc_computation_scheduled());
+  EXPECT_EQ(base::Time::Now(),
+            floc_id_provider_->GetApproximateNextComputeTime());
 
   // Configure the sorting-lsh service to to trigger the 1st floc computation.
   sorting_lsh_service_->ConfigureSortingLsh(base::Version("2.0.0"));
   EXPECT_TRUE(floc_computation_in_progress());
   EXPECT_FALSE(floc_computation_scheduled());
+  EXPECT_EQ(base::Time::Now(),
+            floc_id_provider_->GetApproximateNextComputeTime());
 
   // Finish any outstanding history queries.
   task_environment_.RunUntilIdle();
 
   EXPECT_FALSE(floc_computation_in_progress());
   EXPECT_TRUE(floc_computation_scheduled());
+  EXPECT_EQ(base::Time::Now() + base::TimeDelta::FromDays(7),
+            floc_id_provider_->GetApproximateNextComputeTime());
   EXPECT_EQ(1u, floc_id_provider_->compute_floc_completed_count());
   EXPECT_EQ(1u, floc_id_provider_->log_event_count());
 
@@ -750,6 +756,8 @@
   task_environment_.RunUntilIdle();
   EXPECT_EQ(1u, floc_id_provider_->compute_floc_completed_count());
   EXPECT_EQ(base::Time::Now(), FlocId::ReadFromPrefs(&prefs_).compute_time());
+  EXPECT_EQ(base::Time::Now() + base::TimeDelta::FromDays(1),
+            floc_id_provider_->GetApproximateNextComputeTime());
 
   // Move the clock forward 20 hours and update the floc available time,
   // selecting to reset the compute timer.
@@ -757,6 +765,8 @@
   OnFlocDataAccessibleSinceUpdated(/*reset_compute_timer=*/true);
   const base::Time kResetComputeTime = base::Time::Now();
   EXPECT_EQ(kResetComputeTime, FlocId::ReadFromPrefs(&prefs_).compute_time());
+  EXPECT_EQ(base::Time::Now() + base::TimeDelta::FromDays(1),
+            floc_id_provider_->GetApproximateNextComputeTime());
 
   // Move the clock forward another 20 hours, moving past the default refresh
   // interval of 24 hours. A new floc id should not have been computed as the
@@ -764,17 +774,23 @@
   task_environment_.FastForwardBy(base::TimeDelta::FromHours(20));
   task_environment_.RunUntilIdle();
   EXPECT_EQ(1u, floc_id_provider_->compute_floc_completed_count());
+  EXPECT_EQ(base::Time::Now() + base::TimeDelta::FromHours(4),
+            floc_id_provider_->GetApproximateNextComputeTime());
 
   // Update the floc available time without resetting compute time.
   OnFlocDataAccessibleSinceUpdated(
       /*reset_compute_timer=*/false);
   EXPECT_EQ(kResetComputeTime, FlocId::ReadFromPrefs(&prefs_).compute_time());
+  EXPECT_EQ(base::Time::Now() + base::TimeDelta::FromHours(4),
+            floc_id_provider_->GetApproximateNextComputeTime());
 
   // Move the clock forward 5 hours, making 25 hours since the compute timer was
   // reset, a new floc id should have been computed.
   task_environment_.FastForwardBy(base::TimeDelta::FromHours(5));
   task_environment_.RunUntilIdle();
   EXPECT_EQ(2u, floc_id_provider_->compute_floc_completed_count());
+  EXPECT_EQ(base::Time::Now() + base::TimeDelta::FromHours(23),
+            floc_id_provider_->GetApproximateNextComputeTime());
 }
 
 TEST_F(FlocIdProviderSimpleFeatureParamUnitTest, HistoryDelete_AllHistory) {
@@ -1132,6 +1148,8 @@
   task_environment_.FastForwardBy(base::TimeDelta::FromDays(1));
 
   EXPECT_TRUE(floc_computation_in_progress());
+  EXPECT_EQ(base::Time::Now(),
+            floc_id_provider_->GetApproximateNextComputeTime());
   EXPECT_FALSE(need_recompute());
   EXPECT_EQ(FlocIdTester::Create(
                 FlocId::SimHashHistory({"foo.com", "bar.com", "baz.com"}),
@@ -1160,6 +1178,8 @@
   EXPECT_EQ(3u, floc_id_provider_->compute_floc_completed_count());
   EXPECT_EQ(2u, floc_id_provider_->log_event_count());
   EXPECT_FALSE(need_recompute());
+  EXPECT_EQ(base::Time::Now() + base::TimeDelta::FromDays(1),
+            floc_id_provider_->GetApproximateNextComputeTime());
 
   // The final floc should be derived from "baz.com".
   EXPECT_TRUE(floc_id().IsValid());
@@ -1437,12 +1457,16 @@
   EXPECT_FALSE(floc_computation_in_progress());
   EXPECT_FALSE(floc_computation_scheduled());
   EXPECT_EQ(0u, floc_id_provider_->compute_floc_completed_count());
+  EXPECT_EQ(base::Time::Now(),
+            floc_id_provider_->GetApproximateNextComputeTime());
 
   // Set up the sorting-lsh service to trigger the 1st floc computation.
   sorting_lsh_service_->ConfigureSortingLsh(base::Version("99.0"));
   task_environment_.RunUntilIdle();
   EXPECT_FALSE(floc_computation_in_progress());
   EXPECT_TRUE(floc_computation_scheduled());
+  EXPECT_EQ(base::Time::Now() + base::TimeDelta::FromDays(1),
+            floc_id_provider_->GetApproximateNextComputeTime());
 
   // Expect a completed computation and an update to the local prefs.
   EXPECT_EQ(1u, floc_id_provider_->compute_floc_completed_count());
@@ -1487,6 +1511,8 @@
   EXPECT_EQ(FlocId::ReadFromPrefs(&prefs_), initial_invalid_floc_id);
   EXPECT_FALSE(floc_computation_in_progress());
   EXPECT_FALSE(floc_computation_scheduled());
+  EXPECT_EQ(base::Time::Now(),
+            floc_id_provider_->GetApproximateNextComputeTime());
   EXPECT_EQ(0u, floc_id_provider_->compute_floc_completed_count());
 
   // Set up the sorting-lsh service to trigger the 1st floc computation.
@@ -1494,6 +1520,8 @@
   task_environment_.RunUntilIdle();
   EXPECT_FALSE(floc_computation_in_progress());
   EXPECT_TRUE(floc_computation_scheduled());
+  EXPECT_EQ(base::Time::Now() + base::TimeDelta::FromDays(1),
+            floc_id_provider_->GetApproximateNextComputeTime());
 
   // Expect a completed computation and an update to the local prefs.
   EXPECT_EQ(1u, floc_id_provider_->compute_floc_completed_count());
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index ffae604b..c74f3e07 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -1155,6 +1155,11 @@
     "expiry_milestone": 93
   },
   {
+    "name": "download-shelf-webui",
+    "owners": [ "robliao", "chrome-webui-for-features@google.com" ],
+    "expiry_milestone": 98
+  },
+  {
     "name": "draw-predicted-ink-point",
     "owners": [ "mabian@microsoft.com" ],
     "expiry_milestone": 95
@@ -1410,7 +1415,7 @@
   },
   {
     "name": "enable-bluetooth-spp-in-serial-api",
-    "owners": [ "mattreynolds", "odejesush", "vickymin@google.com" ],
+    "owners": [ "mattreynolds", "odejesush" ],
     "expiry_milestone": 90
   },
   {
@@ -2531,7 +2536,7 @@
   {
     "name": "enable-translate-sub-frames",
     "owners": [ "sclittle", "chrome-language@google.com" ],
-    "expiry_milestone": 90
+    "expiry_milestone": 96
   },
   {
     "name": "enable-ui-devtools",
@@ -2867,7 +2872,7 @@
   },
   {
     "name": "files-trash",
-    "owners": [ "joelhockey", "noel", "simmonsjosh" ],
+    "owners": [ "joelhockey", "noel", "simmonsjosh@google.com" ],
     "expiry_milestone": 95
   },
   {
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 629471d..60c5a96 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -4939,6 +4939,10 @@
     "Snoozing an in-product help promo closes it and schedules it to be shown "
     "later. When enabled, this functionality is allowed on supported promos.";
 
+const char kDownloadShelfWebUI[] = "Download Shelf WebUI";
+const char kDownloadShelfWebUIDescription[] =
+    "Replaces the Views download shelf with a WebUI download shelf.";
+
 const char kEnableMDRoundedCornersOnDialogsName[] =
     "MD corners on secondary UI";
 const char kEnableMDRoundedCornersOnDialogsDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 9b8d736..9f38272 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -2885,12 +2885,14 @@
 extern const char kDesktopInProductHelpSnoozeName[];
 extern const char kDesktopInProductHelpSnoozeDescription[];
 
+extern const char kDownloadShelfWebUI[];
+extern const char kDownloadShelfWebUIDescription[];
+
 extern const char kEnableMDRoundedCornersOnDialogsName[];
 extern const char kEnableMDRoundedCornersOnDialogsDescription[];
 
 extern const char kInstallableInkDropName[];
 extern const char kInstallableInkDropDescription[];
-
 #endif  // defined(TOOLKIT_VIEWS)
 
 // Random platform combinations -----------------------------------------------
diff --git a/chrome/browser/lacros/keystore_service_lacros_browsertest.cc b/chrome/browser/lacros/keystore_service_lacros_browsertest.cc
index 55637a58..3490647d 100644
--- a/chrome/browser/lacros/keystore_service_lacros_browsertest.cc
+++ b/chrome/browser/lacros/keystore_service_lacros_browsertest.cc
@@ -5,16 +5,22 @@
 #include <string>
 
 #include "chrome/test/base/in_process_browser_test.h"
+#include "chromeos/crosapi/mojom/keystore_service.mojom-shared.h"
 #include "chromeos/crosapi/mojom/keystore_service.mojom-test-utils.h"
 #include "chromeos/crosapi/mojom/keystore_service.mojom.h"
 #include "chromeos/lacros/lacros_service.h"
 #include "content/public/test/browser_test.h"
 
-// During GenerateKey* call this error means that the key was created, but
-// Ash-Chrome failed to tag it properly. It happens because Ash-Chrome is trying
-// to work with the real NSS, but in browser tests (i.e. on Linux) it doesn't
-// work the same way as on ChromeOS.
+// During ExtensionGenerateKey* call this error means that the key was created,
+// but Ash-Chrome failed to tag it properly. It happens because Ash-Chrome is
+// trying to work with the real NSS, but in browser tests (i.e. on Linux) it
+// doesn't work the same way as on ChromeOS.
 const char kFailedToSetAttribute[] = "Setting key attribute value failed.";
+// During ExtensionSign call this error means that Ash-Chrome wasn't able to
+// find the key in a list of allowed keys.
+const char kErrorKeyNotAllowedForSigning[] =
+    "This key is not allowed for signing. Either it was used for "
+    "signing before or it was not correctly generated.";
 
 // This class provides integration testing for the keystore service crosapi.
 // TODO(https://crbug.com/1134340): The logic being tested does not rely on
@@ -64,7 +70,7 @@
   EXPECT_EQ(0u, result->get_certificates().size());
 }
 
-// Tests that generate key works.
+// Tests that extension generate key works.
 IN_PROC_BROWSER_TEST_F(KeystoreServiceLacrosBrowserTest,
                        ExtensionGenerateKeyPKCS) {
   crosapi::mojom::ExtensionKeystoreBinaryResultPtr result;
@@ -109,6 +115,23 @@
   EXPECT_EQ(result->get_error_message(), kFailedToSetAttribute);
 }
 
+// Tests that extension sign works.
+IN_PROC_BROWSER_TEST_F(KeystoreServiceLacrosBrowserTest, ExtensionSign) {
+  crosapi::mojom::ExtensionKeystoreBinaryResultPtr result;
+  crosapi::mojom::KeystoreServiceAsyncWaiter async_waiter(
+      keystore_service_remote().get());
+  async_waiter.ExtensionSign(
+      crosapi::mojom::KeystoreType::kUser,
+      /*public_key=*/{1, 2, 3, 4, 5},
+      /*scheme=*/crosapi::mojom::KeystoreSigningScheme::kRsassaPkcs1V15Sha256,
+      /*data=*/{10, 11, 12, 13, 14, 15},
+      /*extension_id=*/"123", &result);
+  // Errors out because the public key is not valid. Currently there's no way to
+  // create a valid key in Ash-Chrome during browser tests.
+  ASSERT_TRUE(result->is_error_message());
+  EXPECT_EQ(result->get_error_message(), kErrorKeyNotAllowedForSigning);
+}
+
 // Tests that trying to add/remove an incorrectly formatted certificate results
 // in failure.
 IN_PROC_BROWSER_TEST_F(KeystoreServiceLacrosBrowserTest, CertificateBadFormat) {
diff --git a/chrome/browser/media/encrypted_media_supported_types_browsertest.cc b/chrome/browser/media/encrypted_media_supported_types_browsertest.cc
index 3977d984..9be1f9f 100644
--- a/chrome/browser/media/encrypted_media_supported_types_browsertest.cc
+++ b/chrome/browser/media/encrypted_media_supported_types_browsertest.cc
@@ -481,9 +481,10 @@
   void SetUpCommandLine(base::CommandLine* command_line) override {
     EncryptedMediaSupportedTypesWidevineTest::SetUpCommandLine(command_line);
     // Pretend that we support hardware secure decryption for vp8 and vp9, but
-    // not for avc1.
+    // not for avc1. This will also pretend that there is support for vorbis
+    // audio.
     command_line->AppendSwitchASCII(
-        switches::kOverrideHardwareSecureCodecsForTesting, "vp8,vp9");
+        switches::kOverrideHardwareSecureCodecsForTesting, "vp8,vp9,vorbis");
   }
 
  private:
@@ -1256,24 +1257,25 @@
 #endif
 
   // Audio proprietary codecs.
-  // Note that "hardware secure audio" is still supported since hardware secure
-  // decryption is supported (because hardware vp8 and vp9 are supported), and
-  // we only do decrypt-only for audio.
+  // "SW_SECURE_CRYPTO" is always supported.
   EXPECT_WV_PROPRIETARY(
       IsAudioMp4RobustnessSupported(kWidevine, "SW_SECURE_CRYPTO"));
-  EXPECT_WV_PROPRIETARY(
-      IsAudioMp4RobustnessSupported(kWidevine, "HW_SECURE_CRYPTO"));
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-  // "SW_SECURE_DECODE" and "HW_SECURE_ALL" supported on ChromeOS when the
-  // protected media identifier permission is allowed. See
-  // kUnsafelyAllowProtectedMediaIdentifierForDomain used above.
+  // "SW_SECURE_DECODE", "HW_SECURE_CRYPTO", and "HW_SECURE_ALL" supported
+  // on ChromeOS when the protected media identifier permission is allowed.
+  // See kUnsafelyAllowProtectedMediaIdentifierForDomain used above.
   EXPECT_WV_PROPRIETARY(
       IsAudioMp4RobustnessSupported(kWidevine, "SW_SECURE_DECODE"));
   EXPECT_WV_PROPRIETARY(
+      IsAudioMp4RobustnessSupported(kWidevine, "HW_SECURE_CRYPTO"));
+  EXPECT_WV_PROPRIETARY(
       IsAudioMp4RobustnessSupported(kWidevine, "HW_SECURE_ALL"));
 #else
+  // Test only enables audio codec Vorbis, so MP4 not supported.
   EXPECT_UNSUPPORTED(
       IsAudioMp4RobustnessSupported(kWidevine, "SW_SECURE_DECODE"));
+  EXPECT_UNSUPPORTED(
+      IsAudioMp4RobustnessSupported(kWidevine, "HW_SECURE_CRYPTO"));
   EXPECT_UNSUPPORTED(IsAudioMp4RobustnessSupported(kWidevine, "HW_SECURE_ALL"));
 #endif
 }
diff --git a/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc b/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc
index bfa4cc1..cb513c14 100644
--- a/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc
+++ b/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc
@@ -695,11 +695,6 @@
   ChromeMetricsServiceAccessor::RegisterSyntheticFieldTrial(
       "BackupRefPtrNoEnterprise", group_name);
 #endif  // BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
-
-  ChromeMetricsServiceAccessor::RegisterSyntheticFieldTrial(
-      "PartitionAllocGigaCageSynthetic",
-      base::features::IsPartitionAllocGigaCageEnabled() ? "Enabled"
-                                                        : "Disabled");
 }
 
 void ChromeBrowserMainExtraPartsMetrics::PostBrowserStart() {
diff --git a/chrome/browser/optimization_guide/prediction/prediction_model_download_manager.h b/chrome/browser/optimization_guide/prediction/prediction_model_download_manager.h
index d346d0e..af3f7f95 100644
--- a/chrome/browser/optimization_guide/prediction/prediction_model_download_manager.h
+++ b/chrome/browser/optimization_guide/prediction/prediction_model_download_manager.h
@@ -13,6 +13,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
 #include "components/download/public/background_service/download_params.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace download {
 class DownloadService;
diff --git a/chrome/browser/password_edit_dialog/android/BUILD.gn b/chrome/browser/password_edit_dialog/android/BUILD.gn
index 6d884e2..281f64f 100644
--- a/chrome/browser/password_edit_dialog/android/BUILD.gn
+++ b/chrome/browser/password_edit_dialog/android/BUILD.gn
@@ -43,7 +43,10 @@
 }
 
 android_resources("java_resources") {
-  sources = [ "java/res/layout/password_edit_dialog.xml" ]
+  sources = [
+    "java/res/layout/password_edit_dialog.xml",
+    "java/res/values/dimens.xml",
+  ]
 
   deps = [
     "//chrome/app:java_strings_grd",
diff --git a/chrome/browser/password_edit_dialog/android/java/res/layout/password_edit_dialog.xml b/chrome/browser/password_edit_dialog/android/java/res/layout/password_edit_dialog.xml
index 23c0619..4bc7d1a 100644
--- a/chrome/browser/password_edit_dialog/android/java/res/layout/password_edit_dialog.xml
+++ b/chrome/browser/password_edit_dialog/android/java/res/layout/password_edit_dialog.xml
@@ -17,6 +17,10 @@
         android:labelFor="@+id/usernames_spinner"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
+        android:layout_marginTop="@dimen/password_edit_field_vertical_margin"
+        android:layout_marginStart="@dimen/password_edit_field_horizontal_margin"
+        android:layout_marginEnd="@dimen/password_edit_field_horizontal_margin"
+
         android:textAppearance="@style/TextAppearance.TextSmall.Secondary"
         android:text="@string/password_manager_username_label" />
 
@@ -24,19 +28,25 @@
         android:id="@+id/usernames_spinner"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
+        android:layout_marginTop="@dimen/password_edit_field_vertical_margin"
+        android:layout_marginStart="@dimen/password_edit_field_horizontal_margin"
+        android:layout_marginEnd="@dimen/password_edit_field_horizontal_margin"
         android:focusable="true"
         android:focusableInTouchMode="true"/>
 
-    <View style="@style/PreferenceSpinnerUnderlineView"/>
+    <View style="@style/PreferenceSpinnerUnderlineView"
+        android:layout_marginStart="@dimen/password_edit_field_horizontal_margin"
+        android:layout_marginEnd="@dimen/password_edit_field_horizontal_margin"
+        android:layout_marginBottom="@dimen/password_edit_large_bottom_margin"/>
 
     <!-- Password -->
     <com.google.android.material.textfield.TextInputLayout
         android:labelFor="@+id/password"
         android:layout_height="wrap_content"
         android:layout_width="match_parent"
-        android:hint="@string/password_manager_password_label"
-        app:endIconMode="password_toggle"
-        app:hintTextAppearance="@style/TextAppearance.TextSmall.Secondary">
+        android:layout_marginTop="@dimen/password_edit_field_vertical_margin"
+        android:layout_marginBottom="@dimen/password_edit_field_vertical_margin"
+        app:endIconMode="password_toggle">
 
         <EditText
             tools:ignore="LabelFor"
@@ -47,8 +57,8 @@
             android:imeOptions="flagNoExtractUi"
             android:enabled="false"
             android:focusable="false"
-            android:importantForAutofill="noExcludeDescendants"
-            android:textAppearance="@style/TextAppearance.TextLarge.Primary"/>
+            android:hint="@string/password_manager_password_label"
+            android:importantForAutofill="noExcludeDescendants"/>
     </com.google.android.material.textfield.TextInputLayout>
 
     <TextView
@@ -56,5 +66,9 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:visibility="gone"
+        android:layout_marginTop="@dimen/password_edit_field_vertical_margin"
+        android:layout_marginBottom="@dimen/password_edit_large_bottom_margin"
+        android:layout_marginStart="@dimen/password_edit_field_horizontal_margin"
+        android:layout_marginEnd="@dimen/password_edit_field_horizontal_margin"
         android:textAppearance="@style/TextAppearance.TextSmall.Secondary"/>
 </org.chromium.chrome.browser.password_edit_dialog.PasswordEditDialogView>
diff --git a/chrome/browser/password_edit_dialog/android/java/res/values/dimens.xml b/chrome/browser/password_edit_dialog/android/java/res/values/dimens.xml
new file mode 100644
index 0000000..2e42b32
--- /dev/null
+++ b/chrome/browser/password_edit_dialog/android/java/res/values/dimens.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2021 The Chromium Authors. All rights reserved.
+     Use of this source code is governed by a BSD-style license that can be
+     found in the LICENSE file. -->
+
+<resources xmlns:tools="http://schemas.android.com/tools">
+    <!--
+      password_edit_field_horizontal_margin is introduced to make
+      TextView fields align with TextInputLayout internal padding.
+    -->
+    <dimen name="password_edit_field_horizontal_margin">4dp</dimen>
+    <dimen name="password_edit_field_vertical_margin">8dp</dimen>
+    <dimen name="password_edit_large_bottom_margin">16dp</dimen>
+</resources>
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_settings.cc b/chrome/browser/privacy_sandbox/privacy_sandbox_settings.cc
index a65d18f5..77c5125 100644
--- a/chrome/browser/privacy_sandbox/privacy_sandbox_settings.cc
+++ b/chrome/browser/privacy_sandbox/privacy_sandbox_settings.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/privacy_sandbox/privacy_sandbox_settings.h"
 
 #include "base/feature_list.h"
+#include "base/i18n/time_formatting.h"
 #include "base/metrics/histogram.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/metrics/user_metrics.h"
@@ -128,6 +129,28 @@
           default_cookie_setting == ContentSetting::CONTENT_SETTING_BLOCK);
 }
 
+// Returns whether FLoC is allowable by the current state of |pref_service|.
+bool IsFlocAllowedByPrefs(PrefService* pref_service) {
+  return pref_service->GetBoolean(prefs::kPrivacySandboxFlocEnabled) &&
+         pref_service->GetBoolean(prefs::kPrivacySandboxApisEnabled);
+}
+
+// Returns the number of days in |time|, rounded to the closest day by hour if
+// there is at least 1 day, but rounded to 0 if |time| is less than 1 day.
+int GetNumberOfDaysRoundedAboveOne(base::TimeDelta time) {
+  int number_of_days = time.InDays();
+  if (number_of_days == 0)
+    return 0;
+
+  int number_of_hours_past_day =
+      (time - base::TimeDelta::FromDays(number_of_days)).InHours();
+
+  if (number_of_hours_past_day >= 12)
+    number_of_days++;
+
+  return number_of_days;
+}
+
 }  // namespace
 
 PrivacySandboxSettings::PrivacySandboxSettings(
@@ -183,8 +206,7 @@
     return !cookie_settings_->ShouldBlockThirdPartyCookies();
   }
 
-  return pref_service_->GetBoolean(prefs::kPrivacySandboxFlocEnabled) &&
-         pref_service_->GetBoolean(prefs::kPrivacySandboxApisEnabled);
+  return IsFlocAllowedByPrefs(pref_service_);
 }
 
 bool PrivacySandboxSettings::IsFlocAllowedForContext(
@@ -214,13 +236,39 @@
   return base::NumberToString16(floc_id.ToUint64());
 }
 
-std::u16string PrivacySandboxSettings::GetFlocResetExplanationForDisplay()
-    const {
-  const int floc_compute_days =
-      federated_learning::kFlocIdScheduledUpdateInterval.Get().InDays();
+/*static*/ std::u16string PrivacySandboxSettings::GetFlocIdNextUpdateForDisplay(
+    federated_learning::FlocIdProvider* floc_id_provider,
+    PrefService* pref_service,
+    const base::Time& current_time) {
+  DCHECK(PrivacySandboxSettingsFunctional());
+  const bool floc_feature_enabled = base::FeatureList::IsEnabled(
+      blink::features::kInterestCohortAPIOriginTrial);
+
+  if (!floc_id_provider || !floc_feature_enabled ||
+      !IsFlocAllowedByPrefs(pref_service)) {
+    return l10n_util::GetStringUTF16(
+        IDS_PRIVACY_SANDBOX_FLOC_TIME_TO_NEXT_COMPUTE_INVALID);
+  }
+
+  auto next_compute_time = floc_id_provider->GetApproximateNextComputeTime();
+
+  // There are no guarantee that the next compute time is in the future. This
+  // should only occur when a compute is soon to occur, so assuming the current
+  // time is suitable.
+  if (next_compute_time < current_time)
+    next_compute_time = current_time;
 
   return l10n_util::GetPluralStringFUTF16(
-      IDS_PRIVACY_SANDBOX_FLOC_RESET_EXPLANATION, floc_compute_days);
+      IDS_PRIVACY_SANDBOX_FLOC_TIME_TO_NEXT_COMPUTE,
+      GetNumberOfDaysRoundedAboveOne(next_compute_time - current_time));
+}
+
+std::u16string PrivacySandboxSettings::GetFlocResetExplanationForDisplay()
+    const {
+  return l10n_util::GetPluralStringFUTF16(
+      IDS_PRIVACY_SANDBOX_FLOC_RESET_EXPLANATION,
+      GetNumberOfDaysRoundedAboveOne(
+          federated_learning::kFlocIdScheduledUpdateInterval.Get()));
 }
 
 std::u16string PrivacySandboxSettings::GetFlocStatusForDisplay() const {
@@ -238,6 +286,10 @@
   return l10n_util::GetStringUTF16(IDS_PRIVACY_SANDBOX_FLOC_STATUS_NOT_ACTIVE);
 }
 
+bool PrivacySandboxSettings::IsFlocIdValid() const {
+  return federated_learning::FlocId::ReadFromPrefs(pref_service_).IsValid();
+}
+
 bool PrivacySandboxSettings::IsConversionMeasurementAllowed(
     const url::Origin& top_frame_origin,
     const url::Origin& reporting_origin) const {
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_settings.h b/chrome/browser/privacy_sandbox/privacy_sandbox_settings.h
index 77fe792..7c5988d 100644
--- a/chrome/browser/privacy_sandbox/privacy_sandbox_settings.h
+++ b/chrome/browser/privacy_sandbox/privacy_sandbox_settings.h
@@ -9,6 +9,7 @@
 #include "base/observer_list.h"
 #include "base/scoped_observation.h"
 #include "base/time/time.h"
+#include "chrome/browser/federated_learning/floc_id_provider.h"
 #include "components/content_settings/core/common/content_settings.h"
 #include "components/keyed_service/core/keyed_service.h"
 #include "components/policy/core/common/policy_service.h"
@@ -82,6 +83,19 @@
   // not valid, the appropriate descriptive string is returned instead.
   std::u16string GetFlocIdForDisplay() const;
 
+  // Returns when the user's current FLoC cohort identifier will next be updated
+  // in a string format suitable for direct display to the user. If no compute
+  // is scheduled, the appropriate descriptive string is returned instead.
+  // This is static to break a circular dependency between this service, and
+  // the FlocIdProvider service. This pushes the requirement to the caller to
+  // ensure the profile is not in a shutdown state before calling.
+  // TODO(crbug.com/1210405): This is indicative of an architecture issue and
+  // should be changed or broken out into an explicit helper.
+  static std::u16string GetFlocIdNextUpdateForDisplay(
+      federated_learning::FlocIdProvider* floc_id_provider,
+      PrefService* pref_service,
+      const base::Time& current_time);
+
   // Returns the display ready string explanaing what happens when the user
   // resets the FLoC cohort identifier.
   std::u16string GetFlocResetExplanationForDisplay() const;
@@ -90,6 +104,9 @@
   // the effective state of the Finch experiment, and the user's setting.
   std::u16string GetFlocStatusForDisplay() const;
 
+  // Returns whether the user's current FLoC ID is valid.
+  bool IsFlocIdValid() const;
+
   // Determines whether Conversion Measurement is allowable in a particular
   // context. Should be called at both impression & conversion. At each of these
   // points |top_frame_origin| is the same as either the impression origin or
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_settings_unittest.cc b/chrome/browser/privacy_sandbox/privacy_sandbox_settings_unittest.cc
index b948bcc..7fc33ebc 100644
--- a/chrome/browser/privacy_sandbox/privacy_sandbox_settings_unittest.cc
+++ b/chrome/browser/privacy_sandbox/privacy_sandbox_settings_unittest.cc
@@ -5,11 +5,14 @@
 #include "chrome/browser/privacy_sandbox/privacy_sandbox_settings.h"
 
 #include "base/test/gtest_util.h"
+#include "base/test/icu_test_util.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/util/values/values_util.h"
 #include "chrome/browser/content_settings/cookie_settings_factory.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
+#include "chrome/browser/federated_learning/floc_id_provider.h"
+#include "chrome/browser/privacy_sandbox/privacy_sandbox_settings.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/common/chrome_features.h"
@@ -33,11 +36,23 @@
 #include "content/public/test/browser_task_environment.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/common/features.h"
+#include "third_party/blink/public/mojom/federated_learning/floc.mojom.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "url/origin.h"
 
 namespace {
 
+class MockFlocIdProvider : public federated_learning::FlocIdProvider {
+ public:
+  blink::mojom::InterestCohortPtr GetInterestCohortForJsApi(
+      const GURL& url,
+      const absl::optional<url::Origin>& top_frame_origin) const override {
+    return blink::mojom::InterestCohort::New();
+  }
+  MOCK_METHOD(void, MaybeRecordFlocToUkm, (ukm::SourceId), (override));
+  MOCK_METHOD(base::Time, GetApproximateNextComputeTime, (), (const, override));
+};
+
 // Define an additional content setting value to simulate an unmanaged default
 // content setting.
 const ContentSetting kNoSetting = static_cast<ContentSetting>(-1);
@@ -894,16 +909,79 @@
             privacy_sandbox_settings()->GetFlocIdForDisplay());
 }
 
+TEST_F(PrivacySandboxSettingsTest, GetFlocIdNextUpdateForDisplay) {
+  // Check that date FLoC will be next updated is returned when available.
+  MockFlocIdProvider mock_floc_id_provider;
+  feature_list()->InitWithFeatures(
+      {blink::features::kInterestCohortAPIOriginTrial}, {});
+  profile()->GetTestingPrefService()->SetBoolean(
+      prefs::kPrivacySandboxApisEnabled, true);
+  profile()->GetTestingPrefService()->SetBoolean(
+      prefs::kPrivacySandboxFlocEnabled, true);
+
+  std::map<base::TimeDelta, std::u16string> offsets_to_expected_string = {
+      {base::TimeDelta::FromHours(23),
+       l10n_util::GetPluralStringFUTF16(
+           IDS_PRIVACY_SANDBOX_FLOC_TIME_TO_NEXT_COMPUTE, 0)},
+      {base::TimeDelta::FromHours(25),
+       l10n_util::GetPluralStringFUTF16(
+           IDS_PRIVACY_SANDBOX_FLOC_TIME_TO_NEXT_COMPUTE, 1)},
+      {base::TimeDelta::FromDays(2),
+       l10n_util::GetPluralStringFUTF16(
+           IDS_PRIVACY_SANDBOX_FLOC_TIME_TO_NEXT_COMPUTE, 2)},
+      {base::TimeDelta::FromHours(60),
+       l10n_util::GetPluralStringFUTF16(
+           IDS_PRIVACY_SANDBOX_FLOC_TIME_TO_NEXT_COMPUTE, 3)},
+      {base::TimeDelta::FromHours(167),  // 1 hour less than 7 days.
+       l10n_util::GetPluralStringFUTF16(
+           IDS_PRIVACY_SANDBOX_FLOC_TIME_TO_NEXT_COMPUTE, 7)}};
+
+  for (const auto& offset_expected : offsets_to_expected_string) {
+    EXPECT_CALL(mock_floc_id_provider, GetApproximateNextComputeTime)
+        .WillOnce(testing::Return(base::Time::Now() + offset_expected.first));
+    EXPECT_EQ(
+        offset_expected.second,
+        privacy_sandbox_settings()->GetFlocIdNextUpdateForDisplay(
+            &mock_floc_id_provider, profile()->GetPrefs(), base::Time::Now()));
+    testing::Mock::VerifyAndClearExpectations(&mock_floc_id_provider);
+  }
+
+  // Check that disabling FLoC is also reflected in the returned string.
+  profile()->GetTestingPrefService()->SetBoolean(
+      prefs::kPrivacySandboxFlocEnabled, false);
+  EXPECT_CALL(mock_floc_id_provider, GetApproximateNextComputeTime).Times(0);
+  EXPECT_EQ(
+      l10n_util::GetStringUTF16(
+          IDS_PRIVACY_SANDBOX_FLOC_TIME_TO_NEXT_COMPUTE_INVALID),
+      privacy_sandbox_settings()->GetFlocIdNextUpdateForDisplay(
+          &mock_floc_id_provider, profile()->GetPrefs(), base::Time::Now()));
+  testing::Mock::VerifyAndClearExpectations(&mock_floc_id_provider);
+
+  // Disabling the FLoC feature should also invalidate the next compute time.
+  feature_list()->Reset();
+  feature_list()->InitWithFeatures(
+      {}, {blink::features::kInterestCohortAPIOriginTrial});
+  profile()->GetTestingPrefService()->SetBoolean(
+      prefs::kPrivacySandboxFlocEnabled, true);
+  testing::Mock::VerifyAndClearExpectations(&mock_floc_id_provider);
+}
+
 TEST_F(PrivacySandboxSettingsTest, GetFlocResetExplanationForDisplay) {
   // Check that the string description indicating what happens when the user
   // resets the FLoC ID updates appropriately based on the feature parameter.
   std::map<std::string, std::u16string> param_to_expected_string = {
       {"1h", l10n_util::GetPluralStringFUTF16(
                  IDS_PRIVACY_SANDBOX_FLOC_RESET_EXPLANATION, 0)},
+      {"23h", l10n_util::GetPluralStringFUTF16(
+                  IDS_PRIVACY_SANDBOX_FLOC_RESET_EXPLANATION, 0)},
       {"24h", l10n_util::GetPluralStringFUTF16(
                   IDS_PRIVACY_SANDBOX_FLOC_RESET_EXPLANATION, 1)},
+      {"25h", l10n_util::GetPluralStringFUTF16(
+                  IDS_PRIVACY_SANDBOX_FLOC_RESET_EXPLANATION, 1)},
+      {"60h", l10n_util::GetPluralStringFUTF16(
+                  IDS_PRIVACY_SANDBOX_FLOC_RESET_EXPLANATION, 3)},
       {"167h", l10n_util::GetPluralStringFUTF16(
-                   IDS_PRIVACY_SANDBOX_FLOC_RESET_EXPLANATION, 6)},
+                   IDS_PRIVACY_SANDBOX_FLOC_RESET_EXPLANATION, 7)},
       {"168h", l10n_util::GetPluralStringFUTF16(
                    IDS_PRIVACY_SANDBOX_FLOC_RESET_EXPLANATION, 7)}};
 
diff --git a/chrome/browser/profiles/profile_manager.cc b/chrome/browser/profiles/profile_manager.cc
index 26c5e35..5a188cc 100644
--- a/chrome/browser/profiles/profile_manager.cc
+++ b/chrome/browser/profiles/profile_manager.cc
@@ -325,7 +325,7 @@
 // It might get called more than once with different values of
 // |status| but only once the profile is fully initialized will
 // |client_callback| be run.
-void OnProfileLoaded(ProfileManager::ProfileLoadedCallback client_callback,
+void OnProfileLoaded(ProfileManager::ProfileLoadedCallback* client_callback,
                      bool incognito,
                      Profile* profile,
                      Profile::CreateStatus status) {
@@ -336,11 +336,11 @@
   }
   if (status != Profile::CREATE_STATUS_INITIALIZED) {
     LOG(WARNING) << "Profile not loaded correctly";
-    std::move(client_callback).Run(nullptr);
+    std::move(*client_callback).Run(nullptr);
     return;
   }
   DCHECK(profile);
-  std::move(client_callback)
+  std::move(*client_callback)
       .Run(incognito ? profile->GetPrimaryOTRProfile(/*create_if_needed=*/true)
                      : profile);
 }
@@ -712,7 +712,8 @@
       base::BindRepeating(&OnProfileLoaded,
                           // OnProfileLoaded may be called multiple times, but
                           // |callback| will be called only once.
-                          base::AdaptCallbackForRepeating(std::move(callback)),
+                          base::Owned(std::make_unique<ProfileLoadedCallback>(
+                              std::move(callback))),
                           incognito));
   return true;
 }
@@ -1736,8 +1737,8 @@
     base::FilePath cur_path = profile->GetPath();
     if (cur_path != profile_dir && cur_path != guest_profile_path &&
         !IsProfileDirectoryMarkedForDeletion(cur_path)) {
-      OnNewActiveProfileLoaded(profile_dir, cur_path, std::move(callback),
-                               profile, Profile::CREATE_STATUS_INITIALIZED);
+      OnNewActiveProfileLoaded(profile_dir, cur_path, &callback, profile,
+                               Profile::CREATE_STATUS_INITIALIZED);
       return;
     }
   }
@@ -1775,7 +1776,8 @@
           profile_dir, fallback_profile_path,
           // OnNewActiveProfileLoaded may be called several times, but
           // only once with CREATE_STATUS_INITIALIZED.
-          base::AdaptCallbackForRepeating(std::move(callback))));
+          base::Owned(
+              std::make_unique<ProfileLoadedCallback>(std::move(callback)))));
 }
 
 void ProfileManager::OnLoadProfileForProfileDeletion(
@@ -2235,7 +2237,7 @@
 void ProfileManager::OnNewActiveProfileLoaded(
     const base::FilePath& profile_to_delete_path,
     const base::FilePath& new_active_profile_path,
-    ProfileLoadedCallback callback,
+    ProfileLoadedCallback* callback,
     Profile* loaded_profile,
     Profile::CreateStatus status) {
   DCHECK(status != Profile::CREATE_STATUS_LOCAL_FAIL &&
@@ -2249,13 +2251,13 @@
     // If the profile we tried to load as the next active profile has been
     // deleted, then retry deleting this profile to redo the logic to load
     // the next available profile.
-    EnsureActiveProfileExistsBeforeDeletion(std::move(callback),
+    EnsureActiveProfileExistsBeforeDeletion(std::move(*callback),
                                             profile_to_delete_path);
     return;
   }
 
   FinishDeletingProfile(profile_to_delete_path, new_active_profile_path);
-  std::move(callback).Run(loaded_profile);
+  std::move(*callback).Run(loaded_profile);
 }
 
 void ProfileManager::ScheduleForcedEphemeralProfileForDeletion(
diff --git a/chrome/browser/profiles/profile_manager.h b/chrome/browser/profiles/profile_manager.h
index 635cec1..cd6fdbb 100644
--- a/chrome/browser/profiles/profile_manager.h
+++ b/chrome/browser/profiles/profile_manager.h
@@ -451,7 +451,7 @@
   void OnNewActiveProfileLoaded(
       const base::FilePath& profile_to_delete_path,
       const base::FilePath& last_non_supervised_profile_path,
-      ProfileLoadedCallback callback,
+      ProfileLoadedCallback* callback,
       Profile* loaded_profile,
       Profile::CreateStatus status);
 
diff --git a/chrome/browser/profiles/profile_window.cc b/chrome/browser/profiles/profile_window.cc
index 917de5e..e0010fdd 100644
--- a/chrome/browser/profiles/profile_window.cc
+++ b/chrome/browser/profiles/profile_window.cc
@@ -138,7 +138,7 @@
                                 /*launch_mode_recorder=*/nullptr);
 }
 
-void OpenBrowserWindowForProfile(ProfileManager::CreateCallback callback,
+void OpenBrowserWindowForProfile(CreateOnceCallback callback,
                                  bool always_create,
                                  bool is_new_profile,
                                  bool unblock_extensions,
@@ -193,8 +193,8 @@
     Browser* browser = chrome::FindTabbedBrowser(profile, false);
     if (browser) {
       browser->window()->Activate();
-      if (!callback.is_null())
-        callback.Run(profile, Profile::CREATE_STATUS_INITIALIZED);
+      if (callback)
+        std::move(callback).Run(profile, Profile::CREATE_STATUS_INITIALIZED);
       return;
     }
   }
@@ -206,8 +206,8 @@
   // up calling LaunchBrowser and opens a new window. If for whatever reason
   // that fails, either something has crashed, or the observer will be cleaned
   // up when a different browser for this profile is opened.
-  if (!callback.is_null())
-    new BrowserAddedForProfileObserver(profile, callback);
+  if (callback)
+    new BrowserAddedForProfileObserver(profile, std::move(callback));
 
   // We already dealt with the case when |always_create| was false and a browser
   // existed, which means that here a browser definitely needs to be created.
@@ -281,9 +281,9 @@
 
 BrowserAddedForProfileObserver::BrowserAddedForProfileObserver(
     Profile* profile,
-    ProfileManager::CreateCallback callback)
-    : profile_(profile), callback_(callback) {
-  DCHECK(!callback_.is_null());
+    CreateOnceCallback callback)
+    : profile_(profile), callback_(std::move(callback)) {
+  DCHECK(callback_);
   BrowserList::AddObserver(this);
 }
 
@@ -296,7 +296,7 @@
     // added. Post the callback to the message loop so it gets executed after
     // the tabs are created.
     base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::BindOnce(callback_, profile_,
+        FROM_HERE, base::BindOnce(std::move(callback_), profile_,
                                   Profile::CREATE_STATUS_INITIALIZED));
     base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
   }
diff --git a/chrome/browser/profiles/profile_window.h b/chrome/browser/profiles/profile_window.h
index 2f3f8ec..ed1b2be 100644
--- a/chrome/browser/profiles/profile_window.h
+++ b/chrome/browser/profiles/profile_window.h
@@ -41,12 +41,16 @@
     chrome::startup::IsFirstRun is_first_run,
     bool always_create);
 
+// Similar to `ProfileManager::CreateCallback` but only called once.
+using CreateOnceCallback =
+    base::OnceCallback<void(Profile*, Profile::CreateStatus)>;
+
 // Opens a Browser for |profile|.
 // If |always_create| is true a window is created even if one already exists.
 // If |is_new_profile| is true a first run window is created.
 // If |unblock_extensions| is true, all extensions are unblocked.
 // When the browser is opened, |callback| will be run if it isn't null.
-void OpenBrowserWindowForProfile(ProfileManager::CreateCallback callback,
+void OpenBrowserWindowForProfile(CreateOnceCallback callback,
                                  bool always_create,
                                  bool is_new_profile,
                                  bool unblock_extensions,
@@ -89,13 +93,13 @@
 // is created and the callback is executed.
 class BrowserAddedForProfileObserver : public BrowserListObserver {
  public:
-  BrowserAddedForProfileObserver(Profile* profile,
-                                 ProfileManager::CreateCallback callback);
+  BrowserAddedForProfileObserver(Profile* profile, CreateOnceCallback callback);
+  ~BrowserAddedForProfileObserver() override;
+
   BrowserAddedForProfileObserver(const BrowserAddedForProfileObserver&) =
       delete;
   BrowserAddedForProfileObserver& operator=(
       const BrowserAddedForProfileObserver&) = delete;
-  ~BrowserAddedForProfileObserver() override;
 
  private:
   // Overridden from BrowserListObserver:
@@ -103,7 +107,7 @@
 
   // Profile for which the browser should be opened.
   Profile* profile_;
-  ProfileManager::CreateCallback callback_;
+  CreateOnceCallback callback_;
 };
 
 }  // namespace profiles
diff --git a/chrome/browser/resources/chromeos/accessibility/switch_access/focus_ring_manager.js b/chrome/browser/resources/chromeos/accessibility/switch_access/focus_ring_manager.js
index e56af07e2..44c845b7 100644
--- a/chrome/browser/resources/chromeos/accessibility/switch_access/focus_ring_manager.js
+++ b/chrome/browser/resources/chromeos/accessibility/switch_access/focus_ring_manager.js
@@ -172,11 +172,6 @@
    * @private
    */
   updateFocusRings_(primaryRingNode, previewRingNode) {
-    if (SwitchAccess.mode === SAConstants.Mode.POINT_SCAN &&
-        !MenuManager.isMenuOpen()) {
-      return;
-    }
-
     const focusRings = [];
     this.rings_.forEach((ring) => focusRings.push(ring));
     chrome.accessibilityPrivate.setFocusRings(focusRings);
diff --git a/chrome/browser/resources/chromeos/accessibility/switch_access/menu_manager.js b/chrome/browser/resources/chromeos/accessibility/switch_access/menu_manager.js
index 327e7f4..3746281 100644
--- a/chrome/browser/resources/chromeos/accessibility/switch_access/menu_manager.js
+++ b/chrome/browser/resources/chromeos/accessibility/switch_access/menu_manager.js
@@ -3,7 +3,6 @@
 // found in the LICENSE file.
 
 import {ActionManager} from './action_manager.js';
-import {FocusRingManager} from './focus_ring_manager.js';
 import {Navigator} from './navigator.js';
 import {SwitchAccess} from './switch_access.js';
 import {SwitchAccessMenuAction} from './switch_access_constants.js';
@@ -68,7 +67,6 @@
 
   /** Exits the menu. */
   static close() {
-    FocusRingManager.clearAll();
     MenuManager.instance.isMenuOpen_ = false;
     MenuManager.instance.actionNode_ = null;
     MenuManager.instance.displayedActions_ = null;
diff --git a/chrome/browser/resources/chromeos/accessibility/switch_access/point_scan_manager.js b/chrome/browser/resources/chromeos/accessibility/switch_access/point_scan_manager.js
index fc818e4..eb3e003 100644
--- a/chrome/browser/resources/chromeos/accessibility/switch_access/point_scan_manager.js
+++ b/chrome/browser/resources/chromeos/accessibility/switch_access/point_scan_manager.js
@@ -29,8 +29,8 @@
 
   /** @override */
   start() {
-    FocusRingManager.clearAll();
     SwitchAccess.mode = SAConstants.Mode.POINT_SCAN;
+    FocusRingManager.clearAll();
     chrome.accessibilityPrivate.onPointScanSet.addListener(this.pointListener_);
     chrome.accessibilityPrivate.setPointScanState(PointScanState.START);
   }
diff --git a/chrome/browser/resources/download_shelf/BUILD.gn b/chrome/browser/resources/download_shelf/BUILD.gn
index 404465b..541bda5 100644
--- a/chrome/browser/resources/download_shelf/BUILD.gn
+++ b/chrome/browser/resources/download_shelf/BUILD.gn
@@ -79,6 +79,7 @@
 }
 
 js_type_check("closure_compile") {
+  is_polymer3 = true
   closure_flags = default_closure_args + mojom_js_args + [
                     "js_module_root=" + rebase_path(".", root_build_dir),
                     "js_module_root=" + rebase_path(
@@ -128,7 +129,10 @@
 js_library("app") {
   deps = [
     ":download_list",
+    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
+    "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button.m",
     "//ui/webui/resources/js:custom_element",
+    "//ui/webui/resources/js:icon.m",
   ]
 }
 
diff --git a/chrome/browser/resources/download_shelf/app.html b/chrome/browser/resources/download_shelf/app.html
index 2846935..3f0570a 100644
--- a/chrome/browser/resources/download_shelf/app.html
+++ b/chrome/browser/resources/download_shelf/app.html
@@ -1 +1,29 @@
+<style>
+  /* See chrome/browser/ui/views/download/download_shelf_view.cc for style. */
+  :host {
+    align-items: center;
+    display: flex;
+    flex-direction: row;
+    height: 100%;
+    margin-inline-start: 4px;
+  }
+
+  download-list {
+    flex-grow: 1;
+    overflow: hidden;
+  }
+
+  #close-button {
+    --cr-icon-button-icon-size: 16px;
+    --cr-icon-button-size: 24px;
+    --cr-icon-button-stroke-color: var(--google-grey-refresh-700);
+    border-radius: 4px;
+    margin-inline-end: 6px;
+    margin-inline-start: 6px;
+  }
+
+</style>
 <download-list></download-list>
+<cr-icon-button id="close-button" iron-icon="cr:close"
+    aria-label="$i18n{close}">
+</cr-icon-button>
diff --git a/chrome/browser/resources/download_shelf/app.js b/chrome/browser/resources/download_shelf/app.js
index 0d239207..4a4166d 100644
--- a/chrome/browser/resources/download_shelf/app.js
+++ b/chrome/browser/resources/download_shelf/app.js
@@ -2,14 +2,37 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icons_css.m.js';
+import 'chrome://resources/cr_elements/icons.m.js';
+import 'chrome://resources/cr_elements/shared_vars_css.m.js';
 import './download_list.js';
+import './strings.m.js';
 
 import {CustomElement} from 'chrome://resources/js/custom_element.js';
+import {DownloadShelfApiProxy, DownloadShelfApiProxyImpl} from './download_shelf_api_proxy.js';
 
 export class DownloadShelfAppElement extends CustomElement {
   static get template() {
     return `{__html_template__}`;
   }
+
+  constructor() {
+    super();
+
+    /** @private {!DownloadShelfApiProxy} */
+    this.apiProxy_ = DownloadShelfApiProxyImpl.getInstance();
+
+    this.$('#close-button').addEventListener('click', e => this.onClose_(e));
+  }
+
+  /**
+   * @param {!Event} e
+   * @private
+   */
+  onClose_(e) {
+    this.apiProxy_.doClose();
+  }
 }
 
 customElements.define('download-shelf-app', DownloadShelfAppElement);
diff --git a/chrome/browser/resources/download_shelf/download_button.html b/chrome/browser/resources/download_shelf/download_button.html
index da746a4..1bed746 100644
--- a/chrome/browser/resources/download_shelf/download_button.html
+++ b/chrome/browser/resources/download_shelf/download_button.html
@@ -1,12 +1,6 @@
 <div>
 <style>
 :host {
-  --google-blue-600-rgb: 26, 115, 232;
-  --google-blue-600: rgb(var(--google-blue-600-rgb));
-  --google-grey-refresh-300-rgb: 218, 220, 224;
-  --google-grey-refresh-300: rgb(var(--google-grey-refresh-300-rgb));
-  --google-blue-refresh-500-rgb: 66, 133, 244;
-
   --border-color: var(--google-grey-refresh-300);
   --text-color: var(--google-blue-600);
   --hover-bg-color: rgba(var(--google-blue-refresh-500-rgb), 0.12);
@@ -33,4 +27,4 @@
 }
 </style>
 <slot></slot>
-</div>
\ No newline at end of file
+</div>
diff --git a/chrome/browser/resources/download_shelf/download_button.js b/chrome/browser/resources/download_shelf/download_button.js
index 3fcea46..a407f23 100644
--- a/chrome/browser/resources/download_shelf/download_button.js
+++ b/chrome/browser/resources/download_shelf/download_button.js
@@ -6,6 +6,8 @@
  * @fileoverview Button UI for "Discard" and "Show All".
  */
 
+import 'chrome://resources/cr_elements/shared_vars_css.m.js';
+
 import {CustomElement} from 'chrome://resources/js/custom_element.js';
 
 export class DownloadButtonElement extends CustomElement {
@@ -18,4 +20,4 @@
   }
 }
 
-customElements.define('download-button', DownloadButtonElement);
\ No newline at end of file
+customElements.define('download-button', DownloadButtonElement);
diff --git a/chrome/browser/resources/download_shelf/download_item.html b/chrome/browser/resources/download_shelf/download_item.html
index 5c83f0b1..9f10fea20 100644
--- a/chrome/browser/resources/download_shelf/download_item.html
+++ b/chrome/browser/resources/download_shelf/download_item.html
@@ -1,18 +1,5 @@
 <style>
 :host {
-  /* The following color values are copied from
-   * ui/webui/resources/cr_elements/shared_vars_css.html
-   * because we don't want to introduce the Polymer 3 dependency
-   * to increase loading overhead from the benchmarking's perspective.
-   * If at some point pulling in Polymer becomes unavoidable then we should
-   * remove these lines and include shared_vars_css.html instead. */
-  --google-grey-refresh-700-rgb: 95, 99, 104;  /* #5f6368 */
-  --google-grey-refresh-700: rgb(var(--google-grey-refresh-700-rgb));
-  --google-grey-900-rgb: 32, 33, 36;  /* #202124 */
-  --google-grey-900: rgb(var(--google-grey-900-rgb));
-  --google-red-600-rgb: 217, 49, 37 ; /* #d93025 */
-  --google-red-600: rgb(var(--google-red-600-rgb));
-
   --button-hover-color: rgba(var(--google-grey-900-rgb), .1);
   --button-icon-stroke-color: var(--google-grey-refresh-700);
   --pi: 3.14159265358979;
diff --git a/chrome/browser/resources/download_shelf/download_item.js b/chrome/browser/resources/download_shelf/download_item.js
index c01183a..1b465154 100644
--- a/chrome/browser/resources/download_shelf/download_item.js
+++ b/chrome/browser/resources/download_shelf/download_item.js
@@ -6,6 +6,7 @@
  * @fileoverview UI element of a download item.
  */
 
+import 'chrome://resources/cr_elements/shared_vars_css.m.js';
 import './download_button.js';
 import './strings.m.js';
 
diff --git a/chrome/browser/resources/download_shelf/download_list.js b/chrome/browser/resources/download_shelf/download_list.js
index 1223151..de44564 100644
--- a/chrome/browser/resources/download_shelf/download_list.js
+++ b/chrome/browser/resources/download_shelf/download_list.js
@@ -44,27 +44,22 @@
     this.resizeObserver_ = new ResizeObserver(() => this.updateElements_());
     this.resizeObserver_.observe(this.listElement_);
 
-    this.apiProxy_.getDownloads().then(({downloadItems}) => {
-      this.items_ = downloadItems;
+    this.getDownloads_(true);
+    this.addDownloadListeners_();
 
-      if (this.items_.length !== 0) {
-        // Sort by descending show time so that the most recent download shows
-        // first on the row.
-        this.items_.sort((first, second) => {
-          return second.showDownloadStartTime - first.showDownloadStartTime;
-        });
-        this.updateElements_();
-
-        // Record the time it took to show the first download, that is, the
-        // download that has the least recent showDownloadStartTime.
-        this.recordDownloadPaintTime_(
-            this.items_[this.items_.length - 1].showDownloadStartTime, true);
+    document.addEventListener('visibilitychange', () => {
+      if (document.visibilityState === 'visible') {
+        this.getDownloads_(false);
+        this.addDownloadListeners_();
+      } else {
+        this.clear_();
       }
     });
+  }
 
+  /** @private */
+  addDownloadListeners_() {
     const callbackRouter = this.apiProxy_.getCallbackRouter();
-    // TODO(romanarora): Once we implement a close panel button, we should
-    // ensure it removes all listeners from this.listenerIds_ when triggered.
 
     // Triggers for downloads other than the first one, as the page handler will
     // not be ready by the first download.
@@ -97,6 +92,46 @@
   }
 
   /**
+   * @param {boolean} firstCall Whether this is the first call to the method.
+   * @private
+   */
+  getDownloads_(firstCall) {
+    this.apiProxy_.getDownloads().then(({downloadItems}) => {
+      this.items_ = downloadItems;
+
+      if (this.items_.length !== 0) {
+        // Sort by descending show time so that the most recent download shows
+        // first on the row.
+        this.items_.sort(
+            (first, second) =>
+                second.showDownloadStartTime - first.showDownloadStartTime);
+        this.updateElements_();
+
+        // Record the time it took to show the first download, that is, the
+        // download that has the least recent showDownloadStartTime.
+        if (firstCall) {
+          this.recordDownloadPaintTime_(
+              this.items_[this.items_.length - 1].showDownloadStartTime, true);
+        }
+      }
+    });
+  }
+
+  clear_() {
+    while (this.listenerIds_.length) {
+      this.apiProxy_.getCallbackRouter().removeListener(
+          this.listenerIds_.shift());
+    }
+
+    while (this.listElement_.firstChild) {
+      this.listElement_.removeChild(this.listElement_.firstChild);
+    }
+
+    this.elements_ = [];
+    this.items_ = [];
+  }
+
+  /**
    * @param {number} startTime The Unix time at which DoShowDownload() was
    *     called on the download shelf. See:
    *     chrome/browser/ui/webui/download_shelf/download_shelf_ui.h
diff --git a/chrome/browser/resources/download_shelf/download_shelf_api_proxy.js b/chrome/browser/resources/download_shelf/download_shelf_api_proxy.js
index 484760d7..20949b5 100644
--- a/chrome/browser/resources/download_shelf/download_shelf_api_proxy.js
+++ b/chrome/browser/resources/download_shelf/download_shelf_api_proxy.js
@@ -11,6 +11,8 @@
   /** @return {!PageCallbackRouter} */
   getCallbackRouter() {}
 
+  doClose() {}
+
   /**
    * @return {!Promise<{
         downloadItems: !Array<!DownloadItem>,
@@ -54,6 +56,11 @@
   }
 
   /** @override */
+  doClose() {
+    this.handler.doClose();
+  }
+
+  /** @override */
   getDownloads() {
     return this.handler.getDownloads();
   }
diff --git a/chrome/browser/resources/feed_internals/feed_internals.html b/chrome/browser/resources/feed_internals/feed_internals.html
index 322aa7be..8dd40627 100644
--- a/chrome/browser/resources/feed_internals/feed_internals.html
+++ b/chrome/browser/resources/feed_internals/feed_internals.html
@@ -181,13 +181,6 @@
   <button id="feed-stream-data-override">Override</button>
 
   <h2>WebFeed UI</h2>
-  <p>WebFeed enabled: </p>
-  <p id="webfeed-ui-enabled-status"></p>
-  <label>
-    <input type="checkbox" id="enable-webfeed-ui" name="enable-webfeed-ui">
-    Enable WebFeed UI
-  </label>
-  <button id="enable-webfeed-ui-apply">Apply</button>
   <p>WebFeed Follow Intro Debug enabled: </p>
   <p id="webfeed-follow-intro-debug-enabled-status"></p>
   <label>
diff --git a/chrome/browser/resources/feed_internals/feed_internals.js b/chrome/browser/resources/feed_internals/feed_internals.js
index e857d1b..149573f0 100644
--- a/chrome/browser/resources/feed_internals/feed_internals.js
+++ b/chrome/browser/resources/feed_internals/feed_internals.js
@@ -26,7 +26,6 @@
     $('load-stream-status').textContent = properties.loadStreamStatus;
     $('feed-fetch-url').textContent = properties.feedFetchUrl.url;
     $('feed-actions-url').textContent = properties.feedActionsUrl.url;
-    $('webfeed-ui-enabled-status').textContent = properties.isWebFeedUiEnabled;
     $('webfeed-follow-intro-debug-enabled-status').textContent =
         properties.isWebFeedFollowIntroDebugEnabled;
   });
@@ -170,10 +169,6 @@
     }
   });
 
-  $('enable-webfeed-ui-apply').addEventListener('click', function() {
-    pageHandler.setWebFeedUIEnabled($('enable-webfeed-ui').checked);
-  });
-
   $('enable-webfeed-follow-intro-debug-apply')
       .addEventListener('click', function() {
         pageHandler.setWebFeedFollowIntroDebugEnabled(
diff --git a/chrome/browser/safe_browsing/safe_browsing_metrics_collector.h b/chrome/browser/safe_browsing/safe_browsing_metrics_collector.h
index 1f06a6e..47329d9 100644
--- a/chrome/browser/safe_browsing/safe_browsing_metrics_collector.h
+++ b/chrome/browser/safe_browsing/safe_browsing_metrics_collector.h
@@ -10,6 +10,7 @@
 #include "base/timer/timer.h"
 #include "components/keyed_service/core/keyed_service.h"
 #include "components/prefs/pref_change_registrar.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class PrefService;
 
diff --git a/chrome/browser/search/background/ntp_background_service.h b/chrome/browser/search/background/ntp_background_service.h
index a586eb7e..2d0a445 100644
--- a/chrome/browser/search/background/ntp_background_service.h
+++ b/chrome/browser/search/background/ntp_background_service.h
@@ -17,6 +17,7 @@
 #include "components/keyed_service/core/keyed_service.h"
 #include "components/signin/public/identity_manager/access_token_info.h"
 #include "net/base/url_util.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 namespace network {
diff --git a/chrome/browser/speech/speech_recognizer_delegate.h b/chrome/browser/speech/speech_recognizer_delegate.h
index d7c86b26..84f3db9 100644
--- a/chrome/browser/speech/speech_recognizer_delegate.h
+++ b/chrome/browser/speech/speech_recognizer_delegate.h
@@ -9,6 +9,7 @@
 #include <string>
 
 #include "base/time/time.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 // Requires cleanup. See crbug.com/800374.
 enum SpeechRecognizerStatus {
diff --git a/chrome/browser/sync_file_system/drive_backend/sync_task_manager.cc b/chrome/browser/sync_file_system/drive_backend/sync_task_manager.cc
index 5981d93..927ae7d 100644
--- a/chrome/browser/sync_file_system/drive_backend/sync_task_manager.cc
+++ b/chrome/browser/sync_file_system/drive_backend/sync_task_manager.cc
@@ -47,11 +47,11 @@
 SyncTaskManager::PendingTask::PendingTask(base::OnceClosure task,
                                           Priority pri,
                                           int seq)
-    : wrapped_once_closure(base::AdaptCallbackForRepeating(std::move(task))),
-      priority(pri),
-      seq(seq) {}
+    : closure(std::move(task)), priority(pri), seq(seq) {}
 
-SyncTaskManager::PendingTask::PendingTask(const PendingTask& other) = default;
+SyncTaskManager::PendingTask::PendingTask(PendingTask&& other) = default;
+SyncTaskManager::PendingTask& SyncTaskManager::PendingTask::operator=(
+    PendingTask&& other) = default;
 
 SyncTaskManager::PendingTask::~PendingTask() {}
 
@@ -384,7 +384,10 @@
     return;
 
   if (!pending_tasks_.empty()) {
-    base::RepeatingClosure closure = pending_tasks_.top().wrapped_once_closure;
+    // const_cast is safe here as the `closure` is not used in determining
+    // priority in `SyncTaskManager::PendingTaskComparator()`.
+    base::OnceClosure closure =
+        std::move(const_cast<PendingTask&>(pending_tasks_.top()).closure);
     pending_tasks_.pop();
     std::move(closure).Run();
     return;
diff --git a/chrome/browser/sync_file_system/drive_backend/sync_task_manager.h b/chrome/browser/sync_file_system/drive_backend/sync_task_manager.h
index 6d298eb..a288e94 100644
--- a/chrome/browser/sync_file_system/drive_backend/sync_task_manager.h
+++ b/chrome/browser/sync_file_system/drive_backend/sync_task_manager.h
@@ -127,17 +127,16 @@
 
  private:
   struct PendingTask {
-    // TODO: Change |wrapped_once_closure| to base::OnceTask if
-    // std::priority_queue supports move-only type. In the meantime, we can
-    // wrap a base::OnceClosure via AdaptCallbackForRepeating.
-    base::RepeatingClosure wrapped_once_closure;
+    base::OnceClosure closure;
     Priority priority;
     int64_t seq;
 
     PendingTask();
     PendingTask(base::OnceClosure task, Priority pri, int seq);
-    PendingTask(const PendingTask& other);
     ~PendingTask();
+
+    PendingTask(PendingTask&& other);
+    PendingTask& operator=(PendingTask&& other);
   };
 
   struct PendingTaskComparator {
diff --git a/chrome/browser/sync_file_system/local/syncable_file_operation_runner_unittest.cc b/chrome/browser/sync_file_system/local/syncable_file_operation_runner_unittest.cc
index fecc34be..18907e6 100644
--- a/chrome/browser/sync_file_system/local/syncable_file_operation_runner_unittest.cc
+++ b/chrome/browser/sync_file_system/local/syncable_file_operation_runner_unittest.cc
@@ -387,12 +387,9 @@
   EXPECT_EQ(1, callback_count_);
 
   // Now the file must have been created and have the same content as temp_path.
-  // TODO(mek): AdaptCallbackForRepeating is needed here because
-  // CannedSyncableFileSystem hasn't switched to OnceCallback yet.
   ResetCallbackStatus();
-  file_system_.DoVerifyFile(
-      URL(kFile), kTestData,
-      base::AdaptCallbackForRepeating(ExpectStatus(FROM_HERE, File::FILE_OK)));
+  file_system_.DoVerifyFile(URL(kFile), kTestData,
+                            ExpectStatus(FROM_HERE, File::FILE_OK));
   content::RunAllTasksUntilIdle();
   EXPECT_EQ(1, callback_count_);
 }
diff --git a/chrome/browser/sync_file_system/sync_file_system_service.cc b/chrome/browser/sync_file_system/sync_file_system_service.cc
index b0d3903..51c8452 100644
--- a/chrome/browser/sync_file_system/sync_file_system_service.cc
+++ b/chrome/browser/sync_file_system/sync_file_system_service.cc
@@ -114,7 +114,7 @@
 void DidGetFileSyncStatusForDump(
     base::ListValue* files,
     size_t* num_results,
-    base::RepeatingCallback<void(const base::ListValue&)> callback,
+    base::OnceCallback<void(const base::ListValue&)>* callback,
     base::DictionaryValue* file,
     SyncStatusCode sync_status_code,
     SyncFileStatus sync_file_status) {
@@ -130,9 +130,9 @@
     return;
 
   // |callback| is backed by a DumpFilesCallback, which should only be called
-  // once. Move |callback| here to force repeated calls to crash instead of
-  // silently failing.
-  std::move(callback).Run(*files);
+  // once. The callback will only be called a single time, even though
+  // `DidGetFileSyncStatusForDump()` is called more than once.
+  std::move(*callback).Run(*files);
 }
 
 // We need this indirection because WeakPtr can only be bound to methods
@@ -573,8 +573,8 @@
   // |accumulate_callback| should only call |callback| once.
   AccumulateFileSyncStatusCallback accumulate_callback = base::BindRepeating(
       &DidGetFileSyncStatusForDump, base::Owned(dump_files.release()),
-      base::Owned(new size_t(0)),
-      base::AdaptCallbackForRepeating(std::move(callback)));
+      base::Owned(std::make_unique<size_t>(0)),
+      base::Owned(std::make_unique<DumpFilesCallback>(std::move(callback))));
 
   // After all metadata loaded, sync status can be added to each entry.
   for (size_t i = 0; i < files->GetSize(); ++i) {
diff --git a/chrome/browser/task_manager/providers/web_contents/subframe_task.cc b/chrome/browser/task_manager/providers/web_contents/subframe_task.cc
index 88eeb00..b28f1aea 100644
--- a/chrome/browser/task_manager/providers/web_contents/subframe_task.cc
+++ b/chrome/browser/task_manager/providers/web_contents/subframe_task.cc
@@ -21,7 +21,6 @@
 namespace task_manager {
 
 SubframeTask::SubframeTask(content::RenderFrameHost* render_frame_host,
-                           content::WebContents* web_contents,
                            RendererTask* main_task)
     : RendererTask(std::u16string(), nullptr, render_frame_host),
       site_instance_(render_frame_host->GetSiteInstance()),
diff --git a/chrome/browser/task_manager/providers/web_contents/subframe_task.h b/chrome/browser/task_manager/providers/web_contents/subframe_task.h
index 958b2be..48944b9 100644
--- a/chrome/browser/task_manager/providers/web_contents/subframe_task.h
+++ b/chrome/browser/task_manager/providers/web_contents/subframe_task.h
@@ -20,7 +20,6 @@
 class SubframeTask : public RendererTask {
  public:
   SubframeTask(content::RenderFrameHost* render_frame_host,
-               content::WebContents* web_contents,
                RendererTask* main_task);
   SubframeTask(const SubframeTask&) = delete;
   SubframeTask& operator=(const SubframeTask&) = delete;
diff --git a/chrome/browser/task_manager/providers/web_contents/web_contents_task_provider.cc b/chrome/browser/task_manager/providers/web_contents/web_contents_task_provider.cc
index 5a34f4f..4681502 100644
--- a/chrome/browser/task_manager/providers/web_contents/web_contents_task_provider.cc
+++ b/chrome/browser/task_manager/providers/web_contents/web_contents_task_provider.cc
@@ -304,8 +304,7 @@
       main_frame_site_instance_ = site_instance;
     } else {
       new_task = std::make_unique<SubframeTask>(
-          render_frame_host, web_contents(),
-          GetTaskForFrame(web_contents()->GetMainFrame()));
+          render_frame_host, GetTaskForFrame(web_contents()->GetMainFrame()));
     }
   }
 
diff --git a/chrome/browser/themes/theme_helper.h b/chrome/browser/themes/theme_helper.h
index 278b996..28ca8e7df 100644
--- a/chrome/browser/themes/theme_helper.h
+++ b/chrome/browser/themes/theme_helper.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_THEMES_THEME_HELPER_H_
 
 #include "base/sequence_checker.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "ui/base/resource/scale_factor.h"
 #include "ui/base/theme_provider.h"
diff --git a/chrome/browser/ui/app_list/search/arc/recommend_apps_fetcher_impl.h b/chrome/browser/ui/app_list/search/arc/recommend_apps_fetcher_impl.h
index 8d0be52..bb796ee 100644
--- a/chrome/browser/ui/app_list/search/arc/recommend_apps_fetcher_impl.h
+++ b/chrome/browser/ui/app_list/search/arc/recommend_apps_fetcher_impl.h
@@ -8,6 +8,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/timer/timer.h"
 #include "chrome/browser/ui/app_list/search/arc/recommend_apps_fetcher.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class Value;
diff --git a/chrome/browser/ui/search/search_tab_helper.cc b/chrome/browser/ui/search/search_tab_helper.cc
index c5653f3d..d3370d3 100644
--- a/chrome/browser/ui/search/search_tab_helper.cc
+++ b/chrome/browser/ui/search/search_tab_helper.cc
@@ -145,6 +145,8 @@
     instant_service_->RemoveObserver(this);
   if (auto* helper = OmniboxTabHelper::FromWebContents(web_contents_))
     helper->RemoveObserver(this);
+  if (select_file_dialog_)
+    select_file_dialog_->ListenerDestroyed();
 }
 
 void SearchTabHelper::OnTabActivated() {
diff --git a/chrome/browser/ui/toolbar/back_forward_menu_model.cc b/chrome/browser/ui/toolbar/back_forward_menu_model.cc
index 1378c56..8aebe6f2 100644
--- a/chrome/browser/ui/toolbar/back_forward_menu_model.cc
+++ b/chrome/browser/ui/toolbar/back_forward_menu_model.cc
@@ -20,6 +20,7 @@
 #include "chrome/browser/ui/browser_navigator_params.h"
 #include "chrome/browser/ui/singleton_tabs.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/common/chrome_features.h"
 #include "chrome/common/url_constants.h"
 #include "components/favicon_base/favicon_types.h"
 #include "components/grit/components_scaled_resources.h"
@@ -69,6 +70,11 @@
   if (chapter_stops)
     items += chapter_stops + 1;  // Chapter stops also need a separator.
 
+  // If the current mode is incognito, "Show Full History" should not be
+  // visible.
+  if (!ShouldShowFullHistoryBeVisible())
+    return items;
+
   // If the menu is not empty, add two positions in the end
   // for a separator and a "Show Full History" item.
   items += 2;
@@ -90,7 +96,7 @@
 
 std::u16string BackForwardMenuModel::GetLabelAt(int index) const {
   // Return label "Show Full History" for the last item of the menu.
-  if (index == GetItemCount() - 1)
+  if (ShouldShowFullHistoryBeVisible() && index == GetItemCount() - 1)
     return l10n_util::GetStringUTF16(IDS_HISTORY_SHOWFULLHISTORY_LINK);
 
   // Return an empty string for a separator.
@@ -131,7 +137,8 @@
   if (!ItemHasIcon(index))
     return ui::ImageModel();
 
-  if (index == GetItemCount() - 1) {
+  // Return icon of "Show Full History" for the last item of the menu.
+  if (ShouldShowFullHistoryBeVisible() && index == GetItemCount() - 1) {
     return ui::ImageModel::FromImage(
         ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed(
             IDR_HISTORY_FAVICON));
@@ -172,7 +179,7 @@
   DCHECK(!IsSeparator(index));
 
   // Execute the command for the last item: "Show Full History".
-  if (index == GetItemCount() - 1) {
+  if (ShouldShowFullHistoryBeVisible() && index == GetItemCount() - 1) {
     base::RecordComputedAction(BuildActionName("ShowFullHistory", -1));
     NavigateParams params(GetSingletonTabNavigateParams(
         browser_, GURL(chrome::kChromeUIHistoryURL)));
@@ -454,3 +461,9 @@
   }
   return metric_string;
 }
+
+bool BackForwardMenuModel::ShouldShowFullHistoryBeVisible() const {
+  return !browser_->profile()->IsOffTheRecord() ||
+         !base::FeatureList::IsEnabled(
+             features::kUpdateHistoryEntryPointsInIncognito);
+}
diff --git a/chrome/browser/ui/toolbar/back_forward_menu_model.h b/chrome/browser/ui/toolbar/back_forward_menu_model.h
index 98cd270..ba8b7fd 100644
--- a/chrome/browser/ui/toolbar/back_forward_menu_model.h
+++ b/chrome/browser/ui/toolbar/back_forward_menu_model.h
@@ -75,6 +75,7 @@
   FRIEND_TEST_ALL_PREFIXES(BackFwdMenuModelTest, ChapterStops);
   FRIEND_TEST_ALL_PREFIXES(BackFwdMenuModelTest, EscapeLabel);
   FRIEND_TEST_ALL_PREFIXES(BackFwdMenuModelTest, FaviconLoadTest);
+  FRIEND_TEST_ALL_PREFIXES(BackFwdMenuModelIncognitoTest, IncognitoCaseTest);
   FRIEND_TEST_ALL_PREFIXES(ChromeNavigationBrowserTest,
                            NoUserActivationSetSkipOnBackForward);
 
@@ -172,6 +173,10 @@
   // An index of -1 means no index.
   std::string BuildActionName(const std::string& name, int index) const;
 
+  // Returns true if "Show Full History" item should be visible. It is visible
+  // only in outside incognito mode.
+  bool ShouldShowFullHistoryBeVisible() const;
+
   Browser* const browser_;
 
   // The unit tests will provide their own WebContents to use.
diff --git a/chrome/browser/ui/toolbar/back_forward_menu_model_unittest.cc b/chrome/browser/ui/toolbar/back_forward_menu_model_unittest.cc
index 4c337859..fb6c4983 100644
--- a/chrome/browser/ui/toolbar/back_forward_menu_model_unittest.cc
+++ b/chrome/browser/ui/toolbar/back_forward_menu_model_unittest.cc
@@ -18,6 +18,7 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_tabstrip.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/common/chrome_features.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "chrome/test/base/test_browser_window.h"
@@ -108,13 +109,36 @@
   }
 };
 
+class BackFwdMenuModelIncognitoTest : public ChromeRenderViewHostTestHarness {
+ public:
+  BackFwdMenuModelIncognitoTest() {
+    // Enable kUpdateHistoryEntryPointsInIncognito feature flag to change menu
+    // content.
+    scoped_feature_list_.InitAndEnableFeature(
+        features::kUpdateHistoryEntryPointsInIncognito);
+  }
+
+  void LoadURLAndUpdateState(const char* url, const std::u16string& title) {
+    NavigateAndCommit(GURL(url));
+    web_contents()->UpdateTitleForEntry(controller().GetLastCommittedEntry(),
+                                        title);
+  }
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
+};
+
 TEST_F(BackFwdMenuModelTest, BasicCase) {
+  Browser::CreateParams native_params(profile(), true);
+  std::unique_ptr<Browser> browser(
+      CreateBrowserWithTestWindowForParams(native_params));
+
   std::unique_ptr<BackForwardMenuModel> back_model(new BackForwardMenuModel(
-      nullptr, BackForwardMenuModel::ModelType::kBackward));
+      browser.get(), BackForwardMenuModel::ModelType::kBackward));
   back_model->set_test_web_contents(web_contents());
 
   std::unique_ptr<BackForwardMenuModel> forward_model(new BackForwardMenuModel(
-      nullptr, BackForwardMenuModel::ModelType::kForward));
+      browser.get(), BackForwardMenuModel::ModelType::kForward));
   forward_model->set_test_web_contents(web_contents());
 
   EXPECT_EQ(0, back_model->GetItemCount());
@@ -177,12 +201,16 @@
 }
 
 TEST_F(BackFwdMenuModelTest, MaxItemsTest) {
+  Browser::CreateParams native_params(profile(), true);
+  std::unique_ptr<Browser> browser(
+      CreateBrowserWithTestWindowForParams(native_params));
+
   std::unique_ptr<BackForwardMenuModel> back_model(new BackForwardMenuModel(
-      nullptr, BackForwardMenuModel::ModelType::kBackward));
+      browser.get(), BackForwardMenuModel::ModelType::kBackward));
   back_model->set_test_web_contents(web_contents());
 
   std::unique_ptr<BackForwardMenuModel> forward_model(new BackForwardMenuModel(
-      nullptr, BackForwardMenuModel::ModelType::kForward));
+      browser.get(), BackForwardMenuModel::ModelType::kForward));
   forward_model->set_test_web_contents(web_contents());
 
   // Seed the controller with 32 URLs
@@ -259,12 +287,16 @@
 }
 
 TEST_F(BackFwdMenuModelTest, ChapterStops) {
+  Browser::CreateParams native_params(profile(), true);
+  std::unique_ptr<Browser> browser(
+      CreateBrowserWithTestWindowForParams(native_params));
+
   std::unique_ptr<BackForwardMenuModel> back_model(new BackForwardMenuModel(
-      nullptr, BackForwardMenuModel::ModelType::kBackward));
+      browser.get(), BackForwardMenuModel::ModelType::kBackward));
   back_model->set_test_web_contents(web_contents());
 
   std::unique_ptr<BackForwardMenuModel> forward_model(new BackForwardMenuModel(
-      nullptr, BackForwardMenuModel::ModelType::kForward));
+      browser.get(), BackForwardMenuModel::ModelType::kForward));
   forward_model->set_test_web_contents(web_contents());
 
   // Seed the controller with 32 URLs.
@@ -470,8 +502,12 @@
 }
 
 TEST_F(BackFwdMenuModelTest, EscapeLabel) {
+  Browser::CreateParams native_params(profile(), true);
+  std::unique_ptr<Browser> browser(
+      CreateBrowserWithTestWindowForParams(native_params));
+
   std::unique_ptr<BackForwardMenuModel> back_model(new BackForwardMenuModel(
-      nullptr, BackForwardMenuModel::ModelType::kBackward));
+      browser.get(), BackForwardMenuModel::ModelType::kBackward));
   back_model->set_test_web_contents(web_contents());
 
   EXPECT_EQ(0, back_model->GetItemCount());
@@ -561,3 +597,33 @@
   // Make sure the browser deconstructor doesn't have problems.
   browser->tab_strip_model()->CloseAllTabs();
 }
+
+// Test to check the menu in Incognito mode.
+TEST_F(BackFwdMenuModelIncognitoTest, IncognitoCaseTest) {
+  Browser::CreateParams native_params(profile()->GetPrimaryOTRProfile(true),
+                                      true);
+  std::unique_ptr<Browser> browser(
+      CreateBrowserWithTestWindowForParams(native_params));
+
+  std::unique_ptr<BackForwardMenuModel> back_model(new BackForwardMenuModel(
+      browser.get(), BackForwardMenuModel::ModelType::kBackward));
+
+  back_model->set_test_web_contents(web_contents());
+
+  EXPECT_EQ(0, back_model->GetItemCount());
+  EXPECT_FALSE(back_model->ItemHasCommand(1));
+
+  // Seed the controller with a few URLs
+  LoadURLAndUpdateState("http://www.a.com/1", u"A1");
+  LoadURLAndUpdateState("http://www.a.com/2", u"A2");
+  LoadURLAndUpdateState("http://www.a.com/3", u"A3");
+
+  // There're should be only the visited pages but not "Show Full History" item
+  // and its separator.
+  EXPECT_EQ(2, back_model->GetItemCount());
+  EXPECT_EQ(u"A2", back_model->GetLabelAt(0));
+  EXPECT_EQ(u"A1", back_model->GetLabelAt(1));
+
+  EXPECT_TRUE(back_model->ItemHasCommand(0));
+  EXPECT_TRUE(back_model->ItemHasCommand(1));
+}
diff --git a/chrome/browser/ui/views/autofill/update_address_profile_view.cc b/chrome/browser/ui/views/autofill/update_address_profile_view.cc
index eee7c80..238319d 100644
--- a/chrome/browser/ui/views/autofill/update_address_profile_view.cc
+++ b/chrome/browser/ui/views/autofill/update_address_profile_view.cc
@@ -10,7 +10,6 @@
 #include "chrome/browser/ui/views/chrome_layout_provider.h"
 #include "chrome/grit/theme_resources.h"
 #include "components/autofill/core/browser/autofill_address_util.h"
-#include "components/autofill/core/browser/data_model/autofill_profile_comparator.h"
 #include "components/autofill/core/browser/field_types.h"
 #include "components/autofill/core/common/autofill_features.h"
 #include "components/vector_icons/vector_icons.h"
@@ -28,6 +27,7 @@
 
 constexpr int kColumnSetId = 0;
 constexpr int kIconSize = 16;
+constexpr int kValuesLabelWidth = 190;
 
 int AddressDetailsIconSize() {
   // Use the line height of the body small text. This allows the icons to adapt
@@ -37,24 +37,25 @@
 }
 
 const gfx::VectorIcon& GetVectorIconForType(ServerFieldType type) {
-  // TODO(crbug.com/1167060): Update icons upon having final mocks.
   switch (type) {
     case NAME_FULL_WITH_HONORIFIC_PREFIX:
       return kAccountCircleIcon;
+    case ADDRESS_HOME_ADDRESS:
+      return vector_icons::kLocationOnIcon;
     case EMAIL_ADDRESS:
       return vector_icons::kEmailIcon;
     case PHONE_HOME_WHOLE_NUMBER:
       return vector_icons::kCallIcon;
     default:
+      NOTREACHED();
       return vector_icons::kLocationOnIcon;
   }
 }
 
-// Creates a view that displays all values in `diff_map`. `are_new_values`
-// decides which set of values from `diff_map` are displayed.
+// Creates a view that displays all values in `diff`. `are_new_values`
+// decides which set of values from `diff` are displayed.
 std::unique_ptr<views::View> CreateValuesView(
-    const base::flat_map<ServerFieldType,
-                         std::pair<std::u16string, std::u16string>>& diff_map,
+    const std::vector<ProfileValueDifference>& diff,
     bool are_new_values,
     ui::NativeTheme::ColorId icon_color) {
   auto view = std::make_unique<views::View>();
@@ -70,12 +71,9 @@
                   DISTANCE_CONTROL_LIST_VERTICAL),
               /*horizontal=*/0));
 
-  for (ServerFieldType type : kVisibleTypesForProfileDifferences) {
-    const auto it = diff_map.find(type);
-    if (it == diff_map.end())
-      continue;
+  for (const ProfileValueDifference& diff_entry : diff) {
     const std::u16string& value =
-        are_new_values ? it->second.first : it->second.second;
+        are_new_values ? diff_entry.first_value : diff_entry.second_value;
     // Don't add rows for empty original values.
     if (value.empty())
       continue;
@@ -83,7 +81,7 @@
         view->AddChildView(std::make_unique<views::View>());
     value_row->SetLayoutManager(std::make_unique<views::FlexLayout>())
         ->SetOrientation(views::LayoutOrientation::kHorizontal)
-        .SetCrossAxisAlignment(views::LayoutAlignment::kCenter)
+        .SetCrossAxisAlignment(views::LayoutAlignment::kStart)
         .SetIgnoreDefaultMainAxisMargins(true)
         .SetCollapseMargins(true)
         .SetDefault(
@@ -94,24 +92,27 @@
                     views::DISTANCE_RELATED_LABEL_HORIZONTAL)));
 
     auto icon_view = std::make_unique<views::ImageView>();
-    icon_view->SetImage(ui::ImageModel::FromVectorIcon(
-        GetVectorIconForType(type), icon_color, AddressDetailsIconSize()));
+    icon_view->SetImage(
+        ui::ImageModel::FromVectorIcon(GetVectorIconForType(diff_entry.type),
+                                       icon_color, AddressDetailsIconSize()));
 
     value_row->AddChildView(std::move(icon_view));
-    value_row->AddChildView(
-        std::make_unique<views::Label>(value, views::style::CONTEXT_LABEL));
+    auto label_view =
+        std::make_unique<views::Label>(value, views::style::CONTEXT_LABEL);
+    label_view->SetMultiLine(true);
+    label_view->SizeToFit(kValuesLabelWidth);
+    label_view->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT);
+    value_row->AddChildView(std::move(label_view));
   }
   return view;
 }
 
 // Add a row in `layout` that contains a label and a view displays all the
 // values in `values`. Labels are added only if `show_row_label` is true.
-void AddValuesRow(
-    views::GridLayout* layout,
-    const base::flat_map<ServerFieldType,
-                         std::pair<std::u16string, std::u16string>>& diff_map,
-    bool show_row_label,
-    views::Button::PressedCallback edit_button_callback) {
+void AddValuesRow(views::GridLayout* layout,
+                  const std::vector<ProfileValueDifference>& diff,
+                  bool show_row_label,
+                  views::Button::PressedCallback edit_button_callback) {
   bool are_new_values = !!edit_button_callback;
   layout->StartRow(/*vertical_resize=*/views::GridLayout::kFixedSize,
                    kColumnSetId);
@@ -128,7 +129,7 @@
   ui::NativeTheme::ColorId icon_color =
       are_new_values ? ui::NativeTheme::kColorId_ProminentButtonColor
                      : ui::NativeTheme::kColorId_SecondaryIconColor;
-  layout->AddView(CreateValuesView(diff_map, are_new_values, icon_color),
+  layout->AddView(CreateValuesView(diff, are_new_values, icon_color),
                   /*col_span=*/1,
                   /*row_span=*/1,
                   /*h_align=*/views::GridLayout::FILL,
@@ -146,17 +147,19 @@
   }
 }
 
-// Returns true if there is there is at least one entry in `diff_map` with
+// Returns true if there is there is at least one entry in `diff` with
 // non-empty second value.
-bool HasNonEmptySecondValues(
-    const base::flat_map<ServerFieldType,
-                         std::pair<std::u16string, std::u16string>>& diff_map) {
-  return base::ranges::any_of(
-      diff_map,
-      [](const std::pair<autofill::ServerFieldType,
-                         std::pair<std::u16string, std::u16string>>& entry) {
-        return !entry.second.second.empty();
-      });
+bool HasNonEmptySecondValues(const std::vector<ProfileValueDifference>& diff) {
+  return base::ranges::any_of(diff, [](const ProfileValueDifference& entry) {
+    return !entry.second_value.empty();
+  });
+}
+
+// Returns true if there is an entry coressponding to type ADDRESS_HOME_ADDRESS.
+bool HasAddressEntry(const std::vector<ProfileValueDifference>& diff) {
+  return base::ranges::any_of(diff, [](const ProfileValueDifference& entry) {
+    return entry.type == ADDRESS_HOME_ADDRESS;
+  });
 }
 
 }  // namespace
@@ -197,28 +200,25 @@
                   DISTANCE_CONTROL_LIST_VERTICAL),
               /*horizontal=*/0));
 
-  views::Label* subtitle_label = AddChildView(std::make_unique<views::Label>(
-      // TODO(crbug.com/1167060): Pass proper `include_address_and_contacts`
-      // value and handle empty description if needed.
-      GetProfileDescription(*controller_->GetOriginalProfile(),
-                            g_browser_process->GetApplicationLocale(),
-                            /*include_address_and_contacts=*/true),
-      views::style::CONTEXT_LABEL, views::style::STYLE_SECONDARY));
-  subtitle_label->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT);
+  std::vector<ProfileValueDifference> profile_diff = GetProfileDifferenceForUi(
+      controller_->GetProfileToSave(), *controller_->GetOriginalProfile(),
+      g_browser_process->GetApplicationLocale());
+
+  std::u16string subtitle = GetProfileDescription(
+      *controller_->GetOriginalProfile(),
+      g_browser_process->GetApplicationLocale(),
+      /*include_address_and_contacts=*/!HasAddressEntry(profile_diff));
+  if (!subtitle.empty()) {
+    views::Label* subtitle_label = AddChildView(std::make_unique<views::Label>(
+        subtitle, views::style::CONTEXT_LABEL, views::style::STYLE_SECONDARY));
+    subtitle_label->SetHorizontalAlignment(
+        gfx::HorizontalAlignment::ALIGN_LEFT);
+  }
 
   views::View* main_content_view =
       AddChildView(std::make_unique<views::View>());
 
-  base::flat_map<ServerFieldType, std::pair<std::u16string, std::u16string>>
-      profile_diff_map = AutofillProfileComparator::GetProfileDifferenceMap(
-          controller_->GetProfileToSave(), *controller_->GetOriginalProfile(),
-          autofill::ServerFieldTypeSet(
-              std::begin(kVisibleTypesForProfileDifferences),
-              std::end(kVisibleTypesForProfileDifferences)),
-          g_browser_process->GetApplicationLocale());
-
-  bool has_non_empty_original_values =
-      HasNonEmptySecondValues(profile_diff_map);
+  bool has_non_empty_original_values = HasNonEmptySecondValues(profile_diff);
 
   // Build the GridLayout column set.
   views::GridLayout* layout = main_content_view->SetLayoutManager(
@@ -250,7 +250,7 @@
       /*fixed_width=*/0, /*min_width=*/0);
 
   AddValuesRow(
-      layout, profile_diff_map,
+      layout, profile_diff,
       /*show_row_label=*/has_non_empty_original_values,
       /*edit_button_callback=*/
       base::BindRepeating(
@@ -261,7 +261,7 @@
     layout->AddPaddingRow(views::GridLayout::kFixedSize,
                           ChromeLayoutProvider::Get()->GetDistanceMetric(
                               DISTANCE_UNRELATED_CONTROL_VERTICAL_LARGE));
-    AddValuesRow(layout, profile_diff_map, /*show_row_label=*/true,
+    AddValuesRow(layout, profile_diff, /*show_row_label=*/true,
                  /*edit_button_callback=*/{});
   }
 }
diff --git a/chrome/browser/ui/views/download/download_shelf_web_view.cc b/chrome/browser/ui/views/download/download_shelf_web_view.cc
index f9d8b0b..de416bc7 100644
--- a/chrome/browser/ui/views/download/download_shelf_web_view.cc
+++ b/chrome/browser/ui/views/download/download_shelf_web_view.cc
@@ -107,6 +107,27 @@
   DCHECK_EQ(&shelf_animation_, animation);
   const bool shown = shelf_animation_.IsShowing();
   parent_->SetDownloadShelfVisible(shown);
+
+  // If the shelf was explicitly closed by the user, there are further steps to
+  // take to complete closing.
+  if (shown || is_hidden())
+    return;
+
+  DownloadShelfUI* download_shelf_ui = GetDownloadShelfUI();
+  if (download_shelf_ui) {
+    // Remove all downloads that are not in progress.
+    for (DownloadUIModel* model : download_shelf_ui->GetDownloads()) {
+      // Treat the item as opened when the shelf closes. This way if it gets
+      // shown again the user need not open the item for the shelf to
+      // auto-close.
+      if ((model->GetState() == download::DownloadItem::IN_PROGRESS) ||
+          model->IsDangerous()) {
+        model->SetOpened(true);
+      } else {
+        download_shelf_ui->RemoveDownload(model->download()->GetId());
+      }
+    }
+  }
 }
 
 views::View* DownloadShelfWebView::GetView() {
diff --git a/chrome/browser/ui/views/frame/webui_tab_strip_container_view.cc b/chrome/browser/ui/views/frame/webui_tab_strip_container_view.cc
index 3cb7a62..84dafb84 100644
--- a/chrome/browser/ui/views/frame/webui_tab_strip_container_view.cc
+++ b/chrome/browser/ui/views/frame/webui_tab_strip_container_view.cc
@@ -260,13 +260,6 @@
     view_observations_.AddObservation(top_container_);
 #endif  // defined(OS_WIN)
 
-    // Our observed Widget's NativeView may be destroyed before us. We
-    // have no reasonable way of un-registering our pre-target handler
-    // from the NativeView while the Widget is destroying. This disables
-    // EventHandler's check that it has been removed from all
-    // EventTargets.
-    DisableCheckTargets();
-
     content_area_->GetWidget()->GetNativeView()->AddPreTargetHandler(this);
     pretarget_handler_added_ = true;
   }
diff --git a/chrome/browser/ui/views/location_bar/custom_tab_bar_view.cc b/chrome/browser/ui/views/location_bar/custom_tab_bar_view.cc
index e6a401a8..b860518 100644
--- a/chrome/browser/ui/views/location_bar/custom_tab_bar_view.cc
+++ b/chrome/browser/ui/views/location_bar/custom_tab_bar_view.cc
@@ -218,8 +218,8 @@
   close_button_->SetFocusBehavior(views::View::FocusBehavior::ACCESSIBLE_ONLY);
   views::InstallCircleHighlightPathGenerator(close_button_);
 
-  location_icon_view_ =
-      AddChildView(std::make_unique<LocationIconView>(font_list, this, this));
+  location_icon_view_ = AddChildView(std::make_unique<LocationIconView>(
+      font_list, this, this, browser_->profile()));
 
   auto title_origin_view = std::make_unique<CustomTabBarTitleOriginView>(
       background_color_, GetShowTitle());
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc
index 44f81c1..4493075 100644
--- a/chrome/browser/ui/views/location_bar/location_bar_view.cc
+++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -193,7 +193,7 @@
       CONTEXT_OMNIBOX_PRIMARY, views::style::STYLE_PRIMARY);
 
   auto location_icon_view =
-      std::make_unique<LocationIconView>(font_list, this, this);
+      std::make_unique<LocationIconView>(font_list, this, this, profile_);
   location_icon_view->set_drag_controller(this);
   location_icon_view_ = AddChildView(std::move(location_icon_view));
 
diff --git a/chrome/browser/ui/views/location_bar/location_icon_view.cc b/chrome/browser/ui/views/location_bar/location_icon_view.cc
index 4b3aa25..29d0784 100644
--- a/chrome/browser/ui/views/location_bar/location_icon_view.cc
+++ b/chrome/browser/ui/views/location_bar/location_icon_view.cc
@@ -6,15 +6,21 @@
 
 #include "base/bind.h"
 #include "chrome/browser/extensions/extension_ui_util.h"
+#include "chrome/browser/feature_engagement/tracker_factory.h"
+#include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/layout_constants.h"
 #include "chrome/browser/ui/page_info/page_info_dialog.h"
 #include "chrome/browser/ui/view_ids.h"
 #include "chrome/browser/ui/views/page_info/page_info_bubble_view.h"
+#include "chrome/browser/ui/views/user_education/feature_promo_controller_views.h"
 #include "chrome/grit/chromium_strings.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/dom_distiller/core/url_constants.h"
+#include "components/feature_engagement/public/event_constants.h"
+#include "components/feature_engagement/public/feature_constants.h"
 #include "components/omnibox/browser/omnibox_edit_model.h"
 #include "components/omnibox/browser/omnibox_field_trial.h"
+#include "components/omnibox/common/omnibox_features.h"
 #include "components/security_state/core/security_state.h"
 #include "components/strings/grit/components_strings.h"
 #include "content/public/browser/web_contents.h"
@@ -33,8 +39,12 @@
 LocationIconView::LocationIconView(
     const gfx::FontList& font_list,
     IconLabelBubbleView::Delegate* parent_delegate,
-    Delegate* delegate)
-    : IconLabelBubbleView(font_list, parent_delegate), delegate_(delegate) {
+    Delegate* delegate,
+    Profile* profile)
+    : IconLabelBubbleView(font_list, parent_delegate),
+      delegate_(delegate),
+      feature_engagement_tracker_(
+          feature_engagement::TrackerFactory::GetForBrowserContext(profile)) {
   DCHECK(delegate_);
 
   SetID(VIEW_ID_LOCATION_ICON);
@@ -262,7 +272,23 @@
   if (!is_editing_or_empty) {
     last_update_security_level_ =
         delegate_->GetLocationBarModel()->GetSecurityLevel();
+
+    // Show in-product help for the updated connection security icon.
+    if (last_update_security_level_ == security_state::SECURE &&
+        base::FeatureList::IsEnabled(
+            omnibox::kUpdatedConnectionSecurityIndicators)) {
+      feature_engagement_tracker_->NotifyEvent(
+          feature_engagement::events::
+              kUpdatedConnectionSecurityIndicatorDisplayed);
+      FeaturePromoControllerViews* controller =
+          FeaturePromoControllerViews::GetForView(this);
+      if (controller) {
+        controller->MaybeShowPromo(
+            feature_engagement::kIPHUpdatedConnectionSecurityIndicatorsFeature);
+      }
+    }
   }
+
   was_editing_or_empty_ = is_editing_or_empty;
 }
 
diff --git a/chrome/browser/ui/views/location_bar/location_icon_view.h b/chrome/browser/ui/views/location_bar/location_icon_view.h
index 8fd6bec..65f7583a 100644
--- a/chrome/browser/ui/views/location_bar/location_icon_view.h
+++ b/chrome/browser/ui/views/location_bar/location_icon_view.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_LOCATION_ICON_VIEW_H_
 
 #include "chrome/browser/ui/views/location_bar/icon_label_bubble_view.h"
+#include "components/feature_engagement/public/tracker.h"
 #include "components/omnibox/browser/location_bar_model.h"
 #include "ui/base/metadata/metadata_header_macros.h"
 
@@ -17,6 +18,8 @@
 enum SecurityLevel;
 }
 
+class Profile;
+
 // Use a LocationIconView to display an icon on the leading side of the edit
 // field. It shows the user's current action (while the user is editing), or the
 // page security status (after navigation has completed), or extension name (if
@@ -62,7 +65,8 @@
 
   LocationIconView(const gfx::FontList& font_list,
                    IconLabelBubbleView::Delegate* parent_delegate,
-                   Delegate* delegate);
+                   Delegate* delegate,
+                   Profile* profile);
   LocationIconView(const LocationIconView&) = delete;
   LocationIconView& operator=(const LocationIconView&) = delete;
   ~LocationIconView() override;
@@ -109,26 +113,9 @@
   bool IsTriggerableEvent(const ui::Event& event) override;
 
  private:
-  // The security level when the location icon was last updated. Used to decide
-  // whether to animate security level transitions.
-  security_state::SecurityLevel last_update_security_level_ =
-      security_state::NONE;
-
-  // Whether the delegate's editing or empty flag was set the last time the
-  // location icon was updated.
-  bool was_editing_or_empty_ = false;
-
   // Returns what the minimum size would be if the preferred size were |size|.
   gfx::Size GetMinimumSizeForPreferredSize(gfx::Size size) const;
 
-  Delegate* delegate_;
-
-  // Used to scope the lifetime of asynchronous icon fetch callbacks to the
-  // lifetime of the object. Weak pointers issued by this factory are
-  // invalidated whenever we start a new icon fetch, so don't use this weak
-  // factory for any other purposes.
-  base::WeakPtrFactory<LocationIconView> icon_fetch_weak_ptr_factory_{this};
-
   // Determines whether or not a text change should be animated.
   bool GetAnimateTextVisibilityChange() const;
 
@@ -142,6 +129,25 @@
 
   // Handles the arrival of an asynchronously fetched icon.
   void OnIconFetched(const gfx::Image& image);
+
+  // The security level when the location icon was last updated. Used to decide
+  // whether to animate security level transitions.
+  security_state::SecurityLevel last_update_security_level_ =
+      security_state::NONE;
+
+  // Whether the delegate's editing or empty flag was set the last time the
+  // location icon was updated.
+  bool was_editing_or_empty_ = false;
+
+  Delegate* delegate_;
+
+  feature_engagement::Tracker* feature_engagement_tracker_;
+
+  // Used to scope the lifetime of asynchronous icon fetch callbacks to the
+  // lifetime of the object. Weak pointers issued by this factory are
+  // invalidated whenever we start a new icon fetch, so don't use this weak
+  // factory for any other purposes.
+  base::WeakPtrFactory<LocationIconView> icon_fetch_weak_ptr_factory_{this};
 };
 
 #endif  // CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_LOCATION_ICON_VIEW_H_
diff --git a/chrome/browser/ui/views/location_bar/location_icon_view_browsertest.cc b/chrome/browser/ui/views/location_bar/location_icon_view_browsertest.cc
index eabbc4c..6eab9fe5 100644
--- a/chrome/browser/ui/views/location_bar/location_icon_view_browsertest.cc
+++ b/chrome/browser/ui/views/location_bar/location_icon_view_browsertest.cc
@@ -23,8 +23,8 @@
     BrowserView* browser_view =
         BrowserView::GetBrowserViewForBrowser(browser());
     location_bar_ = browser_view->GetLocationBarView();
-    icon_view_ = std::make_unique<LocationIconView>(font_list, location_bar_,
-                                                    location_bar_);
+    icon_view_ = std::make_unique<LocationIconView>(
+        font_list, location_bar_, location_bar_, browser()->profile());
   }
 
   LocationBarView* location_bar() const { return location_bar_; }
diff --git a/chrome/browser/ui/views/location_bar/location_icon_view_unittest.cc b/chrome/browser/ui/views/location_bar/location_icon_view_unittest.cc
index 8774dc43..cfe78b6b 100644
--- a/chrome/browser/ui/views/location_bar/location_icon_view_unittest.cc
+++ b/chrome/browser/ui/views/location_bar/location_icon_view_unittest.cc
@@ -8,6 +8,7 @@
 
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
+#include "chrome/test/base/testing_profile.h"
 #include "chrome/test/views/chrome_views_test_base.h"
 #include "components/omnibox/browser/location_bar_model.h"
 #include "components/omnibox/browser/test_location_bar_model.h"
@@ -62,6 +63,8 @@
   // ChromeViewsTestBase:
   void SetUp() override {
     ChromeViewsTestBase::SetUp();
+    profile_ = std::make_unique<TestingProfile>();
+
     gfx::FontList font_list;
 
     widget_ = CreateTestWidget();
@@ -70,8 +73,8 @@
     delegate_ =
         std::make_unique<TestLocationIconDelegate>(location_bar_model());
 
-    auto view =
-        std::make_unique<LocationIconView>(font_list, delegate(), delegate());
+    auto view = std::make_unique<LocationIconView>(font_list, delegate(),
+                                                   delegate(), profile_.get());
     view->SetBoundsRect(gfx::Rect(0, 0, 24, 24));
     view_ = widget_->SetContentsView(std::move(view));
 
@@ -80,6 +83,7 @@
 
   void TearDown() override {
     widget_.reset();
+    profile_.reset();
     ChromeViewsTestBase::TearDown();
   }
 
@@ -106,6 +110,7 @@
   std::unique_ptr<TestLocationIconDelegate> delegate_;
   LocationIconView* view_;
   std::unique_ptr<views::Widget> widget_;
+  std::unique_ptr<TestingProfile> profile_;
 };
 
 TEST_F(LocationIconViewTest, ShouldNotAnimateWhenSuppressingAnimations) {
diff --git a/chrome/browser/ui/views/profiles/profile_picker_sign_in_flow_controller.cc b/chrome/browser/ui/views/profiles/profile_picker_sign_in_flow_controller.cc
index ec63949..a21e4684 100644
--- a/chrome/browser/ui/views/profiles/profile_picker_sign_in_flow_controller.cc
+++ b/chrome/browser/ui/views/profiles/profile_picker_sign_in_flow_controller.cc
@@ -471,9 +471,8 @@
   // profiles::OpenBrowserWindowForProfile() to be a OnceCallback as it is only
   // called once.
   profiles::OpenBrowserWindowForProfile(
-      base::AdaptCallbackForRepeating(
-          base::BindOnce(&ProfilePickerSignInFlowController::OnBrowserOpened,
-                         weak_ptr_factory_.GetWeakPtr(), std::move(callback))),
+      base::BindOnce(&ProfilePickerSignInFlowController::OnBrowserOpened,
+                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)),
       /*always_create=*/false,   // Don't create a window if one already exists.
       /*is_new_profile=*/false,  // Don't create a first run window.
       /*unblock_extensions=*/false,  // There is no need to unblock all
diff --git a/chrome/browser/ui/views/profiles/profile_picker_view.cc b/chrome/browser/ui/views/profiles/profile_picker_view.cc
index 5781279..015ac6d2 100644
--- a/chrome/browser/ui/views/profiles/profile_picker_view.cc
+++ b/chrome/browser/ui/views/profiles/profile_picker_view.cc
@@ -603,10 +603,11 @@
           ->GetProfileAttributesStorage()
           .ChooseNameForNewProfile(icon_index),
       icon_index, /*is_hidden=*/true,
-      base::BindRepeating(&ProfilePickerView::OnProfileForSigninCreated,
-                          weak_ptr_factory_.GetWeakPtr(), profile_color,
-                          base::AdaptCallbackForRepeating(
-                              std::move(switch_finished_callback))));
+      base::BindRepeating(
+          &ProfilePickerView::OnProfileForSigninCreated,
+          weak_ptr_factory_.GetWeakPtr(), profile_color,
+          base::Owned(std::make_unique<base::OnceCallback<void(bool)>>(
+              std::move(switch_finished_callback)))));
 }
 
 void ProfilePickerView::CancelSignIn() {
@@ -644,18 +645,18 @@
 
 void ProfilePickerView::OnProfileForSigninCreated(
     SkColor profile_color,
-    base::RepeatingCallback<void(bool)> switch_finished_callback,
+    base::OnceCallback<void(bool)>* switch_finished_callback,
     Profile* profile,
     Profile::CreateStatus status) {
   if (status == Profile::CREATE_STATUS_LOCAL_FAIL) {
-    std::move(switch_finished_callback).Run(false);
+    std::move(*switch_finished_callback).Run(false);
     return;
   } else if (status != Profile::CREATE_STATUS_INITIALIZED) {
     return;
   }
 
   DCHECK(profile);
-  std::move(switch_finished_callback).Run(true);
+  std::move(*switch_finished_callback).Run(true);
 
   if (signin_util::IsForceSigninEnabled()) {
     // Show the embedded sign-in flow if the force signin is enabled.
diff --git a/chrome/browser/ui/views/profiles/profile_picker_view.h b/chrome/browser/ui/views/profiles/profile_picker_view.h
index 82ef392..7668089 100644
--- a/chrome/browser/ui/views/profiles/profile_picker_view.h
+++ b/chrome/browser/ui/views/profiles/profile_picker_view.h
@@ -139,7 +139,7 @@
   // On creation success for the sign-in profile, it rebuilds the view.
   void OnProfileForSigninCreated(
       SkColor profile_color,
-      base::RepeatingCallback<void(bool)> switch_finished_callback,
+      base::OnceCallback<void(bool)>* switch_finished_callback,
       Profile* new_profile,
       Profile::CreateStatus status);
 
diff --git a/chrome/browser/ui/views/user_education/feature_promo_registry.cc b/chrome/browser/ui/views/user_education/feature_promo_registry.cc
index 917365a..6c315d2 100644
--- a/chrome/browser/ui/views/user_education/feature_promo_registry.cc
+++ b/chrome/browser/ui/views/user_education/feature_promo_registry.cc
@@ -44,6 +44,11 @@
       ->GetIconView(PageActionIconType::kPwaInstall);
 }
 
+// kIPHUpdatedConnectionSecurityIndicatorsFeature:
+views::View* GetLocationIconView(BrowserView* browser_view) {
+  return browser_view->toolbar()->location_bar()->location_icon_view();
+}
+
 // kIPHDesktopTabGroupsNewGroupFeature:
 views::View* GetTabGroupsAnchorView(BrowserView* browser_view) {
   constexpr int kPreferredAnchorTab = 2;
@@ -173,6 +178,18 @@
   }
 
   {
+    // kIPHUpdatedConnectionSecurityIndicatorsFeature:
+    FeaturePromoBubbleParams params;
+    params.body_string_specifier =
+        IDS_UPDATED_CONNECTION_SECURITY_INDICATORS_PROMO;
+    params.arrow = views::BubbleBorder::Arrow::TOP_LEFT;
+
+    RegisterFeature(
+        feature_engagement::kIPHUpdatedConnectionSecurityIndicatorsFeature,
+        params, base::BindRepeating(GetLocationIconView));
+  }
+
+  {
     // kIPHDesktopTabGroupsNewGroupFeature:
     FeaturePromoBubbleParams params;
     params.body_string_specifier = IDS_TAB_GROUPS_NEW_GROUP_PROMO;
diff --git a/chrome/browser/ui/webui/download_shelf/download_shelf.mojom b/chrome/browser/ui/webui/download_shelf/download_shelf.mojom
index 9896794..32b4113 100644
--- a/chrome/browser/ui/webui/download_shelf/download_shelf.mojom
+++ b/chrome/browser/ui/webui/download_shelf/download_shelf.mojom
@@ -192,6 +192,9 @@
 
 // Browser-side handler for requests from WebUI page.
 interface PageHandler {
+  // Notify the Views component to hide itself.
+  DoClose();
+
   // Returns an array of download items.
   GetDownloads() => (array<DownloadItem> download_items);
 
diff --git a/chrome/browser/ui/webui/download_shelf/download_shelf_handler.h b/chrome/browser/ui/webui/download_shelf/download_shelf_handler.h
index bfdc406..a34d3e7 100644
--- a/chrome/browser/ui/webui/download_shelf/download_shelf_handler.h
+++ b/chrome/browser/ui/webui/download_shelf/download_shelf_handler.h
@@ -13,6 +13,9 @@
  public:
   virtual ~DownloadShelfHandler() = default;
 
+  // Notify the Views component to hide itself.
+  virtual void DoClose() = 0;
+
   virtual void GetDownloads(
       download_shelf::mojom::PageHandler::GetDownloadsCallback callback) = 0;
 
@@ -21,7 +24,7 @@
                                int32_t client_y,
                                double timestamp) = 0;
 
-  // Notify the view to show a new download.
+  // Notify the WebUI to show a new download.
   virtual void DoShowDownload(DownloadUIModel* download_model) = 0;
 
   virtual void OnDownloadUpdated(DownloadUIModel* download_model) = 0;
diff --git a/chrome/browser/ui/webui/download_shelf/download_shelf_page_handler.cc b/chrome/browser/ui/webui/download_shelf/download_shelf_page_handler.cc
index 66bde440..c182d63 100644
--- a/chrome/browser/ui/webui/download_shelf/download_shelf_page_handler.cc
+++ b/chrome/browser/ui/webui/download_shelf/download_shelf_page_handler.cc
@@ -32,6 +32,10 @@
 
 DownloadShelfPageHandler::~DownloadShelfPageHandler() = default;
 
+void DownloadShelfPageHandler::DoClose() {
+  download_shelf_ui_->DoClose();
+}
+
 void DownloadShelfPageHandler::GetDownloads(GetDownloadsCallback callback) {
   TRACE_EVENT0("browser",
                "custom_metric:DownloadShelfPageHandler:GetDownloads");
diff --git a/chrome/browser/ui/webui/download_shelf/download_shelf_page_handler.h b/chrome/browser/ui/webui/download_shelf/download_shelf_page_handler.h
index 2c1d8e8..ebb17e1 100644
--- a/chrome/browser/ui/webui/download_shelf/download_shelf_page_handler.h
+++ b/chrome/browser/ui/webui/download_shelf/download_shelf_page_handler.h
@@ -29,6 +29,7 @@
   ~DownloadShelfPageHandler() override;
 
   // download_shelf::mojom::PageHandler:
+  void DoClose() override;
   void GetDownloads(GetDownloadsCallback callback) override;
   void ShowContextMenu(uint32_t download_id,
                        int32_t client_x,
diff --git a/chrome/browser/ui/webui/download_shelf/download_shelf_ui.cc b/chrome/browser/ui/webui/download_shelf/download_shelf_ui.cc
index 4b1b30b..c71efc30 100644
--- a/chrome/browser/ui/webui/download_shelf/download_shelf_ui.cc
+++ b/chrome/browser/ui/webui/download_shelf/download_shelf_ui.cc
@@ -13,6 +13,7 @@
 #include "chrome/grit/download_shelf_resources.h"
 #include "chrome/grit/download_shelf_resources_map.h"
 #include "chrome/grit/generated_resources.h"
+#include "components/strings/grit/components_strings.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_ui_data_source.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
@@ -41,6 +42,7 @@
   content::WebUIDataSource* source =
       content::WebUIDataSource::Create(chrome::kChromeUIDownloadShelfHost);
   static constexpr webui::LocalizedString kStrings[] = {
+      {"close", IDS_ACCNAME_CLOSE},
       {"discardButtonText", IDS_DISCARD_DOWNLOAD}};
   source->AddLocalizedStrings(kStrings);
 
@@ -74,6 +76,11 @@
       std::move(receiver), std::move(page), this);
 }
 
+void DownloadShelfUI::DoClose() {
+  if (embedder())
+    embedder()->DoClose();
+}
+
 void DownloadShelfUI::ShowContextMenu(
     uint32_t download_id,
     int32_t client_x,
@@ -116,6 +123,16 @@
   return show_download_time_map_[download_id];
 }
 
+void DownloadShelfUI::RemoveDownload(uint32_t download_id) {
+  DownloadUIModel* download_ui_model = items_.at(download_id).get();
+  download_ui_model->download()->RemoveObserver(this);
+  items_.erase(download_id);
+
+  if (show_download_time_map_.count(download_id)) {
+    show_download_time_map_.erase(download_id);
+  }
+}
+
 void DownloadShelfUI::OnDownloadUpdated(DownloadItem* download) {
   if (page_handler_) {
     DownloadUIModel* download_model = FindDownloadById(download->GetId());
diff --git a/chrome/browser/ui/webui/download_shelf/download_shelf_ui.h b/chrome/browser/ui/webui/download_shelf/download_shelf_ui.h
index 4ca3f8406..9d27f81b 100644
--- a/chrome/browser/ui/webui/download_shelf/download_shelf_ui.h
+++ b/chrome/browser/ui/webui/download_shelf/download_shelf_ui.h
@@ -39,6 +39,8 @@
   void set_embedder(DownloadShelfUIEmbedder* embedder) { embedder_ = embedder; }
   DownloadShelfUIEmbedder* embedder() const { return embedder_; }
 
+  void DoClose();
+
   void ShowContextMenu(uint32_t download_id,
                        int32_t client_x,
                        int32_t client_y,
@@ -50,6 +52,8 @@
   std::vector<DownloadUIModel*> GetDownloads();
   base::TimeTicks GetShowDownloadTime(uint32_t download_id);
 
+  void RemoveDownload(uint32_t download_id);
+
  protected:
   void SetPageHandlerForTesting(
       std::unique_ptr<DownloadShelfHandler> page_handler);
diff --git a/chrome/browser/ui/webui/download_shelf/download_shelf_ui_embedder.h b/chrome/browser/ui/webui/download_shelf/download_shelf_ui_embedder.h
index cd57656..3d0f9cc 100644
--- a/chrome/browser/ui/webui/download_shelf/download_shelf_ui_embedder.h
+++ b/chrome/browser/ui/webui/download_shelf/download_shelf_ui_embedder.h
@@ -14,6 +14,8 @@
   DownloadShelfUIEmbedder() = default;
   virtual ~DownloadShelfUIEmbedder() = default;
 
+  virtual void DoClose() = 0;
+
   // Show the context menu for |download| at |position| in container's
   // coordinate.
   virtual void ShowDownloadContextMenu(
diff --git a/chrome/browser/ui/webui/download_shelf/download_shelf_ui_unittest.cc b/chrome/browser/ui/webui/download_shelf/download_shelf_ui_unittest.cc
index 4227eb3..658197a 100644
--- a/chrome/browser/ui/webui/download_shelf/download_shelf_ui_unittest.cc
+++ b/chrome/browser/ui/webui/download_shelf/download_shelf_ui_unittest.cc
@@ -22,6 +22,7 @@
 
 class TestDownloadShelfHandler : public DownloadShelfHandler {
  public:
+  MOCK_METHOD0(DoClose, void());
   MOCK_METHOD1(GetDownloads,
                void(download_shelf::mojom::PageHandler::GetDownloadsCallback));
   MOCK_METHOD4(ShowContextMenu,
diff --git a/chrome/browser/ui/webui/feed_internals/feed_internals.mojom b/chrome/browser/ui/webui/feed_internals/feed_internals.mojom
index 1fc7f9cf..9ea6a2a 100644
--- a/chrome/browser/ui/webui/feed_internals/feed_internals.mojom
+++ b/chrome/browser/ui/webui/feed_internals/feed_internals.mojom
@@ -21,9 +21,6 @@
   // Whether prefetching for offline availability is enabled.
   bool is_prefetching_enabled;
 
-  // Whether the WebFeed UI is enabled.
-  bool is_web_feed_ui_enabled;
-
   // Whether debugging the WebFeed follow intro is enabled.
   bool is_web_feed_follow_intro_debug_enabled;
 
@@ -139,9 +136,6 @@
   // testing purpose. See go/feed-stream-data-testing for more details.
   OverrideFeedStreamData(array<uint8> data);
 
-  // Sets whether the WebFeed UI is enabled.
-  SetWebFeedUIEnabled(bool enabled);
-
   // Sets whether debugging the WebFeed follow intro is enabled.
   SetWebFeedFollowIntroDebugEnabled(bool enabled);
 };
diff --git a/chrome/browser/ui/webui/feed_internals/feedv2_internals_page_handler.cc b/chrome/browser/ui/webui/feed_internals/feedv2_internals_page_handler.cc
index ab24113..a1e1ece 100644
--- a/chrome/browser/ui/webui/feed_internals/feedv2_internals_page_handler.cc
+++ b/chrome/browser/ui/webui/feed_internals/feedv2_internals_page_handler.cc
@@ -58,7 +58,6 @@
   properties->is_feed_allowed = IsFeedAllowed();
   properties->is_prefetching_enabled =
       offline_pages::prefetch_prefs::IsEnabled(pref_service_);
-  properties->is_web_feed_ui_enabled = IsWebFeedUIEnabled();
   properties->is_web_feed_follow_intro_debug_enabled =
       IsWebFeedFollowIntroDebugEnabled();
   if (debug_data.fetch_info)
@@ -161,14 +160,6 @@
   feed_stream_->SetForcedStreamUpdateForDebugging(stream_update);
 }
 
-bool FeedV2InternalsPageHandler::IsWebFeedUIEnabled() {
-  return pref_service_->GetBoolean(feed::prefs::kEnableWebFeedUI);
-}
-
-void FeedV2InternalsPageHandler::SetWebFeedUIEnabled(const bool enabled) {
-  pref_service_->SetBoolean(feed::prefs::kEnableWebFeedUI, enabled);
-}
-
 bool FeedV2InternalsPageHandler::IsWebFeedFollowIntroDebugEnabled() {
   return pref_service_->GetBoolean(feed::prefs::kEnableWebFeedFollowIntroDebug);
 }
diff --git a/chrome/browser/ui/webui/feed_internals/feedv2_internals_page_handler.h b/chrome/browser/ui/webui/feed_internals/feedv2_internals_page_handler.h
index b31f6069..e6fb30d 100644
--- a/chrome/browser/ui/webui/feed_internals/feedv2_internals_page_handler.h
+++ b/chrome/browser/ui/webui/feed_internals/feedv2_internals_page_handler.h
@@ -46,12 +46,10 @@
   void OverrideFeedHost(const GURL& host) override;
   void OverrideDiscoverApiEndpoint(const GURL& endpoint_url) override;
   void OverrideFeedStreamData(const std::vector<uint8_t>& data) override;
-  void SetWebFeedUIEnabled(const bool enabled) override;
   void SetWebFeedFollowIntroDebugEnabled(const bool enabled) override;
 
  private:
   bool IsFeedAllowed();
-  bool IsWebFeedUIEnabled();
   bool IsWebFeedFollowIntroDebugEnabled();
 
   mojo::Receiver<feed_internals::mojom::PageHandler> receiver_;
diff --git a/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.cc b/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.cc
index fd34c4c..558f6f72 100644
--- a/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.cc
+++ b/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.cc
@@ -211,9 +211,8 @@
       shutdown_subscription_(
           DiceTurnSyncOnHelperShutdownNotifierFactory::GetInstance()
               ->Get(profile)
-              ->Subscribe(base::AdaptCallbackForRepeating(
-                  base::BindOnce(&DiceTurnSyncOnHelper::AbortAndDelete,
-                                 base::Unretained(this))))) {
+              ->Subscribe(base::BindOnce(&DiceTurnSyncOnHelper::AbortAndDelete,
+                                         base::Unretained(this)))) {
   DCHECK(delegate_);
   DCHECK(profile_);
   // Should not start syncing if the profile is already authenticated
@@ -620,8 +619,8 @@
   shutdown_subscription_ =
       DiceTurnSyncOnHelperShutdownNotifierFactory::GetInstance()
           ->Get(profile_)
-          ->Subscribe(base::AdaptCallbackForRepeating(base::BindOnce(
-              &DiceTurnSyncOnHelper::AbortAndDelete, base::Unretained(this))));
+          ->Subscribe(base::BindOnce(&DiceTurnSyncOnHelper::AbortAndDelete,
+                                     base::Unretained(this)));
   delegate_->SwitchToProfile(new_profile);
 }
 
diff --git a/chrome/browser/upgrade_detector/upgrade_detector.cc b/chrome/browser/upgrade_detector/upgrade_detector.cc
index 722e518..8eb14d0 100644
--- a/chrome/browser/upgrade_detector/upgrade_detector.cc
+++ b/chrome/browser/upgrade_detector/upgrade_detector.cc
@@ -4,10 +4,15 @@
 
 #include "chrome/browser/upgrade_detector/upgrade_detector.h"
 
+#include <vector>
+
 #include "base/bind.h"
+#include "base/check.h"
 #include "base/command_line.h"
+#include "base/rand_util.h"
 #include "base/time/clock.h"
 #include "base/time/tick_clock.h"
+#include "base/values.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
 #include "chrome/browser/ui/browser_list.h"
@@ -16,14 +21,21 @@
 #include "chrome/common/pref_names.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/base/idle/idle.h"
 
+namespace {
+
 // How long to wait between checks for whether the user has been idle.
-static const int kIdleRepeatingTimerWait = 10;  // Minutes (seconds if testing).
+constexpr int kIdleRepeatingTimerWait = 10;  // Minutes (seconds if testing).
 
 // How much idle time (since last input even was detected) must have passed
 // until we notify that a critical update has occurred.
-static const int kIdleAmount = 2;  // Hours (or seconds, if testing).
+constexpr int kIdleAmount = 2;  // Hours (or seconds, if testing).
+
+// Maximum duration for a relaunch window.
+constexpr base::TimeDelta kRelaunchWindowMaxDuration =
+    base::TimeDelta::FromHours(24);
 
 bool UseTestingIntervals() {
   // If a command line parameter specifying how long the upgrade check should
@@ -34,6 +46,43 @@
               .empty();
 }
 
+// Returns the start time of the relaunch window on the day of `time`.
+base::Time ComputeRelaunchWindowStartForDay(
+    const UpgradeDetector::RelaunchWindow& window,
+    base::Time time) {
+  base::Time::Exploded window_start_exploded;
+  time.LocalExplode(&window_start_exploded);
+  window_start_exploded.hour = window.hour;
+  window_start_exploded.minute = window.minute;
+  window_start_exploded.second = 0;
+  window_start_exploded.millisecond = 0;
+  base::Time window_start;
+  if (!base::Time::FromLocalExploded(window_start_exploded, &window_start)) {
+    // The start time doesn't exist on that day; likely due to a TZ change at
+    // that precise moment (e.g., `window` is 02:00 for zones that observe DST
+    // changes at 2am local time). Move forward/backward by one hour and try
+    // again. As of this writing, Australia/Lord_Howe is the only zone that
+    // doesn't change by one full hour on transitions. Meaning no disrespect to
+    // its residents, it is simpler to be fuzzy for that one timezone than to be
+    // absolutely accurate.
+    if (window_start_exploded.hour < 23) {
+      ++window_start_exploded.hour;
+    } else {
+      --window_start_exploded.hour;
+    }
+    CHECK(base::Time::FromLocalExploded(window_start_exploded, &window_start));
+  }
+  return window_start;
+}
+
+// Returns random TimeDelta uniformly selected between zero and `max`.
+base::TimeDelta GenRandomTimeDelta(base::TimeDelta max) {
+  return base::TimeDelta::FromMicroseconds(
+      base::RandGenerator(max.InMicroseconds()));
+}
+
+}  // namespace
+
 // static
 void UpgradeDetector::RegisterPrefs(PrefRegistrySimple* registry) {
   registry->RegisterBooleanPref(prefs::kAttemptedToEnableAutoupdate, false);
@@ -129,6 +178,104 @@
          kChromeMenuOnly;
 }
 
+// static
+base::Time UpgradeDetector::AdjustDeadline(base::Time deadline) {
+  const RelaunchWindow window = GetRelaunchWindow();
+  DCHECK(window.IsValid());
+  const base::TimeDelta duration = window.duration;
+
+  // Window duration greater than equal to 24 hours means window covers the
+  // whole day, so no need to adjust.
+  if (duration >= kRelaunchWindowMaxDuration)
+    return deadline;
+
+  // Compute the window on the day of the deadline.
+  const base::Time window_start =
+      ComputeRelaunchWindowStartForDay(window, deadline);
+
+  if (deadline >= window_start + duration) {
+    // Push the deadline forward into a random interval in the next day's
+    // window. The next day may be 25, 24 or 23 hours in the future. Take a stab
+    // at 24 hours (the norm) and retry once if needed.
+    base::Time next_window_start = ComputeRelaunchWindowStartForDay(
+        window, deadline + base::TimeDelta::FromHours(24));
+    if (next_window_start == window_start) {
+      // The clocks must be set back, yielding a longer day. For example, 24
+      // hours after a deadline of 00:30 could be at 23:30 on the same day due
+      // to a DST change in the interim that sets clocks backward by one hour.
+      // Try again. Use 26 rather than 25 in case some jurisdiction decides to
+      // implement a shift of greater than 1 hour.
+      next_window_start = ComputeRelaunchWindowStartForDay(
+          window, deadline + base::TimeDelta::FromHours(26));
+    } else if (next_window_start - window_start >=
+               base::TimeDelta::FromHours(26)) {
+      // The clocks must be set forward, yielding a shorter day, and we jumped
+      // two days rather than one. For example, 24 hours after a deadline of
+      // 23:30 could be at 00:30 two days later due to a DST change in the
+      // interim that sets clocks forward by one hour". Try again.
+      next_window_start = ComputeRelaunchWindowStartForDay(
+          window, deadline + base::TimeDelta::FromHours(23));
+    }
+    return next_window_start + GenRandomTimeDelta(duration);
+  }
+
+  // Is the deadline within this day's window?
+  if (deadline >= window_start)
+    return deadline;
+
+  // Compute the relaunch window starting on the day prior to the deadline for
+  // cases where the relaunch window straddles midnight.
+  base::Time prev_window_start = ComputeRelaunchWindowStartForDay(
+      window, deadline - base::TimeDelta::FromHours(24));
+  // The above cases do not apply here:
+  // a) Previous day window jumped two days rather than one - This could arise
+  // if, for example, 24 hours before the deadline of 00:30 is 23:30 two days
+  // ago due to a DST change in the interim that set clocks forward by one hour.
+  // But then 00:30 would actually mean 01:30 this day which would mean 00:30 on
+  // the previous day. b) Previous day window on the same day - This could arise
+  // if, for example, 24 hours before the deadline of 23:30 is 00:30 on the same
+  // day due to clocks set back at by one hour. This is already covered in the
+  // above condition `deadline >= window_start`.
+  if (deadline < prev_window_start + duration)
+    return deadline;
+
+  // The deadline is after previous day's window. Push the deadline forward into
+  // a random interval in the day's window.
+  return window_start + GenRandomTimeDelta(duration);
+}
+
+// static
+UpgradeDetector::RelaunchWindow UpgradeDetector::GetRelaunchWindow() {
+  // Not all tests provide a PrefService for local_state().
+  auto* local_state = g_browser_process->local_state();
+  if (!local_state)
+    return GetDefaultRelaunchWindow();
+
+  const auto* preference = local_state->FindPreference(prefs::kRelaunchWindow);
+  DCHECK(preference);
+  if (preference->IsDefaultValue())
+    return GetDefaultRelaunchWindow();
+
+  const base::Value* policy_value = preference->GetValue();
+  DCHECK(policy_value->is_dict());
+
+  const base::Value* entries = policy_value->FindListKey("entries");
+  if (!entries || entries->GetList().empty())
+    return GetDefaultRelaunchWindow();
+
+  // Currently only single daily window is supported.
+  const auto& window = entries->GetList().front();
+  const absl::optional<int> hour = window.FindIntPath("start.hour");
+  const absl::optional<int> minute = window.FindIntPath("start.minute");
+  const absl::optional<int> duration_mins = window.FindIntKey("duration_mins");
+
+  if (!hour || !minute || !duration_mins)
+    return GetDefaultRelaunchWindow();
+
+  return RelaunchWindow(hour.value(), minute.value(),
+                        base::TimeDelta::FromMinutes(duration_mins.value()));
+}
+
 void UpgradeDetector::NotifyUpgrade() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   // An implementation will request that a notification be sent after dropping
diff --git a/chrome/browser/upgrade_detector/upgrade_detector.h b/chrome/browser/upgrade_detector/upgrade_detector.h
index 0565ee0..1aea3fe 100644
--- a/chrome/browser/upgrade_detector/upgrade_detector.h
+++ b/chrome/browser/upgrade_detector/upgrade_detector.h
@@ -49,6 +49,23 @@
     UPGRADE_ANNOYANCE_MAX_VALUE = UPGRADE_ANNOYANCE_VERY_LOW
   };
 
+  struct RelaunchWindow {
+    constexpr RelaunchWindow(int start_hour,
+                             int start_minute,
+                             base::TimeDelta duration)
+        : hour(start_hour), minute(start_minute), duration(duration) {}
+
+    bool IsValid() const {
+      return hour >= 0 && hour <= 23 && minute >= 0 && minute <= 59 &&
+             duration >= base::TimeDelta::FromMinutes(1) &&
+             duration != base::TimeDelta::Max();
+    }
+
+    int hour;
+    int minute;
+    base::TimeDelta duration;
+  };
+
   // Returns the singleton implementation instance.
   static UpgradeDetector* GetInstance();
 
@@ -188,6 +205,21 @@
   static base::TimeDelta GetRelaunchNotificationPeriod();
   static bool IsRelaunchNotificationPolicyEnabled();
 
+  // Returns the adjusted deadline as per the relaunch window from
+  // `UpgradeDetector::GetRelaunchWindow()`. If the deadline has already passed
+  // the window for the day, it is prolonged for the next day within the window.
+  // If the `deadline` already falls within the window, no change is made.
+  static base::Time AdjustDeadline(base::Time deadline);
+
+  // Returns the relaunch window specified via the RelaunchWindow policy
+  // setting, or the default one via
+  // 'UpgradeDetector::GetDefaultRelaunchWindow()` if unset or set incorrectly.
+  static RelaunchWindow GetRelaunchWindow();
+
+  // Returns the default relaunch window within which the relaunch should take
+  // place. It is 2am to 4am from Chrome OS and the whole day for others.
+  static RelaunchWindow GetDefaultRelaunchWindow();
+
   const base::Clock* clock() {
     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
     return clock_;
diff --git a/chrome/browser/upgrade_detector/upgrade_detector_chromeos.cc b/chrome/browser/upgrade_detector/upgrade_detector_chromeos.cc
index cb7db9a..fe1d63a 100644
--- a/chrome/browser/upgrade_detector/upgrade_detector_chromeos.cc
+++ b/chrome/browser/upgrade_detector/upgrade_detector_chromeos.cc
@@ -13,11 +13,11 @@
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/no_destructor.h"
-#include "base/rand_util.h"
 #include "base/threading/sequenced_task_runner_handle.h"
 #include "base/time/clock.h"
 #include "base/time/default_clock.h"
 #include "base/time/default_tick_clock.h"
+#include "base/time/time.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/upgrade_detector/build_state.h"
 #include "chrome/common/pref_names.h"
@@ -167,51 +167,6 @@
   return base::TimeDelta::FromMilliseconds(value);
 }
 
-// static
-base::TimeDelta UpgradeDetectorChromeos::GenRandomTimeDelta(
-    base::TimeDelta max) {
-  return max * base::RandDouble();
-}
-
-// static
-base::Time UpgradeDetectorChromeos::AdjustDeadline(base::Time deadline) {
-  // Compute the offset applied to GMT to get local time at |deadline|.
-  const icu::TimeZone& time_zone =
-      chromeos::system::TimezoneSettings::GetInstance()->GetTimezone();
-  UErrorCode status = U_ZERO_ERROR;
-  int32_t raw_offset, dst_offset;
-  time_zone.getOffset(deadline.ToDoubleT() * base::Time::kMillisecondsPerSecond,
-                      true /* local */, raw_offset, dst_offset, status);
-  base::TimeDelta time_zone_offset;
-  if (U_FAILURE(status)) {
-    LOG(ERROR) << "Failed to get time zone offset, error code: " << status;
-    // The fallback case is to get the raw timezone offset ignoring the daylight
-    // saving time.
-    time_zone_offset =
-        base::TimeDelta::FromMilliseconds(time_zone.getRawOffset());
-  } else {
-    time_zone_offset =
-        base::TimeDelta::FromMilliseconds(raw_offset + dst_offset);
-  }
-
-  // To get local midnight add timezone offset to deadline and treat this time
-  // as UTC based to use UTCMidnight(), then subtract timezone offset.
-  auto midnight =
-      (deadline + time_zone_offset).UTCMidnight() - time_zone_offset;
-  const auto day_time = deadline - midnight;
-  // Return the exact deadline if it naturally falls between 2am and 4am.
-  if (day_time >= base::TimeDelta::FromHours(2) &&
-      day_time <= base::TimeDelta::FromHours(4)) {
-    return deadline;
-  }
-  // Advance to the next day if the deadline falls after 4am.
-  if (day_time > base::TimeDelta::FromHours(4))
-    midnight += base::TimeDelta::FromDays(1);
-
-  return midnight + base::TimeDelta::FromHours(2) +
-         GenRandomTimeDelta(base::TimeDelta::FromHours(2));
-}
-
 void UpgradeDetectorChromeos::CalculateDeadlines() {
   base::TimeDelta notification_period = GetRelaunchNotificationPeriod();
   if (notification_period.is_zero())
@@ -358,3 +313,10 @@
 base::TimeDelta UpgradeDetector::GetDefaultElevatedAnnoyanceThreshold() {
   return kDefaultElevatedThreshold;
 }
+
+// static
+UpgradeDetector::RelaunchWindow UpgradeDetector::GetDefaultRelaunchWindow() {
+  // Two hours starting at 2am.
+  return RelaunchWindow(/*start_hour=*/2, /*start_minute=*/0,
+                        base::TimeDelta::FromHours(2));
+}
diff --git a/chrome/browser/upgrade_detector/upgrade_detector_chromeos.h b/chrome/browser/upgrade_detector/upgrade_detector_chromeos.h
index a8978be..c3b832a2 100644
--- a/chrome/browser/upgrade_detector/upgrade_detector_chromeos.h
+++ b/chrome/browser/upgrade_detector/upgrade_detector_chromeos.h
@@ -49,17 +49,9 @@
   UpgradeDetectorChromeos(const base::Clock* clock,
                           const base::TickClock* tick_clock);
 
-  // Return adjusted high annoyance deadline which takes place at night between
-  // 2am and 4am. If |deadline| takes place after 4am it is prolonged for the
-  // next day night between 2am and 4am.
-  static base::Time AdjustDeadline(base::Time deadline);
-
  private:
   friend class base::NoDestructor<UpgradeDetectorChromeos>;
 
-  // Return random TimeDelta uniformly selected between zero and |max|.
-  static base::TimeDelta GenRandomTimeDelta(base::TimeDelta max);
-
   // Returns the period between first notification and Recommended / Required
   // deadline specified via the RelaunchHeadsUpPeriod policy setting, or a
   // zero delta if unset or out of range.
diff --git a/chrome/browser/upgrade_detector/upgrade_detector_chromeos_unittest.cc b/chrome/browser/upgrade_detector/upgrade_detector_chromeos_unittest.cc
index 086e133..d55b370 100644
--- a/chrome/browser/upgrade_detector/upgrade_detector_chromeos_unittest.cc
+++ b/chrome/browser/upgrade_detector/upgrade_detector_chromeos_unittest.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/upgrade_detector/upgrade_detector_chromeos.h"
 
 #include <memory>
+#include <string>
 #include <utility>
 
 #include "base/macros.h"
@@ -20,11 +21,9 @@
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/fake_update_engine_client.h"
-#include "chromeos/settings/timezone_settings.h"
 #include "components/prefs/testing_pref_service.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/icu/source/i18n/unicode/timezone.h"
 
 namespace {
 
@@ -36,7 +35,7 @@
   ~TestUpgradeDetectorChromeos() override = default;
 
   // Exposed for testing.
-  using UpgradeDetectorChromeos::AdjustDeadline;
+  using UpgradeDetector::AdjustDeadline;
   using UpgradeDetectorChromeos::UPGRADE_AVAILABLE_REGULAR;
 
   DISALLOW_COPY_AND_ASSIGN(TestUpgradeDetectorChromeos);
@@ -67,8 +66,7 @@
 class UpgradeDetectorChromeosTest : public ::testing::Test {
  protected:
   UpgradeDetectorChromeosTest()
-      : utc_(icu::TimeZone::createTimeZone("Etc/GMT")),
-        task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME),
+      : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME),
         scoped_local_state_(TestingBrowserProcess::GetGlobal()) {
     // By default, test with the relaunch policy enabled.
     SetIsRelaunchNotificationPolicyEnabled(true /* enabled */);
@@ -85,12 +83,26 @@
     dbus_setter->SetUpdateEngineClient(
         std::unique_ptr<chromeos::UpdateEngineClient>(
             fake_update_engine_client_));
-    // Set UTC timezone
-    chromeos::system::TimezoneSettings::GetInstance()->SetTimezone(*utc_);
-    // Fast forward to align deadline be at 2am
+
+    // Fast forward to set current time to local 2am . This is done to align the
+    // relaunch deadline within the default relaunch window of 2am to 4am so
+    // that it is not adjusted in tests.
+    const char* tz = getenv("TZ");
+    if (tz)
+      old_tz_ = tz;
+    setenv("TZ", "UTC", 1);
+    tzset();
     FastForwardBy(base::TimeDelta::FromHours(2));
   }
+
   ~UpgradeDetectorChromeosTest() override {
+    if (!old_tz_.empty()) {
+      setenv("TZ", old_tz_.c_str(), 1);
+    } else {
+      unsetenv("TZ");
+    }
+    tzset();
+
     chromeos::DBusThreadManager::Shutdown();
   }
 
@@ -164,9 +176,9 @@
   }
 
  private:
-  std::unique_ptr<icu::TimeZone> utc_;
   base::test::TaskEnvironment task_environment_;
   ScopedTestingLocalState scoped_local_state_;
+  std::string old_tz_;
 
   chromeos::FakeUpdateEngineClient* fake_update_engine_client_;  // Not owned.
 
@@ -410,54 +422,19 @@
   RunUntilIdle();
 }
 
-TEST_F(UpgradeDetectorChromeosTest, TimezoneAdjustment) {
+TEST_F(UpgradeDetectorChromeosTest, DeadlineAdjustmentDefaultWindow) {
   TestUpgradeDetectorChromeos upgrade_detector(GetMockClock(),
                                                GetMockTickClock());
   upgrade_detector.Init();
   const auto delta = base::TimeDelta::FromDays(7);
 
-  // Europe/Moscow timezone
-  std::unique_ptr<icu::TimeZone> msk_timezone(
-      icu::TimeZone::createTimeZone("Europe/Moscow"));
-  chromeos::system::TimezoneSettings::GetInstance()->SetTimezone(*msk_timezone);
   base::Time detect_time;
-  ASSERT_TRUE(
-      base::Time::FromString("1 Jan 2018 06:00 UTC+0300", &detect_time));
+  ASSERT_TRUE(base::Time::FromString("1 Jan 2018 06:00", &detect_time));
   base::Time deadline, deadline_lower_border, deadline_upper_border;
-  ASSERT_TRUE(base::Time::FromString("9 Jan 2018 02:00 UTC+0300",
-                                     &deadline_lower_border));
-  ASSERT_TRUE(base::Time::FromString("9 Jan 2018 04:00 UTC+0300",
-                                     &deadline_upper_border));
-  deadline = upgrade_detector.AdjustDeadline(detect_time + delta);
-  EXPECT_GE(deadline, deadline_lower_border);
-  EXPECT_LE(deadline, deadline_upper_border);
-
-  // Pacific/Midway timezone
-  std::unique_ptr<icu::TimeZone> midway_timezone(
-      icu::TimeZone::createTimeZone("Pacific/Midway"));
-  chromeos::system::TimezoneSettings::GetInstance()->SetTimezone(
-      *midway_timezone);
   ASSERT_TRUE(
-      base::Time::FromString("1 Jan 2018 23:00 UTC-1100", &detect_time));
-  ASSERT_TRUE(base::Time::FromString("9 Jan 2018 02:00 UTC-1100",
-                                     &deadline_lower_border));
-  ASSERT_TRUE(base::Time::FromString("9 Jan 2018 04:00 UTC-1100",
-                                     &deadline_upper_border));
-  deadline = upgrade_detector.AdjustDeadline(detect_time + delta);
-  EXPECT_GE(deadline, deadline_lower_border);
-  EXPECT_LE(deadline, deadline_upper_border);
-
-  // Pacific/Kiritimati timezone
-  std::unique_ptr<icu::TimeZone> kiritimati_timezone(
-      icu::TimeZone::createTimeZone("Pacific/Kiritimati"));
-  chromeos::system::TimezoneSettings::GetInstance()->SetTimezone(
-      *kiritimati_timezone);
+      base::Time::FromString("9 Jan 2018 02:00", &deadline_lower_border));
   ASSERT_TRUE(
-      base::Time::FromString("1 Jan 2018 16:30 UTC+1400", &detect_time));
-  ASSERT_TRUE(base::Time::FromString("9 Jan 2018 02:00 UTC+1400",
-                                     &deadline_lower_border));
-  ASSERT_TRUE(base::Time::FromString("9 Jan 2018 04:00 UTC+1400",
-                                     &deadline_upper_border));
+      base::Time::FromString("9 Jan 2018 04:00", &deadline_upper_border));
   deadline = upgrade_detector.AdjustDeadline(detect_time + delta);
   EXPECT_GE(deadline, deadline_lower_border);
   EXPECT_LE(deadline, deadline_upper_border);
diff --git a/chrome/browser/upgrade_detector/upgrade_detector_impl.cc b/chrome/browser/upgrade_detector/upgrade_detector_impl.cc
index bbcba24..00ff379 100644
--- a/chrome/browser/upgrade_detector/upgrade_detector_impl.cc
+++ b/chrome/browser/upgrade_detector/upgrade_detector_impl.cc
@@ -547,3 +547,10 @@
 base::TimeDelta UpgradeDetector::GetDefaultElevatedAnnoyanceThreshold() {
   return kDefaultElevatedThreshold;
 }
+
+// static
+UpgradeDetector::RelaunchWindow UpgradeDetector::GetDefaultRelaunchWindow() {
+  // Relaunch window is the whole day and any time is within the window.
+  return RelaunchWindow(/*start_hour=*/0, /*start_minute=*/0,
+                        base::TimeDelta::FromHours(24));
+}
diff --git a/chrome/browser/upgrade_detector/upgrade_detector_unittest.cc b/chrome/browser/upgrade_detector/upgrade_detector_unittest.cc
new file mode 100644
index 0000000..56eefcf
--- /dev/null
+++ b/chrome/browser/upgrade_detector/upgrade_detector_unittest.cc
@@ -0,0 +1,285 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <stdlib.h>
+#include <time.h>
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "base/json/json_reader.h"
+#include "base/strings/stringprintf.h"
+#include "base/test/task_environment.h"
+#include "base/time/clock.h"
+#include "base/time/tick_clock.h"
+#include "base/time/time.h"
+#include "base/values.h"
+#include "build/build_config.h"
+#include "chrome/browser/upgrade_detector/upgrade_detector.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/test/base/scoped_testing_local_state.h"
+#include "chrome/test/base/testing_browser_process.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+class TestUpgradeDetector : public UpgradeDetector {
+ public:
+  explicit TestUpgradeDetector(const base::Clock* clock,
+                               const base::TickClock* tick_clock)
+      : UpgradeDetector(clock, tick_clock) {}
+  TestUpgradeDetector(const TestUpgradeDetector&) = delete;
+  TestUpgradeDetector& operator=(const TestUpgradeDetector&) = delete;
+  ~TestUpgradeDetector() override = default;
+
+  // Overriding pure virtual functions for testing.
+  base::TimeDelta GetHighAnnoyanceLevelDelta() override {
+    return base::TimeDelta();
+  }
+  base::Time GetHighAnnoyanceDeadline() override { return base::Time(); }
+  void OnRelaunchNotificationPeriodPrefChanged() override {}
+
+  // Exposed for testing.
+  using UpgradeDetector::AdjustDeadline;
+};
+
+}  // namespace
+
+class UpgradeDetectorTest : public ::testing::Test {
+ protected:
+  UpgradeDetectorTest()
+      : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME),
+        scoped_local_state_(TestingBrowserProcess::GetGlobal()) {}
+
+  const base::Clock* GetMockClock() { return task_environment_.GetMockClock(); }
+
+  const base::TickClock* GetMockTickClock() {
+    return task_environment_.GetMockTickClock();
+  }
+
+#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+  ~UpgradeDetectorTest() override {
+    if (!tz_overridden_)
+      return;
+
+    if (!old_tz_.empty()) {
+      setenv("TZ", old_tz_.c_str(), 1);
+    } else {
+      unsetenv("TZ");
+    }
+    tzset();
+  }
+
+  void OverrideTimezone(const std::string& tz) {
+    if (!tz_overridden_) {
+      // Store the original timezone of the device so that it can be restored in
+      // the destructor at the end of the test.
+      const char* tz = getenv("TZ");
+      if (tz)
+        old_tz_ = tz;
+      tz_overridden_ = true;
+    }
+    setenv("TZ", tz.c_str(), 1);
+    tzset();
+  }
+#endif  // defined(OS_LINUX) || defined(OS_CHROMEOS)
+
+  void RunUntilIdle() { task_environment_.RunUntilIdle(); }
+
+  void DecodeJsonStringAndNormalize(const std::string& json_string,
+                                    base::Value* value) {
+    base::JSONReader::ValueWithError parsed_json =
+        base::JSONReader::ReadAndReturnValueWithError(
+            json_string, base::JSON_ALLOW_TRAILING_COMMAS);
+    ASSERT_EQ(parsed_json.error_message, "");
+    ASSERT_TRUE(parsed_json.value);
+    *value = std::move(*parsed_json.value);
+  }
+
+  std::string CreateRelaunchWindowPolicyJson(int hour,
+                                             int minute,
+                                             int duration) {
+    return base::StringPrintf(
+        "{\"entries\": [{\"start\": {\"hour\": %d, \"minute\": %d}, "
+        "\"duration_mins\": %d}]}",
+        hour, minute, duration);
+  }
+
+  // Sets the browser.relaunch_window preference in Local State.
+  void SetRelaunchWindowPref(int hour, int minute, int duration_mins) {
+    base::Value value;
+    DecodeJsonStringAndNormalize(
+        CreateRelaunchWindowPolicyJson(hour, minute, duration_mins), &value);
+    scoped_local_state_.Get()->SetManagedPref(
+        prefs::kRelaunchWindow,
+        std::make_unique<base::Value>(std::move(value)));
+  }
+
+ private:
+  base::test::TaskEnvironment task_environment_;
+  ScopedTestingLocalState scoped_local_state_;
+#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+  std::string old_tz_;
+  bool tz_overridden_ = false;
+#endif  // defined(OS_LINUX) || defined(OS_CHROMEOS)
+};
+
+TEST_F(UpgradeDetectorTest, DeadlineAdjustment) {
+  TestUpgradeDetector upgrade_detector(GetMockClock(), GetMockTickClock());
+  // Set relaunch window from 2:20am to 5:20am.
+  SetRelaunchWindowPref(/*hour=*/2, /*minute=*/20, /*duration_mins=*/180);
+
+  // Deadline is adjusted to fall within relaunch window on next day.
+  base::Time high_deadline;
+  ASSERT_TRUE(base::Time::FromString("1 Jan 2018 06:00", &high_deadline));
+  base::Time adjusted_deadline, deadline_lower_border, deadline_upper_border;
+  ASSERT_TRUE(
+      base::Time::FromString("2 Jan 2018 02:20", &deadline_lower_border));
+  ASSERT_TRUE(
+      base::Time::FromString("2 Jan 2018 05:20", &deadline_upper_border));
+  adjusted_deadline = upgrade_detector.AdjustDeadline(high_deadline);
+  EXPECT_GE(adjusted_deadline, deadline_lower_border);
+  EXPECT_LT(adjusted_deadline, deadline_upper_border);
+
+  // Deadline is adjusted to fall within relaunch window on the same day.
+  ASSERT_TRUE(base::Time::FromString("1 Jan 2018 01:00", &high_deadline));
+  ASSERT_TRUE(
+      base::Time::FromString("1 Jan 2018 02:20", &deadline_lower_border));
+  ASSERT_TRUE(
+      base::Time::FromString("1 Jan 2018 05:20", &deadline_upper_border));
+  adjusted_deadline = upgrade_detector.AdjustDeadline(high_deadline);
+  EXPECT_GE(adjusted_deadline, deadline_lower_border);
+  EXPECT_LT(adjusted_deadline, deadline_upper_border);
+
+  // No change in the deadline as it already within relaunch window.
+  ASSERT_TRUE(base::Time::FromString("1 Jan 2018 03:00", &high_deadline));
+  adjusted_deadline = upgrade_detector.AdjustDeadline(high_deadline);
+  EXPECT_EQ(adjusted_deadline, high_deadline);
+
+  upgrade_detector.Shutdown();
+  RunUntilIdle();
+}
+
+TEST_F(UpgradeDetectorTest, DeadlineAdjustmentFor24HrsDuration) {
+  TestUpgradeDetector upgrade_detector(GetMockClock(), GetMockTickClock());
+  SetRelaunchWindowPref(/*hour=*/20, /*minute*/ 30, /*duration_mins=*/1440);
+
+  // No change in the deadline as relaunch window covers whole day.
+  base::Time high_deadline;
+  ASSERT_TRUE(base::Time::FromString("1 Jan 2018 06:00", &high_deadline));
+  base::Time adjusted_deadline = upgrade_detector.AdjustDeadline(high_deadline);
+  EXPECT_EQ(adjusted_deadline, high_deadline);
+
+  upgrade_detector.Shutdown();
+  RunUntilIdle();
+}
+
+TEST_F(UpgradeDetectorTest, DeadlineAdjustmentForOneDuration) {
+  TestUpgradeDetector upgrade_detector(GetMockClock(), GetMockTickClock());
+  // Set relaunch window to single time point 8:30pm.
+  SetRelaunchWindowPref(/*hour=*/20, /*minute=*/30, /*duration_mins=*/1);
+
+  base::Time high_deadline;
+  ASSERT_TRUE(base::Time::FromString("1 Jan 2018 06:00", &high_deadline));
+  base::Time adjusted_deadline, deadline_lower_border, deadline_upper_border;
+  ASSERT_TRUE(
+      base::Time::FromString("1 Jan 2018 20:30", &deadline_lower_border));
+  ASSERT_TRUE(
+      base::Time::FromString("1 Jan 2018 20:31", &deadline_upper_border));
+  adjusted_deadline = upgrade_detector.AdjustDeadline(high_deadline);
+  EXPECT_GE(adjusted_deadline, deadline_lower_border);
+  EXPECT_LT(adjusted_deadline, deadline_upper_border);
+
+  upgrade_detector.Shutdown();
+  RunUntilIdle();
+}
+
+TEST_F(UpgradeDetectorTest, DeadlineAdjustmentOverMidnight) {
+  TestUpgradeDetector upgrade_detector(GetMockClock(), GetMockTickClock());
+  // Set relaunch window from 11:10pm to 2:10am.
+  SetRelaunchWindowPref(/*hour=*/23, /*minute=*/10, /*duration_mins=*/180);
+
+  // Deadline is adjusted to fall within relaunch window on the same day.
+  base::Time high_deadline;
+  ASSERT_TRUE(base::Time::FromString("1 Jan 2018 16:00", &high_deadline));
+  base::Time adjusted_deadline, deadline_lower_border, deadline_upper_border;
+  ASSERT_TRUE(
+      base::Time::FromString("1 Jan 2018 23:10", &deadline_lower_border));
+  ASSERT_TRUE(
+      base::Time::FromString("2 Jan 2018 02:10", &deadline_upper_border));
+  adjusted_deadline = upgrade_detector.AdjustDeadline(high_deadline);
+  EXPECT_GE(adjusted_deadline, deadline_lower_border);
+  EXPECT_LT(adjusted_deadline, deadline_upper_border);
+
+  // No change in the deadline post midnight and within the relaunch window.
+  ASSERT_TRUE(base::Time::FromString("1 Jan 2018 00:20", &high_deadline));
+  adjusted_deadline = upgrade_detector.AdjustDeadline(high_deadline);
+  EXPECT_EQ(adjusted_deadline, high_deadline);
+
+  // No change in the deadline pre midnight and within the relaunch window.
+  ASSERT_TRUE(base::Time::FromString("1 Jan 2018 23:35", &high_deadline));
+  adjusted_deadline = upgrade_detector.AdjustDeadline(high_deadline);
+  EXPECT_EQ(adjusted_deadline, high_deadline);
+
+  upgrade_detector.Shutdown();
+  RunUntilIdle();
+}
+
+#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+TEST_F(UpgradeDetectorTest, DeadlineAdjustmentDst) {
+  // Set Europe timezone where daylight saving starts (UTC+1) at local 2:00am
+  // on the last Sunday of March and ends at local 3:00am on the last Sunday of
+  // October.
+  OverrideTimezone("CET-1CEST,M3.5.0/2,M10.5.0/3");
+  TestUpgradeDetector upgrade_detector(GetMockClock(), GetMockTickClock());
+  // Set relaunch window from 12:10am to 12:40am.
+  SetRelaunchWindowPref(/*hour=*/0, /*minute=*/10, /*duration_mins=*/30);
+
+  // Clocks are set forward on 28 March 2021 2:00am local time.
+  base::Time high_deadline;
+  ASSERT_TRUE(base::Time::FromString("27 Mar 2021 23:30", &high_deadline));
+  base::Time adjusted_deadline, deadline_lower_border, deadline_upper_border;
+  ASSERT_TRUE(
+      base::Time::FromString("28 Mar 2021 0:10", &deadline_lower_border));
+  ASSERT_TRUE(
+      base::Time::FromString("28 Mar 2021 0:40", &deadline_upper_border));
+  adjusted_deadline = upgrade_detector.AdjustDeadline(high_deadline);
+  EXPECT_GE(adjusted_deadline, deadline_lower_border);
+  EXPECT_LT(adjusted_deadline, deadline_upper_border);
+
+  // Set North America EST timezone where daylight saving starts (UTC-4) at
+  // local 2:00am on the second Sunday of March and ends at local 2:00am on the
+  // first Sunday of November.
+  OverrideTimezone("EST+5EDT,M3.2.0/2,M11.1.0/2");
+
+  // Clocks are set forward on 14 March 2021 2:00am local time.
+  ASSERT_TRUE(base::Time::FromString("13 Mar 2021 23:30", &high_deadline));
+  ASSERT_TRUE(
+      base::Time::FromString("14 Mar 2021 0:10", &deadline_lower_border));
+  ASSERT_TRUE(
+      base::Time::FromString("14 Mar 2021 0:40", &deadline_upper_border));
+  adjusted_deadline = upgrade_detector.AdjustDeadline(high_deadline);
+  EXPECT_GE(adjusted_deadline, deadline_lower_border);
+  EXPECT_LT(adjusted_deadline, deadline_upper_border);
+
+  // Set Cuba timezone where daylight saving starts (UTC-4) at local midnight
+  // on the second Sunday of March and ends at local midnight on the first
+  // Sunday of November.
+  OverrideTimezone("EST+5EDT,M3.2.0/0,M11.1.0/0");
+
+  // Clocks are set back on 7 Nov 2021 12:00am local time.
+  ASSERT_TRUE(base::Time::FromString("6 Nov 2021 00:50", &high_deadline));
+  ASSERT_TRUE(
+      base::Time::FromString("7 Nov 2021 0:10", &deadline_lower_border));
+  ASSERT_TRUE(
+      base::Time::FromString("7 Nov 2021 0:40", &deadline_upper_border));
+  adjusted_deadline = upgrade_detector.AdjustDeadline(high_deadline);
+  EXPECT_GE(adjusted_deadline, deadline_lower_border);
+  EXPECT_LT(adjusted_deadline, deadline_upper_border);
+
+  upgrade_detector.Shutdown();
+  RunUntilIdle();
+}
+#endif  // defined(OS_LINUX) || defined(OS_CHROMEOS)
diff --git a/chrome/browser/video_tutorials/internal/tutorial_manager.h b/chrome/browser/video_tutorials/internal/tutorial_manager.h
index 17731fa..8c3fa785 100644
--- a/chrome/browser/video_tutorials/internal/tutorial_manager.h
+++ b/chrome/browser/video_tutorials/internal/tutorial_manager.h
@@ -7,6 +7,7 @@
 
 #include "base/callback.h"
 #include "chrome/browser/video_tutorials/internal/tutorial_group.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace video_tutorials {
 
diff --git a/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/SurfaceScopeDependencyProvider.java b/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/SurfaceScopeDependencyProvider.java
index 08ee690..2432919 100644
--- a/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/SurfaceScopeDependencyProvider.java
+++ b/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/SurfaceScopeDependencyProvider.java
@@ -77,23 +77,19 @@
         // Events applying muted autoplay only.
 
         /**
-         * Auto-play is triggered, but not started yet. This occurs when the video card becomes
-         * fully visible.
-         */
-        int AUTOPLAY_REQUESTED = 0;
-        /**
          * Auto-play stops before reaching the end. This occurs when the video card becomes
          * partially visible or invisible.
          */
-        int AUTOPLAY_STOPPED = 1;
+        int AUTOPLAY_STOPPED = 0;
         /** Auto-play reaches the end. */
-        int AUTOPLAY_ENDED = 2;
+        int AUTOPLAY_ENDED = 1;
         /** User clicks on the auto-play video. */
-        int AUTOPLAY_CLICKED = 3;
+        int AUTOPLAY_CLICKED = 2;
 
         // Events applying to both muted autoplay and regular play.
 
         /** The player starts to play the video. */
+        int PLAY_REQUESTED = 3;
         int PLAY_STARTED = 4;
         int PLAY_ERROR = 5;
         int NUM_ENTRIES = 6;
@@ -124,7 +120,8 @@
         int AUTOPLAY_DISABLED = 4;
         int UNEXPECTED_SERVICE_DISCONNECTION = 5;
         int NOT_PLAYABLE_MUTED = 6;
-        int NUM_ENTRIES = 7;
+        int NETWORK_ERROR = 7;
+        int NUM_ENTRIES = 8;
     }
 
     /**
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index e22e1559..82ba0b0f 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-master-1621338723-4b4a10d1ccd4f2a6d2dd12e54a1717fccb7ef5d2.profdata
+chrome-win32-master-1621349817-1d50b69a5e4482ba6511550a3d6135cafd061111.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index a14fed083..986af74 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-master-1621338723-3bb0eb2008be56ccc36f831b10d82cdcc69d34af.profdata
+chrome-win64-master-1621349817-519d8eae9c154f5a52e78d5c4f4b361cf53da7a0.profdata
diff --git a/chrome/common/media/cdm_registration.cc b/chrome/common/media/cdm_registration.cc
index 3850b5f0..f9a9554 100644
--- a/chrome/common/media/cdm_registration.cc
+++ b/chrome/common/media/cdm_registration.cc
@@ -30,6 +30,7 @@
 #if defined(OS_LINUX) || defined(OS_CHROMEOS)
 #include "base/no_destructor.h"
 #include "components/cdm/common/cdm_manifest.h"
+#include "media/cdm/supported_audio_codecs.h"
 // TODO(crbug.com/663554): Needed for WIDEVINE_CDM_VERSION_STRING. Support
 // component updated CDM on all desktop platforms and remove this.
 // This file is In SHARED_INTERMEDIATE_DIR.
@@ -111,6 +112,12 @@
   // values must match the CDM that is being bundled with Chrome.
   media::CdmCapability capability;
 
+  // Note that desktop CDMs only support decryption of audio content,
+  // no decoding. Manifest does not contain any audio codecs, as decoding
+  // will be done by the browser. So use the standard set of audio codecs
+  // supported.
+  capability.audio_codecs = media::GetCdmSupportedAudioCodecs();
+
   // Add the supported codecs as if they came from the component manifest.
   capability.video_codecs.push_back(media::VideoCodec::kCodecVP8);
   capability.video_codecs.push_back(media::VideoCodec::kCodecVP9);
@@ -229,7 +236,11 @@
 #if BUILDFLAG(USE_CHROMEOS_PROTECTED_MEDIA)
   media::CdmCapability capability;
 
-  // We currently support VP9, H264 and HEVC.
+  // The following audio formats are supported for decrypt-only.
+  capability.audio_codecs = media::GetCdmSupportedAudioCodecs();
+
+  // We currently support VP9, H264 and HEVC video formats with
+  // decrypt-and-decode.
   capability.video_codecs.push_back(media::VideoCodec::kCodecVP9);
 #if BUILDFLAG(USE_PROPRIETARY_CODECS)
   capability.video_codecs.push_back(media::VideoCodec::kCodecH264);
@@ -299,7 +310,7 @@
 
   // Supported codecs are hard-coded in ExternalClearKeyProperties.
   media::CdmCapability capability(
-      {}, {media::EncryptionScheme::kCenc, media::EncryptionScheme::kCbcs},
+      {}, {}, {media::EncryptionScheme::kCenc, media::EncryptionScheme::kCbcs},
       {media::CdmSessionType::kTemporary,
        media::CdmSessionType::kPersistentLicense});
 
diff --git a/chrome/installer/util/shell_util.h b/chrome/installer/util/shell_util.h
index 8da9cd5..2d1ace0 100644
--- a/chrome/installer/util/shell_util.h
+++ b/chrome/installer/util/shell_util.h
@@ -27,6 +27,7 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "chrome/installer/util/work_item_list.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class RegistryEntry;
 
diff --git a/chrome/renderer/media/chrome_key_systems.cc b/chrome/renderer/media/chrome_key_systems.cc
index 0ccd581..c6a7a140 100644
--- a/chrome/renderer/media/chrome_key_systems.cc
+++ b/chrome/renderer/media/chrome_key_systems.cc
@@ -141,27 +141,33 @@
 
 #if BUILDFLAG(ENABLE_WIDEVINE)
 static SupportedCodecs GetSupportedCodecs(
-    const std::vector<media::VideoCodec>& supported_video_codecs,
+    const media::CdmCapability& capability,
     bool is_secure) {
   SupportedCodecs supported_codecs = media::EME_CODEC_NONE;
 
-  // Audio codecs are always supported because the CDM only does decrypt-only
-  // for audio. The only exception is when |is_secure| is true and there's no
-  // secure video decoder available, which is a signal that secure hardware
-  // decryption is not available either.
-  // TODO(sandersd): Distinguish these from those that are directly supported,
-  // as those may offer a higher level of protection.
-  if (!supported_video_codecs.empty() || !is_secure) {
-    supported_codecs |= media::EME_CODEC_OPUS;
-    supported_codecs |= media::EME_CODEC_VORBIS;
-    supported_codecs |= media::EME_CODEC_FLAC;
+  for (const auto& codec : capability.audio_codecs) {
+    switch (codec) {
+      case media::AudioCodec::kCodecOpus:
+        supported_codecs |= media::EME_CODEC_OPUS;
+        break;
+      case media::AudioCodec::kCodecVorbis:
+        supported_codecs |= media::EME_CODEC_VORBIS;
+        break;
+      case media::AudioCodec::kCodecFLAC:
+        supported_codecs |= media::EME_CODEC_FLAC;
+        break;
 #if BUILDFLAG(USE_PROPRIETARY_CODECS)
-    supported_codecs |= media::EME_CODEC_AAC;
+      case media::AudioCodec::kCodecAAC:
+        supported_codecs |= media::EME_CODEC_AAC;
+        break;
 #endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
+      default:
+        DVLOG(1) << "Unexpected supported codec: " << GetCodecName(codec);
+        break;
+    }
   }
 
-  // Video codecs are determined by what was registered for the CDM.
-  for (const auto& codec : supported_video_codecs) {
+  for (const auto& codec : capability.video_codecs) {
     switch (codec) {
       case media::VideoCodec::kCodecVP8:
         supported_codecs |= media::EME_CODEC_VP8;
@@ -267,7 +273,7 @@
   bool cdm_supports_persistent_license = false;
 
   if (capability->sw_secure_capability) {
-    codecs = GetSupportedCodecs(capability->sw_secure_capability->video_codecs,
+    codecs = GetSupportedCodecs(capability->sw_secure_capability.value(),
                                 /*is_secure=*/false);
     encryption_schemes = capability->sw_secure_capability->encryption_schemes;
     if (!base::Contains(capability->sw_secure_capability->session_types,
@@ -283,7 +289,7 @@
 
   if (capability->hw_secure_capability) {
     hw_secure_codecs = GetSupportedCodecs(
-        capability->hw_secure_capability->video_codecs, /*is_secure=*/true);
+        capability->hw_secure_capability.value(), /*is_secure=*/true);
     hw_secure_encryption_schemes =
         capability->hw_secure_capability->encryption_schemes;
     if (!base::Contains(capability->hw_secure_capability->session_types,
diff --git a/chrome/renderer/subresource_redirect/robots_rules_parser.cc b/chrome/renderer/subresource_redirect/robots_rules_parser.cc
index 09d50989..155cf7e 100644
--- a/chrome/renderer/subresource_redirect/robots_rules_parser.cc
+++ b/chrome/renderer/subresource_redirect/robots_rules_parser.cc
@@ -18,52 +18,6 @@
 
 namespace {
 
-// Returns true if URL path matches the specified pattern. Pattern is anchored
-// at the beginning of path. '$' is special only at the end of pattern.
-// Algorithm taken from
-// https://github.com/google/robotstxt/blob/f465f0ede81099dd8bc4aeb2966b3a892bd488b3/robots.cc#L74
-bool IsMatchingRobotsRule(const std::string& path, const std::string& pattern) {
-  // Fast path return when pattern is a simple string and not a regex.
-  if (pattern.find('*') == std::string::npos &&
-      pattern.find('$') == std::string::npos) {
-    return base::StartsWith(path, pattern);
-  }
-
-  size_t numpos = 1;
-  std::vector<size_t> pos(path.length() + 1, 0);
-
-  // The pos[] array holds a sorted list of indexes of 'path', with length
-  // 'numpos'.  At the start and end of each iteration of the main loop below,
-  // the pos[] array will hold a list of the prefixes of the 'path' which can
-  // match the current prefix of 'pattern'. If this list is ever empty,
-  // return false. If we reach the end of 'pattern' with at least one element
-  // in pos[], return true.
-
-  for (auto pat = pattern.begin(); pat != pattern.end(); ++pat) {
-    if (*pat == '$' && pat + 1 == pattern.end()) {
-      return (pos[numpos - 1] == path.length());
-    }
-    if (*pat == '*') {
-      numpos = path.length() - pos[0] + 1;
-      for (size_t i = 1; i < numpos; i++) {
-        pos[i] = pos[i - 1] + 1;
-      }
-    } else {
-      // Includes '$' when not at end of pattern.
-      size_t newnumpos = 0;
-      for (size_t i = 0; i < numpos; i++) {
-        if (pos[i] < path.length() && path[pos[i]] == *pat) {
-          pos[newnumpos++] = pos[i] + 1;
-        }
-      }
-      numpos = newnumpos;
-      if (numpos == 0)
-        return false;
-    }
-  }
-  return true;
-}
-
 // Converts the given robots rule pattern to a pattern compatible with
 // |base::MatchPattern|.
 //
@@ -115,10 +69,7 @@
 }  // namespace
 
 bool RobotsRulesParser::RobotsRule::Match(const std::string& path) const {
-  const bool kCanonicalResult = IsMatchingRobotsRule(path, pattern_);
-  const bool kGlobResult = base::MatchPattern(path, glob_);
-  CHECK_EQ(kCanonicalResult, kGlobResult);
-  return kGlobResult;
+  return base::MatchPattern(path, glob_);
 }
 
 RobotsRulesParser::RobotsRulesParser(
@@ -160,14 +111,12 @@
       if (rule.has_allowed_pattern()) {
         const std::string& pattern = rule.allowed_pattern();
         if (allowed_pattern_set.insert(pattern).second) {
-          robots_rules_.emplace_back(true, ConvertRobotsRuleToGlob(pattern),
-                                     pattern);
+          robots_rules_.emplace_back(true, ConvertRobotsRuleToGlob(pattern));
         }
       } else if (rule.has_disallowed_pattern()) {
         const std::string& pattern = rule.disallowed_pattern();
         if (disallowed_pattern_set.insert(pattern).second) {
-          robots_rules_.emplace_back(false, ConvertRobotsRuleToGlob(pattern),
-                                     pattern);
+          robots_rules_.emplace_back(false, ConvertRobotsRuleToGlob(pattern));
         }
       }
     }
diff --git a/chrome/renderer/subresource_redirect/robots_rules_parser.h b/chrome/renderer/subresource_redirect/robots_rules_parser.h
index fb0b450..d9c1dc29 100644
--- a/chrome/renderer/subresource_redirect/robots_rules_parser.h
+++ b/chrome/renderer/subresource_redirect/robots_rules_parser.h
@@ -12,6 +12,7 @@
 #include "base/macros.h"
 #include "base/time/time.h"
 #include "base/timer/timer.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 namespace subresource_redirect {
@@ -99,16 +100,13 @@
 
   // Contains one robots.txt rule.
   struct RobotsRule {
-    RobotsRule(bool is_allow_rule,
-               const std::string& glob,
-               const std::string& pattern)
-        : is_allow_rule_(is_allow_rule), glob_(glob), pattern_(pattern) {}
+    RobotsRule(bool is_allow_rule, std::string glob)
+        : is_allow_rule_(is_allow_rule), glob_(std::move(glob)) {}
 
     bool Match(const std::string& path) const;
 
     const bool is_allow_rule_;
     const std::string glob_;
-    const std::string pattern_;
   };
 
   // Returns the immediate result of whether the URL path is allowed or
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 5485be4..0a39e03 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -4296,6 +4296,7 @@
       "../browser/upgrade_detector/build_state_unittest.cc",
       "../browser/upgrade_detector/mock_build_state_observer.cc",
       "../browser/upgrade_detector/mock_build_state_observer.h",
+      "../browser/upgrade_detector/upgrade_detector_unittest.cc",
       "../browser/webauthn/authenticator_request_scheduler_unittest.cc",
       "../browser/webauthn/chrome_authenticator_request_delegate_unittest.cc",
       "../renderer/cart/commerce_hint_agent_unittest.cc",
diff --git a/chrome/test/data/webui/chromeos/scanning/test_scanning_browser_proxy.js b/chrome/test/data/webui/chromeos/scanning/test_scanning_browser_proxy.js
index 5f6a775e..804ee2b 100644
--- a/chrome/test/data/webui/chromeos/scanning/test_scanning_browser_proxy.js
+++ b/chrome/test/data/webui/chromeos/scanning/test_scanning_browser_proxy.js
@@ -31,6 +31,7 @@
       'saveScanSettings',
       'getScanSettings',
       'ensureValidFilePath',
+      'recordNumCompletedScans',
     ]);
 
     /** @private {!SelectedPath} */
@@ -127,6 +128,9 @@
             EMPTY_SELECTED_PATH);
   }
 
+  /** @override */
+  recordNumCompletedScans() {}
+
   /** @param {!SelectedPath} selectedPath */
   setSelectedPath(selectedPath) {
     this.selectedPath_ = selectedPath;
diff --git a/chrome/test/data/webui/download_shelf/BUILD.gn b/chrome/test/data/webui/download_shelf/BUILD.gn
index e99a0a5..ce97497 100644
--- a/chrome/test/data/webui/download_shelf/BUILD.gn
+++ b/chrome/test/data/webui/download_shelf/BUILD.gn
@@ -5,6 +5,7 @@
 import("//third_party/closure_compiler/compile_js.gni")
 
 js_type_check("closure_compile") {
+  is_polymer3 = true
   closure_flags = default_closure_args + mojom_js_args + [
                     "browser_resolver_prefix_replacements=\"chrome://download-shelf.top-chrome/=./\"",
                     "js_module_root=" +
diff --git a/chrome/test/data/webui/download_shelf/test_download_shelf_api_proxy.js b/chrome/test/data/webui/download_shelf/test_download_shelf_api_proxy.js
index 0cf122d..5de8816 100644
--- a/chrome/test/data/webui/download_shelf/test_download_shelf_api_proxy.js
+++ b/chrome/test/data/webui/download_shelf/test_download_shelf_api_proxy.js
@@ -10,6 +10,7 @@
 export class TestDownloadShelfApiProxy extends TestBrowserProxy {
   constructor() {
     super([
+      'doClose',
       'getDownloads',
       'getFileIcon',
       'showContextMenu',
@@ -27,6 +28,11 @@
   }
 
   /** @override */
+  doClose() {
+    this.methodCalled('doClose');
+  }
+
+  /** @override */
   getDownloads() {
     this.methodCalled('getDownloads');
     return Promise.resolve({downloadItems: this.downloadItems_});
diff --git a/chromecast/browser/extensions/api/tabs/tabs_api.cc b/chromecast/browser/extensions/api/tabs/tabs_api.cc
index d3eee56c..c2c3252b 100644
--- a/chromecast/browser/extensions/api/tabs/tabs_api.cc
+++ b/chromecast/browser/extensions/api/tabs/tabs_api.cc
@@ -486,12 +486,11 @@
   int index = GetActiveWebContentsIndex();
   const CastWebContents* active = GetWebViewForIndex(index);
   WebContents* caller_contents = GetSenderWebContents();
-  std::unique_ptr<base::ListValue> results;
   if (caller_contents && caller_contents == active->web_contents()) {
-    results = tabs::Get::Results::Create(
-        *CreateTabObject(active, extension(), index));
+    return RespondNow(ArgumentList(tabs::Get::Results::Create(
+        *CreateTabObject(active, extension(), index))));
   }
-  return RespondNow(results ? ArgumentList(std::move(results)) : NoArguments());
+  return RespondNow(NoArguments());
 }
 
 ExtensionFunction::ResponseAction TabsHighlightFunction::Run() {
diff --git a/chromecast/media/cma/backend/proxy/buffer_id_manager.h b/chromecast/media/cma/backend/proxy/buffer_id_manager.h
index 0cdf19b..55a35d1 100644
--- a/chromecast/media/cma/backend/proxy/buffer_id_manager.h
+++ b/chromecast/media/cma/backend/proxy/buffer_id_manager.h
@@ -12,6 +12,7 @@
 #include "base/sequence_checker.h"
 #include "chromecast/media/api/cma_backend.h"
 #include "chromecast/media/cma/backend/proxy/audio_decoder_pipeline_node.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace chromecast {
 namespace media {
diff --git a/chromeos/components/diagnostics_ui/backend/BUILD.gn b/chromeos/components/diagnostics_ui/backend/BUILD.gn
index 0408f54f..fe6299d 100644
--- a/chromeos/components/diagnostics_ui/backend/BUILD.gn
+++ b/chromeos/components/diagnostics_ui/backend/BUILD.gn
@@ -37,6 +37,7 @@
   ]
 
   deps = [
+    "//ash/constants:constants",
     "//ash/public/cpp",
     "//base",
     "//chromeos/components/diagnostics_ui/mojom",
diff --git a/chromeos/components/diagnostics_ui/backend/diagnostics_manager.cc b/chromeos/components/diagnostics_ui/backend/diagnostics_manager.cc
index 5d456d0..42217b5a 100644
--- a/chromeos/components/diagnostics_ui/backend/diagnostics_manager.cc
+++ b/chromeos/components/diagnostics_ui/backend/diagnostics_manager.cc
@@ -4,6 +4,7 @@
 
 #include "chromeos/components/diagnostics_ui/backend/diagnostics_manager.h"
 
+#include "ash/constants/ash_features.h"
 #include "chromeos/components/diagnostics_ui/backend/input_data_provider.h"
 #include "chromeos/components/diagnostics_ui/backend/session_log_handler.h"
 #include "chromeos/components/diagnostics_ui/backend/system_data_provider.h"
@@ -16,8 +17,11 @@
     : system_data_provider_(std::make_unique<SystemDataProvider>(
           session_log_handler->GetTelemetryLog())),
       system_routine_controller_(std::make_unique<SystemRoutineController>(
-          session_log_handler->GetRoutineLog())),
-      input_data_provider_(std::make_unique<InputDataProvider>()) {}
+          session_log_handler->GetRoutineLog())) {
+  if (features::IsInputInDiagnosticsAppEnabled()) {
+    input_data_provider_ = std::make_unique<InputDataProvider>();
+  }
+}
 
 DiagnosticsManager::~DiagnosticsManager() = default;
 
diff --git a/chromeos/crosapi/mojom/keystore_error.mojom b/chromeos/crosapi/mojom/keystore_error.mojom
index 11f8dd0..ec36d55 100644
--- a/chromeos/crosapi/mojom/keystore_error.mojom
+++ b/chromeos/crosapi/mojom/keystore_error.mojom
@@ -29,4 +29,6 @@
   kNetCertificateInvalid,
   // Keystore errors.
   kUnsupportedKeystoreType,
+  [MinVersion=1]
+  kUnsupportedAlgorithmType,
 };
diff --git a/chromeos/crosapi/mojom/keystore_service.mojom b/chromeos/crosapi/mojom/keystore_service.mojom
index 90884ee..0015f48 100644
--- a/chromeos/crosapi/mojom/keystore_service.mojom
+++ b/chromeos/crosapi/mojom/keystore_service.mojom
@@ -88,7 +88,7 @@
   string challenge_response;
 };
 
-[Stable, RenamedFrom="crosapi.mojom.KeystoreBinaryResult"]
+[Stable]
 union ExtensionKeystoreBinaryResult {
   // Implies failure.
   string error_message;
@@ -227,4 +227,14 @@
   GenerateKey@8(KeystoreType keystore,
       KeystoreSigningAlgorithm algorithm) =>
       (KeystoreBinaryResult result);
+
+  // Signs some data using a previously generated key, indicated with
+  // |public_key|. |scheme| is the WebCrypto signing scheme. If
+  // |is_keystore_provided| is true, |keystore| holds a valid value. Otherwise
+  // the key will be searched in all available key stores.
+  [MinVersion=7]
+  Sign@9(bool is_keystore_provided, KeystoreType keystore,
+      array<uint8> public_key, KeystoreSigningScheme scheme,
+      array<uint8> data) =>
+      (KeystoreBinaryResult result);
 };
diff --git a/chromeos/network/network_connection_handler_impl.cc b/chromeos/network/network_connection_handler_impl.cc
index 21c02cd6..0502dbb 100644
--- a/chromeos/network/network_connection_handler_impl.cc
+++ b/chromeos/network/network_connection_handler_impl.cc
@@ -421,7 +421,8 @@
   }
   const std::string connection_state = network->connection_state();
   if (!NetworkState::StateIsConnected(connection_state) &&
-      !NetworkState::StateIsConnecting(connection_state)) {
+      !NetworkState::StateIsConnecting(connection_state) &&
+      !GetPendingRequest(service_path)) {
     NET_LOG(ERROR) << "Disconnect Error: Not Connected: " << NetworkId(network);
     network_handler::RunErrorCallback(std::move(error_callback), service_path,
                                       kErrorNotConnected, "");
diff --git a/components/autofill/core/browser/address_profile_save_manager.cc b/components/autofill/core/browser/address_profile_save_manager.cc
index 963dc1d..3fe06619 100644
--- a/components/autofill/core/browser/address_profile_save_manager.cc
+++ b/components/autofill/core/browser/address_profile_save_manager.cc
@@ -11,6 +11,8 @@
 
 namespace autofill {
 
+using UserDecision = AutofillClient::SaveAddressProfileOfferUserDecision;
+
 AddressProfileSaveManager::AddressProfileSaveManager(
     AutofillClient* client,
     PersonalDataManager* personal_data_manager)
@@ -99,7 +101,7 @@
 
 void AddressProfileSaveManager::OnUserDecision(
     std::unique_ptr<ProfileImportProcess> import_process,
-    AutofillClient::SaveAddressProfileOfferUserDecision decision,
+    UserDecision decision,
     AutofillProfile edited_profile) {
   DCHECK(import_process->prompt_shown());
 
@@ -122,14 +124,12 @@
   AutofillProfileImportType import_type = import_process->import_type();
 
   bool accepted_or_edited =
-      import_process->user_decision() ==
-          AutofillClient::SaveAddressProfileOfferUserDecision::kAccepted ||
-      import_process->user_decision() ==
-          AutofillClient::SaveAddressProfileOfferUserDecision::kEdited;
+      import_process->user_decision() == UserDecision::kAccepted ||
+      import_process->user_decision() == UserDecision::kEditAccepted;
 
   bool declined =
-      import_process->user_decision() ==
-      AutofillClient::SaveAddressProfileOfferUserDecision::kDeclined;
+      import_process->user_decision() == UserDecision::kDeclined ||
+      import_process->user_decision() == UserDecision::kEditDeclined;
 
   // If the import of a new profile was declined, add a strike for this source
   // url. If it was accepted, reset the potentially existing strikes.
diff --git a/components/autofill/core/browser/address_profile_save_manager_unittest.cc b/components/autofill/core/browser/address_profile_save_manager_unittest.cc
index 951b7166..21e5060 100644
--- a/components/autofill/core/browser/address_profile_save_manager_unittest.cc
+++ b/components/autofill/core/browser/address_profile_save_manager_unittest.cc
@@ -296,7 +296,7 @@
                      ->GetStrikes(url.host()));
   } else if (is_new_profile &&
              (last_import->user_decision() == UserDecision::kAccepted ||
-              last_import->user_decision() == UserDecision::kEdited)) {
+              last_import->user_decision() == UserDecision::kEditAccepted)) {
     // If the import of a new profile was accepted, the count should have been
     // reset.
     EXPECT_EQ(0, mock_personal_data_manager_.GetProfileSaveStrikeDatabase()
@@ -313,7 +313,7 @@
   // updated.
   if (is_confirmable_merge &&
       (test_scenario.user_decision == UserDecision::kAccepted ||
-       test_scenario.user_decision == UserDecision::kEdited)) {
+       test_scenario.user_decision == UserDecision::kEditAccepted)) {
     EXPECT_EQ(0, mock_personal_data_manager_.GetProfileUpdateStrikeDatabase()
                      ->GetStrikes(test_scenario.merge_candidate->guid()));
   } else if (is_confirmable_merge &&
@@ -422,7 +422,7 @@
       .existing_profiles = {},
       .observed_profile = observed_profile,
       .is_prompt_expected = true,
-      .user_decision = UserDecision::kEdited,
+      .user_decision = UserDecision::kEditAccepted,
       .edited_profile = edited_profile,
       .expected_import_type = AutofillProfileImportType::kNewProfile,
       .is_profile_change_expected = true,
@@ -653,7 +653,7 @@
       .existing_profiles = {mergeable_profile},
       .observed_profile = observed_profile,
       .is_prompt_expected = true,
-      .user_decision = UserDecision::kEdited,
+      .user_decision = UserDecision::kEditAccepted,
       .edited_profile = edited_profile,
       .expected_import_type = AutofillProfileImportType::kConfirmableMerge,
       .is_profile_change_expected = true,
@@ -870,7 +870,7 @@
                             updateable_profile},
       .observed_profile = observed_profile,
       .is_prompt_expected = true,
-      .user_decision = UserDecision::kEdited,
+      .user_decision = UserDecision::kEditAccepted,
       .edited_profile = edited_profile,
       .expected_import_type =
           AutofillProfileImportType::kConfirmableMergeAndSilentUpdate,
diff --git a/components/autofill/core/browser/autofill_client.h b/components/autofill/core/browser/autofill_client.h
index 967f0c66..6eedae2 100644
--- a/components/autofill/core/browser/autofill_client.h
+++ b/components/autofill/core/browser/autofill_client.h
@@ -138,13 +138,31 @@
 
   enum class SaveAddressProfileOfferUserDecision {
     kUndefined,
+    // No prompt is shown and no decision is needed to proceed with the process.
     kUserNotAsked,
+    // The user accepted the save/update flow from the initial prompt.
     kAccepted,
-    kEdited,
+    // The user declined the save/update flow from the initial prompt.
     kDeclined,
+    // The user accepted the save/update flow from the edit dialog.
+    kEditAccepted,
+    // The user declined the save/update flow from the edit dialog.
+    kEditDeclined,
+    // The user selected to never save a new profile on a given domain or update
+    // a specific profile (currently not supported).
     kNever,
+    // The user ignored the prompt.
     kIgnored,
-    kMaxValue = kIgnored,
+    // The save/update message timed out before the user interacted. This is
+    // only relevant on mobile.
+    kMessageTimeout,
+    // The user swipes away the save/update Message. This is only relevant on
+    // mobile.
+    kMessageDeclined,
+    // The prompt is suppressed most likely because there is already another
+    // prompt shown on the same tab.
+    kAutoDeclined,
+    kMaxValue = kAutoDeclined,
   };
 
   // Used for explicitly requesting the user to enter/confirm cardholder name,
diff --git a/components/autofill/core/browser/autofill_profile_import_process.cc b/components/autofill/core/browser/autofill_profile_import_process.cc
index 274f2af..86cbf6c3 100644
--- a/components/autofill/core/browser/autofill_profile_import_process.cc
+++ b/components/autofill/core/browser/autofill_profile_import_process.cc
@@ -208,7 +208,7 @@
       confirmed_import_candidate_ = import_candidate_;
       break;
 
-    case UserDecision::kEdited:
+    case UserDecision::kEditAccepted:
       // If the import candidate is supplied, the 'edited_profile' must be
       // supplied.
       DCHECK(edited_profile.has_value());
@@ -222,7 +222,14 @@
     // candidate should be maintined. Note that the decline/ignore does not mean
     // that silent updates are not performed.
     case UserDecision::kDeclined:
+    case UserDecision::kEditDeclined:
+    case UserDecision::kMessageDeclined:
+    case UserDecision::kMessageTimeout:
     case UserDecision::kIgnored:
+    case UserDecision::kAutoDeclined:
+      confirmed_import_candidate_ = merge_candidate_;
+      break;
+
     case UserDecision::kNever:
       break;
 
@@ -241,7 +248,8 @@
 }
 
 void ProfileImportProcess::AcceptWithEdits(AutofillProfile edited_profile) {
-  SetUserDecision(UserDecision::kEdited, absl::make_optional(edited_profile));
+  SetUserDecision(UserDecision::kEditAccepted,
+                  absl::make_optional(edited_profile));
 }
 
 void ProfileImportProcess::Declined() {
@@ -268,7 +276,7 @@
 
   // If the import was accepted, return true.
   if (user_decision_ == UserDecision::kAccepted ||
-      user_decision_ == UserDecision::kEdited ||
+      user_decision_ == UserDecision::kEditAccepted ||
       user_decision_ == UserDecision::kUserNotAsked) {
     return true;
   }
@@ -298,7 +306,7 @@
   }
 
   // If the profile was edited by the user, record a histogram of edited types.
-  if (user_decision_ == UserDecision::kEdited) {
+  if (user_decision_ == UserDecision::kEditAccepted) {
     for (const auto& difference :
          AutofillProfileComparator::GetSettingsVisibleProfileDifference(
              import_candidate_.value(), confirmed_import_candidate_.value(),
diff --git a/components/autofill/core/browser/autofill_profile_save_strike_database.cc b/components/autofill/core/browser/autofill_profile_save_strike_database.cc
index 43440541..f93fb3f 100644
--- a/components/autofill/core/browser/autofill_profile_save_strike_database.cc
+++ b/components/autofill/core/browser/autofill_profile_save_strike_database.cc
@@ -5,6 +5,7 @@
 #include "components/autofill/core/browser/autofill_profile_save_strike_database.h"
 
 #include "components/autofill/core/browser/proto/strike_data.pb.h"
+#include "components/autofill/core/common/autofill_features.h"
 #include "url/gurl.h"
 
 namespace autofill {
@@ -39,13 +40,15 @@
 }
 
 int AutofillProfileSaveStrikeDatabase::GetMaxStrikesLimit() const {
-  return 3;
+  // The default limit for strikes is 3.
+  return features::kAutofillAutoBlockSaveAddressProfilePromptStrikeLimit.Get();
 }
 
 absl::optional<base::TimeDelta>
 AutofillProfileSaveStrikeDatabase::GetExpiryTimeDelta() const {
-  // Expiry time is 6 months.
-  return base::TimeDelta::FromDays(183);
+  // Expiry time is 180 days by default.
+  return base::TimeDelta::FromDays(
+      features::kAutofillAutoBlockSaveAddressProfilePromptExpirationDays.Get());
 }
 
 bool AutofillProfileSaveStrikeDatabase::UniqueIdsRequired() const {
diff --git a/components/autofill/core/browser/autofill_profile_update_strike_database.cc b/components/autofill/core/browser/autofill_profile_update_strike_database.cc
index 6fb0bef..f08d69f2 100644
--- a/components/autofill/core/browser/autofill_profile_update_strike_database.cc
+++ b/components/autofill/core/browser/autofill_profile_update_strike_database.cc
@@ -5,6 +5,7 @@
 #include "components/autofill/core/browser/autofill_profile_update_strike_database.h"
 
 #include "components/autofill/core/browser/proto/strike_data.pb.h"
+#include "components/autofill/core/common/autofill_features.h"
 
 namespace autofill {
 
@@ -38,13 +39,17 @@
 }
 
 int AutofillProfileUpdateStrikeDatabase::GetMaxStrikesLimit() const {
-  return 3;
+  // The default limit for strikes is 3.
+  return features::kAutofillAutoBlockUpdateAddressProfilePromptStrikeLimit
+      .Get();
 }
 
 absl::optional<base::TimeDelta>
 AutofillProfileUpdateStrikeDatabase::GetExpiryTimeDelta() const {
-  // Expiry time is 6 months.
-  return base::TimeDelta::FromDays(183);
+  // Expiry time is 180 days by default.
+  return base::TimeDelta::FromDays(
+      features::kAutofillAutoBlockUpdateAddressProfilePromptExpirationDays
+          .Get());
 }
 
 bool AutofillProfileUpdateStrikeDatabase::UniqueIdsRequired() const {
diff --git a/components/autofill/core/browser/autofill_save_update_address_profile_delegate_ios.cc b/components/autofill/core/browser/autofill_save_update_address_profile_delegate_ios.cc
index a40fab8..5536cc4 100644
--- a/components/autofill/core/browser/autofill_save_update_address_profile_delegate_ios.cc
+++ b/components/autofill/core/browser/autofill_save_update_address_profile_delegate_ios.cc
@@ -53,12 +53,12 @@
 
 std::u16string AutofillSaveUpdateAddressProfileDelegateIOS::GetPhoneNumber()
     const {
-  return profile_.GetRawInfo(PHONE_HOME_WHOLE_NUMBER);
+  return GetProfileInfo(PHONE_HOME_WHOLE_NUMBER);
 }
 
 std::u16string AutofillSaveUpdateAddressProfileDelegateIOS::GetEmailAddress()
     const {
-  return profile_.GetRawInfo(EMAIL_ADDRESS);
+  return GetProfileInfo(EMAIL_ADDRESS);
 }
 
 std::u16string AutofillSaveUpdateAddressProfileDelegateIOS::GetDescription()
@@ -87,6 +87,11 @@
   return base::OptionalOrNullptr(original_profile_);
 }
 
+std::u16string AutofillSaveUpdateAddressProfileDelegateIOS::GetProfileInfo(
+    ServerFieldType type) const {
+  return profile_.GetInfo(type, locale_);
+}
+
 base::flat_map<ServerFieldType, std::pair<std::u16string, std::u16string>>
 AutofillSaveUpdateAddressProfileDelegateIOS::GetProfileDiff() const {
   return AutofillProfileComparator::GetSettingsVisibleProfileDifferenceMap(
diff --git a/components/autofill/core/browser/autofill_save_update_address_profile_delegate_ios.h b/components/autofill/core/browser/autofill_save_update_address_profile_delegate_ios.h
index 97486d4cc..35d9ad5 100644
--- a/components/autofill/core/browser/autofill_save_update_address_profile_delegate_ios.h
+++ b/components/autofill/core/browser/autofill_save_update_address_profile_delegate_ios.h
@@ -51,6 +51,9 @@
   // Returns the message button text.
   std::u16string GetMessageActionText() const;
 
+  // Returns the data stored in the |profile_| corresponding to |type|.
+  std::u16string GetProfileInfo(ServerFieldType type) const;
+
   // Uses |AutofillProfileComparator::GetSettingsVisibleProfileDifferenceMap| to
   // get profile difference map between |profile_| and |original_profile_|;
   base::flat_map<ServerFieldType, std::pair<std::u16string, std::u16string>>
diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc
index 6a5b833..0f854f8 100644
--- a/components/autofill/core/browser/personal_data_manager.cc
+++ b/components/autofill/core/browser/personal_data_manager.cc
@@ -1625,15 +1625,18 @@
 
 bool PersonalDataManager::IsNewProfileImportBlockedForDomain(
     const GURL& url) const {
-  if (!GetProfileSaveStrikeDatabase() || !url.is_valid() || !url.has_host()) {
+  if (!GetProfileSaveStrikeDatabase() || !url.is_valid() || !url.has_host() ||
+      !features::kAutofillAutoBlockSaveAddressProfilePrompt.Get()) {
     return false;
   }
+
   return GetProfileSaveStrikeDatabase()->IsMaxStrikesLimitReached(url.host());
 }
 
 void PersonalDataManager::AddStrikeToBlockNewProfileImportForDomain(
     const GURL& url) {
-  if (!GetProfileSaveStrikeDatabase() || !url.is_valid() || !url.has_host()) {
+  if (!GetProfileSaveStrikeDatabase() || !url.is_valid() || !url.has_host() ||
+      !features::kAutofillAutoBlockSaveAddressProfilePrompt.Get()) {
     return;
   }
   GetProfileSaveStrikeDatabase()->AddStrike(url.host());
@@ -1649,15 +1652,18 @@
 
 bool PersonalDataManager::IsProfileUpdateBlocked(
     const std::string& guid) const {
-  if (!GetProfileUpdateStrikeDatabase()) {
+  if (!GetProfileUpdateStrikeDatabase() ||
+      !features::kAutofillAutoBlockUpdateAddressProfilePrompt.Get()) {
     return false;
   }
+
   return GetProfileUpdateStrikeDatabase()->IsMaxStrikesLimitReached(guid);
 }
 
 void PersonalDataManager::AddStrikeToBlockProfileUpdate(
     const std::string& guid) {
-  if (!GetProfileUpdateStrikeDatabase()) {
+  if (!GetProfileUpdateStrikeDatabase() ||
+      !features::kAutofillAutoBlockUpdateAddressProfilePrompt.Get()) {
     return;
   }
   GetProfileUpdateStrikeDatabase()->AddStrike(guid);
diff --git a/components/autofill/core/browser/strike_database_integrator_base.h b/components/autofill/core/browser/strike_database_integrator_base.h
index 0a8f115..81e9b5b 100644
--- a/components/autofill/core/browser/strike_database_integrator_base.h
+++ b/components/autofill/core/browser/strike_database_integrator_base.h
@@ -13,6 +13,7 @@
 #include "base/gtest_prod_util.h"
 #include "base/time/time.h"
 #include "components/autofill/core/browser/strike_database_base.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace autofill {
 
diff --git a/components/autofill/core/common/autofill_features.cc b/components/autofill/core/common/autofill_features.cc
index 6366162..b53da407 100644
--- a/components/autofill/core/common/autofill_features.cc
+++ b/components/autofill/core/common/autofill_features.cc
@@ -28,6 +28,36 @@
 // storing any detected address profile.
 const base::Feature kAutofillAddressProfileSavePrompt{
     "AutofillAddressProfileSavePrompt", base::FEATURE_DISABLED_BY_DEFAULT};
+// This parameter controls if save profile prompts are automatically blocked for
+// a given domain after N (default is 3) subsequent declines.
+const base::FeatureParam<bool> kAutofillAutoBlockSaveAddressProfilePrompt{
+    &kAutofillAddressProfileSavePrompt, "save_profile_prompt_auto_block", true};
+// The auto blocking feature is based on a strike model. This parameter defines
+// the months before such strikes expire.
+const base::FeatureParam<int>
+    kAutofillAutoBlockSaveAddressProfilePromptExpirationDays{
+        &kAutofillAddressProfileSavePrompt,
+        "save_profile_prompt_auto_block_strike_expiration_days", 180};
+// The number of strikes before the prompt gets blocked.
+const base::FeatureParam<int>
+    kAutofillAutoBlockSaveAddressProfilePromptStrikeLimit{
+        &kAutofillAddressProfileSavePrompt,
+        "save_profile_prompt_auto_block_strike_limit", 3};
+
+// Same as above but for update bubbles.
+const base::FeatureParam<bool> kAutofillAutoBlockUpdateAddressProfilePrompt{
+    &kAutofillAddressProfileSavePrompt, "update_profile_prompt_auto_block",
+    true};
+// Same as above but for update bubbles.
+const base::FeatureParam<int>
+    kAutofillAutoBlockUpdateAddressProfilePromptExpirationDays{
+        &kAutofillAddressProfileSavePrompt,
+        "update_profile_prompt_auto_block_strike_expiration_days", 180};
+// Same as above but for update bubbles.
+const base::FeatureParam<int>
+    kAutofillAutoBlockUpdateAddressProfilePromptStrikeLimit{
+        &kAutofillAddressProfileSavePrompt,
+        "update_profile_prompt_auto_block_strike_limit", 3};
 
 // TODO(crbug.com/1135188): Remove this feature flag after the explicit save
 // prompts for address profiles is complete.
diff --git a/components/autofill/core/common/autofill_features.h b/components/autofill/core/common/autofill_features.h
index 899fbd1..0ff6e3c5 100644
--- a/components/autofill/core/common/autofill_features.h
+++ b/components/autofill/core/common/autofill_features.h
@@ -21,6 +21,24 @@
 COMPONENT_EXPORT(AUTOFILL)
 extern const base::Feature kAutofillAddressProfileSavePrompt;
 COMPONENT_EXPORT(AUTOFILL)
+extern const base::FeatureParam<bool>
+    kAutofillAutoBlockSaveAddressProfilePrompt;
+COMPONENT_EXPORT(AUTOFILL)
+extern const base::FeatureParam<int>
+    kAutofillAutoBlockSaveAddressProfilePromptExpirationDays;
+COMPONENT_EXPORT(AUTOFILL)
+extern const base::FeatureParam<int>
+    kAutofillAutoBlockSaveAddressProfilePromptStrikeLimit;
+COMPONENT_EXPORT(AUTOFILL)
+extern const base::FeatureParam<bool>
+    kAutofillAutoBlockUpdateAddressProfilePrompt;
+COMPONENT_EXPORT(AUTOFILL)
+extern const base::FeatureParam<int>
+    kAutofillAutoBlockUpdateAddressProfilePromptExpirationDays;
+COMPONENT_EXPORT(AUTOFILL)
+extern const base::FeatureParam<int>
+    kAutofillAutoBlockUpdateAddressProfilePromptStrikeLimit;
+COMPONENT_EXPORT(AUTOFILL)
 extern const base::Feature kAutofillAddressProfileSavePromptNicknameSupport;
 COMPONENT_EXPORT(AUTOFILL)
 extern const base::Feature kAutofillAllowDuplicateFormSubmissions;
diff --git a/components/autofill_strings.grdp b/components/autofill_strings.grdp
index 98c0435..fc3c4f7f 100644
--- a/components/autofill_strings.grdp
+++ b/components/autofill_strings.grdp
@@ -316,4 +316,48 @@
     </message>
   </if>
 
+  <!-- Explicit save/update address prompt strings  -->
+  <message name="IDS_AUTOFILL_SAVE_ADDRESS_PROMPT_TITLE" desc="Title shown at the top of prompt that offers the user to save a new address.">
+    Save address?
+  </message>
+  <message name="IDS_AUTOFILL_SAVE_ADDRESS_PROMPT_OK_BUTTON_LABEL" desc="Label of the OK button in the prompt that offers the user to save a new address.">
+    Save
+  </message>
+  <message name="IDS_AUTOFILL_SAVE_ADDRESS_PROMPT_CANCEL_BUTTON_LABEL" desc="Label of the Cancel button in the prompt that offers the user to save a new address.">
+    No thanks
+  </message>
+  <message name="IDS_AUTOFILL_SAVE_ADDRESS_PROMPT_EDIT_BUTTON_TOOLTIP" desc="Tooltip of the Edit button in the prompt that offers the user to save a new address.">
+    Edit address
+  </message>
+
+  <message name="IDS_AUTOFILL_UPDATE_ADDRESS_PROMPT_TITLE" desc="Title shown at the top of prompt that offers the user to update an existing address.">
+    Update address?
+  </message>
+  <message name="IDS_AUTOFILL_UPDATE_ADDRESS_PROMPT_OK_BUTTON_LABEL" desc="Label of the OK button in the prompt that offers the user to update an existing address.">
+    Update
+  </message>
+  <message name="IDS_AUTOFILL_UPDATE_ADDRESS_PROMPT_CANCEL_BUTTON_LABEL" desc="Label of the Cancel button in the prompt that offers the user to update an existing address.">
+    No thanks
+  </message>
+  <message name="IDS_AUTOFILL_UPDATE_ADDRESS_PROMPT_NEW_VALUES_SECTION_LABEL" meaning="In the address update prompt" desc="Label shown next to the section that displays the new address values in the prompt that offers the user to update an existing address.">
+    New
+  </message>
+  <message name="IDS_AUTOFILL_UPDATE_ADDRESS_PROMPT_OLD_VALUES_SECTION_LABEL" meaning="In the address update prompt" desc="Label shown next to the section that displays the old address values in the prompt that offers the user to update an existing address.">
+    Old
+  </message>
+
+  <message name="IDS_AUTOFILL_EDIT_ADDRESS_DIALOG_TITLE" desc="Title shown at the top of dialog that edits an address before saving it">
+    Edit address
+  </message>
+  <message name="IDS_AUTOFILL_EDIT_ADDRESS_DIALOG_OK_BUTTON_LABEL_SAVE" desc="Label of the OK button in the dialog that edits the address before saving it as a new address.">
+    Save
+  </message>
+  <message name="IDS_AUTOFILL_EDIT_ADDRESS_DIALOG_OK_BUTTON_LABEL_UPDATE" desc="Label of the OK button in the dialog that edits the address before using it to update an existing address.">
+    Update
+  </message>
+  <message name="IDS_AUTOFILL_EDIT_ADDRESS_DIALOG_CANCEL_BUTTON_LABEL" desc="Label of the Cancel button in the dialog that edits an address before saving it.">
+    Cancel
+  </message>
+
+
 </grit-part>
diff --git a/components/autofill_strings_grdp/IDS_AUTOFILL_EDIT_ADDRESS_DIALOG_CANCEL_BUTTON_LABEL.png.sha1 b/components/autofill_strings_grdp/IDS_AUTOFILL_EDIT_ADDRESS_DIALOG_CANCEL_BUTTON_LABEL.png.sha1
new file mode 100644
index 0000000..99ae392
--- /dev/null
+++ b/components/autofill_strings_grdp/IDS_AUTOFILL_EDIT_ADDRESS_DIALOG_CANCEL_BUTTON_LABEL.png.sha1
@@ -0,0 +1 @@
+187e178e87ccc11b83208e0264733d3d813f9e75
\ No newline at end of file
diff --git a/components/autofill_strings_grdp/IDS_AUTOFILL_EDIT_ADDRESS_DIALOG_OK_BUTTON_LABEL_SAVE.png.sha1 b/components/autofill_strings_grdp/IDS_AUTOFILL_EDIT_ADDRESS_DIALOG_OK_BUTTON_LABEL_SAVE.png.sha1
new file mode 100644
index 0000000..99ae392
--- /dev/null
+++ b/components/autofill_strings_grdp/IDS_AUTOFILL_EDIT_ADDRESS_DIALOG_OK_BUTTON_LABEL_SAVE.png.sha1
@@ -0,0 +1 @@
+187e178e87ccc11b83208e0264733d3d813f9e75
\ No newline at end of file
diff --git a/components/autofill_strings_grdp/IDS_AUTOFILL_EDIT_ADDRESS_DIALOG_OK_BUTTON_LABEL_UPDATE.png.sha1 b/components/autofill_strings_grdp/IDS_AUTOFILL_EDIT_ADDRESS_DIALOG_OK_BUTTON_LABEL_UPDATE.png.sha1
new file mode 100644
index 0000000..6b47f83
--- /dev/null
+++ b/components/autofill_strings_grdp/IDS_AUTOFILL_EDIT_ADDRESS_DIALOG_OK_BUTTON_LABEL_UPDATE.png.sha1
@@ -0,0 +1 @@
+712e2e02bb3b80855bd44549d53c11ee7084263c
\ No newline at end of file
diff --git a/components/autofill_strings_grdp/IDS_AUTOFILL_EDIT_ADDRESS_DIALOG_TITLE.png.sha1 b/components/autofill_strings_grdp/IDS_AUTOFILL_EDIT_ADDRESS_DIALOG_TITLE.png.sha1
new file mode 100644
index 0000000..99ae392
--- /dev/null
+++ b/components/autofill_strings_grdp/IDS_AUTOFILL_EDIT_ADDRESS_DIALOG_TITLE.png.sha1
@@ -0,0 +1 @@
+187e178e87ccc11b83208e0264733d3d813f9e75
\ No newline at end of file
diff --git a/components/autofill_strings_grdp/IDS_AUTOFILL_SAVE_ADDRESS_PROMPT_CANCEL_BUTTON_LABEL.png.sha1 b/components/autofill_strings_grdp/IDS_AUTOFILL_SAVE_ADDRESS_PROMPT_CANCEL_BUTTON_LABEL.png.sha1
new file mode 100644
index 0000000..430d465
--- /dev/null
+++ b/components/autofill_strings_grdp/IDS_AUTOFILL_SAVE_ADDRESS_PROMPT_CANCEL_BUTTON_LABEL.png.sha1
@@ -0,0 +1 @@
+205ee10a48b93ab135b8ff013336f41a9c414091
\ No newline at end of file
diff --git a/components/autofill_strings_grdp/IDS_AUTOFILL_SAVE_ADDRESS_PROMPT_EDIT_BUTTON_TOOLTIP.png.sha1 b/components/autofill_strings_grdp/IDS_AUTOFILL_SAVE_ADDRESS_PROMPT_EDIT_BUTTON_TOOLTIP.png.sha1
new file mode 100644
index 0000000..430d465
--- /dev/null
+++ b/components/autofill_strings_grdp/IDS_AUTOFILL_SAVE_ADDRESS_PROMPT_EDIT_BUTTON_TOOLTIP.png.sha1
@@ -0,0 +1 @@
+205ee10a48b93ab135b8ff013336f41a9c414091
\ No newline at end of file
diff --git a/components/autofill_strings_grdp/IDS_AUTOFILL_SAVE_ADDRESS_PROMPT_OK_BUTTON_LABEL.png.sha1 b/components/autofill_strings_grdp/IDS_AUTOFILL_SAVE_ADDRESS_PROMPT_OK_BUTTON_LABEL.png.sha1
new file mode 100644
index 0000000..430d465
--- /dev/null
+++ b/components/autofill_strings_grdp/IDS_AUTOFILL_SAVE_ADDRESS_PROMPT_OK_BUTTON_LABEL.png.sha1
@@ -0,0 +1 @@
+205ee10a48b93ab135b8ff013336f41a9c414091
\ No newline at end of file
diff --git a/components/autofill_strings_grdp/IDS_AUTOFILL_SAVE_ADDRESS_PROMPT_TITLE.png.sha1 b/components/autofill_strings_grdp/IDS_AUTOFILL_SAVE_ADDRESS_PROMPT_TITLE.png.sha1
new file mode 100644
index 0000000..430d465
--- /dev/null
+++ b/components/autofill_strings_grdp/IDS_AUTOFILL_SAVE_ADDRESS_PROMPT_TITLE.png.sha1
@@ -0,0 +1 @@
+205ee10a48b93ab135b8ff013336f41a9c414091
\ No newline at end of file
diff --git a/components/autofill_strings_grdp/IDS_AUTOFILL_UPDATE_ADDRESS_PROMPT_CANCEL_BUTTON_LABEL.png.sha1 b/components/autofill_strings_grdp/IDS_AUTOFILL_UPDATE_ADDRESS_PROMPT_CANCEL_BUTTON_LABEL.png.sha1
new file mode 100644
index 0000000..e130d5a
--- /dev/null
+++ b/components/autofill_strings_grdp/IDS_AUTOFILL_UPDATE_ADDRESS_PROMPT_CANCEL_BUTTON_LABEL.png.sha1
@@ -0,0 +1 @@
+84e751eaf9c2ec6fc565674944b97a8fb8f70361
\ No newline at end of file
diff --git a/components/autofill_strings_grdp/IDS_AUTOFILL_UPDATE_ADDRESS_PROMPT_NEW_VALUES_SECTION_LABEL.png.sha1 b/components/autofill_strings_grdp/IDS_AUTOFILL_UPDATE_ADDRESS_PROMPT_NEW_VALUES_SECTION_LABEL.png.sha1
new file mode 100644
index 0000000..e130d5a
--- /dev/null
+++ b/components/autofill_strings_grdp/IDS_AUTOFILL_UPDATE_ADDRESS_PROMPT_NEW_VALUES_SECTION_LABEL.png.sha1
@@ -0,0 +1 @@
+84e751eaf9c2ec6fc565674944b97a8fb8f70361
\ No newline at end of file
diff --git a/components/autofill_strings_grdp/IDS_AUTOFILL_UPDATE_ADDRESS_PROMPT_OK_BUTTON_LABEL.png.sha1 b/components/autofill_strings_grdp/IDS_AUTOFILL_UPDATE_ADDRESS_PROMPT_OK_BUTTON_LABEL.png.sha1
new file mode 100644
index 0000000..e130d5a
--- /dev/null
+++ b/components/autofill_strings_grdp/IDS_AUTOFILL_UPDATE_ADDRESS_PROMPT_OK_BUTTON_LABEL.png.sha1
@@ -0,0 +1 @@
+84e751eaf9c2ec6fc565674944b97a8fb8f70361
\ No newline at end of file
diff --git a/components/autofill_strings_grdp/IDS_AUTOFILL_UPDATE_ADDRESS_PROMPT_OLD_VALUES_SECTION_LABEL.png.sha1 b/components/autofill_strings_grdp/IDS_AUTOFILL_UPDATE_ADDRESS_PROMPT_OLD_VALUES_SECTION_LABEL.png.sha1
new file mode 100644
index 0000000..e130d5a
--- /dev/null
+++ b/components/autofill_strings_grdp/IDS_AUTOFILL_UPDATE_ADDRESS_PROMPT_OLD_VALUES_SECTION_LABEL.png.sha1
@@ -0,0 +1 @@
+84e751eaf9c2ec6fc565674944b97a8fb8f70361
\ No newline at end of file
diff --git a/components/autofill_strings_grdp/IDS_AUTOFILL_UPDATE_ADDRESS_PROMPT_TITLE.png.sha1 b/components/autofill_strings_grdp/IDS_AUTOFILL_UPDATE_ADDRESS_PROMPT_TITLE.png.sha1
new file mode 100644
index 0000000..e130d5a
--- /dev/null
+++ b/components/autofill_strings_grdp/IDS_AUTOFILL_UPDATE_ADDRESS_PROMPT_TITLE.png.sha1
@@ -0,0 +1 @@
+84e751eaf9c2ec6fc565674944b97a8fb8f70361
\ No newline at end of file
diff --git a/components/background_sync/background_sync_metrics.h b/components/background_sync/background_sync_metrics.h
index 66db7b3..01f0ffcc0 100644
--- a/components/background_sync/background_sync_metrics.h
+++ b/components/background_sync/background_sync_metrics.h
@@ -9,6 +9,7 @@
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "services/metrics/public/cpp/ukm_source_id.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
 
 namespace {
diff --git a/components/breadcrumbs/core/breadcrumb_persistent_storage_manager.h b/components/breadcrumbs/core/breadcrumb_persistent_storage_manager.h
index 9d41bd5..884100a 100644
--- a/components/breadcrumbs/core/breadcrumb_persistent_storage_manager.h
+++ b/components/breadcrumbs/core/breadcrumb_persistent_storage_manager.h
@@ -13,6 +13,7 @@
 #include "base/timer/timer.h"
 #include "components/breadcrumbs/core/breadcrumb_manager_observer.h"
 #include "components/breadcrumbs/core/crash_reporter_breadcrumb_constants.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace breadcrumbs {
 
diff --git a/components/cdm/common/cdm_manifest.cc b/components/cdm/common/cdm_manifest.cc
index 6efbc85e..de31fce 100644
--- a/components/cdm/common/cdm_manifest.cc
+++ b/components/cdm/common/cdm_manifest.cc
@@ -24,6 +24,7 @@
 #include "media/base/decrypt_config.h"
 #include "media/base/video_codecs.h"
 #include "media/cdm/cdm_capability.h"
+#include "media/cdm/supported_audio_codecs.h"
 #include "media/cdm/supported_cdm_versions.h"
 #include "media/media_buildflags.h"
 
@@ -119,11 +120,87 @@
   return false;
 }
 
+// Returns true and updates |encryption_schemes| if the appropriate manifest
+// entry is valid. Returns false and does not modify |encryption_schemes| if the
+// manifest entry is incorrectly formatted. It is assumed that all CDMs support
+// 'cenc', so if the manifest entry is missing, the result will indicate support
+// for 'cenc' only. Incorrect types in the manifest entry will log the error and
+// fail. Unrecognized values will be reported but otherwise ignored.
+bool GetEncryptionSchemes(
+    const base::Value& manifest,
+    base::flat_set<media::EncryptionScheme>* encryption_schemes) {
+  DCHECK(manifest.is_dict());
+  DCHECK(encryption_schemes);
+
+  const base::Value* value =
+      manifest.FindKey(kCdmSupportedEncryptionSchemesName);
+  if (!value) {
+    // No manifest entry found, so assume only 'cenc' supported for backwards
+    // compatibility.
+    encryption_schemes->insert(media::EncryptionScheme::kCenc);
+    return true;
+  }
+
+  if (!value->is_list()) {
+    DLOG(ERROR) << "CDM manifest entry " << kCdmSupportedEncryptionSchemesName
+                << " is not a list.";
+    return false;
+  }
+
+  base::flat_set<media::EncryptionScheme> result;
+  for (const auto& item : value->GetList()) {
+    if (!item.is_string()) {
+      DLOG(ERROR) << "Unrecognized item type in CDM manifest entry "
+                  << kCdmSupportedEncryptionSchemesName;
+      return false;
+    }
+
+    const std::string& scheme = item.GetString();
+    if (scheme == kCdmSupportedEncryptionSchemeCenc) {
+      result.insert(media::EncryptionScheme::kCenc);
+    } else if (scheme == kCdmSupportedEncryptionSchemeCbcs) {
+      result.insert(media::EncryptionScheme::kCbcs);
+    } else {
+      DLOG(WARNING) << "Unrecognized encryption scheme '" << scheme
+                    << "' in CDM manifest entry "
+                    << kCdmSupportedEncryptionSchemesName;
+    }
+  }
+
+  // As the manifest entry exists, it must specify at least one valid value.
+  if (result.empty())
+    return false;
+
+  encryption_schemes->swap(result);
+  return true;
+}
+
+// Returns true and updates |audio_codecs| with the full set of audio
+// codecs that support decryption.
+bool GetAudioCodecs(const base::Value& manifest,
+                    std::vector<media::AudioCodec>* audio_codecs) {
+  DCHECK(manifest.is_dict());
+  DCHECK(audio_codecs);
+
+  // Note that desktop CDMs only support decryption of audio content,
+  // no decoding. Manifest does not contain any audio codecs, so return
+  // the standard set of audio codecs supported only if there is at least
+  // one encryption scheme specified.
+  base::flat_set<media::EncryptionScheme> encryption_schemes;
+  if (!GetEncryptionSchemes(manifest, &encryption_schemes)) {
+    return false;
+  }
+
+  DCHECK(!encryption_schemes.empty());
+  *audio_codecs = media::GetCdmSupportedAudioCodecs();
+  return true;
+}
+
 // Returns true and updates |video_codecs| if the appropriate manifest entry is
 // valid. Returns false and does not modify |video_codecs| if the manifest entry
 // is incorrectly formatted.
-bool GetCodecs(const base::Value& manifest,
-               std::vector<media::VideoCodec>* video_codecs) {
+bool GetVideoCodecs(const base::Value& manifest,
+                    std::vector<media::VideoCodec>* video_codecs) {
   DCHECK(manifest.is_dict());
   DCHECK(video_codecs);
 
@@ -192,61 +269,6 @@
   return true;
 }
 
-// Returns true and updates |encryption_schemes| if the appropriate manifest
-// entry is valid. Returns false and does not modify |encryption_schemes| if the
-// manifest entry is incorrectly formatted. It is assumed that all CDMs support
-// 'cenc', so if the manifest entry is missing, the result will indicate support
-// for 'cenc' only. Incorrect types in the manifest entry will log the error and
-// fail. Unrecognized values will be reported but otherwise ignored.
-bool GetEncryptionSchemes(
-    const base::Value& manifest,
-    base::flat_set<media::EncryptionScheme>* encryption_schemes) {
-  DCHECK(manifest.is_dict());
-  DCHECK(encryption_schemes);
-
-  const base::Value* value =
-      manifest.FindKey(kCdmSupportedEncryptionSchemesName);
-  if (!value) {
-    // No manifest entry found, so assume only 'cenc' supported for backwards
-    // compatibility.
-    encryption_schemes->insert(media::EncryptionScheme::kCenc);
-    return true;
-  }
-
-  if (!value->is_list()) {
-    DLOG(ERROR) << "CDM manifest entry " << kCdmSupportedEncryptionSchemesName
-                << " is not a list.";
-    return false;
-  }
-
-  base::flat_set<media::EncryptionScheme> result;
-  for (const auto& item : value->GetList()) {
-    if (!item.is_string()) {
-      DLOG(ERROR) << "Unrecognized item type in CDM manifest entry "
-                  << kCdmSupportedEncryptionSchemesName;
-      return false;
-    }
-
-    const std::string& scheme = item.GetString();
-    if (scheme == kCdmSupportedEncryptionSchemeCenc) {
-      result.insert(media::EncryptionScheme::kCenc);
-    } else if (scheme == kCdmSupportedEncryptionSchemeCbcs) {
-      result.insert(media::EncryptionScheme::kCbcs);
-    } else {
-      DLOG(WARNING) << "Unrecognized encryption scheme '" << scheme
-                    << "' in CDM manifest entry "
-                    << kCdmSupportedEncryptionSchemesName;
-    }
-  }
-
-  // As the manifest entry exists, it must specify at least one valid value.
-  if (result.empty())
-    return false;
-
-  encryption_schemes->swap(result);
-  return true;
-}
-
 bool GetVersion(const base::Value& manifest, base::Version* version) {
   DCHECK(manifest.is_dict());
   auto* version_string = manifest.FindStringKey(kCdmVersion);
@@ -282,7 +304,8 @@
                       media::CdmCapability* capability) {
   DCHECK(manifest.is_dict());
 
-  return GetCodecs(manifest, &capability->video_codecs) &&
+  return GetAudioCodecs(manifest, &capability->audio_codecs) &&
+         GetVideoCodecs(manifest, &capability->video_codecs) &&
          GetEncryptionSchemes(manifest, &capability->encryption_schemes) &&
          GetSessionTypes(manifest, &capability->session_types);
 }
diff --git a/components/cdm/common/cdm_manifest_unittest.cc b/components/cdm/common/cdm_manifest_unittest.cc
index 4240d569a..0584a8a 100644
--- a/components/cdm/common/cdm_manifest_unittest.cc
+++ b/components/cdm/common/cdm_manifest_unittest.cc
@@ -96,8 +96,9 @@
   return dict;
 }
 
-void CheckCodecs(const std::vector<media::VideoCodec>& actual,
-                 const std::vector<media::VideoCodec>& expected) {
+template <class Codec>
+void CheckCodecs(const std::vector<Codec>& actual,
+                 const std::vector<Codec>& expected) {
   EXPECT_EQ(expected.size(), actual.size());
   for (const auto& codec : expected) {
     EXPECT_TRUE(base::Contains(actual, codec));
@@ -185,6 +186,13 @@
   CheckCodecs(capability.video_codecs,
               {media::VideoCodec::kCodecVP8, media::VideoCodec::kCodecVP9,
                media::VideoCodec::kCodecAV1});
+  CheckCodecs(capability.audio_codecs, {
+    media::AudioCodec::kCodecOpus, media::AudioCodec::kCodecVorbis,
+        media::AudioCodec::kCodecFLAC,
+#if BUILDFLAG(USE_PROPRIETARY_CODECS)
+        media::AudioCodec::kCodecAAC,
+#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
+  });
   CheckEncryptionSchemes(
       capability.encryption_schemes,
       {media::EncryptionScheme::kCenc, media::EncryptionScheme::kCbcs});
@@ -198,6 +206,13 @@
   CdmCapability capability;
   EXPECT_TRUE(ParseCdmManifest(manifest, &capability));
   CheckCodecs(capability.video_codecs, {});
+  CheckCodecs(capability.audio_codecs, {
+    media::AudioCodec::kCodecOpus, media::AudioCodec::kCodecVorbis,
+        media::AudioCodec::kCodecFLAC,
+#if BUILDFLAG(USE_PROPRIETARY_CODECS)
+        media::AudioCodec::kCodecAAC,
+#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
+  });
   CheckEncryptionSchemes(capability.encryption_schemes,
                          {media::EncryptionScheme::kCenc});
   CheckSessionTypes(capability.session_types,
diff --git a/components/feature_engagement/public/event_constants.cc b/components/feature_engagement/public/event_constants.cc
index d1f26b4..b354db6a 100644
--- a/components/feature_engagement/public/event_constants.cc
+++ b/components/feature_engagement/public/event_constants.cc
@@ -39,6 +39,10 @@
 const char kWebUITabStripOpened[] = "webui_tab_strip_opened";
 
 const char kDesktopPwaInstalled[] = "desktop_pwa_installed";
+
+const char kUpdatedConnectionSecurityIndicatorDisplayed[] =
+    "updated_connection_security_indicator_displayed";
+
 #endif  // defined(OS_WIN) || defined(OS_APPLE) || defined(OS_LINUX) ||
         // defined(OS_CHROMEOS)
 
diff --git a/components/feature_engagement/public/event_constants.h b/components/feature_engagement/public/event_constants.h
index 2fd6821f..a81e8b7d 100644
--- a/components/feature_engagement/public/event_constants.h
+++ b/components/feature_engagement/public/event_constants.h
@@ -66,6 +66,9 @@
 // The PWA was installed by the user.
 extern const char kDesktopPwaInstalled[];
 
+// Omnibox displayed the updated connection security indicator.
+extern const char kUpdatedConnectionSecurityIndicatorDisplayed[];
+
 #endif  // defined(OS_WIN) || defined(OS_APPLE) || defined(OS_LINUX) ||
         // defined(OS_CHROMEOS)
 
diff --git a/components/feature_engagement/public/feature_constants.cc b/components/feature_engagement/public/feature_constants.cc
index 0557f22..8b6f5514 100644
--- a/components/feature_engagement/public/feature_constants.cc
+++ b/components/feature_engagement/public/feature_constants.cc
@@ -38,6 +38,10 @@
     "IPH_DesktopPwaInstall", base::FEATURE_DISABLED_BY_DEFAULT};
 const base::Feature kIPHProfileSwitchFeature{"IPH_ProfileSwitch",
                                              base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kIPHUpdatedConnectionSecurityIndicatorsFeature{
+    "IPH_UpdatedConnectionSecurityIndicators",
+    base::FEATURE_DISABLED_BY_DEFAULT};
+
 #endif  // defined(OS_WIN) || defined(OS_APPLE) || defined(OS_LINUX) ||
         // defined(OS_CHROMEOS)
 
diff --git a/components/feature_engagement/public/feature_constants.h b/components/feature_engagement/public/feature_constants.h
index 56d24804..decd9372 100644
--- a/components/feature_engagement/public/feature_constants.h
+++ b/components/feature_engagement/public/feature_constants.h
@@ -30,6 +30,7 @@
 extern const base::Feature kIPHDesktopSnoozeFeature;
 extern const base::Feature kIPHDesktopPwaInstallFeature;
 extern const base::Feature kIPHProfileSwitchFeature;
+extern const base::Feature kIPHUpdatedConnectionSecurityIndicatorsFeature;
 #endif  // defined(OS_WIN) || defined(OS_APPLE) || defined(OS_LINUX) ||
         // defined(OS_CHROMEOS)
 
diff --git a/components/feature_engagement/public/feature_list.cc b/components/feature_engagement/public/feature_list.cc
index 6d63f5a1..806eca8 100644
--- a/components/feature_engagement/public/feature_list.cc
+++ b/components/feature_engagement/public/feature_list.cc
@@ -98,6 +98,7 @@
     &kIPHWebUITabStripFeature,
     &kIPHDesktopPwaInstallFeature,
     &kIPHProfileSwitchFeature,
+    &kIPHUpdatedConnectionSecurityIndicatorsFeature,
 #endif  // defined(OS_WIN) || defined(OS_APPLE) || defined(OS_LINUX) ||
         // defined(OS_CHROMEOS)
 };
diff --git a/components/feature_engagement/public/feature_list.h b/components/feature_engagement/public/feature_list.h
index e2327af..6bbe3353 100644
--- a/components/feature_engagement/public/feature_list.h
+++ b/components/feature_engagement/public/feature_list.h
@@ -175,6 +175,8 @@
 DEFINE_VARIATION_PARAM(kIPHWebUITabStripFeature, "IPH_WebUITabStrip");
 DEFINE_VARIATION_PARAM(kIPHDesktopPwaInstallFeature, "IPH_DesktopPwaInstall");
 DEFINE_VARIATION_PARAM(kIPHProfileSwitchFeature, "IPH_ProfileSwitch");
+DEFINE_VARIATION_PARAM(kIPHUpdatedConnectionSecurityIndicatorsFeature,
+                       "IPH_UpdatedConnectionSecurityIndicators");
 #endif  // defined(OS_WIN) || defined(OS_APPLE) || defined(OS_LINUX) ||
         // defined(OS_CHROMEOS)
 
@@ -266,6 +268,7 @@
         VARIATION_ENTRY(kIPHWebUITabStripFeature),
         VARIATION_ENTRY(kIPHDesktopPwaInstallFeature),
         VARIATION_ENTRY(kIPHProfileSwitchFeature),
+        VARIATION_ENTRY(kIPHUpdatedConnectionSecurityIndicatorsFeature),
 #endif  // defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) ||
         // defined(OS_CHROMEOS)
 };
diff --git a/components/feed/core/common/pref_names.cc b/components/feed/core/common/pref_names.cc
index 020c73a..0915009 100644
--- a/components/feed/core/common/pref_names.cc
+++ b/components/feed/core/common/pref_names.cc
@@ -40,7 +40,6 @@
 // This pref applies to all discover APIs despite the string.
 const char kDiscoverAPIEndpointOverride[] = "feedv2.actions_endpoint_override";
 const char kExperiments[] = "feedv2.experiments";
-const char kEnableWebFeedUI[] = "webfeed_ui.enable";
 const char kEnableWebFeedFollowIntroDebug[] =
     "webfeed_follow_intro_debug.enable";
 const char kReliabilityLoggingIdSalt[] = "feedv2.reliability_logging_id_salt";
@@ -50,6 +49,7 @@
 
 // Deprecated prefs:
 namespace {
+// Deprecated 02/2021
 const char kLastRefreshWasSignedIn[] = "feed.last_refresh_was_signed_in";
 const char kBackgroundRefreshPeriod[] = "feed.background_refresh_period";
 const char kThrottlerRequestCount[] = "feed.refresh_throttler.count";
@@ -58,18 +58,19 @@
     "feed.user_classifier.average_suggestions_veiwed_per_hour";
 const char kUserClassifierAverageSuggestionsUsedPerHour[] =
     "feed.user_classifier.average_suggestions_used_per_hour";
-
 const char kUserClassifierLastTimeToViewSuggestions[] =
     "feed.user_classifier.last_time_to_view_suggestions";
 const char kUserClassifierLastTimeToUseSuggestions[] =
     "feed.user_classifier.last_time_to_use_suggestions";
 
+// Deprecated 05/2021 (can be removed along with 02/2021)
+const char kEnableWebFeedUI[] = "webfeed_ui.enable";
+
 void RegisterObsoletePrefsFeb_2021(PrefRegistrySimple* registry) {
   registry->RegisterBooleanPref(kLastRefreshWasSignedIn, false);
   registry->RegisterTimeDeltaPref(kBackgroundRefreshPeriod, base::TimeDelta());
   registry->RegisterIntegerPref(kThrottlerRequestCount, 0);
   registry->RegisterIntegerPref(kThrottlerRequestsDay, 0);
-
   registry->RegisterDoublePref(kUserClassifierAverageSuggestionsViwedPerHour,
                                0.0);
   registry->RegisterDoublePref(kUserClassifierAverageSuggestionsUsedPerHour,
@@ -78,6 +79,7 @@
                              base::Time());
   registry->RegisterTimePref(kUserClassifierLastTimeToUseSuggestions,
                              base::Time());
+  registry->RegisterBooleanPref(kEnableWebFeedUI, false);
 }
 }  // namespace
 
@@ -101,7 +103,6 @@
   registry->RegisterIntegerPref(feed::prefs::kNoticeCardViewsCount, 0);
   registry->RegisterIntegerPref(feed::prefs::kNoticeCardClicksCount, 0);
   registry->RegisterDictionaryPref(feed::prefs::kExperiments);
-  registry->RegisterBooleanPref(feed::prefs::kEnableWebFeedUI, false);
   registry->RegisterBooleanPref(feed::prefs::kEnableWebFeedFollowIntroDebug,
                                 false);
   registry->RegisterUint64Pref(feed::prefs::kReliabilityLoggingIdSalt, 0);
@@ -120,11 +121,11 @@
   prefs->ClearPref(kBackgroundRefreshPeriod);
   prefs->ClearPref(kThrottlerRequestCount);
   prefs->ClearPref(kThrottlerRequestsDay);
-
   prefs->ClearPref(kUserClassifierAverageSuggestionsViwedPerHour);
   prefs->ClearPref(kUserClassifierAverageSuggestionsUsedPerHour);
   prefs->ClearPref(kUserClassifierLastTimeToViewSuggestions);
   prefs->ClearPref(kUserClassifierLastTimeToUseSuggestions);
+  prefs->ClearPref(kEnableWebFeedUI);
 }
 
 }  // namespace feed
diff --git a/components/feed/core/common/pref_names.h b/components/feed/core/common/pref_names.h
index 27737d47..1853182c 100644
--- a/components/feed/core/common/pref_names.h
+++ b/components/feed/core/common/pref_names.h
@@ -67,8 +67,6 @@
 extern const char kDiscoverAPIEndpointOverride[];
 // The pref name for storing the server experiments the client is in.
 extern const char kExperiments[];
-// If set to false, the WebFeed UI is disabled.
-extern const char kEnableWebFeedUI[];
 // If set to true, the WebFeed follow intro bypasses some gates and only checks
 // for recommended and scroll status.
 extern const char kEnableWebFeedFollowIntroDebug[];
diff --git a/components/keyed_service/core/keyed_service_shutdown_notifier.cc b/components/keyed_service/core/keyed_service_shutdown_notifier.cc
index 6f06f25..d451c42b9 100644
--- a/components/keyed_service/core/keyed_service_shutdown_notifier.cc
+++ b/components/keyed_service/core/keyed_service_shutdown_notifier.cc
@@ -5,14 +5,12 @@
 #include "components/keyed_service/core/keyed_service_export.h"
 #include "components/keyed_service/core/keyed_service_shutdown_notifier.h"
 
-KeyedServiceShutdownNotifier::KeyedServiceShutdownNotifier() {
-}
-KeyedServiceShutdownNotifier::~KeyedServiceShutdownNotifier() {
-}
+KeyedServiceShutdownNotifier::KeyedServiceShutdownNotifier() = default;
+KeyedServiceShutdownNotifier::~KeyedServiceShutdownNotifier() = default;
 
 base::CallbackListSubscription KeyedServiceShutdownNotifier::Subscribe(
-    const base::RepeatingClosure& callback) {
-  return closure_list_.Add(callback);
+    base::OnceClosure callback) {
+  return closure_list_.Add(std::move(callback));
 }
 
 void KeyedServiceShutdownNotifier::Shutdown() {
diff --git a/components/keyed_service/core/keyed_service_shutdown_notifier.h b/components/keyed_service/core/keyed_service_shutdown_notifier.h
index 90ef2af..47603d1 100644
--- a/components/keyed_service/core/keyed_service_shutdown_notifier.h
+++ b/components/keyed_service/core/keyed_service_shutdown_notifier.h
@@ -24,14 +24,13 @@
   // Subscribe for a notification when the keyed services this object depends on
   // (as defined by its factory) are shut down. The subscription can be
   // destroyed to unsubscribe.
-  base::CallbackListSubscription Subscribe(
-      const base::RepeatingClosure& callback);
+  base::CallbackListSubscription Subscribe(base::OnceClosure callback);
 
  private:
   // KeyedService implementation:
   void Shutdown() override;
 
-  base::RepeatingClosureList closure_list_;
+  base::OnceClosureList closure_list_;
 
   DISALLOW_COPY_AND_ASSIGN(KeyedServiceShutdownNotifier);
 };
diff --git a/components/metrics/demographics/demographic_metrics_provider.h b/components/metrics/demographics/demographic_metrics_provider.h
index a6e7cafb..fe4aa99 100644
--- a/components/metrics/demographics/demographic_metrics_provider.h
+++ b/components/metrics/demographics/demographic_metrics_provider.h
@@ -13,6 +13,7 @@
 #include "components/metrics/metrics_provider.h"
 #include "components/metrics/ukm_demographic_metrics_provider.h"
 #include "components/sync/driver/sync_service.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/metrics_proto/chrome_user_metrics_extension.pb.h"
 #include "third_party/metrics_proto/user_demographics.pb.h"
 
diff --git a/components/plugins/renderer/webview_plugin.cc b/components/plugins/renderer/webview_plugin.cc
index 07324967..1708309 100644
--- a/components/plugins/renderer/webview_plugin.cc
+++ b/components/plugins/renderer/webview_plugin.cc
@@ -306,10 +306,6 @@
   web_view_->Close();
 }
 
-bool WebViewPlugin::WebViewHelper::CanUpdateLayout() {
-  return true;
-}
-
 void WebViewPlugin::WebViewHelper::UpdateTooltipUnderCursor(
     const std::u16string& tooltip_text,
     base::i18n::TextDirection hint) {
diff --git a/components/plugins/renderer/webview_plugin.h b/components/plugins/renderer/webview_plugin.h
index c003bb1..431cebf 100644
--- a/components/plugins/renderer/webview_plugin.h
+++ b/components/plugins/renderer/webview_plugin.h
@@ -168,7 +168,6 @@
     blink::WebNavigationControl* main_frame() { return frame_; }
 
     // WebViewClient methods:
-    bool CanUpdateLayout() override;
     void InvalidateContainer() override;
 
     // WebNonCompositedWidgetClient overrides.
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json
index d716c10..fb22397 100644
--- a/components/policy/resources/policy_templates.json
+++ b/components/policy/resources/policy_templates.json
@@ -18630,7 +18630,7 @@
                 'duration_mins': {
                   'description': '''Time period (minutes) that specifies the length of the relaunch window.''',
                   'type': 'integer',
-                  'minimum': 0,
+                  'minimum': 1,
                   'maximum': 1440
                 }
               },
diff --git a/components/power_scheduler/power_mode_voter.h b/components/power_scheduler/power_mode_voter.h
index 84e1729..c58b216 100644
--- a/components/power_scheduler/power_mode_voter.h
+++ b/components/power_scheduler/power_mode_voter.h
@@ -10,6 +10,7 @@
 #include "base/component_export.h"
 #include "base/time/time.h"
 #include "components/power_scheduler/power_mode.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace power_scheduler {
 
diff --git a/components/privacy_sandbox_strings.grdp b/components/privacy_sandbox_strings.grdp
index dcadce2..2730a45f 100644
--- a/components/privacy_sandbox_strings.grdp
+++ b/components/privacy_sandbox_strings.grdp
@@ -3,6 +3,15 @@
   <message name="IDS_PRIVACY_SANDBOX_FLOC_INVALID" desc="A message shown in place of the user's FLoC ID if the ID is invalid for any reason, such as not enough data to compute it">
     ID currently invalid
   </message>
+  <message name="IDS_PRIVACY_SANDBOX_FLOC_TIME_TO_NEXT_COMPUTE" desc="Description of how long until the user's FLoC ID is recomputed, in days.">
+    {NUM_DAYS, plural,
+     =0 {In less than 1 day}
+     =1 {In 1 day}
+     other {In {NUM_DAYS} days}}
+  </message>
+  <message name="IDS_PRIVACY_SANDBOX_FLOC_TIME_TO_NEXT_COMPUTE_INVALID" desc="A message shown in place of when the user's FLoC ID will be next computed if the user's ID will not be recomputed for any reason, such as having FLoC disabled">
+    Not applicable
+  </message>
   <message name="IDS_PRIVACY_SANDBOX_FLOC_RESET_EXPLANATION" desc="Description of what happens when a user chooses to reset their Federated Learning of Cohorts (FLoC) identifier">
     {NUM_DAYS, plural,
      =0 {When you reset ID, your current ID will become invalid and a new one will be issued in less than 1 day}
diff --git a/components/privacy_sandbox_strings_grdp/IDS_PRIVACY_SANDBOX_FLOC_TIME_TO_NEXT_COMPUTE.png.sha1 b/components/privacy_sandbox_strings_grdp/IDS_PRIVACY_SANDBOX_FLOC_TIME_TO_NEXT_COMPUTE.png.sha1
new file mode 100644
index 0000000..c7482d5a
--- /dev/null
+++ b/components/privacy_sandbox_strings_grdp/IDS_PRIVACY_SANDBOX_FLOC_TIME_TO_NEXT_COMPUTE.png.sha1
@@ -0,0 +1 @@
+162239d9e10c268b4f6e9e0a971291c337c58ce5
\ No newline at end of file
diff --git a/components/privacy_sandbox_strings_grdp/IDS_PRIVACY_SANDBOX_FLOC_TIME_TO_NEXT_COMPUTE_INVALID.png.sha1 b/components/privacy_sandbox_strings_grdp/IDS_PRIVACY_SANDBOX_FLOC_TIME_TO_NEXT_COMPUTE_INVALID.png.sha1
new file mode 100644
index 0000000..653922e
--- /dev/null
+++ b/components/privacy_sandbox_strings_grdp/IDS_PRIVACY_SANDBOX_FLOC_TIME_TO_NEXT_COMPUTE_INVALID.png.sha1
@@ -0,0 +1 @@
+49f9f1b55c58eeb7a18da389f1d08eb4d6ae955c
\ No newline at end of file
diff --git a/components/reporting/util/status.h b/components/reporting/util/status.h
index c0a000d..d13a411 100644
--- a/components/reporting/util/status.h
+++ b/components/reporting/util/status.h
@@ -35,6 +35,8 @@
   INTERNAL = 13,
   UNAVAILABLE = 14,
   DATA_LOSS = 15,
+  // The value should always be kept last.
+  MAX_VALUE
 };
 }  // namespace error
 
diff --git a/components/services/storage/public/cpp/BUILD.gn b/components/services/storage/public/cpp/BUILD.gn
index 774d9e7..f3021e1 100644
--- a/components/services/storage/public/cpp/BUILD.gn
+++ b/components/services/storage/public/cpp/BUILD.gn
@@ -8,6 +8,7 @@
   public = [
     "constants.h",
     "quota_client_callback_wrapper.h",
+    "quota_error_or.h",
   ]
 
   sources = [
diff --git a/components/services/storage/public/cpp/quota_error_or.h b/components/services/storage/public/cpp/quota_error_or.h
new file mode 100644
index 0000000..ceb35f0c
--- /dev/null
+++ b/components/services/storage/public/cpp/quota_error_or.h
@@ -0,0 +1,54 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SERVICES_STORAGE_PUBLIC_CPP_QUOTA_ERROR_OR_H_
+#define COMPONENTS_SERVICES_STORAGE_PUBLIC_CPP_QUOTA_ERROR_OR_H_
+
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace storage {
+
+enum class QuotaError {
+  kNone = 0,
+  kUnknownError,
+  kDatabaseError,
+  kEntryExistsError,
+};
+
+// Helper for methods which perform database operations which may fail. Objects
+// of this type can on either a QuotaError or a result value of arbitrary type.
+template <typename ValueType>
+class QuotaErrorOr {
+ public:
+  QuotaErrorOr() = default;
+  QuotaErrorOr(QuotaError error) : error_(error) {}              // NOLINT
+  QuotaErrorOr(const ValueType& value) : maybe_value_(value) {}  // NOLINT
+  QuotaErrorOr(ValueType&& value)                                // NOLINT
+      : maybe_value_(absl::in_place, std::move(value)) {}
+  QuotaErrorOr(const QuotaErrorOr&) = delete;
+  QuotaErrorOr(QuotaErrorOr&&) noexcept = default;
+  QuotaErrorOr& operator=(const QuotaErrorOr&) = delete;
+  QuotaErrorOr& operator=(QuotaErrorOr&&) noexcept = default;
+  ~QuotaErrorOr() = default;
+
+  bool ok() const { return maybe_value_.has_value(); }
+  QuotaError error() const {
+    DCHECK(!ok());
+    return error_;
+  }
+
+  ValueType& value() { return maybe_value_.value(); }
+  const ValueType& value() const { return maybe_value_.value(); }
+
+  ValueType* operator->() { return &maybe_value_.value(); }
+  const ValueType* operator->() const { return &maybe_value_.value(); }
+
+ private:
+  QuotaError error_ = QuotaError::kNone;
+  absl::optional<ValueType> maybe_value_;
+};
+
+}  // namespace storage
+
+#endif  // COMPONENTS_SERVICES_STORAGE_PUBLIC_CPP_QUOTA_ERROR_OR_H_
diff --git a/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate.h b/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate.h
index b742f36d..9e3156a 100644
--- a/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate.h
+++ b/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate.h
@@ -19,6 +19,7 @@
 #include "google_apis/gaia/google_service_auth_error.h"
 #include "google_apis/gaia/oauth2_access_token_manager.h"
 #include "net/base/backoff_entry.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if defined(OS_ANDROID)
 #include "base/android/jni_android.h"
diff --git a/components/soda/OWNERS b/components/soda/OWNERS
index a8d94654..13d5ab6 100644
--- a/components/soda/OWNERS
+++ b/components/soda/OWNERS
@@ -1,2 +1,2 @@
-
+abigailbklein@google.com
 evliu@google.com
diff --git a/components/sync/engine/sync_manager_impl.cc b/components/sync/engine/sync_manager_impl.cc
index 331cac9..5e7c4ad 100644
--- a/components/sync/engine/sync_manager_impl.cc
+++ b/components/sync/engine/sync_manager_impl.cc
@@ -369,14 +369,6 @@
   }
 }
 
-void SyncManagerImpl::RequestNudgeForDataTypes(
-    const base::Location& nudge_location,
-    ModelTypeSet types) {
-  debug_info_event_listener_.OnNudgeFromDatatype(*(types.begin()));
-
-  scheduler_->ScheduleLocalNudge(types, nudge_location);
-}
-
 void SyncManagerImpl::NudgeForInitialDownload(ModelType type) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   scheduler_->ScheduleInitialSyncNudge(type);
@@ -384,7 +376,8 @@
 
 void SyncManagerImpl::NudgeForCommit(ModelType type) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  RequestNudgeForDataTypes(FROM_HERE, ModelTypeSet(type));
+  debug_info_event_listener_.OnNudgeFromDatatype(type);
+  scheduler_->ScheduleLocalNudge(type, FROM_HERE);
 }
 
 void SyncManagerImpl::OnSyncCycleEvent(const SyncCycleEvent& event) {
diff --git a/components/sync/engine/sync_manager_impl.h b/components/sync/engine/sync_manager_impl.h
index 47d909e..f7bb584 100644
--- a/components/sync/engine/sync_manager_impl.h
+++ b/components/sync/engine/sync_manager_impl.h
@@ -135,9 +135,6 @@
  private:
   void NotifyInitializationSuccess();
 
-  void RequestNudgeForDataTypes(const base::Location& nudge_location,
-                                ModelTypeSet type);
-
   const std::string name_;
 
   network::NetworkConnectionTracker* network_connection_tracker_;
diff --git a/components/sync/engine/sync_scheduler.h b/components/sync/engine/sync_scheduler.h
index e0719e646d..fedfa2d 100644
--- a/components/sync/engine/sync_scheduler.h
+++ b/components/sync/engine/sync_scheduler.h
@@ -90,7 +90,7 @@
 
   // The LocalNudge indicates that we've made a local change, and that the
   // syncer should plan to commit this to the server some time soon.
-  virtual void ScheduleLocalNudge(ModelTypeSet types,
+  virtual void ScheduleLocalNudge(ModelType type,
                                   const base::Location& nudge_location) = 0;
 
   // The LocalRefreshRequest occurs when we decide for some reason to manually
diff --git a/components/sync/engine/sync_scheduler_impl.cc b/components/sync/engine/sync_scheduler_impl.cc
index 61ff21d..c23bc22 100644
--- a/components/sync/engine/sync_scheduler_impl.cc
+++ b/components/sync/engine/sync_scheduler_impl.cc
@@ -334,14 +334,13 @@
 }
 
 void SyncSchedulerImpl::ScheduleLocalNudge(
-    ModelTypeSet types,
+    ModelType type,
     const base::Location& nudge_location) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK(!types.Empty());
 
   SDVLOG_LOC(nudge_location, 2) << "Scheduling sync because of local change to "
-                                << ModelTypeSetToString(types);
-  TimeDelta nudge_delay = nudge_tracker_.RecordLocalChange(types);
+                                << ModelTypeToString(type);
+  TimeDelta nudge_delay = nudge_tracker_.RecordLocalChange(ModelTypeSet(type));
   ScheduleNudgeImpl(nudge_delay, nudge_location);
 }
 
diff --git a/components/sync/engine/sync_scheduler_impl.h b/components/sync/engine/sync_scheduler_impl.h
index 1cfa74c..6999bed 100644
--- a/components/sync/engine/sync_scheduler_impl.h
+++ b/components/sync/engine/sync_scheduler_impl.h
@@ -46,7 +46,7 @@
   void Start(Mode mode, base::Time last_poll_time) override;
   void ScheduleConfiguration(ConfigurationParams params) override;
   void Stop() override;
-  void ScheduleLocalNudge(ModelTypeSet types,
+  void ScheduleLocalNudge(ModelType type,
                           const base::Location& nudge_location) override;
   void ScheduleLocalRefreshRequest(
       ModelTypeSet types,
diff --git a/components/sync/engine/sync_scheduler_impl_unittest.cc b/components/sync/engine/sync_scheduler_impl_unittest.cc
index 15e8821..911772c 100644
--- a/components/sync/engine/sync_scheduler_impl_unittest.cc
+++ b/components/sync/engine/sync_scheduler_impl_unittest.cc
@@ -73,18 +73,18 @@
   cycle->delegate()->OnThrottled(throttle);
 }
 
-ACTION_P2(SimulateTypesThrottled, types, throttle) {
+ACTION_P2(SimulateTypeThrottled, type, throttle) {
   SyncCycle* cycle = arg0;
   cycle->mutable_status_controller()->set_commit_result(
       SyncerError(SyncerError::SYNCER_OK));
-  cycle->delegate()->OnTypesThrottled(types, throttle);
+  cycle->delegate()->OnTypesThrottled(ModelTypeSet(type), throttle);
 }
 
-ACTION_P(SimulatePartialFailure, types) {
+ACTION_P(SimulatePartialFailure, type) {
   SyncCycle* cycle = arg0;
   cycle->mutable_status_controller()->set_commit_result(
       SyncerError(SyncerError::SYNCER_OK));
-  cycle->delegate()->OnTypesBackedOff(types);
+  cycle->delegate()->OnTypesBackedOff(ModelTypeSet(type));
 }
 
 ACTION_P(SimulatePollIntervalUpdate, new_poll) {
@@ -335,10 +335,9 @@
   }
 
   bool RunAndGetBackoff() {
-    ModelTypeSet nudge_types(THEMES);
     StartSyncScheduler(base::Time());
 
-    scheduler()->ScheduleLocalNudge(nudge_types, FROM_HERE);
+    scheduler()->ScheduleLocalNudge(THEMES, FROM_HERE);
     RunLoop();
 
     return scheduler()->IsGlobalBackoff();
@@ -498,8 +497,6 @@
 // Test nudge scheduling.
 TEST_F(SyncSchedulerImplTest, Nudge) {
   SyncShareTimes times;
-  ModelTypeSet model_types(THEMES);
-
   EXPECT_CALL(*syncer(), NormalSyncShare)
       .WillOnce(
           DoAll(Invoke(SimulateNormalSuccess), RecordSyncShare(&times, true)))
@@ -507,46 +504,32 @@
 
   StartSyncScheduler(base::Time());
 
-  scheduler()->ScheduleLocalNudge(model_types, FROM_HERE);
+  scheduler()->ScheduleLocalNudge(THEMES, FROM_HERE);
   RunLoop();
 
   Mock::VerifyAndClearExpectations(syncer());
 
   // Make sure a second, later, nudge is unaffected by first (no coalescing).
   SyncShareTimes times2;
-  model_types.Remove(THEMES);
-  model_types.Put(TYPED_URLS);
   EXPECT_CALL(*syncer(), NormalSyncShare)
       .WillOnce(
           DoAll(Invoke(SimulateNormalSuccess), RecordSyncShare(&times2, true)));
-  scheduler()->ScheduleLocalNudge(model_types, FROM_HERE);
+  scheduler()->ScheduleLocalNudge(TYPED_URLS, FROM_HERE);
   RunLoop();
 }
 
 TEST_F(SyncSchedulerImplTest, NudgeForDisabledType) {
-  ModelTypeSet model_types{THEMES, HISTORY_DELETE_DIRECTIVES};
-
   StartSyncScheduler(base::Time());
-  scheduler()->ScheduleLocalNudge(model_types, FROM_HERE);
+  scheduler()->ScheduleLocalNudge(HISTORY_DELETE_DIRECTIVES, FROM_HERE);
 
   // The user enables a custom passphrase at this point, so
   // HISTORY_DELETE_DIRECTIVES gets disabled.
   DisconnectDataType(HISTORY_DELETE_DIRECTIVES);
   ASSERT_FALSE(context()->GetEnabledTypes().Has(HISTORY_DELETE_DIRECTIVES));
 
-  // The resulting sync cycle should ask only for the remaining types.
-  SyncShareTimes times;
-  NudgeTracker* nudge_tracker = nullptr;
-  EXPECT_CALL(*syncer(), NormalSyncShare(context()->GetEnabledTypes(), _, _))
-      .WillOnce(DoAll(SaveArg<1>(&nudge_tracker), Invoke(SimulateNormalSuccess),
-                      RecordSyncShare(&times, true)));
-  RunLoop();
-
-  // Now no sync is required for the enabled types.
-  ASSERT_FALSE(nudge_tracker->IsSyncRequired(context()->GetEnabledTypes()));
-  // ...but HISTORY_DELETE_DIRECTIVES is not enabled, so its earlier nudge is
-  // still there.
-  EXPECT_TRUE(nudge_tracker->IsSyncRequired({HISTORY_DELETE_DIRECTIVES}));
+  // There should be no sync cycle.
+  EXPECT_CALL(*syncer(), NormalSyncShare).Times(0);
+  PumpLoop();
 }
 
 // Make sure a regular config command is scheduled fine in the absence of any
@@ -681,7 +664,6 @@
 // Issue a nudge when the config has failed. Make sure both the config and
 // nudge are executed.
 TEST_F(SyncSchedulerImplTest, NudgeWithConfigWithBackingOff) {
-  const ModelTypeSet model_types(THEMES);
   UseMockDelayProvider();
   EXPECT_CALL(*delay(), GetDelay)
       .WillRepeatedly(Return(TimeDelta::FromMilliseconds(50)));
@@ -693,8 +675,11 @@
   EXPECT_CALL(*syncer(), ConfigureSyncShare)
       .WillOnce(DoAll(Invoke(SimulateConfigureFailed),
                       RecordSyncShare(&times, false)));
+  // TODO(crbug.com/1210434): CallbackCounter can be replaced with MockCallback.
   CallbackCounter ready_counter;
-  ConfigurationParams params(sync_pb::SyncEnums::RECONFIGURATION, model_types,
+  const ModelType model_type = THEMES;
+  ConfigurationParams params(sync_pb::SyncEnums::RECONFIGURATION,
+                             ModelTypeSet(model_type),
                              base::BindOnce(&CallbackCounter::Callback,
                                             base::Unretained(&ready_counter)));
   scheduler()->ScheduleConfiguration(std::move(params));
@@ -706,7 +691,7 @@
   EXPECT_CALL(*syncer(), ConfigureSyncShare)
       .WillOnce(DoAll(Invoke(SimulateConfigureFailed),
                       RecordSyncShare(&times, false)));
-  scheduler()->ScheduleLocalNudge(model_types, FROM_HERE);
+  scheduler()->ScheduleLocalNudge(model_type, FROM_HERE);
   RunLoop();
   // Note that we're not RunLoop()ing for the NUDGE we just scheduled, but
   // for the first retry attempt from the config job (after
@@ -736,10 +721,9 @@
   EXPECT_CALL(*syncer(), NormalSyncShare)
       .WillOnce(
           DoAll(Invoke(SimulateNormalSuccess), RecordSyncShare(&times, true)));
-  const ModelTypeSet types1(THEMES), types2(TYPED_URLS), types3(THEMES);
   TimeTicks optimal_time = TimeTicks::Now() + default_delay();
-  scheduler()->ScheduleLocalNudge(types1, FROM_HERE);
-  scheduler()->ScheduleLocalNudge(types2, FROM_HERE);
+  scheduler()->ScheduleLocalNudge(THEMES, FROM_HERE);
+  scheduler()->ScheduleLocalNudge(TYPED_URLS, FROM_HERE);
   RunLoop();
 
   ASSERT_EQ(1U, times.size());
@@ -751,7 +735,7 @@
   EXPECT_CALL(*syncer(), NormalSyncShare)
       .WillOnce(
           DoAll(Invoke(SimulateNormalSuccess), RecordSyncShare(&times2, true)));
-  scheduler()->ScheduleLocalNudge(types3, FROM_HERE);
+  scheduler()->ScheduleLocalNudge(THEMES, FROM_HERE);
   RunLoop();
 }
 
@@ -763,16 +747,15 @@
   EXPECT_CALL(*syncer(), NormalSyncShare)
       .WillOnce(
           DoAll(Invoke(SimulateNormalSuccess), RecordSyncShare(&times, true)));
-  ModelTypeSet types1(THEMES), types2(TYPED_URLS), types3;
 
   // Create a huge time delay.
   TimeDelta delay = TimeDelta::FromDays(1);
 
   std::map<ModelType, TimeDelta> delay_map;
-  delay_map[*(types1.begin())] = delay;
+  delay_map[THEMES] = delay;
   scheduler()->OnReceivedCustomNudgeDelays(delay_map);
-  scheduler()->ScheduleLocalNudge(types1, FROM_HERE);
-  scheduler()->ScheduleLocalNudge(types2, FROM_HERE);
+  scheduler()->ScheduleLocalNudge(THEMES, FROM_HERE);
+  scheduler()->ScheduleLocalNudge(TYPED_URLS, FROM_HERE);
 
   TimeTicks min_time = TimeTicks::Now();
   TimeTicks max_time = TimeTicks::Now() + delay;
@@ -933,7 +916,6 @@
 
 // Test that no syncing occurs when throttled.
 TEST_F(SyncSchedulerImplTest, ThrottlingDoesThrottle) {
-  const ModelTypeSet types(THEMES);
   TimeDelta poll(TimeDelta::FromMilliseconds(20));
   TimeDelta throttle(TimeDelta::FromMinutes(10));
   scheduler()->OnReceivedPollIntervalUpdate(poll);
@@ -944,13 +926,15 @@
 
   StartSyncScheduler(base::Time());
 
-  scheduler()->ScheduleLocalNudge(types, FROM_HERE);
+  const ModelType type = THEMES;
+  scheduler()->ScheduleLocalNudge(type, FROM_HERE);
   PumpLoop();
 
   StartSyncConfiguration();
 
   CallbackCounter ready_counter;
-  ConfigurationParams params(sync_pb::SyncEnums::RECONFIGURATION, types,
+  ConfigurationParams params(sync_pb::SyncEnums::RECONFIGURATION,
+                             ModelTypeSet(type),
                              base::BindOnce(&CallbackCounter::Callback,
                                             base::Unretained(&ready_counter)));
   scheduler()->ScheduleConfiguration(std::move(params));
@@ -996,9 +980,8 @@
   EXPECT_CALL(*syncer(), NormalSyncShare)
       .WillOnce(DoAll(Invoke(SimulateNormalSuccess), QuitLoopNowAction(true)));
 
-  const ModelTypeSet types(THEMES);
   StartSyncScheduler(base::Time());
-  scheduler()->ScheduleLocalNudge(types, FROM_HERE);
+  scheduler()->ScheduleLocalNudge(THEMES, FROM_HERE);
 
   PumpLoop();  // To get PerformDelayedNudge called.
   PumpLoop();  // To get TrySyncCycleJob called
@@ -1046,24 +1029,24 @@
   TimeDelta throttle1(TimeDelta::FromSeconds(60));
   scheduler()->OnReceivedPollIntervalUpdate(poll);
 
-  const ModelTypeSet types(THEMES);
+  const ModelType type = THEMES;
 
   ::testing::InSequence seq;
   EXPECT_CALL(*syncer(), NormalSyncShare)
-      .WillOnce(DoAll(WithArg<2>(SimulateTypesThrottled(types, throttle1)),
+      .WillOnce(DoAll(WithArg<2>(SimulateTypeThrottled(type, throttle1)),
                       Return(true)))
       .RetiresOnSaturation();
 
   StartSyncScheduler(base::Time());
-  scheduler()->ScheduleLocalNudge(types, FROM_HERE);
+  scheduler()->ScheduleLocalNudge(type, FROM_HERE);
   PumpLoop();  // To get PerformDelayedNudge called.
   PumpLoop();  // To get TrySyncCycleJob called
-  EXPECT_TRUE(GetThrottledTypes().HasAll(types));
+  EXPECT_TRUE(GetThrottledTypes().Has(type));
   EXPECT_FALSE(scheduler()->IsGlobalBackoff());
   EXPECT_FALSE(scheduler()->IsGlobalThrottle());
 
   // This won't cause a sync cycle because the types are throttled.
-  scheduler()->ScheduleLocalNudge(types, FROM_HERE);
+  scheduler()->ScheduleLocalNudge(type, FROM_HERE);
   PumpLoop();
 
   StopSyncScheduler();
@@ -1076,23 +1059,23 @@
   TimeDelta poll(TimeDelta::FromDays(1));
   scheduler()->OnReceivedPollIntervalUpdate(poll);
 
-  const ModelTypeSet types(THEMES);
+  const ModelType type = THEMES;
 
   ::testing::InSequence seq;
   EXPECT_CALL(*syncer(), NormalSyncShare)
-      .WillOnce(DoAll(WithArg<2>(SimulatePartialFailure(types)), Return(true)))
+      .WillOnce(DoAll(WithArg<2>(SimulatePartialFailure(type)), Return(true)))
       .RetiresOnSaturation();
 
   StartSyncScheduler(base::Time());
-  scheduler()->ScheduleLocalNudge(types, FROM_HERE);
+  scheduler()->ScheduleLocalNudge(type, FROM_HERE);
   PumpLoop();  // To get PerformDelayedNudge called.
   PumpLoop();  // To get TrySyncCycleJob called
-  EXPECT_TRUE(GetBackedOffTypes().HasAll(types));
+  EXPECT_TRUE(GetBackedOffTypes().Has(type));
   EXPECT_FALSE(scheduler()->IsGlobalBackoff());
   EXPECT_FALSE(scheduler()->IsGlobalThrottle());
 
   // This won't cause a sync cycle because the types are backed off.
-  scheduler()->ScheduleLocalNudge(types, FROM_HERE);
+  scheduler()->ScheduleLocalNudge(type, FROM_HERE);
   PumpLoop();
 
   StopSyncScheduler();
@@ -1105,18 +1088,18 @@
   TimeDelta poll(TimeDelta::FromDays(1));
   scheduler()->OnReceivedPollIntervalUpdate(poll);
 
-  const ModelTypeSet types(THEMES);
+  const ModelType type = THEMES;
 
   ::testing::InSequence seq;
   EXPECT_CALL(*syncer(), NormalSyncShare)
-      .WillOnce(DoAll(WithArg<2>(SimulatePartialFailure(types)), Return(true)))
+      .WillOnce(DoAll(WithArg<2>(SimulatePartialFailure(type)), Return(true)))
       .RetiresOnSaturation();
 
   StartSyncScheduler(base::Time());
-  scheduler()->ScheduleLocalNudge(types, FROM_HERE);
+  scheduler()->ScheduleLocalNudge(type, FROM_HERE);
   PumpLoop();  // To get PerformDelayedNudge called.
   PumpLoop();  // To get TrySyncCycleJob called
-  EXPECT_TRUE(GetBackedOffTypes().HasAll(types));
+  EXPECT_TRUE(GetBackedOffTypes().Has(type));
   EXPECT_FALSE(scheduler()->IsGlobalBackoff());
   EXPECT_FALSE(scheduler()->IsGlobalThrottle());
 
@@ -1140,18 +1123,18 @@
   TimeDelta poll(TimeDelta::FromDays(1));
   scheduler()->OnReceivedPollIntervalUpdate(poll);
 
-  const ModelTypeSet types(THEMES);
+  const ModelType type = THEMES;
 
   ::testing::InSequence seq;
   EXPECT_CALL(*syncer(), NormalSyncShare)
-      .WillOnce(DoAll(WithArg<2>(SimulatePartialFailure(types)), Return(true)))
+      .WillOnce(DoAll(WithArg<2>(SimulatePartialFailure(type)), Return(true)))
       .RetiresOnSaturation();
 
   StartSyncScheduler(base::Time());
-  scheduler()->ScheduleLocalNudge(types, FROM_HERE);
+  scheduler()->ScheduleLocalNudge(type, FROM_HERE);
   PumpLoop();  // To get PerformDelayedNudge called.
   PumpLoop();  // To get TrySyncCycleJob called
-  EXPECT_TRUE(GetBackedOffTypes().HasAll(types));
+  EXPECT_TRUE(GetBackedOffTypes().Has(type));
   EXPECT_TRUE(BlockTimerIsRunning());
   EXPECT_FALSE(scheduler()->IsGlobalBackoff());
   EXPECT_FALSE(scheduler()->IsGlobalThrottle());
@@ -1163,12 +1146,11 @@
       .RetiresOnSaturation();
 
   // Sync still can throttle.
-  const ModelTypeSet unbacked_off_types(TYPED_URLS);
-  scheduler()->ScheduleLocalNudge(unbacked_off_types, FROM_HERE);
+  scheduler()->ScheduleLocalNudge(TYPED_URLS, FROM_HERE);
   PumpLoop();  // TO get TypesUnblock called.
   PumpLoop();  // To get TrySyncCycleJob called.
 
-  EXPECT_TRUE(GetBackedOffTypes().HasAll(types));
+  EXPECT_TRUE(GetBackedOffTypes().Has(type));
   EXPECT_TRUE(BlockTimerIsRunning());
   EXPECT_FALSE(scheduler()->IsGlobalBackoff());
   EXPECT_TRUE(scheduler()->IsGlobalThrottle());
@@ -1179,7 +1161,7 @@
       .WillOnce(DoAll(Invoke(SimulateNormalSuccess), QuitLoopNowAction(true)));
   RunLoop();
   EXPECT_FALSE(scheduler()->IsGlobalThrottle());
-  EXPECT_TRUE(GetBackedOffTypes().HasAll(types));
+  EXPECT_TRUE(GetBackedOffTypes().Has(type));
   EXPECT_TRUE(BlockTimerIsRunning());
 
   StopSyncScheduler();
@@ -1193,42 +1175,43 @@
   TimeDelta throttle(TimeDelta::FromSeconds(60));
   scheduler()->OnReceivedPollIntervalUpdate(poll);
 
-  const ModelTypeSet throttled_types(THEMES);
+  const ModelType throttled_type = THEMES;
 
   ::testing::InSequence seq;
   EXPECT_CALL(*syncer(), NormalSyncShare)
       .WillOnce(
-          DoAll(WithArg<2>(SimulateTypesThrottled(throttled_types, throttle)),
+          DoAll(WithArg<2>(SimulateTypeThrottled(throttled_type, throttle)),
                 Return(true)))
       .RetiresOnSaturation();
 
   StartSyncScheduler(base::Time());
-  scheduler()->ScheduleLocalNudge(throttled_types, FROM_HERE);
+  scheduler()->ScheduleLocalNudge(throttled_type, FROM_HERE);
   PumpLoop();  // To get PerformDelayedNudge called.
   PumpLoop();  // To get TrySyncCycleJob called
 
-  const ModelTypeSet backed_off_types(TYPED_URLS);
+  const ModelType backed_off_type = TYPED_URLS;
 
   EXPECT_CALL(*syncer(), NormalSyncShare)
-      .WillOnce(DoAll(WithArg<2>(SimulatePartialFailure(backed_off_types)),
+      .WillOnce(DoAll(WithArg<2>(SimulatePartialFailure(backed_off_type)),
                       Return(true)))
       .RetiresOnSaturation();
 
-  scheduler()->ScheduleLocalNudge(backed_off_types, FROM_HERE);
+  scheduler()->ScheduleLocalNudge(backed_off_type, FROM_HERE);
 
   PumpLoop();  // To get PerformDelayedNudge called.
   PumpLoop();  // To get TrySyncCycleJob called
 
-  EXPECT_TRUE(GetThrottledTypes().HasAll(throttled_types));
-  EXPECT_TRUE(GetBackedOffTypes().HasAll(backed_off_types));
+  EXPECT_TRUE(GetThrottledTypes().Has(throttled_type));
+  EXPECT_TRUE(GetBackedOffTypes().Has(backed_off_type));
   EXPECT_TRUE(BlockTimerIsRunning());
   EXPECT_FALSE(scheduler()->IsGlobalBackoff());
   EXPECT_FALSE(scheduler()->IsGlobalThrottle());
 
-  // This won't cause a sync cycle because the types are throttled or backed
-  // off.
-  scheduler()->ScheduleLocalNudge(Union(throttled_types, backed_off_types),
-                                  FROM_HERE);
+  // Neither of these will cause a sync cycle because the types are throttled or
+  // backed off.
+  scheduler()->ScheduleLocalNudge(throttled_type, FROM_HERE);
+  PumpLoop();
+  scheduler()->ScheduleLocalNudge(backed_off_type, FROM_HERE);
   PumpLoop();
 
   StopSyncScheduler();
@@ -1243,31 +1226,31 @@
   TimeDelta throttle1(TimeDelta::FromSeconds(60));
   scheduler()->OnReceivedPollIntervalUpdate(poll);
 
-  const ModelTypeSet throttled_types(THEMES);
-  const ModelTypeSet unthrottled_types(PREFERENCES);
+  const ModelType throttled_type = THEMES;
 
   ::testing::InSequence seq;
   EXPECT_CALL(*syncer(), NormalSyncShare)
       .WillOnce(
-          DoAll(WithArg<2>(SimulateTypesThrottled(throttled_types, throttle1)),
+          DoAll(WithArg<2>(SimulateTypeThrottled(throttled_type, throttle1)),
                 Return(true)))
       .RetiresOnSaturation();
 
   StartSyncScheduler(base::Time());
-  scheduler()->ScheduleLocalNudge(throttled_types, FROM_HERE);
+  scheduler()->ScheduleLocalNudge(throttled_type, FROM_HERE);
   PumpLoop();  // To get PerformDelayedNudge called.
   PumpLoop();  // To get TrySyncCycleJob called
-  EXPECT_TRUE(GetThrottledTypes().HasAll(throttled_types));
+  EXPECT_TRUE(GetThrottledTypes().Has(throttled_type));
   EXPECT_FALSE(scheduler()->IsGlobalBackoff());
   EXPECT_FALSE(scheduler()->IsGlobalThrottle());
 
   // Ignore invalidations for throttled types.
-  scheduler()->ScheduleInvalidationNudge(THEMES, BuildInvalidation(10, "test"),
-                                         FROM_HERE);
+  scheduler()->ScheduleInvalidationNudge(
+      throttled_type, BuildInvalidation(10, "test"), FROM_HERE);
   PumpLoop();
 
   // Ignore refresh requests for throttled types.
-  scheduler()->ScheduleLocalRefreshRequest(throttled_types, FROM_HERE);
+  scheduler()->ScheduleLocalRefreshRequest(ModelTypeSet(throttled_type),
+                                           FROM_HERE);
   PumpLoop();
 
   Mock::VerifyAndClearExpectations(syncer());
@@ -1276,7 +1259,7 @@
   EXPECT_CALL(*syncer(), NormalSyncShare)
       .WillRepeatedly(
           DoAll(Invoke(SimulateNormalSuccess), RecordSyncShare(&times, true)));
-  scheduler()->ScheduleLocalNudge(unthrottled_types, FROM_HERE);
+  scheduler()->ScheduleLocalNudge(PREFERENCES, FROM_HERE);
   RunLoop();
   Mock::VerifyAndClearExpectations(syncer());
 
@@ -1291,30 +1274,30 @@
   TimeDelta poll(TimeDelta::FromDays(1));
   scheduler()->OnReceivedPollIntervalUpdate(poll);
 
-  const ModelTypeSet backed_off_types(THEMES);
-  const ModelTypeSet unbacked_off_types(PREFERENCES);
+  const ModelType backed_off_type = THEMES;
 
   ::testing::InSequence seq;
   EXPECT_CALL(*syncer(), NormalSyncShare)
-      .WillOnce(DoAll(WithArg<2>(SimulatePartialFailure(backed_off_types)),
+      .WillOnce(DoAll(WithArg<2>(SimulatePartialFailure(backed_off_type)),
                       Return(true)))
       .RetiresOnSaturation();
 
   StartSyncScheduler(base::Time());
-  scheduler()->ScheduleLocalNudge(backed_off_types, FROM_HERE);
+  scheduler()->ScheduleLocalNudge(backed_off_type, FROM_HERE);
   PumpLoop();  // To get PerformDelayedNudge called.
   PumpLoop();  // To get TrySyncCycleJob called
-  EXPECT_TRUE(GetBackedOffTypes().HasAll(backed_off_types));
+  EXPECT_TRUE(GetBackedOffTypes().Has(backed_off_type));
   EXPECT_FALSE(scheduler()->IsGlobalBackoff());
   EXPECT_FALSE(scheduler()->IsGlobalThrottle());
 
   // Ignore invalidations for backed off types.
-  scheduler()->ScheduleInvalidationNudge(THEMES, BuildInvalidation(10, "test"),
-                                         FROM_HERE);
+  scheduler()->ScheduleInvalidationNudge(
+      backed_off_type, BuildInvalidation(10, "test"), FROM_HERE);
   PumpLoop();
 
   // Ignore refresh requests for backed off types.
-  scheduler()->ScheduleLocalRefreshRequest(backed_off_types, FROM_HERE);
+  scheduler()->ScheduleLocalRefreshRequest(ModelTypeSet(backed_off_type),
+                                           FROM_HERE);
   PumpLoop();
 
   Mock::VerifyAndClearExpectations(syncer());
@@ -1323,7 +1306,7 @@
   EXPECT_CALL(*syncer(), NormalSyncShare)
       .WillRepeatedly(
           DoAll(Invoke(SimulateNormalSuccess), RecordSyncShare(&times, true)));
-  scheduler()->ScheduleLocalNudge(unbacked_off_types, FROM_HERE);
+  scheduler()->ScheduleLocalNudge(PREFERENCES, FROM_HERE);
   RunLoop();
   Mock::VerifyAndClearExpectations(syncer());
 
@@ -1338,9 +1321,8 @@
 
   StartSyncConfiguration();
 
-  const ModelTypeSet nudge_types(TYPED_URLS);
-  scheduler()->ScheduleLocalNudge(nudge_types, FROM_HERE);
-  scheduler()->ScheduleLocalNudge(nudge_types, FROM_HERE);
+  scheduler()->ScheduleLocalNudge(TYPED_URLS, FROM_HERE);
+  scheduler()->ScheduleLocalNudge(TYPED_URLS, FROM_HERE);
 
   const ModelTypeSet config_types(THEMES);
 
@@ -1445,7 +1427,6 @@
 TEST_F(SyncSchedulerImplTest, BackoffDropsJobs) {
   SyncShareTimes times;
   TimeDelta poll(TimeDelta::FromMilliseconds(10));
-  const ModelTypeSet types(THEMES);
   scheduler()->OnReceivedPollIntervalUpdate(poll);
   UseMockDelayProvider();
 
@@ -1459,7 +1440,8 @@
 
   // This nudge should fail and put us into backoff.  Thanks to our mock
   // GetDelay() setup above, this will be a long backoff.
-  scheduler()->ScheduleLocalNudge(types, FROM_HERE);
+  const ModelType type = THEMES;
+  scheduler()->ScheduleLocalNudge(type, FROM_HERE);
   RunLoop();
 
   // From this point forward, no SyncShare functions should be invoked.
@@ -1469,7 +1451,7 @@
   task_environment_.FastForwardBy(poll * 10);
 
   // Try (and fail) to schedule a nudge.
-  scheduler()->ScheduleLocalNudge(types, FROM_HERE);
+  scheduler()->ScheduleLocalNudge(type, FROM_HERE);
 
   Mock::VerifyAndClearExpectations(syncer());
   Mock::VerifyAndClearExpectations(delay());
@@ -1479,7 +1461,8 @@
   StartSyncConfiguration();
 
   CallbackCounter ready_counter;
-  ConfigurationParams params(sync_pb::SyncEnums::RECONFIGURATION, types,
+  ConfigurationParams params(sync_pb::SyncEnums::RECONFIGURATION,
+                             ModelTypeSet(type),
                              base::BindOnce(&CallbackCounter::Callback,
                                             base::Unretained(&ready_counter)));
   scheduler()->ScheduleConfiguration(std::move(params));
@@ -1522,7 +1505,7 @@
   StartSyncScheduler(base::Time());
 
   // Run again with a nudge.
-  scheduler()->ScheduleLocalNudge(ModelTypeSet(THEMES), FROM_HERE);
+  scheduler()->ScheduleLocalNudge(THEMES, FROM_HERE);
   RunLoop();
 
   ASSERT_EQ(kMinNumSamples, times.size());
@@ -1548,7 +1531,7 @@
   EXPECT_CALL(*syncer(), NormalSyncShare)
       .WillOnce(
           DoAll(Invoke(SimulateCommitFailed), RecordSyncShare(&times, false)));
-  scheduler()->ScheduleLocalNudge(ModelTypeSet(THEMES), FROM_HERE);
+  scheduler()->ScheduleLocalNudge(THEMES, FROM_HERE);
   RunLoop();
   Mock::VerifyAndClearExpectations(syncer());
   TimeTicks optimal_job_time = optimal_start;
@@ -1625,7 +1608,7 @@
       .WillOnce(DoAll(Invoke(SimulateNormalSuccess), Return(true)));
   StartSyncScheduler(base::Time());
 
-  scheduler()->ScheduleLocalNudge(ModelTypeSet(THEMES), FROM_HERE);
+  scheduler()->ScheduleLocalNudge(THEMES, FROM_HERE);
   // Should save the nudge for until after the server is reachable.
   base::RunLoop().RunUntilIdle();
 
@@ -1648,7 +1631,7 @@
       .WillOnce(DoAll(Invoke(SimulateConnectionFailure), Return(false)));
   StartSyncScheduler(base::Time());
 
-  scheduler()->ScheduleLocalNudge(ModelTypeSet(THEMES), FROM_HERE);
+  scheduler()->ScheduleLocalNudge(THEMES, FROM_HERE);
   // The nudge fails because of the connection failure.
   base::RunLoop().RunUntilIdle();
 
@@ -1672,7 +1655,7 @@
       .WillOnce(DoAll(Invoke(SimulateConnectionFailure), Return(false)))
       .WillOnce(DoAll(Invoke(SimulateNormalSuccess), Return(true)));
 
-  scheduler()->ScheduleLocalNudge(ModelTypeSet(THEMES), FROM_HERE);
+  scheduler()->ScheduleLocalNudge(THEMES, FROM_HERE);
   PumpLoop();  // To get PerformDelayedNudge called.
   PumpLoop();  // Run the nudge, that will fail and schedule a quick retry.
   ASSERT_TRUE(scheduler()->IsGlobalBackoff());
@@ -1702,7 +1685,7 @@
       .WillOnce(DoAll(Invoke(SimulateNormalSuccess), Return(true)))
       .WillOnce(DoAll(Invoke(SimulateNormalSuccess), QuitLoopNowAction(true)));
 
-  scheduler()->ScheduleLocalNudge(ModelTypeSet(THEMES), FROM_HERE);
+  scheduler()->ScheduleLocalNudge(THEMES, FROM_HERE);
 
   PumpLoop();  // To get PerformDelayedNudge called.
   PumpLoop();  // Run the nudge, that will fail and schedule a quick retry.
@@ -1714,7 +1697,7 @@
   PumpLoop();
   connection()->SetServerReachable();
   connection()->UpdateConnectionStatus();
-  scheduler()->ScheduleLocalNudge(ModelTypeSet(THEMES), FROM_HERE);
+  scheduler()->ScheduleLocalNudge(THEMES, FROM_HERE);
   base::RunLoop().RunUntilIdle();
 }
 
@@ -1832,7 +1815,7 @@
   TimeDelta delay1 = TimeDelta::FromMilliseconds(100);
   TimeDelta delay2 = TimeDelta::FromMilliseconds(200);
 
-  scheduler()->ScheduleLocalNudge(ModelTypeSet(THEMES), FROM_HERE);
+  scheduler()->ScheduleLocalNudge(THEMES, FROM_HERE);
   scheduler()->OnReceivedGuRetryDelay(delay1);
   EXPECT_EQ(delay1, GetRetryTimerDelay());
 
@@ -1859,26 +1842,26 @@
   TimeDelta poll(TimeDelta::FromDays(1));
   scheduler()->OnReceivedPollIntervalUpdate(poll);
 
-  const ModelTypeSet types(THEMES);
+  const ModelType type = THEMES;
 
   ::testing::InSequence seq;
   EXPECT_CALL(*syncer(), NormalSyncShare)
       .WillRepeatedly(
-          DoAll(WithArg<2>(SimulatePartialFailure(types)), Return(true)))
+          DoAll(WithArg<2>(SimulatePartialFailure(type)), Return(true)))
       .RetiresOnSaturation();
 
   StartSyncScheduler(base::Time());
-  scheduler()->ScheduleLocalNudge(types, FROM_HERE);
+  scheduler()->ScheduleLocalNudge(type, FROM_HERE);
   PumpLoop();  // To get PerformDelayedNudge called.
   PumpLoop();  // To get TrySyncCycleJob called
-  EXPECT_TRUE(GetBackedOffTypes().HasAll(types));
+  EXPECT_TRUE(GetBackedOffTypes().Has(type));
   EXPECT_FALSE(scheduler()->IsGlobalBackoff());
   EXPECT_FALSE(scheduler()->IsGlobalThrottle());
   TimeDelta first_blocking_time = GetTypeBlockingTime(THEMES);
 
   SetTypeBlockingMode(THEMES, WaitInterval::EXPONENTIAL_BACKOFF_RETRYING);
   // This won't cause a sync cycle because the types are backed off.
-  scheduler()->ScheduleLocalNudge(types, FROM_HERE);
+  scheduler()->ScheduleLocalNudge(type, FROM_HERE);
   PumpLoop();
   PumpLoop();
   TimeDelta second_blocking_time = GetTypeBlockingTime(THEMES);
@@ -1904,19 +1887,19 @@
   TimeDelta poll(TimeDelta::FromDays(1));
   scheduler()->OnReceivedPollIntervalUpdate(poll);
 
-  const ModelTypeSet types(THEMES);
+  const ModelType type = THEMES;
 
   // Set backoff datatype.
   ::testing::InSequence seq;
   EXPECT_CALL(*syncer(), NormalSyncShare)
-      .WillOnce(DoAll(WithArg<2>(SimulatePartialFailure(types)), Return(true)))
+      .WillOnce(DoAll(WithArg<2>(SimulatePartialFailure(type)), Return(true)))
       .RetiresOnSaturation();
 
   StartSyncScheduler(base::Time());
-  scheduler()->ScheduleLocalNudge(types, FROM_HERE);
+  scheduler()->ScheduleLocalNudge(type, FROM_HERE);
   PumpLoop();  // To get PerformDelayedNudge called.
   PumpLoop();  // To get TrySyncCycleJob called
-  EXPECT_TRUE(GetBackedOffTypes().HasAll(types));
+  EXPECT_TRUE(GetBackedOffTypes().Has(type));
   EXPECT_TRUE(BlockTimerIsRunning());
   EXPECT_FALSE(scheduler()->IsGlobalBackoff());
   EXPECT_FALSE(scheduler()->IsGlobalThrottle());
@@ -1928,13 +1911,12 @@
       .RetiresOnSaturation();
 
   // Do a successful Sync.
-  const ModelTypeSet unbacked_off_types(TYPED_URLS);
-  scheduler()->ScheduleLocalNudge(unbacked_off_types, FROM_HERE);
+  scheduler()->ScheduleLocalNudge(TYPED_URLS, FROM_HERE);
   PumpLoop();  // TO get PerformDelayedNudge called.
   PumpLoop();  // To get TrySyncCycleJob called.
 
   // Timer is still running for backoff datatype after Sync success.
-  EXPECT_TRUE(GetBackedOffTypes().HasAll(types));
+  EXPECT_TRUE(GetBackedOffTypes().Has(type));
   EXPECT_TRUE(BlockTimerIsRunning());
   EXPECT_FALSE(scheduler()->IsGlobalBackoff());
   EXPECT_FALSE(scheduler()->IsGlobalThrottle());
@@ -1954,38 +1936,38 @@
   scheduler()->OnReceivedPollIntervalUpdate(poll);
 
   // Set a backoff datatype.
-  const ModelTypeSet themes_types(THEMES);
+  const ModelType backed_off_type = THEMES;
   ::testing::InSequence seq;
   EXPECT_CALL(*syncer(), NormalSyncShare)
-      .WillOnce(
-          DoAll(WithArg<2>(SimulatePartialFailure(themes_types)), Return(true)))
+      .WillOnce(DoAll(WithArg<2>(SimulatePartialFailure(backed_off_type)),
+                      Return(true)))
       .RetiresOnSaturation();
 
   StartSyncScheduler(base::Time());
-  scheduler()->ScheduleLocalNudge(themes_types, FROM_HERE);
+  scheduler()->ScheduleLocalNudge(backed_off_type, FROM_HERE);
   PumpLoop();  // To get PerformDelayedNudge called.
   PumpLoop();  // To get TrySyncCycleJob called
-  EXPECT_TRUE(GetBackedOffTypes().HasAll(themes_types));
+  EXPECT_TRUE(GetBackedOffTypes().Has(backed_off_type));
   EXPECT_TRUE(BlockTimerIsRunning());
   EXPECT_FALSE(scheduler()->IsGlobalBackoff());
   EXPECT_FALSE(scheduler()->IsGlobalThrottle());
 
   // Set anther backoff datatype.
-  const ModelTypeSet typed_urls_types(TYPED_URLS);
+  const ModelType backed_off_type2 = TYPED_URLS;
   EXPECT_CALL(*syncer(), NormalSyncShare)
-      .WillOnce(DoAll(WithArg<2>(SimulatePartialFailure(typed_urls_types)),
+      .WillOnce(DoAll(WithArg<2>(SimulatePartialFailure(backed_off_type2)),
                       Return(true)))
       .RetiresOnSaturation();
   EXPECT_CALL(*delay(), GetDelay)
       .WillOnce(Return(default_delay()))
       .RetiresOnSaturation();
 
-  scheduler()->ScheduleLocalNudge(typed_urls_types, FROM_HERE);
+  scheduler()->ScheduleLocalNudge(backed_off_type2, FROM_HERE);
   PumpLoop();  // TO get PerformDelayedNudge called.
   PumpLoop();  // To get TrySyncCycleJob called.
 
-  EXPECT_TRUE(GetBackedOffTypes().HasAll(themes_types));
-  EXPECT_TRUE(GetBackedOffTypes().HasAll(typed_urls_types));
+  EXPECT_TRUE(GetBackedOffTypes().Has(backed_off_type));
+  EXPECT_TRUE(GetBackedOffTypes().Has(backed_off_type2));
   EXPECT_TRUE(BlockTimerIsRunning());
   EXPECT_FALSE(scheduler()->IsGlobalBackoff());
   EXPECT_FALSE(scheduler()->IsGlobalThrottle());
@@ -2001,8 +1983,8 @@
   PumpLoop();  // To get TrySyncCycleJob called.
 
   // Timer is still scheduled for another backoff datatype.
-  EXPECT_TRUE(GetBackedOffTypes().HasAll(themes_types));
-  EXPECT_FALSE(GetBackedOffTypes().HasAll(typed_urls_types));
+  EXPECT_TRUE(GetBackedOffTypes().Has(backed_off_type));
+  EXPECT_FALSE(GetBackedOffTypes().Has(backed_off_type2));
   EXPECT_TRUE(BlockTimerIsRunning());
   EXPECT_FALSE(scheduler()->IsGlobalBackoff());
   EXPECT_FALSE(scheduler()->IsGlobalThrottle());
@@ -2019,14 +2001,14 @@
   scheduler()->OnReceivedPollIntervalUpdate(poll);
 
   StartSyncScheduler(base::Time());
-  scheduler()->ScheduleLocalNudge({THEMES}, FROM_HERE);
+  scheduler()->ScheduleLocalNudge(THEMES, FROM_HERE);
   PumpLoop();  // To get PerformDelayedNudge called.
   EXPECT_FALSE(BlockTimerIsRunning());
   EXPECT_FALSE(scheduler()->IsGlobalBackoff());
 
   // This is the tricky piece. We have a gap while the sync job is bouncing to
   // get onto the |pending_wakeup_timer_|, should be scheduled with no delay.
-  scheduler()->ScheduleLocalNudge({TYPED_URLS}, FROM_HERE);
+  scheduler()->ScheduleLocalNudge(TYPED_URLS, FROM_HERE);
   EXPECT_TRUE(BlockTimerIsRunning());
   EXPECT_EQ(TimeDelta(), GetPendingWakeupTimerDelay());
   EXPECT_FALSE(scheduler()->IsGlobalBackoff());
diff --git a/components/sync/test/engine/fake_sync_scheduler.cc b/components/sync/test/engine/fake_sync_scheduler.cc
index fc5ca2a1..6bcbf7f2 100644
--- a/components/sync/test/engine/fake_sync_scheduler.cc
+++ b/components/sync/test/engine/fake_sync_scheduler.cc
@@ -8,16 +8,16 @@
 
 namespace syncer {
 
-FakeSyncScheduler::FakeSyncScheduler() {}
+FakeSyncScheduler::FakeSyncScheduler() = default;
 
-FakeSyncScheduler::~FakeSyncScheduler() {}
+FakeSyncScheduler::~FakeSyncScheduler() = default;
 
 void FakeSyncScheduler::Start(Mode mode, base::Time last_poll_time) {}
 
 void FakeSyncScheduler::Stop() {}
 
 void FakeSyncScheduler::ScheduleLocalNudge(
-    ModelTypeSet types,
+    ModelType type,
     const base::Location& nudge_location) {}
 
 void FakeSyncScheduler::ScheduleLocalRefreshRequest(
diff --git a/components/sync/test/engine/fake_sync_scheduler.h b/components/sync/test/engine/fake_sync_scheduler.h
index c923ebd..d9fbcf2 100644
--- a/components/sync/test/engine/fake_sync_scheduler.h
+++ b/components/sync/test/engine/fake_sync_scheduler.h
@@ -22,7 +22,7 @@
 
   void Start(Mode mode, base::Time last_poll_time) override;
   void Stop() override;
-  void ScheduleLocalNudge(ModelTypeSet types,
+  void ScheduleLocalNudge(ModelType type,
                           const base::Location& nudge_location) override;
   void ScheduleLocalRefreshRequest(
       ModelTypeSet types,
diff --git a/components/system_media_controls/mac/now_playing_info_center_delegate.h b/components/system_media_controls/mac/now_playing_info_center_delegate.h
index ca9bee9..bb0dfbe 100644
--- a/components/system_media_controls/mac/now_playing_info_center_delegate.h
+++ b/components/system_media_controls/mac/now_playing_info_center_delegate.h
@@ -8,6 +8,7 @@
 #include "base/mac/scoped_nsobject.h"
 #include "base/timer/timer.h"
 #include "components/system_media_controls/system_media_controls.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 @class NowPlayingInfoCenterDelegateCocoa;
 
diff --git a/components/translate/core/browser/translate_metrics_logger_impl.h b/components/translate/core/browser/translate_metrics_logger_impl.h
index f4b1a79..189c0ed 100644
--- a/components/translate/core/browser/translate_metrics_logger_impl.h
+++ b/components/translate/core/browser/translate_metrics_logger_impl.h
@@ -10,6 +10,7 @@
 
 #include "base/memory/weak_ptr.h"
 #include "components/translate/core/browser/translate_metrics_logger.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class TickClock;
diff --git a/components/user_manager/known_user.h b/components/user_manager/known_user.h
index 16701040..22394e38 100644
--- a/components/user_manager/known_user.h
+++ b/components/user_manager/known_user.h
@@ -11,6 +11,7 @@
 #include "base/gtest_prod_util.h"
 #include "base/time/time.h"
 #include "components/user_manager/user_manager_export.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class AccountId;
 enum class AccountType;
diff --git a/components/variations/variations_crash_keys.cc b/components/variations/variations_crash_keys.cc
index e0df470..3794649 100644
--- a/components/variations/variations_crash_keys.cc
+++ b/components/variations/variations_crash_keys.cc
@@ -18,6 +18,7 @@
 #include "components/variations/synthetic_trials.h"
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
+#include "base/task/thread_pool.h"
 #include "components/variations/variations_crash_keys_chromeos.h"
 #endif
 
@@ -78,6 +79,12 @@
   // observer calls that happen on a different thread.
   scoped_refptr<base::SequencedTaskRunner> ui_thread_task_runner_;
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+  // Task runner corresponding to a background thread, used for tasks that may
+  // block.
+  scoped_refptr<base::SequencedTaskRunner> background_thread_task_runner_;
+#endif  // IS_CHROMEOS_ASH
+
   // A serialized string containing the variations state.
   std::string variations_string_;
 
@@ -101,6 +108,11 @@
   for (const auto& entry : active_groups) {
     AppendFieldTrial(entry.trial_name, entry.group_name);
   }
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+  background_thread_task_runner_ = base::ThreadPool::CreateSequencedTaskRunner(
+      {base::TaskPriority::BEST_EFFORT, base::MayBlock()});
+#endif  // IS_CHROMEOS_ASH
+
   UpdateCrashKeys();
 
   ui_thread_task_runner_ = base::SequencedTaskRunnerHandle::Get();
@@ -176,7 +188,7 @@
   g_variations_crash_key.Set(info.experiment_list);
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-  ReportVariationsToChromeOs(info);
+  ReportVariationsToChromeOs(background_thread_task_runner_, info);
 #endif  // IS_CHROMEOS_ASH
 }
 
diff --git a/components/variations/variations_crash_keys_chromeos.cc b/components/variations/variations_crash_keys_chromeos.cc
index af60025a..d1633e6 100644
--- a/components/variations/variations_crash_keys_chromeos.cc
+++ b/components/variations/variations_crash_keys_chromeos.cc
@@ -40,11 +40,10 @@
 
 }  // namespace
 
-void ReportVariationsToChromeOs(ExperimentListInfo info) {
+void ReportVariationsToChromeOs(scoped_refptr<base::SequencedTaskRunner> runner,
+                                ExperimentListInfo info) {
   // On a thread in the background, write variants to a file.
-  base::ThreadPool::PostTask(
-      FROM_HERE, {base::TaskPriority::BEST_EFFORT, base::MayBlock()},
-      base::BindOnce(&WriteVariationsToFile, info));
+  runner->PostTask(FROM_HERE, base::BindOnce(&WriteVariationsToFile, info));
 }
 
 }  // namespace variations
diff --git a/components/variations/variations_crash_keys_chromeos.h b/components/variations/variations_crash_keys_chromeos.h
index d8f0fbf..3453776 100644
--- a/components/variations/variations_crash_keys_chromeos.h
+++ b/components/variations/variations_crash_keys_chromeos.h
@@ -5,6 +5,7 @@
 #ifndef COMPONENTS_VARIATIONS_VARIATIONS_CRASH_KEYS_CHROMEOS_H_
 #define COMPONENTS_VARIATIONS_VARIATIONS_CRASH_KEYS_CHROMEOS_H_
 
+#include "base/sequenced_task_runner.h"
 #include "components/variations/variations_crash_keys.h"
 
 namespace variations {
@@ -12,7 +13,8 @@
 // On a separate thread, report the provided crash keys to Chrome OS using a
 // .variant-list.txt in the user's home directory, or /home/chronos if no user
 // is logged in.
-void ReportVariationsToChromeOs(ExperimentListInfo info);
+void ReportVariationsToChromeOs(scoped_refptr<base::SequencedTaskRunner> runner,
+                                ExperimentListInfo info);
 
 }  // namespace variations
 
diff --git a/components/viz/common/gpu/vulkan_context_provider.h b/components/viz/common/gpu/vulkan_context_provider.h
index 37c1e40e..dfe85d6 100644
--- a/components/viz/common/gpu/vulkan_context_provider.h
+++ b/components/viz/common/gpu/vulkan_context_provider.h
@@ -11,6 +11,7 @@
 #include "base/memory/ref_counted.h"
 #include "components/viz/common/viz_vulkan_context_provider_export.h"
 #include "gpu/vulkan/buildflags.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(ENABLE_VULKAN)
 #include <vulkan/vulkan.h>
diff --git a/components/viz/common/quads/frame_deadline.h b/components/viz/common/quads/frame_deadline.h
index 7d981c81..b32aa0c 100644
--- a/components/viz/common/quads/frame_deadline.h
+++ b/components/viz/common/quads/frame_deadline.h
@@ -5,10 +5,12 @@
 #ifndef COMPONENTS_VIZ_COMMON_QUADS_FRAME_DEADLINE_H_
 #define COMPONENTS_VIZ_COMMON_QUADS_FRAME_DEADLINE_H_
 
-#include "components/viz/common/viz_common_export.h"
+#include <string>
 
 #include "base/time/time.h"
 #include "components/viz/common/frame_sinks/begin_frame_args.h"
+#include "components/viz/common/viz_common_export.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace viz {
 
diff --git a/content/browser/accessibility/browser_accessibility_com_win.cc b/content/browser/accessibility/browser_accessibility_com_win.cc
index 8bbe6c2..218c5a9c 100644
--- a/content/browser/accessibility/browser_accessibility_com_win.cc
+++ b/content/browser/accessibility/browser_accessibility_com_win.cc
@@ -1451,7 +1451,7 @@
   old_win_attributes_.swap(win_attributes_);
 
   old_hypertext_ = hypertext_;
-  hypertext_ = ui::AXHypertext();
+  hypertext_ = ui::AXLegacyHypertext();
 
   win_attributes_ = std::make_unique<WinAttributes>();
 
@@ -1524,7 +1524,7 @@
   }
 
   old_win_attributes_.reset(nullptr);
-  old_hypertext_ = ui::AXHypertext();
+  old_hypertext_ = ui::AXLegacyHypertext();
 }
 
 BrowserAccessibilityManager* BrowserAccessibilityComWin::Manager() const {
diff --git a/content/browser/background_fetch/background_fetch_event_dispatcher.cc b/content/browser/background_fetch/background_fetch_event_dispatcher.cc
index 12f24dd..db489c51c 100644
--- a/content/browser/background_fetch/background_fetch_event_dispatcher.cc
+++ b/content/browser/background_fetch/background_fetch_event_dispatcher.cc
@@ -158,9 +158,9 @@
   LoadServiceWorkerRegistrationForDispatch(
       registration_id, ServiceWorkerMetrics::EventType::BACKGROUND_FETCH_ABORT,
       std::move(finished_closure),
-      base::AdaptCallbackForRepeating(base::BindOnce(
+      base::BindOnce(
           &BackgroundFetchEventDispatcher::DoDispatchBackgroundFetchAbortEvent,
-          std::move(registration))));
+          std::move(registration)));
 }
 
 void BackgroundFetchEventDispatcher::DoDispatchBackgroundFetchAbortEvent(
@@ -189,9 +189,9 @@
   LoadServiceWorkerRegistrationForDispatch(
       registration_id, ServiceWorkerMetrics::EventType::BACKGROUND_FETCH_CLICK,
       std::move(finished_closure),
-      base::AdaptCallbackForRepeating(base::BindOnce(
+      base::BindOnce(
           &BackgroundFetchEventDispatcher::DoDispatchBackgroundFetchClickEvent,
-          std::move(registration))));
+          std::move(registration)));
 }
 
 void BackgroundFetchEventDispatcher::DoDispatchBackgroundFetchClickEvent(
@@ -218,9 +218,9 @@
   LoadServiceWorkerRegistrationForDispatch(
       registration_id, ServiceWorkerMetrics::EventType::BACKGROUND_FETCH_FAIL,
       std::move(finished_closure),
-      base::AdaptCallbackForRepeating(base::BindOnce(
+      base::BindOnce(
           &BackgroundFetchEventDispatcher::DoDispatchBackgroundFetchFailEvent,
-          std::move(registration))));
+          std::move(registration)));
 }
 
 void BackgroundFetchEventDispatcher::DoDispatchBackgroundFetchFailEvent(
@@ -249,10 +249,9 @@
       registration_id,
       ServiceWorkerMetrics::EventType::BACKGROUND_FETCH_SUCCESS,
       std::move(finished_closure),
-      base::AdaptCallbackForRepeating(
-          base::BindOnce(&BackgroundFetchEventDispatcher::
-                             DoDispatchBackgroundFetchSuccessEvent,
-                         std::move(registration))));
+      base::BindOnce(&BackgroundFetchEventDispatcher::
+                         DoDispatchBackgroundFetchSuccessEvent,
+                     std::move(registration)));
 }
 
 void BackgroundFetchEventDispatcher::DoDispatchBackgroundFetchSuccessEvent(
diff --git a/content/browser/conversions/conversion_host.cc b/content/browser/conversions/conversion_host.cc
index 957feeb..1d21a8c 100644
--- a/content/browser/conversions/conversion_host.cc
+++ b/content/browser/conversions/conversion_host.cc
@@ -203,7 +203,6 @@
       !network::IsOriginPotentiallyTrustworthy(reporting_origin) ||
       !network::IsOriginPotentiallyTrustworthy(
           impression.conversion_destination)) {
-    // TODO (1049654): This should log a console error when it occurs.
     return;
   }
 
diff --git a/content/browser/media/cdm_registry_impl_unittest.cc b/content/browser/media/cdm_registry_impl_unittest.cc
index d534d5a6..5dd62b9 100644
--- a/content/browser/media/cdm_registry_impl_unittest.cc
+++ b/content/browser/media/cdm_registry_impl_unittest.cc
@@ -19,12 +19,14 @@
 #include "content/public/common/cdm_info.h"
 #include "media/base/video_codecs.h"
 #include "media/cdm/cdm_capability.h"
+#include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace content {
 
 namespace {
 
+using AudioCodec = media::AudioCodec;
 using VideoCodec = media::VideoCodec;
 using EncryptionScheme = media::EncryptionScheme;
 using CdmSessionType = media::CdmSessionType;
@@ -44,11 +46,14 @@
   return a == Container(b);
 }
 
-#define EXPECT_STL_EQ(a, ...)                 \
-  do {                                        \
-    EXPECT_TRUE(StlEquals(a, {__VA_ARGS__})); \
+#define EXPECT_STL_EQ(container, ...)                            \
+  do {                                                           \
+    EXPECT_THAT(container, ::testing::ElementsAre(__VA_ARGS__)); \
   } while (false)
 
+#define EXPECT_AUDIO_CODECS(...) \
+  EXPECT_STL_EQ(cdm.capability->audio_codecs, __VA_ARGS__)
+
 #define EXPECT_VIDEO_CODECS(...) \
   EXPECT_STL_EQ(cdm.capability->video_codecs, __VA_ARGS__)
 
@@ -70,7 +75,8 @@
  protected:
   media::CdmCapability GetTestCdmCapability() {
     return media::CdmCapability(
-        {media::kCodecVP8, media::kCodecVP9}, {EncryptionScheme::kCenc},
+        {media::kCodecVorbis}, {media::kCodecVP8, media::kCodecVP9},
+        {EncryptionScheme::kCenc},
         {CdmSessionType::kTemporary, CdmSessionType::kPersistentLicense});
   }
 
@@ -128,6 +134,7 @@
   EXPECT_EQ(kVersion1, cdm.version.GetString());
   EXPECT_EQ(kTestPath, cdm.path.MaybeAsASCII());
   EXPECT_EQ(kTestFileSystemId, cdm.file_system_id);
+  EXPECT_AUDIO_CODECS(AudioCodec::kCodecVorbis);
   EXPECT_VIDEO_CODECS(VideoCodec::kCodecVP8, VideoCodec::kCodecVP9);
   EXPECT_ENCRYPTION_SCHEMES(EncryptionScheme::kCenc);
   EXPECT_SESSION_TYPES(CdmSessionType::kTemporary,
diff --git a/content/browser/media/key_system_support_impl.cc b/content/browser/media/key_system_support_impl.cc
index 29c8b8f..e627687 100644
--- a/content/browser/media/key_system_support_impl.cc
+++ b/content/browser/media/key_system_support_impl.cc
@@ -58,6 +58,7 @@
       base::SplitStringPiece(overridden_codecs_string, ",",
                              base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
 
+  std::vector<media::AudioCodec> audio_codecs;
   std::vector<media::VideoCodec> video_codecs;
   for (const auto& codec : overridden_codecs) {
     if (codec == "vp8")
@@ -66,6 +67,8 @@
       video_codecs.push_back(media::VideoCodec::kCodecVP9);
     else if (codec == "avc1")
       video_codecs.push_back(media::VideoCodec::kCodecH264);
+    else if (codec == "vorbis")
+      audio_codecs.push_back(media::AudioCodec::kCodecVorbis);
     else
       DVLOG(1) << "Unsupported codec specified on command line: " << codec;
   }
@@ -78,7 +81,7 @@
   // Overridden codecs assume CENC and temporary session support.
   // The EncryptedMediaSupportedTypesWidevineHwSecureTest tests depend
   // on 'cbcs' not being supported.
-  return media::CdmCapability(std::move(video_codecs),
+  return media::CdmCapability(std::move(audio_codecs), std::move(video_codecs),
                               {media::EncryptionScheme::kCenc},
                               {media::CdmSessionType::kTemporary});
 }
diff --git a/content/browser/media/key_system_support_impl_unittest.cc b/content/browser/media/key_system_support_impl_unittest.cc
index 77dd3db..3b8fded 100644
--- a/content/browser/media/key_system_support_impl_unittest.cc
+++ b/content/browser/media/key_system_support_impl_unittest.cc
@@ -31,6 +31,7 @@
 
 namespace {
 
+using AudioCodec = media::AudioCodec;
 using VideoCodec = media::VideoCodec;
 using EncryptionScheme = media::EncryptionScheme;
 using CdmSessionType = media::CdmSessionType;
@@ -55,6 +56,9 @@
     EXPECT_THAT(container, ::testing::ElementsAre(__VA_ARGS__)); \
   } while (false)
 
+#define EXPECT_AUDIO_CODECS(...) \
+  EXPECT_STL_EQ(capability_->sw_secure_capability->audio_codecs, __VA_ARGS__)
+
 #define EXPECT_VIDEO_CODECS(...) \
   EXPECT_STL_EQ(capability_->sw_secure_capability->video_codecs, __VA_ARGS__)
 
@@ -65,6 +69,9 @@
 #define EXPECT_SESSION_TYPES(...) \
   EXPECT_STL_EQ(capability_->sw_secure_capability->session_types, __VA_ARGS__)
 
+#define EXPECT_HW_SECURE_AUDIO_CODECS(...) \
+  EXPECT_STL_EQ(capability_->hw_secure_capability->audio_codecs, __VA_ARGS__)
+
 #define EXPECT_HW_SECURE_VIDEO_CODECS(...) \
   EXPECT_STL_EQ(capability_->hw_secure_capability->video_codecs, __VA_ARGS__)
 
@@ -74,6 +81,7 @@
 
 #define EXPECT_HW_SECURE_SESSION_TYPES(...) \
   EXPECT_STL_EQ(capability_->hw_secure_capability->session_types, __VA_ARGS__)
+
 }  // namespace
 
 class KeySystemSupportImplTest : public testing::Test {
@@ -95,6 +103,7 @@
 
   media::CdmCapability TestCdmCapability() {
     return media::CdmCapability(
+        {AudioCodec::kCodecVorbis},
         {VideoCodec::kCodecVP8, VideoCodec::kCodecVP9},
         {EncryptionScheme::kCenc, EncryptionScheme::kCbcs},
         {CdmSessionType::kTemporary, CdmSessionType::kPersistentLicense});
@@ -145,6 +154,7 @@
   EXPECT_TRUE(IsSupported("KeySystem"));
   EXPECT_TRUE(capability_->sw_secure_capability);
   EXPECT_FALSE(capability_->hw_secure_capability);
+  EXPECT_AUDIO_CODECS(AudioCodec::kCodecVorbis);
   EXPECT_VIDEO_CODECS(VideoCodec::kCodecVP8, VideoCodec::kCodecVP9);
   EXPECT_ENCRYPTION_SCHEMES(EncryptionScheme::kCenc, EncryptionScheme::kCbcs);
   EXPECT_SESSION_TYPES(CdmSessionType::kTemporary,
@@ -166,6 +176,7 @@
   EXPECT_TRUE(IsSupported("KeySystem"));
   EXPECT_FALSE(capability_->sw_secure_capability);
   EXPECT_TRUE(capability_->hw_secure_capability);
+  EXPECT_HW_SECURE_AUDIO_CODECS(AudioCodec::kCodecVorbis);
   EXPECT_HW_SECURE_VIDEO_CODECS(VideoCodec::kCodecVP8, VideoCodec::kCodecVP9);
   EXPECT_HW_SECURE_ENCRYPTION_SCHEMES(EncryptionScheme::kCenc,
                                       EncryptionScheme::kCbcs);
diff --git a/content/browser/prerender/prerender_browsertest.cc b/content/browser/prerender/prerender_browsertest.cc
index 55dd251..b1ac022 100644
--- a/content/browser/prerender/prerender_browsertest.cc
+++ b/content/browser/prerender/prerender_browsertest.cc
@@ -18,23 +18,18 @@
 #include "base/test/scoped_feature_list.h"
 #include "base/thread_annotations.h"
 #include "build/build_config.h"
-#include "components/services/storage/public/mojom/storage_service.mojom.h"
-#include "components/services/storage/public/mojom/test_api.test-mojom.h"
 #include "content/browser/file_system_access/file_system_chooser_test_helpers.h"
 #include "content/browser/prerender/prerender_host.h"
 #include "content/browser/prerender/prerender_host_registry.h"
 #include "content/browser/prerender/prerender_metrics.h"
-#include "content/browser/renderer_host/back_forward_cache_impl.h"
 #include "content/browser/renderer_host/frame_tree_node.h"
 #include "content/browser/renderer_host/input/synthetic_tap_gesture.h"
 #include "content/browser/renderer_host/render_frame_host_impl.h"
 #include "content/browser/renderer_host/render_view_host_impl.h"
-#include "content/browser/storage_partition_impl.h"
 #include "content/browser/web_contents/web_contents_impl.h"
 #include "content/common/content_navigation_policy.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
-#include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/render_document_host_user_data.h"
 #include "content/public/common/content_client.h"
 #include "content/public/common/content_features.h"
@@ -243,13 +238,12 @@
     return prerender_helper_.get();
   }
 
-  void SetUpCommandLine(base::CommandLine* command_line) override {
+ private:
+  void SetUpCommandLine(base::CommandLine* command_line) final {
     // Useful for testing CSP:prefetch-src
     base::CommandLine::ForCurrentProcess()->AppendSwitch(
         switches::kEnableExperimentalWebPlatformFeatures);
   }
-
- private:
   net::test_server::EmbeddedTestServer ssl_server_{
       net::test_server::EmbeddedTestServer::TYPE_HTTPS};
 
@@ -1788,280 +1782,6 @@
   EXPECT_EQ(GetRequestCount(kImageUrl), 1);
 }
 
-IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
-                       SessionStorageAfterBackNavigation_NoProcessReuse) {
-  // When BackForwardCache feature is enabled, this test doesn't work, because
-  // this test is checking the behavior of a new renderer process which is
-  // created for a back forward navigation from a prerendered page.
-  if (IsBackForwardCacheEnabled())
-    return;
-
-  const GURL kInitialUrl = GetUrl("/prerender/session_storage.html");
-  const GURL kPrerenderingUrl =
-      GetUrl("/prerender/session_storage.html?prerendering=");
-
-  // Navigate to an initial page.
-  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
-
-  std::unique_ptr<RenderProcessHostWatcher> process_host_watcher =
-      std::make_unique<RenderProcessHostWatcher>(
-          current_frame_host()->GetProcess(),
-          RenderProcessHostWatcher::WATCH_FOR_HOST_DESTRUCTION);
-
-  AddPrerender(kPrerenderingUrl);
-  NavigatePrimaryPage(kPrerenderingUrl);
-
-  EXPECT_EQ("initial", EvalJs(current_frame_host(),
-                              "window.sessionKeysInPrerenderingchange")
-                           .ExtractString());
-  EXPECT_EQ(
-      "activated, initial",
-      EvalJs(current_frame_host(), "getSessionStorageKeys()").ExtractString());
-
-  // Make sure that the initial renderer process is destroyed. So that the
-  // initial renderer process will not be reused after the back forward
-  // navigation below.
-  process_host_watcher->Wait();
-
-  // Navigate back to the initial page.
-  content::TestNavigationObserver observer(shell()->web_contents());
-  shell()->GoBackOrForward(-1);
-  observer.Wait();
-  EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), kInitialUrl);
-
-  EXPECT_EQ(
-      "activated, initial",
-      EvalJs(current_frame_host(), "getSessionStorageKeys()").ExtractString());
-}
-
-IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
-                       SessionStorageAfterBackNavigation_KeepInitialProcess) {
-  const GURL kInitialUrl = GetUrl("/prerender/session_storage.html");
-  const GURL kPrerenderingUrl =
-      GetUrl("/prerender/session_storage.html?prerendering=");
-
-  // Navigate to an initial page.
-  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
-
-  RenderProcessHostImpl* initial_process_host =
-      static_cast<RenderProcessHostImpl*>(current_frame_host()->GetProcess());
-  // Increment the keep alive ref count of the renderer process to keep it alive
-  // so it is reused on the back navigation below. The test checks that the
-  // session storage state changed in the activated page is correctly propagated
-  // after a back navigation that uses an existing renderer process. (Note: This
-  // is not working correctly now.)
-  initial_process_host->IncrementKeepAliveRefCount();
-
-  AddPrerender(kPrerenderingUrl);
-  NavigatePrimaryPage(kPrerenderingUrl);
-
-  EXPECT_EQ("initial", EvalJs(current_frame_host(),
-                              "window.sessionKeysInPrerenderingchange")
-                           .ExtractString());
-  EXPECT_EQ(
-      "activated, initial",
-      EvalJs(current_frame_host(), "getSessionStorageKeys()").ExtractString());
-
-  // Navigate back to the initial page.
-  content::TestNavigationObserver observer(shell()->web_contents());
-  shell()->GoBackOrForward(-1);
-  observer.Wait();
-  EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), kInitialUrl);
-
-  // There is a known issue that when the initial renderer process is reused
-  // after the back navigation, the session storage state changed in the
-  // activated is not correctly propagated to the initial renderer process.
-  // TODO(crbug.com/1197383): Fix this issue.
-  EXPECT_EQ(
-      // This should be "activated, initial".
-      "initial",
-      EvalJs(current_frame_host(), "getSessionStorageKeys()").ExtractString());
-}
-
-class PrerenderSingleProcessBrowserTest : public PrerenderBrowserTest {
- public:
-  PrerenderSingleProcessBrowserTest() = default;
-
-  void SetUpCommandLine(base::CommandLine* cmd_line) override {
-    PrerenderBrowserTest::SetUpCommandLine(cmd_line);
-    cmd_line->AppendSwitch("single-process");
-  }
-};
-
-IN_PROC_BROWSER_TEST_F(PrerenderSingleProcessBrowserTest,
-                       SessionStorageAfterBackNavigation) {
-  const GURL kInitialUrl = GetUrl("/prerender/session_storage.html");
-  const GURL kPrerenderingUrl =
-      GetUrl("/prerender/session_storage.html?prerendering=");
-
-  // Navigate to an initial page.
-  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
-
-  AddPrerender(kPrerenderingUrl);
-  NavigatePrimaryPage(kPrerenderingUrl);
-
-  EXPECT_EQ("initial", EvalJs(current_frame_host(),
-                              "window.sessionKeysInPrerenderingchange")
-                           .ExtractString());
-  EXPECT_EQ(
-      "activated, initial",
-      EvalJs(current_frame_host(), "getSessionStorageKeys()").ExtractString());
-
-  // Navigate back to the initial page.
-  content::TestNavigationObserver observer(shell()->web_contents());
-  shell()->GoBackOrForward(-1);
-  observer.Wait();
-  EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), kInitialUrl);
-
-  EXPECT_EQ(
-      "activated, initial",
-      EvalJs(current_frame_host(), "getSessionStorageKeys()").ExtractString());
-}
-
-class PrerenderBackForwardCacheBrowserTest : public PrerenderBrowserTest {
- public:
-  PrerenderBackForwardCacheBrowserTest() {
-    feature_list_.InitWithFeaturesAndParameters(
-        {{features::kBackForwardCache, {{"enable_same_site", "true"}}},
-         {kBackForwardCacheNoTimeEviction, {}}},
-        // Allow BackForwardCache for all devices regardless of their memory.
-        {features::kBackForwardCacheMemoryControls});
-  }
-
- private:
-  base::test::ScopedFeatureList feature_list_;
-};
-
-IN_PROC_BROWSER_TEST_F(PrerenderBackForwardCacheBrowserTest,
-                       SessionStorageAfterBackNavigation) {
-  const GURL kInitialUrl = GetUrl("/prerender/session_storage.html");
-  const GURL kPrerenderingUrl =
-      GetUrl("/prerender/session_storage.html?prerendering=");
-
-  // Navigate to an initial page.
-  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
-
-  RenderFrameDeletedObserver deleted_observer(
-      shell()->web_contents()->GetMainFrame());
-
-  AddPrerender(kPrerenderingUrl);
-  NavigatePrimaryPage(kPrerenderingUrl);
-
-  EXPECT_EQ("initial", EvalJs(current_frame_host(),
-                              "window.sessionKeysInPrerenderingchange")
-                           .ExtractString());
-  EXPECT_EQ(
-      "activated, initial",
-      EvalJs(current_frame_host(), "getSessionStorageKeys()").ExtractString());
-
-  // Navigate back to the initial page.
-  shell()->GoBackOrForward(-1);
-  WaitForLoadStop(shell()->web_contents());
-
-  // Expect the navigation to be served from the back-forward cache to verify
-  // the test is testing what is intended.
-  ASSERT_EQ(shell()->web_contents()->GetMainFrame(),
-            deleted_observer.render_frame_host());
-
-  // There is a known issue that when the initial renderer process is reused
-  // after the back navigation, the session storage state changed in the
-  // activated is not correctly propagated to the initial renderer process.
-  // TODO(crbug.com/1197383): Fix this issue.
-  EXPECT_EQ(
-      // This should be "activated, initial".
-      "initial",
-      EvalJs(current_frame_host(), "getSessionStorageKeys()").ExtractString());
-}
-
-#if !defined(OS_ANDROID)
-// StorageServiceOutOfProcess is not implemented on Android.
-
-class PrerenderRestartStorageServiceBrowserTest : public PrerenderBrowserTest {
- public:
-  PrerenderRestartStorageServiceBrowserTest() {
-    // These tests only make sense when the service is running
-    // out-of-process.
-    feature_list_.InitAndEnableFeature(features::kStorageServiceOutOfProcess);
-  }
-
- protected:
-  void CrashStorageServiceAndWaitForRestart() {
-    mojo::Remote<storage::mojom::StorageService>& service =
-        StoragePartitionImpl::GetStorageServiceForTesting();
-    base::RunLoop loop;
-    service.set_disconnect_handler(base::BindLambdaForTesting([&] {
-      loop.Quit();
-      service.reset();
-    }));
-    mojo::Remote<storage::mojom::TestApi> test_api;
-    StoragePartitionImpl::GetStorageServiceForTesting()->BindTestApi(
-        test_api.BindNewPipeAndPassReceiver().PassPipe());
-    test_api->CrashNow();
-    loop.Run();
-  }
-
- private:
-  base::test::ScopedFeatureList feature_list_;
-};
-
-IN_PROC_BROWSER_TEST_F(PrerenderRestartStorageServiceBrowserTest,
-                       RestartStorageServiceBeforePrerendering) {
-  const GURL kInitialUrl = GetUrl("/prerender/session_storage.html");
-  const GURL kPrerenderingUrl =
-      GetUrl("/prerender/session_storage.html?prerendering=");
-
-  // Navigate to an initial page.
-  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
-
-  CrashStorageServiceAndWaitForRestart();
-
-  EXPECT_EQ(
-      "initial",
-      EvalJs(current_frame_host(), "getSessionStorageKeys()").ExtractString());
-
-  AddPrerender(kPrerenderingUrl);
-  NavigatePrimaryPage(kPrerenderingUrl);
-
-  EXPECT_EQ("initial", EvalJs(current_frame_host(),
-                              "window.sessionKeysInPrerenderingchange")
-                           .ExtractString());
-  EXPECT_EQ(
-      "activated, initial",
-      EvalJs(current_frame_host(), "getSessionStorageKeys()").ExtractString());
-}
-
-IN_PROC_BROWSER_TEST_F(PrerenderRestartStorageServiceBrowserTest,
-                       RestartStorageServiceWhilePrerendering) {
-  const GURL kInitialUrl = GetUrl("/prerender/session_storage.html");
-  const GURL kPrerenderingUrl =
-      GetUrl("/prerender/session_storage.html?prerendering=");
-
-  // Navigate to an initial page.
-  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
-
-  const int host_id = AddPrerender(kPrerenderingUrl);
-
-  CrashStorageServiceAndWaitForRestart();
-
-  EXPECT_EQ(
-      "initial",
-      EvalJs(current_frame_host(), "getSessionStorageKeys()").ExtractString());
-  EXPECT_EQ(
-      "initial, prerendering",
-      EvalJs(GetPrerenderedMainFrameHost(host_id), "getSessionStorageKeys()")
-          .ExtractString());
-
-  NavigatePrimaryPage(kPrerenderingUrl);
-
-  EXPECT_EQ("initial", EvalJs(current_frame_host(),
-                              "window.sessionKeysInPrerenderingchange")
-                           .ExtractString());
-  EXPECT_EQ(
-      "activated, initial",
-      EvalJs(current_frame_host(), "getSessionStorageKeys()").ExtractString());
-}
-#endif
-
 class PrerenderWithProactiveBrowsingInstanceSwap : public PrerenderBrowserTest {
  public:
   PrerenderWithProactiveBrowsingInstanceSwap() {
diff --git a/content/browser/prerender/prerender_host.cc b/content/browser/prerender/prerender_host.cc
index 49a819dc..41d8cbc 100644
--- a/content/browser/prerender/prerender_host.cc
+++ b/content/browser/prerender/prerender_host.cc
@@ -16,7 +16,6 @@
 #include "content/browser/renderer_host/render_frame_host_impl.h"
 #include "content/browser/renderer_host/render_frame_proxy_host.h"
 #include "content/browser/renderer_host/render_view_host_impl.h"
-#include "content/browser/site_instance_impl.h"
 #include "content/browser/web_contents/web_contents_impl.h"
 #include "content/public/browser/back_forward_cache.h"
 #include "content/public/browser/navigation_controller.h"
@@ -78,20 +77,10 @@
                                         &web_contents,
                                         &web_contents,
                                         FrameTree::Type::kPrerender)) {
-    scoped_refptr<SiteInstance> site_instance =
-        SiteInstance::Create(web_contents.GetBrowserContext());
-    frame_tree_->Init(site_instance.get(),
-                      /*renderer_initiated_creation=*/false,
-                      /*main_frame_name=*/"");
-
-    const auto& site_info =
-        static_cast<SiteInstanceImpl*>(site_instance.get())->GetSiteInfo();
-    // Use the same SessionStorageNamespace as the primary page for the
-    // prerendering page.
-    frame_tree_->controller().SetSessionStorageNamespace(
-        site_info.GetStoragePartitionId(site_instance->GetBrowserContext()),
-        web_contents_.GetFrameTree()->controller().GetSessionStorageNamespace(
-            site_info));
+    frame_tree_->Init(
+        SiteInstance::Create(web_contents.GetBrowserContext()).get(),
+        /*renderer_initiated_creation=*/false,
+        /*main_frame_name=*/"");
 
     // TODO(https://crbug.com/1199679): This should be moved to FrameTree::Init
     web_contents_.NotifySwappedFromRenderManager(
diff --git a/content/browser/renderer_host/back_forward_cache_impl.cc b/content/browser/renderer_host/back_forward_cache_impl.cc
index 5c5d52d..795a369 100644
--- a/content/browser/renderer_host/back_forward_cache_impl.cc
+++ b/content/browser/renderer_host/back_forward_cache_impl.cc
@@ -40,6 +40,11 @@
 
 using blink::scheduler::WebSchedulerTrackedFeature;
 
+// Removes the time limit for cached content. This is used on bots to identify
+// accidentally passing tests.
+const base::Feature kBackForwardCacheNoTimeEviction{
+    "BackForwardCacheNoTimeEviction", base::FEATURE_DISABLED_BY_DEFAULT};
+
 // The default number of entries the BackForwardCache can hold per tab.
 static constexpr size_t kDefaultBackForwardCacheSize = 1;
 
diff --git a/content/browser/renderer_host/back_forward_cache_impl.h b/content/browser/renderer_host/back_forward_cache_impl.h
index 0794d62..5339c83 100644
--- a/content/browser/renderer_host/back_forward_cache_impl.h
+++ b/content/browser/renderer_host/back_forward_cache_impl.h
@@ -44,11 +44,6 @@
     "RecordBackForwardCacheMetricsWithoutEnabling",
     base::FEATURE_DISABLED_BY_DEFAULT};
 
-// Removes the time limit for cached content. This is used on bots to identify
-// accidentally passing tests.
-constexpr base::Feature kBackForwardCacheNoTimeEviction{
-    "BackForwardCacheNoTimeEviction", base::FEATURE_DISABLED_BY_DEFAULT};
-
 // BackForwardCache:
 //
 // After the user navigates away from a document, the old one goes into the
diff --git a/content/browser/service_worker/service_worker_context_wrapper.cc b/content/browser/service_worker/service_worker_context_wrapper.cc
index 74172e6..6bc97de 100644
--- a/content/browser/service_worker/service_worker_context_wrapper.cc
+++ b/content/browser/service_worker/service_worker_context_wrapper.cc
@@ -1740,22 +1740,4 @@
     std::move(on_registrations_initialized_).Run();
 }
 
-// static
-void ServiceWorkerContextWrapper::
-    DidGetRegisteredOriginsForGetInstalledRegistrationOrigins(
-        absl::optional<std::string> host_filter,
-        GetInstalledRegistrationOriginsCallback callback,
-        scoped_refptr<base::SingleThreadTaskRunner> task_runner_for_callback,
-        const std::vector<url::Origin>& origins) {
-  std::vector<url::Origin> filtered_origins;
-  for (auto& origin : origins) {
-    if (host_filter.has_value() && host_filter.value() != origin.host())
-      continue;
-    filtered_origins.push_back(std::move(origin));
-  }
-  task_runner_for_callback->PostTask(
-      FROM_HERE,
-      base::BindOnce(std::move(callback), std::move(filtered_origins)));
-}
-
 }  // namespace content
diff --git a/content/browser/service_worker/service_worker_context_wrapper.h b/content/browser/service_worker/service_worker_context_wrapper.h
index cf9a098..a4b1516 100644
--- a/content/browser/service_worker/service_worker_context_wrapper.h
+++ b/content/browser/service_worker/service_worker_context_wrapper.h
@@ -415,10 +415,6 @@
       StartServiceWorkerForNavigationHintCallback callback,
       blink::ServiceWorkerStatusCode code);
 
-  void RecordStartServiceWorkerForNavigationHintResult(
-      StartServiceWorkerForNavigationHintCallback callback,
-      StartServiceWorkerForNavigationHintResult result);
-
   void DidFindRegistrationForMessageDispatch(
       blink::TransferableMessage message,
       const GURL& source_origin,
@@ -438,36 +434,11 @@
   CreateNonNetworkPendingURLLoaderFactoryBundleForUpdateCheck(
       BrowserContext* browser_context);
 
-  void SetUpLoaderFactoryForUpdateCheckOnUI(
-      const GURL& scope,
-      base::OnceCallback<void(scoped_refptr<network::SharedURLLoaderFactory>)>
-          callback);
-
-  // This method completes the remaining work of
-  // SetUpLoaderFactoryForUpdateCheckOnUI() on Core thread: Binds the pending
-  // network factory receiver and creates the loader factory bundle for update
-  // check.
-  void DidSetUpLoaderFactoryForUpdateCheck(
-      mojo::PendingRemote<network::mojom::URLLoaderFactory> remote,
-      mojo::PendingReceiver<network::mojom::URLLoaderFactory> pending_receiver,
-      bool bypass_redirect_checks,
-      base::OnceCallback<void(scoped_refptr<network::SharedURLLoaderFactory>)>
-          callback);
-
   // This is used as a callback of GetRegisteredOrigins when initialising to
   // store a list of origins that have registered service workers.
   void DidGetRegisteredOrigins(const std::vector<url::Origin>& origins);
 
-  static void DidGetRegisteredOriginsForGetInstalledRegistrationOrigins(
-      absl::optional<std::string> host_filter,
-      GetInstalledRegistrationOriginsCallback callback,
-      scoped_refptr<base::SingleThreadTaskRunner> task_runner_for_callback,
-      const std::vector<url::Origin>& origins);
-
   // Temporary for https://crbug.com/1161153.
-  void PerformStorageCleanupOnUIThread(
-      base::OnceClosure callback,
-      scoped_refptr<base::TaskRunner> callback_runner);
   void StartServiceWorkerAndDispatchMessageOnUIThread(
       const GURL& scope,
       blink::TransferableMessage message,
@@ -508,10 +479,6 @@
   void ClearUserDataForAllRegistrationsByKeyPrefixOnUIThread(
       const std::string& key_prefix,
       StatusCallback callback);
-  void GetInstalledRegistrationOriginsOnUIThread(
-      absl::optional<std::string> host_filter,
-      GetInstalledRegistrationOriginsCallback callback,
-      scoped_refptr<base::SingleThreadTaskRunner> task_runner_for_callback);
 
   // Observers of |context_core_| which live within content's implementation
   // boundary. Shared with |context_core_|.
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index 9ee8f76..e373e98 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -471,10 +471,6 @@
   }
 }
 
-bool RenderViewImpl::CanUpdateLayout() {
-  return true;
-}
-
 // RenderView implementation ---------------------------------------------------
 
 RenderFrameImpl* RenderViewImpl::GetMainRenderFrame() {
diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h
index dfaf88a32..51268da 100644
--- a/content/renderer/render_view_impl.h
+++ b/content/renderer/render_view_impl.h
@@ -139,7 +139,6 @@
       bool& consumed_user_gesture,
       const absl::optional<blink::WebImpression>& impression) override;
   void PrintPage(blink::WebLocalFrame* frame) override;
-  bool CanUpdateLayout() override;
   void OnPageFrozenChanged(bool frozen) override;
   void DidUpdateRendererPreferences() override;
 
diff --git a/content/test/data/prerender/session_storage.html b/content/test/data/prerender/session_storage.html
deleted file mode 100644
index 34efa12a..0000000
--- a/content/test/data/prerender/session_storage.html
+++ /dev/null
@@ -1,40 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src="test_utils.js"></script>
-<script>
-function getSessionStorageKeys() {
-  let keys = [];
-  let txt = '';
-  for (let i = 0; i < sessionStorage.length; ++i) {
-    keys.push(sessionStorage.key(i));
-  }
-  keys.sort();
-  keys.forEach((key) => {
-    if (txt.length) {
-      txt += ', ';
-    }
-    txt += key;
-  });
-  return txt;
-}
-
-(() => {
-  const params = new URLSearchParams(location.search);
-  const isPrerendering = params.has('prerendering');
-  if (!isPrerendering) {
-    sessionStorage.setItem('initial', '1');
-    return;
-  }
-  sessionStorage.setItem('prerendering', '1');
-  window.sessionKeysInPrerenderingchange = new Promise((resolve) => {
-    document.addEventListener('prerenderingchange', () => {
-      resolve(getSessionStorageKeys());
-      sessionStorage.setItem('activated', '1');
-    });
-  });
-})();
-</script>
-</head>
-<body></body>
-</html>
diff --git a/device/bluetooth/bluetooth_remote_gatt_descriptor.h b/device/bluetooth/bluetooth_remote_gatt_descriptor.h
index 051293e..7925e3a 100644
--- a/device/bluetooth/bluetooth_remote_gatt_descriptor.h
+++ b/device/bluetooth/bluetooth_remote_gatt_descriptor.h
@@ -14,6 +14,7 @@
 #include "device/bluetooth/bluetooth_export.h"
 #include "device/bluetooth/bluetooth_gatt_descriptor.h"
 #include "device/bluetooth/public/cpp/bluetooth_uuid.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace device {
 
diff --git a/extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_event_router.cc b/extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_event_router.cc
index cce1a6d9..6089b8e 100644
--- a/extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_event_router.cc
+++ b/extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_event_router.cc
@@ -1033,8 +1033,9 @@
   // lists of enums correctly.
   apibtle::Characteristic api_characteristic;
   PopulateCharacteristic(characteristic, &api_characteristic);
-  std::unique_ptr<base::ListValue> args(new base::ListValue());
-  args->Append(apibtle::CharacteristicToValue(&api_characteristic));
+  std::vector<base::Value> args;
+  args.push_back(base::Value::FromUniquePtrValue(
+      apibtle::CharacteristicToValue(&api_characteristic)));
 
   DispatchEventToExtensionsWithPermission(
       events::BLUETOOTH_LOW_ENERGY_ON_CHARACTERISTIC_VALUE_CHANGED,
@@ -1064,8 +1065,9 @@
   // lists of enums correctly.
   apibtle::Descriptor api_descriptor;
   PopulateDescriptor(descriptor, &api_descriptor);
-  std::unique_ptr<base::ListValue> args(new base::ListValue());
-  args->Append(apibtle::DescriptorToValue(&api_descriptor));
+  std::vector<base::Value> args;
+  args.push_back(base::Value::FromUniquePtrValue(
+      apibtle::DescriptorToValue(&api_descriptor)));
 
   DispatchEventToExtensionsWithPermission(
       events::BLUETOOTH_LOW_ENERGY_ON_DESCRIPTOR_VALUE_CHANGED,
@@ -1448,7 +1450,7 @@
     const std::string& event_name,
     const device::BluetoothUUID& uuid,
     const std::string& characteristic_id,
-    std::unique_ptr<base::ListValue> args) {
+    std::vector<base::Value> args) {
   // Obtain the listeners of |event_name|. The list can contain multiple
   // entries for the same extension, so we keep track of the extensions that we
   // already sent the event to, since we want the send an event to an extension
@@ -1488,7 +1490,7 @@
 
     // Send the event.
     auto event = std::make_unique<Event>(histogram_value, event_name,
-                                         args->CreateDeepCopy());
+                                         base::Value(args).TakeList());
     EventRouter::Get(browser_context_)
         ->DispatchEventToExtension(extension_id, std::move(event));
   }
@@ -1498,7 +1500,7 @@
     const std::string& extension_id,
     events::HistogramValue histogram_value,
     const std::string& event_name,
-    std::unique_ptr<base::ListValue> args) {
+    std::vector<base::Value> args) {
   // For all API methods, the "low_energy" permission check is handled by
   // BluetoothLowEnergyExtensionFunction but for events we have to do the
   // check here.
@@ -1509,8 +1511,8 @@
     return;
 
   // Send the event.
-  auto event = std::make_unique<Event>(histogram_value, event_name,
-                                       args->CreateDeepCopy());
+  auto event =
+      std::make_unique<Event>(histogram_value, event_name, std::move(args));
   EventRouter::Get(browser_context_)
       ->DispatchEventToExtension(extension_id, std::move(event));
 }
diff --git a/extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_event_router.h b/extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_event_router.h
index 719397a..6b0e8340 100644
--- a/extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_event_router.h
+++ b/extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_event_router.h
@@ -17,6 +17,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
 #include "base/scoped_observation.h"
+#include "base/values.h"
 #include "device/bluetooth/bluetooth_adapter.h"
 #include "device/bluetooth/bluetooth_device.h"
 #include "device/bluetooth/bluetooth_gatt_characteristic.h"
@@ -30,12 +31,6 @@
 #include "extensions/browser/extension_registry_observer.h"
 #include "extensions/common/api/bluetooth_low_energy.h"
 
-namespace base {
-
-class ListValue;
-
-}  // namespace base
-
 namespace content {
 
 class BrowserContext;
@@ -407,12 +402,12 @@
       const std::string& event_name,
       const device::BluetoothUUID& uuid,
       const std::string& characteristic_id,
-      std::unique_ptr<base::ListValue> args);
+      std::vector<base::Value> args);
 
   void DispatchEventToExtension(const std::string& extension_id,
                                 events::HistogramValue histogram_value,
                                 const std::string& event_name,
-                                std::unique_ptr<base::ListValue> args);
+                                std::vector<base::Value> args);
 
   // Returns a BluetoothRemoteGattService by its instance ID |instance_id|.
   // Returns
diff --git a/extensions/browser/api/bluetooth_socket/bluetooth_socket_api.cc b/extensions/browser/api/bluetooth_socket/bluetooth_socket_api.cc
index 2275b1f4..a869ea2 100644
--- a/extensions/browser/api/bluetooth_socket/bluetooth_socket_api.cc
+++ b/extensions/browser/api/bluetooth_socket/bluetooth_socket_api.cc
@@ -353,7 +353,7 @@
                                std::move(error_callback));
 }
 
-std::unique_ptr<base::ListValue>
+std::vector<base::Value>
 BluetoothSocketListenUsingRfcommFunction::CreateResults() {
   return bluetooth_socket::ListenUsingRfcomm::Results::Create();
 }
@@ -401,7 +401,7 @@
                               std::move(error_callback));
 }
 
-std::unique_ptr<base::ListValue>
+std::vector<base::Value>
 BluetoothSocketListenUsingL2capFunction::CreateResults() {
   return bluetooth_socket::ListenUsingL2cap::Results::Create();
 }
diff --git a/extensions/browser/api/bluetooth_socket/bluetooth_socket_api.h b/extensions/browser/api/bluetooth_socket/bluetooth_socket_api.h
index 4d944a69..804f971 100644
--- a/extensions/browser/api/bluetooth_socket/bluetooth_socket_api.h
+++ b/extensions/browser/api/bluetooth_socket/bluetooth_socket_api.h
@@ -10,8 +10,10 @@
 #include <memory>
 #include <string>
 #include <unordered_set>
+#include <vector>
 
 #include "base/memory/ref_counted.h"
+#include "base/values.h"
 #include "content/public/browser/browser_thread.h"
 #include "device/bluetooth/bluetooth_adapter.h"
 #include "extensions/browser/api/api_resource_manager.h"
@@ -121,7 +123,7 @@
       const absl::optional<std::string>& name,
       device::BluetoothAdapter::CreateServiceCallback callback,
       device::BluetoothAdapter::CreateServiceErrorCallback error_callback) = 0;
-  virtual std::unique_ptr<base::ListValue> CreateResults() = 0;
+  virtual std::vector<base::Value> CreateResults() = 0;
 
   virtual int socket_id() const = 0;
   virtual const std::string& uuid() const = 0;
@@ -159,7 +161,7 @@
                      device::BluetoothAdapter::CreateServiceCallback callback,
                      device::BluetoothAdapter::CreateServiceErrorCallback
                          error_callback) override;
-  std::unique_ptr<base::ListValue> CreateResults() override;
+  std::vector<base::Value> CreateResults() override;
 
  protected:
   ~BluetoothSocketListenUsingRfcommFunction() override;
@@ -187,7 +189,7 @@
                      device::BluetoothAdapter::CreateServiceCallback callback,
                      device::BluetoothAdapter::CreateServiceErrorCallback
                          error_callback) override;
-  std::unique_ptr<base::ListValue> CreateResults() override;
+  std::vector<base::Value> CreateResults() override;
 
  protected:
   ~BluetoothSocketListenUsingL2capFunction() override;
diff --git a/extensions/browser/api/diagnostics/diagnostics_api.cc b/extensions/browser/api/diagnostics/diagnostics_api.cc
index 4443a22..d67ead27 100644
--- a/extensions/browser/api/diagnostics/diagnostics_api.cc
+++ b/extensions/browser/api/diagnostics/diagnostics_api.cc
@@ -90,8 +90,7 @@
   api::diagnostics::SendPacketResult result;
   result.ip = ip;
   result.latency = latency;
-  Respond(OneArgument(
-      base::Value::FromUniquePtrValue(SendPacket::Results::Create(result))));
+  Respond(OneArgument(base::Value(SendPacket::Results::Create(result))));
 }
 
 }  // namespace extensions
diff --git a/extensions/browser/api/hid/hid_device_manager.cc b/extensions/browser/api/hid/hid_device_manager.cc
index 475a41c7..dffd623 100644
--- a/extensions/browser/api/hid/hid_device_manager.cc
+++ b/extensions/browser/api/hid/hid_device_manager.cc
@@ -380,7 +380,7 @@
 void HidDeviceManager::DispatchEvent(
     events::HistogramValue histogram_value,
     const std::string& event_name,
-    std::unique_ptr<base::ListValue> event_args,
+    std::vector<base::Value> event_args,
     const device::mojom::HidDeviceInfo& device_info) {
   std::unique_ptr<Event> event(
       new Event(histogram_value, event_name, std::move(event_args)));
diff --git a/extensions/browser/api/hid/hid_device_manager.h b/extensions/browser/api/hid/hid_device_manager.h
index cab0d7a..0980249 100644
--- a/extensions/browser/api/hid/hid_device_manager.h
+++ b/extensions/browser/api/hid/hid_device_manager.h
@@ -15,6 +15,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/scoped_observer.h"
 #include "base/threading/thread_checker.h"
+#include "base/values.h"
 #include "extensions/browser/browser_context_keyed_api_factory.h"
 #include "extensions/browser/event_router.h"
 #include "extensions/browser/extension_event_histogram_value.h"
@@ -121,7 +122,7 @@
 
   void DispatchEvent(events::HistogramValue histogram_value,
                      const std::string& event_name,
-                     std::unique_ptr<base::ListValue> event_args,
+                     std::vector<base::Value> event_args,
                      const device::mojom::HidDeviceInfo& device_info);
 
   base::ThreadChecker thread_checker_;
diff --git a/extensions/browser/api/socket/socket_api.cc b/extensions/browser/api/socket/socket_api.cc
index 04fcc8f..0bcb92e 100644
--- a/extensions/browser/api/socket/socket_api.cc
+++ b/extensions/browser/api/socket/socket_api.cc
@@ -1162,7 +1162,8 @@
   if (result != net::OK) {
     RemoveSocket(params_->socket_id);
     error_ = net::ErrorToString(result);
-    results_ = api::socket::Secure::Results::Create(result);
+    results_ = std::make_unique<base::ListValue>(
+        api::socket::Secure::Results::Create(result));
     AsyncWorkCompleted();
     return;
   }
@@ -1172,7 +1173,8 @@
                                   std::move(receive_pipe_handle),
                                   std::move(send_pipe_handle), extension_id());
   ReplaceSocket(params_->socket_id, socket.release());
-  results_ = api::socket::Secure::Results::Create(result);
+  results_ = std::make_unique<base::ListValue>(
+      api::socket::Secure::Results::Create(result));
   AsyncWorkCompleted();
 }
 
diff --git a/extensions/browser/api/sockets_tcp/sockets_tcp_api.cc b/extensions/browser/api/sockets_tcp/sockets_tcp_api.cc
index 408f51c..64fdb9f7 100644
--- a/extensions/browser/api/sockets_tcp/sockets_tcp_api.cc
+++ b/extensions/browser/api/sockets_tcp/sockets_tcp_api.cc
@@ -143,7 +143,8 @@
 
   sockets_tcp::CreateInfo create_info;
   create_info.socket_id = AddSocket(socket);
-  results_ = sockets_tcp::Create::Results::Create(create_info);
+  results_ = std::make_unique<base::ListValue>(
+      sockets_tcp::Create::Results::Create(create_info));
 }
 
 SocketsTcpUpdateFunction::SocketsTcpUpdateFunction() {}
@@ -164,7 +165,8 @@
   }
 
   SetSocketProperties(socket, &params_->properties);
-  results_ = sockets_tcp::Update::Results::Create();
+  results_ =
+      std::make_unique<base::ListValue>(sockets_tcp::Update::Results::Create());
 }
 
 SocketsTcpSetPausedFunction::SocketsTcpSetPausedFunction()
@@ -200,7 +202,8 @@
     }
   }
 
-  results_ = sockets_tcp::SetPaused::Results::Create();
+  results_ = std::make_unique<base::ListValue>(
+      sockets_tcp::SetPaused::Results::Create());
 }
 
 SocketsTcpSetKeepAliveFunction::SocketsTcpSetKeepAliveFunction() {}
@@ -217,7 +220,8 @@
   ResumableTCPSocket* socket = GetTcpSocket(params_->socket_id);
   if (!socket) {
     error_ = kSocketNotFoundError;
-    results_ = sockets_tcp::SetKeepAlive::Results::Create(net::ERR_FAILED);
+    results_ = std::make_unique<base::ListValue>(
+        sockets_tcp::SetKeepAlive::Results::Create(net::ERR_FAILED));
     AsyncWorkCompleted();
     return;
   }
@@ -231,7 +235,8 @@
 
 void SocketsTcpSetKeepAliveFunction::OnCompleted(bool success) {
   int net_result = (success ? net::OK : net::ERR_FAILED);
-  results_ = sockets_tcp::SetKeepAlive::Results::Create(net_result);
+  results_ = std::make_unique<base::ListValue>(
+      sockets_tcp::SetKeepAlive::Results::Create(net_result));
   if (net_result != net::OK)
     error_ = net::ErrorToString(net_result);
   AsyncWorkCompleted();
@@ -251,7 +256,8 @@
   ResumableTCPSocket* socket = GetTcpSocket(params_->socket_id);
   if (!socket) {
     error_ = kSocketNotFoundError;
-    results_ = sockets_tcp::SetNoDelay::Results::Create(net::ERR_FAILED);
+    results_ = std::make_unique<base::ListValue>(
+        sockets_tcp::SetNoDelay::Results::Create(net::ERR_FAILED));
     AsyncWorkCompleted();
     return;
   }
@@ -262,7 +268,8 @@
 
 void SocketsTcpSetNoDelayFunction::OnCompleted(bool success) {
   int net_result = (success ? net::OK : net::ERR_FAILED);
-  results_ = sockets_tcp::SetNoDelay::Results::Create(net_result);
+  results_ = std::make_unique<base::ListValue>(
+      sockets_tcp::SetNoDelay::Results::Create(net_result));
   if (net_result != net::OK)
     error_ = net::ErrorToString(net_result);
   AsyncWorkCompleted();
@@ -337,7 +344,8 @@
 
   if (net_result != net::OK)
     error_ = net::ErrorToString(net_result);
-  results_ = sockets_tcp::Connect::Results::Create(net_result);
+  results_ = std::make_unique<base::ListValue>(
+      sockets_tcp::Connect::Results::Create(net_result));
   AsyncWorkCompleted();
 }
 
@@ -359,7 +367,8 @@
   }
 
   socket->Disconnect(false /* socket_destroying */);
-  results_ = sockets_tcp::Disconnect::Results::Create();
+  results_ = std::make_unique<base::ListValue>(
+      sockets_tcp::Disconnect::Results::Create());
 }
 
 SocketsTcpSendFunction::SocketsTcpSendFunction() : io_buffer_size_(0) {}
@@ -406,7 +415,8 @@
 
   if (net_result != net::OK)
     error_ = net::ErrorToString(net_result);
-  results_ = sockets_tcp::Send::Results::Create(send_info);
+  results_ = std::make_unique<base::ListValue>(
+      sockets_tcp::Send::Results::Create(send_info));
   AsyncWorkCompleted();
 }
 
@@ -428,7 +438,8 @@
   }
 
   RemoveSocket(params_->socket_id);
-  results_ = sockets_tcp::Close::Results::Create();
+  results_ =
+      std::make_unique<base::ListValue>(sockets_tcp::Close::Results::Create());
 }
 
 SocketsTcpGetInfoFunction::SocketsTcpGetInfoFunction() {}
@@ -450,7 +461,8 @@
 
   sockets_tcp::SocketInfo socket_info =
       CreateSocketInfo(params_->socket_id, socket);
-  results_ = sockets_tcp::GetInfo::Results::Create(socket_info);
+  results_ = std::make_unique<base::ListValue>(
+      sockets_tcp::GetInfo::Results::Create(socket_info));
 }
 
 SocketsTcpGetSocketsFunction::SocketsTcpGetSocketsFunction() {}
@@ -470,7 +482,8 @@
       }
     }
   }
-  results_ = sockets_tcp::GetSockets::Results::Create(socket_infos);
+  results_ = std::make_unique<base::ListValue>(
+      sockets_tcp::GetSockets::Results::Create(socket_infos));
 }
 
 SocketsTcpSecureFunction::SocketsTcpSecureFunction() {
@@ -549,7 +562,8 @@
   if (result != net::OK) {
     RemoveSocket(params_->socket_id);
     error_ = net::ErrorToString(result);
-    results_ = api::sockets_tcp::Secure::Results::Create(result);
+    results_ = std::make_unique<base::ListValue>(
+        api::sockets_tcp::Secure::Results::Create(result));
     AsyncWorkCompleted();
     return;
   }
@@ -560,7 +574,8 @@
   socket->set_persistent(persistent_);
   socket->set_paused(paused_);
   ReplaceSocket(params_->socket_id, socket.release());
-  results_ = api::sockets_tcp::Secure::Results::Create(result);
+  results_ = std::make_unique<base::ListValue>(
+      api::sockets_tcp::Secure::Results::Create(result));
   AsyncWorkCompleted();
 }
 
diff --git a/extensions/browser/api/sockets_tcp_server/sockets_tcp_server_api.cc b/extensions/browser/api/sockets_tcp_server/sockets_tcp_server_api.cc
index b34b1d4..d4c1b05 100644
--- a/extensions/browser/api/sockets_tcp_server/sockets_tcp_server_api.cc
+++ b/extensions/browser/api/sockets_tcp_server/sockets_tcp_server_api.cc
@@ -103,7 +103,8 @@
 
   sockets_tcp_server::CreateInfo create_info;
   create_info.socket_id = AddSocket(socket);
-  results_ = sockets_tcp_server::Create::Results::Create(create_info);
+  results_ = std::make_unique<base::ListValue>(
+      sockets_tcp_server::Create::Results::Create(create_info));
 }
 
 SocketsTcpServerUpdateFunction::SocketsTcpServerUpdateFunction() {}
@@ -124,7 +125,8 @@
   }
 
   SetSocketProperties(socket, &params_->properties);
-  results_ = sockets_tcp_server::Update::Results::Create();
+  results_ = std::make_unique<base::ListValue>(
+      sockets_tcp_server::Update::Results::Create());
 }
 
 SocketsTcpServerSetPausedFunction::SocketsTcpServerSetPausedFunction()
@@ -161,7 +163,8 @@
     }
   }
 
-  results_ = sockets_tcp_server::SetPaused::Results::Create();
+  results_ = std::make_unique<base::ListValue>(
+      sockets_tcp_server::SetPaused::Results::Create());
 }
 
 SocketsTcpServerListenFunction::SocketsTcpServerListenFunction()
@@ -216,7 +219,8 @@
     AsyncWorkCompleted();
     return;
   }
-  results_ = sockets_tcp_server::Listen::Results::Create(net_result);
+  results_ = std::make_unique<base::ListValue>(
+      sockets_tcp_server::Listen::Results::Create(net_result));
   if (net_result == net::OK) {
     socket_event_dispatcher_->OnServerSocketListen(extension_->id(),
                                                    params_->socket_id);
@@ -247,7 +251,8 @@
   }
 
   socket->Disconnect(false /* socket_destroying */);
-  results_ = sockets_tcp_server::Disconnect::Results::Create();
+  results_ = std::make_unique<base::ListValue>(
+      sockets_tcp_server::Disconnect::Results::Create());
 }
 
 SocketsTcpServerCloseFunction::SocketsTcpServerCloseFunction() {}
@@ -268,7 +273,8 @@
   }
 
   RemoveSocket(params_->socket_id);
-  results_ = sockets_tcp_server::Close::Results::Create();
+  results_ = std::make_unique<base::ListValue>(
+      sockets_tcp_server::Close::Results::Create());
 }
 
 SocketsTcpServerGetInfoFunction::SocketsTcpServerGetInfoFunction() {}
@@ -290,7 +296,8 @@
 
   sockets_tcp_server::SocketInfo socket_info =
       CreateSocketInfo(params_->socket_id, socket);
-  results_ = sockets_tcp_server::GetInfo::Results::Create(socket_info);
+  results_ = std::make_unique<base::ListValue>(
+      sockets_tcp_server::GetInfo::Results::Create(socket_info));
 }
 
 SocketsTcpServerGetSocketsFunction::SocketsTcpServerGetSocketsFunction() {}
@@ -310,7 +317,8 @@
       }
     }
   }
-  results_ = sockets_tcp_server::GetSockets::Results::Create(socket_infos);
+  results_ = std::make_unique<base::ListValue>(
+      sockets_tcp_server::GetSockets::Results::Create(socket_infos));
 }
 
 }  // namespace api
diff --git a/extensions/browser/api/sockets_udp/sockets_udp_api.cc b/extensions/browser/api/sockets_udp/sockets_udp_api.cc
index 5ec1473..03f764e 100644
--- a/extensions/browser/api/sockets_udp/sockets_udp_api.cc
+++ b/extensions/browser/api/sockets_udp/sockets_udp_api.cc
@@ -120,7 +120,8 @@
 
   sockets_udp::CreateInfo create_info;
   create_info.socket_id = AddSocket(socket);
-  results_ = sockets_udp::Create::Results::Create(create_info);
+  results_ = std::make_unique<base::ListValue>(
+      sockets_udp::Create::Results::Create(create_info));
 }
 
 SocketsUdpUpdateFunction::SocketsUdpUpdateFunction() {}
@@ -141,7 +142,8 @@
   }
 
   SetSocketProperties(socket, &params_->properties);
-  results_ = sockets_udp::Update::Results::Create();
+  results_ =
+      std::make_unique<base::ListValue>(sockets_udp::Update::Results::Create());
 }
 
 SocketsUdpSetPausedFunction::SocketsUdpSetPausedFunction()
@@ -177,7 +179,8 @@
     }
   }
 
-  results_ = sockets_udp::SetPaused::Results::Create();
+  results_ = std::make_unique<base::ListValue>(
+      sockets_udp::SetPaused::Results::Create());
 }
 
 SocketsUdpBindFunction::SocketsUdpBindFunction()
@@ -224,7 +227,8 @@
     AsyncWorkCompleted();
     return;
   }
-  results_ = sockets_udp::Bind::Results::Create(net_result);
+  results_ = std::make_unique<base::ListValue>(
+      sockets_udp::Bind::Results::Create(net_result));
   if (net_result == net::OK) {
     socket_event_dispatcher_->OnSocketBind(extension_->id(),
                                            params_->socket_id);
@@ -309,7 +313,8 @@
 
   if (net_result != net::OK)
     error_ = net::ErrorToString(net_result);
-  results_ = sockets_udp::Send::Results::Create(send_info);
+  results_ = std::make_unique<base::ListValue>(
+      sockets_udp::Send::Results::Create(send_info));
   AsyncWorkCompleted();
 }
 
@@ -332,7 +337,8 @@
 
   socket->Disconnect(false /* socket_destroying */);
   RemoveSocket(params_->socket_id);
-  results_ = sockets_udp::Close::Results::Create();
+  results_ =
+      std::make_unique<base::ListValue>(sockets_udp::Close::Results::Create());
 }
 
 SocketsUdpGetInfoFunction::SocketsUdpGetInfoFunction() {}
@@ -354,7 +360,8 @@
 
   sockets_udp::SocketInfo socket_info =
       CreateSocketInfo(params_->socket_id, socket);
-  results_ = sockets_udp::GetInfo::Results::Create(socket_info);
+  results_ = std::make_unique<base::ListValue>(
+      sockets_udp::GetInfo::Results::Create(socket_info));
 }
 
 SocketsUdpGetSocketsFunction::SocketsUdpGetSocketsFunction() {}
@@ -374,7 +381,8 @@
       }
     }
   }
-  results_ = sockets_udp::GetSockets::Results::Create(socket_infos);
+  results_ = std::make_unique<base::ListValue>(
+      sockets_udp::GetSockets::Results::Create(socket_infos));
 }
 
 SocketsUdpJoinGroupFunction::SocketsUdpJoinGroupFunction() {}
@@ -413,7 +421,8 @@
 void SocketsUdpJoinGroupFunction::OnCompleted(int net_result) {
   if (net_result != net::OK)
     error_ = net::ErrorToString(net_result);
-  results_ = sockets_udp::JoinGroup::Results::Create(net_result);
+  results_ = std::make_unique<base::ListValue>(
+      sockets_udp::JoinGroup::Results::Create(net_result));
   AsyncWorkCompleted();
 }
 
@@ -452,7 +461,8 @@
 void SocketsUdpLeaveGroupFunction::OnCompleted(int result) {
   if (result != net::OK)
     error_ = net::ErrorToString(result);
-  results_ = sockets_udp::LeaveGroup::Results::Create(result);
+  results_ = std::make_unique<base::ListValue>(
+      sockets_udp::LeaveGroup::Results::Create(result));
   AsyncWorkCompleted();
 }
 
@@ -478,7 +488,8 @@
   int net_result = socket->SetMulticastTimeToLive(params_->ttl);
   if (net_result != net::OK)
     error_ = net::ErrorToString(net_result);
-  results_ = sockets_udp::SetMulticastTimeToLive::Results::Create(net_result);
+  results_ = std::make_unique<base::ListValue>(
+      sockets_udp::SetMulticastTimeToLive::Results::Create(net_result));
 }
 
 SocketsUdpSetMulticastLoopbackModeFunction::
@@ -503,7 +514,8 @@
   int net_result = socket->SetMulticastLoopbackMode(params_->enabled);
   if (net_result != net::OK)
     error_ = net::ErrorToString(net_result);
-  results_ = sockets_udp::SetMulticastLoopbackMode::Results::Create(net_result);
+  results_ = std::make_unique<base::ListValue>(
+      sockets_udp::SetMulticastLoopbackMode::Results::Create(net_result));
 }
 
 SocketsUdpGetJoinedGroupsFunction::SocketsUdpGetJoinedGroupsFunction() {}
@@ -533,7 +545,8 @@
   }
 
   const std::vector<std::string>& groups = socket->GetJoinedGroups();
-  results_ = sockets_udp::GetJoinedGroups::Results::Create(groups);
+  results_ = std::make_unique<base::ListValue>(
+      sockets_udp::GetJoinedGroups::Results::Create(groups));
 }
 
 SocketsUdpSetBroadcastFunction::SocketsUdpSetBroadcastFunction() {
@@ -564,7 +577,8 @@
 void SocketsUdpSetBroadcastFunction::OnCompleted(int net_result) {
   if (net_result != net::OK)
     error_ = net::ErrorToString(net_result);
-  results_ = sockets_udp::SetBroadcast::Results::Create(net_result);
+  results_ = std::make_unique<base::ListValue>(
+      sockets_udp::SetBroadcast::Results::Create(net_result));
   AsyncWorkCompleted();
 }
 
diff --git a/extensions/browser/api/vpn_provider/vpn_service.cc b/extensions/browser/api/vpn_provider/vpn_service.cc
index 4df364d..4d1867b 100644
--- a/extensions/browser/api/vpn_provider/vpn_service.cc
+++ b/extensions/browser/api/vpn_provider/vpn_service.cc
@@ -581,7 +581,7 @@
     const std::string& extension_id,
     extensions::events::HistogramValue histogram_value,
     const std::string& event_name,
-    std::unique_ptr<base::ListValue> event_args) {
+    std::vector<base::Value> event_args) {
   std::unique_ptr<extensions::Event> event(new extensions::Event(
       histogram_value, event_name, std::move(event_args), browser_context_));
 
diff --git a/extensions/browser/api/vpn_provider/vpn_service.h b/extensions/browser/api/vpn_provider/vpn_service.h
index 189bd44c..f531f92 100644
--- a/extensions/browser/api/vpn_provider/vpn_service.h
+++ b/extensions/browser/api/vpn_provider/vpn_service.h
@@ -13,6 +13,7 @@
 #include "base/callback.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
+#include "base/values.h"
 #include "chromeos/network/network_configuration_observer.h"
 #include "chromeos/network/network_state_handler_observer.h"
 #include "components/keyed_service/core/keyed_service.h"
@@ -20,13 +21,6 @@
 #include "extensions/browser/extension_registry_observer.h"
 #include "extensions/common/api/vpn_provider.h"
 
-namespace base {
-
-class DictionaryValue;
-class ListValue;
-
-}  // namespace base
-
 namespace content {
 
 class BrowserContext;
@@ -211,7 +205,7 @@
   void SendSignalToExtension(const std::string& extension_id,
                              extensions::events::HistogramValue histogram_value,
                              const std::string& event_name,
-                             std::unique_ptr<base::ListValue> event_args);
+                             std::vector<base::Value> event_args);
 
   // Destroy configurations belonging to the extension.
   void DestroyConfigurationsForExtension(
diff --git a/infra/config/OWNERS b/infra/config/OWNERS
new file mode 100644
index 0000000..6d478842
--- /dev/null
+++ b/infra/config/OWNERS
@@ -0,0 +1,6 @@
+# iOS owners for changing Xcode constants only.
+per-file lib/builders.star=file://infra/config/groups/ios/OWNERS
+
+# iOS owners for builder configs.
+per-file subprojects/chromium/ci.star=file://infra/config/groups/ios/OWNERS
+per-file subprojects/chromium/try.star=file://infra/config/groups/ios/OWNERS
diff --git a/infra/config/generated/cr-buildbucket.cfg b/infra/config/generated/cr-buildbucket.cfg
index 56edd2b..a196913a 100644
--- a/infra/config/generated/cr-buildbucket.cfg
+++ b/infra/config/generated/cr-buildbucket.cfg
@@ -2574,7 +2574,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:1"
       exe {
@@ -2636,7 +2636,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -4776,7 +4776,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -4838,7 +4838,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -4900,7 +4900,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -4962,7 +4962,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -5024,7 +5024,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -6428,7 +6428,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -7425,7 +7425,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -7487,7 +7487,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -7739,7 +7739,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -7801,7 +7801,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -7987,7 +7987,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -8049,7 +8049,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -8111,7 +8111,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -8235,7 +8235,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -8297,7 +8297,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -9227,7 +9227,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -9289,7 +9289,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -9351,7 +9351,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -9413,7 +9413,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -9475,7 +9475,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -9661,7 +9661,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -9847,7 +9847,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -9909,7 +9909,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -9971,7 +9971,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -10033,7 +10033,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -10095,7 +10095,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -10157,7 +10157,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -12970,7 +12970,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -16129,7 +16129,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -16191,7 +16191,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -16253,7 +16253,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -22755,7 +22755,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -23189,7 +23189,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -23251,7 +23251,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -25388,7 +25388,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -26318,7 +26318,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -26442,7 +26442,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -26937,7 +26937,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -27371,7 +27371,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -29837,7 +29837,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
diff --git a/infra/config/groups/ios/OWNERS b/infra/config/groups/ios/OWNERS
index cb97ffb..ebdd93e 100644
--- a/infra/config/groups/ios/OWNERS
+++ b/infra/config/groups/ios/OWNERS
@@ -1,3 +1,4 @@
 jeffyoon@google.com
 lindsayw@chromium.org
+zhaoyangli@chromium.org
 zhaoyangli@google.com
diff --git a/infra/config/lib/ci.star b/infra/config/lib/ci.star
index e8b7ae138..aa6fbe4a 100644
--- a/infra/config/lib/ci.star
+++ b/infra/config/lib/ci.star
@@ -609,6 +609,7 @@
         notifies = ("chromium.linux",),
         extra_notifies = None,
         **kwargs):
+    kwargs.setdefault("os", builders.os.LINUX_BIONIC_REMOVE)
     return ci.builder(
         name = name,
         builder_group = "chromium.linux",
@@ -661,6 +662,7 @@
         tree_closing = True,
         **kwargs):
     if name.startswith("Linux"):
+        kwargs.setdefault("os", builders.os.LINUX_BIONIC_REMOVE)
         notifies = (notifies or []) + ["linux-memory"]
 
     return ci.builder(
diff --git a/infra/config/subprojects/chromium/ci.star b/infra/config/subprojects/chromium/ci.star
index d863f1ef..584704b 100644
--- a/infra/config/subprojects/chromium/ci.star
+++ b/infra/config/subprojects/chromium/ci.star
@@ -3054,6 +3054,7 @@
     ),
     cq_mirrors_console_view = "mirrors",
     main_console_view = main_console_if_on_branch(),
+    os = os.LINUX_BIONIC_REMOVE,
 )
 
 ci.fyi_builder(
@@ -3102,6 +3103,7 @@
         ),
     ],
     notifies = ["cr-fuchsia"],
+    os = os.LINUX_BIONIC_REMOVE,
 )
 
 ci.fyi_builder(
@@ -3119,6 +3121,7 @@
         ),
     ],
     notifies = ["cr-fuchsia"],
+    os = os.LINUX_BIONIC_REMOVE,
 )
 
 ci.fyi_builder(
@@ -3153,6 +3156,7 @@
         ),
     ],
     notifies = ["cr-fuchsia"],
+    os = os.LINUX_BIONIC_REMOVE,
 )
 
 ci.fyi_builder(
@@ -3170,6 +3174,7 @@
         short_name = "lnx",
     ),
     notifies = ["annotator-rel"],
+    os = os.LINUX_BIONIC_REMOVE,
 )
 
 ci.fyi_builder(
@@ -3231,6 +3236,7 @@
         category = "linux|blink",
         short_name = "CM",
     ),
+    os = os.LINUX_BIONIC_REMOVE,
 )
 
 ci.fyi_builder(
@@ -3240,6 +3246,7 @@
         short_name = "VF",
     ),
     notifies = ["linux-blink-fyi-bots"],
+    os = os.LINUX_BIONIC_REMOVE,
 )
 
 ci.fyi_builder(
@@ -3249,6 +3256,7 @@
         short_name = "VO",
     ),
     notifies = ["linux-blink-fyi-bots"],
+    os = os.LINUX_BIONIC_REMOVE,
 )
 
 ci.fyi_builder(
@@ -3315,6 +3323,7 @@
     console_view_entry = consoles.console_view_entry(
         category = "linux",
     ),
+    os = os.LINUX_BIONIC_REMOVE,
 )
 
 ci.fyi_builder(
@@ -3324,6 +3333,7 @@
     ),
     experimental = True,
     goma_backend = goma.backend.RBE_PROD,
+    os = os.LINUX_BIONIC_REMOVE,
 )
 
 ci.fyi_builder(
@@ -3333,6 +3343,7 @@
     ),
     experimental = True,
     goma_backend = goma.backend.RBE_PROD,
+    os = os.LINUX_BIONIC_REMOVE,
 )
 
 ci.fyi_builder(
@@ -3342,6 +3353,7 @@
     ),
     experimental = True,
     goma_backend = goma.backend.RBE_PROD,
+    os = os.LINUX_BIONIC_REMOVE,
 )
 
 # This is launching & collecting entirely isolated tests.
@@ -5864,6 +5876,7 @@
         short_name = "asn",
     ),
     main_console_view = "main",
+    os = os.LINUX_BIONIC_REMOVE,
 )
 
 ci.memory_builder(
@@ -5873,6 +5886,7 @@
         short_name = "lk",
     ),
     main_console_view = "main",
+    os = os.LINUX_BIONIC_REMOVE,
 )
 
 ci.memory_builder(
@@ -5882,6 +5896,7 @@
         short_name = "msn",
     ),
     main_console_view = "main",
+    os = os.LINUX_BIONIC_REMOVE,
 )
 
 ci.memory_builder(
@@ -5904,6 +5919,7 @@
     cores = 32,
     main_console_view = "main",
     tree_closing = False,
+    os = os.LINUX_BIONIC_REMOVE,
 )
 
 ci.memory_builder(
diff --git a/ios/chrome/app/app_metrics_app_state_agent_unittest.mm b/ios/chrome/app/app_metrics_app_state_agent_unittest.mm
index ae511d2..e237e89 100644
--- a/ios/chrome/app/app_metrics_app_state_agent_unittest.mm
+++ b/ios/chrome/app/app_metrics_app_state_agent_unittest.mm
@@ -66,6 +66,10 @@
 
 @end
 
+InitStage GetMinimalInitStageThatAllowsLogging() {
+  return static_cast<InitStage>(InitStageSafeMode + 1);
+}
+
 class AppMetricsAppStateAgentTest : public PlatformTest {
  protected:
   AppMetricsAppStateAgentTest() {
@@ -85,7 +89,7 @@
   void SetUp() override {
     PlatformTest::SetUp();
     app_state_.mainBrowserState = browser_state_.get();
-    app_state_.initStageForTesting = InitStageFinal;
+    app_state_.initStageForTesting = GetMinimalInitStageThatAllowsLogging();
     [agent_ setAppState:app_state_];
   }
 
@@ -190,7 +194,7 @@
   EXPECT_EQ(0, getProfileSessionDurationsService()->session_ended_count());
 
   // Session starts when safe mode completes.
-  app_state_.initStageForTesting = InitStageFinal;
+  app_state_.initStageForTesting = GetMinimalInitStageThatAllowsLogging();
   SimulateTransitionToCurrentStage();
   EXPECT_EQ(1, getProfileSessionDurationsService()->session_started_count());
   EXPECT_EQ(0, getProfileSessionDurationsService()->session_ended_count());
diff --git a/ios/chrome/app/application_delegate/app_state.mm b/ios/chrome/app/application_delegate/app_state.mm
index f9c8488..1fb6f1f 100644
--- a/ios/chrome/app/application_delegate/app_state.mm
+++ b/ios/chrome/app/application_delegate/app_state.mm
@@ -119,9 +119,8 @@
 // step cannot be included in the |startUpBrowserToStage:| method.
 - (void)initializeUIPreSafeMode;
 
-// Complete the browser initialization for a regular startup that is needed
-// after safe mode.
-- (void)initializeUIPostSafeMode;
+// Complete the browser initialization for a regular startup.
+- (void)completeUIInitialization;
 
 // Saves the current launch details to user defaults.
 - (void)saveLaunchDetailsToDefaults;
@@ -254,8 +253,7 @@
 
   crash_keys::SetCurrentlyInBackground(true);
 
-  if ([_browserLauncher browserInitializationStage] <
-      INITIALIZATION_STAGE_FOREGROUND) {
+  if (self.initStage < InitStageBrowserObjectsForUI) {
     // The clean-up done in |-applicationDidEnterBackground:| is only valid for
     // the case when the application is started in foreground, so there is
     // nothing to clean up as the application was not initialized for foregound.
@@ -317,12 +315,9 @@
 - (void)applicationWillEnterForeground:(UIApplication*)application
                        metricsMediator:(MetricsMediator*)metricsMediator
                           memoryHelper:(MemoryWarningHelper*)memoryHelper {
-  // TODO(crbug.com/1197330): Replace the browser launcher init stage by the
-  // app init stage.
   // Fully initialize the browser objects for the browser UI if it is not
   // already the case. This is especially needed for scene startup.
-  if ([_browserLauncher browserInitializationStage] <
-      INITIALIZATION_STAGE_FOREGROUND) {
+  if (self.initStage < InitStageBrowserObjectsForUI) {
     // Start the initialization in the case it wasn't already done before
     // foregrounding the app. |initStage| will be greater than InitStageStart if
     // the initialization was already started.
@@ -388,8 +383,7 @@
              connectionInformation:
                  (id<ConnectionInformation>)connectionInformation {
   DCHECK(!base::ios::IsSceneStartupSupported());
-  DCHECK([_browserLauncher browserInitializationStage] ==
-         INITIALIZATION_STAGE_FOREGROUND);
+  DCHECK(self.initStage >= InitStageBrowserObjectsForUI);
 
   // This is for iOS 12-compatibility only.
   DCHECK(self.mainSceneState);
@@ -450,8 +444,7 @@
   // closing the tabs. Set the BVC to inactive to cancel all the dialogs.
   // Don't do this if there are no scenes, since there's no defined interface
   // provider (and no tabs)
-  if ([_browserLauncher browserInitializationStage] >=
-      INITIALIZATION_STAGE_FOREGROUND) {
+  if (self.initStage >= InitStageBrowserObjectsForUI) {
     for (SceneState* sceneState in self.connectedScenes) {
       sceneState.interfaceProvider.currentInterface.userInteractionEnabled = NO;
     }
@@ -490,8 +483,7 @@
 }
 
 - (void)willResignActiveTabModel {
-  if ([_browserLauncher browserInitializationStage] <
-      INITIALIZATION_STAGE_FOREGROUND) {
+  if (self.initStage < InitStageBrowserObjectsForUI) {
     // If the application did not pass the foreground initialization stage,
     // there is no active tab model to resign.
     return;
@@ -657,12 +649,8 @@
   [self queueTransitionToNextInitStage];
 }
 
-- (void)initializeUIPostSafeMode {
-  // Fully start the browser.
-  // Don't add code here. Add it in MainController's
-  // -startUpBrowserForegroundInitialization.
+- (void)completeUIInitialization {
   DCHECK([self.startupInformation isColdStart]);
-  [_browserLauncher startUpBrowserToStage:INITIALIZATION_STAGE_FOREGROUND];
 
   if (EnableSyntheticCrashReportsForUte()) {
     // Must be called after sequenced context creation, which happens in
@@ -762,9 +750,11 @@
 // TODO(crbug.com/1191489): Move this logic to a specific agent.
 - (void)appState:(AppState*)appState
     didTransitionFromInitStage:(InitStage)previousInitStage {
-  if (previousInitStage == InitStageSafeMode) {
-    [self initializeUIPostSafeMode];
+  if (previousInitStage != InitStageBrowserObjectsForUI) {
+    return;
   }
+
+  [self completeUIInitialization];
 }
 
 @end
diff --git a/ios/chrome/app/application_delegate/app_state_observer.h b/ios/chrome/app/application_delegate/app_state_observer.h
index 3adecbc..26aa203 100644
--- a/ios/chrome/app/application_delegate/app_state_observer.h
+++ b/ios/chrome/app/application_delegate/app_state_observer.h
@@ -19,8 +19,15 @@
   // The app is starting the minimal basic browser services to support safe
   // mode.
   InitStageBrowserBasic,
-  // The app is considering whether safe mode should be used.
+  // The app is considering whether safe mode should be used. The app will stay
+  // at the InitStageSafeMode stage if safe mode is needed, or will move to the
+  // next stage otherwise.
   InitStageSafeMode,
+  // The app is initializing the browser objects for the background handlers.
+  InitStageBrowserObjectsForBackgroundHandlers,
+  // The app is initializing the browser objects for the browser UI (e.g., the
+  // browser state).
+  InitStageBrowserObjectsForUI,
   // The final stage before being done with initialization. The label and
   // relative position (always last) of this enum item should not change.
   // The value may change when inserting enum items between Start and Final.
diff --git a/ios/chrome/app/application_delegate/app_state_unittest.mm b/ios/chrome/app/application_delegate/app_state_unittest.mm
index 550365db..78b4a50 100644
--- a/ios/chrome/app/application_delegate/app_state_unittest.mm
+++ b/ios/chrome/app/application_delegate/app_state_unittest.mm
@@ -67,7 +67,7 @@
 - (void)startSafeMode;
 - (void)stopSafeMode;
 - (void)queueTransitionToFirstInitStage;
-- (void)initializeUIPostSafeMode;
+- (void)completeUIInitialization;
 @end
 
 @interface SafeModeAppAgent (Private) <SceneStateObserver, AppStateObserver>
@@ -84,8 +84,22 @@
 @implementation AppStateObserverToMockMainController
 - (void)appState:(AppState*)appState
     didTransitionFromInitStage:(InitStage)previousInitStage {
-  if (appState.initStage == InitStageStart) {
-    [appState queueTransitionToNextInitStage];
+  switch (appState.initStage) {
+    case InitStageStart:
+      [appState queueTransitionToNextInitStage];
+      break;
+    case InitStageBrowserBasic:
+      break;
+    case InitStageSafeMode:
+      break;
+    case InitStageBrowserObjectsForBackgroundHandlers:
+      [appState queueTransitionToNextInitStage];
+      break;
+    case InitStageBrowserObjectsForUI:
+      [appState queueTransitionToNextInitStage];
+      break;
+    case InitStageFinal:
+      break;
   }
 }
 @end
@@ -523,10 +537,6 @@
   id browserLauncherMock = getBrowserLauncherMock();
   [[browserLauncherMock expect] setLaunchOptions:launchOptions];
 
-  // Expected calls after safe mode.
-  [[browserLauncherMock expect]
-      startUpBrowserToStage:INITIALIZATION_STAGE_FOREGROUND];
-
   swizzleSafeModeShouldStart(YES);
 
 
@@ -576,9 +586,6 @@
   [appState addObserver:appStateObserverMock];
 
   id browserLauncherMock = getBrowserLauncherMock();
-  BrowserInitializationStageType stageForeground =
-      INITIALIZATION_STAGE_FOREGROUND;
-  [[browserLauncherMock expect] startUpBrowserToStage:stageForeground];
   [[browserLauncherMock expect] setLaunchOptions:launchOptions];
 
   swizzleSafeModeShouldStart(NO);
@@ -610,8 +617,6 @@
 
   id browserLauncher =
       [OCMockObject mockForProtocol:@protocol(BrowserLauncher)];
-  [[[browserLauncher stub] andReturnValue:@(INITIALIZATION_STAGE_FOREGROUND)]
-      browserInitializationStage];
   [[[browserLauncher stub] andReturn:interfaceProvider] interfaceProvider];
 
   id applicationDelegate =
@@ -626,6 +631,15 @@
                              startupInformation:startupInformation
                             applicationDelegate:applicationDelegate];
 
+  [appState addAgent:[[SafeModeAppAgent alloc] init]];
+  AppStateObserverToMockMainController* observer =
+      [AppStateObserverToMockMainController alloc];
+  [appState addObserver:observer];
+
+  // Start init stages.
+  [appState queueTransitionToFirstInitStage];
+  [appState queueTransitionToNextInitStage];
+
   ASSERT_TRUE([startupInformation isColdStart]);
 
   // Action.
@@ -645,8 +659,6 @@
       [OCMockObject mockForProtocol:@protocol(BrowserLauncher)];
   id applicationDelegate =
       [OCMockObject mockForClass:[MainApplicationDelegate class]];
-  [[[browserLauncher stub] andReturnValue:@(INITIALIZATION_STAGE_FOREGROUND)]
-      browserInitializationStage];
 
   id startupInformation =
       [OCMockObject mockForProtocol:@protocol(StartupInformation)];
@@ -657,6 +669,18 @@
                              startupInformation:startupInformation
                             applicationDelegate:applicationDelegate];
 
+  id appStateMock = OCMPartialMock(appState);
+  [[appStateMock expect] completeUIInitialization];
+
+  [appState addAgent:[[SafeModeAppAgent alloc] init]];
+  AppStateObserverToMockMainController* observer =
+      [AppStateObserverToMockMainController alloc];
+  [appState addObserver:observer];
+
+  // Start init stages.
+  [appState queueTransitionToFirstInitStage];
+  [appState queueTransitionToNextInitStage];
+
   // Create a scene state so that full shutdown will run.
   if (!base::ios::IsSceneStartupSupported()) {
     appState.mainSceneState = [[SceneState alloc] initWithAppState:appState];
@@ -691,9 +715,6 @@
 
   // BrowserLauncher.
   StubBrowserInterfaceProvider* interfaceProvider = getInterfaceProvider();
-  [[[getBrowserLauncherMock() stub]
-      andReturnValue:@(INITIALIZATION_STAGE_FOREGROUND)]
-      browserInitializationStage];
   [[[getBrowserLauncherMock() stub] andReturn:interfaceProvider]
       interfaceProvider];
 
@@ -739,9 +760,6 @@
   // Setup.
   // BrowserLauncher.
   StubBrowserInterfaceProvider* interfaceProvider = getInterfaceProvider();
-  [[[getBrowserLauncherMock() stub]
-      andReturnValue:@(INITIALIZATION_STAGE_FOREGROUND)]
-      browserInitializationStage];
   [[[getBrowserLauncherMock() stub] andReturn:interfaceProvider]
       interfaceProvider];
 
@@ -786,9 +804,6 @@
   // Setup.
   // BrowserLauncher.
   StubBrowserInterfaceProvider* interfaceProvider = getInterfaceProvider();
-  [[[getBrowserLauncherMock() stub]
-      andReturnValue:@(INITIALIZATION_STAGE_FOREGROUND)]
-      browserInitializationStage];
   [[[getBrowserLauncherMock() stub] andReturn:interfaceProvider]
       interfaceProvider];
 
@@ -840,6 +855,8 @@
 
 // Tests that -applicationWillEnterForeground resets components as needed.
 TEST_F(AppStateTest, applicationWillEnterForeground) {
+  swizzleSafeModeShouldStart(NO);
+
   // Setup.
   IOSChromeScopedTestingChromeBrowserProvider provider_(
       std::make_unique<FakeChromeBrowserProvider>());
@@ -850,9 +867,6 @@
   id tabOpener = [OCMockObject mockForProtocol:@protocol(TabOpening)];
   std::unique_ptr<Browser> browser = std::make_unique<TestBrowser>();
 
-  BrowserInitializationStageType stage = INITIALIZATION_STAGE_FOREGROUND;
-  [[[getBrowserLauncherMock() stub] andReturnValue:@(stage)]
-      browserInitializationStage];
   [[[getBrowserLauncherMock() stub] andReturn:interfaceProvider]
       interfaceProvider];
   interfaceProvider.mainInterface.browserState = getBrowserState();
@@ -864,7 +878,7 @@
       shouldOpenNTPTabOnActivationOfBrowser:browser.get()];
 
   id appStateMock = OCMPartialMock(getAppStateWithMock());
-  [[appStateMock expect] initializeUIPostSafeMode];
+  [[appStateMock expect] completeUIInitialization];
 
   // Simulate finishing the initialization before going to background.
   [getAppStateWithMock() queueTransitionToFirstInitStage];
@@ -907,16 +921,10 @@
   id metricsMediator = [OCMockObject mockForClass:[MetricsMediator class]];
   id memoryHelper = [OCMockObject mockForClass:[MemoryWarningHelper class]];
 
-  BrowserInitializationStageType stage = INITIALIZATION_STAGE_BACKGROUND;
-  [[[getBrowserLauncherMock() stub] andReturnValue:@(stage)]
-      browserInitializationStage];
-
   [[[getWindowMock() stub] andReturn:nil] rootViewController];
   swizzleSafeModeShouldStart(NO);
 
   [[[getStartupInformationMock() stub] andReturnValue:@YES] isColdStart];
-  [[getBrowserLauncherMock() expect]
-      startUpBrowserToStage:INITIALIZATION_STAGE_FOREGROUND];
 
   // Actions.
   [getAppStateWithMock() applicationWillEnterForeground:application
@@ -948,10 +956,6 @@
 
   id window = getWindowMock();
 
-  BrowserInitializationStageType stage = INITIALIZATION_STAGE_BACKGROUND;
-  [[[getBrowserLauncherMock() stub] andReturnValue:@(stage)]
-      browserInitializationStage];
-
   [[[window stub] andReturn:nil] rootViewController];
   [[window stub] setRootViewController:[OCMArg any]];
   swizzleSafeModeShouldStart(YES);
@@ -982,13 +986,13 @@
   // Tests.
   EXPECT_OCMOCK_VERIFY(window);
 
-  // Verify that the app is still in safe mode after initializing the UI when
-  // entering foreground from background.
   EXPECT_EQ(InitStageSafeMode, appState.initStage);
 }
 
 // Tests that -applicationDidEnterBackground calls the metrics mediator.
 TEST_F(AppStateTest, applicationDidEnterBackgroundIncognito) {
+  swizzleSafeModeShouldStart(NO);
+
   // Setup.
   ScopedKeyWindow scopedKeyWindow;
   id application = [OCMockObject niceMockForClass:[UIApplication class]];
@@ -998,18 +1002,26 @@
   std::unique_ptr<Browser> browser = std::make_unique<TestBrowser>();
   id startupInformation = getStartupInformationMock();
   id browserLauncher = getBrowserLauncherMock();
-  BrowserInitializationStageType stage = INITIALIZATION_STAGE_FOREGROUND;
 
   AppState* appState = getAppStateWithRealWindow(scopedKeyWindow.Get());
+  id appStateMock = OCMPartialMock(appState);
+  [[appStateMock expect] completeUIInitialization];
 
   [[startupInformation expect] expireFirstUserActionRecorder];
   [[[memoryHelper stub] andReturnValue:@0] foregroundMemoryWarningCount];
   interfaceProvider.incognitoInterface.browser = browser.get();
-  [[[browserLauncher stub] andReturnValue:@(stage)] browserInitializationStage];
   [[[browserLauncher stub] andReturn:interfaceProvider] interfaceProvider];
 
   swizzleMetricsMediatorDisableReporting();
 
+  // Simulate launching the app before going to background. This is to start
+  // initialization process.
+  NSDictionary* launchOptions = @{};
+  id browserLauncherMock = getBrowserLauncherMock();
+  [[browserLauncherMock expect] setLaunchOptions:launchOptions];
+  [appState requiresHandlingAfterLaunchWithOptions:launchOptions
+                                   stateBackground:NO];
+
   // Action.
   [appState applicationDidEnterBackground:application
                              memoryHelper:memoryHelper];
@@ -1022,14 +1034,14 @@
 // Tests that -applicationDidEnterBackground do nothing if the application has
 // never been in a Foreground stage.
 TEST_F(AppStateTest, applicationDidEnterBackgroundStageBackground) {
+  swizzleSafeModeShouldStart(NO);
+
   // Setup.
   ScopedKeyWindow scopedKeyWindow;
   id application = [OCMockObject mockForClass:[UIApplication class]];
   id memoryHelper = [OCMockObject mockForClass:[MemoryWarningHelper class]];
   id browserLauncher = getBrowserLauncherMock();
-  BrowserInitializationStageType stage = INITIALIZATION_STAGE_BACKGROUND;
 
-  [[[browserLauncher stub] andReturnValue:@(stage)] browserInitializationStage];
   [[[browserLauncher stub] andReturn:nil] interfaceProvider];
 
   ASSERT_EQ(NSUInteger(0), [scopedKeyWindow.Get() subviews].count);
diff --git a/ios/chrome/app/application_delegate/browser_launcher.h b/ios/chrome/app/application_delegate/browser_launcher.h
index c86c9d2c..489e662e 100644
--- a/ios/chrome/app/application_delegate/browser_launcher.h
+++ b/ios/chrome/app/application_delegate/browser_launcher.h
@@ -7,36 +7,15 @@
 
 #import "ios/chrome/browser/ui/main/browser_interface_provider.h"
 
-// Possible stages of the browser initialization. These states will be reached
-// in sequence, each stage is a requiremant for the following one.
-enum BrowserInitializationStageType {
-  // This state is before any initialization in MainController.
-  INITIALIZATION_STAGE_NONE = 0,
-  // Initialization state needed by background handlers.
-  INITIALIZATION_STAGE_BACKGROUND,
-  // Full initialization of the browser.
-  INITIALIZATION_STAGE_FOREGROUND,
-  BROWSER_INITIALIZATION_STAGE_TYPE_COUNT,
-};
-
 // This protocol defines the startup method for the application.
 @protocol BrowserLauncher<NSObject>
 
 // Cached launchOptions from AppState's -didFinishLaunchingWithOptions.
 @property(nonatomic, retain) NSDictionary* launchOptions;
 
-// Highest initialization stage reached by the browser.
-@property(nonatomic, readonly)
-    BrowserInitializationStageType browserInitializationStage;
-
 // Browser view information created during startup.
 @property(nonatomic, readonly) id<BrowserInterfaceProvider> interfaceProvider;
 
-// Initializes the application up to |stage|. This is safe to call multiple
-// times for the same value of |stage|; the actions for each stage will only
-// be run once during the lifetime of the app.
-- (void)startUpBrowserToStage:(BrowserInitializationStageType)stage;
-
 @end
 
 #endif  // IOS_CHROME_APP_APPLICATION_DELEGATE_BROWSER_LAUNCHER_H_
diff --git a/ios/chrome/app/main_application_delegate.mm b/ios/chrome/app/main_application_delegate.mm
index c5e7473..733324b 100644
--- a/ios/chrome/app/main_application_delegate.mm
+++ b/ios/chrome/app/main_application_delegate.mm
@@ -334,9 +334,7 @@
     continueUserActivity:(NSUserActivity*)userActivity
       restorationHandler:
           (void (^)(NSArray<id<UIUserActivityRestoring>>*))restorationHandler {
-  if (_appState.initStage <= InitStageSafeMode ||
-      _browserLauncher.browserInitializationStage <
-          INITIALIZATION_STAGE_FOREGROUND)
+  if (_appState.initStage < InitStageBrowserObjectsForUI)
     return NO;
 
   BOOL applicationIsActive =
@@ -355,9 +353,7 @@
 - (void)application:(UIApplication*)application
     performActionForShortcutItem:(UIApplicationShortcutItem*)shortcutItem
                completionHandler:(void (^)(BOOL succeeded))completionHandler {
-  if (_appState.initStage <= InitStageSafeMode ||
-      _browserLauncher.browserInitializationStage <
-          INITIALIZATION_STAGE_FOREGROUND)
+  if (_appState.initStage < InitStageBrowserObjectsForUI)
     return;
 
   [UserActivityHandler
@@ -378,9 +374,7 @@
 - (BOOL)application:(UIApplication*)application
             openURL:(NSURL*)url
             options:(NSDictionary<NSString*, id>*)options {
-  if (_appState.initStage <= InitStageSafeMode ||
-      _browserLauncher.browserInitializationStage <
-          INITIALIZATION_STAGE_FOREGROUND)
+  if (_appState.initStage < InitStageBrowserObjectsForUI)
     return NO;
 
   if (ios::GetChromeBrowserProvider()
diff --git a/ios/chrome/app/main_controller.mm b/ios/chrome/app/main_controller.mm
index 244fa518..3385054 100644
--- a/ios/chrome/app/main_controller.mm
+++ b/ios/chrome/app/main_controller.mm
@@ -338,17 +338,13 @@
 - (void)crashIfRequested;
 // Performs synchronous browser state initialization steps.
 - (void)initializeBrowserState:(ChromeBrowserState*)browserState;
-// Helper methods to initialize the application to a specific stage.
-// Setting |_browserInitializationStage| to a specific stage requires the
-// corresponding function to return YES.
 // Initializes the application to the minimum initialization needed in all
 // cases.
 - (void)startUpBrowserBasicInitialization;
-// Initializes the application to INITIALIZATION_STAGE_BACKGROUND, which is
-// needed by background handlers.
+//  Initializes the browser objects for the background handlers.
 - (void)startUpBrowserBackgroundInitialization;
-// Initializes the application to INITIALIZATION_STAGE_FOREGROUND, which is
-// needed when application runs in foreground.
+// Initializes the browser objects for the browser UI (e.g., the browser
+// state).
 - (void)startUpBrowserForegroundInitialization;
 @end
 
@@ -359,7 +355,6 @@
 // Defined by public protocols.
 // - BrowserLauncher
 @synthesize launchOptions = _launchOptions;
-@synthesize browserInitializationStage = _browserInitializationStage;
 // - StartupInformation
 @synthesize isColdStart = _isColdStart;
 @synthesize appLaunchTime = _appLaunchTime;
@@ -377,25 +372,6 @@
   [NSObject cancelPreviousPerformRequestsWithTarget:self];
 }
 
-// This function starts up to only what is needed at each stage of the
-// initialization. It is possible to continue initialization later.
-- (void)startUpBrowserToStage:(BrowserInitializationStageType)stage {
-  if (_browserInitializationStage < INITIALIZATION_STAGE_BACKGROUND &&
-      stage >= INITIALIZATION_STAGE_BACKGROUND) {
-    [self startUpBrowserBackgroundInitialization];
-    _browserInitializationStage = INITIALIZATION_STAGE_BACKGROUND;
-  }
-
-  if (_browserInitializationStage < INITIALIZATION_STAGE_FOREGROUND &&
-      stage >= INITIALIZATION_STAGE_FOREGROUND) {
-    // When adding a new initialization flow, consider setting
-    // |_appState.userInteracted| at the appropriate time.
-    DCHECK(_appState.userInteracted);
-    [self startUpBrowserForegroundInitialization];
-    _browserInitializationStage = INITIALIZATION_STAGE_FOREGROUND;
-  }
-}
-
 - (void)startUpBrowserBasicInitialization {
   _appLaunchTime = IOSChromeMain::StartTime();
   _isColdStart = YES;
@@ -617,6 +593,17 @@
     case InitStageSafeMode:
       [self addPostSafeModeAgents];
       break;
+    case InitStageBrowserObjectsForBackgroundHandlers:
+      [self startUpBrowserBackgroundInitialization];
+      [appState queueTransitionToNextInitStage];
+      break;
+    case InitStageBrowserObjectsForUI:
+      // When adding a new initialization flow, consider setting
+      // |_appState.userInteracted| at the appropriate time.
+      DCHECK(_appState.userInteracted);
+      [self startUpBrowserForegroundInitialization];
+      [appState queueTransitionToNextInitStage];
+      break;
     case InitStageFinal:
       break;
   }
diff --git a/ios/chrome/app/safe_mode_app_state_agent.mm b/ios/chrome/app/safe_mode_app_state_agent.mm
index ccb41542..f3b92265 100644
--- a/ios/chrome/app/safe_mode_app_state_agent.mm
+++ b/ios/chrome/app/safe_mode_app_state_agent.mm
@@ -91,13 +91,13 @@
   if (self.appState.initStage != InitStageSafeMode) {
     return;
   }
-    // Iterate further in the init stages when safe mode isn't needed; stop
-    // and switch the app to safe mode otherwise.
-    if ([SafeModeCoordinator shouldStart]) {
-      return;
-    }
+  // Iterate further in the init stages when safe mode isn't needed; stop
+  // and switch the app to safe mode otherwise.
+  if ([SafeModeCoordinator shouldStart]) {
+    return;
+  }
 
-    [self.appState queueTransitionToNextInitStage];
+  [self.appState queueTransitionToNextInitStage];
 }
 
 - (void)appState:(AppState*)appState sceneConnected:(SceneState*)sceneState {
diff --git a/ios/chrome/browser/crash_report/breadcrumbs/application_breadcrumbs_logger.h b/ios/chrome/browser/crash_report/breadcrumbs/application_breadcrumbs_logger.h
index f6c3bee..3d824ec 100644
--- a/ios/chrome/browser/crash_report/breadcrumbs/application_breadcrumbs_logger.h
+++ b/ios/chrome/browser/crash_report/breadcrumbs/application_breadcrumbs_logger.h
@@ -12,6 +12,7 @@
 
 #include "base/memory/memory_pressure_listener.h"
 #include "base/metrics/user_metrics.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class TimeTicks;
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/infobar_overlay_browser_agent.mm b/ios/chrome/browser/infobars/overlays/browser_agent/infobar_overlay_browser_agent.mm
index c1849dd..1aa6038d 100644
--- a/ios/chrome/browser/infobars/overlays/browser_agent/infobar_overlay_browser_agent.mm
+++ b/ios/chrome/browser/infobars/overlays/browser_agent/infobar_overlay_browser_agent.mm
@@ -33,14 +33,8 @@
   // installer is gauranteed to be non-null.
   AddInstaller(interaction_handler->CreateBannerCallbackInstaller(),
                OverlayModality::kInfobarBanner);
-  // Add the detail sheet and modal installers.  Not all InfobarTypes support
-  // sheet and modal UI, so the installers must be checked before being added.
-  std::unique_ptr<OverlayRequestCallbackInstaller> detail_sheet_installer =
-      interaction_handler->CreateDetailSheetCallbackInstaller();
-  if (detail_sheet_installer) {
-    AddInstaller(std::move(detail_sheet_installer),
-                 OverlayModality::kInfobarModal);
-  }
+  // Add the modal installers.  Not all InfobarTypes support modal UI, so the
+  // installer must be checked before being added.
   std::unique_ptr<OverlayRequestCallbackInstaller> modal_installer =
       interaction_handler->CreateModalCallbackInstaller();
   if (modal_installer) {
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/infobar_overlay_browser_agent_unittest.mm b/ios/chrome/browser/infobars/overlays/browser_agent/infobar_overlay_browser_agent_unittest.mm
index 55e0b63..1e62cfb8 100644
--- a/ios/chrome/browser/infobars/overlays/browser_agent/infobar_overlay_browser_agent_unittest.mm
+++ b/ios/chrome/browser/infobars/overlays/browser_agent/infobar_overlay_browser_agent_unittest.mm
@@ -83,9 +83,6 @@
         InfobarOverlayType::kBanner,
         FakeInfobarOverlayRequestSupport(InfobarOverlayType::kBanner));
     request_supports_.emplace(
-        InfobarOverlayType::kDetailSheet,
-        FakeInfobarOverlayRequestSupport(InfobarOverlayType::kDetailSheet));
-    request_supports_.emplace(
         InfobarOverlayType::kModal,
         FakeInfobarOverlayRequestSupport(InfobarOverlayType::kModal));
     // Create the interaction handler and set up the mock handlers to return
@@ -94,10 +91,6 @@
         interaction_handler_builder_.Build();
     EXPECT_CALL(*mock_handler(InfobarOverlayType::kBanner), CreateInstaller())
         .WillOnce(Return(ByMove(CreateInstaller(InfobarOverlayType::kBanner))));
-    EXPECT_CALL(*mock_handler(InfobarOverlayType::kDetailSheet),
-                CreateInstaller())
-        .WillOnce(
-            Return(ByMove(CreateInstaller(InfobarOverlayType::kDetailSheet))));
     EXPECT_CALL(*mock_handler(InfobarOverlayType::kModal), CreateInstaller())
         .WillOnce(Return(ByMove(CreateInstaller(InfobarOverlayType::kModal))));
     // Set up the browser agent and mock interaction handler.
@@ -200,5 +193,4 @@
 INSTANTIATE_TEST_SUITE_P(/* No InstantiationName */,
                          InfobarOverlayBrowserAgentTest,
                          testing::Values(InfobarOverlayType::kBanner,
-                                         InfobarOverlayType::kDetailSheet,
                                          InfobarOverlayType::kModal));
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/autofill_address_profile/save_address_profile_infobar_interaction_handler.mm b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/autofill_address_profile/save_address_profile_infobar_interaction_handler.mm
index c16328b..601340c3 100644
--- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/autofill_address_profile/save_address_profile_infobar_interaction_handler.mm
+++ b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/autofill_address_profile/save_address_profile_infobar_interaction_handler.mm
@@ -17,7 +17,6 @@
     : InfobarInteractionHandler(
           InfobarType::kInfobarTypeSaveAutofillAddressProfile,
           std::make_unique<SaveAddressProfileInfobarBannerInteractionHandler>(),
-          /*sheet_handler=*/nullptr,
           std::make_unique<
               SaveAddressProfileInfobarModalInteractionHandler>()) {}
 
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/confirm/confirm_infobar_interaction_handler.mm b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/confirm/confirm_infobar_interaction_handler.mm
index cff7e734..fd57161 100644
--- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/confirm/confirm_infobar_interaction_handler.mm
+++ b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/confirm/confirm_infobar_interaction_handler.mm
@@ -15,7 +15,6 @@
     : InfobarInteractionHandler(
           InfobarType::kInfobarTypeConfirm,
           std::make_unique<ConfirmInfobarBannerInteractionHandler>(),
-          /*sheet_handler=*/nullptr,
           /*modal_handler=*/nullptr) {}
 
 ConfirmInfobarInteractionHandler::~ConfirmInfobarInteractionHandler() = default;
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/infobar_interaction_handler.h b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/infobar_interaction_handler.h
index a35a3f7e..827a0aa 100644
--- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/infobar_interaction_handler.h
+++ b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/infobar_interaction_handler.h
@@ -37,11 +37,10 @@
 
   // Constructor for an InfobarInteractionHandler that uses the provided
   // handlers for each InfobarOverlayType.  |banner_handler| must be non-null.
-  // |detail_sheet_handler| and |modal_handler| may be null if their
-  // corresponding InfobarOverlayTypes are not supported for |infobar_type|.
+  // |modal_handler| may be null if its corresponding InfobarOverlayType is not
+  // supported for |infobar_type|.
   InfobarInteractionHandler(InfobarType infobar_type,
                             std::unique_ptr<Handler> banner_handler,
-                            std::unique_ptr<Handler> detail_sheet_handler,
                             std::unique_ptr<Handler> modal_handler);
   virtual ~InfobarInteractionHandler();
 
@@ -54,12 +53,6 @@
   CreateBannerCallbackInstaller();
 
   // Creates an OverlayRequestCallbackInstaller that handles model-layer updates
-  // the the infobar's detail sheet UI.  Returns null  if detail sheets are not
-  // supported for this InfobarType.
-  std::unique_ptr<OverlayRequestCallbackInstaller>
-  CreateDetailSheetCallbackInstaller();
-
-  // Creates an OverlayRequestCallbackInstaller that handles model-layer updates
   // the the infobar's modal UI.  Returns null  if modals are not
   // supported for this InfobarType.
   std::unique_ptr<OverlayRequestCallbackInstaller>
@@ -76,7 +69,6 @@
   InfobarType infobar_type_;
   // The handlers for each InfobarOverlayType.
   std::unique_ptr<Handler> banner_handler_;
-  std::unique_ptr<Handler> detail_sheet_handler_;
   std::unique_ptr<Handler> modal_handler_;
 };
 
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/infobar_interaction_handler.mm b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/infobar_interaction_handler.mm
index e72e838..3352fe7 100644
--- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/infobar_interaction_handler.mm
+++ b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/infobar_interaction_handler.mm
@@ -13,11 +13,9 @@
 InfobarInteractionHandler::InfobarInteractionHandler(
     InfobarType infobar_type,
     std::unique_ptr<Handler> banner_handler,
-    std::unique_ptr<Handler> detail_sheet_handler,
     std::unique_ptr<Handler> modal_handler)
     : infobar_type_(infobar_type),
       banner_handler_(std::move(banner_handler)),
-      detail_sheet_handler_(std::move(detail_sheet_handler)),
       modal_handler_(std::move(modal_handler)) {
   DCHECK(banner_handler_);
 }
@@ -30,12 +28,6 @@
 }
 
 std::unique_ptr<OverlayRequestCallbackInstaller>
-InfobarInteractionHandler::CreateDetailSheetCallbackInstaller() {
-  return detail_sheet_handler_ ? detail_sheet_handler_->CreateInstaller()
-                               : nullptr;
-}
-
-std::unique_ptr<OverlayRequestCallbackInstaller>
 InfobarInteractionHandler::CreateModalCallbackInstaller() {
   return modal_handler_ ? modal_handler_->CreateInstaller() : nullptr;
 }
@@ -49,9 +41,6 @@
     case InfobarOverlayType::kBanner:
       handler = banner_handler_.get();
       break;
-    case InfobarOverlayType::kDetailSheet:
-      handler = detail_sheet_handler_.get();
-      break;
     case InfobarOverlayType::kModal:
       handler = modal_handler_.get();
       break;
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/passwords/password_infobar_interaction_handler.mm b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/passwords/password_infobar_interaction_handler.mm
index 6027fd8..7397bfe 100644
--- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/passwords/password_infobar_interaction_handler.mm
+++ b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/passwords/password_infobar_interaction_handler.mm
@@ -19,7 +19,6 @@
           InfobarType::kInfobarTypePasswordSave,
           std::make_unique<PasswordInfobarBannerInteractionHandler>(
               SavePasswordInfobarBannerOverlayRequestConfig::RequestSupport()),
-          /*sheet_handler=*/nullptr,
           std::make_unique<PasswordInfobarModalInteractionHandler>(
               browser,
               password_modal::PasswordAction::kSave)) {}
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/passwords/update_password_infobar_interaction_handler.mm b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/passwords/update_password_infobar_interaction_handler.mm
index 869e7f8..51f47e8 100644
--- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/passwords/update_password_infobar_interaction_handler.mm
+++ b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/passwords/update_password_infobar_interaction_handler.mm
@@ -22,7 +22,6 @@
           std::make_unique<PasswordInfobarBannerInteractionHandler>(
               UpdatePasswordInfobarBannerOverlayRequestConfig::
                   RequestSupport()),
-          /*sheet_handler=*/nullptr,
           std::make_unique<PasswordInfobarModalInteractionHandler>(
               browser,
               password_modal::PasswordAction::kUpdate)) {}
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_interaction_handler.mm b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_interaction_handler.mm
index 913e6639..b2b62e76 100644
--- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_interaction_handler.mm
+++ b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_interaction_handler.mm
@@ -16,7 +16,6 @@
     : InfobarInteractionHandler(
           InfobarType::kInfobarTypeSaveCard,
           std::make_unique<SaveCardInfobarBannerInteractionHandler>(),
-          /*sheet_handler=*/nullptr,
           std::make_unique<SaveCardInfobarModalInteractionHandler>()) {}
 
 SaveCardInfobarInteractionHandler::~SaveCardInfobarInteractionHandler() =
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/test/mock_infobar_interaction_handler.mm b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/test/mock_infobar_interaction_handler.mm
index 5896c34f1..f9d0caec 100644
--- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/test/mock_infobar_interaction_handler.mm
+++ b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/test/mock_infobar_interaction_handler.mm
@@ -29,14 +29,10 @@
 
   std::unique_ptr<MockInfobarInteractionHandler::Handler> banner_handler =
       std::make_unique<MockInfobarInteractionHandler::Handler>();
-  std::unique_ptr<MockInfobarInteractionHandler::Handler> sheet_handler =
-      std::make_unique<MockInfobarInteractionHandler::Handler>();
   std::unique_ptr<MockInfobarInteractionHandler::Handler> modal_handler =
       std::make_unique<MockInfobarInteractionHandler::Handler>();
   mock_handlers_[InfobarOverlayType::kBanner] = banner_handler.get();
-  mock_handlers_[InfobarOverlayType::kDetailSheet] = sheet_handler.get();
   mock_handlers_[InfobarOverlayType::kModal] = modal_handler.get();
   return std::make_unique<InfobarInteractionHandler>(
-      infobar_type_, std::move(banner_handler), std::move(sheet_handler),
-      std::move(modal_handler));
+      infobar_type_, std::move(banner_handler), std::move(modal_handler));
 }
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/translate/translate_infobar_interaction_handler.mm b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/translate/translate_infobar_interaction_handler.mm
index 9dd545f..f23fc6ce 100644
--- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/translate/translate_infobar_interaction_handler.mm
+++ b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/translate/translate_infobar_interaction_handler.mm
@@ -21,7 +21,6 @@
     : InfobarInteractionHandler(
           InfobarType::kInfobarTypeTranslate,
           std::make_unique<TranslateInfobarBannerInteractionHandler>(),
-          /*sheet_handler=*/nullptr,
           std::make_unique<TranslateInfobarModalInteractionHandler>()) {}
 
 TranslateInfobarInteractionHandler::~TranslateInfobarInteractionHandler() =
diff --git a/ios/chrome/browser/infobars/overlays/infobar_modal_completion_notifier_unittest.mm b/ios/chrome/browser/infobars/overlays/infobar_modal_completion_notifier_unittest.mm
index f313994b..51048eb4 100644
--- a/ios/chrome/browser/infobars/overlays/infobar_modal_completion_notifier_unittest.mm
+++ b/ios/chrome/browser/infobars/overlays/infobar_modal_completion_notifier_unittest.mm
@@ -57,18 +57,6 @@
 // Tests that the observer is notified when all modal requests for |infobar_|
 // have been removed.
 TEST_F(InfobarModalCompletionNotifierTest, ModalCompletion) {
-  // Add a detail sheet request for |infobar_|.
-  std::unique_ptr<OverlayRequest> detail_sheet_request =
-      OverlayRequest::CreateWithConfig<InfobarOverlayRequestConfig>(
-          &infobar_, InfobarOverlayType::kDetailSheet, false);
-  std::unique_ptr<FakeOverlayRequestCancelHandler>
-      passed_detail_sheet_cancel_handler =
-          std::make_unique<FakeOverlayRequestCancelHandler>(
-              detail_sheet_request.get(), queue());
-  FakeOverlayRequestCancelHandler* detail_sheet_cancel_handler =
-      passed_detail_sheet_cancel_handler.get();
-  queue()->AddRequest(std::move(detail_sheet_request),
-                      std::move(passed_detail_sheet_cancel_handler));
   // Add a modal request for |infobar_|.
   std::unique_ptr<OverlayRequest> modal_request =
       OverlayRequest::CreateWithConfig<InfobarOverlayRequestConfig>(
@@ -81,10 +69,6 @@
   queue()->AddRequest(std::move(modal_request),
                       std::move(passed_modal_cancel_handler));
 
-  // Cancel the detail sheet request, resulting in only a single active request
-  // for |infobar_| in the queue.
-  detail_sheet_cancel_handler->TriggerCancellation();
-
   // Cancel the modal request, expecting that InfobarModalsCompleted() is
   // called.
   EXPECT_CALL(observer_, InfobarModalsCompleted(&notifier_, &infobar_));
diff --git a/ios/chrome/browser/infobars/overlays/infobar_overlay_request_factory_impl.h b/ios/chrome/browser/infobars/overlays/infobar_overlay_request_factory_impl.h
index 3ac5f35..f88078ac 100644
--- a/ios/chrome/browser/infobars/overlays/infobar_overlay_request_factory_impl.h
+++ b/ios/chrome/browser/infobars/overlays/infobar_overlay_request_factory_impl.h
@@ -60,7 +60,6 @@
    public:
     FactoryHelperStorage();
     FactoryHelperStorage(std::unique_ptr<FactoryHelper> banner_factory,
-                         std::unique_ptr<FactoryHelper> detail_sheet_factory,
                          std::unique_ptr<FactoryHelper> modal_factory);
     FactoryHelperStorage(FactoryHelperStorage&& storage);
     ~FactoryHelperStorage();
@@ -83,7 +82,6 @@
   // it to |factory_storages_|.
   void SetUpFactories(InfobarType type,
                       std::unique_ptr<FactoryHelper> banner_factory,
-                      std::unique_ptr<FactoryHelper> detail_sheet_factory,
                       std::unique_ptr<FactoryHelper> modal_factory);
 
   // Map containing the factory storages for each of InfobarType.
diff --git a/ios/chrome/browser/infobars/overlays/infobar_overlay_request_factory_impl.mm b/ios/chrome/browser/infobars/overlays/infobar_overlay_request_factory_impl.mm
index fda9620..be49591 100644
--- a/ios/chrome/browser/infobars/overlays/infobar_overlay_request_factory_impl.mm
+++ b/ios/chrome/browser/infobars/overlays/infobar_overlay_request_factory_impl.mm
@@ -34,28 +34,22 @@
 InfobarOverlayRequestFactoryImpl::InfobarOverlayRequestFactoryImpl() {
   SetUpFactories(InfobarType::kInfobarTypePasswordSave,
                  CreateFactory<SavePasswordInfobarBannerOverlayRequestConfig>(),
-                 /*detail_sheet_factory=*/nullptr,
                  CreateFactory<PasswordInfobarModalOverlayRequestConfig>());
   SetUpFactories(
       InfobarType::kInfobarTypePasswordUpdate,
       CreateFactory<UpdatePasswordInfobarBannerOverlayRequestConfig>(),
-      /*detail_sheet_factory=*/nullptr,
       CreateFactory<PasswordInfobarModalOverlayRequestConfig>());
   SetUpFactories(InfobarType::kInfobarTypeTranslate,
                  CreateFactory<TranslateBannerRequestConfig>(),
-                 /*detail_sheet_factory=*/nullptr,
                  CreateFactory<TranslateModalRequestConfig>());
   SetUpFactories(InfobarType::kInfobarTypeConfirm,
                  CreateFactory<ConfirmBannerRequestConfig>(),
-                 /*detail_sheet_factory=*/nullptr,
                  /*modal_factory=*/nullptr);
   SetUpFactories(InfobarType::kInfobarTypeSaveCard,
                  CreateFactory<SaveCardBannerRequestConfig>(),
-                 /*detail_sheet_factory=*/nullptr,
                  CreateFactory<SaveCardModalRequestConfig>());
   SetUpFactories(InfobarType::kInfobarTypeSaveAutofillAddressProfile,
                  CreateFactory<SaveAddressProfileBannerRequestConfig>(),
-                 /*detail_sheet_factory=*/nullptr,
                  CreateFactory<SaveAddressProfileModalRequestConfig>());
 }
 
@@ -74,11 +68,9 @@
 void InfobarOverlayRequestFactoryImpl::SetUpFactories(
     InfobarType type,
     std::unique_ptr<FactoryHelper> banner_factory,
-    std::unique_ptr<FactoryHelper> detail_sheet_factory,
     std::unique_ptr<FactoryHelper> modal_factory) {
   factory_storages_.emplace(
       type, FactoryHelperStorage(std::move(banner_factory),
-                                 std::move(detail_sheet_factory),
                                  std::move(modal_factory)));
 }
 
@@ -89,11 +81,8 @@
 
 InfobarOverlayRequestFactoryImpl::FactoryHelperStorage::FactoryHelperStorage(
     std::unique_ptr<FactoryHelper> banner_factory,
-    std::unique_ptr<FactoryHelper> detail_sheet_factory,
     std::unique_ptr<FactoryHelper> modal_factory) {
   factories_[InfobarOverlayType::kBanner] = std::move(banner_factory);
-  factories_[InfobarOverlayType::kDetailSheet] =
-      std::move(detail_sheet_factory);
   factories_[InfobarOverlayType::kModal] = std::move(modal_factory);
 }
 
@@ -101,8 +90,6 @@
     InfobarOverlayRequestFactoryImpl::FactoryHelperStorage&& storage) {
   factories_[InfobarOverlayType::kBanner] =
       std::move(storage.factories_[InfobarOverlayType::kBanner]);
-  factories_[InfobarOverlayType::kDetailSheet] =
-      std::move(storage.factories_[InfobarOverlayType::kDetailSheet]);
   factories_[InfobarOverlayType::kModal] =
       std::move(storage.factories_[InfobarOverlayType::kModal]);
 }
diff --git a/ios/chrome/browser/infobars/overlays/infobar_overlay_request_inserter.mm b/ios/chrome/browser/infobars/overlays/infobar_overlay_request_inserter.mm
index b7ec249..e0d55e60 100644
--- a/ios/chrome/browser/infobars/overlays/infobar_overlay_request_inserter.mm
+++ b/ios/chrome/browser/infobars/overlays/infobar_overlay_request_inserter.mm
@@ -50,8 +50,6 @@
   // Populate |queues_| with the request queues at the appropriate modalities.
   queues_[InfobarOverlayType::kBanner] = OverlayRequestQueue::FromWebState(
       web_state_, OverlayModality::kInfobarBanner);
-  queues_[InfobarOverlayType::kDetailSheet] = OverlayRequestQueue::FromWebState(
-      web_state_, OverlayModality::kInfobarModal);
   queues_[InfobarOverlayType::kModal] = OverlayRequestQueue::FromWebState(
       web_state_, OverlayModality::kInfobarModal);
 }
@@ -88,7 +86,6 @@
               request.get(), queue, infobar_ios, this,
               modal_completion_notifier_.get());
       break;
-    case InfobarOverlayType::kDetailSheet:
     case InfobarOverlayType::kModal:
       // Add placeholder request in front of banner queue so no banner get
       // presented behind the modal.
diff --git a/ios/chrome/browser/infobars/overlays/infobar_overlay_type.h b/ios/chrome/browser/infobars/overlays/infobar_overlay_type.h
index 8a93f2a..43612e6 100644
--- a/ios/chrome/browser/infobars/overlays/infobar_overlay_type.h
+++ b/ios/chrome/browser/infobars/overlays/infobar_overlay_type.h
@@ -10,9 +10,6 @@
   // Used to create banner overlays that are displayed in
   // OverlayModality::kInfobarBanner.
   kBanner,
-  // Used to create detail action sheet overlays that are displayed in
-  // OverlayModality::kInfobarModal.
-  kDetailSheet,
   // Used to create modal overlays that are displayed in
   // OverlayModality::kInfobarModal.
   kModal,
diff --git a/ios/chrome/browser/metrics/pageload_foreground_duration_tab_helper.h b/ios/chrome/browser/metrics/pageload_foreground_duration_tab_helper.h
index 048f084e..25bdeab 100644
--- a/ios/chrome/browser/metrics/pageload_foreground_duration_tab_helper.h
+++ b/ios/chrome/browser/metrics/pageload_foreground_duration_tab_helper.h
@@ -5,7 +5,7 @@
 #ifndef IOS_CHROME_BROWSER_METRICS_PAGELOAD_FOREGROUND_DURATION_TAB_HELPER_H_
 #define IOS_CHROME_BROWSER_METRICS_PAGELOAD_FOREGROUND_DURATION_TAB_HELPER_H_
 
-#include "base/scoped_observer.h"
+#include "base/scoped_observation.h"
 #include "base/time/time.h"
 #import "ios/web/public/web_state.h"
 #import "ios/web/public/web_state_observer.h"
@@ -48,7 +48,8 @@
   // WebState reference.
   web::WebState* web_state_ = nullptr;
   // Scoped observer that facilitates observing the WebState.
-  ScopedObserver<web::WebState, WebStateObserver> scoped_observer_;
+  base::ScopedObservation<web::WebState, WebStateObserver> scoped_observation_{
+      this};
   // Holds references to background NSNotification callback observer.
   id foreground_notification_observer_;
   // Holds references to foreground NSNotification callback observer.
diff --git a/ios/chrome/browser/metrics/pageload_foreground_duration_tab_helper.mm b/ios/chrome/browser/metrics/pageload_foreground_duration_tab_helper.mm
index a87d343b..0e18601a 100644
--- a/ios/chrome/browser/metrics/pageload_foreground_duration_tab_helper.mm
+++ b/ios/chrome/browser/metrics/pageload_foreground_duration_tab_helper.mm
@@ -18,9 +18,9 @@
 
 PageloadForegroundDurationTabHelper::PageloadForegroundDurationTabHelper(
     web::WebState* web_state)
-    : web_state_(web_state), scoped_observer_(this) {
+    : web_state_(web_state) {
   DCHECK(web_state);
-  scoped_observer_.Add(web_state);
+  scoped_observation_.Observe(web_state);
   background_notification_observer_ = [[NSNotificationCenter defaultCenter]
       addObserverForName:UIApplicationDidEnterBackgroundNotification
                   object:nil
@@ -115,7 +115,8 @@
     web::WebState* web_state) {
   DCHECK_EQ(web_state_, web_state);
   RecordUkmIfInForeground();
-  scoped_observer_.Remove(web_state);
+  DCHECK(scoped_observation_.IsObservingSource(web_state));
+  scoped_observation_.Reset();
   web_state_ = nullptr;
 }
 
diff --git a/ios/chrome/browser/overlays/public/infobar_modal/save_address_profile_infobar_modal_overlay_request_config.h b/ios/chrome/browser/overlays/public/infobar_modal/save_address_profile_infobar_modal_overlay_request_config.h
index 9df1044..01c8960 100644
--- a/ios/chrome/browser/overlays/public/infobar_modal/save_address_profile_infobar_modal_overlay_request_config.h
+++ b/ios/chrome/browser/overlays/public/infobar_modal/save_address_profile_infobar_modal_overlay_request_config.h
@@ -41,6 +41,11 @@
     return profile_diff_;
   }
 
+  // Prepares and returns a map with key as the autofill::ServerFieldType and
+  // value is the corresponding profile data(NSString*) fetched from the
+  // delegate.
+  NSDictionary* GetProfileInfo();
+
   // Whether the request is for the update address profile modal.
   bool IsUpdateModal() const;
 
diff --git a/ios/chrome/browser/overlays/public/infobar_modal/save_address_profile_infobar_modal_overlay_request_config.mm b/ios/chrome/browser/overlays/public/infobar_modal/save_address_profile_infobar_modal_overlay_request_config.mm
index 5bc2080f..e429186 100644
--- a/ios/chrome/browser/overlays/public/infobar_modal/save_address_profile_infobar_modal_overlay_request_config.mm
+++ b/ios/chrome/browser/overlays/public/infobar_modal/save_address_profile_infobar_modal_overlay_request_config.mm
@@ -65,6 +65,19 @@
   }
 }
 
+NSDictionary* SaveAddressProfileModalRequestConfig::GetProfileInfo() {
+  autofill::AutofillSaveUpdateAddressProfileDelegateIOS* delegate =
+      static_cast<autofill::AutofillSaveUpdateAddressProfileDelegateIOS*>(
+          infobar_->delegate());
+  NSMutableDictionary* items = [[NSMutableDictionary alloc] init];
+  for (const auto& type : GetAutofillTypeForProfileEdit()) {
+    [items setObject:base::SysUTF16ToNSString(delegate->GetProfileInfo(type))
+              forKey:[NSNumber
+                         numberWithInt:AutofillUITypeFromAutofillType(type)]];
+  }
+  return items;
+}
+
 void SaveAddressProfileModalRequestConfig::CreateAuxiliaryData(
     base::SupportsUserData* user_data) {
   InfobarOverlayRequestConfig::CreateForUserData(
diff --git a/ios/chrome/browser/passwords/ios_chrome_password_manager_client.h b/ios/chrome/browser/passwords/ios_chrome_password_manager_client.h
index fc1908f7..1c90ed3 100644
--- a/ios/chrome/browser/passwords/ios_chrome_password_manager_client.h
+++ b/ios/chrome/browser/passwords/ios_chrome_password_manager_client.h
@@ -27,6 +27,7 @@
 #import "ios/web/public/web_state.h"
 #include "ios/web/public/web_state_observer.h"
 #include "services/metrics/public/cpp/ukm_source_id.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class ChromeBrowserState;
 
diff --git a/ios/chrome/browser/reading_list/reading_list_remover_helper.cc b/ios/chrome/browser/reading_list/reading_list_remover_helper.cc
index a23c9189..f50d37b6 100644
--- a/ios/chrome/browser/reading_list/reading_list_remover_helper.cc
+++ b/ios/chrome/browser/reading_list/reading_list_remover_helper.cc
@@ -31,7 +31,8 @@
     const ReadingListModel* reading_list_model) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK_EQ(reading_list_model_, reading_list_model);
-  scoped_observer_.Remove(reading_list_model_);
+  DCHECK(scoped_observation_.IsObservingSource(reading_list_model_));
+  scoped_observation_.Reset();
 
   bool model_cleared = reading_list_model_->DeleteAllEntries();
   reading_list_download_service_->Clear();
@@ -43,7 +44,8 @@
     const ReadingListModel* reading_list_model) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK_EQ(reading_list_model_, reading_list_model);
-  scoped_observer_.Remove(reading_list_model_);
+  DCHECK(scoped_observation_.IsObservingSource(reading_list_model_));
+  scoped_observation_.Reset();
   ReadlingListItemsRemoved(false);
 }
 
@@ -59,7 +61,7 @@
 
   // ReadingListModel::AddObserver calls ReadingListModelLoaded if model is
   // already loaded, so there is no need to check.
-  scoped_observer_.Add(reading_list_model_);
+  scoped_observation_.Observe(reading_list_model_);
 }
 
 void ReadingListRemoverHelper::ReadlingListItemsRemoved(bool success) {
diff --git a/ios/chrome/browser/reading_list/reading_list_remover_helper.h b/ios/chrome/browser/reading_list/reading_list_remover_helper.h
index 14be1345..94477c0 100644
--- a/ios/chrome/browser/reading_list/reading_list_remover_helper.h
+++ b/ios/chrome/browser/reading_list/reading_list_remover_helper.h
@@ -6,7 +6,7 @@
 #define IOS_CHROME_BROWSER_READING_LIST_READING_LIST_REMOVER_HELPER_H_
 
 #include "base/callback.h"
-#include "base/scoped_observer.h"
+#include "base/scoped_observation.h"
 #include "base/sequence_checker.h"
 #include "components/reading_list/core/reading_list_model.h"
 #include "components/reading_list/core/reading_list_model_observer.h"
@@ -41,8 +41,8 @@
   Callback completion_;
   ReadingListModel* reading_list_model_ = nullptr;
   ReadingListDownloadService* reading_list_download_service_ = nullptr;
-  ScopedObserver<ReadingListModel, ReadingListModelObserver> scoped_observer_{
-      this};
+  base::ScopedObservation<ReadingListModel, ReadingListModelObserver>
+      scoped_observation_{this};
 
   SEQUENCE_CHECKER(sequence_checker_);
 
diff --git a/ios/chrome/browser/snapshots/snapshot_tab_helper.h b/ios/chrome/browser/snapshots/snapshot_tab_helper.h
index 3409333..a9d612d 100644
--- a/ios/chrome/browser/snapshots/snapshot_tab_helper.h
+++ b/ios/chrome/browser/snapshots/snapshot_tab_helper.h
@@ -9,7 +9,7 @@
 
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
-#include "base/scoped_observer.h"
+#include "base/scoped_observation.h"
 #include "ios/web/public/web_state_observer.h"
 #import "ios/web/public/web_state_user_data.h"
 
@@ -95,7 +95,8 @@
   SnapshotGenerator* snapshot_generator_ = nil;
 
   // Manages this object as an observer of |web_state_|.
-  ScopedObserver<web::WebState, web::WebStateObserver> web_state_observer_;
+  base::ScopedObservation<web::WebState, web::WebStateObserver>
+      web_state_observation_{this};
 
   bool ignore_next_load_ = false;
 
diff --git a/ios/chrome/browser/snapshots/snapshot_tab_helper.mm b/ios/chrome/browser/snapshots/snapshot_tab_helper.mm
index aea2441..ec80531b 100644
--- a/ios/chrome/browser/snapshots/snapshot_tab_helper.mm
+++ b/ios/chrome/browser/snapshots/snapshot_tab_helper.mm
@@ -112,13 +112,12 @@
 SnapshotTabHelper::SnapshotTabHelper(web::WebState* web_state, NSString* tab_id)
     : web_state_(web_state),
       tab_id_([tab_id copy]),
-      web_state_observer_(this),
       weak_ptr_factory_(this) {
   DCHECK(web_state_);
   DCHECK(tab_id_.length > 0);
   snapshot_generator_ = [[SnapshotGenerator alloc] initWithWebState:web_state_
                                                               tabID:tab_id_];
-  web_state_observer_.Add(web_state_);
+  web_state_observation_.Observe(web_state_);
 }
 
 void SnapshotTabHelper::PageLoaded(
@@ -174,7 +173,8 @@
 
 void SnapshotTabHelper::WebStateDestroyed(web::WebState* web_state) {
   DCHECK_EQ(web_state_, web_state);
-  web_state_observer_.Remove(web_state);
+  DCHECK(web_state_observation_.IsObservingSource(web_state));
+  web_state_observation_.Reset();
   web_state_ = nullptr;
   tab_id_ = nil;
 }
diff --git a/ios/chrome/browser/sync/ios_trusted_vault_client.mm b/ios/chrome/browser/sync/ios_trusted_vault_client.mm
index 5aa9932..23e0c3b 100644
--- a/ios/chrome/browser/sync/ios_trusted_vault_client.mm
+++ b/ios/chrome/browser/sync/ios_trusted_vault_client.mm
@@ -76,8 +76,17 @@
 void IOSTrustedVaultClient::GetIsRecoverabilityDegraded(
     const CoreAccountInfo& account_info,
     base::OnceCallback<void(bool)> callback) {
-  // TODO(crbug.com/1100278): Needs implementation.
-  std::move(callback).Run(false);
+  ios::ChromeBrowserProvider* browser_provider =
+      ios::GetChromeBrowserProvider();
+  ios::ChromeIdentityService* identity_service =
+      browser_provider->GetChromeIdentityService();
+  ChromeIdentity* identity =
+      identity_service->GetIdentityWithGaiaID(account_info.gaia);
+  ios::ChromeTrustedVaultService* trusted_vault_service =
+      browser_provider->GetChromeTrustedVaultService();
+  DCHECK(trusted_vault_service);
+  trusted_vault_service->GetIsRecoverabilityDegraded(identity,
+                                                     std::move(callback));
 }
 
 void IOSTrustedVaultClient::AddTrustedRecoveryMethod(
diff --git a/ios/chrome/browser/ui/autofill/autofill_ui_type_util.h b/ios/chrome/browser/ui/autofill/autofill_ui_type_util.h
index c370309..ec59dd10 100644
--- a/ios/chrome/browser/ui/autofill/autofill_ui_type_util.h
+++ b/ios/chrome/browser/ui/autofill/autofill_ui_type_util.h
@@ -5,8 +5,47 @@
 #ifndef IOS_CHROME_BROWSER_UI_AUTOFILL_AUTOFILL_UI_TYPE_UTIL_H_
 #define IOS_CHROME_BROWSER_UI_AUTOFILL_AUTOFILL_UI_TYPE_UTIL_H_
 
+#import <Foundation/Foundation.h>
+#import <UIKit/UIKit.h>
+
 #include "components/autofill/core/browser/field_types.h"
 #import "ios/chrome/browser/ui/autofill/autofill_ui_type.h"
+#include "ios/chrome/grit/ios_strings.h"
+
+// Defines types for the fields that are used by the edit profile screens.
+struct AutofillProfileFieldDisplayInfo {
+  autofill::ServerFieldType autofillType;
+  int displayStringID;
+  UIReturnKeyType returnKeyType;
+  UIKeyboardType keyboardType;
+  UITextAutocapitalizationType autoCapitalizationType;
+};
+
+// Stores info for the fields that are used in the edit profile screens.
+static const AutofillProfileFieldDisplayInfo kProfileFieldsToDisplay[] = {
+    {autofill::NAME_HONORIFIC_PREFIX, IDS_IOS_AUTOFILL_HONORIFIC_PREFIX,
+     UIReturnKeyNext, UIKeyboardTypeDefault,
+     UITextAutocapitalizationTypeSentences},
+    {autofill::NAME_FULL, IDS_IOS_AUTOFILL_FULLNAME, UIReturnKeyNext,
+     UIKeyboardTypeDefault, UITextAutocapitalizationTypeSentences},
+    {autofill::COMPANY_NAME, IDS_IOS_AUTOFILL_COMPANY_NAME, UIReturnKeyNext,
+     UIKeyboardTypeDefault, UITextAutocapitalizationTypeSentences},
+    {autofill::ADDRESS_HOME_LINE1, IDS_IOS_AUTOFILL_ADDRESS1, UIReturnKeyNext,
+     UIKeyboardTypeDefault, UITextAutocapitalizationTypeSentences},
+    {autofill::ADDRESS_HOME_LINE2, IDS_IOS_AUTOFILL_ADDRESS2, UIReturnKeyNext,
+     UIKeyboardTypeDefault, UITextAutocapitalizationTypeSentences},
+    {autofill::ADDRESS_HOME_CITY, IDS_IOS_AUTOFILL_CITY, UIReturnKeyNext,
+     UIKeyboardTypeDefault, UITextAutocapitalizationTypeSentences},
+    {autofill::ADDRESS_HOME_STATE, IDS_IOS_AUTOFILL_STATE, UIReturnKeyNext,
+     UIKeyboardTypeDefault, UITextAutocapitalizationTypeSentences},
+    {autofill::ADDRESS_HOME_ZIP, IDS_IOS_AUTOFILL_ZIP, UIReturnKeyNext,
+     UIKeyboardTypeDefault, UITextAutocapitalizationTypeAllCharacters},
+    {autofill::ADDRESS_HOME_COUNTRY, IDS_IOS_AUTOFILL_COUNTRY, UIReturnKeyNext,
+     UIKeyboardTypeDefault, UITextAutocapitalizationTypeSentences},
+    {autofill::PHONE_HOME_WHOLE_NUMBER, IDS_IOS_AUTOFILL_PHONE, UIReturnKeyNext,
+     UIKeyboardTypePhonePad, UITextAutocapitalizationTypeSentences},
+    {autofill::EMAIL_ADDRESS, IDS_IOS_AUTOFILL_EMAIL, UIReturnKeyDone,
+     UIKeyboardTypeEmailAddress, UITextAutocapitalizationTypeNone}};
 
 // Returns the AutofillUIType equivalent to |type|.
 AutofillUIType AutofillUITypeFromAutofillType(autofill::ServerFieldType type);
@@ -14,4 +53,8 @@
 // Returns the autofill::ServerFieldType equivalent to |type|.
 autofill::ServerFieldType AutofillTypeFromAutofillUIType(AutofillUIType type);
 
+// Returns the list of autofill::ServerFieldType used by the edit profile
+// screens.
+std::vector<autofill::ServerFieldType> GetAutofillTypeForProfileEdit();
+
 #endif  // IOS_CHROME_BROWSER_UI_AUTOFILL_AUTOFILL_UI_TYPE_UTIL_H_
diff --git a/ios/chrome/browser/ui/autofill/autofill_ui_type_util.mm b/ios/chrome/browser/ui/autofill/autofill_ui_type_util.mm
index 23c9131f..4dd5943f 100644
--- a/ios/chrome/browser/ui/autofill/autofill_ui_type_util.mm
+++ b/ios/chrome/browser/ui/autofill/autofill_ui_type_util.mm
@@ -108,3 +108,11 @@
       return autofill::UNKNOWN_TYPE;
   }
 }
+
+std::vector<autofill::ServerFieldType> GetAutofillTypeForProfileEdit() {
+  std::vector<autofill::ServerFieldType> all_visible_types;
+  for (const AutofillProfileFieldDisplayInfo& row : kProfileFieldsToDisplay)
+    all_visible_types.push_back(row.autofillType);
+
+  return all_visible_types;
+}
diff --git a/ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_coordinator.mm b/ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_coordinator.mm
index 17a45a7..744149e 100644
--- a/ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_coordinator.mm
+++ b/ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_coordinator.mm
@@ -44,6 +44,7 @@
   if (self) {
     self.baseViewController = viewController;
     self.browser = browser;
+    self.shouldUseDefaultDismissal = NO;
   }
   return self;
 }
diff --git a/ios/chrome/browser/ui/first_run/first_run_coordinator.h b/ios/chrome/browser/ui/first_run/first_run_coordinator.h
index b7544fe..0c359045 100644
--- a/ios/chrome/browser/ui/first_run/first_run_coordinator.h
+++ b/ios/chrome/browser/ui/first_run/first_run_coordinator.h
@@ -8,6 +8,7 @@
 #import "ios/chrome/browser/ui/coordinators/chrome_coordinator.h"
 
 @class FirstRunScreenProvider;
+@protocol SyncPresenter;
 
 // The delegate for the FirstRunCoordinator.
 @protocol FirstRunCoordinatorDelegate <NSObject>
@@ -24,10 +25,12 @@
 // Coordinator to present first run screens.
 @interface FirstRunCoordinator : ChromeCoordinator
 
-// Initiate the coordinator.|screenProvider| will help decide which screen to
-// show.
+// Initiate the coordinator.
+// |syncPresenter| helps present sync related UI.
+// |screenProvider| helps decide which screen to show.
 - (instancetype)initWithBaseViewController:(UIViewController*)viewController
                                    browser:(Browser*)browser
+                             syncPresenter:(id<SyncPresenter>)presenter
                             screenProvider:
                                 (FirstRunScreenProvider*)screenProvider
     NS_DESIGNATED_INITIALIZER;
diff --git a/ios/chrome/browser/ui/first_run/first_run_coordinator.mm b/ios/chrome/browser/ui/first_run/first_run_coordinator.mm
index 7970756a..8e87f98 100644
--- a/ios/chrome/browser/ui/first_run/first_run_coordinator.mm
+++ b/ios/chrome/browser/ui/first_run/first_run_coordinator.mm
@@ -9,6 +9,7 @@
 #import "base/metrics/histogram_functions.h"
 #include "base/notreached.h"
 #include "ios/chrome/browser/first_run/first_run_metrics.h"
+#include "ios/chrome/browser/main/browser.h"
 #import "ios/chrome/browser/ui/first_run/first_run_screen_delegate.h"
 #import "ios/chrome/browser/ui/first_run/first_run_screen_provider.h"
 #import "ios/chrome/browser/ui/first_run/first_run_screen_type.h"
@@ -16,6 +17,8 @@
 #import "ios/chrome/browser/ui/first_run/signin/signin_screen_coordinator.h"
 #import "ios/chrome/browser/ui/first_run/sync/sync_screen_coordinator.h"
 #import "ios/chrome/browser/ui/first_run/welcome/welcome_screen_coordinator.h"
+#import "ios/chrome/browser/ui/settings/sync/utils/sync_util.h"
+#import "ios/chrome/browser/web_state_list/web_state_list.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
@@ -28,6 +31,8 @@
 @property(nonatomic, strong) UINavigationController* navigationController;
 // Whether the remaining screens have been skipped.
 @property(nonatomic, assign) BOOL screensSkipped;
+// Presenter for showing sync-related UI.
+@property(nonatomic, readonly, weak) id<SyncPresenter> presenter;
 
 @end
 
@@ -35,10 +40,12 @@
 
 - (instancetype)initWithBaseViewController:(UIViewController*)viewController
                                    browser:(Browser*)browser
+                             syncPresenter:(id<SyncPresenter>)presenter
                             screenProvider:
                                 (FirstRunScreenProvider*)screenProvider {
   self = [super initWithBaseViewController:viewController browser:browser];
   if (self) {
+    _presenter = presenter;
     _screenProvider = screenProvider;
     _navigationController =
         [[UINavigationController alloc] initWithNavigationBarClass:nil
@@ -63,6 +70,12 @@
   void (^completion)(void) = ^{
     base::UmaHistogramEnumeration("FirstRun.Stage", first_run::kComplete);
     WriteFirstRunSentinel();
+    // Display the sync errors infobar.
+    web::WebState* webState =
+        self.browser->GetWebStateList()->GetActiveWebState();
+    DisplaySyncErrors(self.browser->GetBrowserState(), webState,
+                      self.presenter);
+
     // If the remaining screens have been skipped, additional actions will be
     // executed.
     [self.delegate didFinishPresentingScreensWithSubsequentActionsTriggered:
diff --git a/ios/chrome/browser/ui/first_run/first_run_screen_view_controller.h b/ios/chrome/browser/ui/first_run/first_run_screen_view_controller.h
index 7cd1e90..9dacd41 100644
--- a/ios/chrome/browser/ui/first_run/first_run_screen_view_controller.h
+++ b/ios/chrome/browser/ui/first_run/first_run_screen_view_controller.h
@@ -51,10 +51,6 @@
 // NO.
 @property(nonatomic, assign) BOOL scrollToEndMandatory;
 
-// When set to YES, the screen can be dismissed by the user by swiping the view
-// down. Defaults to NO. Has no effect on iOS 12.
-@property(nonatomic, assign) BOOL canDismissScreen;
-
 // YES if an unified button style applies to all buttons.
 @property(nonatomic, assign) BOOL unifiedButtonStyle;
 
diff --git a/ios/chrome/browser/ui/first_run/first_run_screen_view_controller.mm b/ios/chrome/browser/ui/first_run/first_run_screen_view_controller.mm
index 874c237..68580225 100644
--- a/ios/chrome/browser/ui/first_run/first_run_screen_view_controller.mm
+++ b/ios/chrome/browser/ui/first_run/first_run_screen_view_controller.mm
@@ -65,10 +65,6 @@
 - (void)viewDidLoad {
   [super viewDidLoad];
 
-  if (@available(iOS 13, *)) {
-    self.modalInPresentation = !self.canDismissScreen;
-  }
-
   self.view.backgroundColor = [UIColor colorNamed:kBackgroundColor];
 
   // Create a layout guide for the margin between the subtitle and the screen-
@@ -308,6 +304,8 @@
   });
 }
 
+#pragma mark - Setter
+
 - (void)setPrimaryActionString:(NSString*)text {
   _primaryActionString = text;
   // Change the button's label, unless scrolling to the end is mandatory and the
diff --git a/ios/chrome/browser/ui/first_run/signin/signin_screen_coordinator.mm b/ios/chrome/browser/ui/first_run/signin/signin_screen_coordinator.mm
index 8e7d41ff..22021c0 100644
--- a/ios/chrome/browser/ui/first_run/signin/signin_screen_coordinator.mm
+++ b/ios/chrome/browser/ui/first_run/signin/signin_screen_coordinator.mm
@@ -100,6 +100,9 @@
   BOOL animated = self.baseNavigationController.topViewController != nil;
   [self.baseNavigationController setViewControllers:@[ self.viewController ]
                                            animated:animated];
+  if (@available(iOS 13, *)) {
+    self.viewController.modalInPresentation = YES;
+  }
 }
 
 - (void)stop {
diff --git a/ios/chrome/browser/ui/first_run/sync/sync_screen_coordinator.mm b/ios/chrome/browser/ui/first_run/sync/sync_screen_coordinator.mm
index 95a89bb..8fafed14 100644
--- a/ios/chrome/browser/ui/first_run/sync/sync_screen_coordinator.mm
+++ b/ios/chrome/browser/ui/first_run/sync/sync_screen_coordinator.mm
@@ -80,10 +80,12 @@
   BOOL animated = self.baseNavigationController.topViewController != nil;
   [self.baseNavigationController setViewControllers:@[ self.viewController ]
                                            animated:animated];
+  if (@available(iOS 13, *)) {
+    self.viewController.modalInPresentation = YES;
+  }
 }
 
 - (void)stop {
-  // TODO(crbug.com/1189840): Display the sync errors infobar.
   self.delegate = nil;
   self.viewController = nil;
   self.mediator = nil;
diff --git a/ios/chrome/browser/ui/first_run/welcome/welcome_screen_coordinator.mm b/ios/chrome/browser/ui/first_run/welcome/welcome_screen_coordinator.mm
index ebf3d52..1e1c87a 100644
--- a/ios/chrome/browser/ui/first_run/welcome/welcome_screen_coordinator.mm
+++ b/ios/chrome/browser/ui/first_run/welcome/welcome_screen_coordinator.mm
@@ -65,6 +65,9 @@
   BOOL animated = self.baseNavigationController.topViewController != nil;
   [self.baseNavigationController setViewControllers:@[ self.viewController ]
                                            animated:animated];
+  if (@available(iOS 13, *)) {
+    self.viewController.modalInPresentation = YES;
+  }
 }
 
 - (void)stop {
diff --git a/ios/chrome/browser/ui/infobars/BUILD.gn b/ios/chrome/browser/ui/infobars/BUILD.gn
index 1b8108b..bcde93a 100644
--- a/ios/chrome/browser/ui/infobars/BUILD.gn
+++ b/ios/chrome/browser/ui/infobars/BUILD.gn
@@ -73,9 +73,13 @@
   ]
   deps = [
     ":public",
+    "resources:infobar_autofill_address_icon",
     "resources:infobar_downloading",
+    "resources:infobar_email_icon",
     "resources:infobar_hide_password_icon",
+    "resources:infobar_phone_icon",
     "resources:infobar_popup_blocker",
+    "resources:infobar_profile_icon",
     "resources:infobar_reveal_password_icon",
     "resources:infobar_save_card_icon",
     "resources:infobar_settings_icon",
diff --git a/ios/chrome/browser/ui/infobars/coordinators/infobar_coordinator.h b/ios/chrome/browser/ui/infobars/coordinators/infobar_coordinator.h
index 0af41cc..8fb47747 100644
--- a/ios/chrome/browser/ui/infobars/coordinators/infobar_coordinator.h
+++ b/ios/chrome/browser/ui/infobars/coordinators/infobar_coordinator.h
@@ -119,6 +119,10 @@
 // etc.
 @property(nonatomic, assign) BOOL highPriorityPresentation;
 
+// If YES, then InfobarCoordinator will handle dismissing any infobar shown.
+// If NO, then the coordinator should handle dismissal itself. Defaults to YES.
+@property(nonatomic, assign) BOOL shouldUseDefaultDismissal;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_INFOBARS_COORDINATORS_INFOBAR_COORDINATOR_H_
diff --git a/ios/chrome/browser/ui/infobars/coordinators/infobar_coordinator.mm b/ios/chrome/browser/ui/infobars/coordinators/infobar_coordinator.mm
index 6318512..e57f99f1 100644
--- a/ios/chrome/browser/ui/infobars/coordinators/infobar_coordinator.mm
+++ b/ios/chrome/browser/ui/infobars/coordinators/infobar_coordinator.mm
@@ -82,6 +82,7 @@
     _presented = YES;
     _hasBadge = badgeSupport;
     _infobarType = infobarType;
+    _shouldUseDefaultDismissal = YES;
   }
   return self;
 }
@@ -153,7 +154,7 @@
                  }];
 
   // Dismisses the presented banner after a certain number of seconds.
-  if (!UIAccessibilityIsVoiceOverRunning()) {
+  if (!UIAccessibilityIsVoiceOverRunning() && self.shouldUseDefaultDismissal) {
     NSTimeInterval timeInterval =
         self.highPriorityPresentation
             ? kInfobarBannerLongPresentationDurationInSeconds
diff --git a/ios/chrome/browser/ui/infobars/modals/BUILD.gn b/ios/chrome/browser/ui/infobars/modals/BUILD.gn
index 0fd4366..552ebc3 100644
--- a/ios/chrome/browser/ui/infobars/modals/BUILD.gn
+++ b/ios/chrome/browser/ui/infobars/modals/BUILD.gn
@@ -5,6 +5,9 @@
 source_set("modals") {
   configs += [ "//build/config/compiler:enable_arc" ]
   sources = [
+    "infobar_edit_address_profile_modal_consumer.h",
+    "infobar_edit_address_profile_table_view_controller.h",
+    "infobar_edit_address_profile_table_view_controller.mm",
     "infobar_modal_delegate.h",
     "infobar_modal_view_controller.h",
     "infobar_modal_view_controller.mm",
@@ -30,12 +33,15 @@
   deps = [
     ":public",
     "//base",
+    "//components/autofill/core/common:features",
     "//components/translate/core/browser",
     "//ios/chrome/app/strings:ios_strings_grit",
     "//ios/chrome/browser/infobars:public",
     "//ios/chrome/browser/passwords:public",
     "//ios/chrome/browser/ui/autofill:autofill_message",
     "//ios/chrome/browser/ui/autofill:autofill_metrics",
+    "//ios/chrome/browser/ui/autofill:autofill_ui_type",
+    "//ios/chrome/browser/ui/autofill/cells",
     "//ios/chrome/browser/ui/infobars/coordinators:translate_public",
     "//ios/chrome/browser/ui/table_view",
     "//ios/chrome/browser/ui/table_view:styler",
@@ -59,7 +65,10 @@
 source_set("unit_tests") {
   configs += [ "//build/config/compiler:enable_arc" ]
   testonly = true
-  sources = [ "infobar_save_address_profile_table_view_controller_unittest.mm" ]
+  sources = [
+    "infobar_edit_address_profile_table_view_controller_unittest.mm",
+    "infobar_save_address_profile_table_view_controller_unittest.mm",
+  ]
   deps = [
     ":modals",
     "//base/test:test_support",
diff --git a/ios/chrome/browser/ui/infobars/modals/infobar_edit_address_profile_modal_consumer.h b/ios/chrome/browser/ui/infobars/modals/infobar_edit_address_profile_modal_consumer.h
new file mode 100644
index 0000000..e85a64612
--- /dev/null
+++ b/ios/chrome/browser/ui/infobars/modals/infobar_edit_address_profile_modal_consumer.h
@@ -0,0 +1,18 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_UI_INFOBARS_MODALS_INFOBAR_EDIT_ADDRESS_PROFILE_MODAL_CONSUMER_H_
+#define IOS_CHROME_BROWSER_UI_INFOBARS_MODALS_INFOBAR_EDIT_ADDRESS_PROFILE_MODAL_CONSUMER_H_
+
+#import <Foundation/Foundation.h>
+
+// Consumer for model to push configurations to the EDITAddressProfile UI.
+@protocol InfobarEditAddressProfileModalConsumer <NSObject>
+
+// Informs the consumer of the data.
+- (void)setupModalViewControllerWithData:(NSDictionary*)data;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_INFOBARS_MODALS_INFOBAR_EDIT_ADDRESS_PROFILE_MODAL_CONSUMER_H_
diff --git a/ios/chrome/browser/ui/infobars/modals/infobar_edit_address_profile_table_view_controller.h b/ios/chrome/browser/ui/infobars/modals/infobar_edit_address_profile_table_view_controller.h
new file mode 100644
index 0000000..4bc432f
--- /dev/null
+++ b/ios/chrome/browser/ui/infobars/modals/infobar_edit_address_profile_table_view_controller.h
@@ -0,0 +1,22 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_UI_INFOBARS_MODALS_INFOBAR_EDIT_ADDRESS_PROFILE_TABLE_VIEW_CONTROLLER_H_
+#define IOS_CHROME_BROWSER_UI_INFOBARS_MODALS_INFOBAR_EDIT_ADDRESS_PROFILE_TABLE_VIEW_CONTROLLER_H_
+
+#import "ios/chrome/browser/ui/infobars/modals/infobar_edit_address_profile_modal_consumer.h"
+#import "ios/chrome/browser/ui/table_view/chrome_table_view_controller.h"
+
+@protocol InfobarSaveAddressProfileModalDelegate;
+
+// The TableView for an Autofill save/update address edit menu.
+@interface InfobarEditAddressProfileTableViewController
+    : ChromeTableViewController <InfobarEditAddressProfileModalConsumer>
+
+- (instancetype)initWithModalDelegate:
+    (id<InfobarSaveAddressProfileModalDelegate>)delegate;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_INFOBARS_MODALS_INFOBAR_EDIT_ADDRESS_PROFILE_TABLE_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/infobars/modals/infobar_edit_address_profile_table_view_controller.mm b/ios/chrome/browser/ui/infobars/modals/infobar_edit_address_profile_table_view_controller.mm
new file mode 100644
index 0000000..e97fc9f
--- /dev/null
+++ b/ios/chrome/browser/ui/infobars/modals/infobar_edit_address_profile_table_view_controller.mm
@@ -0,0 +1,186 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/ui/infobars/modals/infobar_edit_address_profile_table_view_controller.h"
+
+#include "base/mac/foundation_util.h"
+#include "base/stl_util.h"
+#include "components/autofill/core/common/autofill_features.h"
+#import "ios/chrome/browser/ui/autofill/autofill_ui_type.h"
+#import "ios/chrome/browser/ui/autofill/autofill_ui_type_util.h"
+#import "ios/chrome/browser/ui/autofill/cells/autofill_edit_item.h"
+#import "ios/chrome/browser/ui/infobars/modals/infobar_save_address_profile_modal_delegate.h"
+#import "ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h"
+#import "ios/chrome/browser/ui/table_view/cells/table_view_text_button_item.h"
+#import "ios/chrome/browser/ui/table_view/cells/table_view_text_edit_item.h"
+#import "ios/chrome/browser/ui/table_view/cells/table_view_text_edit_item_delegate.h"
+#import "ios/chrome/browser/ui/table_view/chrome_table_view_styler.h"
+#import "ios/chrome/common/ui/colors/semantic_color_names.h"
+#include "ios/chrome/grit/ios_strings.h"
+#include "ui/base/l10n/l10n_util_mac.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace {
+using ::AutofillTypeFromAutofillUIType;
+using ::AutofillUITypeFromAutofillType;
+
+typedef NS_ENUM(NSInteger, SectionIdentifier) {
+  SectionIdentifierFields = kSectionIdentifierEnumZero,
+};
+
+typedef NS_ENUM(NSInteger, ItemType) {
+  ItemTypeTextField = kItemTypeEnumZero,
+  ItemTypeSaveButton,
+};
+
+}  // namespace
+
+@interface InfobarEditAddressProfileTableViewController () <UITextFieldDelegate>
+
+// The delegate passed to this instance.
+@property(nonatomic, weak) id<InfobarSaveAddressProfileModalDelegate> delegate;
+
+// All the data to be displayed in the edit dialog.
+@property(nonatomic, strong) NSMutableDictionary* profileData;
+
+@end
+
+@implementation InfobarEditAddressProfileTableViewController
+
+#pragma mark - Initialization
+
+- (instancetype)initWithModalDelegate:
+    (id<InfobarSaveAddressProfileModalDelegate>)modalDelegate {
+  self = [super initWithStyle:UITableViewStylePlain];
+  if (self) {
+    _delegate = modalDelegate;
+  }
+  return self;
+}
+
+#pragma mark - ViewController Lifecycle
+
+- (void)viewDidLoad {
+  [super viewDidLoad];
+
+  self.view.backgroundColor = [UIColor colorNamed:kBackgroundColor];
+  self.styler.cellBackgroundColor = [UIColor colorNamed:kBackgroundColor];
+  self.tableView.sectionHeaderHeight = 0;
+  self.tableView.estimatedRowHeight = 56;
+
+  [self.tableView
+      setSeparatorInset:UIEdgeInsetsMake(0, kTableViewHorizontalSpacing, 0, 0)];
+
+  // Configure the NavigationBar.
+  UIBarButtonItem* cancelButton = [[UIBarButtonItem alloc]
+      initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
+                           target:self
+                           action:@selector(handleCancelButton)];
+
+  self.navigationItem.leftBarButtonItem = cancelButton;
+  self.navigationController.navigationBar.prefersLargeTitles = NO;
+
+  // TODO(crbug.com/1167062): Replace with proper localized string.
+  self.navigationItem.title = @"Test Edit Address";
+
+  self.tableView.allowsSelectionDuringEditing = YES;
+
+  [self loadModel];
+}
+
+#pragma mark - TableViewModel
+
+- (void)loadModel {
+  [super loadModel];
+  TableViewModel* model = self.tableViewModel;
+
+  [model addSectionWithIdentifier:SectionIdentifierFields];
+  for (const AutofillProfileFieldDisplayInfo& field : kProfileFieldsToDisplay) {
+    if (field.autofillType == autofill::NAME_HONORIFIC_PREFIX &&
+        !base::FeatureList::IsEnabled(
+            autofill::features::kAutofillEnableSupportForHonorificPrefixes)) {
+      continue;
+    }
+
+    AutofillEditItem* item =
+        [[AutofillEditItem alloc] initWithType:ItemTypeTextField];
+    item.textFieldName = l10n_util::GetNSString(field.displayStringID);
+    item.autofillUIType = AutofillUITypeFromAutofillType(field.autofillType);
+    item.textFieldValue = _profileData[@(item.autofillUIType)];
+    item.textFieldEnabled = YES;
+    item.hideIcon = NO;
+    item.autoCapitalizationType = field.autoCapitalizationType;
+    item.returnKeyType = field.returnKeyType;
+    item.keyboardType = field.keyboardType;
+    [model addItem:item toSectionWithIdentifier:SectionIdentifierFields];
+  }
+
+  TableViewTextButtonItem* saveButton =
+      [[TableViewTextButtonItem alloc] initWithType:ItemTypeSaveButton];
+  saveButton.textAlignment = NSTextAlignmentNatural;
+  // TODO(crbug.com/1167062): Replace with proper localized string.
+  saveButton.buttonText = @"Test Save";
+  saveButton.disableButtonIntrinsicWidth = YES;
+  [model addItem:saveButton toSectionWithIdentifier:SectionIdentifierFields];
+}
+
+#pragma mark - UITableViewDataSource
+
+- (UITableViewCell*)tableView:(UITableView*)tableView
+        cellForRowAtIndexPath:(NSIndexPath*)indexPath {
+  UITableViewCell* cell = [super tableView:tableView
+                     cellForRowAtIndexPath:indexPath];
+  NSInteger itemType = [self.tableViewModel itemTypeForIndexPath:indexPath];
+
+  if (itemType == ItemTypeTextField) {
+    TableViewTextEditCell* editCell =
+        base::mac::ObjCCastStrict<TableViewTextEditCell>(cell);
+    editCell.textField.delegate = self;
+    editCell.selectionStyle = UITableViewCellSelectionStyleNone;
+  } else if (itemType == ItemTypeSaveButton) {
+    TableViewTextButtonCell* tableViewTextButtonCell =
+        base::mac::ObjCCastStrict<TableViewTextButtonCell>(cell);
+    [tableViewTextButtonCell.button addTarget:self
+                                       action:@selector(didTapSaveButton)
+                             forControlEvents:UIControlEventTouchUpInside];
+  }
+
+  return cell;
+}
+
+#pragma mark - InfobarEditAddressProfileModalConsumer
+
+- (void)setupModalViewControllerWithData:(NSDictionary*)data {
+  self.profileData = [NSMutableDictionary dictionaryWithDictionary:data];
+  [self.tableView reloadData];
+}
+
+#pragma mark - UITableViewDelegate
+
+- (CGFloat)tableView:(UITableView*)tableView
+    heightForFooterInSection:(NSInteger)section {
+  return 0;
+}
+
+#pragma mark - UITextFieldDelegate
+
+- (BOOL)textFieldShouldReturn:(UITextField*)textField {
+  [textField resignFirstResponder];
+  return YES;
+}
+
+#pragma mark - Actions
+
+- (void)handleCancelButton {
+  // TODO(crbug.com/1167062):  Implement the functionality.
+}
+
+- (void)didTapSaveButton {
+  // TODO(crbug.com/1167062):  Implement the functionality.
+}
+
+@end
diff --git a/ios/chrome/browser/ui/infobars/modals/infobar_edit_address_profile_table_view_controller_unittest.mm b/ios/chrome/browser/ui/infobars/modals/infobar_edit_address_profile_table_view_controller_unittest.mm
new file mode 100644
index 0000000..7026be47
--- /dev/null
+++ b/ios/chrome/browser/ui/infobars/modals/infobar_edit_address_profile_table_view_controller_unittest.mm
@@ -0,0 +1,43 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/ui/infobars/modals/infobar_edit_address_profile_table_view_controller.h"
+
+#include "base/mac/foundation_util.h"
+#import "ios/chrome/browser/ui/infobars/modals/infobar_save_address_profile_modal_delegate.h"
+#import "ios/chrome/browser/ui/table_view/chrome_table_view_controller_test.h"
+#include "testing/gtest_mac.h"
+
+#import "third_party/ocmock/OCMock/OCMock.h"
+#include "third_party/ocmock/gtest_support.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+// Test fixture for testing InfobarEditAddressProfileTableViewController class.
+class InfobarEditAddressProfileTableViewControllerTest
+    : public ChromeTableViewControllerTest {
+ protected:
+  InfobarEditAddressProfileTableViewControllerTest()
+      : delegate_(OCMProtocolMock(
+            @protocol(InfobarSaveAddressProfileModalDelegate))) {}
+
+  ChromeTableViewController* InstantiateController() override {
+    return [[InfobarEditAddressProfileTableViewController alloc]
+        initWithModalDelegate:delegate_];
+  }
+
+  id delegate_;
+};
+
+// Tests that the edit modal has been initialized.
+TEST_F(InfobarEditAddressProfileTableViewControllerTest,
+       TestEditModalInitialization) {
+  CreateController();
+  CheckController();
+
+  EXPECT_EQ(1, NumberOfSections());
+  EXPECT_EQ(11, NumberOfItemsInSection(0));
+}
diff --git a/ios/chrome/browser/ui/infobars/modals/infobar_save_address_profile_modal_delegate.h b/ios/chrome/browser/ui/infobars/modals/infobar_save_address_profile_modal_delegate.h
index 5b0c87f..b5a900a1 100644
--- a/ios/chrome/browser/ui/infobars/modals/infobar_save_address_profile_modal_delegate.h
+++ b/ios/chrome/browser/ui/infobars/modals/infobar_save_address_profile_modal_delegate.h
@@ -12,9 +12,8 @@
 // Delegate to handle Save Address Profile Infobar Modal actions.
 @protocol InfobarSaveAddressProfileModalDelegate <InfobarModalDelegate>
 
-// Dismisses the InfobarModal with no animation, then presents the Address
-// Profile Settings screen modally.
-- (void)presentAddressProfileSettings;
+// Presents the edit View.
+- (void)showEditView;
 
 @end
 
diff --git a/ios/chrome/browser/ui/infobars/modals/infobar_save_address_profile_table_view_controller.mm b/ios/chrome/browser/ui/infobars/modals/infobar_save_address_profile_table_view_controller.mm
index ed99b1b..95cfc06c 100644
--- a/ios/chrome/browser/ui/infobars/modals/infobar_save_address_profile_table_view_controller.mm
+++ b/ios/chrome/browser/ui/infobars/modals/infobar_save_address_profile_table_view_controller.mm
@@ -238,7 +238,7 @@
 }
 
 - (void)showEditAddressProfileModal {
-  // TODO(crbug.com/1167062): Show edit view.
+  [self.saveAddressProfileModalDelegate showEditView];
 }
 
 - (void)loadUpdateAddressModal {
diff --git a/ios/chrome/browser/ui/infobars/resources/BUILD.gn b/ios/chrome/browser/ui/infobars/resources/BUILD.gn
index 60b4ef7..00115e7 100644
--- a/ios/chrome/browser/ui/infobars/resources/BUILD.gn
+++ b/ios/chrome/browser/ui/infobars/resources/BUILD.gn
@@ -71,3 +71,35 @@
     "infobar_save_card_icon.imageset/infobar_save_card_icon@3x.png",
   ]
 }
+
+imageset("infobar_autofill_address_icon") {
+  sources = [
+    "infobar_autofill_address_icon.imageset/Contents.json",
+    "infobar_autofill_address_icon.imageset/infobar_autofill_address_icon@2x.png",
+    "infobar_autofill_address_icon.imageset/infobar_autofill_address_icon@3x.png",
+  ]
+}
+
+imageset("infobar_email_icon") {
+  sources = [
+    "infobar_email_icon.imageset/Contents.json",
+    "infobar_email_icon.imageset/infobar_email_icon@2x.png",
+    "infobar_email_icon.imageset/infobar_email_icon@3x.png",
+  ]
+}
+
+imageset("infobar_phone_icon") {
+  sources = [
+    "infobar_phone_icon.imageset/Contents.json",
+    "infobar_phone_icon.imageset/infobar_phone_icon@2x.png",
+    "infobar_phone_icon.imageset/infobar_phone_icon@3x.png",
+  ]
+}
+
+imageset("infobar_profile_icon") {
+  sources = [
+    "infobar_profile_icon.imageset/Contents.json",
+    "infobar_profile_icon.imageset/infobar_profile_icon@2x.png",
+    "infobar_profile_icon.imageset/infobar_profile_icon@3x.png",
+  ]
+}
diff --git a/ios/chrome/browser/ui/infobars/resources/infobar_autofill_address_icon.imageset/Contents.json b/ios/chrome/browser/ui/infobars/resources/infobar_autofill_address_icon.imageset/Contents.json
new file mode 100644
index 0000000..428ad28
--- /dev/null
+++ b/ios/chrome/browser/ui/infobars/resources/infobar_autofill_address_icon.imageset/Contents.json
@@ -0,0 +1,18 @@
+{
+    "images": [
+        {
+            "idiom": "universal",
+            "scale": "2x",
+            "filename": "infobar_autofill_address_icon@2x.png"
+        },
+        {
+            "idiom": "universal",
+            "scale": "3x",
+            "filename": "infobar_autofill_address_icon@3x.png"
+        }
+    ],
+    "info": {
+        "version": 1,
+        "author": "xcode"
+    }
+}
diff --git a/ios/chrome/browser/ui/infobars/resources/infobar_autofill_address_icon.imageset/infobar_autofill_address_icon@2x.png b/ios/chrome/browser/ui/infobars/resources/infobar_autofill_address_icon.imageset/infobar_autofill_address_icon@2x.png
new file mode 100644
index 0000000..b63c3f71
--- /dev/null
+++ b/ios/chrome/browser/ui/infobars/resources/infobar_autofill_address_icon.imageset/infobar_autofill_address_icon@2x.png
Binary files differ
diff --git a/ios/chrome/browser/ui/infobars/resources/infobar_autofill_address_icon.imageset/infobar_autofill_address_icon@3x.png b/ios/chrome/browser/ui/infobars/resources/infobar_autofill_address_icon.imageset/infobar_autofill_address_icon@3x.png
new file mode 100644
index 0000000..f731298f
--- /dev/null
+++ b/ios/chrome/browser/ui/infobars/resources/infobar_autofill_address_icon.imageset/infobar_autofill_address_icon@3x.png
Binary files differ
diff --git a/ios/chrome/browser/ui/infobars/resources/infobar_email_icon.imageset/Contents.json b/ios/chrome/browser/ui/infobars/resources/infobar_email_icon.imageset/Contents.json
new file mode 100644
index 0000000..2caeaae2
--- /dev/null
+++ b/ios/chrome/browser/ui/infobars/resources/infobar_email_icon.imageset/Contents.json
@@ -0,0 +1,18 @@
+{
+    "images": [
+        {
+            "idiom": "universal",
+            "scale": "2x",
+            "filename": "infobar_email_icon@2x.png"
+        },
+        {
+            "idiom": "universal",
+            "scale": "3x",
+            "filename": "infobar_email_icon@3x.png"
+        }
+    ],
+    "info": {
+        "version": 1,
+        "author": "xcode"
+    }
+}
diff --git a/ios/chrome/browser/ui/infobars/resources/infobar_email_icon.imageset/infobar_email_icon@2x.png b/ios/chrome/browser/ui/infobars/resources/infobar_email_icon.imageset/infobar_email_icon@2x.png
new file mode 100644
index 0000000..b271ea11
--- /dev/null
+++ b/ios/chrome/browser/ui/infobars/resources/infobar_email_icon.imageset/infobar_email_icon@2x.png
Binary files differ
diff --git a/ios/chrome/browser/ui/infobars/resources/infobar_email_icon.imageset/infobar_email_icon@3x.png b/ios/chrome/browser/ui/infobars/resources/infobar_email_icon.imageset/infobar_email_icon@3x.png
new file mode 100644
index 0000000..87b9ca5
--- /dev/null
+++ b/ios/chrome/browser/ui/infobars/resources/infobar_email_icon.imageset/infobar_email_icon@3x.png
Binary files differ
diff --git a/ios/chrome/browser/ui/infobars/resources/infobar_phone_icon.imageset/Contents.json b/ios/chrome/browser/ui/infobars/resources/infobar_phone_icon.imageset/Contents.json
new file mode 100644
index 0000000..248e0206
--- /dev/null
+++ b/ios/chrome/browser/ui/infobars/resources/infobar_phone_icon.imageset/Contents.json
@@ -0,0 +1,18 @@
+{
+    "images": [
+        {
+            "idiom": "universal",
+            "scale": "2x",
+            "filename": "infobar_phone_icon@2x.png"
+        },
+        {
+            "idiom": "universal",
+            "scale": "3x",
+            "filename": "infobar_phone_icon@3x.png"
+        }
+    ],
+    "info": {
+        "version": 1,
+        "author": "xcode"
+    }
+}
diff --git a/ios/chrome/browser/ui/infobars/resources/infobar_phone_icon.imageset/infobar_phone_icon@2x.png b/ios/chrome/browser/ui/infobars/resources/infobar_phone_icon.imageset/infobar_phone_icon@2x.png
new file mode 100644
index 0000000..4ce77c0
--- /dev/null
+++ b/ios/chrome/browser/ui/infobars/resources/infobar_phone_icon.imageset/infobar_phone_icon@2x.png
Binary files differ
diff --git a/ios/chrome/browser/ui/infobars/resources/infobar_phone_icon.imageset/infobar_phone_icon@3x.png b/ios/chrome/browser/ui/infobars/resources/infobar_phone_icon.imageset/infobar_phone_icon@3x.png
new file mode 100644
index 0000000..c667649
--- /dev/null
+++ b/ios/chrome/browser/ui/infobars/resources/infobar_phone_icon.imageset/infobar_phone_icon@3x.png
Binary files differ
diff --git a/ios/chrome/browser/ui/infobars/resources/infobar_profile_icon.imageset/Contents.json b/ios/chrome/browser/ui/infobars/resources/infobar_profile_icon.imageset/Contents.json
new file mode 100644
index 0000000..281146e6
--- /dev/null
+++ b/ios/chrome/browser/ui/infobars/resources/infobar_profile_icon.imageset/Contents.json
@@ -0,0 +1,18 @@
+{
+    "images": [
+        {
+            "idiom": "universal",
+            "scale": "2x",
+            "filename": "infobar_profile_icon@2x.png"
+        },
+        {
+            "idiom": "universal",
+            "scale": "3x",
+            "filename": "infobar_profile_icon@3x.png"
+        }
+    ],
+    "info": {
+        "version": 1,
+        "author": "xcode"
+    }
+}
diff --git a/ios/chrome/browser/ui/infobars/resources/infobar_profile_icon.imageset/infobar_profile_icon@2x.png b/ios/chrome/browser/ui/infobars/resources/infobar_profile_icon.imageset/infobar_profile_icon@2x.png
new file mode 100644
index 0000000..26c7a05
--- /dev/null
+++ b/ios/chrome/browser/ui/infobars/resources/infobar_profile_icon.imageset/infobar_profile_icon@2x.png
Binary files differ
diff --git a/ios/chrome/browser/ui/infobars/resources/infobar_profile_icon.imageset/infobar_profile_icon@3x.png b/ios/chrome/browser/ui/infobars/resources/infobar_profile_icon.imageset/infobar_profile_icon@3x.png
new file mode 100644
index 0000000..2657030
--- /dev/null
+++ b/ios/chrome/browser/ui/infobars/resources/infobar_profile_icon.imageset/infobar_profile_icon@3x.png
Binary files differ
diff --git a/ios/chrome/browser/ui/main/scene_controller.mm b/ios/chrome/browser/ui/main/scene_controller.mm
index 16bb42016..1bf19d6f 100644
--- a/ios/chrome/browser/ui/main/scene_controller.mm
+++ b/ios/chrome/browser/ui/main/scene_controller.mm
@@ -662,7 +662,7 @@
 // in one place.
 - (void)transitionToSceneActivationLevel:(SceneActivationLevel)level
                             appInitStage:(InitStage)appInitStage {
-  if (appInitStage <= InitStageSafeMode) {
+  if (appInitStage < InitStageFinal) {
     // Nothing per-scene should happen before the app completes the global
     // setup, like executing Safe mode, or creating the main BrowserState.
     return;
@@ -1209,6 +1209,7 @@
   self.firstRunCoordinator = [[FirstRunCoordinator alloc]
       initWithBaseViewController:self.mainInterface.bvc
                          browser:self.mainInterface.browser
+                   syncPresenter:self.mainInterface.bvc
                   screenProvider:provider];
   self.firstRunCoordinator.delegate = self;
   self.sceneState.presentingFirstRunUI = YES;
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_view_ios.h b/ios/chrome/browser/ui/omnibox/omnibox_view_ios.h
index d24c74cb..aaa8b7a 100644
--- a/ios/chrome/browser/ui/omnibox/omnibox_view_ios.h
+++ b/ios/chrome/browser/ui/omnibox/omnibox_view_ios.h
@@ -16,6 +16,7 @@
 #import "ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.h"
 #include "ios/chrome/browser/ui/omnibox/popup/omnibox_popup_provider.h"
 #import "ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_suggestions_delegate.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class AutocompleteResult;
 class ChromeBrowserState;
diff --git a/ios/chrome/browser/ui/overlays/infobar_modal/autofill_address_profile/BUILD.gn b/ios/chrome/browser/ui/overlays/infobar_modal/autofill_address_profile/BUILD.gn
index 9d00b52..8aa4baac 100644
--- a/ios/chrome/browser/ui/overlays/infobar_modal/autofill_address_profile/BUILD.gn
+++ b/ios/chrome/browser/ui/overlays/infobar_modal/autofill_address_profile/BUILD.gn
@@ -8,6 +8,7 @@
     "save_address_profile_infobar_modal_overlay_coordinator.mm",
     "save_address_profile_infobar_modal_overlay_mediator.h",
     "save_address_profile_infobar_modal_overlay_mediator.mm",
+    "save_address_profile_infobar_modal_overlay_mediator_delegate.h",
   ]
 
   configs += [ "//build/config/compiler:enable_arc" ]
diff --git a/ios/chrome/browser/ui/overlays/infobar_modal/autofill_address_profile/save_address_profile_infobar_modal_overlay_coordinator.h b/ios/chrome/browser/ui/overlays/infobar_modal/autofill_address_profile/save_address_profile_infobar_modal_overlay_coordinator.h
index f5ab126..d606133a 100644
--- a/ios/chrome/browser/ui/overlays/infobar_modal/autofill_address_profile/save_address_profile_infobar_modal_overlay_coordinator.h
+++ b/ios/chrome/browser/ui/overlays/infobar_modal/autofill_address_profile/save_address_profile_infobar_modal_overlay_coordinator.h
@@ -5,6 +5,7 @@
 #ifndef IOS_CHROME_BROWSER_UI_OVERLAYS_INFOBAR_MODAL_AUTOFILL_ADDRESS_PROFILE_SAVE_ADDRESS_PROFILE_INFOBAR_MODAL_OVERLAY_COORDINATOR_H_
 #define IOS_CHROME_BROWSER_UI_OVERLAYS_INFOBAR_MODAL_AUTOFILL_ADDRESS_PROFILE_SAVE_ADDRESS_PROFILE_INFOBAR_MODAL_OVERLAY_COORDINATOR_H_
 
+#import "ios/chrome/browser/ui/overlays/infobar_modal/infobar_modal_overlay_coordinator+modal_configuration.h"
 #import "ios/chrome/browser/ui/overlays/infobar_modal/infobar_modal_overlay_coordinator.h"
 
 // A coordinator that displays the Save Address Profile infobar modal UI using
diff --git a/ios/chrome/browser/ui/overlays/infobar_modal/autofill_address_profile/save_address_profile_infobar_modal_overlay_coordinator.mm b/ios/chrome/browser/ui/overlays/infobar_modal/autofill_address_profile/save_address_profile_infobar_modal_overlay_coordinator.mm
index e09b06cc..babce4ee 100644
--- a/ios/chrome/browser/ui/overlays/infobar_modal/autofill_address_profile/save_address_profile_infobar_modal_overlay_coordinator.mm
+++ b/ios/chrome/browser/ui/overlays/infobar_modal/autofill_address_profile/save_address_profile_infobar_modal_overlay_coordinator.mm
@@ -8,8 +8,10 @@
 #import "ios/chrome/browser/overlays/public/infobar_modal/save_address_profile_infobar_modal_overlay_request_config.h"
 #include "ios/chrome/browser/overlays/public/overlay_callback_manager.h"
 #include "ios/chrome/browser/overlays/public/overlay_response.h"
+#import "ios/chrome/browser/ui/infobars/modals/infobar_edit_address_profile_table_view_controller.h"
 #import "ios/chrome/browser/ui/infobars/modals/infobar_save_address_profile_table_view_controller.h"
 #import "ios/chrome/browser/ui/overlays/infobar_modal/autofill_address_profile/save_address_profile_infobar_modal_overlay_mediator.h"
+#import "ios/chrome/browser/ui/overlays/infobar_modal/autofill_address_profile/save_address_profile_infobar_modal_overlay_mediator_delegate.h"
 #import "ios/chrome/browser/ui/overlays/infobar_modal/infobar_modal_overlay_coordinator+modal_configuration.h"
 #include "ios/chrome/grit/ios_strings.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -21,7 +23,8 @@
 using autofill_address_profile_infobar_overlays::
     SaveAddressProfileModalRequestConfig;
 
-@interface SaveAddressProfileInfobarModalOverlayCoordinator ()
+@interface SaveAddressProfileInfobarModalOverlayCoordinator () <
+    SaveAddressProfileInfobarModalOverlayMediatorDelegate>
 // Redefine ModalConfiguration properties as readwrite.
 @property(nonatomic, strong, readwrite) OverlayRequestMediator* modalMediator;
 @property(nonatomic, strong, readwrite) UIViewController* modalViewController;
@@ -46,6 +49,38 @@
   return SaveAddressProfileModalRequestConfig::RequestSupport();
 }
 
+#pragma mark - SaveAddressProfileInfobarModalOverlayMediatorDelegate
+
+- (void)showEditView {
+  [self.baseViewController
+      dismissViewControllerAnimated:YES
+                         completion:^{
+                           // Shows Edit View Controller.
+                           [self onSaveUpdateViewDismissed];
+                         }];
+}
+
+#pragma mark - Private
+
+- (void)onSaveUpdateViewDismissed {
+  SaveAddressProfileInfobarModalOverlayMediator* modalMediator =
+      static_cast<SaveAddressProfileInfobarModalOverlayMediator*>(
+          self.modalMediator);
+  InfobarEditAddressProfileTableViewController* editModalViewController =
+      [[InfobarEditAddressProfileTableViewController alloc]
+          initWithModalDelegate:modalMediator];
+
+  modalMediator.editAddressConsumer = editModalViewController;
+  self.modalMediator = modalMediator;
+  self.modalViewController = editModalViewController;
+
+  [self configureViewController];
+
+  [self.baseViewController presentViewController:self.viewController
+                                        animated:YES
+                                      completion:nil];
+}
+
 @end
 
 @implementation
@@ -61,6 +96,7 @@
       [[InfobarSaveAddressProfileTableViewController alloc]
           initWithModalDelegate:modalMediator];
   modalMediator.consumer = modalViewController;
+  modalMediator.saveAddressProfileMediatorDelegate = self;
   self.modalMediator = modalMediator;
   self.modalViewController = modalViewController;
 }
diff --git a/ios/chrome/browser/ui/overlays/infobar_modal/autofill_address_profile/save_address_profile_infobar_modal_overlay_mediator.h b/ios/chrome/browser/ui/overlays/infobar_modal/autofill_address_profile/save_address_profile_infobar_modal_overlay_mediator.h
index 4c8afd9..ab4ba33 100644
--- a/ios/chrome/browser/ui/overlays/infobar_modal/autofill_address_profile/save_address_profile_infobar_modal_overlay_mediator.h
+++ b/ios/chrome/browser/ui/overlays/infobar_modal/autofill_address_profile/save_address_profile_infobar_modal_overlay_mediator.h
@@ -8,7 +8,9 @@
 #import "ios/chrome/browser/ui/overlays/infobar_modal/infobar_modal_overlay_mediator.h"
 
 #import "ios/chrome/browser/ui/infobars/modals/infobar_save_address_profile_modal_delegate.h"
+#import "ios/chrome/browser/ui/overlays/infobar_modal/autofill_address_profile/save_address_profile_infobar_modal_overlay_mediator_delegate.h"
 
+@protocol InfobarEditAddressProfileModalConsumer;
 @protocol InfobarSaveAddressProfileModalConsumer;
 
 // Mediator that configures the modal UI for save address profile infobar.
@@ -19,6 +21,15 @@
 // configures the new consumer.
 @property(nonatomic) id<InfobarSaveAddressProfileModalConsumer> consumer;
 
+// The consumer that is configured by this mediator for the edit address
+// profile.
+@property(nonatomic) id<InfobarEditAddressProfileModalConsumer>
+    editAddressConsumer;
+
+// Delegate to communicate user actions to change the UI presentation.
+@property(nonatomic) id<SaveAddressProfileInfobarModalOverlayMediatorDelegate>
+    saveAddressProfileMediatorDelegate;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_OVERLAYS_INFOBAR_MODAL_AUTOFILL_ADDRESS_PROFILE_SAVE_ADDRESS_PROFILE_INFOBAR_MODAL_OVERLAY_MEDIATOR_H_
diff --git a/ios/chrome/browser/ui/overlays/infobar_modal/autofill_address_profile/save_address_profile_infobar_modal_overlay_mediator.mm b/ios/chrome/browser/ui/overlays/infobar_modal/autofill_address_profile/save_address_profile_infobar_modal_overlay_mediator.mm
index 421cef42..040576a 100644
--- a/ios/chrome/browser/ui/overlays/infobar_modal/autofill_address_profile/save_address_profile_infobar_modal_overlay_mediator.mm
+++ b/ios/chrome/browser/ui/overlays/infobar_modal/autofill_address_profile/save_address_profile_infobar_modal_overlay_mediator.mm
@@ -6,7 +6,7 @@
 
 #include "base/strings/sys_string_conversions.h"
 #import "ios/chrome/browser/overlays/public/infobar_modal/save_address_profile_infobar_modal_overlay_request_config.h"
-#import "ios/chrome/browser/overlays/public/infobar_modal/save_address_profile_infobar_modal_overlay_responses.h"
+#import "ios/chrome/browser/ui/infobars/modals/infobar_edit_address_profile_modal_consumer.h"
 #import "ios/chrome/browser/ui/infobars/modals/infobar_save_address_profile_modal_consumer.h"
 #import "ios/chrome/browser/ui/overlays/infobar_modal/infobar_modal_overlay_coordinator+modal_configuration.h"
 #import "ios/chrome/browser/ui/overlays/overlay_request_mediator+subclassing.h"
@@ -18,8 +18,6 @@
 
 using autofill_address_profile_infobar_overlays::
     SaveAddressProfileModalRequestConfig;
-using save_address_profile_infobar_modal_responses::
-    PresentAddressProfileSettings;
 
 @interface SaveAddressProfileInfobarModalOverlayMediator ()
 // The save address profile modal config from the request.
@@ -62,6 +60,21 @@
   [_consumer setupModalViewControllerWithPrefs:prefs];
 }
 
+- (void)setEditAddressConsumer:
+    (id<InfobarEditAddressProfileModalConsumer>)editAddressConsumer {
+  if (_editAddressConsumer == editAddressConsumer)
+    return;
+
+  _editAddressConsumer = editAddressConsumer;
+
+  SaveAddressProfileModalRequestConfig* config = self.config;
+  if (!_editAddressConsumer || !config)
+    return;
+
+  [_editAddressConsumer
+      setupModalViewControllerWithData:config->GetProfileInfo()];
+}
+
 #pragma mark - OverlayRequestMediator
 
 + (const OverlayRequestSupport*)requestSupport {
@@ -70,16 +83,11 @@
 
 #pragma mark - InfobarSaveAddressProfileModalDelegate
 
-- (void)presentAddressProfileSettings {
-  // Receiving this delegate callback when the request is null means that the
-  // present address profile settings button was tapped after the request was
-  // cancelled, but before the modal UI has finished being dismissed.
-  if (!self.request)
+- (void)showEditView {
+  if (!self.request) {
     return;
-
-  [self dispatchResponse:OverlayResponse::CreateWithInfo<
-                             PresentAddressProfileSettings>()];
-  [self dismissInfobarModal:nil];
+  }
+  [self.saveAddressProfileMediatorDelegate showEditView];
 }
 
 @end
diff --git a/ios/chrome/browser/ui/overlays/infobar_modal/autofill_address_profile/save_address_profile_infobar_modal_overlay_mediator_delegate.h b/ios/chrome/browser/ui/overlays/infobar_modal/autofill_address_profile/save_address_profile_infobar_modal_overlay_mediator_delegate.h
new file mode 100644
index 0000000..4333a44
--- /dev/null
+++ b/ios/chrome/browser/ui/overlays/infobar_modal/autofill_address_profile/save_address_profile_infobar_modal_overlay_mediator_delegate.h
@@ -0,0 +1,17 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_UI_OVERLAYS_INFOBAR_MODAL_AUTOFILL_ADDRESS_PROFILE_SAVE_ADDRESS_PROFILE_INFOBAR_MODAL_OVERLAY_MEDIATOR_DELEGATE_H_
+#define IOS_CHROME_BROWSER_UI_OVERLAYS_INFOBAR_MODAL_AUTOFILL_ADDRESS_PROFILE_SAVE_ADDRESS_PROFILE_INFOBAR_MODAL_OVERLAY_MEDIATOR_DELEGATE_H_
+
+// Delegate to communicate modal user actions to show options to change
+// languages.
+@protocol SaveAddressProfileInfobarModalOverlayMediatorDelegate
+
+// Indicates the user chose to edit on the Save/Update modal.
+- (void)showEditView;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_OVERLAYS_INFOBAR_MODAL_AUTOFILL_ADDRESS_PROFILE_SAVE_ADDRESS_PROFILE_INFOBAR_MODAL_OVERLAY_MEDIATOR_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/overlays/infobar_modal/infobar_modal_overlay_coordinator+modal_configuration.h b/ios/chrome/browser/ui/overlays/infobar_modal/infobar_modal_overlay_coordinator+modal_configuration.h
index 21e18c2..b919c12a7 100644
--- a/ios/chrome/browser/ui/overlays/infobar_modal/infobar_modal_overlay_coordinator+modal_configuration.h
+++ b/ios/chrome/browser/ui/overlays/infobar_modal/infobar_modal_overlay_coordinator+modal_configuration.h
@@ -28,6 +28,10 @@
 // Resets |modalViewController| and |modalMediator| to the new instances.
 - (void)configureModal;
 
+// Resets |modalTransitionDriver| and |modalNavController|. Reassigns |mediator|
+// to |modalMediator|.
+- (void)configureViewController;
+
 // Resets |modalMediator| and |modalViewController|.
 - (void)resetModal;
 
diff --git a/ios/chrome/browser/ui/overlays/infobar_modal/infobar_modal_overlay_coordinator.mm b/ios/chrome/browser/ui/overlays/infobar_modal/infobar_modal_overlay_coordinator.mm
index d8af6ba..d6b0acfe 100644
--- a/ios/chrome/browser/ui/overlays/infobar_modal/infobar_modal_overlay_coordinator.mm
+++ b/ios/chrome/browser/ui/overlays/infobar_modal/infobar_modal_overlay_coordinator.mm
@@ -33,14 +33,7 @@
   if (self.started || !self.request)
     return;
   [self configureModal];
-  self.mediator = self.modalMediator;
-  self.modalTransitionDriver = [[InfobarModalTransitionDriver alloc]
-      initWithTransitionMode:InfobarModalTransitionBase];
-  self.modalTransitionDriver.modalPositioner = self;
-  self.modalNavController = [[UINavigationController alloc]
-      initWithRootViewController:self.modalViewController];
-  self.modalNavController.modalPresentationStyle = UIModalPresentationCustom;
-  self.modalNavController.transitioningDelegate = self.modalTransitionDriver;
+  [self configureViewController];
   [self.baseViewController presentViewController:self.viewController
                                         animated:animated
                                       completion:^{
@@ -122,6 +115,17 @@
   NOTREACHED() << "Subclasses implement.";
 }
 
+- (void)configureViewController {
+  self.mediator = self.modalMediator;
+  self.modalTransitionDriver = [[InfobarModalTransitionDriver alloc]
+      initWithTransitionMode:InfobarModalTransitionBase];
+  self.modalTransitionDriver.modalPositioner = self;
+  self.modalNavController = [[UINavigationController alloc]
+      initWithRootViewController:self.modalViewController];
+  self.modalNavController.modalPresentationStyle = UIModalPresentationCustom;
+  self.modalNavController.transitioningDelegate = self.modalTransitionDriver;
+}
+
 - (void)resetModal {
   NOTREACHED() << "Subclasses implement.";
 }
diff --git a/ios/chrome/browser/ui/overlays/overlay_presentation_context_fullscreen_disabler.h b/ios/chrome/browser/ui/overlays/overlay_presentation_context_fullscreen_disabler.h
index d78c512..6313342 100644
--- a/ios/chrome/browser/ui/overlays/overlay_presentation_context_fullscreen_disabler.h
+++ b/ios/chrome/browser/ui/overlays/overlay_presentation_context_fullscreen_disabler.h
@@ -7,7 +7,7 @@
 
 #include <memory>
 
-#include "base/scoped_observer.h"
+#include "base/scoped_observation.h"
 #import "ios/chrome/browser/overlays/public/overlay_modality.h"
 #import "ios/chrome/browser/overlays/public/overlay_presenter.h"
 #import "ios/chrome/browser/overlays/public/overlay_presenter_observer.h"
@@ -48,7 +48,8 @@
     FullscreenController* fullscreen_controller_ = nullptr;
     // The animated disabler.
     std::unique_ptr<AnimatedScopedFullscreenDisabler> disabler_;
-    ScopedObserver<OverlayPresenter, OverlayPresenterObserver> scoped_observer_;
+    base::ScopedObservation<OverlayPresenter, OverlayPresenterObserver>
+        scoped_observation_{this};
   };
 
   FullscreenDisabler fullscreen_disabler_;
diff --git a/ios/chrome/browser/ui/overlays/overlay_presentation_context_fullscreen_disabler.mm b/ios/chrome/browser/ui/overlays/overlay_presentation_context_fullscreen_disabler.mm
index cac758d4..22eab1e 100644
--- a/ios/chrome/browser/ui/overlays/overlay_presentation_context_fullscreen_disabler.mm
+++ b/ios/chrome/browser/ui/overlays/overlay_presentation_context_fullscreen_disabler.mm
@@ -29,10 +29,10 @@
 OverlayContainerFullscreenDisabler::FullscreenDisabler::FullscreenDisabler(
     FullscreenController* fullscreen_controller,
     OverlayPresenter* overlay_presenter)
-    : fullscreen_controller_(fullscreen_controller), scoped_observer_(this) {
+    : fullscreen_controller_(fullscreen_controller) {
   DCHECK(fullscreen_controller_);
   DCHECK(overlay_presenter);
-  scoped_observer_.Add(overlay_presenter);
+  scoped_observation_.Observe(overlay_presenter);
 }
 
 OverlayContainerFullscreenDisabler::FullscreenDisabler::~FullscreenDisabler() =
@@ -55,6 +55,7 @@
 
 void OverlayContainerFullscreenDisabler::FullscreenDisabler::
     OverlayPresenterDestroyed(OverlayPresenter* presenter) {
-  scoped_observer_.Remove(presenter);
+  DCHECK(scoped_observation_.IsObservingSource(presenter));
+  scoped_observation_.Reset();
   disabler_ = nullptr;
 }
diff --git a/ios/chrome/browser/ui/settings/autofill/autofill_profile_edit_table_view_controller.mm b/ios/chrome/browser/ui/settings/autofill/autofill_profile_edit_table_view_controller.mm
index bfe88918..3eabfa5 100644
--- a/ios/chrome/browser/ui/settings/autofill/autofill_profile_edit_table_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/autofill/autofill_profile_edit_table_view_controller.mm
@@ -39,39 +39,6 @@
   ItemTypeField = kItemTypeEnumZero,
 };
 
-struct AutofillFieldDisplayInfo {
-  autofill::ServerFieldType autofillType;
-  int displayStringID;
-  UIReturnKeyType returnKeyType;
-  UIKeyboardType keyboardType;
-  UITextAutocapitalizationType autoCapitalizationType;
-};
-
-static const AutofillFieldDisplayInfo kFieldsToDisplay[] = {
-    {autofill::NAME_HONORIFIC_PREFIX, IDS_IOS_AUTOFILL_HONORIFIC_PREFIX,
-     UIReturnKeyNext, UIKeyboardTypeDefault,
-     UITextAutocapitalizationTypeSentences},
-    {autofill::NAME_FULL, IDS_IOS_AUTOFILL_FULLNAME, UIReturnKeyNext,
-     UIKeyboardTypeDefault, UITextAutocapitalizationTypeSentences},
-    {autofill::COMPANY_NAME, IDS_IOS_AUTOFILL_COMPANY_NAME, UIReturnKeyNext,
-     UIKeyboardTypeDefault, UITextAutocapitalizationTypeSentences},
-    {autofill::ADDRESS_HOME_LINE1, IDS_IOS_AUTOFILL_ADDRESS1, UIReturnKeyNext,
-     UIKeyboardTypeDefault, UITextAutocapitalizationTypeSentences},
-    {autofill::ADDRESS_HOME_LINE2, IDS_IOS_AUTOFILL_ADDRESS2, UIReturnKeyNext,
-     UIKeyboardTypeDefault, UITextAutocapitalizationTypeSentences},
-    {autofill::ADDRESS_HOME_CITY, IDS_IOS_AUTOFILL_CITY, UIReturnKeyNext,
-     UIKeyboardTypeDefault, UITextAutocapitalizationTypeSentences},
-    {autofill::ADDRESS_HOME_STATE, IDS_IOS_AUTOFILL_STATE, UIReturnKeyNext,
-     UIKeyboardTypeDefault, UITextAutocapitalizationTypeSentences},
-    {autofill::ADDRESS_HOME_ZIP, IDS_IOS_AUTOFILL_ZIP, UIReturnKeyNext,
-     UIKeyboardTypeDefault, UITextAutocapitalizationTypeAllCharacters},
-    {autofill::ADDRESS_HOME_COUNTRY, IDS_IOS_AUTOFILL_COUNTRY, UIReturnKeyNext,
-     UIKeyboardTypeDefault, UITextAutocapitalizationTypeSentences},
-    {autofill::PHONE_HOME_WHOLE_NUMBER, IDS_IOS_AUTOFILL_PHONE, UIReturnKeyNext,
-     UIKeyboardTypePhonePad, UITextAutocapitalizationTypeSentences},
-    {autofill::EMAIL_ADDRESS, IDS_IOS_AUTOFILL_EMAIL, UIReturnKeyDone,
-     UIKeyboardTypeEmailAddress, UITextAutocapitalizationTypeNone}};
-
 }  // namespace
 
 @interface AutofillProfileEditTableViewController ()
@@ -170,8 +137,8 @@
 
   std::string locale = GetApplicationContext()->GetApplicationLocale();
   [model addSectionWithIdentifier:SectionIdentifierFields];
-  for (size_t i = 0; i < base::size(kFieldsToDisplay); ++i) {
-    const AutofillFieldDisplayInfo& field = kFieldsToDisplay[i];
+  for (size_t i = 0; i < base::size(kProfileFieldsToDisplay); ++i) {
+    const AutofillProfileFieldDisplayInfo& field = kProfileFieldsToDisplay[i];
 
     if (field.autofillType == autofill::NAME_HONORIFIC_PREFIX &&
         !base::FeatureList::IsEnabled(
diff --git a/ios/chrome/browser/url_loading/url_loading_browser_agent.h b/ios/chrome/browser/url_loading/url_loading_browser_agent.h
index a4bbc15..1704a1b 100644
--- a/ios/chrome/browser/url_loading/url_loading_browser_agent.h
+++ b/ios/chrome/browser/url_loading/url_loading_browser_agent.h
@@ -9,6 +9,7 @@
 
 #include "base/memory/weak_ptr.h"
 #import "ios/chrome/browser/main/browser_user_data.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class SceneUrlLoadingService;
 class Browser;
diff --git a/ios/chrome/browser/web/font_size/font_size_tab_helper.h b/ios/chrome/browser/web/font_size/font_size_tab_helper.h
index b3088b2a..dd7997e 100644
--- a/ios/chrome/browser/web/font_size/font_size_tab_helper.h
+++ b/ios/chrome/browser/web/font_size/font_size_tab_helper.h
@@ -10,6 +10,7 @@
 #include "base/macros.h"
 #include "ios/web/public/web_state_observer.h"
 #import "ios/web/public/web_state_user_data.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class PrefService;
 
diff --git a/ios/public/provider/chrome/browser/signin/chrome_trusted_vault_service.h b/ios/public/provider/chrome/browser/signin/chrome_trusted_vault_service.h
index 51b0def6..0f70f0e 100644
--- a/ios/public/provider/chrome/browser/signin/chrome_trusted_vault_service.h
+++ b/ios/public/provider/chrome/browser/signin/chrome_trusted_vault_service.h
@@ -40,6 +40,14 @@
   virtual void FetchKeys(
       ChromeIdentity* chrome_identity,
       base::OnceCallback<void(const TrustedVaultSharedKeyList&)> callback) = 0;
+
+  // Returns whether recoverability of the keys is degraded and user action is
+  // required to add a new method.
+  // TODO(crbug.com/1100278): Make pure.
+  virtual void GetIsRecoverabilityDegraded(
+      ChromeIdentity* chrome_identity,
+      base::OnceCallback<void(bool)> callback);
+
   // Presents the trusted vault key reauthentication UI for |identity|.
   // Once the reauth is done and the UI is dismissed, |callback| is called.
   // |callback| is not called if the reauthentication is canceled.
@@ -47,6 +55,7 @@
                                 UIViewController* presentingViewController,
                                 void (^callback)(BOOL success,
                                                  NSError* error)) = 0;
+
   // Cancels the presented trusted vault key reauthentication UI.
   // The reauthentication callback will not be called.
   // If no reauthentication dialog is not present, |callback| is called
diff --git a/ios/public/provider/chrome/browser/signin/chrome_trusted_vault_service.mm b/ios/public/provider/chrome/browser/signin/chrome_trusted_vault_service.mm
index fd1353c..622ce180 100644
--- a/ios/public/provider/chrome/browser/signin/chrome_trusted_vault_service.mm
+++ b/ios/public/provider/chrome/browser/signin/chrome_trusted_vault_service.mm
@@ -22,6 +22,12 @@
   observer_list_.RemoveObserver(observer);
 }
 
+void ChromeTrustedVaultService::GetIsRecoverabilityDegraded(
+    ChromeIdentity* chrome_identity,
+    base::OnceCallback<void(bool)> callback) {
+  std::move(callback).Run(false);
+}
+
 void ChromeTrustedVaultService::NotifyKeysChanged() {
   for (Observer& observer : observer_list_) {
     observer.OnTrustedVaultKeysChanged();
diff --git a/ios/public/provider/chrome/browser/signin/fake_chrome_identity_service.h b/ios/public/provider/chrome/browser/signin/fake_chrome_identity_service.h
index a07a5d53..81660fb 100644
--- a/ios/public/provider/chrome/browser/signin/fake_chrome_identity_service.h
+++ b/ios/public/provider/chrome/browser/signin/fake_chrome_identity_service.h
@@ -8,6 +8,7 @@
 #include "ios/public/provider/chrome/browser/signin/chrome_identity_service.h"
 
 #include "testing/gmock/include/gmock/gmock.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 @class FakeChromeIdentityInteractionManager;
 @class NSMutableArray;
diff --git a/ios/web/find_in_page/find_in_page_java_script_feature.h b/ios/web/find_in_page/find_in_page_java_script_feature.h
index cfa209d6..df0463c 100644
--- a/ios/web/find_in_page/find_in_page_java_script_feature.h
+++ b/ios/web/find_in_page/find_in_page_java_script_feature.h
@@ -9,6 +9,7 @@
 #include "base/no_destructor.h"
 #include "base/values.h"
 #include "ios/web/public/js_messaging/java_script_feature.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace web {
 
diff --git a/ios/web/find_in_page/find_in_page_manager_impl.h b/ios/web/find_in_page/find_in_page_manager_impl.h
index 5659fc55..55c15b1 100644
--- a/ios/web/find_in_page/find_in_page_manager_impl.h
+++ b/ios/web/find_in_page/find_in_page_manager_impl.h
@@ -11,6 +11,7 @@
 #import "ios/web/find_in_page/find_in_page_request.h"
 #import "ios/web/public/find_in_page/find_in_page_manager.h"
 #include "ios/web/public/web_state_observer.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 @class NSString;
 
diff --git a/ios/web/public/test/fakes/fake_web_state.h b/ios/web/public/test/fakes/fake_web_state.h
index 4a6d303a..41fad446 100644
--- a/ios/web/public/test/fakes/fake_web_state.h
+++ b/ios/web/public/test/fakes/fake_web_state.h
@@ -17,6 +17,7 @@
 #import "ios/web/public/navigation/web_state_policy_decider.h"
 #import "ios/web/public/web_state.h"
 #include "ios/web/public/web_state_observer.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 @class NSURLRequest;
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc
index 6996b92..ba0e481d 100644
--- a/media/base/media_switches.cc
+++ b/media/base/media_switches.cc
@@ -186,7 +186,8 @@
 
 // Overrides hardware secure codecs support for testing. If specified, real
 // platform hardware secure codecs check will be skipped. Codecs are separated
-// by comma. Valid codecs are "vp8", "vp9" and "avc1". For example:
+// by comma. Valid video codecs are "vp8", "vp9" and "avc1", and the only valid
+// audio codec is "vorbis". For example:
 //  --override-hardware-secure-codecs-for-testing=vp8,vp9
 //  --override-hardware-secure-codecs-for-testing=avc1
 // CENC encryption scheme is assumed to be supported for the specified codecs.
diff --git a/media/capture/content/video_capture_oracle_unittest.cc b/media/capture/content/video_capture_oracle_unittest.cc
index e9efd10..aea1256f 100644
--- a/media/capture/content/video_capture_oracle_unittest.cc
+++ b/media/capture/content/video_capture_oracle_unittest.cc
@@ -5,6 +5,7 @@
 #include "media/capture/content/video_capture_oracle.h"
 
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace media {
 
diff --git a/media/cdm/BUILD.gn b/media/cdm/BUILD.gn
index 1f91de0..b166b77e 100644
--- a/media/cdm/BUILD.gn
+++ b/media/cdm/BUILD.gn
@@ -63,6 +63,8 @@
     "default_cdm_factory.h",
     "json_web_key.cc",
     "json_web_key.h",
+    "supported_audio_codecs.cc",
+    "supported_audio_codecs.h",
   ]
 
   # TODO(crbug.com/167187): Fix size_t to int truncations.
diff --git a/media/cdm/cdm_capability.cc b/media/cdm/cdm_capability.cc
index da043fae..80ad6706 100644
--- a/media/cdm/cdm_capability.cc
+++ b/media/cdm/cdm_capability.cc
@@ -11,10 +11,12 @@
 CdmCapability::CdmCapability() = default;
 
 CdmCapability::CdmCapability(
+    std::vector<AudioCodec> audio_codecs,
     std::vector<VideoCodec> video_codecs,
     base::flat_set<EncryptionScheme> encryption_schemes,
     base::flat_set<CdmSessionType> session_types)
-    : video_codecs(std::move(video_codecs)),
+    : audio_codecs(std::move(audio_codecs)),
+      video_codecs(std::move(video_codecs)),
       encryption_schemes(std::move(encryption_schemes)),
       session_types(std::move(session_types)) {}
 
diff --git a/media/cdm/cdm_capability.h b/media/cdm/cdm_capability.h
index 4b83182..0548a3e1 100644
--- a/media/cdm/cdm_capability.h
+++ b/media/cdm/cdm_capability.h
@@ -8,6 +8,7 @@
 #include <vector>
 
 #include "base/containers/flat_set.h"
+#include "media/base/audio_codecs.h"
 #include "media/base/content_decryption_module.h"
 #include "media/base/encryption_scheme.h"
 #include "media/base/media_export.h"
@@ -18,12 +19,19 @@
 // Capabilities supported by a Content Decryption Module.
 struct MEDIA_EXPORT CdmCapability {
   CdmCapability();
-  CdmCapability(std::vector<VideoCodec> video_codecs,
+  CdmCapability(std::vector<AudioCodec> audio_codecs,
+                std::vector<VideoCodec> video_codecs,
                 base::flat_set<EncryptionScheme> encryption_schemes,
                 base::flat_set<CdmSessionType> session_types);
   CdmCapability(const CdmCapability& other);
   ~CdmCapability();
 
+  // List of audio codecs supported by the CDM (e.g. opus). This is the set of
+  // codecs supported by the media pipeline using the CDM, where CDM does the
+  // decryption, and the media pipeline does decoding. As this is generic, not
+  // all profiles or levels of the specified codecs may actually be supported.
+  std::vector<AudioCodec> audio_codecs;
+
   // List of video codecs supported by the CDM (e.g. vp8). This is the set of
   // codecs supported by the media pipeline using the CDM, where CDM does the
   // decryption, and the media pipeline does decoding. As this is generic, not
diff --git a/media/cdm/supported_audio_codecs.cc b/media/cdm/supported_audio_codecs.cc
new file mode 100644
index 0000000..1f416ac1
--- /dev/null
+++ b/media/cdm/supported_audio_codecs.cc
@@ -0,0 +1,20 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "media/cdm/supported_audio_codecs.h"
+
+#include "media/media_buildflags.h"
+
+namespace media {
+
+const std::vector<AudioCodec> GetCdmSupportedAudioCodecs() {
+  return {
+    AudioCodec::kCodecOpus, AudioCodec::kCodecVorbis, AudioCodec::kCodecFLAC,
+#if BUILDFLAG(USE_PROPRIETARY_CODECS)
+        AudioCodec::kCodecAAC,
+#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
+  };
+}
+
+}  // namespace media
diff --git a/media/cdm/supported_audio_codecs.h b/media/cdm/supported_audio_codecs.h
new file mode 100644
index 0000000..c4e0d4b
--- /dev/null
+++ b/media/cdm/supported_audio_codecs.h
@@ -0,0 +1,25 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MEDIA_CDM_SUPPORTED_AUDIO_CODECS_H_
+#define MEDIA_CDM_SUPPORTED_AUDIO_CODECS_H_
+
+#include <vector>
+
+#include "media/base/audio_codecs.h"
+#include "media/base/media_export.h"
+
+namespace media {
+
+// Returns a set of audio codecs that are supported for decoding by the
+// browser after a CDM has decrypted the stream. This will be used by
+// CDMs that only support decryption of audio content.
+// Note that this should only be used on desktop CDMs. On other platforms
+// (e.g. Android) we should query the system for (encrypted) audio codec
+// support.
+MEDIA_EXPORT const std::vector<AudioCodec> GetCdmSupportedAudioCodecs();
+
+}  //  namespace media
+
+#endif  // MEDIA_CDM_SUPPORTED_AUDIO_CODECS_H_
diff --git a/media/gpu/vaapi/test/av1_decoder.h b/media/gpu/vaapi/test/av1_decoder.h
index fc4c818..ef5750f 100644
--- a/media/gpu/vaapi/test/av1_decoder.h
+++ b/media/gpu/vaapi/test/av1_decoder.h
@@ -7,6 +7,7 @@
 
 #include "media/filters/ivf_parser.h"
 #include "media/gpu/vaapi/test/video_decoder.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 // For libgav1::ObuSequenceHeader. absl::optional demands ObuSequenceHeader to
 // fulfill std::is_trivially_constructible if it is forward-declared. But
 // ObuSequenceHeader doesn't.
diff --git a/media/mojo/mojom/cdm_capability_mojom_traits.cc b/media/mojo/mojom/cdm_capability_mojom_traits.cc
index ac48d09..f72a0d32 100644
--- a/media/mojo/mojom/cdm_capability_mojom_traits.cc
+++ b/media/mojo/mojom/cdm_capability_mojom_traits.cc
@@ -12,6 +12,10 @@
 bool StructTraits<media::mojom::CdmCapabilityDataView, media::CdmCapability>::
     Read(media::mojom::CdmCapabilityDataView input,
          media::CdmCapability* output) {
+  std::vector<media::AudioCodec> audio_codecs;
+  if (!input.ReadAudioCodecs(&audio_codecs))
+    return false;
+
   std::vector<media::VideoCodec> video_codecs;
   if (!input.ReadVideoCodecs(&video_codecs))
     return false;
@@ -26,9 +30,9 @@
 
   // |encryption_schemes| and |session_types| are convert to a base::flat_map
   // implicitly.
-  *output = media::CdmCapability(std::move(video_codecs),
-                                 std::move(encryption_schemes),
-                                 std::move(session_types));
+  *output = media::CdmCapability(
+      std::move(audio_codecs), std::move(video_codecs),
+      std::move(encryption_schemes), std::move(session_types));
   return true;
 }
 
diff --git a/media/mojo/mojom/cdm_capability_mojom_traits.h b/media/mojo/mojom/cdm_capability_mojom_traits.h
index f060329..178b17a 100644
--- a/media/mojo/mojom/cdm_capability_mojom_traits.h
+++ b/media/mojo/mojom/cdm_capability_mojom_traits.h
@@ -8,6 +8,7 @@
 #include <vector>
 
 #include "base/containers/flat_set.h"
+#include "media/base/audio_codecs.h"
 #include "media/base/content_decryption_module.h"
 #include "media/base/encryption_scheme.h"
 #include "media/base/video_codecs.h"
@@ -18,6 +19,11 @@
 
 template <>
 struct StructTraits<media::mojom::CdmCapabilityDataView, media::CdmCapability> {
+  static const std::vector<media::AudioCodec>& audio_codecs(
+      const media::CdmCapability& input) {
+    return input.audio_codecs;
+  }
+
   static const std::vector<media::VideoCodec>& video_codecs(
       const media::CdmCapability& input) {
     return input.video_codecs;
diff --git a/media/mojo/mojom/key_system_support.mojom b/media/mojo/mojom/key_system_support.mojom
index b46dd12d..371c259 100644
--- a/media/mojo/mojom/key_system_support.mojom
+++ b/media/mojo/mojom/key_system_support.mojom
@@ -11,6 +11,7 @@
 // TODO(crbug.com/796725) Find a way to include profiles and levels for
 // supported codecs.
 struct CdmCapability {
+  array<AudioCodec> audio_codecs;
   array<VideoCodec> video_codecs;
   array<EncryptionScheme> encryption_schemes;
   array<CdmSessionType> session_types;
diff --git a/media/muxers/webm_muxer.h b/media/muxers/webm_muxer.h
index cd695c1..7121c83 100644
--- a/media/muxers/webm_muxer.h
+++ b/media/muxers/webm_muxer.h
@@ -21,6 +21,7 @@
 #include "media/base/media_export.h"
 #include "media/base/video_codecs.h"
 #include "media/base/video_color_space.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/libwebm/source/mkvmuxer.hpp"
 #include "ui/gfx/geometry/size.h"
 
diff --git a/net/android/network_library.h b/net/android/network_library.h
index ee56780..27647990 100644
--- a/net/android/network_library.h
+++ b/net/android/network_library.h
@@ -20,6 +20,7 @@
 #include "net/base/mime_util.h"
 #include "net/base/net_export.h"
 #include "net/socket/socket_descriptor.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 namespace android {
diff --git a/net/base/proxy_server.cc b/net/base/proxy_server.cc
index c0118d5..a0b8fd1 100644
--- a/net/base/proxy_server.cc
+++ b/net/base/proxy_server.cc
@@ -77,18 +77,6 @@
   }
 }
 
-ProxyServer::ProxyServer(Scheme scheme,
-                         const HostPortPair& host_port_pair,
-                         bool is_trusted_proxy)
-    : ProxyServer(scheme, host_port_pair) {
-  if (is_trusted_proxy) {
-    is_trusted_proxy_ = true;
-    // TODO(https://crbug.com/778010): Update this when cross-origin server
-    // push is allowed for QUIC proxies.
-    DCHECK_EQ(SCHEME_HTTPS, scheme_);
-  }
-}
-
 const HostPortPair& ProxyServer::host_port_pair() const {
   // Doesn't make sense to call this if the URI scheme doesn't
   // have concept of a host.
diff --git a/net/base/proxy_server.h b/net/base/proxy_server.h
index 3e10cba..21206d05 100644
--- a/net/base/proxy_server.h
+++ b/net/base/proxy_server.h
@@ -45,9 +45,6 @@
   ProxyServer() {}
 
   ProxyServer(Scheme scheme, const HostPortPair& host_port_pair);
-  ProxyServer(Scheme scheme,
-              const HostPortPair& host_port_pair,
-              bool is_trusted_proxy);
 
   bool is_valid() const { return scheme_ != SCHEME_INVALID; }
 
@@ -83,10 +80,6 @@
   // the channel between the client and proxy server is secure.
   bool is_secure_http_like() const { return is_https() || is_quic(); }
 
-  // Returns true if the proxy is trusted to push cross-origin resources from
-  // HTTP hosts.
-  bool is_trusted_proxy() const { return is_trusted_proxy_; }
-
   const HostPortPair& host_port_pair() const;
 
   // Parses from an input with format:
@@ -161,17 +154,15 @@
 
   bool operator==(const ProxyServer& other) const {
     return scheme_ == other.scheme_ &&
-           host_port_pair_.Equals(other.host_port_pair_) &&
-           is_trusted_proxy_ == other.is_trusted_proxy_;
+           host_port_pair_.Equals(other.host_port_pair_);
   }
 
   bool operator!=(const ProxyServer& other) const { return !(*this == other); }
 
   // Comparator function so this can be placed in a std::map.
   bool operator<(const ProxyServer& other) const {
-    return std::tie(scheme_, host_port_pair_, is_trusted_proxy_) <
-           std::tie(other.scheme_, other.host_port_pair_,
-                    other.is_trusted_proxy_);
+    return std::tie(scheme_, host_port_pair_) <
+           std::tie(other.scheme_, other.host_port_pair_);
   }
 
   // Returns the estimate of dynamically allocated memory in bytes.
@@ -185,7 +176,6 @@
 
   Scheme scheme_ = SCHEME_INVALID;
   HostPortPair host_port_pair_;
-  bool is_trusted_proxy_ = false;
 };
 
 typedef std::pair<HostPortPair, ProxyServer> HostPortProxyPair;
diff --git a/net/base/proxy_server_unittest.cc b/net/base/proxy_server_unittest.cc
index ab5d520..a38f8603 100644
--- a/net/base/proxy_server_unittest.cc
+++ b/net/base/proxy_server_unittest.cc
@@ -293,12 +293,6 @@
       {// Scheme is different.
        ProxyServer::FromURI("socks4://foo:33", ProxyServer::SCHEME_HTTP),
        ProxyServer::FromURI("http://foo:33", ProxyServer::SCHEME_HTTP), 1},
-      {// Trusted is different.
-       ProxyServer(ProxyServer::SCHEME_HTTPS, HostPortPair("foo", 33),
-                   false /* is_trusted_proxy */),
-       ProxyServer(ProxyServer::SCHEME_HTTPS, HostPortPair("foo", 33),
-                   true /* is_trusted_proxy */),
-       -1},
   };
 
   for (const auto& test : kTests) {
diff --git a/net/base/test_proxy_delegate.cc b/net/base/test_proxy_delegate.cc
index b200ab9..b8cf7d8 100644
--- a/net/base/test_proxy_delegate.cc
+++ b/net/base/test_proxy_delegate.cc
@@ -31,22 +31,7 @@
     const GURL& url,
     const std::string& method,
     const ProxyRetryInfoMap& proxy_retry_info,
-    ProxyInfo* result) {
-  if (!trusted_spdy_proxy_.is_valid())
-    return;
-  ProxyList new_proxy_list;
-  for (const auto& proxy_server : result->proxy_list().GetAll()) {
-    if (proxy_server == trusted_spdy_proxy_) {
-      new_proxy_list.AddProxyServer(ProxyServer(
-          proxy_server.scheme(), proxy_server.host_port_pair(), true));
-    } else {
-      new_proxy_list.AddProxyServer(proxy_server);
-    }
-  }
-  result->UseProxyList(new_proxy_list);
-  result->set_traffic_annotation(
-      MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
-}
+    ProxyInfo* result) {}
 
 void TestProxyDelegate::OnFallback(const ProxyServer& bad_proxy,
                                    int net_error) {}
diff --git a/net/base/test_proxy_delegate.h b/net/base/test_proxy_delegate.h
index 50ebd9c8..aed0c32 100644
--- a/net/base/test_proxy_delegate.h
+++ b/net/base/test_proxy_delegate.h
@@ -26,10 +26,6 @@
     return on_before_tunnel_request_called_;
   }
 
-  void set_trusted_spdy_proxy(const ProxyServer& proxy_server) {
-    trusted_spdy_proxy_ = proxy_server;
-  }
-
   void VerifyOnTunnelHeadersReceived(
       const ProxyServer& proxy_server,
       const std::string& response_header_name,
@@ -51,7 +47,6 @@
   bool on_before_tunnel_request_called_ = false;
   ProxyServer on_tunnel_headers_received_proxy_server_;
   scoped_refptr<HttpResponseHeaders> on_tunnel_headers_received_headers_;
-  ProxyServer trusted_spdy_proxy_;
 };
 
 }  // namespace net
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc
index a2d3ceb..34289b7 100644
--- a/net/http/http_network_transaction_unittest.cc
+++ b/net/http/http_network_transaction_unittest.cc
@@ -5911,12 +5911,6 @@
       results->UsePacString("HTTPS " + ProxyHostPortPairAsString());
       return OK;
     }
-    if (url.path() == "/https_trusted") {
-      results->UseProxyServer(ProxyServer(ProxyServer::SCHEME_HTTPS,
-                                          ProxyHostPortPair(),
-                                          true /* is_trusted_proxy */));
-      return OK;
-    }
     NOTREACHED();
     return ERR_NOT_IMPLEMENTED;
   }
@@ -6035,21 +6029,6 @@
   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
 
-  MockWrite https_trusted_writes[] = {
-      MockWrite(SYNCHRONOUS,
-                "GET http://test/https_trusted HTTP/1.1\r\n"
-                "Host: test\r\n"
-                "Proxy-Connection: keep-alive\r\n\r\n"),
-  };
-  MockRead https_trusted_reads[] = {
-      MockRead("HTTP/1.1 200 OK\r\n"
-               "Proxy-Connection: keep-alive\r\n"
-               "Content-Length: 22\r\n\r\n"
-               "HTTPS Trusted Response"),
-  };
-  StaticSocketDataProvider trusted_https_data(https_trusted_reads,
-                                              https_trusted_writes);
-  session_deps_.socket_factory->AddSocketDataProvider(&trusted_https_data);
   SSLSocketDataProvider ssl2(SYNCHRONOUS, OK);
   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
 
@@ -6064,16 +6043,11 @@
     // pools after the test.
     int expected_idle_http_sockets;
     int expected_idle_https_sockets;
-    // How many idle sockets there should be in the HTTPS proxy socket pool with
-    // the ProxyServer's |is_trusted_proxy| bit set after the test.
-    int expected_idle_trusted_https_sockets;
   } const kTestCases[] = {
-      {GURL("http://test/socks4"), "SOCKS4 Response", 1, 0, 0, 0, 0},
-      {GURL("http://test/socks5"), "SOCKS5 Response", 1, 1, 0, 0, 0},
-      {GURL("http://test/http"), "HTTP Response", 1, 1, 1, 0, 0},
-      {GURL("http://test/https"), "HTTPS Response", 1, 1, 1, 1, 0},
-      {GURL("http://test/https_trusted"), "HTTPS Trusted Response", 1, 1, 1, 1,
-       1},
+      {GURL("http://test/socks4"), "SOCKS4 Response", 1, 0, 0, 0},
+      {GURL("http://test/socks5"), "SOCKS5 Response", 1, 1, 0, 0},
+      {GURL("http://test/http"), "HTTP Response", 1, 1, 1, 0},
+      {GURL("http://test/https"), "HTTPS Response", 1, 1, 1, 1},
   };
 
   for (const auto& test_case : kTestCases) {
@@ -6153,15 +6127,6 @@
                                   SameProxyWithDifferentSchemesProxyResolver::
                                       ProxyHostPortPair()))
                   ->IdleSocketCount());
-    EXPECT_EQ(test_case.expected_idle_trusted_https_sockets,
-              session
-                  ->GetSocketPool(
-                      HttpNetworkSession::NORMAL_SOCKET_POOL,
-                      ProxyServer(ProxyServer::SCHEME_HTTPS,
-                                  SameProxyWithDifferentSchemesProxyResolver::
-                                      ProxyHostPortPair(),
-                                  true /* is_trusted_proxy */))
-                  ->IdleSocketCount());
   }
 }
 
@@ -11823,306 +11788,6 @@
   session->CloseAllConnections(ERR_FAILED, "Very good reason");
 }
 
-// Test that an explicitly trusted SPDY proxy can push a resource from an
-// origin that is different from that of its associated resource.
-TEST_F(HttpNetworkTransactionTest, CrossOriginSpdyProxyPush) {
-  // Configure the proxy delegate to allow cross-origin SPDY pushes.
-  auto proxy_delegate = std::make_unique<TestProxyDelegate>();
-  proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
-      "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
-  HttpRequestInfo request;
-  HttpRequestInfo push_request;
-  request.traffic_annotation =
-      net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
-
-  request.method = "GET";
-  request.url = GURL("http://www.example.org/");
-  push_request.method = "GET";
-  push_request.url = GURL("http://www.another-origin.com/foo.dat");
-  push_request.traffic_annotation =
-      net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
-
-  // Configure against https proxy server "myproxy:443".
-  session_deps_.proxy_resolution_service =
-      ConfiguredProxyResolutionService::CreateFixedFromPacResult(
-          "HTTPS myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
-  RecordingBoundTestNetLog log;
-  session_deps_.net_log = log.bound().net_log();
-
-  session_deps_.proxy_resolution_service->SetProxyDelegate(
-      proxy_delegate.get());
-
-  std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
-
-  spdy::SpdySerializedFrame stream1_syn(
-      spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
-  spdy::SpdySerializedFrame stream2_priority(
-      spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
-
-  MockWrite spdy_writes[] = {
-      CreateMockWrite(stream1_syn, 0, ASYNC),
-      CreateMockWrite(stream2_priority, 3, ASYNC),
-  };
-
-  spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
-      nullptr, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
-
-  spdy::SpdySerializedFrame stream1_reply(
-      spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
-
-  spdy::SpdySerializedFrame stream1_body(
-      spdy_util_.ConstructSpdyDataFrame(1, true));
-
-  spdy::SpdySerializedFrame stream2_body(
-      spdy_util_.ConstructSpdyDataFrame(2, "pushed", true));
-
-  MockRead spdy_reads[] = {
-      CreateMockRead(stream2_syn, 1, ASYNC),
-      CreateMockRead(stream1_reply, 2, ASYNC),
-      CreateMockRead(stream1_body, 4, ASYNC),
-      CreateMockRead(stream2_body, 5, ASYNC),
-      MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6),  // Force a hang
-  };
-
-  SequencedSocketData spdy_data(spdy_reads, spdy_writes);
-  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
-  // Negotiate SPDY to the proxy
-  SSLSocketDataProvider proxy(ASYNC, OK);
-  proxy.next_proto = kProtoHTTP2;
-  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
-
-  auto trans =
-      std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
-  TestCompletionCallback callback;
-  int rv = trans->Start(&request, callback.callback(), log.bound());
-  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
-
-  rv = callback.WaitForResult();
-  EXPECT_THAT(rv, IsOk());
-  const HttpResponseInfo* response = trans->GetResponseInfo();
-
-  auto push_trans =
-      std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
-  rv = push_trans->Start(&push_request, callback.callback(), log.bound());
-  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
-
-  rv = callback.WaitForResult();
-  EXPECT_THAT(rv, IsOk());
-  const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
-
-  ASSERT_TRUE(response);
-  EXPECT_TRUE(response->headers->IsKeepAlive());
-
-  EXPECT_EQ(200, response->headers->response_code());
-  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
-
-  std::string response_data;
-  rv = ReadTransaction(trans.get(), &response_data);
-  EXPECT_THAT(rv, IsOk());
-  EXPECT_EQ("hello!", response_data);
-
-  LoadTimingInfo load_timing_info;
-  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
-  TestLoadTimingNotReusedWithPac(load_timing_info,
-                                 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
-
-  // Verify the pushed stream.
-  EXPECT_TRUE(push_response->headers);
-  EXPECT_EQ(200, push_response->headers->response_code());
-
-  rv = ReadTransaction(push_trans.get(), &response_data);
-  EXPECT_THAT(rv, IsOk());
-  EXPECT_EQ("pushed", response_data);
-
-  LoadTimingInfo push_load_timing_info;
-  EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
-  TestLoadTimingReusedWithPac(push_load_timing_info);
-  // The transactions should share a socket ID, despite being for different
-  // origins.
-  EXPECT_EQ(load_timing_info.socket_log_id,
-            push_load_timing_info.socket_log_id);
-
-  trans.reset();
-  push_trans.reset();
-  session->CloseAllConnections(ERR_FAILED, "Very good reason");
-}
-
-// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
-TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
-  // Configure the proxy delegate to allow cross-origin SPDY pushes.
-  auto proxy_delegate = std::make_unique<TestProxyDelegate>();
-  proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
-      "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
-  HttpRequestInfo request;
-
-  request.method = "GET";
-  request.url = GURL("http://www.example.org/");
-  request.traffic_annotation =
-      net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
-
-  session_deps_.proxy_resolution_service =
-      ConfiguredProxyResolutionService::CreateFixed(
-          "https://myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
-  RecordingBoundTestNetLog log;
-  session_deps_.net_log = log.bound().net_log();
-
-  // Enable cross-origin push.
-  session_deps_.proxy_resolution_service->SetProxyDelegate(
-      proxy_delegate.get());
-
-  std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
-
-  spdy::SpdySerializedFrame stream1_syn(
-      spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
-
-  spdy::SpdySerializedFrame push_rst(
-      spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_REFUSED_STREAM));
-
-  MockWrite spdy_writes[] = {
-      CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
-  };
-
-  spdy::SpdySerializedFrame stream1_reply(
-      spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
-
-  spdy::SpdySerializedFrame stream1_body(
-      spdy_util_.ConstructSpdyDataFrame(1, true));
-
-  spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
-      nullptr, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
-
-  MockRead spdy_reads[] = {
-      CreateMockRead(stream1_reply, 1, ASYNC),
-      CreateMockRead(stream2_syn, 2, ASYNC),
-      CreateMockRead(stream1_body, 4, ASYNC),
-      MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),  // Force a hang
-  };
-
-  SequencedSocketData spdy_data(spdy_reads, spdy_writes);
-  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
-  // Negotiate SPDY to the proxy
-  SSLSocketDataProvider proxy(ASYNC, OK);
-  proxy.next_proto = kProtoHTTP2;
-  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
-
-  auto trans =
-      std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
-  TestCompletionCallback callback;
-  int rv = trans->Start(&request, callback.callback(), log.bound());
-  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
-
-  rv = callback.WaitForResult();
-  EXPECT_THAT(rv, IsOk());
-  const HttpResponseInfo* response = trans->GetResponseInfo();
-
-  ASSERT_TRUE(response);
-  EXPECT_TRUE(response->headers->IsKeepAlive());
-
-  EXPECT_EQ(200, response->headers->response_code());
-  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
-
-  std::string response_data;
-  rv = ReadTransaction(trans.get(), &response_data);
-  EXPECT_THAT(rv, IsOk());
-  EXPECT_EQ("hello!", response_data);
-
-  trans.reset();
-  session->CloseAllConnections(ERR_FAILED, "Very good reason");
-}
-
-// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
-// resources.
-TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
-  // Configure the proxy delegate to allow cross-origin SPDY pushes.
-  auto proxy_delegate = std::make_unique<TestProxyDelegate>();
-  proxy_delegate->set_trusted_spdy_proxy(
-      net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
-
-  HttpRequestInfo request;
-
-  request.method = "GET";
-  request.url = GURL("http://www.example.org/");
-  request.traffic_annotation =
-      net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
-
-  // Configure against https proxy server "myproxy:70".
-  session_deps_.proxy_resolution_service =
-      ConfiguredProxyResolutionService::CreateFixed(
-          "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
-  RecordingBoundTestNetLog log;
-  session_deps_.net_log = log.bound().net_log();
-
-  // Enable cross-origin push.
-  session_deps_.proxy_resolution_service->SetProxyDelegate(
-      proxy_delegate.get());
-
-  std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
-
-  spdy::SpdySerializedFrame stream1_syn(
-      spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
-  spdy::SpdySerializedFrame stream2_priority(
-      spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
-
-  MockWrite spdy_writes[] = {
-      CreateMockWrite(stream1_syn, 0, ASYNC),
-      CreateMockWrite(stream2_priority, 3, ASYNC),
-  };
-
-  spdy::SpdySerializedFrame stream1_reply(
-      spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
-
-  spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
-      nullptr, 0, 2, 1, "http://www.example.org/foo.dat"));
-
-  spdy::SpdySerializedFrame stream1_body(
-      spdy_util_.ConstructSpdyDataFrame(1, true));
-
-  spdy::SpdySerializedFrame stream2_reply(
-      spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
-
-  spdy::SpdySerializedFrame stream2_body(
-      spdy_util_.ConstructSpdyDataFrame(1, true));
-
-  MockRead spdy_reads[] = {
-      CreateMockRead(stream1_reply, 1, ASYNC),
-      CreateMockRead(stream2_syn, 2, ASYNC),
-      CreateMockRead(stream1_body, 4, ASYNC),
-      CreateMockRead(stream2_body, 5, ASYNC),
-      MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6),  // Force a hang
-  };
-
-  SequencedSocketData spdy_data(spdy_reads, spdy_writes);
-  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
-  // Negotiate SPDY to the proxy
-  SSLSocketDataProvider proxy(ASYNC, OK);
-  proxy.next_proto = kProtoHTTP2;
-  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
-
-  auto trans =
-      std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
-  TestCompletionCallback callback;
-  int rv = trans->Start(&request, callback.callback(), log.bound());
-  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
-
-  rv = callback.WaitForResult();
-  EXPECT_THAT(rv, IsOk());
-  const HttpResponseInfo* response = trans->GetResponseInfo();
-
-  ASSERT_TRUE(response);
-  EXPECT_TRUE(response->headers->IsKeepAlive());
-
-  EXPECT_EQ(200, response->headers->response_code());
-  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
-
-  std::string response_data;
-  rv = ReadTransaction(trans.get(), &response_data);
-  EXPECT_THAT(rv, IsOk());
-  EXPECT_EQ("hello!", response_data);
-
-  trans.reset();
-  session->CloseAllConnections(ERR_FAILED, "Very good reason");
-}
-
 // Test HTTPS connections to a site with a bad certificate, going through an
 // HTTPS proxy
 TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
diff --git a/net/http/http_proxy_connect_job.cc b/net/http/http_proxy_connect_job.cc
index 2863e58..1cca4ae 100644
--- a/net/http/http_proxy_connect_job.cc
+++ b/net/http/http_proxy_connect_job.cc
@@ -134,7 +134,6 @@
     scoped_refptr<SSLSocketParams> ssl_params,
     bool is_quic,
     const HostPortPair& endpoint,
-    bool is_trusted_proxy,
     bool tunnel,
     const NetworkTrafficAnnotationTag traffic_annotation,
     const NetworkIsolationKey& network_isolation_key)
@@ -142,7 +141,6 @@
       ssl_params_(std::move(ssl_params)),
       is_quic_(is_quic),
       endpoint_(endpoint),
-      is_trusted_proxy_(is_trusted_proxy),
       tunnel_(tunnel),
       network_isolation_key_(network_isolation_key),
       traffic_annotation_(traffic_annotation) {
@@ -603,8 +601,7 @@
     // Create a session direct to the proxy itself
     spdy_session = common_connect_job_params()
                        ->spdy_session_pool->CreateAvailableSessionFromSocket(
-                           key, params_->is_trusted_proxy(),
-                           nested_connect_job_->PassSocket(),
+                           key, nested_connect_job_->PassSocket(),
                            nested_connect_job_->connect_timing(), net_log());
     DCHECK(spdy_session);
     nested_connect_job_.reset();
diff --git a/net/http/http_proxy_connect_job.h b/net/http/http_proxy_connect_job.h
index 07b2627..a676ea5 100644
--- a/net/http/http_proxy_connect_job.h
+++ b/net/http/http_proxy_connect_job.h
@@ -48,7 +48,6 @@
                         scoped_refptr<SSLSocketParams> ssl_params,
                         bool is_quic,
                         const HostPortPair& endpoint,
-                        bool is_trusted_proxy,
                         bool tunnel,
                         const NetworkTrafficAnnotationTag traffic_annotation,
                         const NetworkIsolationKey& network_isolation_key);
@@ -61,7 +60,6 @@
   }
   bool is_quic() const { return is_quic_; }
   const HostPortPair& endpoint() const { return endpoint_; }
-  bool is_trusted_proxy() const { return is_trusted_proxy_; }
   bool tunnel() const { return tunnel_; }
   const NetworkIsolationKey& network_isolation_key() const {
     return network_isolation_key_;
@@ -78,7 +76,6 @@
   const scoped_refptr<SSLSocketParams> ssl_params_;
   bool is_quic_;
   const HostPortPair endpoint_;
-  const bool is_trusted_proxy_;
   const bool tunnel_;
   const NetworkIsolationKey network_isolation_key_;
   const NetworkTrafficAnnotationTag traffic_annotation_;
diff --git a/net/http/http_proxy_connect_job_unittest.cc b/net/http/http_proxy_connect_job_unittest.cc
index 03902c6b..7790e73 100644
--- a/net/http/http_proxy_connect_job_unittest.cc
+++ b/net/http/http_proxy_connect_job_unittest.cc
@@ -134,9 +134,8 @@
     return base::MakeRefCounted<HttpProxySocketParams>(
         CreateHttpProxyParams(secure_dns_policy),
         CreateHttpsProxyParams(secure_dns_policy), false /* is_quic */,
-        HostPortPair(kEndpointHost, tunnel ? 443 : 80),
-        /*is_trusted_proxy=*/false, tunnel, TRAFFIC_ANNOTATION_FOR_TESTS,
-        NetworkIsolationKey());
+        HostPortPair(kEndpointHost, tunnel ? 443 : 80), tunnel,
+        TRAFFIC_ANNOTATION_FOR_TESTS, NetworkIsolationKey());
   }
 
   std::unique_ptr<HttpProxyConnectJob> CreateConnectJobForHttpRequest(
@@ -921,7 +920,7 @@
       PRIVACY_MODE_DISABLED, NetworkIsolationKey());
   auto http_proxy_params = base::MakeRefCounted<HttpProxySocketParams>(
       nullptr /* tcp_params */, std::move(ssl_params), false /* is_quic */,
-      HostPortPair(kEndpointHost, 443), /*is_trusted_proxy=*/false,
+      HostPortPair(kEndpointHost, 443),
       /*tunnel=*/true, TRAFFIC_ANNOTATION_FOR_TESTS, NetworkIsolationKey());
 
   std::unique_ptr<ConnectJob> connect_job = CreateConnectJob(
diff --git a/net/http/http_stream_factory_job.cc b/net/http/http_stream_factory_job.cc
index 7b1904c..a07072b 100644
--- a/net/http/http_stream_factory_job.cc
+++ b/net/http/http_stream_factory_job.cc
@@ -1149,16 +1149,10 @@
   if (connection_->socket()->IsConnected())
     connection_->CloseIdleSocketsInGroup("Switching to HTTP2 session");
 
-  // If |spdy_session_direct_| is false, then |proxy_info_| is guaranteed to
-  // have a non-empty proxy list.
-  bool is_trusted_proxy =
-      !spdy_session_direct_ && proxy_info_.proxy_server().is_trusted_proxy();
-
   base::WeakPtr<SpdySession> spdy_session;
   int rv =
       session_->spdy_session_pool()->CreateAvailableSessionFromSocketHandle(
-          spdy_session_key_, is_trusted_proxy, std::move(connection_), net_log_,
-          &spdy_session);
+          spdy_session_key_, std::move(connection_), net_log_, &spdy_session);
 
   if (rv != OK) {
     return rv;
diff --git a/net/socket/connect_job.cc b/net/socket/connect_job.cc
index 8335b5fa..156dd00 100644
--- a/net/socket/connect_job.cc
+++ b/net/socket/connect_job.cc
@@ -138,9 +138,8 @@
 
       http_proxy_params = base::MakeRefCounted<HttpProxySocketParams>(
           std::move(proxy_tcp_params), std::move(ssl_params),
-          proxy_server.is_quic(), endpoint, proxy_server.is_trusted_proxy(),
-          force_tunnel || using_ssl, *proxy_annotation_tag,
-          network_isolation_key);
+          proxy_server.is_quic(), endpoint, force_tunnel || using_ssl,
+          *proxy_annotation_tag, network_isolation_key);
     } else {
       DCHECK(proxy_server.is_socks());
       socks_params = base::MakeRefCounted<SOCKSSocketParams>(
diff --git a/net/socket/ssl_connect_job_unittest.cc b/net/socket/ssl_connect_job_unittest.cc
index d18586d..2643b9b 100644
--- a/net/socket/ssl_connect_job_unittest.cc
+++ b/net/socket/ssl_connect_job_unittest.cc
@@ -112,7 +112,6 @@
                                       nullptr /* ssl_params */,
                                       false /* is_quic */,
                                       HostPortPair("host", 80),
-                                      /*is_trusted_proxy=*/false,
                                       /*tunnel=*/true,
                                       TRAFFIC_ANNOTATION_FOR_TESTS,
                                       NetworkIsolationKey())),
diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc
index 53e3067..2106dce 100644
--- a/net/spdy/spdy_network_transaction_unittest.cc
+++ b/net/spdy/spdy_network_transaction_unittest.cc
@@ -6614,19 +6614,11 @@
     // NetworkIsolationKeys are respected.
     request_.network_isolation_key = NetworkIsolationKey::CreateTransient();
 
-    // Enable cross-origin push. Since we are not using a proxy, this should
-    // not actually enable cross-origin SPDY push.
-    auto session_deps = std::make_unique<SpdySessionDependencies>();
-    auto proxy_delegate = std::make_unique<TestProxyDelegate>();
-    proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
-        "https://123.45.67.89:443", net::ProxyServer::SCHEME_HTTP));
-    session_deps->proxy_resolution_service->SetProxyDelegate(
-        proxy_delegate.get());
-
     auto ssl_provider = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
     ssl_provider->ssl_info.client_cert_sent = GetParam().client_cert_sent;
     ssl_provider->ssl_info.cert =
         ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
+    auto session_deps = std::make_unique<SpdySessionDependencies>();
     if (GetParam().expect_ct_error) {
       ssl_provider->ssl_info.ct_policy_compliance =
           ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS;
diff --git a/net/spdy/spdy_proxy_client_socket_unittest.cc b/net/spdy/spdy_proxy_client_socket_unittest.cc
index 3e9c678..799f083 100644
--- a/net/spdy/spdy_proxy_client_socket_unittest.cc
+++ b/net/spdy/spdy_proxy_client_socket_unittest.cc
@@ -110,9 +110,8 @@
 
   base::WeakPtr<SpdySession> spdy_session =
       http_session->spdy_session_pool()->CreateAvailableSessionFromSocket(
-          key, false /* is_trusted_proxy */,
-          connect_job_delegate.ReleaseSocket(), LoadTimingInfo::ConnectTiming(),
-          NetLogWithSource());
+          key, connect_job_delegate.ReleaseSocket(),
+          LoadTimingInfo::ConnectTiming(), NetLogWithSource());
   // Failure is reported asynchronously.
   EXPECT_TRUE(spdy_session);
   EXPECT_TRUE(HasSpdySession(http_session->spdy_session_pool(), key));
diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc
index a54dbb1c..057e9647 100644
--- a/net/spdy/spdy_session.cc
+++ b/net/spdy/spdy_session.cc
@@ -930,7 +930,6 @@
     bool enable_ping_based_connection_checking,
     bool is_http2_enabled,
     bool is_quic_enabled,
-    bool is_trusted_proxy,
     size_t session_max_recv_window_size,
     int session_max_queued_capped_frames,
     const spdy::SettingsMap& initial_settings,
@@ -999,7 +998,6 @@
           enable_ping_based_connection_checking),
       is_http2_enabled_(is_http2_enabled),
       is_quic_enabled_(is_quic_enabled),
-      is_trusted_proxy_(is_trusted_proxy),
       enable_push_(IsPushEnabled(initial_settings)),
       support_websocket_(false),
       connection_at_risk_of_loss_time_(
@@ -2104,44 +2102,33 @@
   // Cross-origin push validation.
   GURL associated_url(associated_it->second->url());
   if (associated_url.GetOrigin() != gurl.GetOrigin()) {
-    if (is_trusted_proxy_) {
-      if (!gurl.SchemeIs(url::kHttpScheme)) {
-        RecordSpdyPushedStreamFateHistogram(
-            SpdyPushedStreamFate::kNonHttpSchemeFromTrustedProxy);
-        EnqueueResetStreamFrame(
-            stream_id, request_priority, spdy::ERROR_CODE_REFUSED_STREAM,
-            "Only http scheme allowed for cross origin push by trusted proxy.");
-        return;
-      }
-    } else {
-      if (!gurl.SchemeIs(url::kHttpsScheme)) {
-        RecordSpdyPushedStreamFateHistogram(
-            SpdyPushedStreamFate::kNonHttpsPushedScheme);
-        EnqueueResetStreamFrame(stream_id, request_priority,
-                                spdy::ERROR_CODE_REFUSED_STREAM,
-                                "Pushed URL must have https scheme.");
-        return;
-      }
-      if (!associated_url.SchemeIs(url::kHttpsScheme)) {
-        RecordSpdyPushedStreamFateHistogram(
-            SpdyPushedStreamFate::kNonHttpsAssociatedScheme);
-        EnqueueResetStreamFrame(stream_id, request_priority,
-                                spdy::ERROR_CODE_REFUSED_STREAM,
-                                "Associated URL must have https scheme.");
-        return;
-      }
-      SSLInfo ssl_info;
-      CHECK(GetSSLInfo(&ssl_info));
-      if (!CanPool(transport_security_state_, ssl_info, *ssl_config_service_,
-                   associated_url.host(), gurl.host(),
-                   spdy_session_key_.network_isolation_key())) {
-        RecordSpdyPushedStreamFateHistogram(
-            SpdyPushedStreamFate::kCertificateMismatch);
-        EnqueueResetStreamFrame(stream_id, request_priority,
-                                spdy::ERROR_CODE_REFUSED_STREAM,
-                                "Certificate does not match pushed URL.");
-        return;
-      }
+    if (!gurl.SchemeIs(url::kHttpsScheme)) {
+      RecordSpdyPushedStreamFateHistogram(
+          SpdyPushedStreamFate::kNonHttpsPushedScheme);
+      EnqueueResetStreamFrame(stream_id, request_priority,
+                              spdy::ERROR_CODE_REFUSED_STREAM,
+                              "Pushed URL must have https scheme.");
+      return;
+    }
+    if (!associated_url.SchemeIs(url::kHttpsScheme)) {
+      RecordSpdyPushedStreamFateHistogram(
+          SpdyPushedStreamFate::kNonHttpsAssociatedScheme);
+      EnqueueResetStreamFrame(stream_id, request_priority,
+                              spdy::ERROR_CODE_REFUSED_STREAM,
+                              "Associated URL must have https scheme.");
+      return;
+    }
+    SSLInfo ssl_info;
+    CHECK(GetSSLInfo(&ssl_info));
+    if (!CanPool(transport_security_state_, ssl_info, *ssl_config_service_,
+                 associated_url.host(), gurl.host(),
+                 spdy_session_key_.network_isolation_key())) {
+      RecordSpdyPushedStreamFateHistogram(
+          SpdyPushedStreamFate::kCertificateMismatch);
+      EnqueueResetStreamFrame(stream_id, request_priority,
+                              spdy::ERROR_CODE_REFUSED_STREAM,
+                              "Certificate does not match pushed URL.");
+      return;
     }
   }
 
diff --git a/net/spdy/spdy_session.h b/net/spdy/spdy_session.h
index 2729994..22135881 100644
--- a/net/spdy/spdy_session.h
+++ b/net/spdy/spdy_session.h
@@ -347,7 +347,6 @@
               bool enable_ping_based_connection_checking,
               bool is_http_enabled,
               bool is_quic_enabled,
-              bool is_trusted_proxy,
               size_t session_max_recv_window_size,
               int session_max_queued_capped_frames,
               const spdy::SettingsMap& initial_settings,
@@ -1262,10 +1261,6 @@
   const bool is_http2_enabled_;
   const bool is_quic_enabled_;
 
-  // If true, this session is being made to a trusted SPDY/HTTP2 proxy that is
-  // allowed to push cross-origin resources.
-  const bool is_trusted_proxy_;
-
   // If true, accept pushed streams from server.
   // If false, reset pushed streams immediately.
   const bool enable_push_;
diff --git a/net/spdy/spdy_session_pool.cc b/net/spdy/spdy_session_pool.cc
index 859e5e1..22bf08e 100644
--- a/net/spdy/spdy_session_pool.cc
+++ b/net/spdy/spdy_session_pool.cc
@@ -144,7 +144,6 @@
 
 int SpdySessionPool::CreateAvailableSessionFromSocketHandle(
     const SpdySessionKey& key,
-    bool is_trusted_proxy,
     std::unique_ptr<ClientSocketHandle> client_socket_handle,
     const NetLogWithSource& net_log,
     base::WeakPtr<SpdySession>* session) {
@@ -152,7 +151,7 @@
                "SpdySessionPool::CreateAvailableSessionFromSocketHandle");
 
   std::unique_ptr<SpdySession> new_session =
-      CreateSession(key, is_trusted_proxy, net_log.net_log());
+      CreateSession(key, net_log.net_log());
   std::vector<std::string> dns_aliases =
       client_socket_handle->socket()->GetDnsAliases();
 
@@ -179,7 +178,6 @@
 
 base::WeakPtr<SpdySession> SpdySessionPool::CreateAvailableSessionFromSocket(
     const SpdySessionKey& key,
-    bool is_trusted_proxy,
     std::unique_ptr<StreamSocket> socket_stream,
     const LoadTimingInfo::ConnectTiming& connect_timing,
     const NetLogWithSource& net_log) {
@@ -187,7 +185,7 @@
                "SpdySessionPool::CreateAvailableSessionFromSocket");
 
   std::unique_ptr<SpdySession> new_session =
-      CreateSession(key, is_trusted_proxy, net_log.net_log());
+      CreateSession(key, net_log.net_log());
   std::vector<std::string> dns_aliases = socket_stream->GetDnsAliases();
 
   new_session->InitializeWithSocket(std::move(socket_stream), connect_timing,
@@ -684,7 +682,6 @@
 
 std::unique_ptr<SpdySession> SpdySessionPool::CreateSession(
     const SpdySessionKey& key,
-    bool is_trusted_proxy,
     NetLog* net_log) {
   UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionGet", IMPORTED_FROM_SOCKET,
                             SPDY_SESSION_GET_MAX);
@@ -708,7 +705,7 @@
       ssl_client_context_ ? ssl_client_context_->ssl_config_service() : nullptr,
       quic_supported_versions_, enable_sending_initial_data_,
       enable_ping_based_connection_checking_, is_http2_enabled_,
-      is_quic_enabled_, is_trusted_proxy, session_max_recv_window_size_,
+      is_quic_enabled_, session_max_recv_window_size_,
       session_max_queued_capped_frames_, initial_settings_,
       greased_http2_frame_, http2_end_stream_with_data_frame_,
       enable_priority_update_, time_func_, push_delegate_,
diff --git a/net/spdy/spdy_session_pool.h b/net/spdy/spdy_session_pool.h
index fe635b3..694576af 100644
--- a/net/spdy/spdy_session_pool.h
+++ b/net/spdy/spdy_session_pool.h
@@ -170,7 +170,6 @@
   // if the first read of |client_socket_handle| fails.
   int CreateAvailableSessionFromSocketHandle(
       const SpdySessionKey& key,
-      bool is_trusted_proxy,
       std::unique_ptr<ClientSocketHandle> client_socket_handle,
       const NetLogWithSource& net_log,
       base::WeakPtr<SpdySession>* session);
@@ -185,7 +184,6 @@
   // can have sockets above them for tunnels, which are put in a socket pool.
   base::WeakPtr<SpdySession> CreateAvailableSessionFromSocket(
       const SpdySessionKey& key,
-      bool is_trusted_proxy,
       std::unique_ptr<StreamSocket> socket_stream,
       const LoadTimingInfo::ConnectTiming& connect_timing,
       const NetLogWithSource& net_log);
@@ -387,7 +385,6 @@
   // Creates a new session. The session must be initialized before
   // InsertSession() is invoked.
   std::unique_ptr<SpdySession> CreateSession(const SpdySessionKey& key,
-                                             bool is_trusted_proxy,
                                              NetLog* net_log);
   // Adds a new session previously created with CreateSession to the pool.
   // |source_net_log| is the NetLog for the object that created the session.
diff --git a/net/spdy/spdy_session_unittest.cc b/net/spdy/spdy_session_unittest.cc
index 774db474..5c720d1 100644
--- a/net/spdy/spdy_session_unittest.cc
+++ b/net/spdy/spdy_session_unittest.cc
@@ -71,7 +71,6 @@
 namespace {
 
 const char kHttpURLFromAnotherOrigin[] = "http://www.example2.org/a.dat";
-const char kHttpsURLFromAnotherOrigin[] = "https://www.example2.org/b.dat";
 const char kPushedUrl[] = "https://www.example.org/a.dat";
 
 const char kBodyData[] = "Body data";
@@ -218,12 +217,6 @@
         ::net::CreateSpdySession(http_session_.get(), key_, log_.bound());
   }
 
-  void CreateTrustedSpdySession() {
-    DCHECK(!session_);
-    session_ = ::net::CreateTrustedSpdySession(http_session_.get(), key_,
-                                               log_.bound());
-  }
-
   void StallSessionSend() {
     // Reduce the send window size to 0 to stall.
     while (session_send_window_size() > 0) {
@@ -5462,109 +5455,9 @@
   histogram_tester.ExpectTotalCount("Net.SpdyPushedStreamFate", 1);
 }
 
-// Tests that HTTP SPDY push streams that advertise an origin different from the
-// associated stream are accepted from a trusted SPDY proxy.
-TEST_F(SpdySessionTest, TrustedSpdyProxy) {
-  base::HistogramTester histogram_tester;
-
-  // Origin of kDefaultUrl should be different from the origin of
-  // kHttpURLFromAnotherOrigin and kHttpsURLFromAnotherOrigin.
-  ASSERT_NE(GURL(kDefaultUrl).host(), GURL(kHttpURLFromAnotherOrigin).host());
-  ASSERT_NE(GURL(kDefaultUrl).host(), GURL(kHttpsURLFromAnotherOrigin).host());
-
-  // cross_origin_push contains HTTP resource for an origin different from the
-  // origin of kDefaultUrl, and should be accepted.
-  spdy::SpdySerializedFrame cross_origin_push(spdy_util_.ConstructSpdyPush(
-      nullptr, 0, 2, 1, kHttpURLFromAnotherOrigin));
-  // cross_origin_https_push contains HTTPS resource, and should be refused.
-  spdy::SpdySerializedFrame cross_origin_https_push(
-      spdy_util_.ConstructSpdyPush(nullptr, 0, 4, 1,
-                                   kHttpsURLFromAnotherOrigin));
-  MockRead reads[] = {
-      MockRead(ASYNC, ERR_IO_PENDING, 1),
-      CreateMockRead(cross_origin_push, 2),
-      MockRead(ASYNC, ERR_IO_PENDING, 4),
-      CreateMockRead(cross_origin_https_push, 5),
-      MockRead(ASYNC, ERR_IO_PENDING, 7),
-      MockRead(ASYNC, 0, 8),
-  };
-
-  spdy::SpdySerializedFrame req(
-      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
-  spdy::SpdySerializedFrame priority_http(
-      spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
-  spdy::SpdySerializedFrame rst_https(
-      spdy_util_.ConstructSpdyRstStream(4, spdy::ERROR_CODE_REFUSED_STREAM));
-  MockWrite writes[] = {
-      CreateMockWrite(req, 0), CreateMockWrite(priority_http, 3),
-      CreateMockWrite(rst_https, 6),
-  };
-
-  SequencedSocketData data(reads, writes);
-  session_deps_.socket_factory->AddSocketDataProvider(&data);
-
-  AddSSLSocketData();
-
-  CreateNetworkSession();
-  CreateTrustedSpdySession();
-
-  base::WeakPtr<SpdyStream> spdy_stream =
-      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
-                                test_url_, LOWEST, NetLogWithSource());
-  ASSERT_TRUE(spdy_stream);
-  EXPECT_EQ(0u, spdy_stream->stream_id());
-  test::StreamDelegateDoNothing delegate(spdy_stream);
-  spdy_stream->SetDelegate(&delegate);
-
-  EXPECT_EQ(0u, num_active_streams());
-  EXPECT_EQ(1u, num_created_streams());
-  EXPECT_EQ(0u, num_pushed_streams());
-  EXPECT_EQ(0u, num_active_pushed_streams());
-
-  spdy::Http2HeaderBlock headers(
-      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
-  spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
-
-  // Run until 1st stream is activated.
-  EXPECT_EQ(0u, delegate.stream_id());
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(1u, delegate.stream_id());
-  EXPECT_EQ(1u, num_active_streams());
-  EXPECT_EQ(0u, num_created_streams());
-  EXPECT_EQ(0u, num_pushed_streams());
-  EXPECT_EQ(0u, num_active_pushed_streams());
-
-  // Run until pushed stream is created.
-  data.Resume();
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(2u, num_active_streams());
-  EXPECT_EQ(0u, num_created_streams());
-  EXPECT_EQ(1u, num_pushed_streams());
-  EXPECT_EQ(1u, num_active_pushed_streams());
-
-  // Reset incoming pushed stream.
-  data.Resume();
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(2u, num_active_streams());
-  EXPECT_EQ(0u, num_created_streams());
-  EXPECT_EQ(1u, num_pushed_streams());
-  EXPECT_EQ(1u, num_active_pushed_streams());
-
-  // Read EOF.
-  data.Resume();
-  base::RunLoop().RunUntilIdle();
-  EXPECT_FALSE(session_);
-
-  histogram_tester.ExpectBucketCount(
-      "Net.SpdyPushedStreamFate",
-      static_cast<int>(SpdyPushedStreamFate::kNonHttpSchemeFromTrustedProxy),
-      1);
-  histogram_tester.ExpectTotalCount("Net.SpdyPushedStreamFate", 1);
-}
-
-// Tests that if the SPDY trusted proxy is not set, then push streams that
-// advertise an origin different from the associated stream are refused.
-TEST_F(SpdySessionTest, TrustedSpdyProxyNotSet) {
+// Tests that push streams that advertise an origin different from the
+// associated stream are refused.
+TEST_F(SpdySessionTest, StreamsAdvertisingDifferentOriginAreRefused) {
   base::HistogramTester histogram_tester;
 
   // Origin of kDefaultUrl should be different from the origin of
diff --git a/net/spdy/spdy_test_util_common.cc b/net/spdy/spdy_test_util_common.cc
index 0c7ae7a..8a1892a 100644
--- a/net/spdy/spdy_test_util_common.cc
+++ b/net/spdy/spdy_test_util_common.cc
@@ -496,8 +496,7 @@
     HttpNetworkSession* http_session,
     const SpdySessionKey& key,
     const NetLogWithSource& net_log,
-    bool enable_ip_based_pooling,
-    bool is_trusted_proxy) {
+    bool enable_ip_based_pooling) {
   EXPECT_FALSE(http_session->spdy_session_pool()->FindAvailableSession(
       key, enable_ip_based_pooling,
       /* is_websocket = */ false, NetLogWithSource()));
@@ -525,7 +524,7 @@
   base::WeakPtr<SpdySession> spdy_session;
   rv =
       http_session->spdy_session_pool()->CreateAvailableSessionFromSocketHandle(
-          key, is_trusted_proxy, std::move(connection), net_log, &spdy_session);
+          key, std::move(connection), net_log, &spdy_session);
   // Failure is reported asynchronously.
   EXPECT_THAT(rv, IsOk());
   EXPECT_TRUE(spdy_session);
@@ -539,17 +538,7 @@
                                              const SpdySessionKey& key,
                                              const NetLogWithSource& net_log) {
   return CreateSpdySessionHelper(http_session, key, net_log,
-                                 /* enable_ip_based_pooling = */ true,
-                                 /* is_trusted_proxy = */ false);
-}
-
-base::WeakPtr<SpdySession> CreateTrustedSpdySession(
-    HttpNetworkSession* http_session,
-    const SpdySessionKey& key,
-    const NetLogWithSource& net_log) {
-  return CreateSpdySessionHelper(http_session, key, net_log,
-                                 /* enable_ip_based_pooling = */ true,
-                                 /* is_trusted_proxy = */ true);
+                                 /* enable_ip_based_pooling = */ true);
 }
 
 base::WeakPtr<SpdySession> CreateSpdySessionWithIpBasedPoolingDisabled(
@@ -557,8 +546,7 @@
     const SpdySessionKey& key,
     const NetLogWithSource& net_log) {
   return CreateSpdySessionHelper(http_session, key, net_log,
-                                 /* enable_ip_based_pooling = */ false,
-                                 /* is_trusted_proxy = */ false);
+                                 /* enable_ip_based_pooling = */ false);
 }
 
 namespace {
@@ -626,8 +614,7 @@
   handle->SetSocket(std::make_unique<FakeSpdySessionClientSocket>());
   base::WeakPtr<SpdySession> spdy_session;
   int rv = pool->CreateAvailableSessionFromSocketHandle(
-      key, /*is_trusted_proxy=*/false, std::move(handle), NetLogWithSource(),
-      &spdy_session);
+      key, std::move(handle), NetLogWithSource(), &spdy_session);
   // Failure is reported asynchronously.
   EXPECT_THAT(rv, IsOk());
   EXPECT_TRUE(spdy_session);
diff --git a/net/spdy/spdy_test_util_common.h b/net/spdy/spdy_test_util_common.h
index 4f2ffd0..d5defb17 100644
--- a/net/spdy/spdy_test_util_common.h
+++ b/net/spdy/spdy_test_util_common.h
@@ -264,13 +264,6 @@
                                              const SpdySessionKey& key,
                                              const NetLogWithSource& net_log);
 
-// Like CreateSpdySession(), but the host is considered a trusted proxy and
-// allowed to push cross-origin resources.
-base::WeakPtr<SpdySession> CreateTrustedSpdySession(
-    HttpNetworkSession* http_session,
-    const SpdySessionKey& key,
-    const NetLogWithSource& net_log);
-
 // Like CreateSpdySession(), but does not fail if there is already an IP
 // pooled session for |key|.
 base::WeakPtr<SpdySession> CreateSpdySessionWithIpBasedPoolingDisabled(
diff --git a/pdf/features.gni b/pdf/features.gni
index 8b7c813..4fe9c63 100644
--- a/pdf/features.gni
+++ b/pdf/features.gni
@@ -9,7 +9,11 @@
 # disabled.
 
 declare_args() {
-  enable_pdf = !is_android && !is_ios && !is_chromecast
+  # TODO(crbug.com/702993): Currently disabled on Fuchsia because the PDF Viewer
+  # currently depends on PPAPI. It does not make sense to port PPAPI, which is
+  # being deprecated, to Fuchsia. Once the PDF Viewer no longer uses PPAPI, the
+  # PDF Viewer should be enabled on Fuchsia, like on other desktop platforms.
+  enable_pdf = !is_android && !is_ios && !is_chromecast && !is_fuchsia
 
   # Enable additional code for the Pepper-free PDF viewer.
   #
diff --git a/remoting/client/notification/json_fetcher.h b/remoting/client/notification/json_fetcher.h
index e9cad3c..69024b58 100644
--- a/remoting/client/notification/json_fetcher.h
+++ b/remoting/client/notification/json_fetcher.h
@@ -8,6 +8,7 @@
 #include <string>
 
 #include "base/callback_forward.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class Value;
@@ -42,4 +43,4 @@
 
 }  // namespace remoting
 
-#endif  // REMOTING_CLIENT_NOTIFICATION_JSON_FETCHER_H_
\ No newline at end of file
+#endif  // REMOTING_CLIENT_NOTIFICATION_JSON_FETCHER_H_
diff --git a/services/network/first_party_sets/first_party_set_parser.cc b/services/network/first_party_sets/first_party_set_parser.cc
index 3fa4ab80..fa3804e3 100644
--- a/services/network/first_party_sets/first_party_set_parser.cc
+++ b/services/network/first_party_sets/first_party_set_parser.cc
@@ -4,8 +4,6 @@
 
 #include "services/network/first_party_sets/first_party_set_parser.h"
 
-#include <iterator>
-#include <memory>
 #include <string>
 #include <utility>
 
@@ -125,21 +123,20 @@
   return Canonicalize(origin_string, emit_errors);
 }
 
-std::unique_ptr<base::flat_map<net::SchemefulSite, net::SchemefulSite>>
+base::flat_map<net::SchemefulSite, net::SchemefulSite>
 FirstPartySetParser::ParseSetsFromComponentUpdater(base::StringPiece raw_sets) {
   absl::optional<base::Value> maybe_value = base::JSONReader::Read(
       raw_sets, base::JSONParserOptions::JSON_ALLOW_TRAILING_COMMAS);
   if (!maybe_value.has_value())
-    return nullptr;
+    return {};
   if (!maybe_value->is_list())
-    return nullptr;
+    return {};
 
-  auto map = std::make_unique<
-      base::flat_map<net::SchemefulSite, net::SchemefulSite>>();
+  base::flat_map<net::SchemefulSite, net::SchemefulSite> map;
   base::flat_set<net::SchemefulSite> elements;
   for (const auto& value : maybe_value->GetList()) {
-    if (!ParseSet(value, *map, elements))
-      return nullptr;
+    if (!ParseSet(value, map, elements))
+      return {};
   }
 
   return map;
diff --git a/services/network/first_party_sets/first_party_set_parser.h b/services/network/first_party_sets/first_party_set_parser.h
index 4a332e62..7dbf7b2 100644
--- a/services/network/first_party_sets/first_party_set_parser.h
+++ b/services/network/first_party_sets/first_party_set_parser.h
@@ -5,10 +5,6 @@
 #ifndef SERVICES_NETWORK_FIRST_PARTY_SETS_FIRST_PARTY_SET_PARSER_H_
 #define SERVICES_NETWORK_FIRST_PARTY_SETS_FIRST_PARTY_SET_PARSER_H_
 
-#include <map>
-#include <memory>
-#include <string>
-
 #include "base/callback.h"
 #include "base/containers/flat_map.h"
 #include "base/strings/string_piece_forward.h"
@@ -34,8 +30,8 @@
   // This function does not check versions or assertions, since it is intended
   // only for sets received by Component Updater.
   //
-  // Returns nullptr if parsing or validation of any set failed.
-  static std::unique_ptr<base::flat_map<net::SchemefulSite, net::SchemefulSite>>
+  // Returns an empty map if parsing or validation of any set failed.
+  static base::flat_map<net::SchemefulSite, net::SchemefulSite>
   ParseSetsFromComponentUpdater(base::StringPiece raw_sets);
 
   // Canonicalizes the passed in origin to a registered domain. In particular,
diff --git a/services/network/first_party_sets/first_party_set_parser_unittest.cc b/services/network/first_party_sets/first_party_set_parser_unittest.cc
index 485890b..481047ac 100644
--- a/services/network/first_party_sets/first_party_set_parser_unittest.cc
+++ b/services/network/first_party_sets/first_party_set_parser_unittest.cc
@@ -8,11 +8,10 @@
 #include "net/base/schemeful_site.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 using ::testing::IsEmpty;
-using ::testing::IsNull;
 using ::testing::Pair;
-using ::testing::Pointee;
 using ::testing::UnorderedElementsAre;
 
 namespace network {
@@ -27,7 +26,8 @@
   // reject it. In particular, we should reject
   // empty input.
 
-  EXPECT_FALSE(FirstPartySetParser::ParseSetsFromComponentUpdater(""));
+  EXPECT_THAT(FirstPartySetParser::ParseSetsFromComponentUpdater(""),
+              IsEmpty());
 }
 
 TEST(FirstPartySetParser, RejectsNonemptyMalformed) {
@@ -38,7 +38,8 @@
   // Sanity check that the input is not valid JSON.
   ASSERT_FALSE(base::JSONReader::Read(input));
 
-  EXPECT_FALSE(FirstPartySetParser::ParseSetsFromComponentUpdater(input));
+  EXPECT_THAT(FirstPartySetParser::ParseSetsFromComponentUpdater(input),
+              IsEmpty());
 }
 
 TEST(FirstPartySetParser, RejectsNonListInput) {
@@ -46,7 +47,8 @@
   const std::string input = "{}";
   ASSERT_TRUE(base::JSONReader::Read(input));
 
-  EXPECT_FALSE(FirstPartySetParser::ParseSetsFromComponentUpdater(input));
+  EXPECT_THAT(FirstPartySetParser::ParseSetsFromComponentUpdater(input),
+              IsEmpty());
 }
 
 TEST(FirstPartySetParser, AcceptsTrivial) {
@@ -56,7 +58,7 @@
   ASSERT_TRUE(base::JSONReader::Read(input));
 
   EXPECT_THAT(FirstPartySetParser::ParseSetsFromComponentUpdater(input),
-              Pointee(IsEmpty()));
+              IsEmpty());
 }
 
 TEST(FirstPartySetParser, RejectsSingletonSet) {
@@ -69,7 +71,8 @@
   // Sanity check that the input is actually valid JSON.
   ASSERT_TRUE(base::JSONReader::Read(input));
 
-  EXPECT_FALSE(FirstPartySetParser::ParseSetsFromComponentUpdater(input));
+  EXPECT_THAT(FirstPartySetParser::ParseSetsFromComponentUpdater(input),
+              IsEmpty());
 }
 
 TEST(FirstPartySetParser, AcceptsMinimal) {
@@ -83,11 +86,10 @@
   ASSERT_TRUE(base::JSONReader::Read(input));
 
   EXPECT_THAT(FirstPartySetParser::ParseSetsFromComponentUpdater(input),
-              Pointee(UnorderedElementsAre(
-                  Pair(SerializesTo("https://example.test"),
-                       SerializesTo("https://example.test")),
-                  Pair(SerializesTo("https://aaaa.test"),
-                       SerializesTo("https://example.test")))));
+              UnorderedElementsAre(Pair(SerializesTo("https://example.test"),
+                                        SerializesTo("https://example.test")),
+                                   Pair(SerializesTo("https://aaaa.test"),
+                                        SerializesTo("https://example.test"))));
 }
 
 TEST(FirstPartySetParser, RejectsMissingOwner) {
@@ -97,7 +99,7 @@
   ASSERT_TRUE(base::JSONReader::Read(input));
 
   EXPECT_THAT(FirstPartySetParser::ParseSetsFromComponentUpdater(input),
-              IsNull());
+              IsEmpty());
 }
 
 TEST(FirstPartySetParser, RejectsTypeUnsafeOwner) {
@@ -108,7 +110,7 @@
   ASSERT_TRUE(base::JSONReader::Read(input));
 
   EXPECT_THAT(FirstPartySetParser::ParseSetsFromComponentUpdater(input),
-              IsNull());
+              IsEmpty());
 }
 
 TEST(FirstPartySetParser, RejectsNonHTTPSOwner) {
@@ -122,7 +124,7 @@
   ASSERT_TRUE(base::JSONReader::Read(input));
 
   EXPECT_THAT(FirstPartySetParser::ParseSetsFromComponentUpdater(input),
-              IsNull());
+              IsEmpty());
 }
 
 TEST(FirstPartySetParser, RejectsNonOriginOwner) {
@@ -136,7 +138,7 @@
   ASSERT_TRUE(base::JSONReader::Read(input));
 
   EXPECT_THAT(FirstPartySetParser::ParseSetsFromComponentUpdater(input),
-              IsNull());
+              IsEmpty());
 }
 
 TEST(FirstPartySetParser, RejectsOwnerWithoutRegisteredDomain) {
@@ -150,7 +152,7 @@
   ASSERT_TRUE(base::JSONReader::Read(input));
 
   EXPECT_THAT(FirstPartySetParser::ParseSetsFromComponentUpdater(input),
-              IsNull());
+              IsEmpty());
 }
 
 TEST(FirstPartySetParser, RejectsMissingMembers) {
@@ -160,7 +162,7 @@
   ASSERT_TRUE(base::JSONReader::Read(input));
 
   EXPECT_THAT(FirstPartySetParser::ParseSetsFromComponentUpdater(input),
-              IsNull());
+              IsEmpty());
 }
 
 TEST(FirstPartySetParser, RejectsTypeUnsafeMembers) {
@@ -174,7 +176,7 @@
   ASSERT_TRUE(base::JSONReader::Read(input));
 
   EXPECT_THAT(FirstPartySetParser::ParseSetsFromComponentUpdater(input),
-              IsNull());
+              IsEmpty());
 }
 
 TEST(FirstPartySetParser, RejectsNonHTTPSMember) {
@@ -188,7 +190,7 @@
   ASSERT_TRUE(base::JSONReader::Read(input));
 
   EXPECT_THAT(FirstPartySetParser::ParseSetsFromComponentUpdater(input),
-              IsNull());
+              IsEmpty());
 }
 
 TEST(FirstPartySetParser, RejectsNonOriginMember) {
@@ -202,7 +204,7 @@
   ASSERT_TRUE(base::JSONReader::Read(input));
 
   EXPECT_THAT(FirstPartySetParser::ParseSetsFromComponentUpdater(input),
-              IsNull());
+              IsEmpty());
 }
 
 TEST(FirstPartySetParser, RejectsMemberWithoutRegisteredDomain) {
@@ -216,7 +218,7 @@
   ASSERT_TRUE(base::JSONReader::Read(input));
 
   EXPECT_THAT(FirstPartySetParser::ParseSetsFromComponentUpdater(input),
-              IsNull());
+              IsEmpty());
 }
 
 TEST(FirstPartySetParser, TruncatesSubdomain_Owner) {
@@ -230,11 +232,10 @@
   ASSERT_TRUE(base::JSONReader::Read(input));
 
   EXPECT_THAT(FirstPartySetParser::ParseSetsFromComponentUpdater(input),
-              Pointee(UnorderedElementsAre(
-                  Pair(SerializesTo("https://example.test"),
-                       SerializesTo("https://example.test")),
-                  Pair(SerializesTo("https://aaaa.test"),
-                       SerializesTo("https://example.test")))));
+              UnorderedElementsAre(Pair(SerializesTo("https://example.test"),
+                                        SerializesTo("https://example.test")),
+                                   Pair(SerializesTo("https://aaaa.test"),
+                                        SerializesTo("https://example.test"))));
 }
 
 TEST(FirstPartySetParser, TruncatesSubdomain_Member) {
@@ -248,11 +249,10 @@
   ASSERT_TRUE(base::JSONReader::Read(input));
 
   EXPECT_THAT(FirstPartySetParser::ParseSetsFromComponentUpdater(input),
-              Pointee(UnorderedElementsAre(
-                  Pair(SerializesTo("https://example.test"),
-                       SerializesTo("https://example.test")),
-                  Pair(SerializesTo("https://aaaa.test"),
-                       SerializesTo("https://example.test")))));
+              UnorderedElementsAre(Pair(SerializesTo("https://example.test"),
+                                        SerializesTo("https://example.test")),
+                                   Pair(SerializesTo("https://aaaa.test"),
+                                        SerializesTo("https://example.test"))));
 }
 
 TEST(FirstPartySetParser, AcceptsMultipleSets) {
@@ -272,16 +272,15 @@
   // Sanity check that the input is actually valid JSON.
   ASSERT_TRUE(base::JSONReader::Read(input));
 
-  EXPECT_THAT(
-      FirstPartySetParser::ParseSetsFromComponentUpdater(input),
-      Pointee(UnorderedElementsAre(Pair(SerializesTo("https://example.test"),
+  EXPECT_THAT(FirstPartySetParser::ParseSetsFromComponentUpdater(input),
+              UnorderedElementsAre(Pair(SerializesTo("https://example.test"),
                                         SerializesTo("https://example.test")),
                                    Pair(SerializesTo("https://member1.test"),
                                         SerializesTo("https://example.test")),
                                    Pair(SerializesTo("https://foo.test"),
                                         SerializesTo("https://foo.test")),
                                    Pair(SerializesTo("https://member2.test"),
-                                        SerializesTo("https://foo.test")))));
+                                        SerializesTo("https://foo.test"))));
 }
 
 TEST(FirstPartySetParser, RejectsInvalidSets_InvalidOwner) {
@@ -302,7 +301,7 @@
   ASSERT_TRUE(base::JSONReader::Read(input));
 
   EXPECT_THAT(FirstPartySetParser::ParseSetsFromComponentUpdater(input),
-              IsNull());
+              IsEmpty());
 }
 
 TEST(FirstPartySetParser, RejectsInvalidSets_InvalidMember) {
@@ -323,7 +322,7 @@
   ASSERT_TRUE(base::JSONReader::Read(input));
 
   EXPECT_THAT(FirstPartySetParser::ParseSetsFromComponentUpdater(input),
-              IsNull());
+              IsEmpty());
 }
 
 TEST(FirstPartySetParser, AllowsTrailingCommas) {
@@ -341,11 +340,10 @@
       input, base::JSONParserOptions::JSON_ALLOW_TRAILING_COMMAS));
 
   EXPECT_THAT(FirstPartySetParser::ParseSetsFromComponentUpdater(input),
-              Pointee(UnorderedElementsAre(
-                  Pair(SerializesTo("https://example.test"),
-                       SerializesTo("https://example.test")),
-                  Pair(SerializesTo("https://member1.test"),
-                       SerializesTo("https://example.test")))));
+              UnorderedElementsAre(Pair(SerializesTo("https://example.test"),
+                                        SerializesTo("https://example.test")),
+                                   Pair(SerializesTo("https://member1.test"),
+                                        SerializesTo("https://example.test"))));
 }
 
 TEST(FirstPartySetParser, Rejects_SameOwner) {
@@ -366,7 +364,7 @@
   ASSERT_TRUE(base::JSONReader::Read(input));
 
   EXPECT_THAT(FirstPartySetParser::ParseSetsFromComponentUpdater(input),
-              IsNull());
+              IsEmpty());
 }
 
 TEST(FirstPartySetParser, Rejects_MemberAsOwner) {
@@ -387,7 +385,7 @@
   ASSERT_TRUE(base::JSONReader::Read(input));
 
   EXPECT_THAT(FirstPartySetParser::ParseSetsFromComponentUpdater(input),
-              IsNull());
+              IsEmpty());
 }
 
 TEST(FirstPartySetParser, Rejects_SameMember) {
@@ -408,7 +406,7 @@
   ASSERT_TRUE(base::JSONReader::Read(input));
 
   EXPECT_THAT(FirstPartySetParser::ParseSetsFromComponentUpdater(input),
-              IsNull());
+              IsEmpty());
 }
 
 TEST(FirstPartySetParser, Rejects_OwnerAsMember) {
@@ -429,7 +427,7 @@
   ASSERT_TRUE(base::JSONReader::Read(input));
 
   EXPECT_THAT(FirstPartySetParser::ParseSetsFromComponentUpdater(input),
-              IsNull());
+              IsEmpty());
 }
 
 }  // namespace network
diff --git a/services/network/first_party_sets/first_party_sets.cc b/services/network/first_party_sets/first_party_sets.cc
index 796d2e68..334bd67 100644
--- a/services/network/first_party_sets/first_party_sets.cc
+++ b/services/network/first_party_sets/first_party_sets.cc
@@ -5,7 +5,9 @@
 #include "services/network/first_party_sets/first_party_sets.h"
 
 #include <initializer_list>
-#include <memory>
+#include <set>
+#include <utility>
+#include <vector>
 
 #include "base/containers/contains.h"
 #include "base/logging.h"
@@ -68,15 +70,7 @@
 
 base::flat_map<net::SchemefulSite, net::SchemefulSite>*
 FirstPartySets::ParseAndSet(base::StringPiece raw_sets) {
-  std::unique_ptr<base::flat_map<net::SchemefulSite, net::SchemefulSite>>
-      parsed = FirstPartySetParser::ParseSetsFromComponentUpdater(raw_sets);
-  if (parsed) {
-    sets_.swap(*parsed);
-  } else {
-    // On any error, we clear the sets, to avoid using the old data and to make
-    // the failure as obvious as possible.
-    sets_.clear();
-  }
+  sets_ = FirstPartySetParser::ParseSetsFromComponentUpdater(raw_sets);
   ApplyManuallySpecifiedSet();
   return &sets_;
 }
diff --git a/services/network/public/cpp/net_ipc_param_traits.cc b/services/network/public/cpp/net_ipc_param_traits.cc
index 897034b..c65f02d11 100644
--- a/services/network/public/cpp/net_ipc_param_traits.cc
+++ b/services/network/public/cpp/net_ipc_param_traits.cc
@@ -224,14 +224,12 @@
       scheme != net::ProxyServer::SCHEME_INVALID) {
     WriteParam(m, p.host_port_pair());
   }
-  WriteParam(m, p.is_trusted_proxy());
 }
 
 bool ParamTraits<net::ProxyServer>::Read(const base::Pickle* m,
                                          base::PickleIterator* iter,
                                          param_type* r) {
   net::ProxyServer::Scheme scheme;
-  bool is_trusted_proxy = false;
   if (!ReadParam(m, iter, &scheme))
     return false;
 
@@ -244,10 +242,7 @@
     return false;
   }
 
-  if (!ReadParam(m, iter, &is_trusted_proxy))
-    return false;
-
-  *r = net::ProxyServer(scheme, host_port_pair, is_trusted_proxy);
+  *r = net::ProxyServer(scheme, host_port_pair);
   return true;
 }
 
diff --git a/storage/browser/BUILD.gn b/storage/browser/BUILD.gn
index 4829ac5..025683c 100644
--- a/storage/browser/BUILD.gn
+++ b/storage/browser/BUILD.gn
@@ -233,7 +233,7 @@
     "//base:i18n",
     "//base/third_party/dynamic_annotations",
     "//build:chromeos_buildflags",
-    "//components/services/storage/public/cpp/filesystem",
+    "//components/services/storage/public/cpp",
     "//mojo/public/cpp/bindings",
     "//net",
     "//services/network:network_service",
@@ -335,7 +335,7 @@
     "//base/test:test_support",
     "//build:chromeos_buildflags",
     "//components/services/filesystem/public/mojom",
-    "//components/services/storage/public/cpp/filesystem",
+    "//components/services/storage/public/cpp",
     "//mojo/public/cpp/system",
     "//net:test_support",
     "//services/network/public/cpp",
diff --git a/storage/browser/quota/quota_database.cc b/storage/browser/quota/quota_database.cc
index 8658777..075ca3a 100644
--- a/storage/browser/quota/quota_database.cc
+++ b/storage/browser/quota/quota_database.cc
@@ -165,6 +165,79 @@
   return true;
 }
 
+QuotaErrorOr<BucketId> QuotaDatabase::CreateBucket(
+    const url::Origin& origin,
+    const std::string& bucket_name) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  // TODO(crbug/1210259): Add DCHECKs for input validation.
+  if (!LazyOpen(/*create_if_needed=*/true))
+    return QuotaError::kDatabaseError;
+
+  // TODO(crbug/1210252): Update to not execute 2 sql statements on creation.
+  QuotaErrorOr<BucketId> bucket_result = GetBucketId(origin, bucket_name);
+  if (!bucket_result.ok())
+    return bucket_result.error();
+
+  if (!bucket_result.value().is_null())
+    return QuotaError::kEntryExistsError;
+
+  base::Time now = base::Time::Now();
+  static constexpr char kSql[] =
+      // clang-format off
+      "INSERT INTO buckets("
+        "origin,"
+        "type,"
+        "name,"
+        "use_count,"
+        "last_accessed,"
+        "last_modified,"
+        "expiration,"
+        "quota) "
+        "VALUES (?, 0, ?, 0, ?, ?, ?, 0)";
+  // clang-format on
+  sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql));
+  // Bucket usage is only for temporary storage types.
+  static_assert(static_cast<int>(StorageType::kTemporary) == 0,
+                "The type value baked in the SQL statement above is wrong.");
+  statement.BindString(0, origin.GetURL().spec());
+  statement.BindString(1, bucket_name);
+  statement.BindTime(2, now);
+  statement.BindTime(3, now);
+  statement.BindTime(4, base::Time::Max());
+
+  if (!statement.Run())
+    return QuotaError::kDatabaseError;
+
+  ScheduleCommit();
+
+  int64_t bucket_id = db_->GetLastInsertRowId();
+  DCHECK_GT(bucket_id, 0);
+  return BucketId(bucket_id);
+}
+
+QuotaErrorOr<BucketId> QuotaDatabase::GetBucketId(
+    const url::Origin& origin,
+    const std::string& bucket_name) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  if (!LazyOpen(/*create_if_needed=*/true))
+    return QuotaError::kDatabaseError;
+
+  static constexpr char kSql[] =
+      "SELECT id FROM buckets WHERE origin = ? AND type = ? AND name = ?";
+  sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql));
+  statement.BindString(0, origin.GetURL().spec());
+  // Bucket usage is only for temporary storage types.
+  statement.BindInt(1, static_cast<int>(StorageType::kTemporary));
+  statement.BindString(2, bucket_name);
+
+  if (!statement.Step()) {
+    return statement.Succeeded()
+               ? QuotaErrorOr<BucketId>(BucketId())
+               : QuotaErrorOr<BucketId>(QuotaError::kDatabaseError);
+  }
+  return BucketId(statement.ColumnInt64(0));
+}
+
 bool QuotaDatabase::SetOriginLastAccessTime(const url::Origin& origin,
                                             StorageType type,
                                             base::Time last_accessed) {
diff --git a/storage/browser/quota/quota_database.h b/storage/browser/quota/quota_database.h
index 71ad79df..416d068b9 100644
--- a/storage/browser/quota/quota_database.h
+++ b/storage/browser/quota/quota_database.h
@@ -19,6 +19,8 @@
 #include "base/sequence_checker.h"
 #include "base/time/time.h"
 #include "base/timer/timer.h"
+#include "base/util/type_safety/id_type.h"
+#include "components/services/storage/public/cpp/quota_error_or.h"
 #include "third_party/blink/public/mojom/quota/quota_types.mojom-shared.h"
 #include "url/origin.h"
 
@@ -31,6 +33,9 @@
 
 class SpecialStoragePolicy;
 
+// IDs will always be generated by SQLite, and all valid BucketIds are positive.
+using BucketId = util::IdType64<class BucketTag>;
+
 // Stores all quota managed origin bucket data and metadata.
 //
 // Instances are owned by QuotaManagerImpl. There is one instance per
@@ -75,6 +80,19 @@
                     int64_t quota);
   bool DeleteHostQuota(const std::string& host, blink::mojom::StorageType type);
 
+  // Creates a bucket with `bucket_name` for the `origin` and returns the bucket
+  // id. Returns an QuotaError if a bucket with the same `bucket_name` for an
+  // `origin` already exists or if the operation has failed.
+  // TODO(crbug/1203467): Include more policies when supported.
+  QuotaErrorOr<BucketId> CreateBucket(const url::Origin& origin,
+                                      const std::string& bucket_name);
+
+  // Retrieves the bucket id of the bucket with `bucket_name` for `origin`.
+  // If one does not exist, it will return an empty BucketId. Returns an error
+  // if the operation has failed.
+  QuotaErrorOr<BucketId> GetBucketId(const url::Origin& origin,
+                                     const std::string& bucket_name);
+
   // TODO(crbug.com/1202167): Remove once all usages have updated to use
   // SetBucketLastAccessTime.
   bool SetOriginLastAccessTime(const url::Origin& origin,
diff --git a/storage/browser/quota/quota_database_unittest.cc b/storage/browser/quota/quota_database_unittest.cc
index 4001b9ea..62028a5 100644
--- a/storage/browser/quota/quota_database_unittest.cc
+++ b/storage/browser/quota/quota_database_unittest.cc
@@ -199,6 +199,50 @@
   EXPECT_FALSE(db.GetHostQuota(kHost, kPerm, &quota));
 }
 
+TEST_P(QuotaDatabaseTest, CreateBucket) {
+  QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath());
+  EXPECT_TRUE(LazyOpen(&db, /*create_if_needed=*/true));
+  url::Origin origin = ToOrigin("http://google/");
+  std::string bucket_name = "google_bucket";
+
+  QuotaErrorOr<BucketId> result = db.CreateBucket(origin, bucket_name);
+  ASSERT_TRUE(result.ok());
+  ASSERT_FALSE(result.value().is_null());
+
+  // Trying to create an existing bucket should return false.
+  result = db.CreateBucket(origin, bucket_name);
+  ASSERT_FALSE(result.ok());
+  EXPECT_EQ(result.error(), QuotaError::kEntryExistsError);
+}
+
+TEST_P(QuotaDatabaseTest, GetBucketId) {
+  QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath());
+  EXPECT_TRUE(LazyOpen(&db, /*create_if_needed=*/true));
+
+  // Add a bucket entry into the bucket table.
+  url::Origin origin = ToOrigin("http://google/");
+  std::string bucket_name = "google_bucket";
+  QuotaErrorOr<BucketId> result = db.CreateBucket(origin, bucket_name);
+  ASSERT_TRUE(result.ok());
+
+  BucketId created_bucket_id = result.value();
+  ASSERT_FALSE(created_bucket_id.is_null());
+
+  db.GetBucketId(origin, bucket_name);
+  ASSERT_TRUE(result.ok());
+  EXPECT_EQ(result.value(), created_bucket_id);
+
+  // Can't retrieve buckets with name mismatch.
+  result = db.GetBucketId(origin, "does_not_exist");
+  ASSERT_TRUE(result.ok());
+  EXPECT_TRUE(result.value().is_null());
+
+  // Can't retrieve buckets with origin mismatch.
+  result = db.GetBucketId(ToOrigin("http://example/"), bucket_name);
+  ASSERT_TRUE(result.ok());
+  EXPECT_TRUE(result.value().is_null());
+}
+
 TEST_P(QuotaDatabaseTest, OriginLastAccessTimeLRU) {
   QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath());
   EXPECT_TRUE(LazyOpen(&db, /*create_if_needed=*/true));
diff --git a/storage/browser/quota/quota_manager_impl.cc b/storage/browser/quota/quota_manager_impl.cc
index fc99a89..017884bd 100644
--- a/storage/browser/quota/quota_manager_impl.cc
+++ b/storage/browser/quota/quota_manager_impl.cc
@@ -90,6 +90,20 @@
   return type == StorageType::kTemporary || type == StorageType::kPersistent;
 }
 
+QuotaErrorOr<BucketId> CreateBucketOnDBThread(const url::Origin& origin,
+                                              const std::string& bucket_name,
+                                              QuotaDatabase* database) {
+  DCHECK(database);
+  return database->CreateBucket(origin, bucket_name);
+}
+
+QuotaErrorOr<BucketId> GetBucketIdOnDBThread(const url::Origin& origin,
+                                             const std::string& bucket_name,
+                                             QuotaDatabase* database) {
+  DCHECK(database);
+  return database->GetBucketId(origin, bucket_name);
+}
+
 bool GetPersistentHostQuotaOnDBThread(const std::string& host,
                                       int64_t* quota,
                                       QuotaDatabase* database) {
@@ -939,6 +953,32 @@
   settings_timestamp_ = base::TimeTicks::Now();
 }
 
+void QuotaManagerImpl::CreateBucket(
+    const url::Origin& origin,
+    const std::string& bucket_name,
+    base::OnceCallback<void(QuotaErrorOr<BucketId>)> callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  LazyInitialize();
+
+  PostTaskAndReplyWithResultForDBThread(
+      base::BindOnce(&CreateBucketOnDBThread, origin, bucket_name),
+      base::BindOnce(&QuotaManagerImpl::DidGetBucketId,
+                     weak_factory_.GetWeakPtr(), std::move(callback)));
+}
+
+void QuotaManagerImpl::GetBucketId(
+    const url::Origin& origin,
+    const std::string& bucket_name,
+    base::OnceCallback<void(QuotaErrorOr<BucketId>)> callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  LazyInitialize();
+
+  PostTaskAndReplyWithResultForDBThread(
+      base::BindOnce(&GetBucketIdOnDBThread, origin, bucket_name),
+      base::BindOnce(&QuotaManagerImpl::DidGetBucketId,
+                     weak_factory_.GetWeakPtr(), std::move(callback)));
+}
+
 void QuotaManagerImpl::GetUsageInfo(GetUsageInfoCallback callback) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   LazyInitialize();
@@ -1950,6 +1990,14 @@
   db_disabled_ = !success;
 }
 
+void QuotaManagerImpl::DidGetBucketId(
+    base::OnceCallback<void(QuotaErrorOr<BucketId>)> callback,
+    QuotaErrorOr<BucketId> result) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  DidDatabaseWork(result.ok());
+  std::move(callback).Run(std::move(result));
+}
+
 void QuotaManagerImpl::PostTaskAndReplyWithResultForDBThread(
     const base::Location& from_here,
     base::OnceCallback<bool(QuotaDatabase*)> task,
@@ -1964,6 +2012,21 @@
       std::move(reply));
 }
 
+template <typename ValueType>
+void QuotaManagerImpl::PostTaskAndReplyWithResultForDBThread(
+    base::OnceCallback<QuotaErrorOr<ValueType>(QuotaDatabase*)> task,
+    base::OnceCallback<void(QuotaErrorOr<ValueType>)> reply,
+    const base::Location& from_here) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  // Deleting manager will post another task to DB sequence to delete
+  // |database_|, therefore we can be sure that database_ is alive when this
+  // task runs.
+  base::PostTaskAndReplyWithResult(
+      db_runner_.get(), from_here,
+      base::BindOnce(std::move(task), base::Unretained(database_.get())),
+      std::move(reply));
+}
+
 // static
 std::tuple<int64_t, int64_t> QuotaManagerImpl::CallGetVolumeInfo(
     GetVolumeInfoFn get_volume_info_fn,
diff --git a/storage/browser/quota/quota_manager_impl.h b/storage/browser/quota/quota_manager_impl.h
index 8e70ef97..01701a0 100644
--- a/storage/browser/quota/quota_manager_impl.h
+++ b/storage/browser/quota/quota_manager_impl.h
@@ -28,6 +28,7 @@
 #include "base/sequence_checker.h"
 #include "base/time/time.h"
 #include "base/timer/timer.h"
+#include "components/services/storage/public/cpp/quota_error_or.h"
 #include "components/services/storage/public/mojom/quota_client.mojom.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/remote.h"
@@ -160,6 +161,19 @@
   // Returns a proxy object that can be used on any thread.
   QuotaManagerProxy* proxy() { return proxy_.get(); }
 
+  // Creates a bucket for `origin` with `bucket_name` and returns the BucketId
+  // to the callback. Will return a QuotaError to the callback on failure.
+  void CreateBucket(const url::Origin& origin,
+                    const std::string& bucket_name,
+                    base::OnceCallback<void(QuotaErrorOr<BucketId>)>);
+
+  // Retrieves the BucketId of the bucket with `bucket_name` for `origin` and
+  // returns it to the callback. Will return an empty BucketId if a bucket does
+  // not exist. Will return a QuotaError on operation failure.
+  void GetBucketId(const url::Origin& origin,
+                   const std::string& bucket_name,
+                   base::OnceCallback<void(QuotaErrorOr<BucketId>)>);
+
   // Called by clients or webapps. Returns usage per host.
   void GetUsageInfo(GetUsageInfoCallback callback);
 
@@ -481,6 +495,9 @@
 
   void DidDatabaseWork(bool success);
 
+  void DidGetBucketId(base::OnceCallback<void(QuotaErrorOr<BucketId>)> callback,
+                      QuotaErrorOr<BucketId> result);
+
   void DeleteOnCorrectThread() const;
 
   void MaybeRunStoragePressureCallback(const url::Origin& origin,
@@ -500,11 +517,18 @@
 
   absl::optional<int64_t> GetQuotaOverrideForOrigin(const url::Origin&);
 
+  // TODO(ayui): Replace instances to use result with QuotaErrorOr.
   void PostTaskAndReplyWithResultForDBThread(
       const base::Location& from_here,
       base::OnceCallback<bool(QuotaDatabase*)> task,
       base::OnceCallback<void(bool)> reply);
 
+  template <typename ValueType>
+  void PostTaskAndReplyWithResultForDBThread(
+      base::OnceCallback<QuotaErrorOr<ValueType>(QuotaDatabase*)> task,
+      base::OnceCallback<void(QuotaErrorOr<ValueType>)> reply,
+      const base::Location& from_here = base::Location::Current());
+
   static std::tuple<int64_t, int64_t> CallGetVolumeInfo(
       GetVolumeInfoFn get_volume_info_fn,
       const base::FilePath& path);
diff --git a/storage/browser/quota/quota_manager_proxy.cc b/storage/browser/quota/quota_manager_proxy.cc
index a9b055a..44cdffe 100644
--- a/storage/browser/quota/quota_manager_proxy.cc
+++ b/storage/browser/quota/quota_manager_proxy.cc
@@ -28,6 +28,22 @@
 
 namespace storage {
 
+namespace {
+
+void DidGetBucketId(
+    scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
+    base::OnceCallback<void(QuotaErrorOr<BucketId>)> callback,
+    QuotaErrorOr<BucketId> result) {
+  if (callback_task_runner->RunsTasksInCurrentSequence()) {
+    std::move(callback).Run(std::move(result));
+    return;
+  }
+  callback_task_runner->PostTask(
+      FROM_HERE, base::BindOnce(std::move(callback), std::move(result)));
+}
+
+}  // namespace
+
 QuotaManagerProxy::QuotaManagerProxy(
     QuotaManagerImpl* quota_manager_impl,
     scoped_refptr<base::SequencedTaskRunner> quota_manager_impl_task_runner)
@@ -80,6 +96,59 @@
   }
 }
 
+void QuotaManagerProxy::CreateBucket(
+    const url::Origin& origin,
+    const std::string& bucket_name,
+    scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
+    base::OnceCallback<void(QuotaErrorOr<BucketId>)> callback) {
+  if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) {
+    quota_manager_impl_task_runner_->PostTask(
+        FROM_HERE,
+        base::BindOnce(&QuotaManagerProxy::CreateBucket, this, origin,
+                       bucket_name, std::move(callback_task_runner),
+                       std::move(callback)));
+    return;
+  }
+
+  DCHECK_CALLED_ON_VALID_SEQUENCE(quota_manager_impl_sequence_checker_);
+  if (!quota_manager_impl_) {
+    DidGetBucketId(std::move(callback_task_runner), std::move(callback),
+                   QuotaErrorOr<BucketId>(QuotaError::kUnknownError));
+    return;
+  }
+
+  quota_manager_impl_->CreateBucket(
+      origin, bucket_name,
+      base::BindOnce(&DidGetBucketId, std::move(callback_task_runner),
+                     std::move(callback)));
+}
+
+void QuotaManagerProxy::GetBucketId(
+    const url::Origin& origin,
+    const std::string& bucket_name,
+    scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
+    base::OnceCallback<void(QuotaErrorOr<BucketId>)> callback) {
+  if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) {
+    quota_manager_impl_task_runner_->PostTask(
+        FROM_HERE, base::BindOnce(&QuotaManagerProxy::GetBucketId, this, origin,
+                                  bucket_name, std::move(callback_task_runner),
+                                  std::move(callback)));
+    return;
+  }
+
+  DCHECK_CALLED_ON_VALID_SEQUENCE(quota_manager_impl_sequence_checker_);
+  if (!quota_manager_impl_) {
+    DidGetBucketId(std::move(callback_task_runner), std::move(callback),
+                   QuotaErrorOr<BucketId>(QuotaError::kUnknownError));
+    return;
+  }
+
+  quota_manager_impl_->GetBucketId(
+      origin, bucket_name,
+      base::BindOnce(&DidGetBucketId, std::move(callback_task_runner),
+                     std::move(callback)));
+}
+
 void QuotaManagerProxy::NotifyStorageAccessed(const url::Origin& origin,
                                               blink::mojom::StorageType type,
                                               base::Time access_time) {
diff --git a/storage/browser/quota/quota_manager_proxy.h b/storage/browser/quota/quota_manager_proxy.h
index e9df9c08..f5452f14 100644
--- a/storage/browser/quota/quota_manager_proxy.h
+++ b/storage/browser/quota/quota_manager_proxy.h
@@ -18,6 +18,7 @@
 #include "base/thread_annotations.h"
 #include "base/time/time.h"
 #include "base/types/pass_key.h"
+#include "components/services/storage/public/cpp/quota_error_or.h"
 #include "components/services/storage/public/mojom/quota_client.mojom-forward.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "storage/browser/quota/quota_callbacks.h"
@@ -75,6 +76,24 @@
       mojo::PendingRemote<mojom::QuotaClient> client,
       QuotaClientType client_type,
       const std::vector<blink::mojom::StorageType>& storage_types);
+
+  // Creates a bucket for `origin` with `bucket_name` and returns the BucketId
+  // to the callback. Will return an QuotaError to the callback on failure.
+  virtual void CreateBucket(
+      const url::Origin& origin,
+      const std::string& bucket_name,
+      scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
+      base::OnceCallback<void(QuotaErrorOr<BucketId>)> callback);
+
+  // Retrieves the BucketId of the bucket with `bucket_name` for `origin` and
+  // returns it to the callback. Will return an empty BucketId if a bucket does
+  // not exist. Will return a QuotaError on operation failure.
+  virtual void GetBucketId(
+      const url::Origin& origin,
+      const std::string& bucket_name,
+      scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
+      base::OnceCallback<void(QuotaErrorOr<BucketId>)> callback);
+
   virtual void NotifyStorageAccessed(const url::Origin& origin,
                                      blink::mojom::StorageType type,
                                      base::Time access_time);
diff --git a/storage/browser/quota/quota_manager_unittest.cc b/storage/browser/quota/quota_manager_unittest.cc
index 629e86f7..b36e087 100644
--- a/storage/browser/quota/quota_manager_unittest.cc
+++ b/storage/browser/quota/quota_manager_unittest.cc
@@ -159,6 +159,20 @@
     return mock_quota_client_ptr;
   }
 
+  void CreateBucket(const url::Origin& origin, const std::string& bucket_name) {
+    quota_manager_impl_->CreateBucket(
+        origin, bucket_name,
+        base::BindOnce(&QuotaManagerImplTest::DidGetBucketId,
+                       weak_factory_.GetWeakPtr()));
+  }
+
+  void GetBucketId(const url::Origin& origin, const std::string& bucket_name) {
+    quota_manager_impl_->GetBucketId(
+        origin, bucket_name,
+        base::BindOnce(&QuotaManagerImplTest::DidGetBucketId,
+                       weak_factory_.GetWeakPtr()));
+  }
+
   void GetUsageInfo() {
     usage_info_.clear();
     quota_manager_impl_->GetUsageInfo(base::BindOnce(
@@ -371,6 +385,10 @@
         &QuotaManagerImplTest::DidDumpBucketTable, weak_factory_.GetWeakPtr()));
   }
 
+  void DidGetBucketId(QuotaErrorOr<BucketId> result) {
+    bucket_id_ = std::move(result);
+  }
+
   void DidGetUsageInfo(UsageInfoEntries entries) {
     usage_info_ = std::move(entries);
   }
@@ -521,13 +539,13 @@
   const QuotaTableEntries& quota_entries() const { return quota_entries_; }
   const BucketTableEntries& bucket_entries() const { return bucket_entries_; }
   const QuotaSettings& settings() const { return settings_; }
-  base::FilePath profile_path() const { return data_dir_.GetPath(); }
   int status_callback_count() const { return status_callback_count_; }
   void reset_status_callback_count() { status_callback_count_ = 0; }
 
  protected:
   base::test::ScopedFeatureList scoped_feature_list_;
   base::test::TaskEnvironment task_environment_;
+  QuotaErrorOr<BucketId> bucket_id_;
 
   static std::vector<QuotaClientType> AllClients() {
     // TODO(pwnall): Implement using something other than an empty vector?
@@ -614,6 +632,40 @@
   }
 }
 
+TEST_F(QuotaManagerImplTest, CreateBucket) {
+  url::Origin origin = ToOrigin("http://a.com/");
+  std::string bucket_name = "BucketA";
+
+  CreateBucket(origin, bucket_name);
+  task_environment_.RunUntilIdle();
+  ASSERT_TRUE(bucket_id_.ok());
+
+  // Try creating a bucket with the same name.
+  CreateBucket(origin, bucket_name);
+  task_environment_.RunUntilIdle();
+  EXPECT_FALSE(bucket_id_.ok());
+}
+
+TEST_F(QuotaManagerImplTest, GetBucketId) {
+  url::Origin origin = ToOrigin("http://a.com/");
+  std::string bucket_name = "BucketA";
+
+  CreateBucket(origin, bucket_name);
+  task_environment_.RunUntilIdle();
+  ASSERT_TRUE(bucket_id_.ok());
+  BucketId created_bucket_id = bucket_id_.value();
+
+  GetBucketId(origin, bucket_name);
+  task_environment_.RunUntilIdle();
+  ASSERT_TRUE(bucket_id_.ok());
+  BucketId retrieved_bucket_id = bucket_id_.value();
+  EXPECT_EQ(created_bucket_id, retrieved_bucket_id);
+
+  GetBucketId(origin, "BucketB");
+  task_environment_.RunUntilIdle();
+  EXPECT_TRUE(bucket_id_.value().is_null());
+}
+
 TEST_F(QuotaManagerImplTest, GetUsageAndQuota_Simple) {
   static const MockOriginData kData[] = {
     { "http://foo.com/", kTemp, 10 },
diff --git a/testing/buildbot/chromium.angle.json b/testing/buildbot/chromium.angle.json
index 7496cf0..597eae93 100644
--- a/testing/buildbot/chromium.angle.json
+++ b/testing/buildbot/chromium.angle.json
@@ -1384,6 +1384,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_0",
+              "path": "Runtime-ios-14.0"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -1438,6 +1442,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_0",
+              "path": "Runtime-ios-14.0"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
diff --git a/testing/buildbot/chromium.clang.json b/testing/buildbot/chromium.clang.json
index bff5099a..05f81ce 100644
--- a/testing/buildbot/chromium.clang.json
+++ b/testing/buildbot/chromium.clang.json
@@ -43355,6 +43355,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -43401,6 +43405,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -43447,6 +43455,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -43493,6 +43505,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -43539,6 +43555,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -43585,6 +43605,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -43631,6 +43655,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -43677,6 +43705,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -43723,6 +43755,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -43769,6 +43805,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -43815,6 +43855,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -43861,6 +43905,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -43907,6 +43955,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -43953,6 +44005,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -43999,6 +44055,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -44045,6 +44105,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -44091,6 +44155,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -44137,6 +44205,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index a8317a25..0a87d9d 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -17500,6 +17500,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -17546,6 +17550,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -17592,6 +17600,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -17638,6 +17650,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -17684,6 +17700,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -17730,6 +17750,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -17776,6 +17800,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -17822,6 +17850,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -17868,6 +17900,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -17914,6 +17950,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -17960,6 +18000,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -18006,6 +18050,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -18052,6 +18100,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -18098,6 +18150,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -18144,6 +18200,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -18190,6 +18250,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -18236,6 +18300,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -18282,6 +18350,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -18328,6 +18400,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -18374,6 +18450,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -18420,6 +18500,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -18466,6 +18550,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -18512,6 +18600,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -18558,6 +18650,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -18604,6 +18700,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -18650,6 +18750,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -18696,6 +18800,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -18742,6 +18850,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -18788,6 +18900,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -18834,6 +18950,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -18880,6 +19000,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -18926,6 +19050,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -18972,6 +19100,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -19018,6 +19150,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -19064,6 +19200,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -19110,6 +19250,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -19156,6 +19300,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -19202,6 +19350,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -19248,6 +19400,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -19294,6 +19450,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -19340,6 +19500,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -19386,6 +19550,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -19432,6 +19600,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -19478,6 +19650,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -19524,6 +19700,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -19570,6 +19750,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -19623,6 +19807,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -19672,6 +19860,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -19721,6 +19913,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -19770,6 +19966,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -19819,6 +20019,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -19868,6 +20072,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -19917,6 +20125,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -19966,6 +20178,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -20015,6 +20231,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -20064,6 +20284,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -20113,6 +20337,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -20162,6 +20390,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -20211,6 +20443,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -20260,6 +20496,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -20309,6 +20549,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -20358,6 +20602,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -20407,6 +20655,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -20456,6 +20708,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -20505,6 +20761,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -20554,6 +20814,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -20603,6 +20867,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -20652,6 +20920,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -20701,6 +20973,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -20750,6 +21026,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -20799,6 +21079,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -20848,6 +21132,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -20897,6 +21185,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -20946,6 +21238,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -20995,6 +21291,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -21044,6 +21344,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -21093,6 +21397,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -21142,6 +21450,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -21191,6 +21503,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -21240,6 +21556,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -21290,6 +21610,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -21340,6 +21664,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -21390,6 +21718,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -21440,6 +21772,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -21490,6 +21826,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -21540,6 +21880,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -21590,6 +21934,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -21641,6 +21989,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -21692,6 +22044,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -21743,6 +22099,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -21794,6 +22154,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -21845,6 +22209,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -21896,6 +22264,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -21947,6 +22319,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -21998,6 +22374,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -22049,6 +22429,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -22100,6 +22484,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -22151,6 +22539,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -22202,6 +22594,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -22252,6 +22648,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -22302,6 +22702,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -22352,6 +22756,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -22402,6 +22810,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -22452,6 +22864,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -22502,6 +22918,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -22552,6 +22972,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -22602,6 +23026,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -22652,6 +23080,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -22702,6 +23134,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -22752,6 +23188,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -22802,6 +23242,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -22853,6 +23297,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -22904,6 +23352,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -22955,6 +23407,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -23006,6 +23462,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -23057,6 +23517,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -23107,6 +23571,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -23156,6 +23624,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -23205,6 +23677,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -23254,6 +23730,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -23303,6 +23783,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -23352,6 +23836,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -23401,6 +23889,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -23450,6 +23942,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -23500,6 +23996,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -23550,6 +24050,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -23600,6 +24104,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -23650,6 +24158,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -23700,6 +24212,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -23750,6 +24266,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -23799,6 +24319,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -23848,6 +24372,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -23897,6 +24425,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -23946,6 +24478,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -23995,6 +24531,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -24044,6 +24584,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -24094,6 +24638,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -24144,6 +24692,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -24194,6 +24746,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -24244,6 +24800,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -24294,6 +24854,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -24344,6 +24908,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -24393,6 +24961,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -24442,6 +25014,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -24491,6 +25067,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -24540,6 +25120,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -24589,6 +25173,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -24638,6 +25226,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -24687,6 +25279,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -24736,6 +25332,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -24785,6 +25385,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -24834,6 +25438,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -24884,6 +25492,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -24934,6 +25546,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -24984,6 +25600,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -25034,6 +25654,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -25084,6 +25708,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -25134,6 +25762,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -25183,6 +25815,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -25232,6 +25868,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -25281,6 +25921,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -25330,6 +25974,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -25379,6 +26027,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -25428,6 +26080,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -25477,6 +26133,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -25526,6 +26186,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -25575,6 +26239,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -25624,6 +26292,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -25673,6 +26345,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -25722,6 +26398,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -25771,6 +26451,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -25820,6 +26504,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -25869,6 +26557,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -25918,6 +26610,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -25967,6 +26663,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -26016,6 +26716,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -26065,6 +26769,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -26114,6 +26822,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -26163,6 +26875,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -26212,6 +26928,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -26261,6 +26981,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -26310,6 +27034,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -26359,6 +27087,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -26408,6 +27140,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -26457,6 +27193,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -26506,6 +27246,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -26555,6 +27299,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -26604,6 +27352,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -26653,6 +27405,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -26702,6 +27458,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -26751,6 +27511,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -26800,6 +27564,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -26849,6 +27617,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -26898,6 +27670,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -26947,6 +27723,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -26996,6 +27776,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -27045,6 +27829,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -27094,6 +27882,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -27143,6 +27935,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -27192,6 +27988,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -27241,6 +28041,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -27290,6 +28094,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -27339,6 +28147,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -27388,6 +28200,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -27437,6 +28253,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -27486,6 +28306,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -27536,6 +28360,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_12_4",
+              "path": "Runtime-ios-12.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -27582,6 +28410,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -27632,6 +28464,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -27678,6 +28514,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -27724,6 +28564,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -27770,6 +28614,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -27816,6 +28664,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -27862,6 +28714,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -27908,6 +28764,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -27954,6 +28814,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -28001,6 +28865,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -28048,6 +28916,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -28096,6 +28968,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -28144,6 +29020,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -28191,6 +29071,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -28238,6 +29122,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -28285,6 +29173,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -28332,6 +29224,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -28378,6 +29274,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -28424,6 +29324,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -28470,6 +29374,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -28517,6 +29425,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -28563,6 +29475,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -28609,6 +29525,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -28656,6 +29576,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -28702,6 +29626,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -28748,6 +29676,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -28794,6 +29726,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -28840,6 +29776,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -28886,6 +29826,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -28932,6 +29876,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -28978,6 +29926,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -29024,6 +29976,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -29070,6 +30026,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -29122,6 +30082,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -29170,6 +30134,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -29218,6 +30186,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -29266,6 +30238,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -29314,6 +30290,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -29362,6 +30342,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -29410,6 +30394,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -29458,6 +30446,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -29506,6 +30498,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -29554,6 +30550,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -29602,6 +30602,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -29650,6 +30654,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -29698,6 +30706,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -29746,6 +30758,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -29794,6 +30810,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -29842,6 +30862,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -29891,6 +30915,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -29940,6 +30968,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -29989,6 +31021,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -30039,6 +31075,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -30089,6 +31129,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -30139,6 +31183,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -30189,6 +31237,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -30238,6 +31290,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -30287,6 +31343,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -30336,6 +31396,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -30385,6 +31449,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -30435,6 +31503,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -30484,6 +31556,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -30532,6 +31608,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -30581,6 +31661,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -30630,6 +31714,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -30678,6 +31766,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -30726,6 +31818,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -30774,6 +31870,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -30822,6 +31922,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -30870,6 +31974,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -30918,6 +32026,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -30967,6 +32079,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -31016,6 +32132,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -31064,6 +32184,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -31112,6 +32236,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -31160,6 +32288,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -31208,6 +32340,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -31257,6 +32393,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -31306,6 +32446,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -31354,6 +32498,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -31402,6 +32550,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -31450,6 +32602,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -31498,6 +32654,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -31546,6 +32706,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -31594,6 +32758,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -31642,6 +32810,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -31690,6 +32862,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -31738,6 +32914,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -31786,6 +32966,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -31834,6 +33018,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -31882,6 +33070,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -31930,6 +33122,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -31978,6 +33174,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -32026,6 +33226,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -32074,6 +33278,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -32122,6 +33330,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -32170,6 +33382,10 @@
             {
               "name": "xcode_ios_11e608c",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_5",
+              "path": "Runtime-ios-13.5"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -32238,6 +33454,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -32284,6 +33504,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -32330,6 +33554,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -32376,6 +33604,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -32422,6 +33654,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -32468,6 +33704,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -32514,6 +33754,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -32560,6 +33804,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -32606,6 +33854,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -32652,6 +33904,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -32698,6 +33954,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -32744,6 +34004,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -32790,6 +34054,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -32836,6 +34104,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -32883,6 +34155,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -32930,6 +34206,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -32977,6 +34257,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -33024,6 +34308,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -33071,6 +34359,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -33119,6 +34411,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -33167,6 +34463,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -33215,6 +34515,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -33263,6 +34567,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -33311,6 +34619,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -33359,6 +34671,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -33407,6 +34723,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -33455,6 +34775,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -33502,6 +34826,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -33549,6 +34877,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -33596,6 +34928,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -33643,6 +34979,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -33690,6 +35030,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -33737,6 +35081,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -33784,6 +35132,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -33831,6 +35183,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -33879,6 +35235,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -33927,6 +35287,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -33975,6 +35339,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -34022,6 +35390,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -34068,6 +35440,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -34114,6 +35490,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -34161,6 +35541,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -34208,6 +35592,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -34255,6 +35643,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -34302,6 +35694,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -34348,6 +35744,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -34394,6 +35794,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -34440,6 +35844,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -34487,6 +35895,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -34534,6 +35946,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -34581,6 +35997,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -34628,6 +36048,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -34674,6 +36098,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -34720,6 +36148,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -34766,6 +36198,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -34812,6 +36248,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -34859,6 +36299,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -34906,6 +36350,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -34953,6 +36401,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -35000,6 +36452,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -35046,6 +36502,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -35092,6 +36552,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -35138,6 +36602,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -35184,6 +36652,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -35230,6 +36702,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -35276,6 +36752,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -35322,6 +36802,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -35368,6 +36852,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -35414,6 +36902,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -35460,6 +36952,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -35506,6 +37002,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -35552,6 +37052,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -35598,6 +37102,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -35644,6 +37152,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -35690,6 +37202,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -35736,6 +37252,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -35782,6 +37302,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -35828,6 +37352,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -35874,6 +37402,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -35927,6 +37459,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -35973,6 +37509,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -36019,6 +37559,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -36065,6 +37609,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -36111,6 +37659,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -36157,6 +37709,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -36203,6 +37759,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -36249,6 +37809,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -36295,6 +37859,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -36341,6 +37909,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -36387,6 +37959,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -36434,6 +38010,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -36481,6 +38061,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -36528,6 +38112,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -36575,6 +38163,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -36623,6 +38215,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -36671,6 +38267,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -36719,6 +38319,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -36767,6 +38371,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -36815,6 +38423,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -36863,6 +38475,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -36910,6 +38526,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -36957,6 +38577,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -37004,6 +38628,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -37051,6 +38679,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -37098,6 +38730,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -37145,6 +38781,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -37193,6 +38833,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -37241,6 +38885,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -37288,6 +38936,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -37334,6 +38986,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -37381,6 +39037,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -37428,6 +39088,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -37475,6 +39139,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -37521,6 +39189,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -37567,6 +39239,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -37613,6 +39289,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -37660,6 +39340,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -37707,6 +39391,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -37754,6 +39442,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -37800,6 +39492,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -37846,6 +39542,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -37892,6 +39592,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -37939,6 +39643,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -37986,6 +39694,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -38033,6 +39745,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -38079,6 +39795,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -38125,6 +39845,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -38171,6 +39895,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -38217,6 +39945,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -38263,6 +39995,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -38309,6 +40045,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -38355,6 +40095,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -38401,6 +40145,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -38447,6 +40195,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -38493,6 +40245,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -38539,6 +40295,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -38585,6 +40345,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -38631,6 +40395,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -38677,6 +40445,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
diff --git a/testing/buildbot/chromium.mac.json b/testing/buildbot/chromium.mac.json
index f944e6b..da91432 100644
--- a/testing/buildbot/chromium.mac.json
+++ b/testing/buildbot/chromium.mac.json
@@ -12733,6 +12733,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -12780,6 +12784,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -12827,6 +12835,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -12874,6 +12886,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -12921,6 +12937,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -12968,6 +12988,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -13015,6 +13039,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -13062,6 +13090,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -13109,6 +13141,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -13156,6 +13192,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -13203,6 +13243,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -13250,6 +13294,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -13297,6 +13345,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -13344,6 +13396,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -13391,6 +13447,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -13438,6 +13498,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -13485,6 +13549,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -13532,6 +13600,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -13579,6 +13651,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -13626,6 +13702,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -13673,6 +13753,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -13720,6 +13804,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -13767,6 +13855,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -13814,6 +13906,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -13861,6 +13957,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -13908,6 +14008,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -13955,6 +14059,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -14002,6 +14110,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -14049,6 +14161,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -14096,6 +14212,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -14143,6 +14263,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -14190,6 +14314,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -14237,6 +14365,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -14284,6 +14416,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -14332,6 +14468,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -14381,6 +14521,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -14430,6 +14574,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -14478,6 +14626,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -14526,6 +14678,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -14575,6 +14731,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -14623,6 +14783,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -14670,6 +14834,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -14717,6 +14885,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -14764,6 +14936,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -14811,6 +14987,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -14858,6 +15038,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -14905,6 +15089,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -14952,6 +15140,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -14999,6 +15191,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -15046,6 +15242,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -15093,6 +15293,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -15140,6 +15344,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -15187,6 +15395,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -15234,6 +15446,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -15281,6 +15497,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -15328,6 +15548,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -15375,6 +15599,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -15422,6 +15650,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -15469,6 +15701,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -15516,6 +15752,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -15563,6 +15803,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -15610,6 +15854,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -15657,6 +15905,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -15704,6 +15956,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -15752,6 +16008,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -15800,6 +16060,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -15847,6 +16111,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -15894,6 +16162,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -15941,6 +16213,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -15988,6 +16264,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -16035,6 +16315,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -16082,6 +16366,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -16129,6 +16417,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -16176,6 +16468,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -16223,6 +16519,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -16270,6 +16570,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -16317,6 +16621,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -16364,6 +16672,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -16411,6 +16723,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -16458,6 +16774,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -16505,6 +16825,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -16552,6 +16876,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -16599,6 +16927,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -16646,6 +16978,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -16693,6 +17029,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -16740,6 +17080,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -16787,6 +17131,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -16834,6 +17182,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -16881,6 +17233,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -16928,6 +17284,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -16975,6 +17335,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -17022,6 +17386,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -17069,6 +17437,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -17116,6 +17488,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -17163,6 +17539,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -17210,6 +17590,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -17257,6 +17641,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -17304,6 +17692,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -17351,6 +17743,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -17398,6 +17794,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -17445,6 +17845,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -17492,6 +17896,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -17539,6 +17947,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -17586,6 +17998,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -17633,6 +18049,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -17680,6 +18100,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -17727,6 +18151,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -17774,6 +18202,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -17821,6 +18253,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -17868,6 +18304,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -17915,6 +18355,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -17962,6 +18406,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -18009,6 +18457,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -18056,6 +18508,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -18111,6 +18567,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -18159,6 +18619,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -18207,6 +18671,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -18255,6 +18723,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -18303,6 +18775,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -18351,6 +18827,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -18399,6 +18879,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -18448,6 +18932,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -18497,6 +18985,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -18546,6 +19038,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -18595,6 +19091,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -18644,6 +19144,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -18693,6 +19197,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -18742,6 +19250,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -18791,6 +19303,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -18840,6 +19356,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -18889,6 +19409,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -18937,6 +19461,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -18985,6 +19513,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -19033,6 +19565,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -19081,6 +19617,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -19129,6 +19669,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -19177,6 +19721,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -19225,6 +19773,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -19273,6 +19825,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -19321,6 +19877,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -19369,6 +19929,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -19418,6 +19982,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -19467,6 +20035,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -19516,6 +20088,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -19565,6 +20141,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -19613,6 +20193,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -19661,6 +20245,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -19709,6 +20297,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -19757,6 +20349,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -19805,6 +20401,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -19853,6 +20453,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -19901,6 +20505,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -19949,6 +20557,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -19997,6 +20609,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -20045,6 +20661,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -20093,6 +20713,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -20141,6 +20765,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -20189,6 +20817,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -20237,6 +20869,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_13_6",
+              "path": "Runtime-ios-13.6"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -20285,6 +20921,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_14_4",
+              "path": "Runtime-ios-14.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -20338,6 +20978,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_12_4",
+              "path": "Runtime-ios-12.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -20384,6 +21028,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_12_4",
+              "path": "Runtime-ios-12.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -20430,6 +21078,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_12_4",
+              "path": "Runtime-ios-12.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -20476,6 +21128,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_12_4",
+              "path": "Runtime-ios-12.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -20522,6 +21178,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_12_4",
+              "path": "Runtime-ios-12.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -20569,6 +21229,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_12_4",
+              "path": "Runtime-ios-12.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -20616,6 +21280,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_12_4",
+              "path": "Runtime-ios-12.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -20663,6 +21331,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_12_4",
+              "path": "Runtime-ios-12.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -20711,6 +21383,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_12_4",
+              "path": "Runtime-ios-12.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -20759,6 +21435,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_12_4",
+              "path": "Runtime-ios-12.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -20807,6 +21487,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_12_4",
+              "path": "Runtime-ios-12.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -20855,6 +21539,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_12_4",
+              "path": "Runtime-ios-12.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -20902,6 +21590,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_12_4",
+              "path": "Runtime-ios-12.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -20949,6 +21641,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_12_4",
+              "path": "Runtime-ios-12.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -20996,6 +21692,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_12_4",
+              "path": "Runtime-ios-12.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -21043,6 +21743,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_12_4",
+              "path": "Runtime-ios-12.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -21091,6 +21795,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_12_4",
+              "path": "Runtime-ios-12.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -21139,6 +21847,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_12_4",
+              "path": "Runtime-ios-12.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -21186,6 +21898,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_12_4",
+              "path": "Runtime-ios-12.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -21232,6 +21948,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_12_4",
+              "path": "Runtime-ios-12.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -21278,6 +21998,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_12_4",
+              "path": "Runtime-ios-12.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -21324,6 +22048,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_12_4",
+              "path": "Runtime-ios-12.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -21371,6 +22099,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_12_4",
+              "path": "Runtime-ios-12.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -21418,6 +22150,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_12_4",
+              "path": "Runtime-ios-12.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -21464,6 +22200,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_12_4",
+              "path": "Runtime-ios-12.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -21511,6 +22251,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_12_4",
+              "path": "Runtime-ios-12.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -21558,6 +22302,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_12_4",
+              "path": "Runtime-ios-12.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -21604,6 +22352,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_12_4",
+              "path": "Runtime-ios-12.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -21650,6 +22402,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_12_4",
+              "path": "Runtime-ios-12.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -21696,6 +22452,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_12_4",
+              "path": "Runtime-ios-12.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -21742,6 +22502,10 @@
             {
               "name": "xcode_ios_12d4e",
               "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_12_4",
+              "path": "Runtime-ios-12.4"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
diff --git a/testing/buildbot/filters/ozone-linux.interactive_ui_tests_wayland.filter b/testing/buildbot/filters/ozone-linux.interactive_ui_tests_wayland.filter
index b30d9be..faf7746 100644
--- a/testing/buildbot/filters/ozone-linux.interactive_ui_tests_wayland.filter
+++ b/testing/buildbot/filters/ozone-linux.interactive_ui_tests_wayland.filter
@@ -63,6 +63,7 @@
 -WidgetInputMethodInteractiveTest.TwoWindows
 
 # Extremely flaky.
+-MenuControllerUITest.TestMouseOverShownMenu
 -MenuItemViewTestInsert20.InsertItem20
 -MenuItemViewTestInsert00.InsertItem00
 -BookmarkBarViewTest18.BookmarkBarViewTest18_SiblingMenu
diff --git a/testing/buildbot/mixins.pyl b/testing/buildbot/mixins.pyl
index 1e7a606..d4a7834c 100644
--- a/testing/buildbot/mixins.pyl
+++ b/testing/buildbot/mixins.pyl
@@ -444,6 +444,66 @@
       ],
     },
   },
+  'ios_runtime_cache_12_4': {
+    '$mixin_append': {
+      'swarming': {
+        'named_caches': [
+          {
+            'name': 'runtime_ios_12_4',
+            'path': 'Runtime-ios-12.4',
+          },
+        ],
+      },
+    },
+  },
+  'ios_runtime_cache_13_5': {
+    '$mixin_append': {
+      'swarming': {
+        'named_caches': [
+          {
+            'name': 'runtime_ios_13_5',
+            'path': 'Runtime-ios-13.5',
+          },
+        ],
+      },
+    },
+  },
+  'ios_runtime_cache_13_6': {
+    '$mixin_append': {
+      'swarming': {
+        'named_caches': [
+          {
+            'name': 'runtime_ios_13_6',
+            'path': 'Runtime-ios-13.6',
+          },
+        ],
+      },
+    },
+  },
+  'ios_runtime_cache_14_0': {
+    '$mixin_append': {
+      'swarming': {
+        'named_caches': [
+          {
+            'name': 'runtime_ios_14_0',
+            'path': 'Runtime-ios-14.0',
+          },
+        ],
+      },
+    },
+  },
+  'ios_runtime_cache_14_4': {
+    '$mixin_append': {
+      'swarming': {
+        'named_caches': [
+          {
+            'name': 'runtime_ios_14_4',
+            'path': 'Runtime-ios-14.4',
+          },
+        ],
+      },
+    },
+  },
   'isolate_profile_data': {
     'isolate_profile_data': True,
   },
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl
index 4b44ca7..21cc864 100644
--- a/testing/buildbot/variants.pyl
+++ b/testing/buildbot/variants.pyl
@@ -86,16 +86,10 @@
       '--version',
       '12.4'
     ],
-    'identifier': 'iPad Air 2 12.4'
-  },
-  'SIM_IPAD_AIR_2_13_6': {
-    'args': [
-      '--platform',
-      'iPad Air 2',
-      '--version',
-      '13.6'
+    'identifier': 'iPad Air 2 12.4',
+    'mixins': [
+      'ios_runtime_cache_12_4',
     ],
-    'identifier': 'iPad Air 2 13.6'
   },
   'SIM_IPAD_AIR_2_13_5': {
     'args': [
@@ -104,7 +98,10 @@
       '--version',
       '13.5'
     ],
-    'identifier': 'iPad Air 2 13.5'
+    'identifier': 'iPad Air 2 13.5',
+    'mixins': [
+      'ios_runtime_cache_13_5',
+    ],
   },
   'SIM_IPAD_AIR_2_13_6': {
     'args': [
@@ -113,7 +110,10 @@
       '--version',
       '13.6'
     ],
-    'identifier': 'iPad Air 2 13.6'
+    'identifier': 'iPad Air 2 13.6',
+    'mixins': [
+      'ios_runtime_cache_13_6',
+    ],
   },
   'SIM_IPAD_AIR_2_14_4': {
     'args': [
@@ -122,16 +122,10 @@
       '--version',
       '14.4'
     ],
-    'identifier': 'iPad Air 2 14.4'
-  },
-  'SIM_IPAD_AIR_2_14_4': {
-    'args': [
-      '--platform',
-      'iPad Air 2',
-      '--version',
-      '14.4'
+    'identifier': 'iPad Air 2 14.4',
+    'mixins': [
+      'ios_runtime_cache_14_4',
     ],
-    'identifier': 'iPad Air 2 14.4'
   },
   'SIM_IPAD_AIR_3RD_GEN_14_4': {
     'args': [
@@ -140,7 +134,10 @@
       '--version',
       '14.4'
     ],
-    'identifier': 'iPad Air (3rd generation) 14.4'
+    'identifier': 'iPad Air (3rd generation) 14.4',
+    'mixins': [
+      'ios_runtime_cache_14_4',
+    ],
   },
   # In Xcode 12, "iPad Pro (12.9-inch)" requires a generation suffix in
   # "platform" arg.
@@ -151,7 +148,10 @@
       '--version',
       '14.4',
     ],
-    'identifier': 'iPad Pro (12.9-inch) (2nd generation) 14.4'
+    'identifier': 'iPad Pro (12.9-inch) (2nd generation) 14.4',
+    'mixins': [
+      'ios_runtime_cache_14_4',
+    ],
   },
   'SIM_IPAD_6_GEN_14_4': {
     'args': [
@@ -160,7 +160,10 @@
       '--version',
       '14.4',
     ],
-    'identifier': 'iPad (6th generation) 14.4'
+    'identifier': 'iPad (6th generation) 14.4',
+    'mixins': [
+      'ios_runtime_cache_14_4',
+    ],
   },
   'SIM_IPHONE_6S_12_4': {
     'args': [
@@ -169,7 +172,10 @@
       '--version',
       '12.4',
     ],
-    'identifier': 'iPhone 6s 12.4'
+    'identifier': 'iPhone 6s 12.4',
+    'mixins': [
+      'ios_runtime_cache_12_4',
+    ],
   },
   'SIM_IPHONE_6S_13_6': {
     'args': [
@@ -178,7 +184,10 @@
       '--version',
       '13.6',
     ],
-    'identifier': 'iPhone 6s 13.6'
+    'identifier': 'iPhone 6s 13.6',
+    'mixins': [
+      'ios_runtime_cache_13_6',
+    ],
   },
   'SIM_IPHONE_6S_14_4': {
     'args': [
@@ -187,16 +196,10 @@
       '--version',
       '14.4',
     ],
-    'identifier': 'iPhone 6s 14.4'
-  },
-  'SIM_IPHONE_6S_14_4': {
-    'args': [
-      '--platform',
-      'iPhone 6s',
-      '--version',
-      '14.4',
+    'identifier': 'iPhone 6s 14.4',
+    'mixins': [
+      'ios_runtime_cache_14_4',
     ],
-    'identifier': 'iPhone 6s 14.4'
   },
   'SIM_IPHONE_6S_PLUS_13_6': {
     'args': [
@@ -205,16 +208,10 @@
       '--version',
       '13.6',
     ],
-    'identifier': 'iPhone 6s Plus 13.6'
-  },
-  'SIM_IPHONE_6S_PLUS_13_6': {
-    'args': [
-      '--platform',
-      'iPhone 6s Plus',
-      '--version',
-      '13.6',
+    'identifier': 'iPhone 6s Plus 13.6',
+    'mixins': [
+      'ios_runtime_cache_13_6',
     ],
-    'identifier': 'iPhone 6s Plus 13.6'
   },
   'SIM_IPHONE_6S_PLUS_14_4': {
     'args': [
@@ -223,16 +220,10 @@
       '--version',
       '14.4',
     ],
-    'identifier': 'iPhone 6s Plus 14.4'
-  },
-  'SIM_IPHONE_6S_PLUS_14_4': {
-    'args': [
-      '--platform',
-      'iPhone 6s Plus',
-      '--version',
-      '14.4',
+    'identifier': 'iPhone 6s Plus 14.4',
+    'mixins': [
+      'ios_runtime_cache_14_4',
     ],
-    'identifier': 'iPhone 6s Plus 14.4'
   },
   'SIM_IPHONE_7_13_6': {
     'args': [
@@ -241,16 +232,10 @@
       '--version',
       '13.6',
     ],
-    'identifier': 'iPhone 7 13.6'
-  },
-  'SIM_IPHONE_7_13_6': {
-    'args': [
-      '--platform',
-      'iPhone 7',
-      '--version',
-      '13.6',
+    'identifier': 'iPhone 7 13.6',
+    'mixins': [
+      'ios_runtime_cache_13_6',
     ],
-    'identifier': 'iPhone 7 13.6'
   },
   'SIM_IPHONE_7_14_4': {
     'args': [
@@ -259,16 +244,10 @@
       '--version',
       '14.4',
     ],
-    'identifier': 'iPhone 7 14.4'
-  },
-  'SIM_IPHONE_7_14_4': {
-    'args': [
-      '--platform',
-      'iPhone 7',
-      '--version',
-      '14.4',
+    'identifier': 'iPhone 7 14.4',
+    'mixins': [
+      'ios_runtime_cache_14_4',
     ],
-    'identifier': 'iPhone 7 14.4'
   },
   'SIM_IPHONE_SE_1ST_GEN_13_6': {
     'args': [
@@ -277,7 +256,10 @@
       '--version',
       '13.6',
     ],
-    'identifier': 'iPhone SE (1st generation) 13.6'
+    'identifier': 'iPhone SE (1st generation) 13.6',
+    'mixins': [
+      'ios_runtime_cache_13_6',
+    ],
   },
   'SIM_IPHONE_SE_1ST_GEN_14_4': {
     'args': [
@@ -286,7 +268,10 @@
       '--version',
       '14.4',
     ],
-    'identifier': 'iPhone SE (1st generation) 14.4'
+    'identifier': 'iPhone SE (1st generation) 14.4',
+    'mixins': [
+      'ios_runtime_cache_14_4',
+    ],
   },
   'SIM_IPHONE_X_12_4': {
     'args': [
@@ -295,7 +280,10 @@
       '--version',
       '12.4',
     ],
-    'identifier': 'iPhone X 12.4'
+    'identifier': 'iPhone X 12.4',
+    'mixins': [
+      'ios_runtime_cache_12_4',
+    ],
   },
   'SIM_IPHONE_X_13_5': {
     'args': [
@@ -304,7 +292,10 @@
       '--version',
       '13.5',
     ],
-    'identifier': 'iPhone X 13.5'
+    'identifier': 'iPhone X 13.5',
+    'mixins': [
+      'ios_runtime_cache_13_5',
+    ],
   },
   'SIM_IPHONE_X_13_6': {
     'args': [
@@ -313,7 +304,10 @@
       '--version',
       '13.6',
     ],
-    'identifier': 'iPhone X 13.6'
+    'identifier': 'iPhone X 13.6',
+    'mixins': [
+      'ios_runtime_cache_13_6',
+    ],
   },
   'SIM_IPHONE_X_14_0': {
     'args': [
@@ -322,7 +316,10 @@
       '--version',
       '14.0',
     ],
-    'identifier': 'iPhone X 14.0'
+    'identifier': 'iPhone X 14.0',
+    'mixins': [
+      'ios_runtime_cache_14_0',
+    ],
   },
   'SIM_IPHONE_X_14_4': {
     'args': [
@@ -331,7 +328,10 @@
       '--version',
       '14.4',
     ],
-    'identifier': 'iPhone X 14.4'
+    'identifier': 'iPhone X 14.4',
+    'mixins': [
+      'ios_runtime_cache_14_4',
+    ],
   },
   'WEBLAYER_10_AND_M_IMPL_SKEW_TESTS_NTH_MILESTONE': {
     'args': [
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 45073ba0..58c4cc7 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -1901,6 +1901,26 @@
             ]
         }
     ],
+    "ChromeTipsInMainMenu": [
+        {
+            "platforms": [
+                "chromeos",
+                "chromeos_lacros",
+                "linux",
+                "mac",
+                "windows"
+            ],
+            "experiments": [
+                {
+                    "name": "EnabledWithNewBadgePromo",
+                    "enable_features": [
+                        "ChromeTipsInMainMenu",
+                        "ChromeTipsInMainMenuNewBadge"
+                    ]
+                }
+            ]
+        }
+    ],
     "ClickAsPointerEvent": [
         {
             "platforms": [
@@ -5391,6 +5411,29 @@
             ]
         }
     ],
+    "OmniboxUpdatedConnectionSecurityIndicatorsIPH": [
+        {
+            "platforms": [
+                "linux",
+                "mac",
+                "windows"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "params": {
+                        "availability": "any",
+                        "event_trigger": "name:updated_connection_security_indicators_iph_trigger;comparator:==0;window:360;storage:360",
+                        "event_used": "name:updated_connection_security_indicators_iph_opened;comparator:==0;window:360;storage:360",
+                        "session_rate": "any"
+                    },
+                    "enable_features": [
+                        "IPH_UpdatedConnectionSecurityIndicators"
+                    ]
+                }
+            ]
+        }
+    ],
     "OneCopyRasterBufferPlaybackNormalThreadPriority": [
         {
             "platforms": [
diff --git a/third_party/blink/public/mojom/web_feature/web_feature.mojom b/third_party/blink/public/mojom/web_feature/web_feature.mojom
index 9be467c..753ba876 100644
--- a/third_party/blink/public/mojom/web_feature/web_feature.mojom
+++ b/third_party/blink/public/mojom/web_feature/web_feature.mojom
@@ -3228,6 +3228,7 @@
   kGetBBoxForText = 3913,
   kSVGTextHangingFromPath = 3914,
   kClientHintsPrefersColorScheme = 3915,
+  kOverscrollBehaviorWillBeFixed = 3916,
 
   // Add new features immediately above this line. Don't change assigned
   // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/blink/public/web/web_view_client.h b/third_party/blink/public/web/web_view_client.h
index ffe4af894..22d7a35d 100644
--- a/third_party/blink/public/web/web_view_client.h
+++ b/third_party/blink/public/web/web_view_client.h
@@ -96,9 +96,6 @@
 
   // UI ------------------------------------------------------------------
 
-  // Called to check if layout update should be processed.
-  virtual bool CanUpdateLayout() { return false; }
-
   // Called when the View has changed size as a result of an auto-resize.
   virtual void DidAutoResize(const gfx::Size& new_size) {}
 
diff --git a/third_party/blink/renderer/core/animation/compositor_animations_test.cc b/third_party/blink/renderer/core/animation/compositor_animations_test.cc
index c9a8c29..6dd999bc 100644
--- a/third_party/blink/renderer/core/animation/compositor_animations_test.cc
+++ b/third_party/blink/renderer/core/animation/compositor_animations_test.cc
@@ -57,7 +57,6 @@
 #include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
 #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
 #include "third_party/blink/renderer/core/layout/layout_object.h"
-#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h"
 #include "third_party/blink/renderer/core/paint/object_paint_properties.h"
 #include "third_party/blink/renderer/core/paint/paint_layer.h"
 #include "third_party/blink/renderer/core/style/computed_style.h"
@@ -75,6 +74,7 @@
 #include "third_party/blink/renderer/platform/geometry/int_size.h"
 #include "third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h"
 #include "third_party/blink/renderer/platform/heap/heap.h"
+#include "third_party/blink/renderer/platform/testing/find_cc_layer.h"
 #include "third_party/blink/renderer/platform/testing/histogram_tester.h"
 #include "third_party/blink/renderer/platform/testing/paint_test_configurations.h"
 #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
@@ -160,13 +160,18 @@
     // Having an animation would normally ensure this but these tests don't
     // explicitly construct a full animation on the element.
     SetBodyInnerHTML(R"HTML(
-        <div id='test' style='will-change: opacity,filter,transform; height:100px; background: green;'></div>
-        <span id='inline' style='will-change: opacity,filter,transform;'>text</div>
+      <div id='test' style='will-change: opacity,filter,transform;
+                            height:100px; background: green;'>
+      </div>
+      <span id='inline' style='will-change: opacity,filter,transform;'>
+        text
+      </span>
     )HTML");
     element_ = GetDocument().getElementById("test");
     inline_ = GetDocument().getElementById("inline");
 
     helper_.Initialize(nullptr, nullptr, nullptr);
+    helper_.Resize(gfx::Size(800, 600));
     base_url_ = "http://www.test.com/";
   }
 
@@ -1047,12 +1052,6 @@
 
 TEST_P(AnimationCompositorAnimationsTest,
        CanStartElementOnCompositorEffectFilter) {
-  // TODO(https://crbug.com/960953): Create a filter effect node when
-  // will-change: filter is specified so that filter effects can be tested
-  // without compositing changes.
-  if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
-    return;
-
   // Filter Properties use a different ID namespace
   StringKeyframeEffectModel* effect1 = CreateKeyframeEffectModel(
       CreateReplaceOpKeyframe(CSSPropertyID::kFilter, "none", 0),
@@ -2052,10 +2051,6 @@
 }
 
 TEST_P(AnimationCompositorAnimationsTest, CompositedTransformAnimation) {
-  // TODO(wangxianzhu): Fix this test for CompositeAfterPaint.
-  if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
-    return;
-
   LoadTestData("transform-animation.html");
   Document* document = GetFrame()->GetDocument();
   Element* target = document->getElementById("target");
@@ -2086,10 +2081,6 @@
 }
 
 TEST_P(AnimationCompositorAnimationsTest, CompositedScaleAnimation) {
-  // TODO(wangxianzhu): Fix this test for CompositeAfterPaint.
-  if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
-    return;
-
   LoadTestData("scale-animation.html");
   Document* document = GetFrame()->GetDocument();
   Element* target = document->getElementById("target");
@@ -2121,10 +2112,6 @@
 
 TEST_P(AnimationCompositorAnimationsTest,
        NonAnimatedTransformPropertyChangeGetsUpdated) {
-  // TODO(wangxianzhu): Fix this test for CompositeAfterPaint.
-  if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
-    return;
-
   LoadTestData("transform-animation-update.html");
   Document* document = GetFrame()->GetDocument();
   Element* target = document->getElementById("target");
@@ -2155,10 +2142,8 @@
   EXPECT_FALSE(transform->Matrix().IsIdentity());  // Rotated
   EXPECT_EQ(transform->GetBackfaceVisibilityForTesting(),
             TransformPaintPropertyNode::BackfaceVisibility::kVisible);
-  const CompositedLayerMapping* composited_layer_mapping =
-      target->GetLayoutBoxModelObject()->Layer()->GetCompositedLayerMapping();
-  ASSERT_NE(nullptr, composited_layer_mapping);
-  const auto& layer = composited_layer_mapping->MainGraphicsLayer()->CcLayer();
+  const auto& layer =
+      *CcLayersByDOMElementId(document->View()->RootCcLayer(), "target")[0];
   EXPECT_FALSE(layer.should_check_backface_visibility());
 
   // Change the backface visibility, while the compositor animation is
diff --git a/third_party/blink/renderer/core/animation/test_data/scale-animation.html b/third_party/blink/renderer/core/animation/test_data/scale-animation.html
index 68977fb9..4e4fec2d 100644
--- a/third_party/blink/renderer/core/animation/test_data/scale-animation.html
+++ b/third_party/blink/renderer/core/animation/test_data/scale-animation.html
@@ -13,4 +13,4 @@
   background: green;
 }
 </style>
-<div id="target" class="animate"></div>
+<div id="target" class="animate">TARGET</div>
diff --git a/third_party/blink/renderer/core/animation/test_data/transform-animation.html b/third_party/blink/renderer/core/animation/test_data/transform-animation.html
index 8121274..33d682b 100644
--- a/third_party/blink/renderer/core/animation/test_data/transform-animation.html
+++ b/third_party/blink/renderer/core/animation/test_data/transform-animation.html
@@ -13,4 +13,4 @@
   background: green;
 }
 </style>
-<div id="target" class="animate"></div>;
+<div id="target" class="animate">TARGET</div>
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver.cc b/third_party/blink/renderer/core/css/resolver/style_resolver.cc
index 2190fb8..7f3d519 100644
--- a/third_party/blink/renderer/core/css/resolver/style_resolver.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_resolver.cc
@@ -1828,15 +1828,26 @@
     // TODO(954423): Remove once propagation logic change is complete.
     if (document_element_style && overflow_style &&
         overflow_style != document_element_style) {
-      bool overscroll_behavior_is_different =
-          overflow_style->OverscrollBehaviorX() !=
-              document_element_style->OverscrollBehaviorX() ||
-          overflow_style->OverscrollBehaviorY() !=
-              document_element_style->OverscrollBehaviorY();
-      if (overscroll_behavior_is_different) {
+      EOverscrollBehavior document_x =
+          document_element_style->OverscrollBehaviorX();
+      EOverscrollBehavior document_y =
+          document_element_style->OverscrollBehaviorY();
+      EOverscrollBehavior body_x = overflow_style->OverscrollBehaviorX();
+      EOverscrollBehavior body_y = overflow_style->OverscrollBehaviorY();
+      // Document style is auto but body is not: fixing crbug.com/954423 might
+      // break the page.
+      if ((document_x == EOverscrollBehavior::kAuto && document_x != body_x) ||
+          (document_y == EOverscrollBehavior::kAuto && document_y != body_y)) {
         UseCounter::Count(GetDocument(),
                           WebFeature::kOversrollBehaviorOnViewportBreaks);
       }
+      // Body style is auto but document is not: currently we are showing the
+      // wrong behavior, and fixing crbug.com/954423 gives the correct behavior.
+      if ((body_x == EOverscrollBehavior::kAuto && document_x != body_x) ||
+          (body_y == EOverscrollBehavior::kAuto && document_y != body_y)) {
+        UseCounter::Count(GetDocument(),
+                          WebFeature::kOverscrollBehaviorWillBeFixed);
+      }
     }
 
     EOverflow overflow_x = EOverflow::kAuto;
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
index a20093f..4e98dd5 100644
--- a/third_party/blink/renderer/core/dom/document.cc
+++ b/third_party/blink/renderer/core/dom/document.cc
@@ -8185,12 +8185,6 @@
   if (DocumentLoader* loader = Loader())
     loader->NotifyPrerenderingDocumentActivated();
 
-  Vector<base::OnceClosure> callbacks;
-  callbacks.swap(will_dispatch_prerenderingchange_callbacks_);
-  for (auto& callback : callbacks) {
-    std::move(callback).Run();
-  }
-
   // https://jeremyroman.github.io/alternate-loading-modes/#prerendering-browsing-context-activate
   // Step 8.3.4 "Fire an event named prerenderingchange at doc."
   DispatchEvent(*Event::Create(event_type_names::kPrerenderingchange));
@@ -8203,12 +8197,6 @@
     frame->DidActivateForPrerendering();
 }
 
-void Document::AddWillDispatchPrerenderingchangeCallback(
-    base::OnceClosure closure) {
-  DCHECK(is_prerendering_);
-  will_dispatch_prerenderingchange_callbacks_.push_back(std::move(closure));
-}
-
 void Document::AddPostPrerenderingActivationStep(base::OnceClosure callback) {
   DCHECK(is_prerendering_);
   post_prerendering_activation_callbacks_.push_back(std::move(callback));
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h
index 083cd83..6eb556a 100644
--- a/third_party/blink/renderer/core/dom/document.h
+++ b/third_party/blink/renderer/core/dom/document.h
@@ -1689,8 +1689,6 @@
 
   void ActivateForPrerendering();
 
-  void AddWillDispatchPrerenderingchangeCallback(base::OnceClosure);
-
   void AddPostPrerenderingActivationStep(base::OnceClosure callback);
 
   class CORE_EXPORT PaintPreviewScope {
@@ -1865,10 +1863,6 @@
   // https://github.com/jeremyroman/alternate-loading-modes/blob/main/prerendering-state.md#documentprerendering
   bool is_prerendering_;
 
-  // Callbacks to execute upon activation of a prerendered page, just before the
-  // prerenderingchange event is dispatched.
-  Vector<base::OnceClosure> will_dispatch_prerenderingchange_callbacks_;
-
   // The callback list for post-prerendering activation step.
   // https://jeremyroman.github.io/alternate-loading-modes/#document-post-prerendering-activation-steps-list
   Vector<base::OnceClosure> post_prerendering_activation_callbacks_;
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc
index e5d1206..32b9407 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -3286,7 +3286,7 @@
 void WebViewImpl::ResizeAfterLayout() {
   DCHECK(MainFrameImpl());
 
-  if (!web_view_client_ || !web_view_client_->CanUpdateLayout())
+  if (!web_view_client_)
     return;
 
   if (should_auto_resize_) {
diff --git a/third_party/blink/renderer/core/frame/frame_test_helpers.h b/third_party/blink/renderer/core/frame/frame_test_helpers.h
index 468dfcb..94d0ba5 100644
--- a/third_party/blink/renderer/core/frame/frame_test_helpers.h
+++ b/third_party/blink/renderer/core/frame/frame_test_helpers.h
@@ -309,7 +309,6 @@
   void DestroyChildViews();
 
   // WebViewClient overrides.
-  bool CanUpdateLayout() override { return true; }
   WebView* CreateView(WebLocalFrame* opener,
                       const WebURLRequest&,
                       const WebWindowFeatures&,
diff --git a/third_party/blink/renderer/core/layout/layout_flexible_box.cc b/third_party/blink/renderer/core/layout/layout_flexible_box.cc
index 9eb3c8e..6d5cef9 100644
--- a/third_party/blink/renderer/core/layout/layout_flexible_box.cc
+++ b/third_party/blink/renderer/core/layout/layout_flexible_box.cc
@@ -1214,7 +1214,7 @@
                                  : resolved_main_size;
 
         sizes.min_size = std::min(specified_size, content_size);
-      } else if (UseChildAspectRatio(child)) {
+      } else if (child.IsLayoutReplaced() && UseChildAspectRatio(child)) {
         const Length& cross_size_length = IsHorizontalFlow()
                                               ? child.StyleRef().Height()
                                               : child.StyleRef().Width();
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc b/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc
index 5122c942..e7246a22e 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc
@@ -1230,6 +1230,8 @@
   NGInlineCursor cursor(*container);
   cursor.MoveTo(*layout_object);
   DCHECK(cursor);
+  const PhysicalOffset this_offset_in_container =
+      cursor.Current()->OffsetInContainerFragment();
 #if DCHECK_IS_ON()
   bool has_this_fragment = false;
 #endif
@@ -1255,9 +1257,10 @@
   if (rects->size() <= initial_rects_size)
     return;
 
+  // At this point, |rects| are in the container coordinate space.
   // Adjust the rectangles using |additional_offset| and |container_relative|.
   if (!container_relative)
-    additional_offset -= (*rects)[initial_rects_size].offset;
+    additional_offset -= this_offset_in_container;
   if (additional_offset.IsZero())
     return;
   for (PhysicalRect& rect :
diff --git a/third_party/blink/renderer/core/paint/background_image_geometry.cc b/third_party/blink/renderer/core/paint/background_image_geometry.cc
index 23ea702..f52614d 100644
--- a/third_party/blink/renderer/core/paint/background_image_geometry.cc
+++ b/third_party/blink/renderer/core/paint/background_image_geometry.cc
@@ -666,12 +666,14 @@
     snapped_dest_rect_ = unsnapped_dest_rect_;
     snapped_dest_rect_.Contract(snapped_dest_adjust);
     snapped_dest_rect_ = PhysicalRect(PixelSnappedIntRect(snapped_dest_rect_));
+    snapped_dest_rect_.size.ClampNegativeToZero();
     unsnapped_dest_rect_.Contract(unsnapped_dest_adjust);
     unsnapped_dest_rect_.size.ClampNegativeToZero();
     snapped_positioning_area = unsnapped_positioning_area;
     snapped_positioning_area.Contract(snapped_box_outset);
     snapped_positioning_area =
         PhysicalRect(PixelSnappedIntRect(snapped_positioning_area));
+    snapped_positioning_area.size.ClampNegativeToZero();
     unsnapped_positioning_area.Contract(unsnapped_box_outset);
     unsnapped_positioning_area.size.ClampNegativeToZero();
 
diff --git a/third_party/blink/renderer/core/paint/highlight_painting_utils.h b/third_party/blink/renderer/core/paint/highlight_painting_utils.h
index 6e8c397..c29608d 100644
--- a/third_party/blink/renderer/core/paint/highlight_painting_utils.h
+++ b/third_party/blink/renderer/core/paint/highlight_painting_utils.h
@@ -6,6 +6,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_HIGHLIGHT_PAINTING_UTILS_H_
 
 #include "base/memory/scoped_refptr.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/paint/paint_phase.h"
 #include "third_party/blink/renderer/core/style/applied_text_decoration.h"
diff --git a/third_party/blink/renderer/modules/animationworklet/worklet_animation_test.cc b/third_party/blink/renderer/modules/animationworklet/worklet_animation_test.cc
index a40e451..23e5475 100644
--- a/third_party/blink/renderer/modules/animationworklet/worklet_animation_test.cc
+++ b/third_party/blink/renderer/modules/animationworklet/worklet_animation_test.cc
@@ -8,6 +8,7 @@
 #include <utility>
 
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/renderer/bindings/core/v8/double_or_scroll_timeline_auto_keyword.h"
 #include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_scroll_timeline_options.h"
diff --git a/third_party/blink/renderer/modules/audio_output_devices/html_media_element_audio_output_device.cc b/third_party/blink/renderer/modules/audio_output_devices/html_media_element_audio_output_device.cc
index 8d587c2..c2b6710 100644
--- a/third_party/blink/renderer/modules/audio_output_devices/html_media_element_audio_output_device.cc
+++ b/third_party/blink/renderer/modules/audio_output_devices/html_media_element_audio_output_device.cc
@@ -58,6 +58,8 @@
   ~SetSinkIdResolver() override = default;
   void StartAsync();
 
+  void Start();
+
   void Trace(Visitor*) const override;
 
  private:
@@ -96,6 +98,25 @@
                                       WrapWeakPersistent(this)));
 }
 
+void SetSinkIdResolver::Start() {
+  auto* context = GetExecutionContext();
+  if (!context || context->IsContextDestroyed())
+    return;
+
+  if (LocalDOMWindow* window = DynamicTo<LocalDOMWindow>(context)) {
+    if (window->document()->IsPrerendering()) {
+      window->document()->AddPostPrerenderingActivationStep(
+          WTF::Bind(&SetSinkIdResolver::Start, WrapWeakPersistent(this)));
+      return;
+    }
+  }
+
+  if (sink_id_ == HTMLMediaElementAudioOutputDevice::sinkId(*element_))
+    Resolve();
+  else
+    StartAsync();
+}
+
 void SetSinkIdResolver::DoSetSinkId() {
   auto set_sink_id_completion_callback =
       WTF::Bind(&SetSinkIdResolver::OnSetSinkIdComplete, WrapPersistent(this));
@@ -189,11 +210,7 @@
   SetSinkIdResolver* resolver =
       SetSinkIdResolver::Create(script_state, element, sink_id);
   ScriptPromise promise = resolver->Promise();
-  if (sink_id == HTMLMediaElementAudioOutputDevice::sinkId(element))
-    resolver->Resolve();
-  else
-    resolver->StartAsync();
-
+  resolver->Start();
   return promise;
 }
 
diff --git a/third_party/blink/renderer/modules/storage/cached_storage_area.cc b/third_party/blink/renderer/modules/storage/cached_storage_area.cc
index 4b98ae5e..cf91500 100644
--- a/third_party/blink/renderer/modules/storage/cached_storage_area.cc
+++ b/third_party/blink/renderer/modules/storage/cached_storage_area.cc
@@ -102,13 +102,10 @@
   KURL page_url = source->GetPageUrl();
   String source_id = areas_->at(source);
   String source_string = PackSource(page_url, source_id);
-
-  if (!is_session_storage_for_prerendering_) {
-    remote_area_->Put(StringToUint8Vector(key, GetKeyFormat()),
-                      StringToUint8Vector(value, value_format),
-                      optional_old_value, source_string,
-                      MakeSuccessCallback(source));
-  }
+  remote_area_->Put(StringToUint8Vector(key, GetKeyFormat()),
+                    StringToUint8Vector(value, value_format),
+                    optional_old_value, source_string,
+                    MakeSuccessCallback(source));
   if (!IsSessionStorage())
     EnqueuePendingMutation(key, value, old_value, source_string);
   else if (old_value != value)
@@ -130,11 +127,9 @@
   KURL page_url = source->GetPageUrl();
   String source_id = areas_->at(source);
   String source_string = PackSource(page_url, source_id);
-  if (!is_session_storage_for_prerendering_) {
-    remote_area_->Delete(StringToUint8Vector(key, GetKeyFormat()),
-                         optional_old_value, source_string,
-                         MakeSuccessCallback(source));
-  }
+  remote_area_->Delete(StringToUint8Vector(key, GetKeyFormat()),
+                       optional_old_value, source_string,
+                       MakeSuccessCallback(source));
   if (!IsSessionStorage())
     EnqueuePendingMutation(key, String(), old_value, source_string);
   else
@@ -169,10 +164,8 @@
   KURL page_url = source->GetPageUrl();
   String source_id = areas_->at(source);
   String source_string = PackSource(page_url, source_id);
-  if (!is_session_storage_for_prerendering_) {
-    remote_area_->DeleteAll(source_string, std::move(new_observer),
-                            MakeSuccessCallback(source));
-  }
+  remote_area_->DeleteAll(source_string, std::move(new_observer),
+                          MakeSuccessCallback(source));
   if (!IsSessionStorage())
     EnqueuePendingMutation(String(), String(), String(), source_string);
   else if (!already_empty)
@@ -189,12 +182,10 @@
     AreaType type,
     scoped_refptr<const SecurityOrigin> origin,
     scoped_refptr<base::SingleThreadTaskRunner> task_runner,
-    StorageNamespace* storage_namespace,
-    bool is_session_storage_for_prerendering)
+    StorageNamespace* storage_namespace)
     : type_(type),
       origin_(std::move(origin)),
       storage_namespace_(storage_namespace),
-      is_session_storage_for_prerendering_(is_session_storage_for_prerendering),
       task_runner_(std::move(task_runner)),
       areas_(MakeGarbageCollected<HeapHashMap<WeakMember<Source>, String>>()) {
   BindStorageArea();
@@ -227,7 +218,6 @@
 
 void CachedStorageArea::ResetConnection(
     mojo::PendingRemote<mojom::blink::StorageArea> new_area) {
-  DCHECK(!is_session_storage_for_prerendering_);
   remote_area_.reset();
   BindStorageArea(std::move(new_area));
 
diff --git a/third_party/blink/renderer/modules/storage/cached_storage_area.h b/third_party/blink/renderer/modules/storage/cached_storage_area.h
index 68caa52..9196428d 100644
--- a/third_party/blink/renderer/modules/storage/cached_storage_area.h
+++ b/third_party/blink/renderer/modules/storage/cached_storage_area.h
@@ -63,8 +63,7 @@
   CachedStorageArea(AreaType type,
                     scoped_refptr<const SecurityOrigin> origin,
                     scoped_refptr<base::SingleThreadTaskRunner> ipc_runner,
-                    StorageNamespace* storage_namespace,
-                    bool is_session_storage_for_prerendering);
+                    StorageNamespace* storage_namespace);
 
   // These correspond to blink::Storage.
   unsigned GetLength();
@@ -98,10 +97,6 @@
   void ResetConnection(
       mojo::PendingRemote<mojom::blink::StorageArea> new_area = {});
 
-  bool is_session_storage_for_prerendering() const {
-    return is_session_storage_for_prerendering_;
-  }
-
   void SetRemoteAreaForTesting(
       mojo::PendingRemote<mojom::blink::StorageArea> area) {
     remote_area_.Bind(std::move(area));
@@ -182,12 +177,6 @@
   const AreaType type_;
   const scoped_refptr<const SecurityOrigin> origin_;
   const WeakPersistent<StorageNamespace> storage_namespace_;
-  // Session storage state for prerendering is initialized by cloning the
-  // primary session storage state. It is used locally by the prerendering
-  // context, and does not get propagated back to the primary state (i.e., via
-  // remote_area_). For more details:
-  // https://docs.google.com/document/d/1I5Hr8I20-C1GBr4tAXdm0U8a1RDUKHt4n7WcH4fxiSE/edit?usp=sharing
-  const bool is_session_storage_for_prerendering_;
   const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
 
   std::unique_ptr<StorageAreaMap> map_;
diff --git a/third_party/blink/renderer/modules/storage/cached_storage_area_test.cc b/third_party/blink/renderer/modules/storage/cached_storage_area_test.cc
index 8299784..b434607 100644
--- a/third_party/blink/renderer/modules/storage/cached_storage_area_test.cc
+++ b/third_party/blink/renderer/modules/storage/cached_storage_area_test.cc
@@ -38,7 +38,7 @@
                            : CachedStorageArea::AreaType::kLocalStorage;
     cached_area_ = base::MakeRefCounted<CachedStorageArea>(
         area_type, kOrigin, scheduler::GetSingleThreadTaskRunnerForTesting(),
-        nullptr, /*is_session_storage_for_prerendering=*/false);
+        nullptr);
     cached_area_->SetRemoteAreaForTesting(
         mock_storage_area_.GetInterfaceRemote());
     source_area_ = MakeGarbageCollected<FakeAreaSource>(kPageUrl);
diff --git a/third_party/blink/renderer/modules/storage/dom_window_storage.cc b/third_party/blink/renderer/modules/storage/dom_window_storage.cc
index 9888455..6723295 100644
--- a/third_party/blink/renderer/modules/storage/dom_window_storage.cc
+++ b/third_party/blink/renderer/modules/storage/dom_window_storage.cc
@@ -90,16 +90,10 @@
       StorageNamespace::From(window->GetFrame()->GetPage());
   if (!storage_namespace)
     return nullptr;
-  scoped_refptr<CachedStorageArea> cached_storage_area;
-  if (window->document()->IsPrerendering()) {
-    cached_storage_area = storage_namespace->CreateCachedAreaForPrerender(
-        window->GetSecurityOrigin());
-  } else {
-    cached_storage_area =
-        storage_namespace->GetCachedArea(window->GetSecurityOrigin());
-  }
+  auto storage_area =
+      storage_namespace->GetCachedArea(window->GetSecurityOrigin());
   session_storage_ =
-      StorageArea::Create(window, std::move(cached_storage_area),
+      StorageArea::Create(window, std::move(storage_area),
                           StorageArea::StorageType::kSessionStorage);
 
   if (!session_storage_->CanAccessStorage()) {
diff --git a/third_party/blink/renderer/modules/storage/storage_area.cc b/third_party/blink/renderer/modules/storage/storage_area.cc
index a40cd63..32373c8 100644
--- a/third_party/blink/renderer/modules/storage/storage_area.cc
+++ b/third_party/blink/renderer/modules/storage/storage_area.cc
@@ -41,7 +41,6 @@
 #include "third_party/blink/renderer/modules/storage/storage_namespace.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/weborigin/security_origin.h"
-#include "third_party/blink/renderer/platform/wtf/functional.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 
 namespace blink {
@@ -74,11 +73,6 @@
   DCHECK(window);
   DCHECK(cached_area_);
   cached_area_->RegisterSource(this);
-  if (cached_area_->is_session_storage_for_prerendering()) {
-    DomWindow()->document()->AddWillDispatchPrerenderingchangeCallback(
-        WTF::Bind(&StorageArea::OnDocumentActivatedForPrerendering,
-                  WrapWeakPersistent(this)));
-  }
 }
 
 unsigned StorageArea::length(ExceptionState& exception_state) const {
@@ -252,18 +246,4 @@
       ->CreateWebScopedVirtualTimePauser(name, duration);
 }
 
-void StorageArea::OnDocumentActivatedForPrerendering() {
-  StorageNamespace* storage_namespace =
-      StorageNamespace::From(DomWindow()->GetFrame()->GetPage());
-  if (!storage_namespace)
-    return;
-
-  // Swap out the session storage state used within prerendering, and replace it
-  // with the normal session storage state. For more details:
-  // https://docs.google.com/document/d/1I5Hr8I20-C1GBr4tAXdm0U8a1RDUKHt4n7WcH4fxiSE/edit?usp=sharing
-  cached_area_ =
-      storage_namespace->GetCachedArea(DomWindow()->GetSecurityOrigin());
-  cached_area_->RegisterSource(this);
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/storage/storage_area.h b/third_party/blink/renderer/modules/storage/storage_area.h
index 698c270c..941e2bd 100644
--- a/third_party/blink/renderer/modules/storage/storage_area.h
+++ b/third_party/blink/renderer/modules/storage/storage_area.h
@@ -92,10 +92,7 @@
 
  private:
   void RecordModificationInMetrics();
-
-  void OnDocumentActivatedForPrerendering();
-
-  scoped_refptr<CachedStorageArea> cached_area_;
+  const scoped_refptr<CachedStorageArea> cached_area_;
   StorageType storage_type_;
   const bool should_enqueue_events_;
 
diff --git a/third_party/blink/renderer/modules/storage/storage_namespace.cc b/third_party/blink/renderer/modules/storage/storage_namespace.cc
index 3827a9a..b10a0f2 100644
--- a/third_party/blink/renderer/modules/storage/storage_namespace.cc
+++ b/third_party/blink/renderer/modules/storage/storage_namespace.cc
@@ -100,23 +100,11 @@
   result = base::MakeRefCounted<CachedStorageArea>(
       IsSessionStorage() ? CachedStorageArea::AreaType::kSessionStorage
                          : CachedStorageArea::AreaType::kLocalStorage,
-      origin, controller_->TaskRunner(), this,
-      /*is_session_storage_for_prerendering=*/false);
+      origin, controller_->TaskRunner(), this);
   cached_areas_.insert(std::move(origin), result);
   return result;
 }
 
-scoped_refptr<CachedStorageArea> StorageNamespace::CreateCachedAreaForPrerender(
-    const SecurityOrigin* origin_ptr) {
-  DCHECK((IsSessionStorage()));
-  scoped_refptr<const SecurityOrigin> origin(origin_ptr);
-  return base::MakeRefCounted<CachedStorageArea>(
-      IsSessionStorage() ? CachedStorageArea::AreaType::kSessionStorage
-                         : CachedStorageArea::AreaType::kLocalStorage,
-      origin, controller_->TaskRunner(), this,
-      /*is_session_storage_for_prerendering=*/true);
-}
-
 void StorageNamespace::CloneTo(const String& target) {
   DCHECK(IsSessionStorage()) << "Cannot clone a local storage namespace.";
   EnsureConnected();
diff --git a/third_party/blink/renderer/modules/storage/storage_namespace.h b/third_party/blink/renderer/modules/storage/storage_namespace.h
index ec36582..bb62188 100644
--- a/third_party/blink/renderer/modules/storage/storage_namespace.h
+++ b/third_party/blink/renderer/modules/storage/storage_namespace.h
@@ -84,9 +84,6 @@
 
   scoped_refptr<CachedStorageArea> GetCachedArea(const SecurityOrigin* origin);
 
-  scoped_refptr<CachedStorageArea> CreateCachedAreaForPrerender(
-      const SecurityOrigin* origin);
-
   // Only valid to call this if |this| and |target| are session storage
   // namespaces.
   void CloneTo(const String& target);
diff --git a/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl.cc b/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl.cc
index a044442..8fa9f28 100644
--- a/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl.cc
+++ b/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl.cc
@@ -99,6 +99,13 @@
   // This allows the first frame of the new media player (requested in
   // OnWebMediaPlayerCreated()) to restart the rVFC loop.
   pending_execution_ = false;
+
+  // If we don't reset |last_presented_frames_|, the first frame from video B
+  // will appear stale, if we switched away from video A after exactly 1
+  // presented frame. This would result in rVFC calls not being executed, and
+  // |consecutive_stale_frames_| being incremented instead.
+  last_presented_frames_ = 0;
+  consecutive_stale_frames_ = 0;
 }
 
 void VideoFrameCallbackRequesterImpl::ScheduleWindowRaf() {
diff --git a/third_party/blink/renderer/modules/webcodecs/image_track.cc b/third_party/blink/renderer/modules/webcodecs/image_track.cc
index 30139483..688ae0e5 100644
--- a/third_party/blink/renderer/modules/webcodecs/image_track.cc
+++ b/third_party/blink/renderer/modules/webcodecs/image_track.cc
@@ -65,8 +65,10 @@
   frame_count_ = frame_count;
   repetition_count_ = repetition_count;
 
-  // Animation state isn't allowed to change after construction.
-  DCHECK_EQ(was_animated, animated());
+  // Changes from still to animated are not allowed since they can cause sites
+  // to think there are no further frames to decode in the streaming case.
+  if (!was_animated)
+    DCHECK_EQ(was_animated, animated());
 }
 
 void ImageTrack::Trace(Visitor* visitor) const {
diff --git a/third_party/blink/renderer/platform/fonts/shaping/font_features.h b/third_party/blink/renderer/platform/fonts/shaping/font_features.h
index ad483b1f..4ec06850 100644
--- a/third_party/blink/renderer/platform/fonts/shaping/font_features.h
+++ b/third_party/blink/renderer/platform/fonts/shaping/font_features.h
@@ -7,6 +7,7 @@
 
 #include <hb.h>
 
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/renderer/platform/platform_export.h"
 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc
index 150e07e..770d741 100644
--- a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc
+++ b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc
@@ -843,6 +843,8 @@
     RestoreBackBufferOOP(image);
   }
 
+  bool UseOopRasterization() final { return use_oop_rasterization_; }
+
   bool WritePixels(const SkImageInfo& orig_info,
                    const void* pixels,
                    size_t row_bytes,
diff --git a/third_party/blink/renderer/platform/graphics/offscreen_canvas_placeholder.h b/third_party/blink/renderer/platform/graphics/offscreen_canvas_placeholder.h
index 71667559..4c4c10f5 100644
--- a/third_party/blink/renderer/platform/graphics/offscreen_canvas_placeholder.h
+++ b/third_party/blink/renderer/platform/graphics/offscreen_canvas_placeholder.h
@@ -9,6 +9,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/single_thread_task_runner.h"
 #include "components/viz/common/resources/resource_id.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/renderer/platform/platform_export.h"
 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
 #include "third_party/skia/include/core/SkFilterQuality.h"
diff --git a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
index eaf2824..475d5f0 100644
--- a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
+++ b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
@@ -168,6 +168,8 @@
 ### external/wpt/css/css-sizing/
 crbug.com/1045668 external/wpt/css/css-sizing/aspect-ratio/abspos-013.html [ Pass ]
 crbug.com/1154572 external/wpt/css/css-sizing/aspect-ratio/block-aspect-ratio-030.html [ Failure ]
+crbug.com/1157740 external/wpt/css/css-sizing/aspect-ratio/flex-aspect-ratio-002.html [ Pass ]
+crbug.com/1157740 external/wpt/css/css-sizing/aspect-ratio/flex-aspect-ratio-004.html [ Pass ]
 crbug.com/1157740 external/wpt/css/css-sizing/aspect-ratio/flex-aspect-ratio-024.html [ Failure ]
 crbug.com/1157740 external/wpt/css/css-sizing/aspect-ratio/flex-aspect-ratio-025.html [ Pass ]
 crbug.com/1203090 external/wpt/css/css-sizing/aspect-ratio/grid-aspect-ratio-018.html [ Pass ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 22f7cff..18d9070 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -1092,7 +1092,6 @@
 crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/static-child-becomes-fixedpos.html [ Failure ]
 crbug.com/1079031 virtual/layout_ng_block_frag/fast/multicol/tall-line-in-short-block.html [ Failure ]
 crbug.com/1079031 virtual/layout_ng_block_frag/fast/multicol/transform-with-fixedpos.html [ Failure ]
-crbug.com/1058792 virtual/layout_ng_block_frag/fast/multicol/vertical-lr/composited-relpos-overlapping-will-change.html [ Failure ]
 crbug.com/1058792 virtual/layout_ng_block_frag/fast/multicol/vertical-rl/composited-relpos-overlapping-will-change.html [ Failure ]
 
 ### With LayoutNGFragmentTraversal (and LayoutNGFragmentItem) enabled:
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/transformations/2d.transformation.rotate3d.X.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/transformations/2d.transformation.rotate3d.x.html
similarity index 92%
rename from third_party/blink/web_tests/external/wpt/html/canvas/element/transformations/2d.transformation.rotate3d.X.html
rename to third_party/blink/web_tests/external/wpt/html/canvas/element/transformations/2d.transformation.rotate3d.x.html
index 42a4e3c..284ffd4 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/element/transformations/2d.transformation.rotate3d.X.html
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/transformations/2d.transformation.rotate3d.x.html
@@ -1,13 +1,13 @@
 <!DOCTYPE html>
 <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
-<title>Canvas test: 2d.transformation.rotate3d.X</title>
+<title>Canvas test: 2d.transformation.rotate3d.x</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/html/canvas/resources/canvas-tests.js"></script>
 <link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
 <body class="show_output">
 
-<h1>2d.transformation.rotate3d.X</h1>
+<h1>2d.transformation.rotate3d.x</h1>
 <p class="desc">rotate3d() around the x axis results in the correct transformation matrix</p>
 
 
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/transformations/2d.transformation.rotate3d.Y.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/transformations/2d.transformation.rotate3d.y.html
similarity index 92%
rename from third_party/blink/web_tests/external/wpt/html/canvas/element/transformations/2d.transformation.rotate3d.Y.html
rename to third_party/blink/web_tests/external/wpt/html/canvas/element/transformations/2d.transformation.rotate3d.y.html
index 5006769..d1dae96 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/element/transformations/2d.transformation.rotate3d.Y.html
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/transformations/2d.transformation.rotate3d.y.html
@@ -1,13 +1,13 @@
 <!DOCTYPE html>
 <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
-<title>Canvas test: 2d.transformation.rotate3d.Y</title>
+<title>Canvas test: 2d.transformation.rotate3d.y</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/html/canvas/resources/canvas-tests.js"></script>
 <link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
 <body class="show_output">
 
-<h1>2d.transformation.rotate3d.Y</h1>
+<h1>2d.transformation.rotate3d.y</h1>
 <p class="desc">rotate3d() around the y axis results in the correct transformation matrix</p>
 
 
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/transformations/2d.transformation.rotate3d.Z.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/transformations/2d.transformation.rotate3d.z.html
similarity index 92%
rename from third_party/blink/web_tests/external/wpt/html/canvas/element/transformations/2d.transformation.rotate3d.Z.html
rename to third_party/blink/web_tests/external/wpt/html/canvas/element/transformations/2d.transformation.rotate3d.z.html
index 71e113d..2012a123 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/element/transformations/2d.transformation.rotate3d.Z.html
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/transformations/2d.transformation.rotate3d.z.html
@@ -1,13 +1,13 @@
 <!DOCTYPE html>
 <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
-<title>Canvas test: 2d.transformation.rotate3d.Z</title>
+<title>Canvas test: 2d.transformation.rotate3d.z</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/html/canvas/resources/canvas-tests.js"></script>
 <link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
 <body class="show_output">
 
-<h1>2d.transformation.rotate3d.Z</h1>
+<h1>2d.transformation.rotate3d.z</h1>
 <p class="desc">rotate3d() around the z axis results in the correct transformation matrix</p>
 
 
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.perspective.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.perspective.html
new file mode 100644
index 0000000..e6bc88095
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.perspective.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.transformation.perspective</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.transformation.perspective</h1>
+<p class="desc">perspective() results in the correct transformation matrix</p>
+
+
+<script>
+var t = async_test("perspective() results in the correct transformation matrix");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+    throw reason;
+});
+t.step(function() {
+
+var offscreenCanvas = new OffscreenCanvas(100, 50);
+var ctx = offscreenCanvas.getContext('2d');
+
+const length = 100;
+ctx.perspective(length);
+const domMatrix = new DOMMatrix();
+domMatrix.m34 = -1/length;
+_assertMatricesApproxEqual(domMatrix, ctx.getTransform());
+ctx.rotateAxis(1, 2, 3, 4);
+domMatrix.rotateAxisAngleSelf(1, 2, 3, rad2deg(4));
+_assertMatricesApproxEqual(domMatrix, ctx.getTransform());
+t.done();
+
+});
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.perspective.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.perspective.worker.js
new file mode 100644
index 0000000..a155ebf
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.perspective.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.transformation.perspective
+// Description:perspective() results in the correct transformation matrix
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("perspective() results in the correct transformation matrix");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+    throw reason;
+});
+t.step(function() {
+
+var offscreenCanvas = new OffscreenCanvas(100, 50);
+var ctx = offscreenCanvas.getContext('2d');
+
+const length = 100;
+ctx.perspective(length);
+const domMatrix = new DOMMatrix();
+domMatrix.m34 = -1/length;
+_assertMatricesApproxEqual(domMatrix, ctx.getTransform());
+ctx.rotateAxis(1, 2, 3, 4);
+domMatrix.rotateAxisAngleSelf(1, 2, 3, rad2deg(4));
+_assertMatricesApproxEqual(domMatrix, ctx.getTransform());
+t.done();
+
+});
+done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.rotate3d.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.rotate3d.html
new file mode 100644
index 0000000..4925c11
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.rotate3d.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.transformation.rotate3d</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.transformation.rotate3d</h1>
+<p class="desc">rotate3d() results in the correct transformation matrix</p>
+
+
+<script>
+var t = async_test("rotate3d() results in the correct transformation matrix");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+    throw reason;
+});
+t.step(function() {
+
+var offscreenCanvas = new OffscreenCanvas(100, 50);
+var ctx = offscreenCanvas.getContext('2d');
+
+// angles are in radians, test something that is not a multiple of pi
+const angleX = 2;
+const angleY = 3;
+const angleZ = 4;
+const domMatrix = new DOMMatrix();
+ctx.rotate3d(angleX, angleY, angleZ);
+domMatrix.rotateSelf(rad2deg(angleX), rad2deg(angleY), rad2deg(angleZ));
+_assertMatricesApproxEqual(domMatrix, ctx.getTransform());
+ctx.rotate3d(angleX, angleY, angleZ);
+domMatrix.rotateSelf(rad2deg(angleX), rad2deg(angleY), rad2deg(angleZ));
+_assertMatricesApproxEqual(domMatrix, ctx.getTransform());
+t.done();
+
+});
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.rotate3d.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.rotate3d.worker.js
new file mode 100644
index 0000000..785b0e2
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.rotate3d.worker.js
@@ -0,0 +1,33 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.transformation.rotate3d
+// Description:rotate3d() results in the correct transformation matrix
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("rotate3d() results in the correct transformation matrix");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+    throw reason;
+});
+t.step(function() {
+
+var offscreenCanvas = new OffscreenCanvas(100, 50);
+var ctx = offscreenCanvas.getContext('2d');
+
+// angles are in radians, test something that is not a multiple of pi
+const angleX = 2;
+const angleY = 3;
+const angleZ = 4;
+const domMatrix = new DOMMatrix();
+ctx.rotate3d(angleX, angleY, angleZ);
+domMatrix.rotateSelf(rad2deg(angleX), rad2deg(angleY), rad2deg(angleZ));
+_assertMatricesApproxEqual(domMatrix, ctx.getTransform());
+ctx.rotate3d(angleX, angleY, angleZ);
+domMatrix.rotateSelf(rad2deg(angleX), rad2deg(angleY), rad2deg(angleZ));
+_assertMatricesApproxEqual(domMatrix, ctx.getTransform());
+t.done();
+
+});
+done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/transformations/2d.transformation.rotate3d.X.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.rotate3d.x.html
similarity index 69%
copy from third_party/blink/web_tests/external/wpt/html/canvas/element/transformations/2d.transformation.rotate3d.X.html
copy to third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.rotate3d.x.html
index 42a4e3c..2905ac3 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/element/transformations/2d.transformation.rotate3d.X.html
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.rotate3d.x.html
@@ -1,23 +1,24 @@
 <!DOCTYPE html>
 <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
-<title>Canvas test: 2d.transformation.rotate3d.X</title>
+<title>OffscreenCanvas test: 2d.transformation.rotate3d.x</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/html/canvas/resources/canvas-tests.js"></script>
-<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
-<body class="show_output">
 
-<h1>2d.transformation.rotate3d.X</h1>
+<h1>2d.transformation.rotate3d.x</h1>
 <p class="desc">rotate3d() around the x axis results in the correct transformation matrix</p>
 
 
-<p class="output">Actual output:</p>
-<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
-
-<ul id="d"></ul>
 <script>
 var t = async_test("rotate3d() around the x axis results in the correct transformation matrix");
-_addTest(function(canvas, ctx) {
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+    throw reason;
+});
+t.step(function() {
+
+var offscreenCanvas = new OffscreenCanvas(100, 50);
+var ctx = offscreenCanvas.getContext('2d');
 
 // angles are in radians, test something that is not a multiple of pi
 const angle = 2;
@@ -28,8 +29,7 @@
 ctx.rotate3d(angle, 0, 0);
 domMatrix.rotateAxisAngleSelf(1, 0, 0, rad2deg(angle));
 _assertMatricesApproxEqual(domMatrix, ctx.getTransform())
-
+t.done();
 
 });
 </script>
-
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.rotate3d.x.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.rotate3d.x.worker.js
new file mode 100644
index 0000000..fcee7c1
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.rotate3d.x.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.transformation.rotate3d.x
+// Description:rotate3d() around the x axis results in the correct transformation matrix
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("rotate3d() around the x axis results in the correct transformation matrix");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+    throw reason;
+});
+t.step(function() {
+
+var offscreenCanvas = new OffscreenCanvas(100, 50);
+var ctx = offscreenCanvas.getContext('2d');
+
+// angles are in radians, test something that is not a multiple of pi
+const angle = 2;
+const domMatrix = new DOMMatrix();
+ctx.rotate3d(angle, 0, 0);
+domMatrix.rotateAxisAngleSelf(1, 0, 0, rad2deg(angle));
+_assertMatricesApproxEqual(domMatrix, ctx.getTransform())
+ctx.rotate3d(angle, 0, 0);
+domMatrix.rotateAxisAngleSelf(1, 0, 0, rad2deg(angle));
+_assertMatricesApproxEqual(domMatrix, ctx.getTransform())
+t.done();
+
+});
+done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/transformations/2d.transformation.rotate3d.Y.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.rotate3d.y.html
similarity index 69%
copy from third_party/blink/web_tests/external/wpt/html/canvas/element/transformations/2d.transformation.rotate3d.Y.html
copy to third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.rotate3d.y.html
index 5006769..27b4eff 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/element/transformations/2d.transformation.rotate3d.Y.html
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.rotate3d.y.html
@@ -1,23 +1,24 @@
 <!DOCTYPE html>
 <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
-<title>Canvas test: 2d.transformation.rotate3d.Y</title>
+<title>OffscreenCanvas test: 2d.transformation.rotate3d.y</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/html/canvas/resources/canvas-tests.js"></script>
-<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
-<body class="show_output">
 
-<h1>2d.transformation.rotate3d.Y</h1>
+<h1>2d.transformation.rotate3d.y</h1>
 <p class="desc">rotate3d() around the y axis results in the correct transformation matrix</p>
 
 
-<p class="output">Actual output:</p>
-<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
-
-<ul id="d"></ul>
 <script>
 var t = async_test("rotate3d() around the y axis results in the correct transformation matrix");
-_addTest(function(canvas, ctx) {
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+    throw reason;
+});
+t.step(function() {
+
+var offscreenCanvas = new OffscreenCanvas(100, 50);
+var ctx = offscreenCanvas.getContext('2d');
 
 // angles are in radians, test something that is not a multiple of pi
 const angle = 2;
@@ -28,8 +29,7 @@
 ctx.rotate3d(0, angle, 0);
 domMatrix.rotateAxisAngleSelf(0, 1, 0, rad2deg(angle));
 _assertMatricesApproxEqual(domMatrix, ctx.getTransform())
-
+t.done();
 
 });
 </script>
-
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.rotate3d.y.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.rotate3d.y.worker.js
new file mode 100644
index 0000000..c4cfd343
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.rotate3d.y.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.transformation.rotate3d.y
+// Description:rotate3d() around the y axis results in the correct transformation matrix
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("rotate3d() around the y axis results in the correct transformation matrix");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+    throw reason;
+});
+t.step(function() {
+
+var offscreenCanvas = new OffscreenCanvas(100, 50);
+var ctx = offscreenCanvas.getContext('2d');
+
+// angles are in radians, test something that is not a multiple of pi
+const angle = 2;
+const domMatrix = new DOMMatrix();
+ctx.rotate3d(0, angle, 0);
+domMatrix.rotateAxisAngleSelf(0, 1, 0, rad2deg(angle));
+_assertMatricesApproxEqual(domMatrix, ctx.getTransform())
+ctx.rotate3d(0, angle, 0);
+domMatrix.rotateAxisAngleSelf(0, 1, 0, rad2deg(angle));
+_assertMatricesApproxEqual(domMatrix, ctx.getTransform())
+t.done();
+
+});
+done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/transformations/2d.transformation.rotate3d.Z.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.rotate3d.z.html
similarity index 69%
copy from third_party/blink/web_tests/external/wpt/html/canvas/element/transformations/2d.transformation.rotate3d.Z.html
copy to third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.rotate3d.z.html
index 71e113d..96405e8 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/element/transformations/2d.transformation.rotate3d.Z.html
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.rotate3d.z.html
@@ -1,23 +1,24 @@
 <!DOCTYPE html>
 <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
-<title>Canvas test: 2d.transformation.rotate3d.Z</title>
+<title>OffscreenCanvas test: 2d.transformation.rotate3d.z</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/html/canvas/resources/canvas-tests.js"></script>
-<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
-<body class="show_output">
 
-<h1>2d.transformation.rotate3d.Z</h1>
+<h1>2d.transformation.rotate3d.z</h1>
 <p class="desc">rotate3d() around the z axis results in the correct transformation matrix</p>
 
 
-<p class="output">Actual output:</p>
-<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
-
-<ul id="d"></ul>
 <script>
 var t = async_test("rotate3d() around the z axis results in the correct transformation matrix");
-_addTest(function(canvas, ctx) {
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+    throw reason;
+});
+t.step(function() {
+
+var offscreenCanvas = new OffscreenCanvas(100, 50);
+var ctx = offscreenCanvas.getContext('2d');
 
 // angles are in radians, test something that is not a multiple of pi
 const angle = 2;
@@ -28,8 +29,7 @@
 ctx.rotate3d(0, 0, angle);
 domMatrix.rotateAxisAngleSelf(0, 0, 1, rad2deg(angle));
 _assertMatricesApproxEqual(domMatrix, ctx.getTransform())
-
+t.done();
 
 });
 </script>
-
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.rotate3d.z.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.rotate3d.z.worker.js
new file mode 100644
index 0000000..f3c5913
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.rotate3d.z.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.transformation.rotate3d.z
+// Description:rotate3d() around the z axis results in the correct transformation matrix
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("rotate3d() around the z axis results in the correct transformation matrix");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+    throw reason;
+});
+t.step(function() {
+
+var offscreenCanvas = new OffscreenCanvas(100, 50);
+var ctx = offscreenCanvas.getContext('2d');
+
+// angles are in radians, test something that is not a multiple of pi
+const angle = 2;
+const domMatrix = new DOMMatrix();
+ctx.rotate3d(0, 0, angle);
+domMatrix.rotateAxisAngleSelf(0, 0, 1, rad2deg(angle));
+_assertMatricesApproxEqual(domMatrix, ctx.getTransform())
+ctx.rotate3d(0, 0, angle);
+domMatrix.rotateAxisAngleSelf(0, 0, 1, rad2deg(angle));
+_assertMatricesApproxEqual(domMatrix, ctx.getTransform())
+t.done();
+
+});
+done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.rotateAxis.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.rotateAxis.html
new file mode 100644
index 0000000..d7257a23b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.rotateAxis.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.transformation.rotateAxis</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.transformation.rotateAxis</h1>
+<p class="desc">rotateAxis() results in the correct transformation matrix</p>
+
+
+<script>
+var t = async_test("rotateAxis() results in the correct transformation matrix");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+    throw reason;
+});
+t.step(function() {
+
+var offscreenCanvas = new OffscreenCanvas(100, 50);
+var ctx = offscreenCanvas.getContext('2d');
+
+// angles are in radians, test something that is not a multiple of pi
+const angle = 2;
+const axis = {x: 1, y: 2, z: 3}
+const domMatrix = new DOMMatrix();
+ctx.rotateAxis(axis.x, axis.y, axis.z, angle);
+domMatrix.rotateAxisAngleSelf(axis.x, axis.y, axis.z, rad2deg(angle));
+_assertMatricesApproxEqual(domMatrix, ctx.getTransform());
+ctx.rotateAxis(axis.x, axis.y, axis.z, angle);
+domMatrix.rotateAxisAngleSelf(axis.x, axis.y, axis.z, rad2deg(angle));
+_assertMatricesApproxEqual(domMatrix, ctx.getTransform());
+t.done();
+
+});
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.rotateAxis.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.rotateAxis.worker.js
new file mode 100644
index 0000000..f17356c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.rotateAxis.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.transformation.rotateAxis
+// Description:rotateAxis() results in the correct transformation matrix
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("rotateAxis() results in the correct transformation matrix");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+    throw reason;
+});
+t.step(function() {
+
+var offscreenCanvas = new OffscreenCanvas(100, 50);
+var ctx = offscreenCanvas.getContext('2d');
+
+// angles are in radians, test something that is not a multiple of pi
+const angle = 2;
+const axis = {x: 1, y: 2, z: 3}
+const domMatrix = new DOMMatrix();
+ctx.rotateAxis(axis.x, axis.y, axis.z, angle);
+domMatrix.rotateAxisAngleSelf(axis.x, axis.y, axis.z, rad2deg(angle));
+_assertMatricesApproxEqual(domMatrix, ctx.getTransform());
+ctx.rotateAxis(axis.x, axis.y, axis.z, angle);
+domMatrix.rotateAxisAngleSelf(axis.x, axis.y, axis.z, rad2deg(angle));
+_assertMatricesApproxEqual(domMatrix, ctx.getTransform());
+t.done();
+
+});
+done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.scale.3d.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.scale.3d.html
new file mode 100644
index 0000000..ffd2287
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.scale.3d.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.transformation.scale.3d</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.transformation.scale.3d</h1>
+<p class="desc">scale() function with three arguments modifies the underlying matrix appropriately</p>
+
+
+<script>
+var t = async_test("scale() function with three arguments modifies the underlying matrix appropriately");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+    throw reason;
+});
+t.step(function() {
+
+var offscreenCanvas = new OffscreenCanvas(100, 50);
+var ctx = offscreenCanvas.getContext('2d');
+
+const sx = 2;
+const sy = 3;
+const sz = 4;
+ctx.scale(sx, sy, sz);
+let canvasTransform = ctx.getTransform();
+_assert(canvasTransform.m11 = sx, "canvasTransform.m11 = sx");
+_assert(canvasTransform.m22 = sy, "canvasTransform.m22 = sy");
+_assert(canvasTransform.m33 = sz, "canvasTransform.m33 = sz");
+ctx.scale(sx, sy, sz);
+canvasTransform = ctx.getTransform();
+_assert(canvasTransform.m11 = 2 * sx, "canvasTransform.m11 = 2 * sx");
+_assert(canvasTransform.m22 = 2 * sy, "canvasTransform.m22 = 2 * sy");
+_assert(canvasTransform.m33 = 2 * sz, "canvasTransform.m33 = 2 * sz");
+t.done();
+
+});
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.scale.3d.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.scale.3d.worker.js
new file mode 100644
index 0000000..692967f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.scale.3d.worker.js
@@ -0,0 +1,35 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.transformation.scale.3d
+// Description:scale() function with three arguments modifies the underlying matrix appropriately
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("scale() function with three arguments modifies the underlying matrix appropriately");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+    throw reason;
+});
+t.step(function() {
+
+var offscreenCanvas = new OffscreenCanvas(100, 50);
+var ctx = offscreenCanvas.getContext('2d');
+
+const sx = 2;
+const sy = 3;
+const sz = 4;
+ctx.scale(sx, sy, sz);
+let canvasTransform = ctx.getTransform();
+_assert(canvasTransform.m11 = sx, "canvasTransform.m11 = sx");
+_assert(canvasTransform.m22 = sy, "canvasTransform.m22 = sy");
+_assert(canvasTransform.m33 = sz, "canvasTransform.m33 = sz");
+ctx.scale(sx, sy, sz);
+canvasTransform = ctx.getTransform();
+_assert(canvasTransform.m11 = 2 * sx, "canvasTransform.m11 = 2 * sx");
+_assert(canvasTransform.m22 = 2 * sy, "canvasTransform.m22 = 2 * sy");
+_assert(canvasTransform.m33 = 2 * sz, "canvasTransform.m33 = 2 * sz");
+t.done();
+
+});
+done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.setTransform.3d.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.setTransform.3d.html
new file mode 100644
index 0000000..fb31cda
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.setTransform.3d.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.transformation.setTransform.3d</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.transformation.setTransform.3d</h1>
+<p class="desc">setTransform() with 4x4 matrix keeps all parameters</p>
+
+
+<script>
+var t = async_test("setTransform() with 4x4 matrix keeps all parameters");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+    throw reason;
+});
+t.step(function() {
+
+var offscreenCanvas = new OffscreenCanvas(100, 50);
+var ctx = offscreenCanvas.getContext('2d');
+
+const transform = new DOMMatrix([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]);
+ctx.setTransform(transform);
+const canvasTransform = ctx.getTransform();
+_assert(transform.toLocaleString() == canvasTransform.toLocaleString(), "transform.toLocaleString() == canvasTransform.toLocaleString()");
+t.done();
+
+});
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.setTransform.3d.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.setTransform.3d.worker.js
new file mode 100644
index 0000000..aa6c033
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.setTransform.3d.worker.js
@@ -0,0 +1,26 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.transformation.setTransform.3d
+// Description:setTransform() with 4x4 matrix keeps all parameters
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("setTransform() with 4x4 matrix keeps all parameters");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+    throw reason;
+});
+t.step(function() {
+
+var offscreenCanvas = new OffscreenCanvas(100, 50);
+var ctx = offscreenCanvas.getContext('2d');
+
+const transform = new DOMMatrix([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]);
+ctx.setTransform(transform);
+const canvasTransform = ctx.getTransform();
+_assert(transform.toLocaleString() == canvasTransform.toLocaleString(), "transform.toLocaleString() == canvasTransform.toLocaleString()");
+t.done();
+
+});
+done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.transform.3d.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.transform.3d.html
new file mode 100644
index 0000000..2dfc718
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.transform.3d.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.transformation.transform.3d</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.transformation.transform.3d</h1>
+<p class="desc">transform() with 4x4 matrix concatenates properly</p>
+
+
+<script>
+var t = async_test("transform() with 4x4 matrix concatenates properly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+    throw reason;
+});
+t.step(function() {
+
+var offscreenCanvas = new OffscreenCanvas(100, 50);
+var ctx = offscreenCanvas.getContext('2d');
+
+const transform = new DOMMatrix([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]);
+ctx.transform(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
+let canvasTransform = ctx.getTransform();
+_assert(transform.toLocaleString() == canvasTransform.toLocaleString(), "transform.toLocaleString() == canvasTransform.toLocaleString()");
+ctx.transform(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
+canvasTransform = ctx.getTransform();
+transform.multiplySelf(transform);
+_assert(transform.toLocaleString() == canvasTransform.toLocaleString(), "transform.toLocaleString() == canvasTransform.toLocaleString()");
+t.done();
+
+});
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.transform.3d.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.transform.3d.worker.js
new file mode 100644
index 0000000..976c4e0
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.transform.3d.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.transformation.transform.3d
+// Description:transform() with 4x4 matrix concatenates properly
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("transform() with 4x4 matrix concatenates properly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+    throw reason;
+});
+t.step(function() {
+
+var offscreenCanvas = new OffscreenCanvas(100, 50);
+var ctx = offscreenCanvas.getContext('2d');
+
+const transform = new DOMMatrix([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]);
+ctx.transform(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
+let canvasTransform = ctx.getTransform();
+_assert(transform.toLocaleString() == canvasTransform.toLocaleString(), "transform.toLocaleString() == canvasTransform.toLocaleString()");
+ctx.transform(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
+canvasTransform = ctx.getTransform();
+transform.multiplySelf(transform);
+_assert(transform.toLocaleString() == canvasTransform.toLocaleString(), "transform.toLocaleString() == canvasTransform.toLocaleString()");
+t.done();
+
+});
+done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.translate.3d.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.translate.3d.html
new file mode 100644
index 0000000..73abc7e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.translate.3d.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.transformation.translate.3d</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.transformation.translate.3d</h1>
+<p class="desc">translate() function with three arguments modifies the underlying matrix appropriately</p>
+
+
+<script>
+var t = async_test("translate() function with three arguments modifies the underlying matrix appropriately");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+    throw reason;
+});
+t.step(function() {
+
+var offscreenCanvas = new OffscreenCanvas(100, 50);
+var ctx = offscreenCanvas.getContext('2d');
+
+const dx = 2;
+const dy = 3;
+const dz = 4;
+ctx.translate(dx, dy, dz);
+let canvasTransform = ctx.getTransform();
+_assert(canvasTransform.m41 = dx, "canvasTransform.m41 = dx");
+_assert(canvasTransform.m42 = dy, "canvasTransform.m42 = dy");
+_assert(canvasTransform.m43 = dz, "canvasTransform.m43 = dz");
+ctx.translate(dx, dy, dz);
+canvasTransform = ctx.getTransform();
+_assert(canvasTransform.m41 = 2 * dx, "canvasTransform.m41 = 2 * dx");
+_assert(canvasTransform.m42 = 2 * dy, "canvasTransform.m42 = 2 * dy");
+_assert(canvasTransform.m43 = 2 * dz, "canvasTransform.m43 = 2 * dz");
+t.done();
+
+});
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.translate.3d.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.translate.3d.worker.js
new file mode 100644
index 0000000..4336022e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/transformations/2d.transformation.translate.3d.worker.js
@@ -0,0 +1,35 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.transformation.translate.3d
+// Description:translate() function with three arguments modifies the underlying matrix appropriately
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("translate() function with three arguments modifies the underlying matrix appropriately");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+    throw reason;
+});
+t.step(function() {
+
+var offscreenCanvas = new OffscreenCanvas(100, 50);
+var ctx = offscreenCanvas.getContext('2d');
+
+const dx = 2;
+const dy = 3;
+const dz = 4;
+ctx.translate(dx, dy, dz);
+let canvasTransform = ctx.getTransform();
+_assert(canvasTransform.m41 = dx, "canvasTransform.m41 = dx");
+_assert(canvasTransform.m42 = dy, "canvasTransform.m42 = dy");
+_assert(canvasTransform.m43 = dz, "canvasTransform.m43 = dz");
+ctx.translate(dx, dy, dz);
+canvasTransform = ctx.getTransform();
+_assert(canvasTransform.m41 = 2 * dx, "canvasTransform.m41 = 2 * dx");
+_assert(canvasTransform.m42 = 2 * dy, "canvasTransform.m42 = 2 * dy");
+_assert(canvasTransform.m43 = 2 * dz, "canvasTransform.m43 = 2 * dz");
+t.done();
+
+});
+done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml/element/transformations.yaml b/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml/element/transformations.yaml
index 89f72468..bca1617 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml/element/transformations.yaml
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml/element/transformations.yaml
@@ -463,10 +463,10 @@
     @assert canvasTransform.m22 = 2 * sy;
     @assert canvasTransform.m33 = 2 * sz;
 
-- name: 2d.transformation.rotate3d.X
+- name: 2d.transformation.rotate3d.x
   desc: rotate3d() around the x axis results in the correct transformation matrix
   testing:
-  - 2d.transformation.rotate3d.X
+  - 2d.transformation.rotate3d.x
   code: |
     // angles are in radians, test something that is not a multiple of pi
     const angle = 2;
@@ -478,10 +478,10 @@
     domMatrix.rotateAxisAngleSelf(1, 0, 0, rad2deg(angle));
     _assertMatricesApproxEqual(domMatrix, ctx.getTransform())
 
-- name: 2d.transformation.rotate3d.Y
+- name: 2d.transformation.rotate3d.y
   desc: rotate3d() around the y axis results in the correct transformation matrix
   testing:
-  - 2d.transformation.rotate3d.Y
+  - 2d.transformation.rotate3d.y
   code: |
     // angles are in radians, test something that is not a multiple of pi
     const angle = 2;
@@ -493,10 +493,10 @@
     domMatrix.rotateAxisAngleSelf(0, 1, 0, rad2deg(angle));
     _assertMatricesApproxEqual(domMatrix, ctx.getTransform())
 
-- name: 2d.transformation.rotate3d.Z
+- name: 2d.transformation.rotate3d.z
   desc: rotate3d() around the z axis results in the correct transformation matrix
   testing:
-  - 2d.transformation.rotate3d.Z
+  - 2d.transformation.rotate3d.z
   code: |
     // angles are in radians, test something that is not a multiple of pi
     const angle = 2;
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml/offscreen/transformations.yaml b/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml/offscreen/transformations.yaml
index 9b4cbd34..5a784f4 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml/offscreen/transformations.yaml
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml/offscreen/transformations.yaml
@@ -404,4 +404,169 @@
     @assert pixel 39,31 == 0,255,0,255;
     @assert pixel 61,31 == 0,255,0,255;
     t.done();
-  expected: green
\ No newline at end of file
+  expected: green
+
+- name: 2d.transformation.setTransform.3d
+  desc: setTransform() with 4x4 matrix keeps all parameters
+  testing:
+  - 2d.transformation.setTransform.3d
+  code: |
+    const transform = new DOMMatrix([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]);
+    ctx.setTransform(transform);
+    const canvasTransform = ctx.getTransform();
+    @assert transform.toLocaleString() == canvasTransform.toLocaleString();
+    t.done();
+
+- name: 2d.transformation.transform.3d
+  desc: transform() with 4x4 matrix concatenates properly
+  testing:
+  - 2d.transformation.transform.3d
+  code: |
+    const transform = new DOMMatrix([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]);
+    ctx.transform(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
+    let canvasTransform = ctx.getTransform();
+    @assert transform.toLocaleString() == canvasTransform.toLocaleString();
+    ctx.transform(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
+    canvasTransform = ctx.getTransform();
+    transform.multiplySelf(transform);
+    @assert transform.toLocaleString() == canvasTransform.toLocaleString();
+    t.done();
+
+- name: 2d.transformation.translate.3d
+  desc: translate() function with three arguments modifies the underlying matrix appropriately
+  testing:
+  - 2d.transformation.translate.3d
+  code: |
+    const dx = 2;
+    const dy = 3;
+    const dz = 4;
+    ctx.translate(dx, dy, dz);
+    let canvasTransform = ctx.getTransform();
+    @assert canvasTransform.m41 = dx;
+    @assert canvasTransform.m42 = dy;
+    @assert canvasTransform.m43 = dz;
+    ctx.translate(dx, dy, dz);
+    canvasTransform = ctx.getTransform();
+    @assert canvasTransform.m41 = 2 * dx;
+    @assert canvasTransform.m42 = 2 * dy;
+    @assert canvasTransform.m43 = 2 * dz;
+    t.done();
+
+- name: 2d.transformation.scale.3d
+  desc: scale() function with three arguments modifies the underlying matrix appropriately
+  testing:
+  - 2d.transformation.scale.3d
+  code: |
+    const sx = 2;
+    const sy = 3;
+    const sz = 4;
+    ctx.scale(sx, sy, sz);
+    let canvasTransform = ctx.getTransform();
+    @assert canvasTransform.m11 = sx;
+    @assert canvasTransform.m22 = sy;
+    @assert canvasTransform.m33 = sz;
+    ctx.scale(sx, sy, sz);
+    canvasTransform = ctx.getTransform();
+    @assert canvasTransform.m11 = 2 * sx;
+    @assert canvasTransform.m22 = 2 * sy;
+    @assert canvasTransform.m33 = 2 * sz;
+    t.done();
+
+- name: 2d.transformation.rotate3d.x
+  desc: rotate3d() around the x axis results in the correct transformation matrix
+  testing:
+  - 2d.transformation.rotate3d.x
+  code: |
+    // angles are in radians, test something that is not a multiple of pi
+    const angle = 2;
+    const domMatrix = new DOMMatrix();
+    ctx.rotate3d(angle, 0, 0);
+    domMatrix.rotateAxisAngleSelf(1, 0, 0, rad2deg(angle));
+    _assertMatricesApproxEqual(domMatrix, ctx.getTransform())
+    ctx.rotate3d(angle, 0, 0);
+    domMatrix.rotateAxisAngleSelf(1, 0, 0, rad2deg(angle));
+    _assertMatricesApproxEqual(domMatrix, ctx.getTransform())
+    t.done();
+
+- name: 2d.transformation.rotate3d.y
+  desc: rotate3d() around the y axis results in the correct transformation matrix
+  testing:
+  - 2d.transformation.rotate3d.y
+  code: |
+    // angles are in radians, test something that is not a multiple of pi
+    const angle = 2;
+    const domMatrix = new DOMMatrix();
+    ctx.rotate3d(0, angle, 0);
+    domMatrix.rotateAxisAngleSelf(0, 1, 0, rad2deg(angle));
+    _assertMatricesApproxEqual(domMatrix, ctx.getTransform())
+    ctx.rotate3d(0, angle, 0);
+    domMatrix.rotateAxisAngleSelf(0, 1, 0, rad2deg(angle));
+    _assertMatricesApproxEqual(domMatrix, ctx.getTransform())
+    t.done();
+
+- name: 2d.transformation.rotate3d.z
+  desc: rotate3d() around the z axis results in the correct transformation matrix
+  testing:
+  - 2d.transformation.rotate3d.z
+  code: |
+    // angles are in radians, test something that is not a multiple of pi
+    const angle = 2;
+    const domMatrix = new DOMMatrix();
+    ctx.rotate3d(0, 0, angle);
+    domMatrix.rotateAxisAngleSelf(0, 0, 1, rad2deg(angle));
+    _assertMatricesApproxEqual(domMatrix, ctx.getTransform())
+    ctx.rotate3d(0, 0, angle);
+    domMatrix.rotateAxisAngleSelf(0, 0, 1, rad2deg(angle));
+    _assertMatricesApproxEqual(domMatrix, ctx.getTransform())
+    t.done();
+
+- name: 2d.transformation.rotate3d
+  desc: rotate3d() results in the correct transformation matrix
+  testing:
+  - 2d.transformation.rotate3d
+  code: |
+    // angles are in radians, test something that is not a multiple of pi
+    const angleX = 2;
+    const angleY = 3;
+    const angleZ = 4;
+    const domMatrix = new DOMMatrix();
+    ctx.rotate3d(angleX, angleY, angleZ);
+    domMatrix.rotateSelf(rad2deg(angleX), rad2deg(angleY), rad2deg(angleZ));
+    _assertMatricesApproxEqual(domMatrix, ctx.getTransform());
+    ctx.rotate3d(angleX, angleY, angleZ);
+    domMatrix.rotateSelf(rad2deg(angleX), rad2deg(angleY), rad2deg(angleZ));
+    _assertMatricesApproxEqual(domMatrix, ctx.getTransform());
+    t.done();
+
+- name: 2d.transformation.rotateAxis
+  desc: rotateAxis() results in the correct transformation matrix
+  testing:
+  - 2d.transformation.rotateAxis
+  code: |
+    // angles are in radians, test something that is not a multiple of pi
+    const angle = 2;
+    const axis = {x: 1, y: 2, z: 3}
+    const domMatrix = new DOMMatrix();
+    ctx.rotateAxis(axis.x, axis.y, axis.z, angle);
+    domMatrix.rotateAxisAngleSelf(axis.x, axis.y, axis.z, rad2deg(angle));
+    _assertMatricesApproxEqual(domMatrix, ctx.getTransform());
+    ctx.rotateAxis(axis.x, axis.y, axis.z, angle);
+    domMatrix.rotateAxisAngleSelf(axis.x, axis.y, axis.z, rad2deg(angle));
+    _assertMatricesApproxEqual(domMatrix, ctx.getTransform());
+    t.done();
+
+- name: 2d.transformation.perspective
+  desc: perspective() results in the correct transformation matrix
+  testing:
+  - 2d.transformation.perspective
+  code: |
+    const length = 100;
+    ctx.perspective(length);
+    const domMatrix = new DOMMatrix();
+    domMatrix.m34 = -1/length;
+    _assertMatricesApproxEqual(domMatrix, ctx.getTransform());
+    ctx.rotateAxis(1, 2, 3, 4);
+    domMatrix.rotateAxisAngleSelf(1, 2, 3, rad2deg(4));
+    _assertMatricesApproxEqual(domMatrix, ctx.getTransform());
+    t.done();
+
diff --git a/third_party/blink/web_tests/external/wpt/video-rvfc/request-video-frame-callback.html b/third_party/blink/web_tests/external/wpt/video-rvfc/request-video-frame-callback.html
index afc6b83..a4404143 100644
--- a/third_party/blink/web_tests/external/wpt/video-rvfc/request-video-frame-callback.html
+++ b/third_party/blink/web_tests/external/wpt/video-rvfc/request-video-frame-callback.html
@@ -12,6 +12,12 @@
   width: 320,
 }
 
+var altTestVideo = {
+  url: getVideoURI('/media/counting'),
+  height: 240,
+  width: 320,
+}
+
 async_test(function(t) {
     let video = document.createElement('video');
     document.body.appendChild(video);
@@ -96,5 +102,50 @@
     video.cancelVideoFrameCallback(-1);
 
 }, 'Test invalid calls to the video.rVFC API.');
+
+promise_test(async function(t) {
+    let video = document.createElement('video');
+    document.body.appendChild(video);
+
+    let first_width = 0;
+    let first_height = 0;
+
+    video.src = testVideo.url;
+
+    await video.play();
+
+    // Switch to and from a second video, and make sure we get rVFC calls at
+    // each step.
+    return new Promise((resolve, reject) => {
+      let onReturnToOriginalVideo = t.step_func((now, metadata) => {
+        assert_equals(first_width, metadata.width);
+        assert_equals(first_height, metadata.height);
+
+        resolve();
+      });
+
+      let onAltVideoFirstFrame = t.step_func((now, metadata) => {
+        // The videos have different sizes, and shouldn't match.
+        assert_not_equals(first_width, metadata.width);
+        assert_not_equals(first_height, metadata.height);
+
+        // Swith back to the original video.
+        video.requestVideoFrameCallback(onReturnToOriginalVideo);
+        video.src = testVideo.url;
+      });
+
+      let onFirstFrame = t.step_func((now, metadata) => {
+        first_width = metadata.width;
+        first_height = metadata.height;
+
+        // Callbacks should persist after changing the source to the alt video.
+        video.requestVideoFrameCallback(onAltVideoFirstFrame);
+        video.src = altTestVideo.url;
+      })
+
+      video.requestVideoFrameCallback(onFirstFrame);
+    });
+}, 'Test video.rVFC does not stop when switching sources.');
+
 </script>
 </html>
diff --git a/third_party/blink/web_tests/platform/linux/virtual/layout_ng_block_frag/fast/multicol/vertical-lr/composited-relpos-overlapping-will-change-expected.png b/third_party/blink/web_tests/platform/linux/virtual/layout_ng_block_frag/fast/multicol/vertical-lr/composited-relpos-overlapping-will-change-expected.png
new file mode 100644
index 0000000..1c7811bd
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/virtual/layout_ng_block_frag/fast/multicol/vertical-lr/composited-relpos-overlapping-will-change-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac-arm11.0/virtual/layout_ng_block_frag/fast/multicol/vertical-lr/composited-relpos-overlapping-will-change-expected.png b/third_party/blink/web_tests/platform/mac-mac-arm11.0/virtual/layout_ng_block_frag/fast/multicol/vertical-lr/composited-relpos-overlapping-will-change-expected.png
new file mode 100644
index 0000000..c54c9267f
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac-arm11.0/virtual/layout_ng_block_frag/fast/multicol/vertical-lr/composited-relpos-overlapping-will-change-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/layout_ng_block_frag/fast/multicol/vertical-lr/composited-relpos-overlapping-will-change-expected.png b/third_party/blink/web_tests/platform/mac/virtual/layout_ng_block_frag/fast/multicol/vertical-lr/composited-relpos-overlapping-will-change-expected.png
new file mode 100644
index 0000000..cf609fc
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/virtual/layout_ng_block_frag/fast/multicol/vertical-lr/composited-relpos-overlapping-will-change-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/layout_ng_block_frag/fast/multicol/vertical-lr/composited-relpos-overlapping-will-change-expected.png b/third_party/blink/web_tests/platform/win/virtual/layout_ng_block_frag/fast/multicol/vertical-lr/composited-relpos-overlapping-will-change-expected.png
new file mode 100644
index 0000000..2b2083a9
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/virtual/layout_ng_block_frag/fast/multicol/vertical-lr/composited-relpos-overlapping-will-change-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/wpt_internal/css/css-ui/outline-float-in-inline-box-ref.html b/third_party/blink/web_tests/wpt_internal/css/css-ui/outline-float-in-inline-box-ref.html
new file mode 100644
index 0000000..7514a6f
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/css/css-ui/outline-float-in-inline-box-ref.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<style>
+.outline {
+  outline: auto;
+}
+
+.float {
+  background: orange;
+  float: right;
+  width: 100px;
+  height: 20px;
+  margin-left: 24px;
+}
+
+.block {
+  display: block;
+  height: 20px;
+  line-height: 20px;
+  overflow: hidden;
+}
+</style>
+<div>
+  <span class="float outline"></span>
+  <a class="outline">
+    <span class="block">
+      <span>X</span>
+    </span>
+  </a>
+</div>
diff --git a/third_party/blink/web_tests/wpt_internal/css/css-ui/outline-float-in-inline-box.html b/third_party/blink/web_tests/wpt_internal/css/css-ui/outline-float-in-inline-box.html
new file mode 100644
index 0000000..3cda4274
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/css/css-ui/outline-float-in-inline-box.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-ui-3/#outline-props">
+<link rel="help" href="https://crbug.com/1207824">
+<link rel="match" href="outline-float-in-inline-box-ref.html">
+<link rel="author" href="mailto:kojii@chromium.com">
+<style>
+.outline {
+  outline: auto;
+}
+
+.float {
+  background: orange;
+  float: right;
+  width: 100px;
+  height: 20px;
+  margin-left: 24px;
+}
+
+.block {
+  display: block;
+  height: 20px;
+  line-height: 20px;
+  overflow: hidden;
+}
+</style>
+<div>
+  <a class="outline">
+    <span class="float"></span>
+    <span class="block">
+      <span>X</span>
+    </span>
+  </a>
+</div>
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/resources/audio-setSinkId.https.html b/third_party/blink/web_tests/wpt_internal/prerender/resources/audio-setSinkId.https.html
new file mode 100644
index 0000000..bec8e09b
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/prerender/resources/audio-setSinkId.https.html
@@ -0,0 +1,31 @@
+<!--
+ Copyright 2021 The Chromium Authors. All rights reserved.
+ Use of this source code is governed by a BSD-style license that can be
+ found in the LICENSE file.
+-->
+
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="utils.js"></script>
+<script src="deferred-promise-utils.js"></script>
+<audio controls id="beat" src="/media/mp3/sound_5.mp3" loop></audio>
+<script>
+
+const params = new URLSearchParams(location.search);
+
+// The main test page (restriction-audio-setSinkId.https.html) loads the
+// initiator page, then the initiator page will prerender itself with the
+// `prerendering` parameter.
+const isPrerendering = params.has('prerendering');
+
+if (!isPrerendering) {
+  loadInitiatorPage();
+} else {
+  const prerenderEventCollector = new PrerenderEventCollector();
+
+  const promise = beat.setSinkId(
+      params.get('sinkId') === 'invalid' ? 'fakeId' : '');
+  prerenderEventCollector.start(promise, 'Audio.setSinkId');
+}
+</script>
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/resources/session-storage-carry-over-to-prerender-page.html b/third_party/blink/web_tests/wpt_internal/prerender/resources/session-storage-carry-over-to-prerender-page.html
deleted file mode 100644
index c3a6fe0..0000000
--- a/third_party/blink/web_tests/wpt_internal/prerender/resources/session-storage-carry-over-to-prerender-page.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<!DOCTYPE html>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="utils.js"></script>
-<script src="session-storage-utils.js"></script>
-<script>
-RunSessionStorageTest(async (isPrerendering, url, prerenderChannel, done) => {
-  if (!isPrerendering) {
-    sessionStorage.setItem('set by initiator page', '1');
-    startPrerendering(url);
-  } else {
-    assert_equals(
-        getSessionStorageKeys(),
-        'set by initiator page',
-        'The session storage item set by the initiator page must be carried' +
-        ' over to the prerendering page.');
-    done();
-  }
-});
-</script>
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/resources/session-storage-isolated-while-prerendering.html b/third_party/blink/web_tests/wpt_internal/prerender/resources/session-storage-isolated-while-prerendering.html
deleted file mode 100644
index 4fcd5ac..0000000
--- a/third_party/blink/web_tests/wpt_internal/prerender/resources/session-storage-isolated-while-prerendering.html
+++ /dev/null
@@ -1,41 +0,0 @@
-<!DOCTYPE html>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="utils.js"></script>
-<script src="session-storage-utils.js"></script>
-<script>
-RunSessionStorageTest(async (isPrerendering, url, prerenderChannel, done) => {
-  if (!isPrerendering) {
-    startPrerendering(url);
-    // Wait for the message from the prerendering page.
-    assert_equals(
-        await getNextMessage(prerenderChannel),
-        'From prerendering page 1')
-
-    // Add an item to the session storage.
-    sessionStorage.setItem('set by initiator page', '1');
-
-    // Send the message to the prerendering page.
-    prerenderChannel.postMessage('From initiator page');
-
-  } else {
-    sessionStorage.setItem('set by prerendering page', '1');
-
-    // Send the message to the initiator page.
-    prerenderChannel.postMessage('From prerendering page 1');
-
-    // Wait for the message from the initiator page.
-    assert_equals(
-        await getNextMessage(prerenderChannel),
-        'From initiator page');
-
-    assert_equals(
-        getSessionStorageKeys(),
-        'set by prerendering page',
-        'The session storage item added by the initiator page after the ' +
-        'prerendering page accessed the session storage must not be visible ' +
-        'in the prerendering page.');
-    done();
-  }
-});
-</script>
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/resources/session-storage-no-leak-to-initiator-page.html b/third_party/blink/web_tests/wpt_internal/prerender/resources/session-storage-no-leak-to-initiator-page.html
deleted file mode 100644
index 0348439..0000000
--- a/third_party/blink/web_tests/wpt_internal/prerender/resources/session-storage-no-leak-to-initiator-page.html
+++ /dev/null
@@ -1,35 +0,0 @@
-<!DOCTYPE html>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="utils.js"></script>
-<script src="session-storage-utils.js"></script>
-<script>
-RunSessionStorageTest(async (isPrerendering, url, prerenderChannel, done) => {
-  if (!isPrerendering) {
-    startPrerendering(url);
-
-    // Wait for the message from the prerendering page.
-    assert_equals(
-        await getNextMessage(prerenderChannel),
-        'From prerendering page')
-
-    assert_equals(
-        getSessionStorageKeys(),
-        '',
-        'The session storage item set by the prerendering page must not be ' +
-        'visible in the initiator page.');
-
-    done();
-  } else {
-    sessionStorage.setItem('set by prerendering page', '1');
-
-    assert_equals(
-        getSessionStorageKeys(),
-        'set by prerendering page',
-        'The session storage item must have been added by the prerendering' +
-        ' page.');
-    // Send the message to the initiator page.
-    prerenderChannel.postMessage('From prerendering page');
-  }
-});
-</script>
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/resources/session-storage-swap-after-activate.html b/third_party/blink/web_tests/wpt_internal/prerender/resources/session-storage-swap-after-activate.html
deleted file mode 100644
index f81841b1..0000000
--- a/third_party/blink/web_tests/wpt_internal/prerender/resources/session-storage-swap-after-activate.html
+++ /dev/null
@@ -1,76 +0,0 @@
-<!DOCTYPE html>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="utils.js"></script>
-<script src="session-storage-utils.js"></script>
-<script>
-RunSessionStorageTest(async (isPrerendering, url, prerenderChannel, done) => {
-  if (!isPrerendering) {
-    sessionStorage.setItem('set by initiator page 1', '1');
-    startPrerendering(url);
-    // Wait for the message from the prerendering page.
-    assert_equals(
-        await getNextMessage(prerenderChannel),
-        'From prerendering page 1')
-
-    // Add an item to the session storage.
-    sessionStorage.setItem('set by initiator page 2', '1');
-
-    // Send the message to the prerendering page.
-    prerenderChannel.postMessage('From initiator page');
-
-    // Wait for the message from the prerendering page.
-    assert_equals(
-        await getNextMessage(prerenderChannel),
-        'From prerendering page 2')
-
-    // Register beforeunload event handler which adds a new item in the
-    // session storage.
-    window.addEventListener('beforeunload', () => {
-      sessionStorage.setItem('set by initiator page 3', '1');
-    });
-
-    // Navigate to the prerenderered page.
-    window.location = url;
-  } else {
-    const prerenderingchangePromise =
-        new Promise(resolve => {
-            document.addEventListener('prerenderingchange', () => {
-              sessionStorage.setItem('set by activated page', 1);
-              resolve();
-            });
-          });
-
-    sessionStorage.setItem('set by prerendering page', '1');
-
-    // Send the message to the initiator page.
-    prerenderChannel.postMessage('From prerendering page 1');
-
-    // Wait for the message from the initiator page.
-    assert_equals(await getNextMessage(prerenderChannel),
-        'From initiator page');
-
-    assert_equals(
-        getSessionStorageKeys(),
-        'set by initiator page 1, set by prerendering page',
-        'The session storage item added by the initiator page after ' +
-        'starting prerendering must not be visible in the prerendering ' +
-        'page.');
-
-    // Send the message to the initiator page.
-    prerenderChannel.postMessage('From prerendering page 2');
-
-    // Wait until activated.
-    await prerenderingchangePromise;
-
-    assert_equals(
-        getSessionStorageKeys(),
-        'set by activated page, set by initiator page 1, ' +
-        'set by initiator page 2, set by initiator page 3',
-        'The all session storage items added by the initiator page and ' +
-        'the item added by the activated page must be visible in the ' +
-        'activated page.');
-    done();
-  }
-});
-</script>
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/resources/session-storage-utils.js b/third_party/blink/web_tests/wpt_internal/prerender/resources/session-storage-utils.js
deleted file mode 100644
index d7688607..0000000
--- a/third_party/blink/web_tests/wpt_internal/prerender/resources/session-storage-utils.js
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-function getSessionStorageKeys() {
-  let keys = [];
-  let txt = '';
-  for (let i = 0; i < sessionStorage.length; ++i) {
-    keys.push(sessionStorage.key(i));
-  }
-  keys.sort();
-  keys.forEach((key) => {
-    if (txt.length) {
-      txt += ', ';
-    }
-    txt += key;
-  });
-  return txt;
-}
-
-function getNextMessage(channel) {
-  return new Promise(resolve => {
-    channel.addEventListener('message', e => {
-      resolve(e.data);
-    }, {once: true});
-  });
-}
-
-// session_storage_test() is a utility function for running session storage
-// related tests that open a initiator page using window.open().
-function session_storage_test(testPath) {
-  promise_test(async t => {
-    const testChannel = new BroadcastChannel('test-channel');
-    t.add_cleanup(() => {
-      testChannel.close();
-    });
-    const gotMessage = getNextMessage(testChannel);
-    const url = 'resources/' + testPath;
-    window.open(url, '_blank', 'noopener');
-    assert_equals(await gotMessage, 'Done');
-  }, testPath);
-}
-
-// RunSessionStorageTest() is a utility function for running session storage
-// related tests that requires coordinated code execution on both the initiator
-// page and the prerendering page. The passed |func| function will be called
-// with the following arguments:
-//   - isPrerendering: Whether the |func| is called in the prerendering page.
-//   - url: The URL of the prerendering page. |func| should call
-//     startPrerendering(url) when |isPrerendering| is false to start the
-//     prerendering.
-//   - channel: A Broadcast Channel which can be used to coordinate the code
-//     execution on the initiator page and the prerendering page.
-//   - done: A function that should be called when the test completes
-//     successfully.
-async function RunSessionStorageTest(func) {
-  const url = new URL(document.URL);
-  url.searchParams.set('prerendering', '');
-  const params = new URLSearchParams(location.search);
-  // The main test page loads the initiator page, then the initiator page will
-  // prerender itself with the `prerendering` parameter.
-  const isPrerendering = params.has('prerendering');
-  const prerenderChannel = new BroadcastChannel('prerender-channel');
-  const testChannel = new BroadcastChannel('test-channel');
-  window.addEventListener('unload', () => {
-    prerenderChannel.close();
-    testChannel.close();
-  });
-  try {
-    await func(isPrerendering, url.toString(), prerenderChannel, () => {
-      testChannel.postMessage('Done');
-    })
-  } catch (e) {
-    testChannel.postMessage(e.toString());
-  }
-}
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/restriction-audio-setSinkId-with-invalid-sinkId.https.html b/third_party/blink/web_tests/wpt_internal/prerender/restriction-audio-setSinkId-with-invalid-sinkId.https.html
new file mode 100644
index 0000000..66122a2
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/prerender/restriction-audio-setSinkId-with-invalid-sinkId.https.html
@@ -0,0 +1,64 @@
+<!--
+ Copyright 2021 The Chromium Authors. All rights reserved.
+ Use of this source code is governed by a BSD-style license that can be
+ found in the LICENSE file.
+-->
+
+<!DOCTYPE html>
+<!--
+This file cannot be upstreamed to WPT until:
+* startPrerendering() usage is replaced with a WebDriver API
+* 'speaker-selection' gets permission to use speaker devices with a WebDriver
+*  API
+-->
+
+<title>
+Access to the setSinkId of the Audio API with an invalid value is deferred
+</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/utils.js"></script>
+<body>
+<script>
+
+promise_test(async t => {
+  const bc = new BroadcastChannel('test-channel');
+  t.add_cleanup(_ => bc.close());
+
+  const gotMessage = new Promise(resolve => {
+    bc.addEventListener('message', e => {
+      resolve(e.data);
+    }, {
+      once: true
+    });
+  });
+
+  const url = `resources/audio-setSinkId.https.html?sinkId=invalid`;
+  window.open(url, '_blank', 'noopener');
+
+  const result = await gotMessage;
+  const expected = [
+    {
+      event: 'started waiting Audio.setSinkId',
+      prerendering: true
+    },
+    {
+      event: 'prerendering change',
+      prerendering: false
+    },
+    {
+      event: 'Audio.setSinkId rejected: NotFoundError',
+      prerendering: false
+    },
+  ];
+  assert_equals(result.length, expected.length);
+  for (let i = 0; i < result.length; i++) {
+    assert_equals(result[i].event, expected[i].event, `event${i}`);
+    assert_equals(result[i].prerendering, expected[i].prerendering,
+      `prerendering${i}`);
+  }
+
+}, `the access to the setSinkId of Audio API with the invalid sinkId should be
+    deferred until the prerendered page is activated`);
+</script>
+</body>
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/restriction-audio-setSinkId.https.html b/third_party/blink/web_tests/wpt_internal/prerender/restriction-audio-setSinkId.https.html
new file mode 100644
index 0000000..c7309c5
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/prerender/restriction-audio-setSinkId.https.html
@@ -0,0 +1,62 @@
+<!--
+ Copyright 2021 The Chromium Authors. All rights reserved.
+ Use of this source code is governed by a BSD-style license that can be
+ found in the LICENSE file.
+-->
+
+<!DOCTYPE html>
+<!--
+This file cannot be upstreamed to WPT until:
+* startPrerendering() usage is replaced with a WebDriver API
+* 'speaker-selection' is used with a WebDriver API
+-->
+
+<title>Access to the setSinkId of the Audio API is deferred</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/utils.js"></script>
+<body>
+<script>
+
+promise_test(async t => {
+  const bc = new BroadcastChannel('test-channel');
+  t.add_cleanup(_ => bc.close());
+
+  const gotMessage = new Promise(resolve => {
+    bc.addEventListener('message', e => {
+      resolve(e.data);
+    }, {
+      once: true
+    });
+  });
+
+  const url = `resources/audio-setSinkId.https.html?sinkId=default`;
+  window.open(url, '_blank', 'noopener');
+
+  const result = await gotMessage;
+  const expected = [
+    {
+      event: 'started waiting Audio.setSinkId',
+      prerendering: true
+    },
+    {
+      event: 'prerendering change',
+      prerendering: false
+    },
+    {
+      event: 'finished waiting Audio.setSinkId',
+      prerendering: false
+    },
+  ];
+  assert_equals(result.length, expected.length);
+  for (let i = 0; i < result.length; i++) {
+    assert_equals(result[i].event, expected[i].event, `event${i}`);
+    assert_equals(result[i].prerendering, expected[i].prerendering,
+      `prerendering${i}`);
+  }
+
+}, `the access to the setSinkId of Audio API should be deferred until the
+    prerendered page is activated`);
+
+</script>
+</body>
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/session-storage.html b/third_party/blink/web_tests/wpt_internal/prerender/session-storage.html
deleted file mode 100644
index 8f6bfc10..0000000
--- a/third_party/blink/web_tests/wpt_internal/prerender/session-storage.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<!DOCTYPE html>
-<!--
-This file cannot be upstreamed to WPT until:
-* startPrerendering() usage is replaced with a WebDriver API.
-* The "clone & swap" mechanism for session storage in prerendering described in
-  https://github.com/whatwg/storage/issues/119 is added to the specification.
--->
-<title>Same-origin prerendering can access sessionStorage</title>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="resources/utils.js"></script>
-<script src="resources/session-storage-utils.js"></script>
-<body>
-<script>
-session_storage_test(
-  'session-storage-carry-over-to-prerender-page.html');
-
-session_storage_test(
-  'session-storage-no-leak-to-initiator-page.html');
-
-session_storage_test(
-  'session-storage-isolated-while-prerendering.html');
-
-session_storage_test(
-  'session-storage-swap-after-activate.html');
-</script>
-</body>
diff --git a/tools/accessibility/inspect/ax_tree_server.h b/tools/accessibility/inspect/ax_tree_server.h
index 128ac93c..d9937d69 100644
--- a/tools/accessibility/inspect/ax_tree_server.h
+++ b/tools/accessibility/inspect/ax_tree_server.h
@@ -10,6 +10,7 @@
 #include "base/callback.h"
 #include "base/files/file_path.h"
 #include "build/build_config.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/accessibility/platform/inspect/ax_tree_formatter.h"
 
 #if defined(OS_WIN)
diff --git a/tools/binary_size/libsupersize/apkanalyzer.py b/tools/binary_size/libsupersize/apkanalyzer.py
index a53e793c..e40f682 100644
--- a/tools/binary_size/libsupersize/apkanalyzer.py
+++ b/tools/binary_size/libsupersize/apkanalyzer.py
@@ -183,7 +183,7 @@
         # The base_name group needs to be non-greedy/minimal (using +?) since we
         # want it to not include $$Lambda$28 when present.
         r'(?P<base_name>.+?)(\$\$Lambda\$\d+)?'
-        r'\$\$InternalSynthetic(Lambda|Outline)'
+        r'\$\$InternalSynthetic[a-zA-Z0-9_]+'
         r'\$\d+\$[0-9a-f]+\$\d+',
         class_path)
     if match:
@@ -192,9 +192,10 @@
       return outer_class, full_name.replace(class_path, new_name)
     # Example: AnimatedProgressBar$$ExternalSyntheticLambda0
     # Example: AutofillAssistant$$Lambda$2$$ExternalSyntheticOutline0
+    # Example: ContextMenuCoord$$Lambda$2$$ExternalSyntheticThrowCCEIfNotNull0
     match = re.fullmatch(
         r'(?P<base_name>.+?)(\$\$Lambda\$\d+)?'
-        r'\$\$ExternalSynthetic(Lambda|Outline)\d+', class_path)
+        r'\$\$ExternalSynthetic[a-zA-Z0-9_]+', class_path)
     if match:
       new_name = self._GetLambdaName(class_path=class_path,
                                      base_name=match.group('base_name'),
@@ -221,7 +222,10 @@
       new_name = self._GetLambdaName(class_path=class_path, base_name=base_name)
       outer_class = package_name + class_name
       return outer_class, full_name.replace(class_path, new_name)
-    assert False, 'No valid match for lambda ' + class_path
+    assert False, (
+        'No valid match for new lambda name format: ' + class_path + '\n'
+        'Please update https://crbug.com/1208385 with this error so we can '
+        'update the lambda normalization code.')
 
 
 # Visible for testing.
diff --git a/tools/binary_size/libsupersize/apkanalyzer_test.py b/tools/binary_size/libsupersize/apkanalyzer_test.py
index 01f5119..391e877 100755
--- a/tools/binary_size/libsupersize/apkanalyzer_test.py
+++ b/tools/binary_size/libsupersize/apkanalyzer_test.py
@@ -122,6 +122,14 @@
         expected_name=('$$Outlined$AutofillAssistant$$Lambda$0'),
     )
 
+  def testLambdaNormalizer_externalSyntheticLambdaWithExtraText(self):
+    self.assertNormalizedTo(
+        # pylint: disable=line-too-long
+        class_path='ContextMenuCoordinator$$Lambda$1$$ExternalSyntheticThrowCCEIfNotNull0',
+        expected_outer_class='ContextMenuCoordinator',
+        expected_name=('$$Outlined$ContextMenuCoordinator$$Lambda$0'),
+    )
+
   def testLambdaNormalizer_internalSyntheticLambda(self):
     self.assertNormalizedTo(
         class_path=
diff --git a/tools/download_optimization_profile.py b/tools/download_optimization_profile.py
index 26887e86..6cc5359 100755
--- a/tools/download_optimization_profile.py
+++ b/tools/download_optimization_profile.py
@@ -20,7 +20,11 @@
 import os
 import subprocess
 import sys
-import urllib2
+
+if sys.version_info.major == 2:
+  from urllib2 import urlopen
+else:
+  from urllib.request import urlopen
 
 GS_HTTP_URL = 'https://storage.googleapis.com'
 
@@ -80,7 +84,7 @@
   else:
     gs_url = '/'.join([GS_HTTP_URL, desired_profile_name[len(gs_prefix):]])
 
-  with contextlib.closing(urllib2.urlopen(gs_url)) as u:
+  with contextlib.closing(urlopen(gs_url)) as u:
     with open(out_path, 'wb') as f:
       while True:
         buf = u.read(4096)
diff --git a/tools/json_schema_compiler/cc_generator.py b/tools/json_schema_compiler/cc_generator.py
index 7f453e8f..06d7711b 100644
--- a/tools/json_schema_compiler/cc_generator.py
+++ b/tools/json_schema_compiler/cc_generator.py
@@ -1237,18 +1237,20 @@
     c = Code()
     c.Concat(self._GeneratePropertyFunctions(function_scope, params))
 
-    (c.Sblock('std::unique_ptr<base::ListValue> %(function_scope)s'
+    (c.Sblock('std::vector<base::Value> %(function_scope)s'
                   'Create(%(declaration_list)s) {')
-      .Append('auto create_results = std::make_unique<base::ListValue>();')
+      .Append('std::vector<base::Value> create_results;')
+      .Append('create_results.reserve(%d);' % len(params))
     )
     declaration_list = []
     for param in params:
       declaration_list.append(cpp_util.GetParameterDeclaration(
           param, self._type_helper.GetCppType(param.type_)))
-      c.Cblock(self._CreateValueFromType('create_results->Append(%s);',
-                                         param.name,
-                                         param.type_,
-                                         param.unix_name))
+      c.Cblock(self._CreateValueFromType(
+          'create_results.push_back(base::Value::FromUniquePtrValue(%s));',
+          param.name,
+          param.type_,
+          param.unix_name))
     c.Append('return create_results;')
     c.Eblock('}')
     c.Substitute({
diff --git a/tools/json_schema_compiler/cpp_util.py b/tools/json_schema_compiler/cpp_util.py
index 7478c9d..1d76e2d 100644
--- a/tools/json_schema_compiler/cpp_util.py
+++ b/tools/json_schema_compiler/cpp_util.py
@@ -19,14 +19,17 @@
 )
 GENERATED_FILE_MESSAGE = """// GENERATED FROM THE API DEFINITION IN
 //   %s
+// by tools/json_schema_compiler.
 // DO NOT EDIT.
 """
 GENERATED_BUNDLE_FILE_MESSAGE = """// GENERATED FROM THE API DEFINITIONS IN
 //   %s
+// by tools/json_schema_compiler.
 // DO NOT EDIT.
 """
 GENERATED_FEATURE_MESSAGE = """// GENERATED FROM THE FEATURE DEFINITIONS IN
 //   %s
+// by tools/json_schema_compiler.
 // DO NOT EDIT.
 """
 
diff --git a/tools/json_schema_compiler/feature_compiler.py b/tools/json_schema_compiler/feature_compiler.py
index 645c5fb..fcd45b5 100644
--- a/tools/json_schema_compiler/feature_compiler.py
+++ b/tools/json_schema_compiler/feature_compiler.py
@@ -25,6 +25,7 @@
 
 // GENERATED FROM THE FEATURES FILE:
 //   %(source_files)s
+// by tools/json_schema_compiler.
 // DO NOT EDIT.
 
 #ifndef %(header_guard)s
@@ -48,6 +49,7 @@
 
 // GENERATED FROM THE FEATURES FILE:
 //   %(source_files)s
+// by tools/json_schema_compiler.
 // DO NOT EDIT.
 
 #include "%(header_file_path)s"
diff --git a/tools/json_schema_compiler/h_generator.py b/tools/json_schema_compiler/h_generator.py
index 5186983c..4c22baa 100644
--- a/tools/json_schema_compiler/h_generator.py
+++ b/tools/json_schema_compiler/h_generator.py
@@ -440,7 +440,7 @@
         c.Comment(param.description)
       declaration_list.append(cpp_util.GetParameterDeclaration(
           param, self._type_helper.GetCppType(param.type_)))
-    c.Append('std::unique_ptr<base::ListValue> Create(%s);' %
+    c.Append('std::vector<base::Value> Create(%s);' %
              ', '.join(declaration_list))
     return c
 
diff --git a/tools/json_schema_compiler/test/additional_properties_unittest.cc b/tools/json_schema_compiler/test/additional_properties_unittest.cc
index 1461b3e..9d8ff35 100644
--- a/tools/json_schema_compiler/test/additional_properties_unittest.cc
+++ b/tools/json_schema_compiler/test/additional_properties_unittest.cc
@@ -6,6 +6,7 @@
 
 #include <memory>
 #include <utility>
+#include <vector>
 
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -55,14 +56,14 @@
   result_object.integer = 5;
   result_object.additional_properties["key"] = "value";
 
-  base::ListValue expected;
+  std::vector<base::Value> expected;
   {
-    auto dict = std::make_unique<base::DictionaryValue>();
-    dict->SetInteger("integer", 5);
-    dict->SetString("key", "value");
-    expected.Append(std::move(dict));
+    base::Value dict(base::Value::Type::DICTIONARY);
+    dict.SetIntKey("integer", 5);
+    dict.SetStringKey("key", "value");
+    expected.push_back(std::move(dict));
   }
 
   EXPECT_EQ(expected,
-            *ap::ReturnAdditionalProperties::Results::Create(result_object));
+            ap::ReturnAdditionalProperties::Results::Create(result_object));
 }
diff --git a/tools/json_schema_compiler/test/arrays_unittest.cc b/tools/json_schema_compiler/test/arrays_unittest.cc
index 2c2a5b31..3b1ae0b 100644
--- a/tools/json_schema_compiler/test/arrays_unittest.cc
+++ b/tools/json_schema_compiler/test/arrays_unittest.cc
@@ -251,8 +251,7 @@
   std::vector<int> integers;
   integers.push_back(1);
   integers.push_back(2);
-  base::Value results = base::Value::FromUniquePtrValue(
-      arrays::ReturnIntegerArray::Results::Create(integers));
+  base::Value results(arrays::ReturnIntegerArray::Results::Create(integers));
 
   base::Value expected(base::Value::Type::LIST);
   base::Value expected_argument(base::Value::Type::LIST);
@@ -268,8 +267,7 @@
   items.push_back(arrays::Item());
   items[0].val = 1;
   items[1].val = 2;
-  base::Value results = base::Value::FromUniquePtrValue(
-      arrays::ReturnRefArray::Results::Create(items));
+  base::Value results(arrays::ReturnRefArray::Results::Create(items));
 
   base::ListValue expected;
   auto expected_argument = std::make_unique<base::ListValue>();
diff --git a/tools/json_schema_compiler/test/callbacks_unittest.cc b/tools/json_schema_compiler/test/callbacks_unittest.cc
index 1eb05c7..5f88a38 100644
--- a/tools/json_schema_compiler/test/callbacks_unittest.cc
+++ b/tools/json_schema_compiler/test/callbacks_unittest.cc
@@ -12,7 +12,7 @@
 TEST(JsonSchemaCompilerCallbacksTest, ReturnsObjectResultCreate) {
   test::api::callbacks::ReturnsObject::Results::SomeObject some_object;
   some_object.state = test::api::callbacks::ENUMERATION_FOO;
-  base::Value results = base::Value::FromUniquePtrValue(
+  base::Value results(
       test::api::callbacks::ReturnsObject::Results::Create(some_object));
 
   auto expected_dict = std::make_unique<base::DictionaryValue>();
@@ -25,7 +25,7 @@
 TEST(JsonSchemaCompilerCallbacksTest, ReturnsMultipleResultCreate) {
   test::api::callbacks::ReturnsMultiple::Results::SomeObject some_object;
   some_object.state = test::api::callbacks::ENUMERATION_FOO;
-  base::Value results = base::Value::FromUniquePtrValue(
+  base::Value results(
       test::api::callbacks::ReturnsMultiple::Results::Create(5, some_object));
 
   auto expected_dict = std::make_unique<base::DictionaryValue>();
diff --git a/tools/json_schema_compiler/test/crossref_unittest.cc b/tools/json_schema_compiler/test/crossref_unittest.cc
index b1718a74..64c55b8 100644
--- a/tools/json_schema_compiler/test/crossref_unittest.cc
+++ b/tools/json_schema_compiler/test/crossref_unittest.cc
@@ -6,6 +6,7 @@
 
 #include <memory>
 #include <utility>
+#include <vector>
 
 #include "base/values.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -78,11 +79,10 @@
   auto test_type = std::make_unique<simple_api::TestType>();
   EXPECT_TRUE(simple_api::TestType::Populate(*value, test_type.get()));
 
-  base::Value results = base::Value::FromUniquePtrValue(
-      crossref::GetTestType::Results::Create(*test_type));
-  ASSERT_TRUE(results.is_list());
-  ASSERT_EQ(1u, results.GetList().size());
-  EXPECT_EQ(*value, results.GetList()[0]);
+  std::vector<base::Value> results =
+      crossref::GetTestType::Results::Create(*test_type);
+  ASSERT_EQ(1u, results.size());
+  EXPECT_EQ(*value, results[0]);
 }
 
 TEST(JsonSchemaCompilerCrossrefTest, TestTypeInObjectParamsCreate) {
diff --git a/tools/json_schema_compiler/test/enums_unittest.cc b/tools/json_schema_compiler/test/enums_unittest.cc
index 5e19a09e..7c77567 100644
--- a/tools/json_schema_compiler/test/enums_unittest.cc
+++ b/tools/json_schema_compiler/test/enums_unittest.cc
@@ -38,8 +38,8 @@
     ASSERT_TRUE(params.get());
     EXPECT_EQ(enums::ENUMERATION_ONE, params->enumeration);
 
-    EXPECT_EQ(args, *enums::ReturnsEnumAsType::Results::Create(
-                        enums::ENUMERATION_ONE));
+    EXPECT_EQ(args, base::Value(enums::ReturnsEnumAsType::Results::Create(
+                        enums::ENUMERATION_ONE)));
   }
   {
     enums::HasEnumeration enumeration;
@@ -100,8 +100,7 @@
   }
   {
     enums::Enumeration state = enums::ENUMERATION_ONE;
-    base::Value results = base::Value::FromUniquePtrValue(
-        enums::ReturnsEnum::Results::Create(state));
+    base::Value results(enums::ReturnsEnum::Results::Create(state));
     base::ListValue expected;
     expected.AppendString("one");
     EXPECT_EQ(expected, results);
@@ -110,9 +109,8 @@
 
 TEST(JsonSchemaCompilerEnumsTest, ReturnsTwoEnumsCreate) {
   {
-    base::Value results =
-        base::Value::FromUniquePtrValue(enums::ReturnsTwoEnums::Results::Create(
-            enums::ENUMERATION_ONE, enums::OTHER_ENUMERATION_HAM));
+    base::Value results(enums::ReturnsTwoEnums::Results::Create(
+        enums::ENUMERATION_ONE, enums::OTHER_ENUMERATION_HAM));
     base::ListValue expected;
     expected.AppendString("one");
     expected.AppendString("ham");
@@ -255,8 +253,7 @@
   }
   {
     enums::Enumeration some_enum = enums::ENUMERATION_ONE;
-    base::Value results =
-        base::Value::FromUniquePtrValue(enums::OnEnumFired::Create(some_enum));
+    base::Value results(enums::OnEnumFired::Create(some_enum));
     base::ListValue expected;
     expected.AppendString("one");
     EXPECT_EQ(expected, results);
@@ -265,9 +262,8 @@
 
 TEST(JsonSchemaCompilerEnumsTest, OnTwoEnumsFiredCreate) {
   {
-    base::Value results =
-        base::Value::FromUniquePtrValue(enums::OnTwoEnumsFired::Create(
-            enums::ENUMERATION_ONE, enums::OTHER_ENUMERATION_HAM));
+    base::Value results(enums::OnTwoEnumsFired::Create(
+        enums::ENUMERATION_ONE, enums::OTHER_ENUMERATION_HAM));
     base::ListValue expected;
     expected.AppendString("one");
     expected.AppendString("ham");
diff --git a/tools/json_schema_compiler/test/functions_on_types_unittest.cc b/tools/json_schema_compiler/test/functions_on_types_unittest.cc
index 90550a8e..d8384d2 100644
--- a/tools/json_schema_compiler/test/functions_on_types_unittest.cc
+++ b/tools/json_schema_compiler/test/functions_on_types_unittest.cc
@@ -54,7 +54,7 @@
   functions_on_types::StorageArea::Get::Results::Items items;
   items.additional_properties.SetDouble("asdf", 0.1);
   items.additional_properties.SetString("sdfg", "zxcv");
-  base::Value results = base::Value::FromUniquePtrValue(
+  base::Value results(
       functions_on_types::StorageArea::Get::Results::Create(items));
   ASSERT_TRUE(results.is_list());
   ASSERT_EQ(1u, results.GetList().size());
diff --git a/tools/json_schema_compiler/test/idl_schemas_unittest.cc b/tools/json_schema_compiler/test/idl_schemas_unittest.cc
index 260e9664..a6deda7 100644
--- a/tools/json_schema_compiler/test/idl_schemas_unittest.cc
+++ b/tools/json_schema_compiler/test/idl_schemas_unittest.cc
@@ -62,19 +62,16 @@
 
   // Test functions that take a callback function as a parameter, with varying
   // callback signatures.
-  base::Value f4_results =
-      base::Value::FromUniquePtrValue(Function4::Results::Create());
+  base::Value f4_results(Function4::Results::Create());
   base::ListValue expected;
   EXPECT_EQ(expected, f4_results);
 
-  base::Value f5_results =
-      base::Value::FromUniquePtrValue(Function5::Results::Create(13));
+  base::Value f5_results(Function5::Results::Create(13));
   ASSERT_TRUE(f5_results.is_list());
   ASSERT_EQ(1u, f5_results.GetList().size());
   EXPECT_TRUE(f5_results.GetList()[0].is_int());
 
-  base::Value f6_results =
-      base::Value::FromUniquePtrValue(Function6::Results::Create(a));
+  base::Value f6_results(Function6::Results::Create(a));
   ASSERT_TRUE(f6_results.is_list());
   ASSERT_EQ(1u, f6_results.GetList().size());
   MyType1 c;
diff --git a/tools/json_schema_compiler/test/objects_unittest.cc b/tools/json_schema_compiler/test/objects_unittest.cc
index 6550033..7f36ea2 100644
--- a/tools/json_schema_compiler/test/objects_unittest.cc
+++ b/tools/json_schema_compiler/test/objects_unittest.cc
@@ -57,8 +57,7 @@
 TEST(JsonSchemaCompilerObjectsTest, ReturnsObjectResultCreate) {
   test::api::objects::ReturnsObject::Results::Info info;
   info.state = test::api::objects::FIRST_STATE_FOO;
-  base::Value results = base::Value::FromUniquePtrValue(
-      test::api::objects::ReturnsObject::Results::Create(info));
+  base::Value results(test::api::objects::ReturnsObject::Results::Create(info));
   ASSERT_TRUE(results.is_list());
   ASSERT_EQ(1u, results.GetList().size());
 
@@ -70,8 +69,7 @@
 TEST(JsonSchemaCompilerObjectsTest, OnObjectFiredCreate) {
   test::api::objects::OnObjectFired::SomeObject object;
   object.state = test::api::objects::FIRST_STATE_BAR;
-  base::Value results = base::Value::FromUniquePtrValue(
-      test::api::objects::OnObjectFired::Create(object));
+  base::Value results(test::api::objects::OnObjectFired::Create(object));
   ASSERT_TRUE(results.is_list());
   ASSERT_EQ(1u, results.GetList().size());
 
diff --git a/tools/json_schema_compiler/test/returns_async_unittest.cc b/tools/json_schema_compiler/test/returns_async_unittest.cc
index 8f4cdf3..d94c6b4e 100644
--- a/tools/json_schema_compiler/test/returns_async_unittest.cc
+++ b/tools/json_schema_compiler/test/returns_async_unittest.cc
@@ -4,7 +4,6 @@
 
 #include "tools/json_schema_compiler/test/returns_async.h"
 
-#include <memory>
 #include <utility>
 
 #include "testing/gtest/include/gtest/gtest.h"
@@ -15,7 +14,7 @@
 TEST(JsonSchemaCompilerReturnsAsyncTest, ReturnsObjectResultCreate) {
   test::api::returns_async::SupportsPromises::Results::SomeObject some_object;
   some_object.state = test::api::returns_async::ENUMERATION_FOO;
-  base::Value results = base::Value::FromUniquePtrValue(
+  base::Value results(
       test::api::returns_async::SupportsPromises::Results::Create(some_object));
 
   base::Value expected_dict = base::Value(base::Value::Type::DICTIONARY);
diff --git a/tools/json_schema_compiler/test/simple_api_unittest.cc b/tools/json_schema_compiler/test/simple_api_unittest.cc
index 87c79ac1..489ffbb 100644
--- a/tools/json_schema_compiler/test/simple_api_unittest.cc
+++ b/tools/json_schema_compiler/test/simple_api_unittest.cc
@@ -59,8 +59,7 @@
 }  // namespace
 
 TEST(JsonSchemaCompilerSimpleTest, IncrementIntegerResultCreate) {
-  base::Value results = base::Value::FromUniquePtrValue(
-      simple_api::IncrementInteger::Results::Create(5));
+  base::Value results(simple_api::IncrementInteger::Results::Create(5));
   base::ListValue expected;
   expected.AppendInteger(5);
   EXPECT_EQ(expected, results);
@@ -146,8 +145,7 @@
 }
 
 TEST(JsonSchemaCompilerSimpleTest, NoParamsResultCreate) {
-  base::Value results = base::Value::FromUniquePtrValue(
-      simple_api::OptionalString::Results::Create());
+  base::Value results(simple_api::OptionalString::Results::Create());
   base::ListValue expected;
   EXPECT_EQ(expected, results);
 }
@@ -176,18 +174,16 @@
     std::unique_ptr<base::DictionaryValue> value = CreateTestTypeDictionary();
     auto test_type = std::make_unique<simple_api::TestType>();
     EXPECT_TRUE(simple_api::TestType::Populate(*value, test_type.get()));
-    base::Value results = base::Value::FromUniquePtrValue(
-        simple_api::GetTestType::Results::Create(*test_type));
-    ASSERT_TRUE(results.is_list());
-    ASSERT_EQ(1u, results.GetList().size());
-    EXPECT_TRUE(results.GetList()[0].Equals(value.get()));
+    std::vector<base::Value> results =
+        simple_api::GetTestType::Results::Create(*test_type);
+    ASSERT_EQ(1u, results.size());
+    EXPECT_TRUE(results[0].Equals(value.get()));
   }
 }
 
 TEST(JsonSchemaCompilerSimpleTest, OnIntegerFiredCreate) {
   {
-    base::Value results =
-        base::Value::FromUniquePtrValue(simple_api::OnIntegerFired::Create(5));
+    base::Value results(simple_api::OnIntegerFired::Create(5));
     base::ListValue expected;
     expected.AppendInteger(5);
     EXPECT_EQ(expected, results);
@@ -196,8 +192,7 @@
 
 TEST(JsonSchemaCompilerSimpleTest, OnStringFiredCreate) {
   {
-    base::Value results = base::Value::FromUniquePtrValue(
-        simple_api::OnStringFired::Create("yo dawg"));
+    base::Value results(simple_api::OnStringFired::Create("yo dawg"));
     base::ListValue expected;
     expected.AppendString("yo dawg");
     EXPECT_EQ(expected, results);
@@ -214,8 +209,7 @@
     ASSERT_TRUE(expected->GetInteger("integer", &some_test_type.integer));
     ASSERT_TRUE(expected->GetBoolean("boolean", &some_test_type.boolean));
 
-    base::Value results = base::Value::FromUniquePtrValue(
-        simple_api::OnTestTypeFired::Create(some_test_type));
+    base::Value results(simple_api::OnTestTypeFired::Create(some_test_type));
     ASSERT_TRUE(results.is_list());
     ASSERT_EQ(1u, results.GetList().size());
     EXPECT_EQ(*expected, results.GetList()[0]);
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml
index 65a7d67..1b6b54e 100644
--- a/tools/metrics/actions/actions.xml
+++ b/tools/metrics/actions/actions.xml
@@ -28309,6 +28309,8 @@
       label="For tab switcher with tab groups."/>
   <suffix name="TabSwitcherButton" label="For tab switcher button."/>
   <suffix name="TranslateMenuButton" label="For translate menu button."/>
+  <suffix name="UpdatedConnectionSecurityIndicators"
+      label="For updated omnibox connection security indicators."/>
   <suffix name="VideoTutorial_NTP_ChromeIntro"
       label="For Chrome intro video tutorial."/>
   <suffix name="VideoTutorial_NTP_Download"
@@ -28318,6 +28320,9 @@
       label="For video tutorial summary card."/>
   <suffix name="VideoTutorial_NTP_VoiceSearch"
       label="For voice search video tutorial."/>
+  <suffix name="WebFeedFollow" label="For Web Feed follow recommendations."/>
+  <suffix name="WebFeedPostFollowDialog"
+      label="For Web Feed successful follow operations."/>
   <suffix name="WebUITabStrip" label="For the WebUI tab strip."/>
   <affected-action name="InProductHelp.NotifyEvent.IPH"/>
   <affected-action name="InProductHelp.NotifyUsedEvent.IPH"/>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 9ad5dc3..4419e7b 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -6096,10 +6096,14 @@
   <int value="0" label="Undefined"/>
   <int value="1" label="UserNotAsked"/>
   <int value="2" label="Accpeted"/>
-  <int value="3" label="Edited"/>
-  <int value="4" label="Declined"/>
-  <int value="5" label="Never"/>
-  <int value="6" label="Ignored"/>
+  <int value="3" label="Declined"/>
+  <int value="4" label="EditAccepted"/>
+  <int value="5" label="EditDeclined"/>
+  <int value="6" label="Never"/>
+  <int value="7" label="Ignored"/>
+  <int value="8" label="MessageTimeout"/>
+  <int value="9" label="MessageDeclined"/>
+  <int value="10" label="AutoDeclined"/>
 </enum>
 
 <enum name="AutofillProfileImportEditedType">
@@ -32532,6 +32536,7 @@
   <int value="3913" label="GetBBoxForText"/>
   <int value="3914" label="SVGTextHangingFromPath"/>
   <int value="3915" label="ClientHintsPrefersColorScheme"/>
+  <int value="3916" label="OverscrollBehaviorWillBeFixed"/>
 </enum>
 
 <enum name="FeaturePolicyAllowlistType">
@@ -45746,6 +45751,7 @@
   <int value="-1117104514" label="smbfs-file-shares"/>
   <int value="-1116278039" label="ShelfAppScaling:disabled"/>
   <int value="-1114080030" label="ResourceLoadingHints:enabled"/>
+  <int value="-1113373128" label="WebUIDownloadShelf:enabled"/>
   <int value="-1112782121" label="AndroidSigninPromos:disabled"/>
   <int value="-1109826787" label="AccessibilityExposeDisplayNone:enabled"/>
   <int value="-1108636917" label="DetectedSourceLanguageOption:enabled"/>
@@ -49423,6 +49429,7 @@
   <int value="2098714203" label="enable-generic-sensors"/>
   <int value="2098907258" label="UseSurfaceLayerForVideo:disabled"/>
   <int value="2099945365" label="OmniboxAssistantVoiceSearch:enabled"/>
+  <int value="2101124624" label="WebUIDownloadShelf:disabled"/>
   <int value="2101151142" label="disable-direct-write"/>
   <int value="2104340988" label="CrostiniUsername:disabled"/>
   <int value="2104439359"
diff --git a/tools/metrics/histograms/histograms_xml/cross_device/histograms.xml b/tools/metrics/histograms/histograms_xml/cross_device/histograms.xml
index 0e8ac7c..99a03bd 100644
--- a/tools/metrics/histograms/histograms_xml/cross_device/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/cross_device/histograms.xml
@@ -1641,7 +1641,7 @@
 </histogram>
 
 <histogram name="MultiDevice.DeviceSyncService.SetSoftwareFeatureState.Result"
-    enum="BooleanSuccess" expires_after="2021-09-12">
+    enum="BooleanSuccess" expires_after="2021-11-14">
   <owner>vecore@google.com</owner>
   <owner>better-together-dev@google.com</owner>
   <summary>Result of enabling and disabling features for devices.</summary>
diff --git a/tools/metrics/histograms/histograms_xml/cryptohome/histograms.xml b/tools/metrics/histograms/histograms_xml/cryptohome/histograms.xml
index 93ab3534..73f9649 100644
--- a/tools/metrics/histograms/histograms_xml/cryptohome/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/cryptohome/histograms.xml
@@ -395,7 +395,7 @@
 </histogram>
 
 <histogram name="Cryptohome.ParallelTasks" units="count"
-    expires_after="2021-09-12">
+    expires_after="2021-11-14">
   <owner>zuan@chromium.org</owner>
   <owner>cros-hwsec+uma@chromium.org</owner>
   <summary>
@@ -556,7 +556,7 @@
 </histogram>
 
 <histogram name="Cryptohome.TimeToTakeTpmOwnership" units="ms"
-    expires_after="2021-09-12">
+    expires_after="2021-11-14">
   <owner>apronin@chromium.org</owner>
   <owner>cros-hwsec+uma@chromium.org</owner>
   <summary>
@@ -602,7 +602,7 @@
   </token>
 </histogram>
 
-<histogram name="CryptohomeClient" units="ms" expires_after="2021-09-12">
+<histogram name="CryptohomeClient" units="ms" expires_after="2021-11-14">
   <owner>zuan@chromium.org</owner>
   <owner>cros-hwsec+uma@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/enterprise/histograms.xml b/tools/metrics/histograms/histograms_xml/enterprise/histograms.xml
index 69690602..51ba010 100644
--- a/tools/metrics/histograms/histograms_xml/enterprise/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/enterprise/histograms.xml
@@ -605,6 +605,35 @@
   </summary>
 </histogram>
 
+<histogram name="Enterprise.Dlp.ReportedBlockLevelRestriction"
+    enum="EnterpriseDlpPolicyRestriction" expires_after="2022-03-01">
+  <owner>poromov@chromium.org</owner>
+  <owner>chromeos-dlp@google.com</owner>
+  <summary>
+    Recorded when Data Leak Prevention event with &quot;block&quot; level was
+    reported. Identifies which restriction was blocked and reported.
+  </summary>
+</histogram>
+
+<histogram name="Enterprise.Dlp.ReportedEventStatus" enum="GoogleRpcCode"
+    expires_after="2022-03-01">
+  <owner>poromov@chromium.org</owner>
+  <owner>chromeos-dlp@google.com</owner>
+  <summary>
+    Result of enqueueing Data Leak Prevention event to the reporting queue.
+  </summary>
+</histogram>
+
+<histogram name="Enterprise.Dlp.ReportedReportLevelRestriction"
+    enum="EnterpriseDlpPolicyRestriction" expires_after="2022-03-01">
+  <owner>poromov@chromium.org</owner>
+  <owner>chromeos-dlp@google.com</owner>
+  <summary>
+    Recorded when Data Leak Prevention event with &quot;report&quot; level was
+    reported. Identifies which restriction was reported.
+  </summary>
+</histogram>
+
 <histogram name="Enterprise.Dlp.RestrictionConfigured"
     enum="EnterpriseDlpPolicyRestriction" expires_after="2022-03-01">
   <owner>poromov@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml b/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml
index 601939c4..68355a5 100644
--- a/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml
+++ b/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml
@@ -8266,6 +8266,9 @@
       label="In product help for tab swticher button."/>
   <suffix name="IPH_TranslateMenuButton"
       label="In product help translate menu button."/>
+  <suffix name="IPH_UpdatedConnectionSecurityIndicators"
+      label="In product help for updated omnibox connection security
+             indicators."/>
   <suffix name="IPH_VideoTutorial_NTP_ChromeIntro"
       label="Video tutorial card on NTP about introduction to chrome."/>
   <suffix name="IPH_VideoTutorial_NTP_Download"
@@ -8276,6 +8279,10 @@
       label="Video tutorial summary card on NTP."/>
   <suffix name="IPH_VideoTutorial_NTP_VoiceSearch"
       label="Video tutorial card on NTP about voice search in chrome."/>
+  <suffix name="IPH_WebFeedFollow"
+      label="In product help for proactive Web Feed follow recommendations."/>
+  <suffix name="IPH_WebFeedPostFollowDialog"
+      label="In product help for Web Feed successful follow operations."/>
   <suffix name="IPH_WebUITabStrip"
       label="In product help for opening the WebUI tab strip."/>
   <affected-histogram name="InProductHelp.NotifyEventReadyState"/>
diff --git a/tools/metrics/histograms/histograms_xml/input/histograms.xml b/tools/metrics/histograms/histograms_xml/input/histograms.xml
index 7e1bb85..0723ab3 100644
--- a/tools/metrics/histograms/histograms_xml/input/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/input/histograms.xml
@@ -527,7 +527,7 @@
 </histogram>
 
 <histogram name="InputMethod.MultilingualExperiment.Autocorrect.Actions"
-    enum="IMEAutocorrectActions" expires_after="2021-06-30">
+    enum="IMEAutocorrectActions" expires_after="2021-12-31">
   <owner>tranbaoduy@google.com</owner>
   <owner>essential-inputs-team@google.com</owner>
   <summary>
@@ -537,7 +537,7 @@
 </histogram>
 
 <histogram name="InputMethod.MultilingualExperiment.Autocorrect.Count"
-    enum="IMETextInputClient" expires_after="2021-06-30">
+    enum="IMETextInputClient" expires_after="2021-12-31">
   <owner>tranbaoduy@google.com</owner>
   <owner>essential-inputs-team@google.com</owner>
   <summary>
@@ -547,7 +547,7 @@
 </histogram>
 
 <histogram name="InputMethod.MultilingualExperiment.Autocorrect.Delay"
-    units="ms" expires_after="2021-06-30">
+    units="ms" expires_after="2021-12-31">
   <owner>tranbaoduy@google.com</owner>
   <owner>essential-inputs-team@google.com</owner>
   <summary>
@@ -558,7 +558,7 @@
 
 <histogram
     name="InputMethod.MultilingualExperiment.DiacriticalAutocorrect.Actions"
-    enum="IMEAutocorrectActions" expires_after="2021-06-30">
+    enum="IMEAutocorrectActions" expires_after="2021-12-31">
   <owner>tranbaoduy@google.com</owner>
   <owner>essential-inputs-team@google.com</owner>
   <summary>
@@ -568,7 +568,7 @@
 </histogram>
 
 <histogram name="InputMethod.MultilingualExperiment.NonAutocorrect"
-    enum="IMENonAutocorrectDiacriticStatus" expires_after="2021-06-30">
+    enum="IMENonAutocorrectDiacriticStatus" expires_after="2021-12-31">
   <owner>tranbaoduy@google.com</owner>
   <owner>essential-inputs-team@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/net/histograms.xml b/tools/metrics/histograms/histograms_xml/net/histograms.xml
index 2e8bcb1..bc6e18c 100644
--- a/tools/metrics/histograms/histograms_xml/net/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/net/histograms.xml
@@ -1258,7 +1258,7 @@
 </histogram>
 
 <histogram name="Net.DNS.ProbeSequence.ConfigChange.Success.AttemptTime"
-    units="ms" expires_after="2021-09-12">
+    units="ms" expires_after="2021-11-14">
   <owner>ericorth@chromium.org</owner>
   <owner>doh-core@google.com</owner>
   <summary>
@@ -1435,7 +1435,7 @@
 </histogram>
 
 <histogram name="Net.DNS.SecureDnsTask.DnsModeAutomatic.FailureTime" units="ms"
-    expires_after="2021-09-12">
+    expires_after="2021-11-14">
   <owner>ericorth@chromium.org</owner>
   <owner>doh-core@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/others/histograms.xml b/tools/metrics/histograms/histograms_xml/others/histograms.xml
index 583f8ba..8b391a20 100644
--- a/tools/metrics/histograms/histograms_xml/others/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/others/histograms.xml
@@ -8759,7 +8759,7 @@
 </histogram>
 
 <histogram name="Lens.ImageClassification.ClassificationTime.EarlyTerminatedMs"
-    units="ms" expires_after="2021-07-04">
+    units="ms" expires_after="2021-11-14">
   <owner>yusuyoutube@google.com</owner>
   <owner>benwgold@google.com</owner>
   <summary>
@@ -13549,7 +13549,7 @@
 </histogram>
 
 <histogram name="SB2.RemoteCall.CanCheckUrl" enum="BooleanCanCheckUrl"
-    expires_after="2021-09-12">
+    expires_after="2021-11-14">
   <owner>vakh@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
@@ -14648,7 +14648,7 @@
 </histogram>
 
 <histogram name="SiteEngagementService.EngagementType"
-    enum="SiteEngagementServiceEngagementType" expires_after="2021-09-12">
+    enum="SiteEngagementServiceEngagementType" expires_after="2021-11-14">
   <owner>calamity@chromium.org</owner>
   <owner>dominickn@chromium.org</owner>
   <summary>
@@ -15744,7 +15744,7 @@
 </histogram>
 
 <histogram name="SupervisedUsers.ExtensionsMayRequestPermissions"
-    enum="BooleanEnabled" expires_after="2021-09-12">
+    enum="BooleanEnabled" expires_after="2021-11-14">
   <owner>tobyhuang@chromium.org</owner>
   <owner>cros-families@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/platform/histograms.xml b/tools/metrics/histograms/histograms_xml/platform/histograms.xml
index e6a76a7..c35b55c 100644
--- a/tools/metrics/histograms/histograms_xml/platform/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/platform/histograms.xml
@@ -1310,7 +1310,7 @@
 </histogram>
 
 <histogram name="Platform.Trunks.TpmErrorCode" enum="TPMResponseCode"
-    expires_after="2021-09-10">
+    expires_after="2021-11-14">
   <owner>yich@google.com</owner>
   <owner>cros-hwsec+uma@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/scanning/histograms.xml b/tools/metrics/histograms/histograms_xml/scanning/histograms.xml
index bfbe026..51dfd18 100644
--- a/tools/metrics/histograms/histograms_xml/scanning/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/scanning/histograms.xml
@@ -21,6 +21,17 @@
 
 <histograms>
 
+<histogram name="Scanning.NumCompletedScanScansInSession" units="scans"
+    expires_after="2021-11-17">
+  <owner>gavinwill@chromium.org</owner>
+  <owner>cros-peripherals@google.com</owner>
+  <summary>
+    Records the number of completed scans in a single session of the Scan app
+    being open. This value gets recorded whenever the Scan app is closed or
+    refreshed.
+  </summary>
+</histogram>
+
 <histogram name="Scanning.NumDetectedScanners" units="scanners"
     expires_after="2021-12-04">
   <owner>gavinwill@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/subresource/histograms.xml b/tools/metrics/histograms/histograms_xml/subresource/histograms.xml
index 8117372..425066b 100644
--- a/tools/metrics/histograms/histograms_xml/subresource/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/subresource/histograms.xml
@@ -421,7 +421,7 @@
 </histogram>
 
 <histogram name="SubresourceFilter.PageLoad.ActivationList"
-    enum="ActivationList" expires_after="2021-09-12">
+    enum="ActivationList" expires_after="2021-11-14">
   <owner>alexmt@chromium.org</owner>
   <owner>chrome-ads-histograms@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/update_engine/histograms.xml b/tools/metrics/histograms/histograms_xml/update_engine/histograms.xml
index 09292de..2660c4a 100644
--- a/tools/metrics/histograms/histograms_xml/update_engine/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/update_engine/histograms.xml
@@ -363,6 +363,32 @@
   </summary>
 </histogram>
 
+<histogram name="UpdateEngine.ConsecutiveUpdate.Count" units="updates"
+    expires_after="2021-12-29">
+  <owner>vyshu@chromium.org</owner>
+  <owner>chromeos-core-services@google.com</owner>
+  <summary>
+    The total number of times the inactive partition was updated before reboot.
+
+    This is reported after every reboot.
+
+    This metric is specific to Chrome OS.
+  </summary>
+</histogram>
+
+<histogram name="UpdateEngine.ConsecutiveUpdate.Failed" enum="BooleanHit"
+    expires_after="2021-12-29">
+  <owner>vyshu@chromium.org</owner>
+  <owner>chromeos-core-services@google.com</owner>
+  <summary>
+    This is reported after every failed consecutive update. The first update is
+    not included. This metric can be interpreted alongside metrics such as
+    SuccessfulUpdate.AttemptCount, and Attempt.Result.
+
+    This metric is specific to Chrome OS.
+  </summary>
+</histogram>
+
 <histogram name="UpdateEngine.Daily.OSAgeDays" units="days"
     expires_after="2021-12-29">
   <owner>ahassani@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/web_apk/histograms.xml b/tools/metrics/histograms/histograms_xml/web_apk/histograms.xml
index 09c4f3b0..7893755b 100644
--- a/tools/metrics/histograms/histograms_xml/web_apk/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/web_apk/histograms.xml
@@ -70,7 +70,7 @@
 </histogram>
 
 <histogram name="WebApk.Install.GooglePlayInstallResult"
-    enum="WebApkGooglePlayInstallResult" expires_after="2021-09-12">
+    enum="WebApkGooglePlayInstallResult" expires_after="2021-11-14">
   <owner>hartmanng@chromium.org</owner>
   <owner>
     src/chrome/android/java/src/org/chromium/chrome/browser/webapps/OWNERS
diff --git a/tools/perf/benchmarks/rendering.py b/tools/perf/benchmarks/rendering.py
index faa4189..4acb2f2 100644
--- a/tools/perf/benchmarks/rendering.py
+++ b/tools/perf/benchmarks/rendering.py
@@ -33,9 +33,11 @@
 
 
 class _RenderingBenchmark(perf_benchmark.PerfBenchmark):
-  options = {
-      'capture_screen_video': True
-  }
+  # TODO(crbug/1205829): Capturing video is causing long cycle time and timeout
+  # on some Pixel devices. Disabling this option until the issue can be fixed.
+  #options = {
+  #    'capture_screen_video': True
+  #}
 
   @classmethod
   def AddBenchmarkCommandLineArgs(cls, parser):
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index e27d532..7cab00a 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -2,15 +2,15 @@
     "trace_processor_shell": {
         "win": {
             "hash": "6c9d1659449dd8f1930cfcf263ab1005aa602320",
-            "remote_path": "perfetto_binaries/trace_processor_shell/win/b91884a97a74eee3d9dde816a107e934550ccf26/trace_processor_shell.exe"
+            "remote_path": "perfetto_binaries/trace_processor_shell/win/5e860d49ed384a4785abec0eb68f4ce2f652dca6/trace_processor_shell.exe"
         },
         "mac": {
             "hash": "b71e08180101b61191679d51b089504977d8c19c",
             "remote_path": "perfetto_binaries/trace_processor_shell/mac/5e860d49ed384a4785abec0eb68f4ce2f652dca6/trace_processor_shell"
         },
         "linux": {
-            "hash": "49882ef6447cc9a26ae7226e86416be1bce74b30",
-            "remote_path": "perfetto_binaries/trace_processor_shell/linux/5e860d49ed384a4785abec0eb68f4ce2f652dca6/trace_processor_shell"
+            "hash": "9076c8b15696207c77b63956250bee3969d86d35",
+            "remote_path": "perfetto_binaries/trace_processor_shell/linux/9109f50a742ab7b4cb70717308281137a8734b2b/trace_processor_shell"
         }
     },
     "power_profile.sql": {
diff --git a/tools/translation/helper/translation_helper.py b/tools/translation/helper/translation_helper.py
index 6bbf650..299e1df 100644
--- a/tools/translation/helper/translation_helper.py
+++ b/tools/translation/helper/translation_helper.py
@@ -9,8 +9,12 @@
 import ast
 import os
 import re
+import sys
 import xml.etree.cElementTree as ElementTree
 
+if sys.version_info.major != 2:
+  basestring = str  # pylint: disable=redefined-builtin
+
 
 class GRDFile(object):
   """Class representing a grd xml file.
@@ -95,7 +99,7 @@
   # the translation expectations.
   grds_with_expectations = set(grd_to_langs.keys()).union(untranslated_grds)
   all_grds = {p: GRDFile(os.path.join(repo_root, p)) for p in all_grd_paths}
-  for path, grd in all_grds.iteritems():
+  for path, grd in all_grds.items():
     if grd.appears_translatable:
       if path not in grds_with_expectations:
         errors.append('%s appears to be translatable (because it contains '
@@ -113,7 +117,7 @@
                     (translation_expectations_path, '\n - '.join(errors)))
 
   translatable_grds = []
-  for path, expected_languages_list in grd_to_langs.iteritems():
+  for path, expected_languages_list in grd_to_langs.items():
     grd = all_grds[path]
     grd.expected_languages = expected_languages_list
     grd._populate_lang_to_xtb_path(errors)
diff --git a/ui/accessibility/BUILD.gn b/ui/accessibility/BUILD.gn
index bb5bd7c..cf03156 100644
--- a/ui/accessibility/BUILD.gn
+++ b/ui/accessibility/BUILD.gn
@@ -111,6 +111,8 @@
     "ax_event_generator.cc",
     "ax_event_generator.h",
     "ax_export.h",
+    "ax_hypertext.cc",
+    "ax_hypertext.h",
     "ax_language_detection.cc",
     "ax_language_detection.h",
     "ax_mode_observer.h",
diff --git a/ui/accessibility/accessibility_features.cc b/ui/accessibility/accessibility_features.cc
index c7e3879..722db1ee 100644
--- a/ui/accessibility/accessibility_features.cc
+++ b/ui/accessibility/accessibility_features.cc
@@ -121,7 +121,7 @@
 
 const base::Feature kExperimentalAccessibilityDictationListening{
     "ExperimentalAccessibilityDictationListening",
-    base::FEATURE_DISABLED_BY_DEFAULT};
+    base::FEATURE_ENABLED_BY_DEFAULT};
 
 bool IsExperimentalAccessibilityDictationListeningEnabled() {
   return base::FeatureList::IsEnabled(
diff --git a/ui/accessibility/ax_hypertext.cc b/ui/accessibility/ax_hypertext.cc
new file mode 100644
index 0000000..a6770a1
--- /dev/null
+++ b/ui/accessibility/ax_hypertext.cc
@@ -0,0 +1,14 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/accessibility/ax_hypertext.h"
+
+namespace ui {
+
+AXHypertext::AXHypertext() = default;
+AXHypertext::~AXHypertext() = default;
+AXHypertext::AXHypertext(const AXHypertext& other) = default;
+AXHypertext& AXHypertext::operator=(const AXHypertext& other) = default;
+
+}  // namespace ui
diff --git a/ui/accessibility/ax_hypertext.h b/ui/accessibility/ax_hypertext.h
new file mode 100644
index 0000000..6abb3d7
--- /dev/null
+++ b/ui/accessibility/ax_hypertext.h
@@ -0,0 +1,50 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_ACCESSIBILITY_AX_HYPERTEXT_H_
+#define UI_ACCESSIBILITY_AX_HYPERTEXT_H_
+
+#include <map>
+#include <ostream>
+#include <string>
+#include <vector>
+
+#include "ui/accessibility/ax_export.h"
+#include "ui/accessibility/ax_node_data.h"
+
+namespace ui {
+
+// Stores the hypertext for an `AXNode` in the accessibility tree. Hypertext has
+// nothing to do with HTML but is how displayed text and embedded objects are
+// represented in ATK and IAccessible2 APIs.
+//
+// Hypertext is computed as follows: If this node is a leaf, returns the inner
+// text of this node. This is equivalent to its visible accessible name.
+// Otherwise, if this node is not a leaf, represents every non-textual child
+// node with a special "embedded object character", and every textual child node
+// with its inner text. Textual nodes include e.g. static text and white space.
+// Each non-textual child node is also called a hyperlink.
+struct AX_EXPORT AXHypertext {
+  AXHypertext();
+  ~AXHypertext();
+  AXHypertext(const AXHypertext& other);
+  AXHypertext& operator=(const AXHypertext& other);
+
+  // A flag that should be set if the hypertext information in this struct is
+  // out-of-date and needs to be updated. This flag should always be set upon
+  // construction because constructing this struct doesn't compute the
+  // hypertext.
+  bool needs_update = true;
+
+  // Maps an embedded character offset in |hypertext| to an index in the list of
+  // unignored children. A hyperlink is defined as any non-textual child.
+  std::map<int, int> hypertext_offset_to_hyperlink_child_index;
+
+  // See class comment for information on how this is computed.
+  std::u16string hypertext;
+};
+
+}  // namespace ui
+
+#endif  // UI_ACCESSIBILITY_AX_HYPERTEXT_H_
diff --git a/ui/accessibility/ax_node.cc b/ui/accessibility/ax_node.cc
index 3057e683..e6cf4b3 100644
--- a/ui/accessibility/ax_node.cc
+++ b/ui/accessibility/ax_node.cc
@@ -15,6 +15,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
 #include "ui/accessibility/ax_enums.mojom.h"
+#include "ui/accessibility/ax_hypertext.h"
 #include "ui/accessibility/ax_language_detection.h"
 #include "ui/accessibility/ax_role_properties.h"
 #include "ui/accessibility/ax_table_info.h"
@@ -629,13 +630,16 @@
 
 std::u16string AXNode::GetHypertext() const {
   DCHECK(!tree_->GetTreeUpdateInProgressState());
+  // TODO(nektar): Introduce proper caching of hypertext via
+  // `AXHypertext::needs_update`.
+  hypertext_ = AXHypertext();
 
   // Hypertext is not exposed for descendants of leaf nodes. For such nodes,
   // their inner text is equivalent to their hypertext. Otherwise, we would
-  // never be able to compute equivalent ancestor positions in text fields given
-  // an AXPosition on an inline text box descendant, because there is often an
-  // ignored generic container between the text descendants and the text field
-  // node.
+  // never be able to compute equivalent ancestor positions in atomic text
+  // fields given an AXPosition on an inline text box descendant, because there
+  // is often an ignored generic container between the text descendants and the
+  // text field node.
   //
   // For example, look at the following accessibility tree and the text
   // positions indicated using "<>" symbols in the inner text of every node, and
@@ -646,29 +650,62 @@
   // ++++kGenericContainer "Hell<o>" ignored IsChildOfLeaf=true
   // ++++++kStaticText "Hell<o>" IsChildOfLeaf=true
   // ++++++++kInlineTextBox "Hell<o>" IsChildOfLeaf=true
-  if (IsLeaf() || IsChildOfLeaf())
-    return base::UTF8ToUTF16(GetInnerText());
 
-  // Construct the hypertext for this node, which contains the concatenation of
-  // the inner text of this node's textual children, and an "object replacement
-  // character" for all the other children.
-  //
-  // Note that the word "hypertext" comes from the IAccessible2 Standard and has
-  // nothing to do with HTML.
-  const std::u16string embedded_character_str(kEmbeddedCharacter);
-  DCHECK_EQ(int{embedded_character_str.length()}, kEmbeddedCharacterLength);
-  std::u16string hypertext;
-  for (auto it = UnignoredChildrenBegin(); it != UnignoredChildrenEnd(); ++it) {
-    // Similar to Firefox, we don't expose text nodes in IAccessible2 and ATK
-    // hypertext with the embedded object character. We copy all of their text
-    // instead.
-    if (it->IsText()) {
-      hypertext += base::UTF8ToUTF16(it->GetInnerText());
-    } else {
-      hypertext += embedded_character_str;
+  if (IsLeaf() || IsChildOfLeaf()) {
+    hypertext_.hypertext = base::UTF8ToUTF16(GetInnerText());
+  } else {
+    // Construct the hypertext for this node, which contains the concatenation
+    // of the inner text of this node's textual children, and an "object
+    // replacement character" for all the other children.
+    //
+    // Note that the word "hypertext" comes from the IAccessible2 Standard and
+    // has nothing to do with HTML.
+    const std::u16string embedded_character_str(kEmbeddedCharacter);
+    DCHECK_EQ(int{embedded_character_str.length()}, kEmbeddedCharacterLength);
+    for (size_t i = 0; i < GetUnignoredChildCountCrossingTreeBoundary(); ++i) {
+      const AXNode* child = GetUnignoredChildAtIndexCrossingTreeBoundary(i);
+      // Similar to Firefox, we don't expose text nodes in IAccessible2 and ATK
+      // hypertext with the embedded object character. We copy all of their text
+      // instead.
+      if (child->IsText()) {
+        hypertext_.hypertext += base::UTF8ToUTF16(child->GetInnerText());
+      } else {
+        int character_offset = int{hypertext_.hypertext.size()};
+        auto inserted =
+            hypertext_.hypertext_offset_to_hyperlink_child_index.emplace(
+                character_offset, int{i});
+        DCHECK(inserted.second) << "An embedded object at " << character_offset
+                                << " has already been encountered.";
+        hypertext_.hypertext += embedded_character_str;
+      }
     }
   }
-  return hypertext;
+
+  hypertext_.needs_update = false;
+  return hypertext_.hypertext;
+}
+
+void AXNode::SetNeedsToUpdateHypertext() {
+  old_hypertext_ = hypertext_;
+  hypertext_.needs_update = true;
+  // TODO(nektar): Introduce proper caching of hypertext via
+  // `AXHypertext::needs_update`.
+  GetHypertext();  // Forces `hypertext_` to immediately update.
+}
+
+const std::map<int, int>& AXNode::GetHypertextOffsetToHyperlinkChildIndex()
+    const {
+  // TODO(nektar): Introduce proper caching of hypertext via
+  // `AXHypertext::needs_update`.
+  GetHypertext();  // Update `hypertext_` if not up-to-date.
+  return hypertext_.hypertext_offset_to_hyperlink_child_index;
+}
+
+const AXHypertext& AXNode::GetOldHypertext() const {
+  // TODO(nektar): Introduce proper caching of hypertext via
+  // `AXHypertext::needs_update`.
+  GetHypertext();  // Update `hypertext_` if not up-to-date.
+  return old_hypertext_;
 }
 
 std::string AXNode::GetInnerText() const {
diff --git a/ui/accessibility/ax_node.h b/ui/accessibility/ax_node.h
index f350d42eb..8e192d5 100644
--- a/ui/accessibility/ax_node.h
+++ b/ui/accessibility/ax_node.h
@@ -17,6 +17,7 @@
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "ui/accessibility/ax_export.h"
+#include "ui/accessibility/ax_hypertext.h"
 #include "ui/accessibility/ax_node_data.h"
 #include "ui/accessibility/ax_tree_id.h"
 
@@ -26,7 +27,7 @@
 struct AXLanguageInfo;
 struct AXTreeData;
 
-// One node in an AXTree.
+// This class is used to represent a node in an accessibility tree (`AXTree`).
 class AX_EXPORT AXNode final {
  public:
   // Replacement character used to represent an embedded (or, additionally for
@@ -347,6 +348,14 @@
   // TODO(nektar): Consider changing the return value to std::string.
   std::u16string GetHypertext() const;
 
+  // Temporary method that marks `hypertext_` dirty. This will eventually be
+  // handled by the AX tree in a followup patch.
+  void SetNeedsToUpdateHypertext();
+  // Temporary accessor methods until hypertext is fully migrated to this class.
+  // Hypertext won't eventually need to be accessed outside this class.
+  const std::map<int, int>& GetHypertextOffsetToHyperlinkChildIndex() const;
+  const AXHypertext& GetOldHypertext() const;
+
   // Returns the text that is found inside this node and all its descendants;
   // including text found in embedded objects.
   //
@@ -568,7 +577,7 @@
   void IdVectorToNodeVector(const std::vector<AXNodeID>& ids,
                             std::vector<AXNode*>* nodes) const;
 
-  int UpdateUnignoredCachedValuesRecursive(int startIndex);
+  int UpdateUnignoredCachedValuesRecursive(int start_index);
   AXNode* ComputeLastUnignoredChildRecursive() const;
   AXNode* ComputeFirstUnignoredChildRecursive() const;
 
@@ -598,6 +607,11 @@
   std::vector<AXNode*> children_;
   AXNodeData data_;
 
+  // See the class comment in "ax_hypertext.h" for an explanation of this
+  // member.
+  mutable AXHypertext hypertext_;
+  mutable AXHypertext old_hypertext_;
+
   // Stores the detected language computed from the node's text.
   std::unique_ptr<AXLanguageInfo> language_info_;
 };
diff --git a/ui/accessibility/ax_node_position_unittest.cc b/ui/accessibility/ax_node_position_unittest.cc
index 6fda4c4..d3ac095 100644
--- a/ui/accessibility/ax_node_position_unittest.cc
+++ b/ui/accessibility/ax_node_position_unittest.cc
@@ -3983,6 +3983,10 @@
                         inline_box_data_2, container_data, static_text_data_2,
                         inline_box_data_3}));
 
+  // TODO(nektar): AXTree has a bug whereby it doesn't update the unignored
+  // cached values when the ignored state is flipped on the root.
+  GetNodeFromTree(root_data.id)->UpdateUnignoredCachedValues();
+
   text_position = AXNodePosition::CreateTextPosition(
       GetTreeID(), root_data.id, 0 /* text_offset */,
       ax::mojom::TextAffinity::kDownstream);
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.cc b/ui/accessibility/platform/ax_platform_node_auralinux.cc
index 02a02d3..8017d30 100644
--- a/ui/accessibility/platform/ax_platform_node_auralinux.cc
+++ b/ui/accessibility/platform/ax_platform_node_auralinux.cc
@@ -915,7 +915,7 @@
   if (!obj)
     return nullptr;
 
-  const AXHypertext& ax_hypertext = obj->GetAXHypertext();
+  const AXLegacyHypertext& ax_hypertext = obj->GetAXHypertext();
   if (index > static_cast<int>(ax_hypertext.hyperlinks.size()) || index < 0)
     return nullptr;
 
@@ -4201,7 +4201,7 @@
   if (!atk_object)
     return;
 
-  AXHypertext old_hypertext = hypertext_;
+  AXLegacyHypertext old_hypertext = hypertext_;
   base::OffsetAdjuster::Adjustments old_adjustments = GetHypertextAdjustments();
 
   UpdateComputedHypertext();
@@ -4250,7 +4250,7 @@
   }
 }
 
-const AXHypertext& AXPlatformNodeAuraLinux::GetAXHypertext() {
+const AXLegacyHypertext& AXPlatformNodeAuraLinux::GetAXHypertext() {
   return hypertext_;
 }
 
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.h b/ui/accessibility/platform/ax_platform_node_auralinux.h
index 8a9160a..39d9786d0 100644
--- a/ui/accessibility/platform/ax_platform_node_auralinux.h
+++ b/ui/accessibility/platform/ax_platform_node_auralinux.h
@@ -249,7 +249,7 @@
   bool IsNameExposed();
 
   void UpdateHypertext();
-  const AXHypertext& GetAXHypertext();
+  const AXLegacyHypertext& GetAXHypertext();
   const base::OffsetAdjuster::Adjustments& GetHypertextAdjustments();
   size_t UTF16ToUnicodeOffsetInText(size_t utf16_offset);
   size_t UnicodeToUTF16OffsetInText(int unicode_offset);
diff --git a/ui/accessibility/platform/ax_platform_node_base.cc b/ui/accessibility/platform/ax_platform_node_base.cc
index 5650dd1f..42064ce 100644
--- a/ui/accessibility/platform/ax_platform_node_base.cc
+++ b/ui/accessibility/platform/ax_platform_node_base.cc
@@ -1381,16 +1381,17 @@
   AddAttributeToList(name, value.c_str(), attributes);
 }
 
-AXHypertext::AXHypertext() = default;
-AXHypertext::~AXHypertext() = default;
-AXHypertext::AXHypertext(const AXHypertext& other) = default;
-AXHypertext& AXHypertext::operator=(const AXHypertext& other) = default;
+AXLegacyHypertext::AXLegacyHypertext() = default;
+AXLegacyHypertext::~AXLegacyHypertext() = default;
+AXLegacyHypertext::AXLegacyHypertext(const AXLegacyHypertext& other) = default;
+AXLegacyHypertext& AXLegacyHypertext::operator=(
+    const AXLegacyHypertext& other) = default;
 
 // TODO(nektar): To be able to use AXNode in Views, move this logic to AXNode.
 void AXPlatformNodeBase::UpdateComputedHypertext() const {
   if (!delegate_)
     return;
-  hypertext_ = AXHypertext();
+  hypertext_ = AXLegacyHypertext();
 
   if (IsLeaf()) {
     hypertext_.hypertext = GetInnerText();
@@ -1785,7 +1786,7 @@
 }
 
 bool AXPlatformNodeBase::IsSameHypertextCharacter(
-    const AXHypertext& old_hypertext,
+    const AXLegacyHypertext& old_hypertext,
     size_t old_char_index,
     size_t new_char_index) {
   if (old_char_index >= old_hypertext.hypertext.size() ||
@@ -1843,7 +1844,7 @@
 }
 
 void AXPlatformNodeBase::ComputeHypertextRemovedAndInserted(
-    const AXHypertext& old_hypertext,
+    const AXLegacyHypertext& old_hypertext,
     size_t* start,
     size_t* old_len,
     size_t* new_len) {
diff --git a/ui/accessibility/platform/ax_platform_node_base.h b/ui/accessibility/platform/ax_platform_node_base.h
index 8463ec5f..ada6e8c 100644
--- a/ui/accessibility/platform/ax_platform_node_base.h
+++ b/ui/accessibility/platform/ax_platform_node_base.h
@@ -30,11 +30,11 @@
 
 // TODO(nektar): Move this struct over to AXNode so that it can be accessed by
 // AXPosition.
-struct AX_EXPORT AXHypertext {
-  AXHypertext();
-  ~AXHypertext();
-  AXHypertext(const AXHypertext& other);
-  AXHypertext& operator=(const AXHypertext& other);
+struct AX_EXPORT AXLegacyHypertext {
+  AXLegacyHypertext();
+  ~AXLegacyHypertext();
+  AXLegacyHypertext(const AXLegacyHypertext& other);
+  AXLegacyHypertext& operator=(const AXLegacyHypertext& other);
 
   // A flag that should be set if the hypertext information in this struct is
   // out-of-date and needs to be updated. This flag should always be set upon
@@ -506,13 +506,14 @@
   int GetHypertextOffsetFromEndpoint(AXPlatformNodeBase* endpoint_object,
                                      int endpoint_offset);
 
-  bool IsSameHypertextCharacter(const AXHypertext& old_hypertext,
+  bool IsSameHypertextCharacter(const AXLegacyHypertext& old_hypertext,
                                 size_t old_char_index,
                                 size_t new_char_index);
-  void ComputeHypertextRemovedAndInserted(const AXHypertext& old_hypertext,
-                                          size_t* start,
-                                          size_t* old_len,
-                                          size_t* new_len);
+  void ComputeHypertextRemovedAndInserted(
+      const AXLegacyHypertext& old_hypertext,
+      size_t* start,
+      size_t* old_len,
+      size_t* new_len);
 
   std::string GetInvalidValue() const;
 
@@ -521,7 +522,7 @@
   // selectable children that this object could potentially contain.
   int GetMaxSelectableItems() const;
 
-  mutable AXHypertext hypertext_;
+  mutable AXLegacyHypertext hypertext_;
 
  private:
   // Returns true if the index represents a text character.
diff --git a/ui/accessibility/platform/ax_platform_node_win.h b/ui/accessibility/platform/ax_platform_node_win.h
index fdd24d5..481addd 100644
--- a/ui/accessibility/platform/ax_platform_node_win.h
+++ b/ui/accessibility/platform/ax_platform_node_win.h
@@ -1200,7 +1200,7 @@
   // Relationships between this node and other nodes.
   std::vector<Microsoft::WRL::ComPtr<AXPlatformRelationWin>> relations_;
 
-  AXHypertext old_hypertext_;
+  AXLegacyHypertext old_hypertext_;
 
   // These protected methods are still used by BrowserAccessibilityComWin. At
   // some point post conversion, we can probably move these to be private
diff --git a/ui/base/clipboard/clipboard_test_template.h b/ui/base/clipboard/clipboard_test_template.h
index 4d5d6b4c..e89e626 100644
--- a/ui/base/clipboard/clipboard_test_template.h
+++ b/ui/base/clipboard/clipboard_test_template.h
@@ -576,6 +576,10 @@
   }
 }
 
+#if !defined(OS_ANDROID)
+// TODO(https://crbug.com/1056650): Re-enable these tests after fixing the root
+// cause. This test only fails on Android.
+
 // Only kN32_SkColorType bitmaps are allowed in the clipboard to prevent
 // surprising buffer overflows due to bits-per-pixel assumptions.
 TYPED_TEST(ClipboardTest, Bitmap_F16_Premul) {
@@ -611,6 +615,7 @@
   };
   TestBitmapWrite(&this->clipboard(), SkImageInfo::MakeN32Premul(2, 7), b, b);
 }
+#endif  // !defined(OS_ANDROID)
 
 }  // namespace
 
diff --git a/ui/base/metadata/base_type_conversion.cc b/ui/base/metadata/base_type_conversion.cc
index 5dadd5fc..9724cf2c 100644
--- a/ui/base/metadata/base_type_conversion.cc
+++ b/ui/base/metadata/base_type_conversion.cc
@@ -17,6 +17,7 @@
 #include "base/strings/stringprintf.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/skia/include/core/SkScalar.h"
 #include "ui/gfx/color_utils.h"
 #include "ui/gfx/geometry/rect.h"
diff --git a/ui/base/resource/resource_bundle.cc b/ui/base/resource/resource_bundle.cc
index 7c5db6b..65b1649 100644
--- a/ui/base/resource/resource_bundle.cc
+++ b/ui/base/resource/resource_bundle.cc
@@ -26,6 +26,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/synchronization/lock.h"
+#include "base/trace_event/base_tracing.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "net/filter/gzip_header.h"
@@ -576,6 +577,14 @@
 base::RefCountedMemory* ResourceBundle::LoadDataResourceBytesForScale(
     int resource_id,
     ScaleFactor scale_factor) const {
+  TRACE_EVENT("ui", "ResourceBundle::LoadDataResourceBytesForScale",
+              [&](perfetto::EventContext ctx) {
+                auto* event =
+                    ctx.event<perfetto::protos::pbzero::ChromeTrackEvent>();
+                auto* data = event->set_resource_bundle();
+                data->set_resource_id(resource_id);
+              });
+
   if (delegate_) {
     base::RefCountedMemory* bytes =
         delegate_->LoadDataResourceBytes(resource_id, scale_factor);
diff --git a/ui/display/manager/display_manager.cc b/ui/display/manager/display_manager.cc
index 1266efa..3285e74 100644
--- a/ui/display/manager/display_manager.cc
+++ b/ui/display/manager/display_manager.cc
@@ -1431,20 +1431,6 @@
   UpdateDisplaysWith(new_display_info_list);
 }
 
-void DisplayManager::ToggleDisplayScaleFactor() {
-  DCHECK(!active_display_list_.empty());
-  DisplayInfoList new_display_info_list;
-  for (Displays::const_iterator iter = active_display_list_.begin();
-       iter != active_display_list_.end(); ++iter) {
-    ManagedDisplayInfo display_info = GetDisplayInfo(iter->id());
-    display_info.set_device_scale_factor(
-        display_info.device_scale_factor() == 1.0f ? 2.0f : 1.0f);
-    new_display_info_list.push_back(display_info);
-  }
-  AddMirrorDisplayInfoIfAny(&new_display_info_list);
-  UpdateDisplaysWith(new_display_info_list);
-}
-
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 void DisplayManager::InitConfigurator(
     std::unique_ptr<NativeDisplayDelegate> delegate) {
diff --git a/ui/events/event_handler.cc b/ui/events/event_handler.cc
index 9bcaec2..b327edd 100644
--- a/ui/events/event_handler.cc
+++ b/ui/events/event_handler.cc
@@ -11,11 +11,7 @@
 
 namespace ui {
 
-// static
-bool EventHandler::check_targets_ = true;
-
-EventHandler::EventHandler() {
-}
+EventHandler::EventHandler() = default;
 
 EventHandler::~EventHandler() {
   while (!dispatchers_.empty()) {
@@ -23,9 +19,6 @@
     dispatchers_.pop();
     dispatcher->OnHandlerDestroyed(this);
   }
-
-  // Should have been removed from all pre-target handlers.
-  CHECK(!check_targets_ || targets_installed_on_.empty());
 }
 
 void EventHandler::OnEvent(Event* event) {
diff --git a/ui/events/event_handler.h b/ui/events/event_handler.h
index 4feb491..3870be3 100644
--- a/ui/events/event_handler.h
+++ b/ui/events/event_handler.h
@@ -5,12 +5,8 @@
 #ifndef UI_EVENTS_EVENT_HANDLER_H_
 #define UI_EVENTS_EVENT_HANDLER_H_
 
-#include <vector>
-
 #include "base/containers/stack.h"
-#include "base/macros.h"
 #include "base/strings/string_piece.h"
-#include "ui/events/event_constants.h"
 #include "ui/events/events_export.h"
 
 namespace ui {
@@ -30,13 +26,10 @@
 class EVENTS_EXPORT EventHandler {
  public:
   EventHandler();
+  EventHandler(const EventHandler&) = delete;
+  EventHandler& operator=(const EventHandler&) = delete;
   virtual ~EventHandler();
 
-  // Disables a CHECK() that this has been removed from all pre-target
-  // handlers in the destructor.
-  // TODO(sky): remove, used to track https://crbug.com/867035.
-  static void DisableCheckTargets() { check_targets_ = false; }
-
   // This is called for all events. The default implementation routes the event
   // to one of the event-specific callbacks (OnKeyEvent, OnMouseEvent etc.). If
   // this is overridden, then normally, the override should chain into the
@@ -66,19 +59,9 @@
   // EventDispatcher pushes itself on the top of this stack while dispatching
   // events to this then pops itself off when done.
   base::stack<EventDispatcher*> dispatchers_;
-
-  // Set of EventTargets |this| has been installed as a pre-target handler on.
-  // This is a vector as AddPreTargetHandler() may be called multiple times for
-  // the same EventTarget.
-  // TODO(sky): remove, used to track https://crbug.com/867035.
-  std::vector<EventTarget*> targets_installed_on_;
-
-  static bool check_targets_;
-
-  DISALLOW_COPY_AND_ASSIGN(EventHandler);
 };
 
-typedef std::vector<EventHandler*> EventHandlerList;
+using EventHandlerList = std::vector<EventHandler*>;
 
 }  // namespace ui
 
diff --git a/ui/events/event_target.cc b/ui/events/event_target.cc
index 9ce28b23..c7c6ceb 100644
--- a/ui/events/event_target.cc
+++ b/ui/events/event_target.cc
@@ -40,18 +40,10 @@
     pre_target_list_.push_back(prioritized);
   else
     pre_target_list_.insert(pre_target_list_.begin(), prioritized);
-  handler->targets_installed_on_.push_back(this);
 }
 
 void EventTarget::RemovePreTargetHandler(EventHandler* handler) {
   CHECK(handler);
-  // Only erase a single one, which matches the removal code right after this.
-  auto installed_on_iter =
-      std::find(handler->targets_installed_on_.begin(),
-                handler->targets_installed_on_.end(), this);
-  if (installed_on_iter != handler->targets_installed_on_.end())
-    handler->targets_installed_on_.erase(installed_on_iter);
-
   EventHandlerPriorityList::iterator it, end;
   for (it = pre_target_list_.begin(), end = pre_target_list_.end(); it != end;
        ++it) {
diff --git a/ui/gfx/animation/keyframe/keyframe_model.h b/ui/gfx/animation/keyframe/keyframe_model.h
index f0b8db9e..4423a75c 100644
--- a/ui/gfx/animation/keyframe/keyframe_model.h
+++ b/ui/gfx/animation/keyframe/keyframe_model.h
@@ -7,6 +7,7 @@
 
 #include <string>
 
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/animation/keyframe/animation_curve.h"
 #include "ui/gfx/animation/keyframe/keyframe_animation_export.h"
 #include "ui/gfx/animation/keyframe/keyframed_animation_curve.h"
diff --git a/ui/gl/dc_renderer_layer_params.h b/ui/gl/dc_renderer_layer_params.h
index 0d5a2725..70f2fa8 100644
--- a/ui/gl/dc_renderer_layer_params.h
+++ b/ui/gl/dc_renderer_layer_params.h
@@ -8,6 +8,7 @@
 #include <array>
 
 #include "base/memory/ref_counted.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "ui/gfx/geometry/point.h"
 #include "ui/gfx/geometry/rect.h"
diff --git a/ui/ozone/platform/wayland/host/wayland_zwp_pointer_gestures.h b/ui/ozone/platform/wayland/host/wayland_zwp_pointer_gestures.h
index fa1fdba..3c3ad05 100644
--- a/ui/ozone/platform/wayland/host/wayland_zwp_pointer_gestures.h
+++ b/ui/ozone/platform/wayland/host/wayland_zwp_pointer_gestures.h
@@ -6,6 +6,7 @@
 #define UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_ZWP_POINTER_GESTURES_H_
 
 #include "base/time/time.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/events/types/event_type.h"
 #include "ui/ozone/platform/wayland/common/wayland_object.h"
 
diff --git a/ui/webui/resources/cr_components/chromeos/network/network_select.js b/ui/webui/resources/cr_components/chromeos/network/network_select.js
index 1e6757d..e114590 100644
--- a/ui/webui/resources/cr_components/chromeos/network/network_select.js
+++ b/ui/webui/resources/cr_components/chromeos/network/network_select.js
@@ -86,12 +86,6 @@
       type: Boolean,
       value: false,
     },
-
-    /**
-     * The cellular DeviceState, or undefined if there is no Cellular device.
-     * @private {!OncMojo.DeviceStateProperties|undefined} deviceState
-     */
-    cellularDeviceState_: Object,
   },
 
   /** @type {!OncMojo.NetworkStateProperties|undefined} */
@@ -262,12 +256,6 @@
    * @private
    */
   onGetNetworkStateList_(deviceStates, networkStates) {
-    this.cellularDeviceState_ = deviceStates.find(function(device) {
-      return device.type === mojom.NetworkType.kCellular;
-    });
-    if (this.cellularDeviceState_) {
-      this.ensureCellularNetwork_(networkStates);
-    }
     this.networkStateList_ = networkStates;
     this.fire('network-list-changed', networkStates);
 
@@ -289,37 +277,6 @@
   },
 
   /**
-   * Modifies |networkStates| to include a cellular network if one is required
-   * but does not exist.
-   * @param {!Array<!OncMojo.NetworkStateProperties>} networkStates
-   * @private
-   */
-  ensureCellularNetwork_(networkStates) {
-    if (networkStates.find(function(network) {
-          return network.type === mojom.NetworkType.kCellular;
-        })) {
-      return;
-    }
-    const deviceState = this.cellularDeviceState_.deviceState;
-    if (deviceState === mojom.DeviceStateType.kDisabled ||
-        deviceState === mojom.DeviceStateType.kProhibited) {
-      return;  // No Cellular network
-    }
-
-    // Note: the default connectionState is kNotConnected.
-    // TODO(khorimoto): Maybe set an 'initializing' CellularState property if
-    // the device state is initializing, see TODO in network_list_item.js.
-
-    // Insert the Cellular network after the Ethernet network if it exists.
-    const idx = (networkStates.length > 0 &&
-                 networkStates[0].type === mojom.NetworkType.kEthernet) ?
-        1 :
-        0;
-    networkStates.splice(
-        idx, 0, OncMojo.getDefaultNetworkState(mojom.NetworkType.kCellular));
-  },
-
-  /**
    * Event triggered when a network-list-item is selected.
    * @param {!{target: HTMLElement, detail: !OncMojo.NetworkStateProperties}} e
    * @private