diff --git a/DEPS b/DEPS
index 2d9ecece5..4065a93 100644
--- a/DEPS
+++ b/DEPS
@@ -188,22 +188,22 @@
 
   # Fetches only the SDK boot images that match at least one of the
   # entries in a comma-separated list.
-  # Wildcards are supported (e.g. "qemu.*").
   #
   # Available images:
   #   Emulation:
-  #   - qemu.x64 (pulls terminal.qemu-x64-release)
-  #   - qemu.arm64 (pulls terminal.qemu-arm64-release)
-  #   - workstation.qemu-x64-release
+  #   - core.x64-dfv2
+  #   - terminal.qemu-x64
+  #   - terminal.qemu-arm64
+  #   - workstation.qemu-x64
   #   Hardware:
-  #   - generic.x64 (pulls terminal.x64-debug)
-  #   - generic.arm64 (pulls terminal.arm64-debug)
-  #   - chromebook.x64 (pulls terminal.chromebook-x64-debug)
+  #   - workstation_eng.chromebook-x64
+  #   - workstation_eng.chromebook-x64-dfv2 
   #
   # Since the images are hundreds of MB, default to only downloading the image
   # most commonly useful for developers. Bots and developers that need to use
-  # other images (e.g., qemu.arm64) can override this with additional images.
-  'checkout_fuchsia_boot_images': "qemu.x64",
+  # other images can override this with additional images.
+  'checkout_fuchsia_boot_images': "terminal.qemu-x64",
+  'checkout_fuchsia_product_bundles': '"{checkout_fuchsia_boot_images}" != ""',
 
   # By default, do not check out files required to run fuchsia tests in
   # qemu on linux-arm64 machines.
@@ -253,7 +253,7 @@
   # luci-go CIPD package version.
   # Make sure the revision is uploaded by infra-packagers builder.
   # https://ci.chromium.org/p/infra-internal/g/infra-packagers/console
-  'luci_go': 'git_revision:50ab33853a8b220162f851dcb74a1519e106b3df',
+  'luci_go': 'git_revision:765f51c332c38e9b8d7981f23640b9df59371cd5',
 
   # This can be overridden, e.g. with custom_vars, to build clang from HEAD
   # instead of downloading the prebuilt pinned revision.
@@ -307,7 +307,7 @@
   # 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': '4cf2c682d5a75a8505633beacf1116f34829254d',
+  'skia_revision': '027bf16067abf2eefe6950784a8ddd02aa53309f',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
@@ -315,7 +315,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': '9f693aa383b2d3ef32179cfefa253db5ddb8c1bb',
+  'angle_revision': '31a090ca17d7db450e9e1a8074a3ccde6c81e995',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -817,7 +817,7 @@
 
   'src/clank': {
     'url': 'https://chrome-internal.googlesource.com/clank/internal/apps.git' + '@' +
-    'f148bb485a5fb167266582ad9b257aa4739a9604',
+    'fbfcd2589d1b1e3fb1464fb8d91cdb4ad2765e40',
     'condition': 'checkout_android and checkout_src_internal and not checkout_clank_via_src_internal',
   },
 
@@ -841,7 +841,7 @@
   },
 
   'src/ios/third_party/material_components_ios/src': {
-      'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '520dac76c6f76226474a31d5ef9cc30ce0dfbf2f',
+      'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + 'de2dabc46ca4493889964d9fedbc5259c4564ac1',
       'condition': 'checkout_ios',
   },
 
@@ -1244,13 +1244,13 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '9f38b63b4e343d9600d2dc173ab4f59d14ab6713',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '451b8402705d62ee87e7a7c043c52e695a50ce20',
 
   'src/third_party/devtools-frontend/src':
     Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'),
 
   'src/third_party/devtools-frontend-internal': {
-      'url': 'https://chrome-internal.googlesource.com/devtools/devtools-internal.git' + '@' + '1a9a2794f54b2b05d8260bf4b4f2ba7ef75d4585',
+      'url': 'https://chrome-internal.googlesource.com/devtools/devtools-internal.git' + '@' + 'c7ff7462eb69bbae259acf6db055f3aaef8a89e1',
     'condition': 'checkout_src_internal',
   },
 
@@ -1847,7 +1847,7 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'd1b65aa5a88f6efd900604dfcda840154e9f16e2',
 
   'src/third_party/webgpu-cts/src':
-    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '0f0cf479db365038b57a90403c3df7bc12937a7f',
+    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '0439f3ed86ebc7ca85fa2081d50c0ce84a19fdb9',
 
   'src/third_party/webrtc':
     Var('webrtc_git') + '/src.git' + '@' + '4a3f26198d094c7b2cf0f65b755f33f20916c66c',
@@ -1877,7 +1877,7 @@
       'packages': [
         {
           'package': 'skia/tools/goldctl/linux-amd64',
-          'version': '2jACzfYmBkYCdQ9gLvlFoviF5AraIODRg-SfRNRWNiIC',
+          'version': '96rKSNFMICaC-zy3dzFRxE3xkMm8mIPbR6pxbfHXZysC',
         },
       ],
       'dep_type': 'cipd',
@@ -1898,7 +1898,7 @@
       'packages': [
         {
           'package': 'skia/tools/goldctl/mac-amd64',
-          'version': '5vFrHRbi1KP0gUzJkuPP8M8rTg7vmsthBjTYuWfIXZgC',
+          'version': 'BTXwaBdnwpgPkzCAT5gTk0xV0_vzeR2q_icN_le7NBIC',
         },
       ],
       'dep_type': 'cipd',
@@ -1909,7 +1909,7 @@
       'packages': [
         {
           'package': 'skia/tools/goldctl/mac-arm64',
-          'version': 'jR1whwPGU-fOybjyLlxp1oKOEah--L9-_-dsqLyYkBMC',
+          'version': 'r0TJJDCO6SDuVGZoUBvAzDe7hACLXwX3fWH6tvNkYAAC',
         },
       ],
       'dep_type': 'cipd',
@@ -1920,7 +1920,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@3d3673317c682c363504cc9cc07285884922527b',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@e9def4826c390289984b90d933529addcec69de0',
     'condition': 'checkout_src_internal',
   },
 
@@ -4722,12 +4722,11 @@
   {
     'name': 'Download Fuchsia system images',
     'pattern': '.',
-    'condition': 'checkout_fuchsia',
+    'condition': 'checkout_fuchsia and checkout_fuchsia_product_bundles',
     'action': [
       'python3',
-      'src/build/fuchsia/update_images.py',
-      '--boot-images={checkout_fuchsia_boot_images}',
-      '--default-bucket={fuchsia_images_bucket}',
+      'src/build/fuchsia/update_product_bundles.py',
+      '{checkout_fuchsia_boot_images}',
     ],
   },
 
diff --git a/OWNERS b/OWNERS
index c02b7ec..00de2c5 100644
--- a/OWNERS
+++ b/OWNERS
@@ -23,6 +23,7 @@
 per-file .yapfignore=*
 per-file AUTHORS=*
 per-file BUILD.gn=file://build/OWNERS
+per-file CODE_OF_CONDUCT.md=dpranke@google.com
 per-file CODE_OF_CONDUCT.md=benhenry@chromium.org
 per-file CODE_OF_CONDUCT.md=ellyjones@chromium.org
 per-file DEPS=*
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index 27b62fe..a22016d 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -225,8 +225,8 @@
       ),
       True,
       excluded_paths=(
-          r'Test[^a-z]',
-          r'^third_party/',
+          r'.*Test[^a-z]',
+          r'third_party/',
           'base/android/java/src/org/chromium/base/ContextUtils.java',
       ),
     ),
@@ -738,7 +738,7 @@
       [_THIRD_PARTY_EXCEPT_BLINK],  # Don't warn in third_party folders.
     ),
     BanRule(
-      r'\b(absl|std)::any\b',
+      r'/\b(absl|std)::any\b',
       (
         'absl::any / std::any are not safe to use in a component build.',
       ),
@@ -756,9 +756,70 @@
       [_THIRD_PARTY_EXCEPT_BLINK],  # Not an error in third_party folders.
     ),
     BanRule(
+      (
+        r'/\b(?:'
+        r'std::linear_congruential_engine|std::mersenne_twister_engine|'
+        r'std::subtract_with_carry_engine|std::discard_block_engine|'
+        r'std::independent_bits_engine|std::shuffle_order_engine|'
+        r'std::minstd_rand0|std::minstd_rand|'
+        r'std::mt19937|std::mt19937_64|'
+        r'std::ranlux24_base|std::ranlux48_base|std::ranlux24|std::ranlux48|'
+        r'std::knuth_b|'
+        r'std::default_random_engine|'
+        r'std::random_device'
+        r')\b'
+      ),
+      (
+        'STL random number engines and generators are banned. Use the ',
+        'helpers in base/rand_util.h instead, e.g. base::RandBytes() or ',
+        'base::RandomBitGenerator.'
+      ),
+      True,
+      [
+        # Not an error in third_party folders.
+        _THIRD_PARTY_EXCEPT_BLINK,
+        # Various tools which build outside of Chrome.
+        r'testing/libfuzzer',
+        r'tools/android/io_benchmark/',
+        # Fuzzers are allowed to use standard library random number generators
+        # since fuzzing speed + reproducibility is important.
+        r'tools/ipc_fuzzer/',
+        r'.+_fuzzer\.cc$',
+        r'.+_fuzzertest\.cc$',
+        # TODO(https://crbug.com/1380528): These are all unsanctioned uses of
+        # the standard library's random number generators, and should be
+        # migrated to the //base equivalent.
+        r'ash/ambient/model/ambient_topic_queue\.cc',
+        r'base/allocator/partition_allocator/partition_alloc_unittest\.cc',
+        r'base/ranges/algorithm_unittest\.cc',
+        r'base/test/launcher/test_launcher\.cc',
+        r'cc/metrics/video_playback_roughness_reporter_unittest\.cc',
+        r'chrome/browser/apps/app_service/metrics/website_metrics\.cc',
+        r'chrome/browser/ash/power/auto_screen_brightness/monotone_cubic_spline_unittest\.cc',
+        r'chrome/browser/ash/printing/zeroconf_printer_detector_unittest\.cc',
+        r'chrome/browser/nearby_sharing/contacts/nearby_share_contact_manager_impl_unittest\.cc',
+        r'chrome/browser/nearby_sharing/contacts/nearby_share_contacts_sorter_unittest\.cc',
+        r'chrome/browser/privacy_budget/mesa_distribution_unittest\.cc',
+        r'chrome/browser/web_applications/test/web_app_test_utils\.cc',
+        r'chrome/browser/web_applications/test/web_app_test_utils\.cc',
+        r'chrome/browser/win/conflicts/module_blocklist_cache_util_unittest\.cc',
+        r'chrome/chrome_cleaner/logging/detailed_info_sampler\.cc',
+        r'chromeos/ash/components/memory/userspace_swap/swap_storage_unittest\.cc',
+        r'chromeos/ash/components/memory/userspace_swap/userspace_swap\.cc',
+        r'components/metrics/metrics_state_manager\.cc',
+        r'components/omnibox/browser/history_quick_provider_performance_unittest\.cc',
+        r'components/zucchini/disassembler_elf_unittest\.cc',
+        r'content/browser/webid/federated_auth_request_impl\.cc',
+        r'content/browser/webid/federated_auth_request_impl\.cc',
+        r'media/cast/test/utility/udp_proxy\.h',
+        r'sql/recover_module/module_unittest\.cc',
+      ],
+    ),
+    BanRule(
       r'/\babsl::bind_front\b',
       (
-        'absl::bind_front is banned. Use base::Bind instead.',
+        'absl::bind_front is banned. Use base::BindOnce() or '
+        'base::BindRepeating() instead.',
       ),
       True,
       [_THIRD_PARTY_EXCEPT_BLINK],  # Not an error in third_party folders.
@@ -799,8 +860,9 @@
     BanRule(
       r'/\babsl::(Insecure)?BitGen\b',
       (
-        'Abseil random number generators are banned. Use base/rand_util.h',
-        'instead.',
+        'absl random number generators are banned. Use the helpers in '
+        'base/rand_util.h instead, e.g. base::RandBytes() or ',
+        'base::RandomBitGenerator.'
       ),
       True,
       [_THIRD_PARTY_EXCEPT_BLINK],  # Not an error in third_party folders.
diff --git a/PRESUBMIT_test.py b/PRESUBMIT_test.py
index 93b8c7a..a4600e49 100755
--- a/PRESUBMIT_test.py
+++ b/PRESUBMIT_test.py
@@ -2799,6 +2799,48 @@
     self.assertFalse('some/cpp/comment/file.cc' in results[0].message)
     self.assertFalse('some/cpp/comment/file.cc' in results[1].message)
 
+  def testBannedCppRandomFunctions(self):
+    banned_rngs = [
+        'absl::BitGen',
+        'absl::InsecureBitGen',
+        'std::linear_congruential_engine',
+        'std::mersenne_twister_engine',
+        'std::subtract_with_carry_engine',
+        'std::discard_block_engine',
+        'std::independent_bits_engine',
+        'std::shuffle_order_engine',
+        'std::minstd_rand0',
+        'std::minstd_rand',
+        'std::mt19937',
+        'std::mt19937_64',
+        'std::ranlux24_base',
+        'std::ranlux48_base',
+        'std::ranlux24',
+        'std::ranlux48',
+        'std::knuth_b',
+        'std::default_random_engine',
+        'std::random_device',
+    ]
+    for banned_rng in banned_rngs:
+      input_api = MockInputApi()
+      input_api.files = [
+        MockFile('some/cpp/problematic/file.cc',
+                 [f'{banned_rng} engine;']),
+        MockFile('third_party/blink/problematic/file.cc',
+                 [f'{banned_rng} engine;']),
+        MockFile('third_party/ok/file.cc',
+                 [f'{banned_rng} engine;']),
+      ]
+      results = PRESUBMIT.CheckNoBannedFunctions(input_api, MockOutputApi())
+      self.assertEqual(1, len(results), banned_rng)
+      self.assertTrue('some/cpp/problematic/file.cc' in results[0].message,
+                      banned_rng)
+      self.assertTrue(
+          'third_party/blink/problematic/file.cc' in results[0].message,
+          banned_rng)
+      self.assertFalse(
+          'third_party/ok/file.cc' in results[0].message, banned_rng)
+
   def testBannedIosObjcFunctions(self):
     input_api = MockInputApi()
     input_api.files = [
diff --git a/android_webview/expectations/system_webview_bundle.AndroidManifest.expected b/android_webview/expectations/system_webview_bundle.AndroidManifest.expected
index 9738952..94da9a2 100644
--- a/android_webview/expectations/system_webview_bundle.AndroidManifest.expected
+++ b/android_webview/expectations/system_webview_bundle.AndroidManifest.expected
@@ -11,7 +11,7 @@
   <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
   <uses-permission android:name="android.permission.INTERNET"/>
   <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
-  <uses-sdk android:minSdkVersion="23" android:targetSdkVersion="33"/>
+  <uses-sdk android:minSdkVersion="24" android:targetSdkVersion="33"/>
   <application
       android:name="org.chromium.android_webview.nonembedded.WebViewApkApplication"
       android:extractNativeLibs="True"
diff --git a/android_webview/tools/system_webview_shell/lint-baseline.xml b/android_webview/tools/system_webview_shell/lint-baseline.xml
index 2a061fec..ff008ee 100644
--- a/android_webview/tools/system_webview_shell/lint-baseline.xml
+++ b/android_webview/tools/system_webview_shell/lint-baseline.xml
@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 7.4.0-alpha10" type="baseline" client="" dependencies="true" name="" variant="all" version="7.4.0-alpha10">
+<issues format="6" by="lint 8.0.0-alpha06" type="baseline" client="" dependencies="true" name="" variant="all" version="8.0.0-alpha06">
 
     <issue
         id="LintError"
-        message="../../android_webview/tools/system_webview_shell/lint-baseline.xml (relative to /usr/local/google/home/chesterchen/chromium/src/out/Emulator_avd) does not exist"
+        message="../../android_webview/tools/system_webview_shell/lint-baseline.xml (relative to /usr/local/google/code/clankium/src/out/Lint-Default) does not exist"
         errorLine1="  &lt;baseline file=&quot;../../android_webview/tools/system_webview_shell/lint-baseline.xml&quot;/>"
         errorLine2="  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
@@ -18,8 +18,8 @@
         errorLine1="    public void onRequestPermissionsResult(int requestCode,"
         errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java"
-            line="569"
+            file="../../android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java"
+            line="625"
             column="17"/>
     </issue>
 
@@ -30,7 +30,7 @@
         errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="gen/android_webview/tools/system_webview_shell/system_webview_shell_apk__lint/gen/android_webview/system_webview_shell_apk/AndroidManifest.xml"
-            line="165"
+            line="187"
             column="29"/>
     </issue>
 
@@ -40,8 +40,8 @@
         errorLine1="            TracingController tracingController = TracingController.getInstance();"
         errorLine2="                                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java"
-            line="660"
+            file="../../android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java"
+            line="744"
             column="51"/>
     </issue>
 
@@ -51,8 +51,8 @@
         errorLine1="            WebSettingsCompat.setForceDark("
         errorLine2="            ^">
         <location
-            file="$SRC/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java"
-            line="681"
+            file="../../android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java"
+            line="765"
             column="13"/>
     </issue>
 
@@ -62,8 +62,8 @@
         errorLine1="            WebSettingsCompat.setForceDark("
         errorLine2="            ^">
         <location
-            file="$SRC/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java"
-            line="686"
+            file="../../android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java"
+            line="770"
             column="13"/>
     </issue>
 
@@ -73,8 +73,8 @@
         errorLine1="            WebSettingsCompat.setForceDark(mWebView.getSettings(), WebSettingsCompat.FORCE_DARK_ON);"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java"
-            line="691"
+            file="../../android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java"
+            line="775"
             column="13"/>
     </issue>
 
@@ -84,7 +84,7 @@
         errorLine1="        final TracingController tracingController = TracingController.getInstance();"
         errorLine2="                                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewTracingActivity.java"
+            file="../../android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewTracingActivity.java"
             line="100"
             column="53"/>
     </issue>
@@ -95,7 +95,7 @@
         errorLine1="                    GET_STATUS_UMA_HISTOGRAM, status, Status.NUM_ENTRIES);"
         errorLine2="                                                             ~~~~~~~~~~~">
         <location
-            file="$SRC/base/android/java/src/org/chromium/base/task/AsyncTask.java"
+            file="../../base/android/java/src/org/chromium/base/task/AsyncTask.java"
             line="314"
             column="62"/>
     </issue>
@@ -106,7 +106,7 @@
         errorLine1="                    GET_STATUS_UMA_HISTOGRAM, status, Status.NUM_ENTRIES);"
         errorLine2="                                                             ~~~~~~~~~~~">
         <location
-            file="$SRC/base/android/java/src/org/chromium/base/task/AsyncTask.java"
+            file="../../base/android/java/src/org/chromium/base/task/AsyncTask.java"
             line="352"
             column="62"/>
     </issue>
@@ -117,7 +117,7 @@
         errorLine1="                mHistogramName, notification, Notification.NUM_ENTRIES);"
         errorLine2="                                                           ~~~~~~~~~~~">
         <location
-            file="$SRC/base/android/java/src/org/chromium/base/memory/MemoryPressureUma.java"
+            file="../../base/android/java/src/org/chromium/base/memory/MemoryPressureUma.java"
             line="110"
             column="60"/>
     </issue>
@@ -128,7 +128,7 @@
         errorLine1="            config.setLocale(Locale.forLanguageTag(languageTag));"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/base/android/java/src/org/chromium/base/LocaleUtils.java"
+            file="../../base/android/java/src/org/chromium/base/LocaleUtils.java"
             line="267"
             column="13"/>
     </issue>
@@ -139,7 +139,7 @@
         errorLine1="            return pm.queryIntentActivities(intent, flags);"
         errorLine2="                      ~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/base/android/java/src/org/chromium/base/PackageManagerUtils.java"
+            file="../../base/android/java/src/org/chromium/base/PackageManagerUtils.java"
             line="63"
             column="23"/>
     </issue>
@@ -150,7 +150,7 @@
         errorLine1="                return res.getDrawable(id, null);"
         errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java"
+            file="../../base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java"
             line="311"
             column="24"/>
     </issue>
@@ -158,12 +158,23 @@
     <issue
         id="HardcodedDebugMode"
         message="Avoid hardcoding the debug mode; leaving it out allows debug and release builds to automatically assign one"
-        errorLine1="  &lt;application android:icon=&quot;@drawable/ic_launcher&quot; android:label=&quot;@string/app_name&quot; android:theme=&quot;@style/ShellTheme&quot; android:networkSecurityConfig=&quot;@xml/network_security_config&quot; android:debuggable=&quot;true&quot;>"
-        errorLine2="                                                                                                                                                                                    ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        errorLine1="  &lt;application android:icon=&quot;@drawable/ic_launcher&quot; android:label=&quot;@string/app_name&quot; android:theme=&quot;@style/ShellTheme&quot; android:enableOnBackInvokedCallback=&quot;true&quot; android:networkSecurityConfig=&quot;@xml/network_security_config&quot; android:debuggable=&quot;true&quot;>"
+        errorLine2="                                                                                                                                                                                                                               ~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="gen/android_webview/tools/system_webview_shell/system_webview_shell_apk__lint/gen/android_webview/system_webview_shell_apk/AndroidManifest.xml"
-            line="47"
-            column="181"/>
+            line="69"
+            column="224"/>
+    </issue>
+
+    <issue
+        id="ObsoleteSdkInt"
+        message="Unnecessary; SDK_INT is always >= 24"
+        errorLine1="    @RequiresApi(Build.VERSION_CODES.N)"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="../../base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java"
+            line="120"
+            column="5"/>
     </issue>
 
     <issue
@@ -172,217 +183,393 @@
         errorLine1="    @RequiresApi(Build.VERSION_CODES.M)"
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java"
+            file="../../base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java"
             line="144"
             column="5"/>
     </issue>
 
     <issue
         id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is always >= 23"
+        message="Unnecessary; SDK_INT is always >= 24"
+        errorLine1="        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="../../base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java"
+            line="220"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="ObsoleteSdkInt"
+        message="Unnecessary; SDK_INT is always >= 24"
         errorLine1="        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java"
+            file="../../base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java"
             line="269"
             column="13"/>
     </issue>
 
     <issue
         id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is never &lt; 23"
+        message="Unnecessary; SDK_INT is never &lt; 24"
         errorLine1="        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP) {"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java"
+            file="../../base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java"
             line="284"
             column="13"/>
     </issue>
 
     <issue
         id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is never &lt; 23"
+        message="Unnecessary; SDK_INT is never &lt; 24"
         errorLine1="        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP) {"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java"
+            file="../../base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java"
             line="293"
             column="13"/>
     </issue>
 
     <issue
         id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is always >= 23"
+        message="Unnecessary; SDK_INT is always >= 24"
+        errorLine1="        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="../../base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java"
+            line="364"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="ObsoleteSdkInt"
+        message="Unnecessary; SDK_INT is always >= 24"
+        errorLine1="        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="../../base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java"
+            line="375"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="ObsoleteSdkInt"
+        message="Unnecessary; SDK_INT is always >= 24"
         errorLine1="        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java"
+            file="../../base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java"
             line="423"
             column="13"/>
     </issue>
 
     <issue
         id="ObsoleteSdkInt"
+        message="Unnecessary; SDK_INT is always >= 24"
+        errorLine1="        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) return;"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="../../base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java"
+            line="436"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="ObsoleteSdkInt"
         message="Unnecessary; SDK_INT is always >= 23"
         errorLine1="@RequiresApi(Build.VERSION_CODES.M)"
         errorLine2="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/base/android/java/src/org/chromium/base/compat/ApiHelperForM.java"
-            line="37"
+            file="../../base/android/java/src/org/chromium/base/compat/ApiHelperForM.java"
+            line="38"
             column="1"/>
     </issue>
 
     <issue
         id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is always >= 23"
+        message="Unnecessary; SDK_INT is always >= 24"
+        errorLine1="@RequiresApi(Build.VERSION_CODES.N)"
+        errorLine2="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="../../base/android/java/src/org/chromium/base/compat/ApiHelperForN.java"
+            line="36"
+            column="1"/>
+    </issue>
+
+    <issue
+        id="ObsoleteSdkInt"
+        message="Unnecessary; SDK_INT is always >= 24"
+        errorLine1="    @RequiresApi(Build.VERSION_CODES.N)"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="../../base/android/java/src/org/chromium/base/process_launcher/BindService.java"
+            line="66"
+            column="5"/>
+    </issue>
+
+    <issue
+        id="ObsoleteSdkInt"
+        message="Unnecessary; SDK_INT is always >= 24"
         errorLine1="            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {"
         errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/base/android/java/src/org/chromium/base/BuildInfo.java"
-            line="202"
+            file="../../base/android/java/src/org/chromium/base/BuildInfo.java"
+            line="212"
             column="17"/>
     </issue>
 
     <issue
         id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is always >= 23"
+        message="Unnecessary; SDK_INT is always >= 24"
+        errorLine1="                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="../../base/android/java/src/org/chromium/base/process_launcher/ChildProcessService.java"
+            line="320"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="ObsoleteSdkInt"
+        message="Unnecessary; SDK_INT is always >= 24"
         errorLine1="        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/base/android/java/src/org/chromium/base/multidex/ChromiumMultiDexInstaller.java"
+            file="../../base/android/java/src/org/chromium/base/multidex/ChromiumMultiDexInstaller.java"
             line="31"
             column="13"/>
     </issue>
 
     <issue
         id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is never &lt; 23"
+        message="Unnecessary; SDK_INT is never &lt; 24"
         errorLine1="        if (Build.VERSION.SDK_INT &lt; Build.VERSION_CODES.KITKAT) return false;"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/base/android/java/src/org/chromium/base/ContentUriUtils.java"
+            file="../../base/android/java/src/org/chromium/base/ContentUriUtils.java"
             line="251"
             column="13"/>
     </issue>
 
     <issue
         id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is always >= 23"
+        message="Unnecessary; SDK_INT is never &lt; 24"
+        errorLine1="        if (Build.VERSION.SDK_INT &lt; Build.VERSION_CODES.N) return false;"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="../../base/android/java/src/org/chromium/base/ContentUriUtils.java"
+            line="279"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="ObsoleteSdkInt"
+        message="Unnecessary; SDK_INT is always >= 24"
         errorLine1="        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/base/android/java/src/org/chromium/base/ContextUtils.java"
+            file="../../base/android/java/src/org/chromium/base/ContextUtils.java"
             line="187"
             column="13"/>
     </issue>
 
     <issue
         id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is always >= 23"
+        message="Unnecessary; SDK_INT is always >= 24"
+        errorLine1="@RequiresApi(api = VERSION_CODES.N)"
+        errorLine2="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="../../base/android/java/src/org/chromium/base/jank_tracker/FrameMetricsListener.java"
+            line="23"
+            column="1"/>
+    </issue>
+
+    <issue
+        id="ObsoleteSdkInt"
+        message="Unnecessary; SDK_INT is always >= 24"
+        errorLine1="    @RequiresApi(api = VERSION_CODES.N)"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="../../base/android/java/src/org/chromium/base/jank_tracker/FrameMetricsListener.java"
+            line="41"
+            column="5"/>
+    </issue>
+
+    <issue
+        id="ObsoleteSdkInt"
+        message="Unnecessary; SDK_INT is always >= 24"
         errorLine1="        if (!mutable &amp;&amp; Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {"
         errorLine2="                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/base/android/java/src/org/chromium/base/IntentUtils.java"
-            line="514"
+            file="../../base/android/java/src/org/chromium/base/IntentUtils.java"
+            line="492"
             column="25"/>
     </issue>
 
     <issue
         id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is always >= 23"
+        message="Unnecessary; SDK_INT is always >= 24"
+        errorLine1="@RequiresApi(api = VERSION_CODES.N)"
+        errorLine2="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="../../base/android/java/src/org/chromium/base/jank_tracker/JankActivityTracker.java"
+            line="25"
+            column="1"/>
+    </issue>
+
+    <issue
+        id="ObsoleteSdkInt"
+        message="Unnecessary; SDK_INT is always >= 24"
+        errorLine1="            Build.VERSION.SDK_INT >= Build.VERSION_CODES.N;"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="../../base/android/java/src/org/chromium/base/jank_tracker/JankTrackerImpl.java"
+            line="19"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="ObsoleteSdkInt"
+        message="Unnecessary; SDK_INT is always >= 24"
         errorLine1="        assert !isInZipFile() || Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;"
         errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java"
-            line="812"
+            file="../../base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java"
+            line="827"
             column="34"/>
     </issue>
 
     <issue
         id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is always >= 23"
+        message="Unnecessary; SDK_INT is always >= 24"
         errorLine1="        if (BuildConfig.IS_UBSAN &amp;&amp; Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {"
         errorLine2="                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java"
-            line="1027"
+            file="../../base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java"
+            line="1071"
             column="37"/>
     </issue>
 
     <issue
         id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is always >= 23"
+        message="Unnecessary; SDK_INT is always >= 24"
         errorLine1="        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/base/android/java/src/org/chromium/base/LocaleUtils.java"
+            file="../../base/android/java/src/org/chromium/base/LocaleUtils.java"
             line="135"
             column="13"/>
     </issue>
 
     <issue
         id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is never &lt; 23"
+        message="Unnecessary; SDK_INT is always >= 24"
+        errorLine1="    @RequiresApi(Build.VERSION_CODES.N)"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="../../base/android/java/src/org/chromium/base/LocaleUtils.java"
+            line="169"
+            column="5"/>
+    </issue>
+
+    <issue
+        id="ObsoleteSdkInt"
+        message="Unnecessary; SDK_INT is always >= 24"
+        errorLine1="        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="../../base/android/java/src/org/chromium/base/LocaleUtils.java"
+            line="218"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="ObsoleteSdkInt"
+        message="Unnecessary; SDK_INT is always >= 24"
+        errorLine1="        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="../../base/android/java/src/org/chromium/base/LocaleUtils.java"
+            line="264"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="ObsoleteSdkInt"
+        message="Unnecessary; SDK_INT is always >= 24"
+        errorLine1="        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="../../base/android/java/src/org/chromium/base/LocaleUtils.java"
+            line="276"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="ObsoleteSdkInt"
+        message="Unnecessary; SDK_INT is always >= 24"
+        errorLine1="    @RequiresApi(Build.VERSION_CODES.N)"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="../../base/android/java/src/org/chromium/base/LocaleUtils.java"
+            line="286"
+            column="5"/>
+    </issue>
+
+    <issue
+        id="ObsoleteSdkInt"
+        message="Unnecessary; SDK_INT is never &lt; 24"
         errorLine1="        if (Build.VERSION.SDK_INT &lt; Build.VERSION_CODES.LOLLIPOP) return;"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/base/android/java/src/org/chromium/base/PathUtils.java"
+            file="../../base/android/java/src/org/chromium/base/PathUtils.java"
             line="91"
             column="13"/>
     </issue>
 
     <issue
         id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is never &lt; 23"
+        message="Unnecessary; SDK_INT is never &lt; 24"
         errorLine1="        if (Build.VERSION.SDK_INT &lt; Build.VERSION_CODES.LOLLIPOP) return 0;"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/base/android/java/src/org/chromium/base/PowerMonitor.java"
+            file="../../base/android/java/src/org/chromium/base/PowerMonitor.java"
             line="99"
             column="13"/>
     </issue>
 
     <issue
         id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is always >= 23"
-        errorLine1="        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/base/android/java/src/org/chromium/base/task/SingleThreadTaskRunnerImpl.java"
-            line="100"
-            column="13"/>
-    </issue>
-
-    <issue
-        id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is always >= 23"
+        message="Unnecessary; SDK_INT is always >= 24"
         errorLine1="        if (appContext != null &amp;&amp; Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {"
         errorLine2="                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/base/android/java/src/org/chromium/base/SysUtils.java"
-            line="186"
+            file="../../base/android/java/src/org/chromium/base/SysUtils.java"
+            line="185"
             column="35"/>
     </issue>
 
     <issue
         id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is always >= 23"
+        message="Unnecessary; SDK_INT is always >= 24"
         errorLine1="        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java"
-            line="405"
+            file="../../android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java"
+            line="446"
             column="13"/>
     </issue>
 
     <issue
         id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is never &lt; 23"
+        message="Unnecessary; SDK_INT is never &lt; 24"
         errorLine1="                if (Build.VERSION.SDK_INT &lt; Build.VERSION_CODES.LOLLIPOP) {"
         errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java"
-            line="458"
+            file="../../android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java"
+            line="514"
             column="21"/>
     </issue>
 
@@ -392,74 +579,52 @@
         errorLine1="    @RequiresApi(Build.VERSION_CODES.M)"
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java"
-            line="513"
+            file="../../android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java"
+            line="569"
             column="5"/>
     </issue>
 
     <issue
         id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is never &lt; 23"
+        message="Unnecessary; SDK_INT is never &lt; 24"
         errorLine1="        if (Build.VERSION.SDK_INT &lt; Build.VERSION_CODES.M) {"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java"
-            line="533"
+            file="../../android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java"
+            line="589"
             column="13"/>
     </issue>
 
     <issue
         id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is always >= 23"
+        message="Unnecessary; SDK_INT is always >= 24"
         errorLine1="        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java"
-            line="804"
+            file="../../android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java"
+            line="899"
             column="13"/>
     </issue>
 
     <issue
         id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is always >= 23"
+        message="Unnecessary; SDK_INT is always >= 24"
         errorLine1="        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java"
-            line="823"
+            file="../../android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java"
+            line="926"
             column="13"/>
     </issue>
 
     <issue
-        id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is never &lt; 23"
-        errorLine1="        if (Build.VERSION.SDK_INT &lt; Build.VERSION_CODES.LOLLIPOP) {"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewPackageHelper.java"
-            line="37"
-            column="13"/>
-    </issue>
-
-    <issue
-        id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is always >= 23"
-        errorLine1="            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP"
-        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewPackageHelper.java"
-            line="81"
-            column="17"/>
-    </issue>
-
-    <issue
         id="AssertionSideEffect"
         message="Assertion condition has a side effect: f.setAccessible(true)"
         errorLine1="                    assert reachesWindowCallback(activity.getWindow().getCallback());"
         errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/base/android/java/src/org/chromium/base/ApplicationStatus.java"
-            line="301"
+            file="../../base/android/java/src/org/chromium/base/ApplicationStatus.java"
+            line="351"
             column="28"/>
     </issue>
 
@@ -469,7 +634,7 @@
         errorLine1="        assert isSupported();"
         errorLine2="               ~~~~~~~~~~~~~">
         <location
-            file="$SRC/base/android/java/src/org/chromium/base/RadioUtils.java"
+            file="../../base/android/java/src/org/chromium/base/RadioUtils.java"
             line="80"
             column="16"/>
     </issue>
@@ -480,7 +645,7 @@
         errorLine1="        assert isSupported();"
         errorLine2="               ~~~~~~~~~~~~~">
         <location
-            file="$SRC/base/android/java/src/org/chromium/base/RadioUtils.java"
+            file="../../base/android/java/src/org/chromium/base/RadioUtils.java"
             line="105"
             column="16"/>
     </issue>
@@ -491,7 +656,7 @@
         errorLine1="        assert isSupported();"
         errorLine2="               ~~~~~~~~~~~~~">
         <location
-            file="$SRC/base/android/java/src/org/chromium/base/RadioUtils.java"
+            file="../../base/android/java/src/org/chromium/base/RadioUtils.java"
             line="131"
             column="16"/>
     </issue>
@@ -500,7 +665,7 @@
         id="IconMissingDensityFolder"
         message="Missing density variation folders in `../../android_webview/tools/system_webview_shell/apk/res`: drawable-hdpi, drawable-xhdpi, drawable-xxhdpi">
         <location
-            file="$SRC/android_webview/tools/system_webview_shell/apk/res"/>
+            file="../../android_webview/tools/system_webview_shell/apk/res"/>
     </issue>
 
 </issues>
diff --git a/ash/BUILD.gn b/ash/BUILD.gn
index 4e49373..6cdefb4 100644
--- a/ash/BUILD.gn
+++ b/ash/BUILD.gn
@@ -327,6 +327,10 @@
     "capture_mode/capture_window_observer.h",
     "capture_mode/folder_selection_dialog_controller.cc",
     "capture_mode/folder_selection_dialog_controller.h",
+    "capture_mode/key_combo_view.cc",
+    "capture_mode/key_combo_view.h",
+    "capture_mode/key_item_view.cc",
+    "capture_mode/key_item_view.h",
     "capture_mode/recording_overlay_controller.cc",
     "capture_mode/recording_overlay_controller.h",
     "capture_mode/stop_recording_button_tray.cc",
@@ -1366,14 +1370,8 @@
     "system/message_center/notifier_settings_view.h",
     "system/message_center/session_state_notification_blocker.cc",
     "system/message_center/session_state_notification_blocker.h",
-    "system/message_center/stacked_notification_bar.cc",
-    "system/message_center/stacked_notification_bar.h",
     "system/message_center/unified_message_center_bubble.cc",
     "system/message_center/unified_message_center_bubble.h",
-    "system/message_center/unified_message_center_view.cc",
-    "system/message_center/unified_message_center_view.h",
-    "system/message_center/unified_message_list_view.cc",
-    "system/message_center/unified_message_list_view.h",
     "system/microphone_mute/microphone_mute_notification_controller.cc",
     "system/microphone_mute/microphone_mute_notification_controller.h",
     "system/model/clock_model.cc",
@@ -1496,6 +1494,12 @@
     "system/night_light/night_light_feature_pod_controller.h",
     "system/notification_center/notification_center_tray.cc",
     "system/notification_center/notification_center_tray.h",
+    "system/notification_center/notification_center_view.cc",
+    "system/notification_center/notification_center_view.h",
+    "system/notification_center/notification_list_view.cc",
+    "system/notification_center/notification_list_view.h",
+    "system/notification_center/stacked_notification_bar.cc",
+    "system/notification_center/stacked_notification_bar.h",
     "system/overview/overview_button_tray.cc",
     "system/overview/overview_button_tray.h",
     "system/palette/common_palette_tool.cc",
@@ -2947,8 +2951,6 @@
     "system/message_center/notifier_settings_view_unittest.cc",
     "system/message_center/session_state_notification_blocker_unittest.cc",
     "system/message_center/unified_message_center_bubble_unittest.cc",
-    "system/message_center/unified_message_center_view_unittest.cc",
-    "system/message_center/unified_message_list_view_unittest.cc",
     "system/microphone_mute/microphone_mute_notification_controller_unittest.cc",
     "system/nearby_share/nearby_share_feature_pod_controller_unittest.cc",
     "system/network/active_network_icon_unittest.cc",
@@ -2973,6 +2975,8 @@
     "system/night_light/night_light_controller_unittest.cc",
     "system/night_light/night_light_feature_pod_controller_unittest.cc",
     "system/notification_center/notification_center_tray_unittest.cc",
+    "system/notification_center/notification_center_view_unittest.cc",
+    "system/notification_center/notification_list_view_unittest.cc",
     "system/overview/overview_button_tray_unittest.cc",
     "system/palette/mock_palette_tool_delegate.cc",
     "system/palette/mock_palette_tool_delegate.h",
@@ -3469,6 +3473,8 @@
     "assistant/test/test_assistant_service.h",
     "assistant/test/test_assistant_setup.cc",
     "assistant/test/test_assistant_setup.h",
+    "capture_mode/capture_mode_demo_tools_test_api.cc",
+    "capture_mode/capture_mode_demo_tools_test_api.h",
     "capture_mode/capture_mode_session_test_api.cc",
     "capture_mode/capture_mode_session_test_api.h",
     "capture_mode/capture_mode_settings_test_api.cc",
diff --git a/ash/app_list/app_list_presenter_impl.cc b/ash/app_list/app_list_presenter_impl.cc
index be70a34..8251a22 100644
--- a/ash/app_list/app_list_presenter_impl.cc
+++ b/ash/app_list/app_list_presenter_impl.cc
@@ -40,6 +40,7 @@
 #include "ui/compositor/layer.h"
 #include "ui/compositor/layer_animation_element.h"
 #include "ui/compositor/layer_animation_observer.h"
+#include "ui/compositor/layer_observer.h"
 #include "ui/compositor/scoped_layer_animation_settings.h"
 #include "ui/display/screen.h"
 #include "ui/display/types/display_constants.h"
@@ -118,20 +119,28 @@
 
 // Invokes `complete_callback_` at the end of animation.
 class FullscreenLauncherAnimationObserver
-    : public ui::ImplicitAnimationObserver {
+    : public ui::ImplicitAnimationObserver,
+      public ui::LayerObserver {
  public:
   // Invoked with `true` if animation was aborted.
   using AnimationCompleteCallback = base::OnceCallback<void(bool)>;
 
-  explicit FullscreenLauncherAnimationObserver(
+  FullscreenLauncherAnimationObserver(
+      ui::Layer* layer,
       AnimationCompleteCallback complete_callback)
-      : complete_callback_(std::move(complete_callback)) {}
+      : layer_(layer), complete_callback_(std::move(complete_callback)) {
+    DCHECK(layer_);
+    layer_->AddObserver(this);
+  }
+
   FullscreenLauncherAnimationObserver(
       const FullscreenLauncherAnimationObserver& other) = delete;
   FullscreenLauncherAnimationObserver& operator=(
       const FullscreenLauncherAnimationObserver& other) = delete;
+
   ~FullscreenLauncherAnimationObserver() override {
     StopObservingImplicitAnimations();
+    layer_->RemoveObserver(this);
   }
 
   // ui::ImplicitAnimationObserver:
@@ -145,7 +154,17 @@
     delete this;
   }
 
+  // ui::LayerObserver overrides:
+  void LayerDestroyed(ui::Layer* layer) override {
+    // Old `AppListView`'s layer can be cloned and then destroyed by
+    // `ScreenRotationAnimator`. In this case run `complete_callback_` and
+    // destroy `this`.
+    std::move(complete_callback_).Run(false);
+    delete this;
+  }
+
  private:
+  ui::Layer* const layer_;
   AnimationCompleteCallback complete_callback_;
 };
 
@@ -315,7 +334,7 @@
             &AppListPresenterImpl::OnTabletToClamshellTransitionAnimationDone,
             weak_ptr_factory_.GetWeakPtr(), /*target_visibility=*/true);
     auto* animation_observer = new FullscreenLauncherAnimationObserver(
-        std::move(animation_complete_callback));
+        layer, std::move(animation_complete_callback));
     UpdateScaleAndOpacityForHomeLauncher(
         1.0f, 1.0f, absl::nullopt,
         base::BindRepeating(&UpdateTabletModeTransitionAnimationSettings,
@@ -398,20 +417,17 @@
   last_open_time_.reset();
 
   if (!view_->GetWidget()->GetNativeWindow()->is_destroying()) {
+    auto* const layer = view_->GetWidget()->GetNativeWindow()->layer();
     if (app_list_features::IsAnimateScaleOnTabletModeTransitionEnabled()) {
       FullscreenLauncherAnimationObserver::AnimationCompleteCallback
           animation_complete_callback = base::BindOnce(
               &AppListPresenterImpl::OnTabletToClamshellTransitionAnimationDone,
               weak_ptr_factory_.GetWeakPtr(), /*target_visibility=*/false);
       auto* animation_observer = new FullscreenLauncherAnimationObserver(
-          std::move(animation_complete_callback));
+          layer, std::move(animation_complete_callback));
       // Aborts show animation (if it's running, noop otherwise). This helps to
       // run dismiss animation smoothly from the aborted scale/opacity points.
-      view_->GetWidget()
-          ->GetNativeWindow()
-          ->layer()
-          ->GetAnimator()
-          ->AbortAllAnimations();
+      layer->GetAnimator()->AbortAllAnimations();
       UpdateScaleAndOpacityForHomeLauncher(
           kFullscreenLauncherFadeAnimationScale, 0.0f, absl::nullopt,
           base::BindRepeating(&UpdateTabletModeTransitionAnimationSettings,
diff --git a/ash/app_list/app_list_presenter_impl.h b/ash/app_list/app_list_presenter_impl.h
index e4ff09f..400cb6a 100644
--- a/ash/app_list/app_list_presenter_impl.h
+++ b/ash/app_list/app_list_presenter_impl.h
@@ -18,7 +18,6 @@
 #include "ash/shelf/shelf.h"
 #include "ash/shelf/shelf_observer.h"
 #include "base/callback.h"
-#include "base/compiler_specific.h"
 #include "base/scoped_observation.h"
 #include "base/time/time.h"
 #include "ui/aura/client/focus_change_observer.h"
diff --git a/ash/app_list/views/app_list_bubble_apps_page_unittest.cc b/ash/app_list/views/app_list_bubble_apps_page_unittest.cc
index 8a76632c..2e25396 100644
--- a/ash/app_list/views/app_list_bubble_apps_page_unittest.cc
+++ b/ash/app_list/views/app_list_bubble_apps_page_unittest.cc
@@ -19,14 +19,12 @@
 #include "ash/app_list/views/recent_apps_view.h"
 #include "ash/app_list/views/scrollable_apps_grid_view.h"
 #include "ash/app_list/views/search_box_view.h"
-#include "ash/constants/ash_features.h"
 #include "ash/public/cpp/app_list/app_list_controller.h"
 #include "ash/shell.h"
 #include "ash/style/icon_button.h"
 #include "ash/test/ash_test_base.h"
 #include "base/test/bind.h"
 #include "base/test/metrics/histogram_tester.h"
-#include "base/test/scoped_feature_list.h"
 #include "base/time/time.h"
 #include "ui/compositor/layer.h"
 #include "ui/compositor/layer_animator.h"
@@ -44,12 +42,7 @@
 
 class AppListBubbleAppsPageTest : public AshTestBase {
  public:
-  AppListBubbleAppsPageTest() {
-    features_.InitWithFeatures(
-        {features::kProductivityLauncher,
-         features::kLauncherDismissButtonsOnSortNudgeAndToast},
-        {});
-  }
+  AppListBubbleAppsPageTest() = default;
 
   void OnReorderAnimationDone(base::OnceClosure closure,
                               bool expect_abort,
@@ -82,9 +75,6 @@
             base::Unretained(this), run_loop.QuitClosure(), expect_abort));
     run_loop.Run();
   }
-
- private:
-  base::test::ScopedFeatureList features_;
 };
 
 TEST_F(AppListBubbleAppsPageTest, SlideViewIntoPositionCleansUpLayers) {
diff --git a/ash/app_list/views/app_list_bubble_view_unittest.cc b/ash/app_list/views/app_list_bubble_view_unittest.cc
index cca2892..c42b780f 100644
--- a/ash/app_list/views/app_list_bubble_view_unittest.cc
+++ b/ash/app_list/views/app_list_bubble_view_unittest.cc
@@ -28,7 +28,6 @@
 #include "ash/app_list/views/scrollable_apps_grid_view.h"
 #include "ash/app_list/views/search_box_view.h"
 #include "ash/assistant/model/assistant_ui_model.h"
-#include "ash/constants/ash_features.h"
 #include "ash/controls/gradient_layer_delegate.h"
 #include "ash/controls/scroll_view_gradient_helper.h"
 #include "ash/public/cpp/assistant/controller/assistant_ui_controller.h"
@@ -42,7 +41,6 @@
 #include "base/run_loop.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/test/metrics/histogram_tester.h"
-#include "base/test/scoped_feature_list.h"
 #include "chromeos/ash/services/assistant/public/cpp/assistant_enums.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/compositor/layer.h"
@@ -105,9 +103,7 @@
 
 class AppListBubbleViewTest : public AshTestBase {
  public:
-  AppListBubbleViewTest() {
-    scoped_features_.InitAndEnableFeature(features::kProductivityLauncher);
-  }
+  AppListBubbleViewTest() = default;
   ~AppListBubbleViewTest() override = default;
 
   // testing::Test:
@@ -190,7 +186,6 @@
     return view ? view->GetClassName() : "none";
   }
 
-  base::test::ScopedFeatureList scoped_features_;
   std::unique_ptr<test::AppListTestModel> app_list_test_model_;
   std::unique_ptr<SearchModel> search_model_;
   std::unique_ptr<AssistantTestApi> assistant_test_api_;
diff --git a/ash/app_list/views/app_list_nudge_controller_unittest.cc b/ash/app_list/views/app_list_nudge_controller_unittest.cc
index ba33b15..23b74cb 100644
--- a/ash/app_list/views/app_list_nudge_controller_unittest.cc
+++ b/ash/app_list/views/app_list_nudge_controller_unittest.cc
@@ -12,14 +12,12 @@
 #include "ash/app_list/views/app_list_toast_container_view.h"
 #include "ash/app_list/views/apps_container_view.h"
 #include "ash/app_list/views/search_box_view.h"
-#include "ash/constants/ash_features.h"
 #include "ash/public/cpp/app_list/app_list_types.h"
 #include "ash/session/session_controller_impl.h"
 #include "ash/shell.h"
 #include "ash/test/ash_test_base.h"
 #include "ash/wm/tablet_mode/tablet_mode_controller.h"
 #include "base/callback.h"
-#include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
 #include "ui/views/controls/button/label_button.h"
 #include "ui/wm/core/window_util.h"
@@ -46,12 +44,7 @@
 class AppListNudgeControllerTest : public AshTestBase {
  public:
   AppListNudgeControllerTest()
-      : AshTestBase(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {
-    scoped_feature_list_.InitWithFeatures(
-        {features::kLauncherAppSort, features::kProductivityLauncher,
-         features::kLauncherDismissButtonsOnSortNudgeAndToast},
-        {});
-  }
+      : AshTestBase(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
   AppListNudgeControllerTest(const AppListNudgeControllerTest&) = delete;
   AppListNudgeControllerTest& operator=(const AppListNudgeControllerTest&) =
       delete;
@@ -91,9 +84,6 @@
   }
 
   void DismissAppList() { GetAppListTestHelper()->Dismiss(); }
-
- private:
-  base::test::ScopedFeatureList scoped_feature_list_;
 };
 
 TEST_F(AppListNudgeControllerTest, Basic) {
diff --git a/ash/app_list/views/continue_section_view_unittest.cc b/ash/app_list/views/continue_section_view_unittest.cc
index c2e180a0..e1c0b45 100644
--- a/ash/app_list/views/continue_section_view_unittest.cc
+++ b/ash/app_list/views/continue_section_view_unittest.cc
@@ -25,16 +25,13 @@
 #include "ash/app_list/views/recent_apps_view.h"
 #include "ash/app_list/views/scrollable_apps_grid_view.h"
 #include "ash/app_list/views/search_box_view.h"
-#include "ash/constants/ash_features.h"
 #include "ash/constants/ash_pref_names.h"
-#include "ash/public/cpp/app_list/app_list_features.h"
 #include "ash/public/cpp/app_list/app_list_types.h"
 #include "ash/session/session_controller_impl.h"
 #include "ash/shell.h"
 #include "ash/test/ash_test_base.h"
 #include "base/run_loop.h"
 #include "base/test/metrics/histogram_tester.h"
-#include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -94,10 +91,7 @@
  public:
   explicit ContinueSectionViewTestBase(bool tablet_mode)
       : AshTestBase(base::test::TaskEnvironment::TimeSource::MOCK_TIME),
-        tablet_mode_(tablet_mode) {
-    scoped_feature_list_.InitWithFeatures(
-        {features::kLauncherAppSort, features::kProductivityLauncher}, {});
-  }
+        tablet_mode_(tablet_mode) {}
   ~ContinueSectionViewTestBase() override = default;
 
   void TearDown() override {
@@ -304,7 +298,6 @@
 
   absl::optional<ui::ScopedAnimationDurationScaleMode> animation_duration_;
   std::unique_ptr<test::AppsGridViewTestApi> test_api_;
-  base::test::ScopedFeatureList scoped_feature_list_;
 };
 
 class ContinueSectionViewTest : public ContinueSectionViewTestBase,
diff --git a/ash/app_list/views/recent_apps_view_unittest.cc b/ash/app_list/views/recent_apps_view_unittest.cc
index 5d42bc88..b0bb2ad2 100644
--- a/ash/app_list/views/recent_apps_view_unittest.cc
+++ b/ash/app_list/views/recent_apps_view_unittest.cc
@@ -20,12 +20,10 @@
 #include "ash/app_list/views/apps_grid_view_test_api.h"
 #include "ash/app_list/views/paged_apps_grid_view.h"
 #include "ash/app_list/views/scrollable_apps_grid_view.h"
-#include "ash/constants/ash_features.h"
 #include "ash/public/cpp/app_list/app_list_types.h"
 #include "ash/shell.h"
 #include "ash/test/ash_test_base.h"
 #include "base/strings/stringprintf.h"
-#include "base/test/scoped_feature_list.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gfx/geometry/point.h"
 #include "ui/gfx/geometry/rect.h"
@@ -51,9 +49,7 @@
 class RecentAppsViewTest : public AshTestBase,
                            public testing::WithParamInterface<bool> {
  public:
-  RecentAppsViewTest() {
-    scoped_feature_list_.InitAndEnableFeature(features::kProductivityLauncher);
-  }
+  RecentAppsViewTest() = default;
   ~RecentAppsViewTest() override = default;
 
   // Whether we should run the test in tablet mode.
@@ -138,7 +134,6 @@
   }
 
   std::unique_ptr<test::AppsGridViewTestApi> test_api_;
-  base::test::ScopedFeatureList scoped_feature_list_;
 };
 INSTANTIATE_TEST_SUITE_P(All, RecentAppsViewTest, testing::Bool());
 
diff --git a/ash/capture_mode/capture_mode_demo_tools_controller.cc b/ash/capture_mode/capture_mode_demo_tools_controller.cc
index 938be17..b76743b 100644
--- a/ash/capture_mode/capture_mode_demo_tools_controller.cc
+++ b/ash/capture_mode/capture_mode_demo_tools_controller.cc
@@ -4,17 +4,26 @@
 
 #include "ash/capture_mode/capture_mode_demo_tools_controller.h"
 
+#include <memory>
+
+#include "ash/capture_mode/key_combo_view.h"
+#include "ash/capture_mode/video_recording_watcher.h"
 #include "base/check_op.h"
 #include "base/containers/contains.h"
+#include "ui/compositor/layer.h"
 #include "ui/events/event.h"
 #include "ui/events/event_constants.h"
 #include "ui/events/keycodes/keyboard_codes_posix.h"
 #include "ui/events/types/event_type.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/views/widget/widget.h"
 
 namespace ash {
 
 namespace {
 
+constexpr int kDistanceFromBottom = 30;
+
 int GetModifierFlagForKeyCode(ui::KeyboardCode key_code) {
   switch (key_code) {
     case ui::VKEY_COMMAND:
@@ -49,9 +58,21 @@
   return base::Contains(kNotNeedingModifierKeys, key_code);
 }
 
+views::Widget::InitParams CreateWidgetParams(
+    VideoRecordingWatcher* video_recording_watcher) {
+  views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
+  params.parent =
+      video_recording_watcher->GetOnCaptureSurfaceWidgetParentWindow();
+  params.child = true;
+  params.name = "CaptureModeDemoToolsWidget";
+  return params;
+}
+
 }  // namespace
 
-CaptureModeDemoToolsController::CaptureModeDemoToolsController() = default;
+CaptureModeDemoToolsController::CaptureModeDemoToolsController(
+    VideoRecordingWatcher* video_recording_watcher)
+    : video_recording_watcher_(video_recording_watcher) {}
 
 CaptureModeDemoToolsController::~CaptureModeDemoToolsController() = default;
 
@@ -77,6 +98,10 @@
 
 void CaptureModeDemoToolsController::OnKeyDownEvent(ui::KeyEvent* event) {
   const ui::KeyboardCode key_code = event->key_code();
+  // Return directly if it is a repeated key event for non-modifier key.
+  if (key_code == last_non_modifier_key_)
+    return;
+
   const int modifier_flag = GetModifierFlagForKeyCode(key_code);
   modifiers_ |= modifier_flag;
 
@@ -87,8 +112,35 @@
 }
 
 void CaptureModeDemoToolsController::RefreshKeyComboViewer() {
-  demo_tools_widget_ =
-      (modifiers_ != 0) || ShouldConsiderKey(last_non_modifier_key_);
+  if ((modifiers_ == 0) && !ShouldConsiderKey(last_non_modifier_key_)) {
+    demo_tools_widget_.reset();
+    key_combo_view_ = nullptr;
+    return;
+  }
+
+  if (!demo_tools_widget_) {
+    demo_tools_widget_ = std::make_unique<views::Widget>();
+    demo_tools_widget_->Init(CreateWidgetParams(video_recording_watcher_));
+    key_combo_view_ =
+        demo_tools_widget_->SetContentsView(std::make_unique<KeyComboView>());
+    ui::Layer* layer = demo_tools_widget_->GetLayer();
+    layer->SetFillsBoundsOpaquely(false);
+    layer->SetMasksToBounds(true);
+    demo_tools_widget_->Show();
+  }
+
+  key_combo_view_->RefreshView(modifiers_, last_non_modifier_key_);
+  demo_tools_widget_->SetBounds(CalculateBounds());
+}
+
+gfx::Rect CaptureModeDemoToolsController::CalculateBounds() const {
+  const gfx::Size preferred_size = key_combo_view_->GetPreferredSize();
+  auto bounds = video_recording_watcher_->GetCaptureSurfaceConfineBounds();
+  int demo_tools_y =
+      bounds.bottom() - kDistanceFromBottom - preferred_size.height();
+  bounds.ClampToCenteredSize(preferred_size);
+  bounds.set_y(demo_tools_y);
+  return bounds;
 }
 
 }  // namespace ash
\ No newline at end of file
diff --git a/ash/capture_mode/capture_mode_demo_tools_controller.h b/ash/capture_mode/capture_mode_demo_tools_controller.h
index a2cd4b2..747ef74 100644
--- a/ash/capture_mode/capture_mode_demo_tools_controller.h
+++ b/ash/capture_mode/capture_mode_demo_tools_controller.h
@@ -6,6 +6,7 @@
 #define ASH_CAPTURE_MODE_CAPTURE_MODE_DEMO_TOOLS_CONTROLLER_H_
 
 #include "ui/events/keycodes/keyboard_codes_posix.h"
+#include "ui/views/widget/unique_widget_ptr.h"
 
 namespace ui {
 class KeyEvent;
@@ -13,6 +14,9 @@
 
 namespace ash {
 
+class KeyComboView;
+class VideoRecordingWatcher;
+
 // Observes and decides whether to show a helper widget representing the
 // currently pressed key combination or not. The key combination will be used to
 // construct or modify the `KeyComboViewer`. The
@@ -20,7 +24,8 @@
 // recording and has to be explicitly enabled by the user.
 class CaptureModeDemoToolsController {
  public:
-  CaptureModeDemoToolsController();
+  explicit CaptureModeDemoToolsController(
+      VideoRecordingWatcher* video_recording_watcher);
   CaptureModeDemoToolsController(const CaptureModeDemoToolsController&) =
       delete;
   CaptureModeDemoToolsController& operator=(
@@ -30,23 +35,21 @@
   // Decides whether to show a helper widget for the `event` or not.
   void OnKeyEvent(ui::KeyEvent* event);
 
-  bool demo_tools_widget_for_testing() const { return demo_tools_widget_; }
-  int modifiers_for_testing() const { return modifiers_; }
-  ui::KeyboardCode last_non_modifier_key_for_testing() const {
-    return last_non_modifier_key_;
-  }
-
  private:
+  friend class CaptureModeDemoToolsTestApi;
+
   void OnKeyUpEvent(ui::KeyEvent* event);
   void OnKeyDownEvent(ui::KeyEvent* event);
 
-  // Refresh the state of the key combo viewer based on the current state of
+  // Refreshes the state of the `key_combo_view_` based on the current state of
   // `modifiers_` and `last_non_modifier_key_`.
   void RefreshKeyComboViewer();
 
-  // TODO(https://crbug.com/1356362): Remove this and replace it with the actual
-  // demo tools widget. This was added temporarily for testing purpose.
-  bool demo_tools_widget_ = false;
+  gfx::Rect CalculateBounds() const;
+
+  VideoRecordingWatcher* const video_recording_watcher_;
+  views::UniqueWidgetPtr demo_tools_widget_;
+  KeyComboView* key_combo_view_ = nullptr;
 
   // The state of the modifier keys i.e. Shift/Ctrl/Alt/Launcher keys.
   int modifiers_ = 0;
diff --git a/ash/capture_mode/capture_mode_demo_tools_test_api.cc b/ash/capture_mode/capture_mode_demo_tools_test_api.cc
new file mode 100644
index 0000000..bb64fa4
--- /dev/null
+++ b/ash/capture_mode/capture_mode_demo_tools_test_api.cc
@@ -0,0 +1,56 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/capture_mode/capture_mode_demo_tools_test_api.h"
+
+#include <vector>
+
+#include "ash/capture_mode/capture_mode_demo_tools_controller.h"
+#include "ash/capture_mode/key_combo_view.h"
+#include "ui/events/keycodes/keyboard_codes_posix.h"
+
+namespace ash {
+
+CaptureModeDemoToolsTestApi::CaptureModeDemoToolsTestApi(
+    CaptureModeDemoToolsController* demo_tools_controller)
+    : demo_tools_controller_(demo_tools_controller) {}
+
+views::Widget* CaptureModeDemoToolsTestApi::GetDemoToolsWidget() {
+  return demo_tools_controller_->demo_tools_widget_.get();
+}
+
+KeyComboView* CaptureModeDemoToolsTestApi::GetKeyComboView() {
+  return demo_tools_controller_->key_combo_view_;
+}
+
+int CaptureModeDemoToolsTestApi::GetCurrentModifiersFlags() {
+  return demo_tools_controller_->modifiers_;
+}
+
+ui::KeyboardCode CaptureModeDemoToolsTestApi::GetLastNonModifierKey() {
+  return demo_tools_controller_->last_non_modifier_key_;
+}
+
+std::vector<ui::KeyboardCode>
+CaptureModeDemoToolsTestApi::GetShownModifiersKeyCodes() {
+  DCHECK(demo_tools_controller_);
+  KeyComboView* key_combo_view = demo_tools_controller_->key_combo_view_;
+
+  if (!key_combo_view || !key_combo_view->modifiers_container_view_)
+    return std::vector<ui::KeyboardCode>();
+
+  return key_combo_view->GetModifierKeycodeVector();
+}
+
+ui::KeyboardCode CaptureModeDemoToolsTestApi::GetShownNonModifierKeyCode() {
+  DCHECK(demo_tools_controller_);
+  KeyComboView* key_combo_view = demo_tools_controller_->key_combo_view_;
+
+  if (key_combo_view == nullptr)
+    return ui::VKEY_UNKNOWN;
+
+  return key_combo_view->last_non_modifier_key_;
+}
+
+}  // namespace ash
\ No newline at end of file
diff --git a/ash/capture_mode/capture_mode_demo_tools_test_api.h b/ash/capture_mode/capture_mode_demo_tools_test_api.h
new file mode 100644
index 0000000..f7a7a75
--- /dev/null
+++ b/ash/capture_mode/capture_mode_demo_tools_test_api.h
@@ -0,0 +1,54 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_CAPTURE_MODE_CAPTURE_MODE_DEMO_TOOLS_TEST_API_H_
+#define ASH_CAPTURE_MODE_CAPTURE_MODE_DEMO_TOOLS_TEST_API_H_
+
+#include <vector>
+
+#include "ui/events/keycodes/keyboard_codes_posix.h"
+
+namespace views {
+class Widget;
+}  // namespace views
+
+namespace ash {
+
+class CaptureModeDemoToolsController;
+class KeyComboView;
+
+class CaptureModeDemoToolsTestApi {
+ public:
+  explicit CaptureModeDemoToolsTestApi(
+      CaptureModeDemoToolsController* demo_tools_controller);
+  CaptureModeDemoToolsTestApi(CaptureModeDemoToolsTestApi&) = delete;
+  CaptureModeDemoToolsTestApi& operator=(CaptureModeDemoToolsTestApi) = delete;
+  ~CaptureModeDemoToolsTestApi() = default;
+
+  views::Widget* GetDemoToolsWidget();
+
+  // Returns the contents view for the `demo_tools_widget_`.
+  KeyComboView* GetKeyComboView();
+
+  // Returns the state of modifier keys in the `CaptureModeDemoToolsController`.
+  int GetCurrentModifiersFlags();
+
+  // Returns the most recently pressed non-modifier key in the
+  // `CaptureModeDemoToolsController`.
+  ui::KeyboardCode GetLastNonModifierKey();
+
+  // Returns the key code vector in the `ModifiersContainerView` of the
+  // `KeyComboView`.
+  std::vector<ui::KeyboardCode> GetShownModifiersKeyCodes();
+
+  // Returns the non-modifier key that is currently on display.
+  ui::KeyboardCode GetShownNonModifierKeyCode();
+
+ private:
+  CaptureModeDemoToolsController* const demo_tools_controller_;
+};
+
+}  // namespace ash
+
+#endif  // ASH_CAPTURE_MODE_CAPTURE_MODE_DEMO_TOOLS_TEST_API_H_
\ No newline at end of file
diff --git a/ash/capture_mode/capture_mode_demo_tools_unittests.cc b/ash/capture_mode/capture_mode_demo_tools_unittests.cc
index f63d857..ce4c8cf 100644
--- a/ash/capture_mode/capture_mode_demo_tools_unittests.cc
+++ b/ash/capture_mode/capture_mode_demo_tools_unittests.cc
@@ -2,15 +2,19 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <vector>
+
 #include "ash/capture_mode/capture_mode_bar_view.h"
 #include "ash/capture_mode/capture_mode_controller.h"
 #include "ash/capture_mode/capture_mode_demo_tools_controller.h"
+#include "ash/capture_mode/capture_mode_demo_tools_test_api.h"
 #include "ash/capture_mode/capture_mode_menu_toggle_button.h"
 #include "ash/capture_mode/capture_mode_session_test_api.h"
 #include "ash/capture_mode/capture_mode_settings_test_api.h"
 #include "ash/capture_mode/capture_mode_settings_view.h"
 #include "ash/capture_mode/capture_mode_test_util.h"
 #include "ash/capture_mode/capture_mode_types.h"
+#include "ash/capture_mode/key_combo_view.h"
 #include "ash/constants/ash_features.h"
 #include "ash/style/icon_button.h"
 #include "ash/test/ash_test_base.h"
@@ -33,7 +37,7 @@
   void SetUp() override {
     scoped_feature_list_.InitAndEnableFeature(features::kCaptureModeDemoTools);
     AshTestBase::SetUp();
-    window_ = CreateTestWindow(gfx::Rect(100, 200, 500, 600));
+    window_ = CreateTestWindow(gfx::Rect(20, 30, 601, 300));
   }
 
   void TearDown() override {
@@ -41,19 +45,7 @@
     AshTestBase::TearDown();
   }
 
-  CaptureModeController* StartVideoRecordingWithGivenSource(
-      CaptureModeSource source) {
-    auto* controller = CaptureModeController::Get();
-    const gfx::Rect capture_region(30, 50, 200, 500);
-    controller->SetUserCaptureRegion(capture_region, true);
-    StartCaptureSession(source, CaptureModeType::kVideo);
-
-    if (source == CaptureModeSource::kWindow)
-      GetEventGenerator()->MoveMouseToCenterOf(window_.get());
-
-    StartVideoRecordingImmediately();
-    return controller;
-  }
+  aura::Window* window() const { return window_.get(); }
 
   IconButton* GetSettingsButton() const {
     return GetCaptureModeBarView()->settings_button();
@@ -103,33 +95,35 @@
   // Press the 'A' key and the event will not be considered to generate a
   // corresponding key widget.
   event_generator->PressKey(ui::VKEY_A, ui::EF_NONE);
-  EXPECT_FALSE(demo_tools_controller->demo_tools_widget_for_testing());
+  CaptureModeDemoToolsTestApi capture_mode_demo_tools_test_api(
+      demo_tools_controller);
+  EXPECT_FALSE(capture_mode_demo_tools_test_api.GetDemoToolsWidget());
   event_generator->ReleaseKey(ui::VKEY_A, ui::EF_NONE);
-  EXPECT_EQ(demo_tools_controller->modifiers_for_testing(), 0);
-  EXPECT_EQ(demo_tools_controller->last_non_modifier_key_for_testing(),
+  EXPECT_EQ(capture_mode_demo_tools_test_api.GetCurrentModifiersFlags(), 0);
+  EXPECT_EQ(capture_mode_demo_tools_test_api.GetLastNonModifierKey(),
             ui::VKEY_UNKNOWN);
 
   // Press Ctrl + A the key event will be considered to generate a
   // corresponding key widget.
   event_generator->PressKey(ui::VKEY_A, ui::EF_NONE);
   event_generator->PressKey(ui::VKEY_CONTROL, ui::EF_NONE);
-  EXPECT_TRUE(demo_tools_controller->demo_tools_widget_for_testing());
-  EXPECT_EQ(demo_tools_controller->modifiers_for_testing(),
+  EXPECT_TRUE(capture_mode_demo_tools_test_api.GetDemoToolsWidget());
+  EXPECT_EQ(capture_mode_demo_tools_test_api.GetCurrentModifiersFlags(),
             ui::EF_CONTROL_DOWN);
-  EXPECT_EQ(demo_tools_controller->last_non_modifier_key_for_testing(),
+  EXPECT_EQ(capture_mode_demo_tools_test_api.GetLastNonModifierKey(),
             ui::VKEY_A);
 
   event_generator->ReleaseKey(ui::VKEY_A, ui::EF_NONE);
   event_generator->ReleaseKey(ui::VKEY_CONTROL, ui::EF_NONE);
-  EXPECT_FALSE(demo_tools_controller->demo_tools_widget_for_testing());
-  EXPECT_EQ(demo_tools_controller->modifiers_for_testing(), 0);
-  EXPECT_EQ(demo_tools_controller->last_non_modifier_key_for_testing(),
+  EXPECT_FALSE(capture_mode_demo_tools_test_api.GetDemoToolsWidget());
+  EXPECT_EQ(capture_mode_demo_tools_test_api.GetCurrentModifiersFlags(), 0);
+  EXPECT_EQ(capture_mode_demo_tools_test_api.GetLastNonModifierKey(),
             ui::VKEY_UNKNOWN);
 
   event_generator->PressKey(ui::VKEY_TAB, ui::EF_NONE);
-  EXPECT_TRUE(demo_tools_controller->demo_tools_widget_for_testing());
-  EXPECT_EQ(demo_tools_controller->modifiers_for_testing(), 0);
-  EXPECT_EQ(demo_tools_controller->last_non_modifier_key_for_testing(),
+  EXPECT_TRUE(capture_mode_demo_tools_test_api.GetDemoToolsWidget());
+  EXPECT_EQ(capture_mode_demo_tools_test_api.GetCurrentModifiersFlags(), 0);
+  EXPECT_EQ(capture_mode_demo_tools_test_api.GetLastNonModifierKey(),
             ui::VKEY_TAB);
 }
 
@@ -160,7 +154,9 @@
   CaptureModeDemoToolsController* demo_tools_controller =
       GetCaptureModeDemoToolsController();
   EXPECT_TRUE(demo_tools_controller);
-  EXPECT_TRUE(demo_tools_controller->demo_tools_widget_for_testing());
+  CaptureModeDemoToolsTestApi capture_mode_demo_tools_test_api(
+      demo_tools_controller);
+  EXPECT_TRUE(capture_mode_demo_tools_test_api.GetDemoToolsWidget());
   controller->EndVideoRecording(EndRecordingReason::kStopRecordingButton);
   WaitForCaptureFileToBeSaved();
   EXPECT_FALSE(controller->IsActive());
@@ -183,4 +179,128 @@
   EXPECT_FALSE(GetCaptureModeDemoToolsController());
 }
 
+// Tests that the key combo viewer widget displays the expected contents on key
+// event and the modifier key should always be displayed before the non-modifier
+// key. With no modifier keys or no non-modifier key that can be displayed
+// independently, the key combo widget will not be displayed.
+TEST_F(CaptureModeDemoToolsTest, KeyComboWidgetTest) {
+  CaptureModeController* controller = StartCaptureSession(
+      CaptureModeSource::kFullscreen, CaptureModeType::kVideo);
+  controller->EnableDemoTools(true);
+  StartVideoRecordingImmediately();
+  EXPECT_TRUE(controller->is_recording_in_progress());
+  auto* event_generator = GetEventGenerator();
+  event_generator->PressKey(ui::VKEY_CONTROL, ui::EF_NONE);
+  event_generator->PressKey(ui::VKEY_C, ui::EF_NONE);
+  CaptureModeDemoToolsController* demo_tools_controller =
+      GetCaptureModeDemoToolsController();
+  EXPECT_TRUE(demo_tools_controller);
+  CaptureModeDemoToolsTestApi capture_mode_demo_tools_test_api(
+      demo_tools_controller);
+  EXPECT_TRUE(capture_mode_demo_tools_test_api.GetDemoToolsWidget());
+  EXPECT_TRUE(capture_mode_demo_tools_test_api.GetKeyComboView());
+  std::vector<ui::KeyboardCode> expected_modifier_key_vector = {
+      ui::VKEY_CONTROL};
+  EXPECT_EQ(capture_mode_demo_tools_test_api.GetShownModifiersKeyCodes(),
+            expected_modifier_key_vector);
+  EXPECT_EQ(capture_mode_demo_tools_test_api.GetShownNonModifierKeyCode(),
+            ui::VKEY_C);
+
+  // Press the key 'Shift' at last, but it will still show before the 'C' key.
+  event_generator->PressKey(ui::VKEY_SHIFT, ui::EF_NONE);
+  expected_modifier_key_vector = {ui::VKEY_CONTROL, ui::VKEY_SHIFT};
+  EXPECT_TRUE(capture_mode_demo_tools_test_api.GetShownModifiersKeyCodes() ==
+              expected_modifier_key_vector);
+  EXPECT_EQ(capture_mode_demo_tools_test_api.GetShownNonModifierKeyCode(),
+            ui::VKEY_C);
+
+  // Release the modifier keys, and the key combo view will not be displayed.
+  event_generator->ReleaseKey(ui::VKEY_SHIFT, ui::EF_NONE);
+  event_generator->ReleaseKey(ui::VKEY_CONTROL, ui::EF_NONE);
+  EXPECT_FALSE(capture_mode_demo_tools_test_api.GetDemoToolsWidget());
+}
+
+class CaptureModeDemoToolsTestWithAllSources
+    : public CaptureModeDemoToolsTest,
+      public testing::WithParamInterface<CaptureModeSource> {
+ public:
+  CaptureModeDemoToolsTestWithAllSources() = default;
+  CaptureModeDemoToolsTestWithAllSources(
+      const CaptureModeDemoToolsTestWithAllSources&) = delete;
+  CaptureModeDemoToolsTestWithAllSources& operator=(
+      const CaptureModeDemoToolsTestWithAllSources&) = delete;
+  ~CaptureModeDemoToolsTestWithAllSources() override = default;
+
+  CaptureModeController* StartDemoToolsEnabledVideoRecordingWithParam() {
+    auto* controller = CaptureModeController::Get();
+    const gfx::Rect capture_region(100, 200, 300, 400);
+    controller->SetUserCaptureRegion(capture_region, /*by_user=*/true);
+
+    StartCaptureSession(GetParam(), CaptureModeType::kVideo);
+    controller->EnableDemoTools(true);
+
+    if (GetParam() == CaptureModeSource::kWindow)
+      GetEventGenerator()->MoveMouseToCenterOf(window());
+
+    StartVideoRecordingImmediately();
+    EXPECT_TRUE(controller->is_recording_in_progress());
+    return controller;
+  }
+};
+
+// Tests that the key combo viewer widget should be centered within its confined
+// bounds.
+TEST_P(CaptureModeDemoToolsTestWithAllSources,
+       KeyComboViewerShouldBeCenteredTest) {
+  auto* controller = StartDemoToolsEnabledVideoRecordingWithParam();
+  auto* demo_tools_controller = GetCaptureModeDemoToolsController();
+  EXPECT_TRUE(demo_tools_controller);
+
+  auto* recording_watcher =
+      CaptureModeController::Get()->video_recording_watcher_for_testing();
+  gfx::Rect confined_bounds_in_screen =
+      recording_watcher->GetCaptureSurfaceConfineBounds();
+
+  // Converts the bounds if it is in the window's coordinate to screen
+  // coordinate.
+  if (GetParam() == CaptureModeSource::kWindow) {
+    auto window_bounds = window()->GetBoundsInScreen();
+    confined_bounds_in_screen.Offset(window_bounds.x(), window_bounds.y());
+  }
+
+  // Verifies that the `demo_tools_widget` is positioned in the middle
+  // horizontally within the confined bounds.
+  auto verify_demo_tools_been_centered = [&]() {
+    CaptureModeDemoToolsTestApi capture_mode_demo_tools_test_api(
+        demo_tools_controller);
+    auto* demo_tools_widget =
+        capture_mode_demo_tools_test_api.GetDemoToolsWidget();
+    ASSERT_TRUE(demo_tools_widget);
+    const gfx::Rect demo_tools_widget_bounds =
+        demo_tools_widget->GetWindowBoundsInScreen();
+    EXPECT_TRUE(abs(confined_bounds_in_screen.CenterPoint().x() -
+                    demo_tools_widget_bounds.CenterPoint().x()) <= 1);
+  };
+
+  auto* event_generator = GetEventGenerator();
+  event_generator->PressKey(ui::VKEY_CONTROL, ui::EF_NONE);
+  verify_demo_tools_been_centered();
+
+  event_generator->PressKey(ui::VKEY_SHIFT, ui::EF_NONE);
+  verify_demo_tools_been_centered();
+
+  event_generator->PressKey(ui::VKEY_A, ui::EF_NONE);
+  verify_demo_tools_been_centered();
+
+  controller->EndVideoRecording(EndRecordingReason::kStopRecordingButton);
+  WaitForCaptureFileToBeSaved();
+  EXPECT_FALSE(controller->IsActive());
+}
+
+INSTANTIATE_TEST_SUITE_P(All,
+                         CaptureModeDemoToolsTestWithAllSources,
+                         testing::Values(CaptureModeSource::kFullscreen,
+                                         CaptureModeSource::kRegion,
+                                         CaptureModeSource::kWindow));
+
 }  // namespace ash
diff --git a/ash/capture_mode/key_combo_view.cc b/ash/capture_mode/key_combo_view.cc
new file mode 100644
index 0000000..bb2eee4
--- /dev/null
+++ b/ash/capture_mode/key_combo_view.cc
@@ -0,0 +1,153 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/capture_mode/key_combo_view.h"
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "ash/accelerators/keyboard_code_util.h"
+#include "ash/capture_mode/key_item_view.h"
+#include "key_item_view.h"
+#include "ui/base/metadata/metadata_impl_macros.h"
+#include "ui/events/event_constants.h"
+#include "ui/events/keycodes/keyboard_codes_posix.h"
+#include "ui/gfx/vector_icon_types.h"
+#include "ui/views/layout/box_layout.h"
+#include "ui/views/view.h"
+
+namespace ash {
+
+namespace {
+
+constexpr auto kBetweenKeyItemSpace = 10;
+constexpr auto kPadding = gfx::Insets::VH(8, 6);
+
+std::vector<ui::KeyboardCode> DecodeModifiers(int modifiers) {
+  std::vector<ui::KeyboardCode> modifier_vector;
+  if (modifiers == 0)
+    return modifier_vector;
+
+  if ((modifiers & ui::EF_COMMAND_DOWN) != 0)
+    modifier_vector.push_back(ui::VKEY_COMMAND);
+  if ((modifiers & ui::EF_CONTROL_DOWN) != 0)
+    modifier_vector.push_back(ui::VKEY_CONTROL);
+  if ((modifiers & ui::EF_ALT_DOWN) != 0)
+    modifier_vector.push_back(ui::VKEY_MENU);
+  if ((modifiers & ui::EF_SHIFT_DOWN) != 0)
+    modifier_vector.push_back(ui::VKEY_SHIFT);
+
+  return modifier_vector;
+}
+
+void ToUpper(std::u16string& str) {
+  for (auto& ch : str)
+    ch = toupper(ch);
+}
+
+std::unique_ptr<views::View> CreateKeyItemView(ui::KeyboardCode key_code) {
+  std::unique_ptr key_item_view = std::make_unique<KeyItemView>();
+  const gfx::VectorIcon* vector_icon = GetVectorIconForKeyboardCode(key_code);
+  if (vector_icon) {
+    key_item_view->SetIcon(*vector_icon);
+  } else {
+    std::u16string key_item_string =
+        GetStringForKeyboardCode(key_code, /*remap_positional_key=*/false);
+    ToUpper(key_item_string);
+    key_item_view->SetText(key_item_string);
+  }
+  return key_item_view;
+}
+
+}  // namespace
+
+// -----------------------------------------------------------------------------
+// ModifiersContainerView:
+
+// The container view that hosts the modifiers key item views.
+class ModifiersContainerView : public views::View {
+ public:
+  METADATA_HEADER(ModifiersContainerView);
+
+  explicit ModifiersContainerView() {
+    views::BoxLayout* layout_manager =
+        SetLayoutManager(std::make_unique<views::BoxLayout>(
+            views::BoxLayout::Orientation::kHorizontal, gfx::Insets::VH(0, 0),
+            kBetweenKeyItemSpace));
+    layout_manager->set_cross_axis_alignment(
+        views::BoxLayout::CrossAxisAlignment::kCenter);
+  }
+
+  ModifiersContainerView(const ModifiersContainerView&) = delete;
+  ModifiersContainerView& operator=(const ModifiersContainerView&) = delete;
+  ~ModifiersContainerView() override = default;
+
+  const std::vector<ui::KeyboardCode>& modifier_key_codes() const {
+    return modifier_key_codes_;
+  }
+
+  // Rebuilds the modifier container view based on the given `modifiers`.
+  void RebuildModifiersContainerView(int modifiers) {
+    RemoveAllChildViews();
+    modifier_key_codes_ = DecodeModifiers(modifiers);
+    for (auto key_code : modifier_key_codes_) {
+      AddChildView((CreateKeyItemView(key_code)));
+    }
+  }
+
+ private:
+  std::vector<ui::KeyboardCode> modifier_key_codes_;
+};
+
+BEGIN_METADATA(ModifiersContainerView, views::View)
+END_METADATA
+
+// -----------------------------------------------------------------------------
+// KeyComboView:
+
+KeyComboView::KeyComboView() {
+  SetLayoutManager(std::make_unique<views::BoxLayout>(
+      views::BoxLayout::Orientation::kHorizontal, kPadding,
+      kBetweenKeyItemSpace));
+}
+
+KeyComboView::~KeyComboView() = default;
+
+void KeyComboView::RefreshView(int modifiers,
+                               ui::KeyboardCode last_non_modifier_key) {
+  if (modifiers_ != modifiers) {
+    modifiers_ = modifiers;
+    if (!modifiers_container_view_) {
+      modifiers_container_view_ = AddChildViewAt(
+          std::make_unique<ModifiersContainerView>(), /*index=*/0);
+    }
+
+    modifiers_container_view_->RebuildModifiersContainerView(modifiers_);
+  }
+
+  if (last_non_modifier_key != last_non_modifier_key_) {
+    last_non_modifier_key_ = last_non_modifier_key;
+    if (non_modifier_view_) {
+      RemoveChildViewT(non_modifier_view_);
+      non_modifier_view_ = nullptr;
+    }
+
+    if (last_non_modifier_key != ui::VKEY_UNKNOWN) {
+      non_modifier_view_ =
+          AddChildView(CreateKeyItemView(last_non_modifier_key_));
+    }
+  }
+}
+
+std::vector<ui::KeyboardCode> KeyComboView::GetModifierKeycodeVector() const {
+  return modifiers_container_view_
+             ? modifiers_container_view_->modifier_key_codes()
+             : std::vector<ui::KeyboardCode>();
+}
+
+BEGIN_METADATA(KeyComboView, views::View)
+END_METADATA
+
+}  // namespace ash
\ No newline at end of file
diff --git a/ash/capture_mode/key_combo_view.h b/ash/capture_mode/key_combo_view.h
new file mode 100644
index 0000000..7ad20f3
--- /dev/null
+++ b/ash/capture_mode/key_combo_view.h
@@ -0,0 +1,50 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_CAPTURE_MODE_KEY_COMBO_VIEW_H_
+#define ASH_CAPTURE_MODE_KEY_COMBO_VIEW_H_
+
+#include <string>
+#include <vector>
+
+#include "ash/ash_export.h"
+#include "ui/events/keycodes/keyboard_codes_posix.h"
+#include "ui/views/view.h"
+
+namespace ash {
+
+class ModifiersContainerView;
+
+// A view that contains the key item widgets that constitute the keyboard
+// shortcuts combo view. The modifier key will always show before the
+// non-modifier key, which will be hosted in the `modifiers_container_view_`.
+class ASH_EXPORT KeyComboView : public views::View {
+ public:
+  METADATA_HEADER(KeyComboView);
+
+  KeyComboView();
+  KeyComboView(const KeyComboView&) = delete;
+  KeyComboView& operator=(const KeyComboView&) = delete;
+  ~KeyComboView() override;
+
+  // Appends or removes a key item view based on the given `modifiers` and
+  // `last_non_modifier_key`.
+  void RefreshView(int modifiers, ui::KeyboardCode last_non_modifier_key);
+
+ private:
+  friend class CaptureModeDemoToolsTestApi;
+
+  // Returns the key code vector in the `ModifiersContainerView`, this function
+  // is needed for testing.
+  std::vector<ui::KeyboardCode> GetModifierKeycodeVector() const;
+
+  int modifiers_ = 0;
+  ui::KeyboardCode last_non_modifier_key_ = ui::VKEY_UNKNOWN;
+  ModifiersContainerView* modifiers_container_view_ = nullptr;
+  views::View* non_modifier_view_ = nullptr;
+};
+
+}  // namespace ash
+
+#endif  // ASH_CAPTURE_MODE_KEY_COMBO_VIEW_H_
\ No newline at end of file
diff --git a/ash/capture_mode/key_item_view.cc b/ash/capture_mode/key_item_view.cc
new file mode 100644
index 0000000..66fc9c2
--- /dev/null
+++ b/ash/capture_mode/key_item_view.cc
@@ -0,0 +1,89 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/capture_mode/key_item_view.h"
+
+#include <memory>
+
+#include "ash/style/ash_color_id.h"
+#include "ui/base/models/image_model.h"
+#include "ui/color/color_provider.h"
+#include "ui/compositor/layer.h"
+#include "ui/gfx/geometry/size.h"
+#include "ui/views/background.h"
+#include "ui/views/border.h"
+#include "ui/views/controls/image_view.h"
+#include "ui/views/controls/label.h"
+
+namespace ash {
+
+namespace {
+
+constexpr int kKeyItemPadding = 4;
+constexpr gfx::Size kIconSize{26, 26};
+constexpr int kKeyItemCornerRadius = 8;
+
+}  // namespace
+
+KeyItemView::KeyItemView() {
+  SetPaintToLayer();
+  layer()->SetFillsBoundsOpaquely(false);
+  SetBorder(views::CreateEmptyBorder(kKeyItemPadding));
+}
+
+KeyItemView::~KeyItemView() = default;
+
+void KeyItemView::OnThemeChanged() {
+  views::View::OnThemeChanged();
+  SetBackground(views::CreateRoundedRectBackground(
+      GetColorProvider()->GetColor(kColorAshShieldAndBase80),
+      kKeyItemCornerRadius));
+}
+
+void KeyItemView::Layout() {
+  const auto bounds = GetContentsBounds();
+  if (icon_)
+    icon_->SetBoundsRect(bounds);
+
+  if (label_)
+    label_->SetBoundsRect(bounds);
+}
+
+gfx::Size KeyItemView::CalculatePreferredSize() const {
+  int width = 0;
+  int height = 0;
+
+  for (const auto* child : children()) {
+    const auto child_size = child->GetPreferredSize();
+    height = std::max(height, child_size.height());
+    width += child_size.width();
+  }
+  const auto insets = GetInsets();
+  return gfx::Size(width + insets.width(), height + insets.height());
+}
+
+void KeyItemView::SetIcon(const gfx::VectorIcon& icon) {
+  if (!icon_) {
+    icon_ = AddChildView(std::make_unique<views::ImageView>());
+    icon_->SetHorizontalAlignment(views::ImageView::Alignment::kCenter);
+    icon_->SetVerticalAlignment(views::ImageView::Alignment::kCenter);
+  }
+
+  icon_->SetImage(
+      ui::ImageModel::FromVectorIcon(icon, kColorAshButtonIconColor));
+  icon_->SetImageSize(kIconSize);
+}
+
+void KeyItemView::SetText(const std::u16string& text) {
+  if (!label_) {
+    label_ = AddChildView(std::make_unique<views::Label>());
+    label_->SetEnabledColor(kColorAshTextColorPrimary);
+    label_->SetElideBehavior(gfx::ElideBehavior::NO_ELIDE);
+    label_->SetFontList(views::Label::GetDefaultFontList().Derive(
+        8, gfx::Font::FontStyle::NORMAL, gfx::Font::Weight::NORMAL));
+  }
+  label_->SetText(text);
+}
+
+}  // namespace ash
diff --git a/ash/capture_mode/key_item_view.h b/ash/capture_mode/key_item_view.h
new file mode 100644
index 0000000..c28ef34
--- /dev/null
+++ b/ash/capture_mode/key_item_view.h
@@ -0,0 +1,42 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_CAPTURE_MODE_KEY_ITEM_VIEW_H_
+#define ASH_CAPTURE_MODE_KEY_ITEM_VIEW_H_
+
+#include "ui/gfx/vector_icon_types.h"
+#include "ui/views/view.h"
+
+namespace views {
+class ImageView;
+class Label;
+}  // namespace views
+
+namespace ash {
+
+// A view that displays a modifier or a key as a rounded corner UI component,
+// which can contain a text label or an icon.
+class KeyItemView : public views::View {
+ public:
+  KeyItemView();
+  KeyItemView(const KeyItemView&) = delete;
+  KeyItemView& operator=(const KeyItemView&) = delete;
+  ~KeyItemView() override;
+
+  // views::View:
+  void OnThemeChanged() override;
+  void Layout() override;
+  gfx::Size CalculatePreferredSize() const override;
+
+  void SetIcon(const gfx::VectorIcon& icon);
+  void SetText(const std::u16string& text);
+
+ private:
+  views::ImageView* icon_ = nullptr;
+  views::Label* label_ = nullptr;
+};
+
+}  // namespace ash
+
+#endif  // ASH_CAPTURE_MODE_KEY_ITEM_VIEW_H_
\ No newline at end of file
diff --git a/ash/capture_mode/recording_overlay_controller.h b/ash/capture_mode/recording_overlay_controller.h
index 5526251..c690306b 100644
--- a/ash/capture_mode/recording_overlay_controller.h
+++ b/ash/capture_mode/recording_overlay_controller.h
@@ -52,7 +52,7 @@
   void Start();
   void Stop();
 
-  // Updates the z-order of the |overlay_widget_|'s native window.
+  // Updates the z-order of the `overlay_widget_`'s native window.
   void UpdateWidgetStacking();
 
   // The overlay widget and its contents view.
diff --git a/ash/capture_mode/video_recording_watcher.cc b/ash/capture_mode/video_recording_watcher.cc
index eee14794..7c3633d 100644
--- a/ash/capture_mode/video_recording_watcher.cc
+++ b/ash/capture_mode/video_recording_watcher.cc
@@ -247,7 +247,8 @@
 
   if (features::AreCaptureModeDemoToolsEnabled() &&
       controller_->enable_demo_tools()) {
-    demo_tools_controller_ = std::make_unique<CaptureModeDemoToolsController>();
+    demo_tools_controller_ =
+        std::make_unique<CaptureModeDemoToolsController>(this);
   }
 
   if (features::IsProjectorEnabled()) {
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc
index cec13683..0cc28026 100644
--- a/ash/constants/ash_features.cc
+++ b/ash/constants/ash_features.cc
@@ -1211,6 +1211,11 @@
              "LacrosSupport",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
+// When this feature is enabled, wayland logging is enabled for Lacros.
+BASE_FEATURE(kLacrosWaylandLogging,
+             "LacrosWaylandLogging",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
 // Emergency switch to turn off profile migration.
 BASE_FEATURE(kLacrosProfileMigrationForceOff,
              "LacrosProfileMigrationForceOff",
@@ -1839,11 +1844,6 @@
              "SmartDimExperimentalComponent",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
-// Disconnects bluetooth connection when screen turns off.
-BASE_FEATURE(kSmartLockBluetoothScreenOffFix,
-             "SmartLockBluetoothScreenOffFix",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
 // Deprecates Sign in with Smart Lock feature. Hides Smart Lock at the sign in
 // screen, removes the Smart Lock subpage in settings, and shows a one-time
 // notification for users who previously had this feature enabled.
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h
index e6051a0..ebaf45b5 100644
--- a/ash/constants/ash_features.h
+++ b/ash/constants/ash_features.h
@@ -347,6 +347,7 @@
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kLacrosOnly);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kLacrosPrimary);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kLacrosSupport);
+COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kLacrosWaylandLogging);
 COMPONENT_EXPORT(ASH_CONSTANTS)
 BASE_DECLARE_FEATURE(kLacrosProfileMigrationForAnyUser);
 COMPONENT_EXPORT(ASH_CONSTANTS)
@@ -520,8 +521,6 @@
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kSimLockPolicy);
 COMPONENT_EXPORT(ASH_CONSTANTS)
 BASE_DECLARE_FEATURE(kSmartDimExperimentalComponent);
-COMPONENT_EXPORT(ASH_CONSTANTS)
-BASE_DECLARE_FEATURE(kSmartLockBluetoothScreenOffFix);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kSmartLockSignInRemoved);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kSmartLockUIRevamp);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kSnapGroup);
diff --git a/ash/system/message_center/ash_notification_view_unittest.cc b/ash/system/message_center/ash_notification_view_unittest.cc
index 820bc5520..c09fd1d8 100644
--- a/ash/system/message_center/ash_notification_view_unittest.cc
+++ b/ash/system/message_center/ash_notification_view_unittest.cc
@@ -14,8 +14,8 @@
 #include "ash/system/message_center/message_center_style.h"
 #include "ash/system/message_center/metrics_utils.h"
 #include "ash/system/message_center/unified_message_center_bubble.h"
-#include "ash/system/message_center/unified_message_center_view.h"
-#include "ash/system/message_center/unified_message_list_view.h"
+#include "ash/system/notification_center/notification_center_view.h"
+#include "ash/system/notification_center/notification_list_view.h"
 #include "ash/system/unified/unified_system_tray.h"
 #include "ash/test/ash_test_base.h"
 #include "base/test/metrics/histogram_tester.h"
@@ -164,8 +164,8 @@
     return static_cast<AshNotificationView*>(
         GetPrimaryUnifiedSystemTray()
             ->message_center_bubble()
-            ->message_center_view()
-            ->message_list_view()
+            ->notification_center_view()
+            ->notification_list_view()
             ->GetMessageViewForNotificationId(std::string(id)));
   }
 
diff --git a/ash/system/message_center/metrics_utils_unittest.cc b/ash/system/message_center/metrics_utils_unittest.cc
index 0310242..5bd039ab 100644
--- a/ash/system/message_center/metrics_utils_unittest.cc
+++ b/ash/system/message_center/metrics_utils_unittest.cc
@@ -7,8 +7,8 @@
 #include "ash/constants/ash_features.h"
 #include "ash/system/message_center/ash_message_popup_collection.h"
 #include "ash/system/message_center/unified_message_center_bubble.h"
-#include "ash/system/message_center/unified_message_center_view.h"
-#include "ash/system/message_center/unified_message_list_view.h"
+#include "ash/system/notification_center/notification_center_view.h"
+#include "ash/system/notification_center/notification_list_view.h"
 #include "ash/system/unified/unified_system_tray.h"
 #include "ash/test/ash_test_base.h"
 #include "base/test/metrics/histogram_tester.h"
@@ -184,8 +184,8 @@
   views::View* GetNotificationViewFromMessageCenter(const std::string& id) {
     return GetPrimaryUnifiedSystemTray()
         ->message_center_bubble()
-        ->message_center_view()
-        ->message_list_view()
+        ->notification_center_view()
+        ->notification_list_view()
         ->GetMessageViewForNotificationId(id);
   }
 
diff --git a/ash/system/message_center/notification_grouping_controller.cc b/ash/system/message_center/notification_grouping_controller.cc
index 19fff0db..34ba1ec8 100644
--- a/ash/system/message_center/notification_grouping_controller.cc
+++ b/ash/system/message_center/notification_grouping_controller.cc
@@ -9,8 +9,8 @@
 #include "ash/system/message_center/message_center_utils.h"
 #include "ash/system/message_center/metrics_utils.h"
 #include "ash/system/message_center/unified_message_center_bubble.h"
-#include "ash/system/message_center/unified_message_center_view.h"
-#include "ash/system/message_center/unified_message_list_view.h"
+#include "ash/system/notification_center/notification_center_view.h"
+#include "ash/system/notification_center/notification_list_view.h"
 #include "ash/system/unified/unified_system_tray.h"
 #include "base/ranges/algorithm.h"
 #include "ui/display/display.h"
@@ -343,11 +343,11 @@
 message_center::NotificationViewController*
 NotificationGroupingController::GetActiveNotificationViewController() {
   if (tray_->IsMessageCenterBubbleShown()) {
-    auto* message_list_view = tray_->message_center_bubble()
-                                  ->message_center_view()
-                                  ->message_list_view();
-    if (message_list_view)
-      return message_list_view;
+    auto* notification_list_view = tray_->message_center_bubble()
+                                       ->notification_center_view()
+                                       ->notification_list_view();
+    if (notification_list_view)
+      return notification_list_view;
   }
   return tray_->GetMessagePopupCollection();
 }
diff --git a/ash/system/message_center/unified_message_center_bubble.cc b/ash/system/message_center/unified_message_center_bubble.cc
index 1c68d3d..24beb130 100644
--- a/ash/system/message_center/unified_message_center_bubble.cc
+++ b/ash/system/message_center/unified_message_center_bubble.cc
@@ -14,7 +14,7 @@
 #include "ash/strings/grit/ash_strings.h"
 #include "ash/style/system_shadow.h"
 #include "ash/system/message_center/message_center_style.h"
-#include "ash/system/message_center/unified_message_center_view.h"
+#include "ash/system/notification_center/notification_center_view.h"
 #include "ash/system/tray/tray_constants.h"
 #include "ash/system/tray/tray_event_filter.h"
 #include "ash/system/tray/tray_utils.h"
@@ -86,14 +86,14 @@
 
   bubble_view_ = new TrayBubbleView(init_params);
 
-  message_center_view_ =
-      bubble_view_->AddChildView(std::make_unique<UnifiedMessageCenterView>(
+  notification_center_view_ =
+      bubble_view_->AddChildView(std::make_unique<NotificationCenterView>(
           nullptr /* parent */, tray->model(), this));
 
   time_to_click_recorder_ =
-      std::make_unique<TimeToClickRecorder>(this, message_center_view_);
+      std::make_unique<TimeToClickRecorder>(this, notification_center_view_);
 
-  message_center_view_->AddObserver(this);
+  notification_center_view_->AddObserver(this);
 }
 
 void UnifiedMessageCenterBubble::ShowBubble() {
@@ -123,7 +123,7 @@
   }
 
   bubble_view_->InitializeAndShowBubble();
-  message_center_view_->Init();
+  notification_center_view_->Init();
   UpdateBubbleState();
 
   tray_->tray_event_filter()->AddBubble(this);
@@ -134,8 +134,8 @@
   if (bubble_widget_) {
     tray_->tray_event_filter()->RemoveBubble(this);
     tray_->bubble()->unified_view()->RemoveObserver(this);
-    CHECK(message_center_view_);
-    message_center_view_->RemoveObserver(this);
+    CHECK(notification_center_view_);
+    notification_center_view_->RemoveObserver(this);
 
     bubble_view_->ResetDelegate();
     bubble_widget_->RemoveObserver(this);
@@ -150,20 +150,20 @@
 }
 
 void UnifiedMessageCenterBubble::CollapseMessageCenter() {
-  if (message_center_view_->collapsed())
+  if (notification_center_view_->collapsed())
     return;
 
-  message_center_view_->SetCollapsed(true /*animate*/);
+  notification_center_view_->SetCollapsed(true /*animate*/);
 }
 
 void UnifiedMessageCenterBubble::ExpandMessageCenter() {
-  if (!message_center_view_->collapsed())
+  if (!notification_center_view_->collapsed())
     return;
 
   if (tray_->IsShowingCalendarView())
     tray_->bubble()->unified_system_tray_controller()->TransitionToMainView(
         /*restore_focus=*/true);
-  message_center_view_->SetExpanded();
+  notification_center_view_->SetExpanded();
   UpdatePosition();
   tray_->EnsureQuickSettingsCollapsed(true /*animate*/);
 }
@@ -171,8 +171,8 @@
 void UnifiedMessageCenterBubble::UpdatePosition() {
   int available_height = CalculateAvailableHeight();
 
-  message_center_view_->SetMaxHeight(available_height);
-  message_center_view_->SetAvailableHeight(available_height);
+  notification_center_view_->SetMaxHeight(available_height);
+  notification_center_view_->SetAvailableHeight(available_height);
 
   if (!tray_->bubble())
     return;
@@ -208,11 +208,11 @@
                     kUnifiedMessageCenterBubbleSpacing);
   bubble_view_->ChangeAnchorRect(anchor_rect);
 
-  message_center_view_->UpdateNotificationBar();
+  notification_center_view_->UpdateNotificationBar();
 
   if (!features::IsNotificationsRefreshEnabled()) {
     bubble_view_->layer()->StackAtTop(border_->layer());
-    border_->layer()->SetBounds(message_center_view_->GetContentsBounds());
+    border_->layer()->SetBounds(notification_center_view_->GetContentsBounds());
   }
 
   if (shadow_) {
@@ -221,12 +221,13 @@
     // than its blur region. To avoid this, we hide the shadow when the message
     // center has no notifications.
     shadow_->GetLayer()->SetVisible(
-        message_center_view_->message_list_view()->GetTotalNotificationCount());
+        notification_center_view_->notification_list_view()
+            ->GetTotalNotificationCount());
   }
 }
 
 void UnifiedMessageCenterBubble::FocusEntered(bool reverse) {
-  message_center_view_->FocusEntered(reverse);
+  notification_center_view_->FocusEntered(reverse);
 }
 
 bool UnifiedMessageCenterBubble::FocusOut(bool reverse) {
@@ -238,12 +239,12 @@
 }
 
 bool UnifiedMessageCenterBubble::IsMessageCenterVisible() {
-  return !!bubble_widget_ && message_center_view_ &&
-         message_center_view_->GetVisible();
+  return !!bubble_widget_ && notification_center_view_ &&
+         notification_center_view_->GetVisible();
 }
 
 bool UnifiedMessageCenterBubble::IsMessageCenterCollapsed() {
-  return message_center_view_->collapsed();
+  return notification_center_view_->collapsed();
 }
 
 TrayBackgroundView* UnifiedMessageCenterBubble::GetTray() const {
@@ -277,7 +278,7 @@
     views::View* starting_view) {
   // Hide the message center widget if the message center is not
   // visible. This is to ensure we do not see an empty bubble.
-  if (observed_view != message_center_view_)
+  if (observed_view != notification_center_view_)
     return;
 
   bubble_view_->UpdateBubble();
@@ -287,7 +288,7 @@
   CHECK_EQ(bubble_widget_, widget);
   tray_->tray_event_filter()->RemoveBubble(this);
   tray_->bubble()->unified_view()->RemoveObserver(this);
-  message_center_view_->RemoveObserver(this);
+  notification_center_view_->RemoveObserver(this);
   bubble_widget_->RemoveObserver(this);
   bubble_widget_ = nullptr;
   shadow_.reset();
@@ -311,15 +312,16 @@
 
 void UnifiedMessageCenterBubble::UpdateBubbleState() {
   if (CalculateAvailableHeight() < kMessageCenterCollapseThreshold &&
-      message_center_view_->message_list_view()->GetTotalNotificationCount()) {
+      notification_center_view_->notification_list_view()
+          ->GetTotalNotificationCount()) {
     if (tray_->IsQuickSettingsExplicitlyExpanded()) {
-      message_center_view_->SetCollapsed(false /*animate*/);
+      notification_center_view_->SetCollapsed(false /*animate*/);
     } else {
-      message_center_view_->SetExpanded();
+      notification_center_view_->SetExpanded();
       tray_->EnsureQuickSettingsCollapsed(false /*animate*/);
     }
-  } else if (message_center_view_->collapsed()) {
-    message_center_view_->SetExpanded();
+  } else if (notification_center_view_->collapsed()) {
+    notification_center_view_->SetExpanded();
   }
 
   UpdatePosition();
diff --git a/ash/system/message_center/unified_message_center_bubble.h b/ash/system/message_center/unified_message_center_bubble.h
index 8bdef3f..8f59310 100644
--- a/ash/system/message_center/unified_message_center_bubble.h
+++ b/ash/system/message_center/unified_message_center_bubble.h
@@ -19,10 +19,10 @@
 namespace ash {
 
 class UnifiedSystemTray;
-class UnifiedMessageCenterView;
+class NotificationCenterView;
 class SystemShadow;
 
-// Manages the bubble that contains UnifiedMessageCenterView.
+// Manages the bubble that contains `NotificationCenterView`.
 // Shows the bubble on `ShowBubble()`, and closes the bubble on the destructor.
 class ASH_EXPORT UnifiedMessageCenterBubble
     : public ScreenLayoutObserver,
@@ -43,9 +43,10 @@
   gfx::Rect GetBoundsInScreen() const;
 
   // We need the code to show the bubble explicitly separated from the
-  // contructor. This is to prevent trigerring the TrayEventFilter from within
-  // the constructor. Doing so can cause a crash when the TrayEventFilter tries
-  // to reference the message center bubble before it is fully instantiated.
+  // constructor. This is to prevent triggering the `TrayEventFilter` from
+  // within the constructor. Doing so can cause a crash when the
+  // `TrayEventFilter` tries to reference the message center bubble before it is
+  // fully instantiated.
   void ShowBubble();
 
   // Collapse the bubble to only have the notification bar visible.
@@ -58,7 +59,7 @@
   // widget whenever the quick settings widget is resized.
   void UpdatePosition();
 
-  // Inform `UnifiedMessageCenterView` of focus being acquired. The oldest
+  // Inform `NotificationCenterView` of focus being acquired. The oldest
   // notification should be focused if `reverse` is `true`. Otherwise, if
   // `reverse` is `false`, the newest notification should be focused.
   void FocusEntered(bool reverse);
@@ -97,8 +98,8 @@
   // ScreenLayoutObserver:
   void OnDisplayConfigurationChanged() override;
 
-  UnifiedMessageCenterView* message_center_view() {
-    return message_center_view_;
+  NotificationCenterView* notification_center_view() {
+    return notification_center_view_;
   }
 
  private:
@@ -113,13 +114,21 @@
   // TimeToClickRecorder::Delegate:
   void RecordTimeToClick() override;
 
+  // Owned by `StatusAreaWidget`.
   UnifiedSystemTray* const tray_;
+
+  // Unowned, the widget is created by a static function in
+  // `BubbleDialogDelegateView`.
+  views::Widget* bubble_widget_ = nullptr;
+
+  // Owned by `bubble_view_`
+  NotificationCenterView* notification_center_view_ = nullptr;
+
+  // Owned by `bubble_widget_`.
+  TrayBubbleView* bubble_view_ = nullptr;
+
   std::unique_ptr<Border> border_;
   std::unique_ptr<SystemShadow> shadow_;
-
-  views::Widget* bubble_widget_ = nullptr;
-  TrayBubbleView* bubble_view_ = nullptr;
-  UnifiedMessageCenterView* message_center_view_ = nullptr;
   std::unique_ptr<TimeToClickRecorder> time_to_click_recorder_;
 };
 
diff --git a/ash/system/message_center/unified_message_center_bubble_unittest.cc b/ash/system/message_center/unified_message_center_bubble_unittest.cc
index 79a21689..3ec023f 100644
--- a/ash/system/message_center/unified_message_center_bubble_unittest.cc
+++ b/ash/system/message_center/unified_message_center_bubble_unittest.cc
@@ -10,7 +10,7 @@
 #include "ash/constants/ash_pref_names.h"
 #include "ash/session/session_controller_impl.h"
 #include "ash/shell.h"
-#include "ash/system/message_center/unified_message_center_view.h"
+#include "ash/system/notification_center/notification_center_view.h"
 #include "ash/system/tray/tray_constants.h"
 #include "ash/system/unified/unified_system_tray.h"
 #include "ash/system/unified/unified_system_tray_bubble.h"
@@ -80,8 +80,8 @@
     message_center::MessageCenter::Get()->RemoveAllNotifications(
         /*by_user=*/true, MessageCenter::RemoveType::ALL);
     GetMessageCenterBubble()
-        ->message_center_view()
-        ->message_list_view()
+        ->notification_center_view()
+        ->notification_list_view()
         ->ResetBounds();
   }
 
@@ -104,7 +104,7 @@
   }
 
   bool IsMessageCenterCollapsed() {
-    return GetMessageCenterBubble()->message_center_view()->collapsed();
+    return GetMessageCenterBubble()->notification_center_view()->collapsed();
   }
 
   bool IsQuickSettingsCollapsed() {
@@ -146,13 +146,13 @@
 
   views::View* GetFirstMessageCenterFocusable() {
     return GetMessageCenterBubble()
-        ->message_center_view()
+        ->notification_center_view()
         ->GetFirstFocusableChild();
   }
 
   views::View* GetLastMessageCenterFocusable() {
     return GetMessageCenterBubble()
-        ->message_center_view()
+        ->notification_center_view()
         ->GetLastFocusableChild();
   }
 
@@ -345,8 +345,9 @@
     ASSERT_FALSE(GetMessageCenterBubble()->IsMessageCenterCollapsed());
 
     // Add enough notifications so that the scroll bar is visible.
-    while (
-        !GetMessageCenterBubble()->message_center_view()->IsScrollBarVisible())
+    while (!GetMessageCenterBubble()
+                ->notification_center_view()
+                ->IsScrollBarVisible())
       AddNotification();
 
     // The message center bubble should be positioned above the system tray
diff --git a/ash/system/message_center/unified_message_center_view.cc b/ash/system/notification_center/notification_center_view.cc
similarity index 78%
rename from ash/system/message_center/unified_message_center_view.cc
rename to ash/system/notification_center/notification_center_view.cc
index f026ce3..31ef7ea6 100644
--- a/ash/system/message_center/unified_message_center_view.cc
+++ b/ash/system/notification_center/notification_center_view.cc
@@ -1,8 +1,8 @@
-// Copyright 2018 The Chromium Authors
+// Copyright 2022 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ash/system/message_center/unified_message_center_view.h"
+#include "ash/system/notification_center/notification_center_view.h"
 
 #include <algorithm>
 #include <memory>
@@ -13,9 +13,9 @@
 #include "ash/system/message_center/ash_message_center_lock_screen_controller.h"
 #include "ash/system/message_center/message_center_constants.h"
 #include "ash/system/message_center/message_center_scroll_bar.h"
-#include "ash/system/message_center/stacked_notification_bar.h"
 #include "ash/system/message_center/unified_message_center_bubble.h"
-#include "ash/system/message_center/unified_message_list_view.h"
+#include "ash/system/notification_center/notification_list_view.h"
+#include "ash/system/notification_center/stacked_notification_bar.h"
 #include "ash/system/tray/tray_constants.h"
 #include "ash/system/tray/tray_popup_utils.h"
 #include "ash/system/unified/unified_system_tray_model.h"
@@ -24,6 +24,7 @@
 #include "base/memory/scoped_refptr.h"
 #include "base/metrics/user_metrics.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
+#include "ui/base/metadata/metadata_impl_macros.h"
 #include "ui/compositor/layer.h"
 #include "ui/gfx/animation/linear_animation.h"
 #include "ui/message_center/message_center.h"
@@ -46,12 +47,12 @@
 
 class ScrollerContentsView : public views::View {
  public:
-  explicit ScrollerContentsView(UnifiedMessageListView* message_list_view) {
+  explicit ScrollerContentsView(NotificationListView* notification_list_view) {
     auto* contents_layout = SetLayoutManager(std::make_unique<views::BoxLayout>(
         views::BoxLayout::Orientation::kVertical));
     contents_layout->set_cross_axis_alignment(
         views::BoxLayout::CrossAxisAlignment::kStretch);
-    AddChildView(message_list_view);
+    AddChildView(notification_list_view);
   }
 
   ScrollerContentsView(const ScrollerContentsView&) = delete;
@@ -69,7 +70,7 @@
 
 }  // namespace
 
-UnifiedMessageCenterView::UnifiedMessageCenterView(
+NotificationCenterView::NotificationCenterView(
     UnifiedSystemTrayView* parent,
     scoped_refptr<UnifiedSystemTrayModel> model,
     UnifiedMessageCenterBubble* bubble)
@@ -80,7 +81,7 @@
       // TODO(crbug.com/1247455): Determine how to use ScrollWithLayers without
       // breaking ARC.
       scroller_(new views::ScrollView()),
-      message_list_view_(new UnifiedMessageListView(this, model)),
+      notification_list_view_(new NotificationListView(this, model)),
       last_scroll_position_from_bottom_(0),
       is_notifications_refresh_enabled_(
           features::IsNotificationsRefreshEnabled()),
@@ -98,7 +99,7 @@
   }
 }
 
-UnifiedMessageCenterView::~UnifiedMessageCenterView() {
+NotificationCenterView::~NotificationCenterView() {
   DCHECK(model_);
   model_->set_notification_target_mode(
       UnifiedSystemTrayModel::NotificationTargetMode::LAST_NOTIFICATION);
@@ -106,8 +107,8 @@
   RemovedFromWidget();
 }
 
-void UnifiedMessageCenterView::Init() {
-  message_list_view_->Init();
+void NotificationCenterView::Init() {
+  notification_list_view_->Init();
 
   if (!is_notifications_refresh_enabled_)
     AddChildView(notification_bar_);
@@ -117,7 +118,7 @@
   // TODO(crbug.com/1247455): Be able to do
   // SetContentsLayerType(LAYER_NOT_DRAWN).
   scroller_->SetContents(
-      std::make_unique<ScrollerContentsView>(message_list_view_));
+      std::make_unique<ScrollerContentsView>(notification_list_view_));
   scroller_->SetBackgroundColor(absl::nullopt);
   scroller_->SetVerticalScrollBar(base::WrapUnique(scroll_bar_));
   scroller_->SetDrawOverflowIndicator(false);
@@ -132,14 +133,14 @@
     AddChildView(notification_bar_);
 }
 
-bool UnifiedMessageCenterView::UpdateNotificationBar() {
+bool NotificationCenterView::UpdateNotificationBar() {
   return notification_bar_->Update(
-      message_list_view_->GetTotalNotificationCount(),
-      message_list_view_->GetTotalPinnedNotificationCount(),
+      notification_list_view_->GetTotalNotificationCount(),
+      notification_list_view_->GetTotalPinnedNotificationCount(),
       GetStackedNotifications());
 }
 
-void UnifiedMessageCenterView::SetMaxHeight(int max_height) {
+void NotificationCenterView::SetMaxHeight(int max_height) {
   int max_scroller_height = max_height;
   if (notification_bar_->GetVisible()) {
     max_scroller_height -=
@@ -151,12 +152,12 @@
   scroller_->ClipHeightTo(0, max_scroller_height);
 }
 
-void UnifiedMessageCenterView::SetAvailableHeight(int available_height) {
+void NotificationCenterView::SetAvailableHeight(int available_height) {
   available_height_ = available_height;
   UpdateVisibility();
 }
 
-void UnifiedMessageCenterView::SetExpanded() {
+void NotificationCenterView::SetExpanded() {
   if (!collapsed_)
     return;
 
@@ -165,7 +166,7 @@
   scroller_->SetVisible(true);
 }
 
-void UnifiedMessageCenterView::SetCollapsed(bool animate) {
+void NotificationCenterView::SetCollapsed(bool animate) {
   if (!GetVisible() || collapsed_)
     return;
 
@@ -183,40 +184,40 @@
   }
 }
 
-void UnifiedMessageCenterView::ClearAllNotifications() {
+void NotificationCenterView::ClearAllNotifications() {
   base::RecordAction(
       base::UserMetricsAction("StatusArea_Notifications_StackingBarClearAll"));
 
-  message_list_view_->ClearAllWithAnimation();
+  notification_list_view_->ClearAllWithAnimation();
 }
 
-void UnifiedMessageCenterView::ExpandMessageCenter() {
+void NotificationCenterView::ExpandMessageCenter() {
   base::RecordAction(
       base::UserMetricsAction("StatusArea_Notifications_SeeAllNotifications"));
   message_center_bubble_->ExpandMessageCenter();
 }
 
-bool UnifiedMessageCenterView::IsNotificationBarVisible() const {
+bool NotificationCenterView::IsNotificationBarVisible() const {
   return notification_bar_->GetVisible();
 }
 
-bool UnifiedMessageCenterView::IsScrollBarVisible() const {
+bool NotificationCenterView::IsScrollBarVisible() const {
   return scroll_bar_->GetVisible();
 }
 
-void UnifiedMessageCenterView::OnNotificationSlidOut() {
+void NotificationCenterView::OnNotificationSlidOut() {
   if (notification_bar_->GetVisible()) {
     UpdateNotificationBar();
     if (!notification_bar_->GetVisible())
       StartHideStackingBarAnimation();
   }
 
-  if (!message_list_view_->GetTotalNotificationCount()) {
+  if (!notification_list_view_->GetTotalNotificationCount()) {
     StartCollapseAnimation();
   }
 }
 
-void UnifiedMessageCenterView::ListPreferredSizeChanged() {
+void NotificationCenterView::ListPreferredSizeChanged() {
   UpdateVisibility();
   PreferredSizeChanged();
   SetMaxHeight(available_height_);
@@ -225,25 +226,25 @@
     GetWidget()->SynthesizeMouseMoveEvent();
 }
 
-void UnifiedMessageCenterView::ConfigureMessageView(
+void NotificationCenterView::ConfigureMessageView(
     message_center::MessageView* message_view) {
   message_view->set_scroller(scroller_);
 }
 
-void UnifiedMessageCenterView::AddedToWidget() {
+void NotificationCenterView::AddedToWidget() {
   focus_manager_ = GetFocusManager();
   if (focus_manager_)
     focus_manager_->AddFocusChangeListener(this);
 }
 
-void UnifiedMessageCenterView::RemovedFromWidget() {
+void NotificationCenterView::RemovedFromWidget() {
   if (!focus_manager_)
     return;
   focus_manager_->RemoveFocusChangeListener(this);
   focus_manager_ = nullptr;
 }
 
-void UnifiedMessageCenterView::Layout() {
+void NotificationCenterView::Layout() {
   if (is_notifications_refresh_enabled_)
     return views::View::Layout();
 
@@ -256,8 +257,7 @@
                                       ? kStackedNotificationBarCollapsedHeight
                                       : notification_bar_expanded_height;
     int notification_bar_offset = 0;
-    if (animation_state_ ==
-        UnifiedMessageCenterAnimationState::HIDE_STACKING_BAR)
+    if (animation_state_ == NotificationCenterAnimationState::HIDE_STACKING_BAR)
       notification_bar_offset = GetAnimationValue() * notification_bar_height;
 
     counter_bounds.set_height(notification_bar_height);
@@ -276,7 +276,7 @@
   ScrollToTarget();
 }
 
-gfx::Size UnifiedMessageCenterView::CalculatePreferredSize() const {
+gfx::Size NotificationCenterView::CalculatePreferredSize() const {
   if (is_notifications_refresh_enabled_)
     return views::View::CalculatePreferredSize();
 
@@ -285,13 +285,12 @@
   if (notification_bar_->GetVisible()) {
     int bar_height = kStackedNotificationBarHeight;
 
-    if (animation_state_ ==
-        UnifiedMessageCenterAnimationState::HIDE_STACKING_BAR)
+    if (animation_state_ == NotificationCenterAnimationState::HIDE_STACKING_BAR)
       bar_height -= GetAnimationValue() * bar_height;
     preferred_size.set_height(preferred_size.height() + bar_height);
   }
 
-  if (animation_state_ == UnifiedMessageCenterAnimationState::COLLAPSE) {
+  if (animation_state_ == NotificationCenterAnimationState::COLLAPSE) {
     int height = preferred_size.height() * (1.0 - GetAnimationValue());
 
     if (collapsed_)
@@ -305,11 +304,7 @@
   return preferred_size;
 }
 
-const char* UnifiedMessageCenterView::GetClassName() const {
-  return "UnifiedMessageCenterView";
-}
-
-void UnifiedMessageCenterView::OnMessageCenterScrolled() {
+void NotificationCenterView::OnMessageCenterScrolled() {
   last_scroll_position_from_bottom_ =
       scroll_bar_->GetMaxPosition() - scroller_->GetVisibleRect().y();
 
@@ -328,12 +323,12 @@
   }
 }
 
-void UnifiedMessageCenterView::OnWillChangeFocus(views::View* before,
-                                                 views::View* now) {}
+void NotificationCenterView::OnWillChangeFocus(views::View* before,
+                                               views::View* now) {}
 
-void UnifiedMessageCenterView::OnDidChangeFocus(views::View* before,
-                                                views::View* now) {
-  if (message_list_view_->is_deleting_removed_notifications())
+void NotificationCenterView::OnDidChangeFocus(views::View* before,
+                                              views::View* now) {
+  if (notification_list_view_->is_deleting_removed_notifications())
     return;
 
   OnMessageCenterScrolled();
@@ -362,17 +357,17 @@
   }
 }
 
-void UnifiedMessageCenterView::AnimationEnded(const gfx::Animation* animation) {
+void NotificationCenterView::AnimationEnded(const gfx::Animation* animation) {
   // This is also called from AnimationCanceled().
   animation_->SetCurrentValue(1.0);
   PreferredSizeChanged();
 
-  animation_state_ = UnifiedMessageCenterAnimationState::IDLE;
+  animation_state_ = NotificationCenterAnimationState::IDLE;
   notification_bar_->SetAnimationState(animation_state_);
   UpdateVisibility();
 }
 
-void UnifiedMessageCenterView::AnimationProgressed(
+void NotificationCenterView::AnimationProgressed(
     const gfx::Animation* animation) {
   // Make the scroller containing notifications invisible and change the
   // notification bar to it's collapsed state in the middle of the animation to
@@ -385,43 +380,42 @@
   PreferredSizeChanged();
 }
 
-void UnifiedMessageCenterView::AnimationCanceled(
+void NotificationCenterView::AnimationCanceled(
     const gfx::Animation* animation) {
   AnimationEnded(animation);
 }
 
-void UnifiedMessageCenterView::StartHideStackingBarAnimation() {
+void NotificationCenterView::StartHideStackingBarAnimation() {
   animation_->End();
-  animation_state_ = UnifiedMessageCenterAnimationState::HIDE_STACKING_BAR;
+  animation_state_ = NotificationCenterAnimationState::HIDE_STACKING_BAR;
   notification_bar_->SetAnimationState(animation_state_);
   animation_->SetDuration(kHideStackingBarAnimationDuration);
   animation_->Start();
 }
 
-void UnifiedMessageCenterView::StartCollapseAnimation() {
+void NotificationCenterView::StartCollapseAnimation() {
   animation_->End();
-  animation_state_ = UnifiedMessageCenterAnimationState::COLLAPSE;
+  animation_state_ = NotificationCenterAnimationState::COLLAPSE;
   notification_bar_->SetAnimationState(animation_state_);
   animation_->SetDuration(kCollapseAnimationDuration);
   animation_->Start();
 }
 
-double UnifiedMessageCenterView::GetAnimationValue() const {
+double NotificationCenterView::GetAnimationValue() const {
   return gfx::Tween::CalculateValue(gfx::Tween::FAST_OUT_SLOW_IN,
                                     animation_->GetCurrentValue());
 }
 
-void UnifiedMessageCenterView::UpdateVisibility() {
+void NotificationCenterView::UpdateVisibility() {
   SessionControllerImpl* session_controller =
       Shell::Get()->session_controller();
 
-  SetVisible(
-      available_height_ >= kUnifiedNotificationMinimumHeight &&
-      (animation_state_ == UnifiedMessageCenterAnimationState::COLLAPSE ||
-       message_list_view_->GetPreferredSize().height() > 0) &&
-      session_controller->ShouldShowNotificationTray() &&
-      (!session_controller->IsScreenLocked() ||
-       AshMessageCenterLockScreenController::IsEnabled()));
+  SetVisible(available_height_ >= kUnifiedNotificationMinimumHeight &&
+             (animation_state_ == NotificationCenterAnimationState::COLLAPSE ||
+              notification_list_view_->GetPreferredSize().height() > 0) &&
+             session_controller->ShouldShowNotificationTray() &&
+             (!session_controller->IsScreenLocked() ||
+              AshMessageCenterLockScreenController::IsEnabled()));
 
   DCHECK(model_);
   if (!GetVisible()) {
@@ -439,7 +433,7 @@
   }
 }
 
-void UnifiedMessageCenterView::ScrollToTarget() {
+void NotificationCenterView::ScrollToTarget() {
   // Following logic doesn't work when the view is invisible, because it uses
   // the height of |scroller_|.
   if (!GetVisible())
@@ -451,7 +445,7 @@
 
   // Notification views may be deleted during an animation, so wait until it
   // finishes before scrolling to a new target (see crbug.com/954001).
-  if (message_list_view_->IsAnimating())
+  if (notification_list_view_->IsAnimating())
     target_mode = UnifiedSystemTrayModel::NotificationTargetMode::LAST_POSITION;
 
   int position;
@@ -468,9 +462,9 @@
       const gfx::Rect& target_rect =
           (model_->notification_target_mode() ==
            UnifiedSystemTrayModel::NotificationTargetMode::NOTIFICATION_ID)
-              ? message_list_view_->GetNotificationBounds(
+              ? notification_list_view_->GetNotificationBounds(
                     model_->notification_target_id())
-              : message_list_view_->GetLastNotificationBounds();
+              : notification_list_view_->GetLastNotificationBounds();
 
       const int last_notification_offset =
           target_rect.height() - scroller_->height();
@@ -493,7 +487,7 @@
 }
 
 std::vector<message_center::Notification*>
-UnifiedMessageCenterView::GetStackedNotifications() const {
+NotificationCenterView::GetStackedNotifications() const {
   // CountNotificationsAboveY() only works after SetBoundsRect() is called at
   // least once.
   if (scroller_->bounds().IsEmpty())
@@ -502,23 +496,23 @@
   if (collapsed_) {
     // When in collapsed state, all notifications are hidden, so all
     // notifications are stacked.
-    return message_list_view_->GetAllNotifications();
+    return notification_list_view_->GetAllNotifications();
   }
 
   if (is_notifications_refresh_enabled_) {
     const int y_offset = scroller_->GetVisibleRect().bottom() - scroller_->y();
-    return message_list_view_->GetNotificationsBelowY(y_offset);
+    return notification_list_view_->GetNotificationsBelowY(y_offset);
   }
 
   const int notification_bar_height =
       IsNotificationBarVisible() ? kStackedNotificationBarHeight : 0;
   const int y_offset = scroller_->GetVisibleRect().y() - scroller_->y() +
                        notification_bar_height;
-  return message_list_view_->GetNotificationsAboveY(y_offset);
+  return notification_list_view_->GetNotificationsAboveY(y_offset);
 }
 
 std::vector<std::string>
-UnifiedMessageCenterView::GetNonVisibleNotificationIdsInViewHierarchy() const {
+NotificationCenterView::GetNonVisibleNotificationIdsInViewHierarchy() const {
   // CountNotificationsAboveY() only works after SetBoundsRect() is called at
   // least once.
   if (scroller_->bounds().IsEmpty())
@@ -526,7 +520,7 @@
   if (collapsed_) {
     // When in collapsed state, all notifications are hidden, so all
     // notifications are stacked.
-    return message_list_view_->GetAllNotificationIds();
+    return notification_list_view_->GetAllNotificationIds();
   }
 
   const int notification_bar_height =
@@ -534,31 +528,31 @@
   const int y_offset_above = scroller_->GetVisibleRect().y() - scroller_->y() +
                              notification_bar_height;
   auto above_id_list =
-      message_list_view_->GetNotificationIdsAboveY(y_offset_above);
+      notification_list_view_->GetNotificationIdsAboveY(y_offset_above);
   const int y_offset_below =
       scroller_->GetVisibleRect().bottom() - scroller_->y();
   const auto below_id_list =
-      message_list_view_->GetNotificationIdsBelowY(y_offset_below);
+      notification_list_view_->GetNotificationIdsBelowY(y_offset_below);
   above_id_list.insert(above_id_list.end(), below_id_list.begin(),
                        below_id_list.end());
   return above_id_list;
 }
 
-void UnifiedMessageCenterView::FocusOut(bool reverse) {
+void NotificationCenterView::FocusOut(bool reverse) {
   if (message_center_bubble_ && message_center_bubble_->FocusOut(reverse)) {
     GetFocusManager()->ClearFocus();
     GetFocusManager()->SetStoredFocusView(nullptr);
   }
 }
 
-void UnifiedMessageCenterView::FocusEntered(bool reverse) {
+void NotificationCenterView::FocusEntered(bool reverse) {
   views::View* focus_view =
       reverse ? GetLastFocusableChild() : GetFirstFocusableChild();
   GetFocusManager()->ClearFocus();
   GetFocusManager()->SetFocusedView(focus_view);
 }
 
-views::View* UnifiedMessageCenterView::GetFirstFocusableChild() {
+views::View* NotificationCenterView::GetFirstFocusableChild() {
   views::FocusTraversable* dummy_focus_traversable;
   views::View* dummy_focus_traversable_view;
   return focus_search_->FindNextFocusableView(
@@ -569,7 +563,7 @@
       &dummy_focus_traversable, &dummy_focus_traversable_view);
 }
 
-views::View* UnifiedMessageCenterView::GetLastFocusableChild() {
+views::View* NotificationCenterView::GetLastFocusableChild() {
   views::FocusTraversable* focus_traversable = nullptr;
   views::View* dummy_focus_traversable_view = nullptr;
   views::View* last_view = focus_search_->FindNextFocusableView(
@@ -590,4 +584,7 @@
       &focus_traversable, &dummy_focus_traversable_view);
 }
 
+BEGIN_METADATA(NotificationCenterView, views::View);
+END_METADATA
+
 }  // namespace ash
diff --git a/ash/system/message_center/unified_message_center_view.h b/ash/system/notification_center/notification_center_view.h
similarity index 73%
rename from ash/system/message_center/unified_message_center_view.h
rename to ash/system/notification_center/notification_center_view.h
index 566eda2..1eb44a6 100644
--- a/ash/system/message_center/unified_message_center_view.h
+++ b/ash/system/notification_center/notification_center_view.h
@@ -1,13 +1,13 @@
-// Copyright 2018 The Chromium Authors
+// Copyright 2022 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ASH_SYSTEM_MESSAGE_CENTER_UNIFIED_MESSAGE_CENTER_VIEW_H_
-#define ASH_SYSTEM_MESSAGE_CENTER_UNIFIED_MESSAGE_CENTER_VIEW_H_
+#ifndef ASH_SYSTEM_NOTIFICATION_CENTER_NOTIFICATION_CENTER_VIEW_H_
+#define ASH_SYSTEM_NOTIFICATION_CENTER_NOTIFICATION_CENTER_VIEW_H_
 
 #include "ash/ash_export.h"
 #include "ash/system/message_center/message_center_scroll_bar.h"
-#include "ash/system/message_center/unified_message_list_view.h"
+#include "ash/system/notification_center/notification_list_view.h"
 #include "base/memory/scoped_refptr.h"
 #include "ui/gfx/animation/animation_delegate.h"
 #include "ui/views/background.h"
@@ -36,12 +36,15 @@
 class UnifiedSystemTrayModel;
 class UnifiedSystemTrayView;
 
-// Note: This enum represents the current animation state for
-// UnifiedMessageCenterView. There is an equivalent animation state enum in
-// the child UnifiedMessageListView. The animations for these two views can
-// occur simultaneously or independently, so states for both views are tracked
-// separately.
-enum class UnifiedMessageCenterAnimationState {
+// TODO(b:252887883): Clean up old animation code once the new clear all
+// animation is implemented.
+
+// Note: This enum represents the current animation
+// state for `NotificationCenterView`. There is an equivalent animation state
+// enum in the child `NotificationListView`. The animations for these two views
+// can occur simultaneously or independently, so states for both views are
+// tracked separately.
+enum class NotificationCenterAnimationState {
   // No animation is running.
   IDLE,
 
@@ -51,27 +54,28 @@
 
   // Animating collapsing the entire message center. Runs after the user
   // dismisses the last notification and during the clear all animation.
-  // TODO(tengs): This animation is not yet implemented.
   COLLAPSE,
 };
 
 // Manages scrolling of notification list.
-class ASH_EXPORT UnifiedMessageCenterView
+class ASH_EXPORT NotificationCenterView
     : public views::View,
       public MessageCenterScrollBar::Observer,
       public views::FocusChangeListener,
       public gfx::AnimationDelegate {
  public:
-  UnifiedMessageCenterView(UnifiedSystemTrayView* parent,
-                           scoped_refptr<UnifiedSystemTrayModel> model,
-                           UnifiedMessageCenterBubble* bubble);
+  METADATA_HEADER(NotificationCenterView);
 
-  UnifiedMessageCenterView(const UnifiedMessageCenterView&) = delete;
-  UnifiedMessageCenterView& operator=(const UnifiedMessageCenterView&) = delete;
+  NotificationCenterView(UnifiedSystemTrayView* parent,
+                         scoped_refptr<UnifiedSystemTrayModel> model,
+                         UnifiedMessageCenterBubble* bubble);
 
-  ~UnifiedMessageCenterView() override;
+  NotificationCenterView(const NotificationCenterView&) = delete;
+  NotificationCenterView& operator=(const NotificationCenterView&) = delete;
 
-  // Initializes the `UnifiedMessageListView` with existing notifications.
+  ~NotificationCenterView() override;
+
+  // Initializes the `NotificationListView` with existing notifications.
   // Should be called after ctor.
   void Init();
 
@@ -83,27 +87,27 @@
   // Sets the maximum height that the view can take.
   // TODO(tengs): The layout of this view is heavily dependant on this max
   // height (equal to the height of the entire tray), but we should refactor and
-  // consolidate this function with SetAvailableHeight().
+  // consolidate this function with `SetAvailableHeight()`.
   void SetMaxHeight(int max_height);
 
   // Sets the height available to the message center view. This is the remaining
   // height after counting the system menu, which may be expanded or collapsed.
   void SetAvailableHeight(int available_height);
 
-  // Called from UnifiedMessageListView when the preferred size is changed.
+  // Called from `NotificationListView` when the preferred size is changed.
   void ListPreferredSizeChanged();
 
-  // Called from the UnifiedMessageListView after a notification is dismissed by
+  // Called from the `NotificationListView` after a notification is dismissed by
   // the user and the slide animation is finished.
   void OnNotificationSlidOut();
 
-  // Configures MessageView to forward scroll events. Called from
-  // UnifiedMessageListView.
+  // Configures `MessageView` to forward scroll events. Called from
+  // `NotificationListView`.
   void ConfigureMessageView(message_center::MessageView* message_view);
 
-  // Count number of notifications that are still in the MessageCenter that are
-  // above visible area. NOTE: views may be in the view hierarchy, but no longer
-  // in the message center.
+  // Count number of notifications that are still in the `MessageCenter` that
+  // are above visible area. NOTE: views may be in the view hierarchy, but no
+  // longer in the message center.
   std::vector<message_center::Notification*> GetStackedNotifications() const;
 
   // Count the number of notifications that are not visible in the scrollable
@@ -143,7 +147,6 @@
   void RemovedFromWidget() override;
   void Layout() override;
   gfx::Size CalculatePreferredSize() const override;
-  const char* GetClassName() const override;
 
   // MessageCenterScrollBar::Observer:
   void OnMessageCenterScrolled() override;
@@ -157,14 +160,16 @@
   void AnimationProgressed(const gfx::Animation* animation) override;
   void AnimationCanceled(const gfx::Animation* animation) override;
 
-  UnifiedMessageListView* message_list_view() { return message_list_view_; }
+  NotificationListView* notification_list_view() {
+    return notification_list_view_;
+  }
   bool collapsed() { return collapsed_; }
 
  private:
-  friend class UnifiedMessageCenterViewTest;
+  friend class NotificationCenterViewTest;
   friend class UnifiedMessageCenterBubbleTest;
 
-  // Starts the animation to hide the notification stacking bar.
+  // Starts the animation to hide the `StackedNotificationBar`.
   void StartHideStackingBarAnimation();
 
   // Starts the animation to collapse the message center.
@@ -192,7 +197,7 @@
   StackedNotificationBar* const notification_bar_;
   views::ScrollBar* scroll_bar_;
   views::ScrollView* const scroller_;
-  UnifiedMessageListView* const message_list_view_;
+  NotificationListView* const notification_list_view_;
 
   // Position from the bottom of scroll contents in dip.
   int last_scroll_position_from_bottom_;
@@ -208,8 +213,8 @@
   bool collapsed_ = false;
 
   // Tracks the current animation state.
-  UnifiedMessageCenterAnimationState animation_state_ =
-      UnifiedMessageCenterAnimationState::IDLE;
+  NotificationCenterAnimationState animation_state_ =
+      NotificationCenterAnimationState::IDLE;
   const std::unique_ptr<gfx::LinearAnimation> animation_;
 
   const std::unique_ptr<views::FocusSearch> focus_search_;
@@ -219,4 +224,4 @@
 
 }  // namespace ash
 
-#endif  // ASH_SYSTEM_MESSAGE_CENTER_UNIFIED_MESSAGE_CENTER_VIEW_H_
+#endif  // ASH_SYSTEM_NOTIFICATION_CENTER_NOTIFICATION_CENTER_VIEW_H_
diff --git a/ash/system/message_center/unified_message_center_view_unittest.cc b/ash/system/notification_center/notification_center_view_unittest.cc
similarity index 71%
rename from ash/system/message_center/unified_message_center_view_unittest.cc
rename to ash/system/notification_center/notification_center_view_unittest.cc
index 2937d71..aa0c0e0a 100644
--- a/ash/system/message_center/unified_message_center_view_unittest.cc
+++ b/ash/system/notification_center/notification_center_view_unittest.cc
@@ -1,8 +1,8 @@
-// Copyright 2018 The Chromium Authors
+// Copyright 2022 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ash/system/message_center/unified_message_center_view.h"
+#include "ash/system/notification_center/notification_center_view.h"
 
 #include "ash/constants/ash_features.h"
 #include "ash/constants/ash_pref_names.h"
@@ -11,7 +11,7 @@
 #include "ash/system/message_center/ash_message_center_lock_screen_controller.h"
 #include "ash/system/message_center/message_center_constants.h"
 #include "ash/system/message_center/message_center_scroll_bar.h"
-#include "ash/system/message_center/stacked_notification_bar.h"
+#include "ash/system/notification_center/stacked_notification_bar.h"
 #include "ash/system/tray/tray_constants.h"
 #include "ash/system/unified/unified_system_tray_controller.h"
 #include "ash/system/unified/unified_system_tray_model.h"
@@ -42,33 +42,31 @@
 
 constexpr int kDefaultMaxHeight = 500;
 
-class TestUnifiedMessageCenterView : public UnifiedMessageCenterView {
+class TestNotificationCenterView : public NotificationCenterView {
  public:
-  explicit TestUnifiedMessageCenterView(UnifiedSystemTrayModel* model)
-      : UnifiedMessageCenterView(nullptr /*parent*/,
-                                 model,
-                                 nullptr /*bubble*/) {}
+  explicit TestNotificationCenterView(UnifiedSystemTrayModel* model)
+      : NotificationCenterView(nullptr /*parent*/, model, nullptr /*bubble*/) {}
 
-  TestUnifiedMessageCenterView(const TestUnifiedMessageCenterView&) = delete;
-  TestUnifiedMessageCenterView& operator=(const TestUnifiedMessageCenterView&) =
+  TestNotificationCenterView(const TestNotificationCenterView&) = delete;
+  TestNotificationCenterView& operator=(const TestNotificationCenterView&) =
       delete;
 
-  ~TestUnifiedMessageCenterView() override = default;
+  ~TestNotificationCenterView() override = default;
 };
 
 }  // namespace
 
-class UnifiedMessageCenterViewTest : public AshTestBase,
-                                     public views::ViewObserver,
-                                     public testing::WithParamInterface<bool> {
+class NotificationCenterViewTest : public AshTestBase,
+                                   public views::ViewObserver,
+                                   public testing::WithParamInterface<bool> {
  public:
-  UnifiedMessageCenterViewTest() = default;
+  NotificationCenterViewTest() = default;
 
-  UnifiedMessageCenterViewTest(const UnifiedMessageCenterViewTest&) = delete;
-  UnifiedMessageCenterViewTest& operator=(const UnifiedMessageCenterViewTest&) =
+  NotificationCenterViewTest(const NotificationCenterViewTest&) = delete;
+  NotificationCenterViewTest& operator=(const NotificationCenterViewTest&) =
       delete;
 
-  ~UnifiedMessageCenterViewTest() override = default;
+  ~NotificationCenterViewTest() override = default;
 
   // AshTestBase:
   void SetUp() override {
@@ -93,7 +91,7 @@
 
   void TearDown() override {
     base::RunLoop().RunUntilIdle();
-    message_center_view_.reset();
+    notification_center_view_.reset();
     model_.reset();
     AshTestBase::TearDown();
   }
@@ -130,10 +128,10 @@
     return ids;
   }
 
-  std::unique_ptr<TestUnifiedMessageCenterView> CreateMessageCenterViewImpl(
+  std::unique_ptr<TestNotificationCenterView> CreateMessageCenterViewImpl(
       int max_height) {
     auto message_center_view =
-        std::make_unique<TestUnifiedMessageCenterView>(model_.get());
+        std::make_unique<TestNotificationCenterView>(model_.get());
     message_center_view->Init();
     message_center_view->AddObserver(this);
     message_center_view->SetMaxHeight(max_height);
@@ -146,74 +144,80 @@
   }
 
   virtual void CreateMessageCenterView(int max_height = kDefaultMaxHeight) {
-    message_center_view_ = CreateMessageCenterViewImpl(max_height);
+    notification_center_view_ = CreateMessageCenterViewImpl(max_height);
   }
 
-  void AnimateMessageListToValue(float value) {
-    GetMessageListView()->animation_->SetCurrentValue(value);
-    GetMessageListView()->AnimationProgressed(
-        GetMessageListView()->animation_.get());
+  void AnimateNotificationListToValue(float value) {
+    GetNotificationListView()->animation_->SetCurrentValue(value);
+    GetNotificationListView()->AnimationProgressed(
+        GetNotificationListView()->animation_.get());
   }
 
-  void AnimateMessageListToMiddle() { AnimateMessageListToValue(0.5); }
-
-  void AnimateMessageListToEnd() {
-    FinishMessageListSlideOutAnimations();
-    GetMessageListView()->animation_->End();
+  void AnimateNotificationListToMiddle() {
+    AnimateNotificationListToValue(0.5);
   }
 
-  void AnimateMessageListUntilIdle() {
-    while (GetMessageListView()->animation_->is_animating()) {
-      GetMessageListView()->animation_->End();
+  void AnimateNotificationListToEnd() {
+    FinishNotificationListSlideOutAnimations();
+    GetNotificationListView()->animation_->End();
+  }
+
+  void AnimateNotificationListUntilIdle() {
+    while (GetNotificationListView()->animation_->is_animating()) {
+      GetNotificationListView()->animation_->End();
     }
   }
 
-  void FinishMessageListSlideOutAnimations() { base::RunLoop().RunUntilIdle(); }
+  void FinishNotificationListSlideOutAnimations() {
+    base::RunLoop().RunUntilIdle();
+  }
 
   gfx::Rect GetMessageViewVisibleBounds(size_t index) {
-    gfx::Rect bounds = GetMessageListView()->children()[index]->bounds();
+    gfx::Rect bounds = GetNotificationListView()->children()[index]->bounds();
     bounds -= GetScroller()->GetVisibleRect().OffsetFromOrigin();
     bounds += GetScroller()->bounds().OffsetFromOrigin();
     return bounds;
   }
 
-  UnifiedMessageListView* GetMessageListView() {
-    return message_center_view()->message_list_view_;
+  NotificationListView* GetNotificationListView() {
+    return notification_center_view()->notification_list_view_;
   }
 
   gfx::LinearAnimation* GetMessageCenterAnimation() {
-    return message_center_view()->animation_.get();
+    return notification_center_view()->animation_.get();
   }
 
-  views::ScrollView* GetScroller() { return message_center_view()->scroller_; }
+  views::ScrollView* GetScroller() {
+    return notification_center_view()->scroller_;
+  }
 
   views::ScrollBar* GetScrollBar() {
-    return message_center_view()->scroll_bar_;
+    return notification_center_view()->scroll_bar_;
   }
 
   views::View* GetScrollerContents() {
-    return message_center_view()->scroller_->contents();
+    return notification_center_view()->scroller_->contents();
   }
 
   StackedNotificationBar* GetNotificationBar() {
-    return message_center_view()->notification_bar_;
+    return notification_center_view()->notification_bar_;
   }
 
   views::View* GetNotificationBarIconsContainer() {
-    return message_center_view()
+    return notification_center_view()
         ->notification_bar_->notification_icons_container_;
   }
 
   views::View* GetNotificationBarLabel() {
-    return message_center_view()->notification_bar_->count_label_;
+    return notification_center_view()->notification_bar_->count_label_;
   }
 
   views::View* GetNotificationBarClearAllButton() {
-    return message_center_view()->notification_bar_->clear_all_button_;
+    return notification_center_view()->notification_bar_->clear_all_button_;
   }
 
   views::View* GetNotificationBarExpandAllButton() {
-    return message_center_view()->notification_bar_->expand_all_button_;
+    return notification_center_view()->notification_bar_->expand_all_button_;
   }
 
   int total_notification_count() {
@@ -235,18 +239,19 @@
 
   message_center::MessageView* ToggleFocusToMessageView(size_t index,
                                                         bool reverse) {
-    auto* focus_manager = message_center_view()->GetFocusManager();
+    auto* focus_manager = notification_center_view()->GetFocusManager();
     if (!focus_manager)
       return nullptr;
 
     message_center::MessageView* focused_message_view = nullptr;
     const size_t max_focus_toggles =
-        GetMessageListView()->children().size() * 5;
+        GetNotificationListView()->children().size() * 5;
     for (size_t i = 0; i < max_focus_toggles; ++i) {
       focus_manager->AdvanceFocus(reverse);
       auto* focused_view = focus_manager->GetFocusedView();
-      // The MessageView is wrapped in container view in the MessageList.
-      if (focused_view->parent() == GetMessageListView()->children()[index]) {
+      // The MessageView is wrapped in container view in the NotificationList.
+      if (focused_view->parent() ==
+          GetNotificationListView()->children()[index]) {
         focused_message_view =
             static_cast<message_center::MessageView*>(focused_view);
         break;
@@ -261,19 +266,19 @@
     // relayout, and then this view will relayout. In test, we don't have
     // TrayBubbleView as the parent, so we need to ensure Layout() is executed
     // in some circumstances.
-    views::test::RunScheduledLayout(message_center_view_.get());
+    views::test::RunScheduledLayout(notification_center_view_.get());
   }
 
   void UpdateNotificationBarForTest() {
     // TODO(crbug/1357232): Refactor so this code mirrors production better.
     // Outside of tests, the notification bar is updated with a call to
-    // UnifiedMessageCenterBubble::UpdatePosition(), but this function is not
+    // NotificationCenterBubble::UpdatePosition(), but this function is not
     // triggered when adding notifications in tests.
-    message_center_view_->UpdateNotificationBar();
+    notification_center_view_->UpdateNotificationBar();
   }
 
-  virtual TestUnifiedMessageCenterView* message_center_view() {
-    return message_center_view_.get();
+  virtual TestNotificationCenterView* notification_center_view() {
+    return notification_center_view_.get();
   }
 
   int size_changed_count() const { return size_changed_count_; }
@@ -285,24 +290,23 @@
   int size_changed_count_ = 0;
 
   scoped_refptr<UnifiedSystemTrayModel> model_;
-  std::unique_ptr<TestUnifiedMessageCenterView> message_center_view_;
+  std::unique_ptr<TestNotificationCenterView> notification_center_view_;
   std::unique_ptr<base::test::ScopedFeatureList> scoped_feature_list_;
 };
 
-class UnifiedMessageCenterViewInWidgetTest
-    : public UnifiedMessageCenterViewTest {
+class NotificationCenterViewInWidgetTest : public NotificationCenterViewTest {
  public:
-  UnifiedMessageCenterViewInWidgetTest() = default;
-  UnifiedMessageCenterViewInWidgetTest(
-      const UnifiedMessageCenterViewInWidgetTest&) = delete;
-  UnifiedMessageCenterViewInWidgetTest& operator=(
-      const UnifiedMessageCenterViewInWidgetTest&) = delete;
-  ~UnifiedMessageCenterViewInWidgetTest() override = default;
+  NotificationCenterViewInWidgetTest() = default;
+  NotificationCenterViewInWidgetTest(
+      const NotificationCenterViewInWidgetTest&) = delete;
+  NotificationCenterViewInWidgetTest& operator=(
+      const NotificationCenterViewInWidgetTest&) = delete;
+  ~NotificationCenterViewInWidgetTest() override = default;
 
   void TearDown() override {
     widget_.reset();
 
-    UnifiedMessageCenterViewTest::TearDown();
+    NotificationCenterViewTest::TearDown();
   }
 
  protected:
@@ -312,7 +316,7 @@
         CreateMessageCenterViewImpl(max_height));
   }
 
-  TestUnifiedMessageCenterView* message_center_view() override {
+  TestNotificationCenterView* notification_center_view() override {
     return message_center_;
   }
 
@@ -320,65 +324,66 @@
 
  private:
   std::unique_ptr<views::Widget> widget_;
-  TestUnifiedMessageCenterView* message_center_ = nullptr;
+  TestNotificationCenterView* message_center_ = nullptr;
 };
 
 INSTANTIATE_TEST_SUITE_P(All,
-                         UnifiedMessageCenterViewTest,
+                         NotificationCenterViewTest,
                          testing::Bool() /* IsNotificationsRefreshEnabled() */);
 
 // Flaky: https://crbug.com/1293165
-TEST_P(UnifiedMessageCenterViewTest, DISABLED_AddAndRemoveNotification) {
+TEST_P(NotificationCenterViewTest, DISABLED_AddAndRemoveNotification) {
   CreateMessageCenterView();
-  EXPECT_FALSE(message_center_view()->GetVisible());
+  EXPECT_FALSE(notification_center_view()->GetVisible());
 
   auto id0 = AddNotification();
-  EXPECT_TRUE(message_center_view()->GetVisible());
+  EXPECT_TRUE(notification_center_view()->GetVisible());
 
   // The notification first slides out of the list.
   MessageCenter::Get()->RemoveNotification(id0, true /* by_user */);
-  AnimateMessageListToEnd();
+  AnimateNotificationListToEnd();
 
   // After all the last notifiation slides out, the message center and list
   // should collapse.
   auto* collapse_animation = GetMessageCenterAnimation();
   collapse_animation->SetCurrentValue(0.5);
-  message_center_view()->AnimationProgressed(collapse_animation);
-  EXPECT_TRUE(message_center_view()->GetVisible());
+  notification_center_view()->AnimationProgressed(collapse_animation);
+  EXPECT_TRUE(notification_center_view()->GetVisible());
 
   // The message center is now hidden after all animations complete.
   collapse_animation->End();
-  AnimateMessageListToEnd();
-  EXPECT_FALSE(message_center_view()->GetVisible());
+  AnimateNotificationListToEnd();
+  EXPECT_FALSE(notification_center_view()->GetVisible());
 }
 
-TEST_P(UnifiedMessageCenterViewTest, RemoveNotificationAtTail) {
+TEST_P(NotificationCenterViewTest, RemoveNotificationAtTail) {
   // No special scroll behavior with the Notifications Refresh anymore.
   if (IsNotificationsRefreshEnabled())
     return;
   // Show message center with multiple notifications.
   AddManyNotifications();
   CreateMessageCenterView();
-  EXPECT_TRUE(message_center_view()->GetVisible());
+  EXPECT_TRUE(notification_center_view()->GetVisible());
 
   // The message center should autoscroll to the bottom of the list after adding
   // a new notification.
   auto id_to_remove = AddNotification();
   RelayoutMessageCenterViewForTest();
   int scroll_position = GetScroller()->GetVisibleRect().y();
-  EXPECT_EQ(GetMessageListView()->height() - GetScroller()->height(),
+  EXPECT_EQ(GetNotificationListView()->height() - GetScroller()->height(),
             scroll_position);
 
   // Get the height of last notification and then remove it.
   int removed_notification_height =
-      GetMessageViewVisibleBounds(GetMessageListView()->children().size() - 1)
+      GetMessageViewVisibleBounds(GetNotificationListView()->children().size() -
+                                  1)
           .height();
   MessageCenter::Get()->RemoveNotification(id_to_remove, true /* by_user */);
   scroll_position = GetScroller()->GetVisibleRect().y();
 
   // The scroll position should be reduced by the height of the removed
   // notification after collapsing.
-  AnimateMessageListToEnd();
+  AnimateNotificationListToEnd();
   RelayoutMessageCenterViewForTest();
 
   EXPECT_EQ(scroll_position - removed_notification_height -
@@ -386,43 +391,44 @@
             GetScroller()->GetVisibleRect().y());
 
   // Check that the list is still scrolled to the bottom.
-  EXPECT_EQ(GetMessageListView()->height() - GetScroller()->height(),
+  EXPECT_EQ(GetNotificationListView()->height() - GetScroller()->height(),
             GetScroller()->GetVisibleRect().y());
 }
 
-TEST_P(UnifiedMessageCenterViewTest, ContentsRelayout) {
+TEST_P(NotificationCenterViewTest, ContentsRelayout) {
   std::vector<std::string> ids = AddManyNotifications();
   CreateMessageCenterView();
-  EXPECT_TRUE(message_center_view()->GetVisible());
+  EXPECT_TRUE(notification_center_view()->GetVisible());
   // MessageCenterView is maxed out.
-  EXPECT_GT(GetMessageListView()->bounds().height(),
-            message_center_view()->bounds().height());
+  EXPECT_GT(GetNotificationListView()->bounds().height(),
+            notification_center_view()->bounds().height());
   const int previous_contents_height = GetScrollerContents()->height();
-  const int previous_list_height = GetMessageListView()->height();
+  const int previous_list_height = GetNotificationListView()->height();
 
   MessageCenter::Get()->RemoveNotification(ids.back(), true /* by_user */);
-  AnimateMessageListToEnd();
+  AnimateNotificationListToEnd();
   RelayoutMessageCenterViewForTest();
 
-  EXPECT_TRUE(message_center_view()->GetVisible());
+  EXPECT_TRUE(notification_center_view()->GetVisible());
   EXPECT_GT(previous_contents_height, GetScrollerContents()->height());
-  EXPECT_GT(previous_list_height, GetMessageListView()->height());
+  EXPECT_GT(previous_list_height, GetNotificationListView()->height());
 }
 
-TEST_P(UnifiedMessageCenterViewTest, InsufficientHeight) {
+TEST_P(NotificationCenterViewTest, InsufficientHeight) {
   CreateMessageCenterView();
   AddNotification();
-  EXPECT_TRUE(message_center_view()->GetVisible());
+  EXPECT_TRUE(notification_center_view()->GetVisible());
 
-  message_center_view()->SetAvailableHeight(kUnifiedNotificationMinimumHeight -
-                                            1);
-  EXPECT_FALSE(message_center_view()->GetVisible());
+  notification_center_view()->SetAvailableHeight(
+      kUnifiedNotificationMinimumHeight - 1);
+  EXPECT_FALSE(notification_center_view()->GetVisible());
 
-  message_center_view()->SetAvailableHeight(kUnifiedNotificationMinimumHeight);
-  EXPECT_TRUE(message_center_view()->GetVisible());
+  notification_center_view()->SetAvailableHeight(
+      kUnifiedNotificationMinimumHeight);
+  EXPECT_TRUE(notification_center_view()->GetVisible());
 }
 
-TEST_P(UnifiedMessageCenterViewTest, NotVisibleWhenLocked) {
+TEST_P(NotificationCenterViewTest, NotVisibleWhenLocked) {
   // Disable the lock screen notification if the feature is enable.
   PrefService* user_prefs =
       Shell::Get()->session_controller()->GetLastActiveUserPrefService();
@@ -437,10 +443,10 @@
   BlockUserSession(BLOCKED_BY_LOCK_SCREEN);
   CreateMessageCenterView();
 
-  EXPECT_FALSE(message_center_view()->GetVisible());
+  EXPECT_FALSE(notification_center_view()->GetVisible());
 }
 
-TEST_P(UnifiedMessageCenterViewTest, VisibleWhenLocked) {
+TEST_P(NotificationCenterViewTest, VisibleWhenLocked) {
   // This test is only valid if the lock screen feature is enabled.
   // TODO(yoshiki): Clean up after the feature is launched crbug.com/913764.
   if (!features::IsLockScreenNotificationsEnabled())
@@ -460,53 +466,53 @@
   BlockUserSession(BLOCKED_BY_LOCK_SCREEN);
   CreateMessageCenterView();
 
-  EXPECT_TRUE(message_center_view()->GetVisible());
+  EXPECT_TRUE(notification_center_view()->GetVisible());
 }
 
-TEST_P(UnifiedMessageCenterViewTest, ClearAllPressed) {
+TEST_P(NotificationCenterViewTest, ClearAllPressed) {
   AddNotification();
   AddNotification();
   CreateMessageCenterView();
-  EXPECT_TRUE(message_center_view()->GetVisible());
+  EXPECT_TRUE(notification_center_view()->GetVisible());
   EXPECT_TRUE(GetNotificationBar()->GetVisible());
 
   // When Clear All button is pressed, all notifications are removed and the
   // view becomes invisible.
-  message_center_view()->ClearAllNotifications();
-  AnimateMessageListUntilIdle();
-  EXPECT_FALSE(message_center_view()->GetVisible());
+  notification_center_view()->ClearAllNotifications();
+  AnimateNotificationListUntilIdle();
+  EXPECT_FALSE(notification_center_view()->GetVisible());
 }
 
-TEST_P(UnifiedMessageCenterViewTest, InitialPosition) {
+TEST_P(NotificationCenterViewTest, InitialPosition) {
   AddNotification();
   AddNotification();
   CreateMessageCenterView();
-  EXPECT_TRUE(message_center_view()->GetVisible());
+  EXPECT_TRUE(notification_center_view()->GetVisible());
 
   // MessageCenterView is not maxed out.
-  EXPECT_LT(GetMessageListView()->bounds().height(),
-            message_center_view()->bounds().height());
+  EXPECT_LT(GetNotificationListView()->bounds().height(),
+            notification_center_view()->bounds().height());
 }
 
-TEST_P(UnifiedMessageCenterViewTest, InitialPositionMaxOut) {
+TEST_P(NotificationCenterViewTest, InitialPositionMaxOut) {
   AddManyNotifications();
   CreateMessageCenterView();
-  EXPECT_TRUE(message_center_view()->GetVisible());
+  EXPECT_TRUE(notification_center_view()->GetVisible());
 
   // MessageCenterView is maxed out.
-  EXPECT_GT(GetMessageListView()->bounds().height(),
-            message_center_view()->bounds().height());
+  EXPECT_GT(GetNotificationListView()->bounds().height(),
+            notification_center_view()->bounds().height());
 }
 
-TEST_P(UnifiedMessageCenterViewTest, InitialPositionWithLargeNotification) {
+TEST_P(NotificationCenterViewTest, InitialPositionWithLargeNotification) {
   AddNotification();
   AddNotification();
   CreateMessageCenterView(60 /* max_height */);
-  EXPECT_TRUE(message_center_view()->GetVisible());
+  EXPECT_TRUE(notification_center_view()->GetVisible());
 
   // MessageCenterView is shorter than the notification.
   gfx::Rect message_view_bounds = GetMessageViewVisibleBounds(1);
-  EXPECT_LT(message_center_view()->bounds().height(),
+  EXPECT_LT(notification_center_view()->bounds().height(),
             message_view_bounds.height());
 
   // Top of the second notification aligns with the top of MessageCenterView.
@@ -514,49 +520,49 @@
     EXPECT_EQ(kStackedNotificationBarHeight, message_view_bounds.y());
 }
 
-TEST_P(UnifiedMessageCenterViewTest, ScrollPositionWhenResized) {
+TEST_P(NotificationCenterViewTest, ScrollPositionWhenResized) {
   // We keep the scroll position at the top after the notifications refresh.
   if (IsNotificationsRefreshEnabled())
     return;
 
   AddManyNotifications();
   CreateMessageCenterView();
-  EXPECT_TRUE(message_center_view()->GetVisible());
+  EXPECT_TRUE(notification_center_view()->GetVisible());
 
   // MessageCenterView is maxed out.
-  EXPECT_GT(GetMessageListView()->bounds().height(),
-            message_center_view()->bounds().height());
+  EXPECT_GT(GetNotificationListView()->bounds().height(),
+            notification_center_view()->bounds().height());
   gfx::Rect previous_visible_rect = GetScroller()->GetVisibleRect();
 
-  gfx::Size new_size = message_center_view()->size();
+  gfx::Size new_size = notification_center_view()->size();
   new_size.set_height(250);
-  message_center_view()->SetPreferredSize(new_size);
-  OnViewPreferredSizeChanged(message_center_view());
+  notification_center_view()->SetPreferredSize(new_size);
+  OnViewPreferredSizeChanged(notification_center_view());
 
   EXPECT_EQ(previous_visible_rect.bottom(),
             GetScroller()->GetVisibleRect().bottom());
 
   GetScroller()->ScrollToPosition(GetScrollBar(), 200);
-  message_center_view()->OnMessageCenterScrolled();
+  notification_center_view()->OnMessageCenterScrolled();
   previous_visible_rect = GetScroller()->GetVisibleRect();
 
   new_size.set_height(300);
-  message_center_view()->SetPreferredSize(new_size);
-  OnViewPreferredSizeChanged(message_center_view());
+  notification_center_view()->SetPreferredSize(new_size);
+  OnViewPreferredSizeChanged(notification_center_view());
 
   EXPECT_EQ(previous_visible_rect.bottom(),
             GetScroller()->GetVisibleRect().bottom());
 }
 
 // Tests basic layout of the StackingNotificationBar.
-TEST_P(UnifiedMessageCenterViewTest, StackingCounterLabelLayout) {
+TEST_P(NotificationCenterViewTest, StackingCounterLabelLayout) {
   AddManyNotifications();
 
   // MessageCenterView is maxed out.
   CreateMessageCenterView();
 
-  EXPECT_GT(GetMessageListView()->bounds().height(),
-            message_center_view()->bounds().height());
+  EXPECT_GT(GetNotificationListView()->bounds().height(),
+            notification_center_view()->bounds().height());
 
   EXPECT_TRUE(GetNotificationBar()->GetVisible());
 
@@ -576,7 +582,7 @@
 }
 
 // Tests that the NotificationBarLabel is invisible when scrolled to the top.
-TEST_P(UnifiedMessageCenterViewTest, StackingCounterLabelInvisible) {
+TEST_P(NotificationCenterViewTest, StackingCounterLabelInvisible) {
   AddManyNotifications();
   CreateMessageCenterView();
 
@@ -587,7 +593,7 @@
                                   features::IsNotificationsRefreshEnabled()
                                       ? GetScrollBar()->bounds().bottom()
                                       : 0);
-  message_center_view()->OnMessageCenterScrolled();
+  notification_center_view()->OnMessageCenterScrolled();
 
   EXPECT_FALSE(GetNotificationBarLabel()->GetVisible());
   // ClearAll label should always be visible.
@@ -595,7 +601,7 @@
 }
 
 // Tests that the NotificationBarLabel is visible when scrolling down.
-TEST_P(UnifiedMessageCenterViewTest, StackingCounterLabelVisible) {
+TEST_P(NotificationCenterViewTest, StackingCounterLabelVisible) {
   AddManyNotifications();
   CreateMessageCenterView();
 
@@ -604,7 +610,7 @@
   GetScroller()->ScrollToPosition(
       GetScrollBar(),
       features::IsNotificationsRefreshEnabled() ? 0 : scroll_amount);
-  message_center_view()->OnMessageCenterScrolled();
+  notification_center_view()->OnMessageCenterScrolled();
 
   EXPECT_TRUE(GetNotificationBarLabel()->GetVisible());
   // ClearAll label should always be visible.
@@ -612,7 +618,7 @@
 }
 
 // Tests that the +n notifications label hides after being shown.
-TEST_P(UnifiedMessageCenterViewTest, StackingCounterLabelHidesAfterShown) {
+TEST_P(NotificationCenterViewTest, StackingCounterLabelHidesAfterShown) {
   AddManyNotifications();
   CreateMessageCenterView();
 
@@ -622,7 +628,7 @@
   GetScroller()->ScrollToPosition(
       GetScrollBar(),
       features::IsNotificationsRefreshEnabled() ? bottom_position : 0);
-  message_center_view()->OnMessageCenterScrolled();
+  notification_center_view()->OnMessageCenterScrolled();
 
   EXPECT_FALSE(GetNotificationBarLabel()->GetVisible());
 
@@ -632,7 +638,7 @@
                                   features::IsNotificationsRefreshEnabled()
                                       ? bottom_position - scroll_amount
                                       : scroll_amount);
-  message_center_view()->OnMessageCenterScrolled();
+  notification_center_view()->OnMessageCenterScrolled();
 
   ASSERT_TRUE(GetNotificationBarLabel()->GetVisible());
 
@@ -642,7 +648,7 @@
                                   features::IsNotificationsRefreshEnabled()
                                       ? GetScrollBar()->bounds().bottom()
                                       : 0);
-  message_center_view()->OnMessageCenterScrolled();
+  notification_center_view()->OnMessageCenterScrolled();
 
   EXPECT_FALSE(GetNotificationBarLabel()->GetVisible());
   // ClearAll label should always be visible.
@@ -654,7 +660,7 @@
 // time (this prevents the user from over-scrolling and showing multiple
 // animations when they scroll very quickly). Before, users could scroll fast
 // and have a large amount of icons, instead of keeping it to 3.
-TEST_P(UnifiedMessageCenterViewTest, StackingIconsNeverMoreThanThree) {
+TEST_P(NotificationCenterViewTest, StackingIconsNeverMoreThanThree) {
   for (int i = 0; i < 20; ++i)
     AddNotification(false);
   CreateMessageCenterView();
@@ -662,7 +668,7 @@
   auto bottom_position = GetScrollBar()->bounds().bottom();
   if (features::IsNotificationsRefreshEnabled()) {
     GetScroller()->ScrollToPosition(GetScrollBar(), bottom_position);
-    message_center_view()->OnMessageCenterScrolled();
+    notification_center_view()->OnMessageCenterScrolled();
   }
 
   // Force animations to happen, so we can see if multiple animations trigger.
@@ -675,7 +681,7 @@
                                     features::IsNotificationsRefreshEnabled()
                                         ? bottom_position - scroll_amount
                                         : scroll_amount);
-    message_center_view()->OnMessageCenterScrolled();
+    notification_center_view()->OnMessageCenterScrolled();
 
     auto icons_container_children =
         GetNotificationBarIconsContainer()->children();
@@ -695,21 +701,21 @@
 }
 
 // Flaky: crbug.com/1163575
-TEST_P(UnifiedMessageCenterViewTest,
+TEST_P(NotificationCenterViewTest,
        DISABLED_StackingCounterNotificationRemoval) {
   std::vector<std::string> ids = AddManyNotifications();
   CreateMessageCenterView();
-  EXPECT_TRUE(message_center_view()->GetVisible());
+  EXPECT_TRUE(notification_center_view()->GetVisible());
 
   // MessageCenterView is maxed out.
-  EXPECT_GT(GetMessageListView()->bounds().height(),
-            message_center_view()->bounds().height());
+  EXPECT_GT(GetNotificationListView()->bounds().height(),
+            notification_center_view()->bounds().height());
 
   // Dismiss until there are 2 notifications. The bar should still be visible.
   EXPECT_TRUE(GetNotificationBar()->GetVisible());
   for (size_t i = 0; (i + 2) < ids.size(); ++i) {
     MessageCenter::Get()->RemoveNotification(ids[i], true /* by_user */);
-    AnimateMessageListToEnd();
+    AnimateNotificationListToEnd();
   }
   EXPECT_TRUE(GetNotificationBar()->GetVisible());
   EXPECT_FALSE(GetNotificationBarLabel()->GetVisible());
@@ -717,8 +723,8 @@
 
   // The MessageCenterView should be tall enough to contain the bar, two
   // notifications.
-  EXPECT_EQ(kStackedNotificationBarHeight + GetMessageListView()->height(),
-            message_center_view()->height());
+  EXPECT_EQ(kStackedNotificationBarHeight + GetNotificationListView()->height(),
+            notification_center_view()->height());
 
   // Dismiss until there is only 1 notification left. The bar should be
   // hidden after an animation.
@@ -727,24 +733,24 @@
   EXPECT_TRUE(GetNotificationBar()->GetVisible());
 
   // The HIDE_STACKING_BAR animation starts after the notification is slid out.
-  AnimateMessageListToEnd();
+  AnimateNotificationListToEnd();
   auto* hide_animation = GetMessageCenterAnimation();
   EXPECT_TRUE(hide_animation->is_animating());
   EXPECT_TRUE(GetNotificationBar()->GetVisible());
 
   // Animate to middle. The bar should still be visible.
-  AnimateMessageListToMiddle();
+  AnimateNotificationListToMiddle();
   hide_animation->SetCurrentValue(0.5);
-  message_center_view()->AnimationProgressed(hide_animation);
+  notification_center_view()->AnimationProgressed(hide_animation);
   EXPECT_TRUE(GetNotificationBar()->GetVisible());
 
   // Animate to end. The bar should now be hidden.
-  AnimateMessageListToEnd();
+  AnimateNotificationListToEnd();
   hide_animation->End();
   EXPECT_FALSE(GetNotificationBar()->GetVisible());
 }
 
-TEST_P(UnifiedMessageCenterViewTest, StackingCounterLabelRelaidOutOnScroll) {
+TEST_P(NotificationCenterViewTest, StackingCounterLabelRelaidOutOnScroll) {
   // Open the message center at the top of the notification list so the stacking
   // bar is hidden by default.
   std::string id = AddNotification();
@@ -760,7 +766,7 @@
 
   if (features::IsNotificationsRefreshEnabled()) {
     GetScroller()->ScrollToPosition(GetScrollBar(), bottom_position);
-    message_center_view()->OnMessageCenterScrolled();
+    notification_center_view()->OnMessageCenterScrolled();
   }
 
   EXPECT_FALSE(GetNotificationBarLabel()->GetVisible());
@@ -771,7 +777,7 @@
                                   features::IsNotificationsRefreshEnabled()
                                       ? bottom_position - scroll_amount
                                       : scroll_amount);
-  message_center_view()->OnMessageCenterScrolled();
+  notification_center_view()->OnMessageCenterScrolled();
   RelayoutMessageCenterViewForTest();
   EXPECT_TRUE(GetNotificationBarLabel()->GetVisible());
   int label_width = GetNotificationBarLabel()->bounds().width();
@@ -784,12 +790,12 @@
                                   features::IsNotificationsRefreshEnabled()
                                       ? bottom_position - scroll_amount
                                       : scroll_amount);
-  message_center_view()->OnMessageCenterScrolled();
+  notification_center_view()->OnMessageCenterScrolled();
   RelayoutMessageCenterViewForTest();
   EXPECT_GT(GetNotificationBarLabel()->bounds().width(), label_width);
 }
 
-TEST_P(UnifiedMessageCenterViewTest, StackingCounterVisibility) {
+TEST_P(NotificationCenterViewTest, StackingCounterVisibility) {
   std::string id0 = AddNotification();
   std::string id1 = AddNotification();
   CreateMessageCenterView();
@@ -799,7 +805,7 @@
   EXPECT_TRUE(GetNotificationBarClearAllButton()->GetVisible());
 
   MessageCenter::Get()->RemoveNotification(id0, true /* by_user */);
-  AnimateMessageListToEnd();
+  AnimateNotificationListToEnd();
   auto* hide_animation = GetMessageCenterAnimation();
   hide_animation->End();
 
@@ -833,12 +839,12 @@
 }
 
 INSTANTIATE_TEST_SUITE_P(All,
-                         UnifiedMessageCenterViewInWidgetTest,
+                         NotificationCenterViewInWidgetTest,
                          testing::Bool() /* IsNotificationsRefreshEnabled()
                          */);
 
 // We need a widget to initialize a FocusManager.
-TEST_P(UnifiedMessageCenterViewInWidgetTest,
+TEST_P(NotificationCenterViewInWidgetTest,
        FocusClearedAfterNotificationRemoval) {
   CreateMessageCenterView();
 
@@ -857,11 +863,11 @@
 
   // Remove the notification and observe that the focus is cleared.
   MessageCenter::Get()->RemoveNotification(id1, true /* by_user */);
-  AnimateMessageListToEnd();
-  EXPECT_FALSE(message_center_view()->GetFocusManager()->GetFocusedView());
+  AnimateNotificationListToEnd();
+  EXPECT_FALSE(notification_center_view()->GetFocusManager()->GetFocusedView());
 }
 
-TEST_P(UnifiedMessageCenterViewTest, CollapseAndExpand_NonAnimated) {
+TEST_P(NotificationCenterViewTest, CollapseAndExpand_NonAnimated) {
   AddNotification();
   AddNotification();
   CreateMessageCenterView();
@@ -870,66 +876,66 @@
   EXPECT_FALSE(GetNotificationBarExpandAllButton()->GetVisible());
 
   // Set to collapsed state.
-  message_center_view()->SetCollapsed(false /* animate */);
+  notification_center_view()->SetCollapsed(false /* animate */);
   EXPECT_FALSE(GetScroller()->GetVisible());
   EXPECT_TRUE(GetNotificationBar()->GetVisible());
   EXPECT_TRUE(GetNotificationBarExpandAllButton()->GetVisible());
   EXPECT_FALSE(GetNotificationBarClearAllButton()->GetVisible());
 
   // Set back to expanded state.
-  message_center_view()->SetExpanded();
+  notification_center_view()->SetExpanded();
   EXPECT_FALSE(GetNotificationBarExpandAllButton()->GetVisible());
   EXPECT_TRUE(GetNotificationBarClearAllButton()->GetVisible());
   EXPECT_TRUE(GetScroller()->GetVisible());
 }
 
-TEST_P(UnifiedMessageCenterViewTest, CollapseAndExpand_Animated) {
+TEST_P(NotificationCenterViewTest, CollapseAndExpand_Animated) {
   AddNotification();
   AddNotification();
   CreateMessageCenterView();
   EXPECT_TRUE(GetScroller()->GetVisible());
 
   // Set to collapsed state with animation.
-  message_center_view()->SetCollapsed(true /* animate */);
+  notification_center_view()->SetCollapsed(true /* animate */);
   auto* collapse_animation = GetMessageCenterAnimation();
   EXPECT_TRUE(collapse_animation->is_animating());
 
   // The scroller should be hidden at the half way point.
   collapse_animation->SetCurrentValue(0.5);
-  message_center_view()->AnimationProgressed(collapse_animation);
+  notification_center_view()->AnimationProgressed(collapse_animation);
   EXPECT_FALSE(GetScroller()->GetVisible());
   EXPECT_TRUE(GetNotificationBar()->GetVisible());
 
   collapse_animation->End();
-  AnimateMessageListToEnd();
+  AnimateNotificationListToEnd();
   EXPECT_TRUE(GetNotificationBarExpandAllButton()->GetVisible());
   EXPECT_FALSE(GetNotificationBarClearAllButton()->GetVisible());
 
   // Set back to expanded state.
-  message_center_view()->SetExpanded();
+  notification_center_view()->SetExpanded();
   EXPECT_FALSE(GetNotificationBarExpandAllButton()->GetVisible());
   EXPECT_TRUE(GetNotificationBarClearAllButton()->GetVisible());
   EXPECT_TRUE(GetScroller()->GetVisible());
 }
 
-TEST_P(UnifiedMessageCenterViewTest, CollapseAndExpand_NoNotifications) {
+TEST_P(NotificationCenterViewTest, CollapseAndExpand_NoNotifications) {
   CreateMessageCenterView();
-  EXPECT_FALSE(message_center_view()->GetVisible());
+  EXPECT_FALSE(notification_center_view()->GetVisible());
 
   // Setting to the collapsed state should do nothing.
-  message_center_view()->SetCollapsed(true /* animate */);
-  EXPECT_FALSE(message_center_view()->GetVisible());
+  notification_center_view()->SetCollapsed(true /* animate */);
+  EXPECT_FALSE(notification_center_view()->GetVisible());
 
   // Same with setting it back to the expanded state.
-  message_center_view()->SetExpanded();
-  EXPECT_FALSE(message_center_view()->GetVisible());
+  notification_center_view()->SetExpanded();
+  EXPECT_FALSE(notification_center_view()->GetVisible());
 }
 
-TEST_P(UnifiedMessageCenterViewTest, ClearAllButtonHeight) {
+TEST_P(NotificationCenterViewTest, ClearAllButtonHeight) {
   std::string id0 = AddNotification();
   std::string id1 = AddNotification();
   CreateMessageCenterView();
-  EXPECT_TRUE(message_center_view()->GetVisible());
+  EXPECT_TRUE(notification_center_view()->GetVisible());
   EXPECT_TRUE(GetNotificationBar()->GetVisible());
   EXPECT_TRUE(GetNotificationBarClearAllButton()->GetVisible());
 
@@ -945,13 +951,13 @@
             GetNotificationBarClearAllButton()->height());
 }
 
-TEST_P(UnifiedMessageCenterViewTest, StackedNotificationCount) {
+TEST_P(NotificationCenterViewTest, StackedNotificationCount) {
   // There should not be any stacked notifications in the expanded message
   // center with just one notification added.
   AddNotification();
   CreateMessageCenterView();
-  message_center_view()->SetExpanded();
-  EXPECT_TRUE(message_center_view()->GetVisible());
+  notification_center_view()->SetExpanded();
+  EXPECT_TRUE(notification_center_view()->GetVisible());
   EXPECT_EQ(1, total_notification_count());
   EXPECT_EQ(0, stacked_notification_count());
 
diff --git a/ash/system/message_center/unified_message_list_view.cc b/ash/system/notification_center/notification_list_view.cc
similarity index 88%
rename from ash/system/message_center/unified_message_list_view.cc
rename to ash/system/notification_center/notification_list_view.cc
index cae7fc4..83c3364 100644
--- a/ash/system/message_center/unified_message_list_view.cc
+++ b/ash/system/notification_center/notification_list_view.cc
@@ -1,8 +1,8 @@
-// Copyright 2018 The Chromium Authors
+// Copyright 2022 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ash/system/message_center/unified_message_list_view.h"
+#include "ash/system/notification_center/notification_list_view.h"
 
 #include <string>
 
@@ -15,7 +15,7 @@
 #include "ash/system/message_center/message_view_factory.h"
 #include "ash/system/message_center/metrics_utils.h"
 #include "ash/system/message_center/notification_swipe_control_view.h"
-#include "ash/system/message_center/unified_message_center_view.h"
+#include "ash/system/notification_center/notification_center_view.h"
 #include "ash/system/tray/tray_constants.h"
 #include "ash/system/unified/unified_system_tray_model.h"
 #include "base/auto_reset.h"
@@ -27,6 +27,7 @@
 #include "base/metrics/histogram_macros.h"
 #include "base/ranges/algorithm.h"
 #include "base/time/time.h"
+#include "ui/base/metadata/metadata_impl_macros.h"
 #include "ui/compositor/compositor.h"
 #include "ui/gfx/animation/linear_animation.h"
 #include "ui/gfx/canvas.h"
@@ -86,13 +87,12 @@
 }  // namespace
 
 // Container view of notification and swipe control.
-// All children of UnifiedMessageListView should be MessageViewContainer.
-class UnifiedMessageListView::MessageViewContainer
-    : public MessageView::Observer,
-      public views::View {
+// All children of NotificationListView should be MessageViewContainer.
+class NotificationListView::MessageViewContainer : public MessageView::Observer,
+                                                   public views::View {
  public:
   MessageViewContainer(MessageView* message_view,
-                       UnifiedMessageListView* list_view)
+                       NotificationListView* list_view)
       : message_view_(message_view),
         list_view_(list_view),
         control_view_(new NotificationSwipeControlView(message_view)) {
@@ -224,7 +224,7 @@
     return message_view_->GetSlideAmount() < 0 ? -1 : 1;
   }
 
-  // Allows UnifiedMessageListView to force preferred size to change during
+  // Allows NotificationListView to force preferred size to change during
   // animations.
   void TriggerPreferredSizeChangedForAnimation() {
     views::View::PreferredSizeChanged();
@@ -237,7 +237,7 @@
       return;
 
     // PreferredSizeChanged will trigger
-    // UnifiedMessageListView::ChildPreferredSizeChanged.
+    // NotificationListView::ChildPreferredSizeChanged.
     base::ScopedClosureRunner defer_preferred_size_changed(base::BindOnce(
         &MessageViewContainer::PreferredSizeChanged, base::Unretained(this)));
 
@@ -407,12 +407,12 @@
   bool need_update_corner_radius_ = true;
 
   MessageView* const message_view_;
-  UnifiedMessageListView* const list_view_;
+  NotificationListView* const list_view_;
   NotificationSwipeControlView* const control_view_;
 };
 
-UnifiedMessageListView::UnifiedMessageListView(
-    UnifiedMessageCenterView* message_center_view,
+NotificationListView::NotificationListView(
+    NotificationCenterView* message_center_view,
     scoped_refptr<UnifiedSystemTrayModel> model)
     : views::AnimationDelegateViews(this),
       message_center_view_(message_center_view),
@@ -432,14 +432,14 @@
   }
 }
 
-UnifiedMessageListView::~UnifiedMessageListView() {
+NotificationListView::~NotificationListView() {
   DCHECK(model_);
   model_->ClearNotificationChanges();
   for (auto* view : children())
     AsMVC(view)->StoreExpandedState(model_.get());
 }
 
-void UnifiedMessageListView::Init() {
+void NotificationListView::Init() {
   DCHECK(model_);
   bool is_latest = true;
   for (auto* notification :
@@ -459,7 +459,7 @@
   UpdateBounds();
 }
 
-void UnifiedMessageListView::ClearAllWithAnimation() {
+void NotificationListView::ClearAllWithAnimation() {
   if (state_ == State::CLEAR_ALL_STACKED || state_ == State::CLEAR_ALL_VISIBLE)
     return;
   ResetBounds();
@@ -487,7 +487,7 @@
 }
 
 std::vector<message_center::Notification*>
-UnifiedMessageListView::GetAllNotifications() const {
+NotificationListView::GetAllNotifications() const {
   std::vector<message_center::Notification*> notifications;
   for (views::View* view : children()) {
     // The view may be present in the view hierarchy, but deleted in the message
@@ -500,7 +500,7 @@
   return notifications;
 }
 
-std::vector<std::string> UnifiedMessageListView::GetAllNotificationIds() const {
+std::vector<std::string> NotificationListView::GetAllNotificationIds() const {
   std::vector<std::string> notifications;
   for (views::View* view : children()) {
     notifications.insert(notifications.begin(),
@@ -510,7 +510,7 @@
 }
 
 std::vector<message_center::Notification*>
-UnifiedMessageListView::GetNotificationsAboveY(int y_offset) const {
+NotificationListView::GetNotificationsAboveY(int y_offset) const {
   std::vector<message_center::Notification*> notifications;
   for (views::View* view : children()) {
     const int bottom_limit =
@@ -526,7 +526,7 @@
 }
 
 std::vector<message_center::Notification*>
-UnifiedMessageListView::GetNotificationsBelowY(int y_offset) const {
+NotificationListView::GetNotificationsBelowY(int y_offset) const {
   std::vector<message_center::Notification*> notifications;
   for (views::View* view : children()) {
     const int bottom_limit =
@@ -541,7 +541,7 @@
   return notifications;
 }
 
-std::vector<std::string> UnifiedMessageListView::GetNotificationIdsAboveY(
+std::vector<std::string> NotificationListView::GetNotificationIdsAboveY(
     int y_offset) const {
   std::vector<std::string> notifications;
   for (views::View* view : children()) {
@@ -555,7 +555,7 @@
   return notifications;
 }
 
-std::vector<std::string> UnifiedMessageListView::GetNotificationIdsBelowY(
+std::vector<std::string> NotificationListView::GetNotificationIdsBelowY(
     int y_offset) const {
   std::vector<std::string> notifications;
   for (views::View* view : children()) {
@@ -568,11 +568,11 @@
   return notifications;
 }
 
-int UnifiedMessageListView::GetTotalNotificationCount() const {
+int NotificationListView::GetTotalNotificationCount() const {
   return static_cast<int>(children().size());
 }
 
-int UnifiedMessageListView::GetTotalPinnedNotificationCount() const {
+int NotificationListView::GetTotalPinnedNotificationCount() const {
   int count = 0;
   for (auto* child : children()) {
     if (AsMVC(child)->IsPinned())
@@ -581,11 +581,11 @@
   return count;
 }
 
-bool UnifiedMessageListView::IsAnimating() const {
+bool NotificationListView::IsAnimating() const {
   return animation_->is_animating();
 }
 
-bool UnifiedMessageListView::IsAnimatingExpandOrCollapseContainer(
+bool NotificationListView::IsAnimatingExpandOrCollapseContainer(
     const views::View* view) const {
   if (!view || !expand_or_collapsing_container_)
     return false;
@@ -596,7 +596,7 @@
   return message_view_container == expand_or_collapsing_container_;
 }
 
-void UnifiedMessageListView::ChildPreferredSizeChanged(views::View* child) {
+void NotificationListView::ChildPreferredSizeChanged(views::View* child) {
   if (ignore_size_change_)
     return;
 
@@ -630,13 +630,13 @@
   ResetBounds();
 }
 
-void UnifiedMessageListView::PreferredSizeChanged() {
+void NotificationListView::PreferredSizeChanged() {
   views::View::PreferredSizeChanged();
   if (message_center_view_)
     message_center_view_->ListPreferredSizeChanged();
 }
 
-void UnifiedMessageListView::Layout() {
+void NotificationListView::Layout() {
   for (auto* child : children()) {
     auto* view = AsMVC(child);
     if (state_ == State::IDLE) {
@@ -648,7 +648,7 @@
   }
 }
 
-gfx::Rect UnifiedMessageListView::GetNotificationBounds(
+gfx::Rect NotificationListView::GetNotificationBounds(
     const std::string& notification_id) const {
   const MessageViewContainer* child = nullptr;
   if (!notification_id.empty())
@@ -656,11 +656,11 @@
   return child ? child->bounds() : GetLastNotificationBounds();
 }
 
-gfx::Rect UnifiedMessageListView::GetLastNotificationBounds() const {
+gfx::Rect NotificationListView::GetLastNotificationBounds() const {
   return children().empty() ? gfx::Rect() : children().back()->bounds();
 }
 
-gfx::Rect UnifiedMessageListView::GetNotificationBoundsBelowY(
+gfx::Rect NotificationListView::GetNotificationBoundsBelowY(
     int y_offset) const {
   const auto it = base::ranges::lower_bound(
       children(), y_offset, {},
@@ -668,7 +668,7 @@
   return (it == children().cend()) ? gfx::Rect() : (*it)->bounds();
 }
 
-gfx::Size UnifiedMessageListView::CalculatePreferredSize() const {
+gfx::Size NotificationListView::CalculatePreferredSize() const {
   if (state_ == State::IDLE)
     return gfx::Size(message_view_width_, target_height_);
 
@@ -677,17 +677,13 @@
                                                target_height_));
 }
 
-const char* UnifiedMessageListView::GetClassName() const {
-  return "UnifiedMessageListView";
-}
-
-void UnifiedMessageListView::AnimateResize() {
-  // TODO(crbug/1330026): Refactor UnifiedMessageListView animations to use
+void NotificationListView::AnimateResize() {
+  // TODO(crbug/1330026): Refactor NotificationListView animations to use
   // animation builder instead of the existing layout based animations.
 }
 
 message_center::MessageView*
-UnifiedMessageListView::GetMessageViewForNotificationId(const std::string& id) {
+NotificationListView::GetMessageViewForNotificationId(const std::string& id) {
   auto it = base::ranges::find(children(), id, [](auto* child) {
     DCHECK(child->GetClassName() == kMessageViewContainerClassName);
     return static_cast<MessageViewContainer*>(child)
@@ -700,7 +696,7 @@
   return static_cast<MessageViewContainer*>(*it)->message_view();
 }
 
-void UnifiedMessageListView::ConvertNotificationViewToGroupedNotificationView(
+void NotificationListView::ConvertNotificationViewToGroupedNotificationView(
     const std::string& ungrouped_notification_id,
     const std::string& new_grouped_notification_id) {
   auto* message_view =
@@ -709,14 +705,14 @@
     message_view->set_notification_id(new_grouped_notification_id);
 }
 
-void UnifiedMessageListView::ConvertGroupedNotificationViewToNotificationView(
+void NotificationListView::ConvertGroupedNotificationViewToNotificationView(
     const std::string& grouped_notification_id,
     const std::string& new_single_notification_id) {
   GetMessageViewForNotificationId(grouped_notification_id)
       ->set_notification_id(new_single_notification_id);
 }
 
-void UnifiedMessageListView::OnNotificationAdded(const std::string& id) {
+void NotificationListView::OnNotificationAdded(const std::string& id) {
   auto* notification = MessageCenter::Get()->FindVisibleNotificationById(id);
   if (!notification)
     return;
@@ -772,8 +768,8 @@
   ResetBounds();
 }
 
-void UnifiedMessageListView::OnNotificationRemoved(const std::string& id,
-                                                   bool by_user) {
+void NotificationListView::OnNotificationRemoved(const std::string& id,
+                                                 bool by_user) {
   if (ignore_notification_remove_)
     return;
 
@@ -794,7 +790,7 @@
     child->SlideOutAndClose();
 }
 
-void UnifiedMessageListView::OnNotificationSlidOut() {
+void NotificationListView::OnNotificationSlidOut() {
   DeleteRemovedNotifications();
 
   // |message_center_view_| can be null in tests.
@@ -806,7 +802,7 @@
   StartAnimation();
 }
 
-void UnifiedMessageListView::OnNotificationUpdated(const std::string& id) {
+void NotificationListView::OnNotificationUpdated(const std::string& id) {
   auto* notification = MessageCenter::Get()->FindVisibleNotificationById(id);
   if (!notification)
     return;
@@ -823,8 +819,7 @@
   ResetBounds();
 }
 
-void UnifiedMessageListView::OnSlideStarted(
-    const std::string& notification_id) {
+void NotificationListView::OnSlideStarted(const std::string& notification_id) {
   // When the swipe control for |notification_id| is shown, hide all other swipe
   // controls.
   for (auto* child : children()) {
@@ -834,25 +829,25 @@
   }
 }
 
-void UnifiedMessageListView::OnCloseButtonPressed(
+void NotificationListView::OnCloseButtonPressed(
     const std::string& notification_id) {
   metrics_utils::LogClosedByUser(notification_id, /*is_swipe=*/false,
                                  /*is_popup=*/false);
 }
 
-void UnifiedMessageListView::OnSettingsButtonPressed(
+void NotificationListView::OnSettingsButtonPressed(
     const std::string& notification_id) {
   metrics_utils::LogSettingsShown(notification_id, /*is_slide_controls=*/false,
                                   /*is_popup=*/false);
 }
 
-void UnifiedMessageListView::OnSnoozeButtonPressed(
+void NotificationListView::OnSnoozeButtonPressed(
     const std::string& notification_id) {
   metrics_utils::LogSnoozed(notification_id, /*is_slide_controls=*/false,
                             /*is_popup=*/false);
 }
 
-void UnifiedMessageListView::AnimationEnded(const gfx::Animation* animation) {
+void NotificationListView::AnimationEnded(const gfx::Animation* animation) {
   if (throughput_tracker_) {
     // Reset `throughput_tracker_` to reset animation metrics recording.
     throughput_tracker_->Stop();
@@ -886,7 +881,7 @@
     StartAnimation();
 }
 
-void UnifiedMessageListView::AnimationProgressed(
+void NotificationListView::AnimationProgressed(
     const gfx::Animation* animation) {
   if (state_ == State::EXPAND_OR_COLLAPSE)
     expand_or_collapsing_container_->TriggerPreferredSizeChangedForAnimation();
@@ -894,12 +889,11 @@
   PreferredSizeChanged();
 }
 
-void UnifiedMessageListView::AnimationCanceled(
-    const gfx::Animation* animation) {
+void NotificationListView::AnimationCanceled(const gfx::Animation* animation) {
   AnimationEnded(animation);
 }
 
-MessageView* UnifiedMessageListView::CreateMessageView(
+MessageView* NotificationListView::CreateMessageView(
     const Notification& notification) {
   auto* message_view =
       MessageViewFactory::Create(notification, /*shown_in_popup=*/false)
@@ -908,7 +902,7 @@
   return message_view;
 }
 
-void UnifiedMessageListView::ConfigureMessageView(
+void NotificationListView::ConfigureMessageView(
     message_center::MessageView* message_view) {
   // Setting grouped notifications as nested is handled in
   // `AshNotificationView`.
@@ -924,37 +918,37 @@
 }
 
 std::vector<message_center::Notification*>
-UnifiedMessageListView::GetStackedNotifications() const {
+NotificationListView::GetStackedNotifications() const {
   return message_center_view_->GetStackedNotifications();
 }
 
 std::vector<std::string>
-UnifiedMessageListView::GetNonVisibleNotificationIdsInViewHierarchy() const {
+NotificationListView::GetNonVisibleNotificationIdsInViewHierarchy() const {
   return message_center_view_->GetNonVisibleNotificationIdsInViewHierarchy();
 }
 
 // static
-const UnifiedMessageListView::MessageViewContainer*
-UnifiedMessageListView::AsMVC(const views::View* v) {
+const NotificationListView::MessageViewContainer* NotificationListView::AsMVC(
+    const views::View* v) {
   return static_cast<const MessageViewContainer*>(v);
 }
 
 // static
-UnifiedMessageListView::MessageViewContainer* UnifiedMessageListView::AsMVC(
+NotificationListView::MessageViewContainer* NotificationListView::AsMVC(
     views::View* v) {
   return static_cast<MessageViewContainer*>(v);
 }
 
-const UnifiedMessageListView::MessageViewContainer*
-UnifiedMessageListView::GetNotificationById(const std::string& id) const {
+const NotificationListView::MessageViewContainer*
+NotificationListView::GetNotificationById(const std::string& id) const {
   const auto i = base::ranges::find(children(), id, [](const auto* v) {
     return AsMVC(v)->GetNotificationId();
   });
   return (i == children().cend()) ? nullptr : AsMVC(*i);
 }
 
-UnifiedMessageListView::MessageViewContainer*
-UnifiedMessageListView::GetNextRemovableNotification() {
+NotificationListView::MessageViewContainer*
+NotificationListView::GetNextRemovableNotification() {
   if (is_notifications_refresh_enabled_) {
     const auto i = base::ranges::find_if_not(
         base::Reversed(children()),
@@ -967,13 +961,13 @@
   return (i == children().cend()) ? nullptr : AsMVC(*i);
 }
 
-void UnifiedMessageListView::CollapseAllNotifications() {
+void NotificationListView::CollapseAllNotifications() {
   base::AutoReset<bool> auto_reset(&ignore_size_change_, true);
   for (auto* child : children())
     AsMVC(child)->Collapse();
 }
 
-void UnifiedMessageListView::UpdateBorders(bool force_update) {
+void NotificationListView::UpdateBorders(bool force_update) {
   // The top notification is drawn with rounded corners when the stacking bar
   // is not shown.
   bool is_top = state_ != State::MOVE_DOWN;
@@ -987,7 +981,7 @@
   }
 }
 
-void UnifiedMessageListView::UpdateBounds() {
+void NotificationListView::UpdateBounds() {
   int y = 0;
   for (auto* child : children()) {
     auto* view = AsMVC(child);
@@ -1012,7 +1006,7 @@
   target_height_ = y;
 }
 
-void UnifiedMessageListView::ResetBounds() {
+void NotificationListView::ResetBounds() {
   DeleteRemovedNotifications();
   UpdateBounds();
 
@@ -1023,7 +1017,7 @@
     PreferredSizeChanged();
 }
 
-void UnifiedMessageListView::InterruptClearAll() {
+void NotificationListView::InterruptClearAll() {
   if (state_ != State::CLEAR_ALL_STACKED && state_ != State::CLEAR_ALL_VISIBLE)
     return;
 
@@ -1036,7 +1030,7 @@
   DeleteRemovedNotifications();
 }
 
-void UnifiedMessageListView::DeleteRemovedNotifications() {
+void NotificationListView::DeleteRemovedNotifications() {
   DCHECK(model_);
   views::View::Views removed_views;
   base::ranges::copy_if(children(), std::back_inserter(removed_views),
@@ -1055,7 +1049,7 @@
   UpdateBorders(/*force_update=*/false);
 }
 
-void UnifiedMessageListView::StartAnimation() {
+void NotificationListView::StartAnimation() {
   DCHECK_NE(state_, State::IDLE);
 
   base::TimeDelta animation_duration;
@@ -1098,7 +1092,7 @@
   animation_->Start();
 }
 
-void UnifiedMessageListView::UpdateClearAllAnimation() {
+void NotificationListView::UpdateClearAllAnimation() {
   DCHECK(state_ == State::CLEAR_ALL_STACKED ||
          state_ == State::CLEAR_ALL_VISIBLE);
 
@@ -1141,7 +1135,7 @@
   }
 }
 
-double UnifiedMessageListView::GetCurrentValue() const {
+double NotificationListView::GetCurrentValue() const {
   gfx::Tween::Type tween;
   switch (state_) {
     case State::IDLE:
@@ -1164,4 +1158,7 @@
   return gfx::Tween::CalculateValue(tween, animation_->GetCurrentValue());
 }
 
+BEGIN_METADATA(NotificationListView, views::View);
+END_METADATA
+
 }  // namespace ash
diff --git a/ash/system/message_center/unified_message_list_view.h b/ash/system/notification_center/notification_list_view.h
similarity index 88%
rename from ash/system/message_center/unified_message_list_view.h
rename to ash/system/notification_center/notification_list_view.h
index 001fb362..4de1e4b6 100644
--- a/ash/system/message_center/unified_message_list_view.h
+++ b/ash/system/notification_center/notification_list_view.h
@@ -1,9 +1,9 @@
-// Copyright 2018 The Chromium Authors
+// Copyright 2022 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ASH_SYSTEM_MESSAGE_CENTER_UNIFIED_MESSAGE_LIST_VIEW_H_
-#define ASH_SYSTEM_MESSAGE_CENTER_UNIFIED_MESSAGE_LIST_VIEW_H_
+#ifndef ASH_SYSTEM_NOTIFICATION_CENTER_NOTIFICATION_LIST_VIEW_H_
+#define ASH_SYSTEM_NOTIFICATION_CENTER_NOTIFICATION_LIST_VIEW_H_
 
 #include "ash/ash_export.h"
 #include "ash/system/unified/unified_system_tray_model.h"
@@ -29,25 +29,26 @@
 
 namespace ash {
 
-class UnifiedMessageCenterView;
+class NotificationCenterView;
 class UnifiedSystemTrayModel;
 
 // Manages list of notifications. The class doesn't know about the ScrollView
-// it's enclosed. This class is used only from UnifiedMessageCenterView.
-class ASH_EXPORT UnifiedMessageListView
+// it's enclosed. This class is used only from NotificationCenterView.
+class ASH_EXPORT NotificationListView
     : public views::View,
       public message_center::MessageCenterObserver,
       public message_center::NotificationViewController,
       public message_center::MessageView::Observer,
       public views::AnimationDelegateViews {
  public:
+  METADATA_HEADER(NotificationListView);
+
   // |message_center_view| can be null in unit tests.
-  UnifiedMessageListView(UnifiedMessageCenterView* message_center_view,
-                         scoped_refptr<UnifiedSystemTrayModel> model);
-  UnifiedMessageListView(const UnifiedMessageListView& other) = delete;
-  UnifiedMessageListView& operator=(const UnifiedMessageListView& other) =
-      delete;
-  ~UnifiedMessageListView() override;
+  NotificationListView(NotificationCenterView* message_center_view,
+                       scoped_refptr<UnifiedSystemTrayModel> model);
+  NotificationListView(const NotificationListView& other) = delete;
+  NotificationListView& operator=(const NotificationListView& other) = delete;
+  ~NotificationListView() override;
 
   // Initializes the view with existing notifications. Should be called right
   // after ctor.
@@ -122,7 +123,6 @@
   void PreferredSizeChanged() override;
   void Layout() override;
   gfx::Size CalculatePreferredSize() const override;
-  const char* GetClassName() const override;
 
   // message_center::NotificationViewController:
   void AnimateResize() override;
@@ -171,13 +171,13 @@
       const;
 
  private:
-  friend class UnifiedMessageCenterViewTest;
-  friend class UnifiedMessageListViewTest;
+  friend class NotificationCenterViewTest;
+  friend class NotificationListViewTest;
   friend class UnifiedMessageCenterBubbleTest;
   class Background;
   class MessageViewContainer;
 
-  // UnifiedMessageListView always runs a single animation at one time. When
+  // NotificationListView always runs a single animation at one time. When
   // `state_` is IDLE, `animation_->is_animating()` is always false and vice
   // versa.
   enum class State {
@@ -207,7 +207,7 @@
   const MessageViewContainer* GetNotificationById(const std::string& id) const;
   MessageViewContainer* GetNotificationById(const std::string& id) {
     return const_cast<MessageViewContainer*>(
-        static_cast<const UnifiedMessageListView*>(this)->GetNotificationById(
+        static_cast<const NotificationListView*>(this)->GetNotificationById(
             id));
   }
 
@@ -249,7 +249,7 @@
   // Updates the state between each Clear All animation phase.
   void UpdateClearAllAnimation();
 
-  UnifiedMessageCenterView* const message_center_view_;
+  NotificationCenterView* const message_center_view_;
   scoped_refptr<UnifiedSystemTrayModel> model_;
 
   // Non-null during State::EXPAND_OR_COLLAPSE. Keeps track of the
@@ -265,7 +265,7 @@
   // ClearAllWithAnimation().
   bool ignore_notification_remove_ = false;
 
-  // Manages notification closing animation. UnifiedMessageListView does not use
+  // Manages notification closing animation. `NotificationListView` does not use
   // implicit animation.
   const std::unique_ptr<gfx::LinearAnimation> animation_;
 
@@ -274,15 +274,15 @@
 
   State state_ = State::IDLE;
 
-  // The height the UnifiedMessageListView starts animating from. If not
+  // The height the `NotificationListView` starts animating from. If not
   // animating, it's ignored.
   int start_height_ = 0;
 
-  // The final height of the UnifiedMessageListView. If not animating, it's same
+  // The final height of `the NotificationListView`. If not animating, it's same
   // as height().
   int target_height_ = 0;
 
-  // True if the UnifiedMessageListView is currently deleting notifications
+  // True if the `NotificationListView` is currently deleting notifications
   // marked for removal. This check is needed to prevent re-entrancing issues
   // (e.g. crbug.com/933327) caused by the View destructor.
   bool is_deleting_removed_notifications_ = false;
@@ -301,4 +301,4 @@
 
 }  // namespace ash
 
-#endif  // ASH_SYSTEM_MESSAGE_CENTER_UNIFIED_MESSAGE_LIST_VIEW_H_
+#endif  // ASH_SYSTEM_NOTIFICATION_CENTER_NOTIFICATION_LIST_VIEW_H_
diff --git a/ash/system/message_center/unified_message_list_view_unittest.cc b/ash/system/notification_center/notification_list_view_unittest.cc
similarity index 90%
rename from ash/system/message_center/unified_message_list_view_unittest.cc
rename to ash/system/notification_center/notification_list_view_unittest.cc
index cc8961be..f862c59 100644
--- a/ash/system/message_center/unified_message_list_view_unittest.cc
+++ b/ash/system/notification_center/notification_list_view_unittest.cc
@@ -1,8 +1,8 @@
-// Copyright 2018 The Chromium Authors
+// Copyright 2022 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ash/system/message_center/unified_message_list_view.h"
+#include "ash/system/notification_center/notification_list_view.h"
 
 #include "ash/bubble/bubble_constants.h"
 #include "ash/constants/ash_features.h"
@@ -71,16 +71,15 @@
   absl::optional<float> slide_amount_;
 };
 
-class TestUnifiedMessageListView : public UnifiedMessageListView {
+class TestNotificationListView : public NotificationListView {
  public:
-  explicit TestUnifiedMessageListView(UnifiedSystemTrayModel* model)
-      : UnifiedMessageListView(nullptr, model) {}
+  explicit TestNotificationListView(UnifiedSystemTrayModel* model)
+      : NotificationListView(nullptr, model) {}
 
-  TestUnifiedMessageListView(const TestUnifiedMessageListView&) = delete;
-  TestUnifiedMessageListView& operator=(const TestUnifiedMessageListView&) =
-      delete;
+  TestNotificationListView(const TestNotificationListView&) = delete;
+  TestNotificationListView& operator=(const TestNotificationListView&) = delete;
 
-  ~TestUnifiedMessageListView() override = default;
+  ~TestNotificationListView() override = default;
 
   void set_stacked_notification_count(int stacked_notification_count) {
     stacked_notifications_.clear();
@@ -99,7 +98,7 @@
     }
   }
 
-  // UnifiedMessageListView:
+  // NotificationListView:
   message_center::MessageView* CreateMessageView(
       const message_center::Notification& notification) override {
     auto* message_view = new TestNotificationView(notification);
@@ -126,16 +125,15 @@
 
 // The base test class, has no params so tests with no params can inherit from
 // this.
-class UnifiedMessageListViewTest : public AshTestBase,
-                                   public views::ViewObserver {
+class NotificationListViewTest : public AshTestBase,
+                                 public views::ViewObserver {
  public:
-  UnifiedMessageListViewTest() = default;
+  NotificationListViewTest() = default;
 
-  UnifiedMessageListViewTest(const UnifiedMessageListViewTest&) = delete;
-  UnifiedMessageListViewTest& operator=(const UnifiedMessageListViewTest&) =
-      delete;
+  NotificationListViewTest(const NotificationListViewTest&) = delete;
+  NotificationListViewTest& operator=(const NotificationListViewTest&) = delete;
 
-  ~UnifiedMessageListViewTest() override = default;
+  ~NotificationListViewTest() override = default;
 
   void SetUp() override {
     AshTestBase::SetUp();
@@ -143,7 +141,7 @@
   }
 
   void TearDown() override {
-    message_list_view_.reset();
+    notification_list_view_.reset();
     model_.reset();
     AshTestBase::TearDown();
   }
@@ -191,15 +189,15 @@
   }
 
   void CreateMessageListView() {
-    message_list_view_ =
-        std::make_unique<TestUnifiedMessageListView>(model_.get());
-    message_list_view_->Init();
-    message_list_view_->AddObserver(this);
-    OnViewPreferredSizeChanged(message_list_view_.get());
+    notification_list_view_ =
+        std::make_unique<TestNotificationListView>(model_.get());
+    notification_list_view_->Init();
+    notification_list_view_->AddObserver(this);
+    OnViewPreferredSizeChanged(notification_list_view_.get());
     size_changed_count_ = 0;
   }
 
-  void DestroyMessageListView() { message_list_view_.reset(); }
+  void DestroyMessageListView() { notification_list_view_.reset(); }
 
   TestNotificationView* GetMessageViewAt(size_t index) const {
     return static_cast<TestNotificationView*>(
@@ -228,8 +226,8 @@
 
   bool IsAnimating() { return message_list_view()->animation_->is_animating(); }
 
-  TestUnifiedMessageListView* message_list_view() const {
-    return message_list_view_.get();
+  TestNotificationListView* message_list_view() const {
+    return notification_list_view_.get();
   }
 
   int size_changed_count() const { return size_changed_count_; }
@@ -243,22 +241,22 @@
   int size_changed_count_ = 0;
 
   scoped_refptr<UnifiedSystemTrayModel> model_;
-  std::unique_ptr<TestUnifiedMessageListView> message_list_view_;
+  std::unique_ptr<TestNotificationListView> notification_list_view_;
 };
 
 // Tests with NotificationsRefresh enabled and disabled.
-class ParameterizedUnifiedMessageListViewTest
-    : public UnifiedMessageListViewTest,
+class ParameterizedNotificationListViewTest
+    : public NotificationListViewTest,
       public testing::WithParamInterface<bool> {
  public:
-  ParameterizedUnifiedMessageListViewTest() = default;
+  ParameterizedNotificationListViewTest() = default;
 
-  ParameterizedUnifiedMessageListViewTest(
-      const ParameterizedUnifiedMessageListViewTest&) = delete;
-  ParameterizedUnifiedMessageListViewTest& operator=(
-      const ParameterizedUnifiedMessageListViewTest&) = delete;
+  ParameterizedNotificationListViewTest(
+      const ParameterizedNotificationListViewTest&) = delete;
+  ParameterizedNotificationListViewTest& operator=(
+      const ParameterizedNotificationListViewTest&) = delete;
 
-  ~ParameterizedUnifiedMessageListViewTest() override = default;
+  ~ParameterizedNotificationListViewTest() override = default;
 
   // AshTestBase:
   void SetUp() override {
@@ -275,7 +273,7 @@
                                  chromeos::features::kDarkLightMode});
     }
 
-    UnifiedMessageListViewTest::SetUp();
+    NotificationListViewTest::SetUp();
   }
 
   int GetMessageCenterNotificationCornerRadius() {
@@ -291,10 +289,10 @@
 };
 
 INSTANTIATE_TEST_SUITE_P(All,
-                         ParameterizedUnifiedMessageListViewTest,
+                         ParameterizedNotificationListViewTest,
                          testing::Bool() /* IsNotificationsRefreshEnabled() */);
 
-TEST_P(ParameterizedUnifiedMessageListViewTest, Open) {
+TEST_P(ParameterizedNotificationListViewTest, Open) {
   auto id0 = AddNotification();
   auto id1 = AddNotification();
   auto id2 = AddNotification();
@@ -354,7 +352,7 @@
   EXPECT_LT(0, message_list_view()->GetPreferredSize().height());
 }
 
-TEST_P(ParameterizedUnifiedMessageListViewTest, AddNotifications) {
+TEST_P(ParameterizedNotificationListViewTest, AddNotifications) {
   CreateMessageListView();
   EXPECT_EQ(0, message_list_view()->GetPreferredSize().height());
 
@@ -368,9 +366,9 @@
   EXPECT_EQ(kMessageCenterNotificationTopBottomCornerRadius,
             GetMessageViewAt(0)->bottom_radius());
 
-  int previous_message_list_view_height =
+  int previous_notification_list_view_height =
       message_list_view()->GetPreferredSize().height();
-  EXPECT_LT(0, previous_message_list_view_height);
+  EXPECT_LT(0, previous_notification_list_view_height);
 
   gfx::Rect previous_bounds = GetMessageViewBounds(0);
   auto id1 = AddNotification();
@@ -380,7 +378,7 @@
             GetMessageViewAt(features::IsNotificationsRefreshEnabled() ? 0 : 1)
                 ->notification_id());
 
-  EXPECT_LT(previous_message_list_view_height,
+  EXPECT_LT(previous_notification_list_view_height,
             message_list_view()->GetPreferredSize().height());
 
   if (!IsNotificationsRefreshEnabled()) {
@@ -411,7 +409,7 @@
             GetMessageViewAt(1)->bottom_radius());
 }
 
-TEST_P(ParameterizedUnifiedMessageListViewTest, RemoveNotification) {
+TEST_P(ParameterizedNotificationListViewTest, RemoveNotification) {
   auto id0 = AddNotification();
   auto id1 = AddNotification();
 
@@ -449,7 +447,7 @@
   EXPECT_EQ(0, message_list_view()->GetPreferredSize().height());
 }
 
-TEST_P(ParameterizedUnifiedMessageListViewTest, CollapseOlderNotifications) {
+TEST_P(ParameterizedNotificationListViewTest, CollapseOlderNotifications) {
   AddNotification();
   CreateMessageListView();
   EXPECT_TRUE(GetMessageViewAt(0)->IsExpanded());
@@ -494,7 +492,7 @@
   }
 }
 
-TEST_P(ParameterizedUnifiedMessageListViewTest, RemovingNotificationAnimation) {
+TEST_P(ParameterizedNotificationListViewTest, RemovingNotificationAnimation) {
   auto id0 = AddNotification(/*pinned=*/false);
   auto id1 = AddNotification();
   auto id2 = AddNotification();
@@ -536,7 +534,7 @@
 }
 
 // Flaky: https://crbug.com/1292774.
-TEST_P(ParameterizedUnifiedMessageListViewTest, DISABLED_ResetAnimation) {
+TEST_P(ParameterizedNotificationListViewTest, DISABLED_ResetAnimation) {
   auto id0 = AddNotification();
   auto id1 = AddNotification();
   CreateMessageListView();
@@ -555,7 +553,7 @@
   EXPECT_EQ(id2, GetMessageViewAt(1)->notification_id());
 }
 
-TEST_P(ParameterizedUnifiedMessageListViewTest, KeepManuallyExpanded) {
+TEST_P(ParameterizedNotificationListViewTest, KeepManuallyExpanded) {
   AddNotification();
   AddNotification();
   CreateMessageListView();
@@ -609,7 +607,7 @@
   }
 }
 
-TEST_P(ParameterizedUnifiedMessageListViewTest,
+TEST_P(ParameterizedNotificationListViewTest,
        ClearAllWithOnlyVisibleNotifications) {
   AddNotification();
   AddNotification();
@@ -652,7 +650,7 @@
   EXPECT_FALSE(IsAnimating());
 }
 
-TEST_P(ParameterizedUnifiedMessageListViewTest,
+TEST_P(ParameterizedNotificationListViewTest,
        ClearAllWithStackingNotifications) {
   AddNotification();
   AddNotification();
@@ -700,7 +698,7 @@
   EXPECT_FALSE(IsAnimating());
 }
 
-TEST_P(ParameterizedUnifiedMessageListViewTest, ClearAllClosedInTheMiddle) {
+TEST_P(ParameterizedNotificationListViewTest, ClearAllClosedInTheMiddle) {
   AddNotification();
   AddNotification();
   AddNotification();
@@ -713,7 +711,7 @@
   EXPECT_TRUE(MessageCenter::Get()->GetVisibleNotifications().empty());
 }
 
-TEST_P(ParameterizedUnifiedMessageListViewTest, ClearAllInterrupted) {
+TEST_P(ParameterizedNotificationListViewTest, ClearAllInterrupted) {
   AddNotification();
   AddNotification();
   AddNotification();
@@ -727,8 +725,7 @@
   EXPECT_TRUE(MessageCenter::Get()->FindVisibleNotificationById(new_id));
 }
 
-TEST_P(ParameterizedUnifiedMessageListViewTest,
-       ClearAllWithPinnedNotifications) {
+TEST_P(ParameterizedNotificationListViewTest, ClearAllWithPinnedNotifications) {
   AddNotification(/*pinned=*/true);
   AddNotification();
   AddNotification();
@@ -740,7 +737,7 @@
 }
 
 // Flaky: https://crbug.com/1292701.
-TEST_P(ParameterizedUnifiedMessageListViewTest,
+TEST_P(ParameterizedNotificationListViewTest,
        DISABLED_UserSwipesAwayNotification) {
   // Show message list with two notifications.
   AddNotification();
@@ -767,7 +764,7 @@
   EXPECT_FALSE(message_list_view()->IsAnimating());
 }
 
-TEST_P(ParameterizedUnifiedMessageListViewTest, InitInSortedOrder) {
+TEST_P(ParameterizedNotificationListViewTest, InitInSortedOrder) {
   // MessageViews should be ordered, from top down: [ id1, id2, id0 ].
   auto id0 = AddNotification(/*pinned=*/true);
   OffsetNotificationTimestamp(id0, 2000 /* milliseconds */);
@@ -789,8 +786,7 @@
   }
 }
 
-TEST_P(ParameterizedUnifiedMessageListViewTest,
-       NotificationAddedInSortedOrder) {
+TEST_P(ParameterizedNotificationListViewTest, NotificationAddedInSortedOrder) {
   auto id0 = AddNotification(/*pinned=*/true);
   OffsetNotificationTimestamp(id0, 3000 /* milliseconds */);
   auto id1 = AddNotification();
@@ -829,19 +825,18 @@
 }
 
 // Tests only with NotificationsRefresh enabled.
-class RefreshedUnifiedMessageListView : public UnifiedMessageListViewTest {
+class RefreshedNotificationListView : public NotificationListViewTest {
  public:
-  RefreshedUnifiedMessageListView() = default;
-  RefreshedUnifiedMessageListView(const RefreshedUnifiedMessageListView&) =
-      delete;
-  RefreshedUnifiedMessageListView& operator=(
-      const RefreshedUnifiedMessageListView&) = delete;
-  ~RefreshedUnifiedMessageListView() override = default;
+  RefreshedNotificationListView() = default;
+  RefreshedNotificationListView(const RefreshedNotificationListView&) = delete;
+  RefreshedNotificationListView& operator=(
+      const RefreshedNotificationListView&) = delete;
+  ~RefreshedNotificationListView() override = default;
 
   void SetUp() override {
     scoped_feature_list_ = std::make_unique<base::test::ScopedFeatureList>();
     scoped_feature_list_->InitAndEnableFeature(features::kNotificationsRefresh);
-    UnifiedMessageListViewTest::SetUp();
+    NotificationListViewTest::SetUp();
   }
 
   // Start sliding the message view at the given index in the list.
@@ -856,7 +851,7 @@
 };
 
 // Tests that preferred size changes upon toggle of expand/collapse.
-TEST_F(RefreshedUnifiedMessageListView, PreferredSizeChangesOnToggle) {
+TEST_F(RefreshedNotificationListView, PreferredSizeChangesOnToggle) {
   AddNotification(/*pinned=*/false, /*expandable=*/true);
   AddNotification(/*pinned=*/false, /*expandable=*/true);
   CreateMessageListView();
@@ -890,7 +885,7 @@
 
 // Tests that expanding a notification while a different notification is
 // expanding is handled gracefully.
-TEST_F(RefreshedUnifiedMessageListView, TwoExpandsInARow) {
+TEST_F(RefreshedNotificationListView, TwoExpandsInARow) {
   AddNotification(/*pinned=*/false, /*expandable=*/true);
   AddNotification(/*pinned=*/false, /*expandable=*/true);
   CreateMessageListView();
@@ -930,7 +925,7 @@
 }
 
 // Tests that collapsing/expanding is reversible.
-TEST_F(RefreshedUnifiedMessageListView, ReverseExpand) {
+TEST_F(RefreshedNotificationListView, ReverseExpand) {
   AddNotification(/*pinned=*/false, /*expandable=*/true);
   AddNotification(/*pinned=*/false, /*expandable=*/true);
   CreateMessageListView();
@@ -957,7 +952,7 @@
 }
 
 // Tests that destroying during a collapse animation does not crash.
-TEST_F(RefreshedUnifiedMessageListView, DestroyMessageListViewDuringCollapse) {
+TEST_F(RefreshedNotificationListView, DestroyMessageListViewDuringCollapse) {
   AddNotification(/*pinned=*/false, /*expandable=*/true);
   AddNotification(/*pinned=*/false, /*expandable=*/true);
   CreateMessageListView();
@@ -970,7 +965,7 @@
 
 // Tests that closing a notification while its collapse animation is ongoing
 // works properly.
-TEST_F(RefreshedUnifiedMessageListView, RemoveNotificationDuringCollapse) {
+TEST_F(RefreshedNotificationListView, RemoveNotificationDuringCollapse) {
   auto id1 = AddNotification(/*pinned=*/false, /*expandable=*/true);
   CreateMessageListView();
   auto* message_view = GetMessageViewAt(0);
@@ -996,7 +991,7 @@
 // Tests that expanding a notification at various stages while it is being
 // closed does not result in an animation.
 // TODO(crbug.com/1292775): Test is flaky.
-TEST_F(RefreshedUnifiedMessageListView,
+TEST_F(RefreshedNotificationListView,
        DISABLED_CollapseDuringCloseResultsInNoCollapseAnimation) {
   auto id1 = AddNotification(/*pinned=*/false, /*expandable=*/true);
   AddNotification(/*pinned=*/false, /*expandable=*/true);
@@ -1008,13 +1003,13 @@
   MessageCenter::Get()->RemoveNotification(id1, /*by_user=*/true);
   EXPECT_EQ(notification_container->GetPreferredSize(), pre_remove_size);
   // Removing the notification does not trigger an animation at the level of
-  // UnifiedMessageListView
+  // NotificationListView
   EXPECT_FALSE(message_list_view()->IsAnimating());
   EXPECT_FALSE(message_list_view()->IsAnimatingExpandOrCollapseContainer(
       notification_container));
 
   // Trigger the collapse before slide out completes, this should not trigger an
-  // animation for UnifiedMessageListView, and no animation should occur.
+  // animation for NotificationListView, and no animation should occur.
   // SlideOut animation happens at a lower level. Also, size changes should be
   // ignored when being removed.
   GetMessageViewAt(0)->SetExpanded(/*expanded=*/false);
@@ -1034,8 +1029,7 @@
 // Tests that collapsing a notification while it is being moved automatically
 // completes both animations.
 // TODO(crbug.com/1292816): Test is flaky.
-TEST_F(RefreshedUnifiedMessageListView,
-       DISABLED_CollapseDuringMoveNoAnimation) {
+TEST_F(RefreshedNotificationListView, DISABLED_CollapseDuringMoveNoAnimation) {
   auto to_be_removed_notification =
       AddNotification(/*pinned=*/false, /*expandable=*/true);
   auto to_be_collapsed_notification =
@@ -1071,7 +1065,7 @@
 
 // Tests that moving a notification while it is already collapsing completes
 // both animations.
-TEST_F(RefreshedUnifiedMessageListView, MoveDuringCollapseNoAnimation) {
+TEST_F(RefreshedNotificationListView, MoveDuringCollapseNoAnimation) {
   auto to_be_removed_notification =
       AddNotification(/*pinned=*/false, /*expandable=*/true);
   auto to_be_collapsed_notification =
@@ -1101,7 +1095,7 @@
       to_be_collapsed_message_view_container->GetPreferredSize().height());
 }
 
-TEST_F(RefreshedUnifiedMessageListView, SlideNotification) {
+TEST_F(RefreshedNotificationListView, SlideNotification) {
   // Show message list with four notifications.
   auto id0 = AddNotification();
   auto id1 = AddNotification();
diff --git a/ash/system/message_center/stacked_notification_bar.cc b/ash/system/notification_center/stacked_notification_bar.cc
similarity index 94%
rename from ash/system/message_center/stacked_notification_bar.cc
rename to ash/system/notification_center/stacked_notification_bar.cc
index 6e37f1e0..a549dfd 100644
--- a/ash/system/message_center/stacked_notification_bar.cc
+++ b/ash/system/notification_center/stacked_notification_bar.cc
@@ -1,8 +1,8 @@
-// Copyright 2019 The Chromium Authors
+// Copyright 2022 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ash/system/message_center/stacked_notification_bar.h"
+#include "ash/system/notification_center/stacked_notification_bar.h"
 
 #include "ash/constants/ash_features.h"
 #include "ash/strings/grit/ash_strings.h"
@@ -43,7 +43,7 @@
 
   StackingBarLabelButton(PressedCallback callback,
                          const std::u16string& text,
-                         UnifiedMessageCenterView* message_center_view)
+                         NotificationCenterView* notification_center_view)
       : PillButton(
             std::move(callback),
             text,
@@ -53,7 +53,7 @@
             /*use_light_colors=*/!features::IsNotificationsRefreshEnabled(),
             /*rounded_highlight_path=*/
             features::IsNotificationsRefreshEnabled()),
-        message_center_view_(message_center_view) {
+        notification_center_view_(notification_center_view) {
     const SkColor bg_color =
         features::IsNotificationsRefreshEnabled()
             ? gfx::kPlaceholderColor
@@ -70,12 +70,12 @@
 
   // PillButton:
   void AboutToRequestFocusFromTabTraversal(bool reverse) override {
-    if (message_center_view_->collapsed() && HasFocus())
-      message_center_view_->FocusOut(reverse);
+    if (notification_center_view_->collapsed() && HasFocus())
+      notification_center_view_->FocusOut(reverse);
   }
 
  private:
-  UnifiedMessageCenterView* message_center_view_;
+  NotificationCenterView* notification_center_view_;
 };
 
 BEGIN_METADATA(StackingBarLabelButton, PillButton)
@@ -241,24 +241,24 @@
 };
 
 StackedNotificationBar::StackedNotificationBar(
-    UnifiedMessageCenterView* message_center_view)
-    : message_center_view_(message_center_view),
+    NotificationCenterView* notification_center_view)
+    : notification_center_view_(notification_center_view),
       notification_icons_container_(
           AddChildView(std::make_unique<views::View>())),
       count_label_(AddChildView(std::make_unique<views::Label>())),
       spacer_(AddChildView(std::make_unique<views::View>())),
       clear_all_button_(AddChildView(std::make_unique<StackingBarLabelButton>(
-          base::BindRepeating(&UnifiedMessageCenterView::ClearAllNotifications,
-                              base::Unretained(message_center_view_)),
+          base::BindRepeating(&NotificationCenterView::ClearAllNotifications,
+                              base::Unretained(notification_center_view_)),
           l10n_util::GetStringUTF16(
               IDS_ASH_MESSAGE_CENTER_CLEAR_ALL_BUTTON_LABEL),
-          message_center_view))),
+          notification_center_view))),
       expand_all_button_(AddChildView(std::make_unique<StackingBarLabelButton>(
-          base::BindRepeating(&UnifiedMessageCenterView::ExpandMessageCenter,
-                              base::Unretained(message_center_view_)),
+          base::BindRepeating(&NotificationCenterView::ExpandMessageCenter,
+                              base::Unretained(notification_center_view_)),
           l10n_util::GetStringUTF16(
               IDS_ASH_MESSAGE_CENTER_EXPAND_ALL_NOTIFICATIONS_BUTTON_LABEL),
-          message_center_view))),
+          notification_center_view))),
       layout_manager_(SetLayoutManager(std::make_unique<views::BoxLayout>(
           views::BoxLayout::Orientation::kHorizontal,
           features::IsNotificationsRefreshEnabled() ? kNotificationBarPadding
@@ -336,7 +336,7 @@
 }
 
 void StackedNotificationBar::SetAnimationState(
-    UnifiedMessageCenterAnimationState animation_state) {
+    NotificationCenterAnimationState animation_state) {
   animation_state_ = animation_state;
   UpdateVisibility();
 }
@@ -559,15 +559,15 @@
     clear_all_button_->SetVisible(show_clear_all);
 
   switch (animation_state_) {
-    case UnifiedMessageCenterAnimationState::IDLE:
+    case NotificationCenterAnimationState::IDLE:
       SetVisible(
           (stacked_notification_count_ && total_notification_count_ > 1) ||
           show_clear_all || expand_all_button_->GetVisible());
       break;
-    case UnifiedMessageCenterAnimationState::HIDE_STACKING_BAR:
+    case NotificationCenterAnimationState::HIDE_STACKING_BAR:
       SetVisible(true);
       break;
-    case UnifiedMessageCenterAnimationState::COLLAPSE:
+    case NotificationCenterAnimationState::COLLAPSE:
       SetVisible(
           (stacked_notification_count_ && total_notification_count_ > 1) ||
           show_clear_all || expand_all_button_->GetVisible());
@@ -580,7 +580,8 @@
   // know the position where it may have been added.
   notification_icons_container_->RemoveAllChildViews();
   stacked_notification_count_ = 0;
-  UpdateStackedNotifications(message_center_view_->GetStackedNotifications());
+  UpdateStackedNotifications(
+      notification_center_view_->GetStackedNotifications());
 }
 
 void StackedNotificationBar::OnNotificationRemoved(const std::string& id,
diff --git a/ash/system/message_center/stacked_notification_bar.h b/ash/system/notification_center/stacked_notification_bar.h
similarity index 84%
rename from ash/system/message_center/stacked_notification_bar.h
rename to ash/system/notification_center/stacked_notification_bar.h
index de61f90..84d1b1b 100644
--- a/ash/system/message_center/stacked_notification_bar.h
+++ b/ash/system/notification_center/stacked_notification_bar.h
@@ -1,11 +1,11 @@
-// Copyright 2019 The Chromium Authors
+// Copyright 2022 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ASH_SYSTEM_MESSAGE_CENTER_STACKED_NOTIFICATION_BAR_H_
-#define ASH_SYSTEM_MESSAGE_CENTER_STACKED_NOTIFICATION_BAR_H_
+#ifndef ASH_SYSTEM_NOTIFICATION_CENTER_STACKED_NOTIFICATION_BAR_H_
+#define ASH_SYSTEM_NOTIFICATION_CENTER_STACKED_NOTIFICATION_BAR_H_
 
-#include "ash/system/message_center/unified_message_center_view.h"
+#include "ash/system/notification_center/notification_center_view.h"
 #include "base/memory/weak_ptr.h"
 #include "ui/message_center/message_center_observer.h"
 #include "ui/views/view.h"
@@ -28,7 +28,7 @@
                                public message_center::MessageCenterObserver {
  public:
   explicit StackedNotificationBar(
-      UnifiedMessageCenterView* message_center_view);
+      NotificationCenterView* notification_center_view);
 
   StackedNotificationBar(const StackedNotificationBar&) = delete;
   StackedNotificationBar& operator=(const StackedNotificationBar&) = delete;
@@ -43,7 +43,7 @@
               std::vector<message_center::Notification*> stacked_notifications);
 
   // Sets the current animation state.
-  void SetAnimationState(UnifiedMessageCenterAnimationState animation_state);
+  void SetAnimationState(NotificationCenterAnimationState animation_state);
 
   // Set notification bar state to collapsed.
   void SetCollapsed();
@@ -62,7 +62,7 @@
 
  private:
   class StackedNotificationBarIcon;
-  friend class UnifiedMessageCenterViewTest;
+  friend class NotificationCenterViewTest;
 
   // Clean up icon view after it's removal animation is complete, adds an icon
   // for `notification` if needed. Called from a callback registered in
@@ -100,10 +100,10 @@
   int pinned_notification_count_ = 0;
   int stacked_notification_count_ = 0;
 
-  UnifiedMessageCenterAnimationState animation_state_ =
-      UnifiedMessageCenterAnimationState::IDLE;
+  NotificationCenterAnimationState animation_state_ =
+      NotificationCenterAnimationState::IDLE;
 
-  UnifiedMessageCenterView* const message_center_view_;
+  NotificationCenterView* const notification_center_view_;
   views::View* notification_icons_container_;
   views::Label* const count_label_;
   views::View* const spacer_;
@@ -116,4 +116,4 @@
 
 }  // namespace ash
 
-#endif  // ASH_SYSTEM_MESSAGE_CENTER_STACKED_NOTIFICATION_BAR_H_
+#endif  // ASH_SYSTEM_NOTIFICATION_CENTER_STACKED_NOTIFICATION_BAR_H_
diff --git a/ash/system/phonehub/multidevice_feature_opt_in_view.cc b/ash/system/phonehub/multidevice_feature_opt_in_view.cc
index ba16850f..f696992 100644
--- a/ash/system/phonehub/multidevice_feature_opt_in_view.cc
+++ b/ash/system/phonehub/multidevice_feature_opt_in_view.cc
@@ -11,10 +11,14 @@
 #include "ash/components/phonehub/util/histogram_util.h"
 #include "ash/constants/ash_features.h"
 #include "ash/public/cpp/new_window_delegate.h"
+#include "ash/root_window_controller.h"
+#include "ash/shell.h"
 #include "ash/strings/grit/ash_strings.h"
 #include "ash/style/ash_color_provider.h"
 #include "ash/system/phonehub/phone_hub_metrics.h"
+#include "ash/system/phonehub/phone_hub_tray.h"
 #include "ash/system/phonehub/phone_hub_view_ids.h"
+#include "ash/system/status_area_widget.h"
 #include "chromeos/ash/components/multidevice/logging/logging.h"
 #include "ui/base/metadata/metadata_impl_macros.h"
 
@@ -151,6 +155,7 @@
   NewWindowDelegate::GetInstance()->OpenUrl(
       GURL(url), NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       NewWindowDelegate::Disposition::kNewForegroundTab);
+  ClosePhoneHubBubble();
 }
 
 void MultideviceFeatureOptInView::DismissButtonPressed() {
@@ -188,6 +193,24 @@
   PreferredSizeChanged();
 }
 
+void MultideviceFeatureOptInView::ClosePhoneHubBubble() {
+  // Close Phone Hub bubble in current display.
+  views::Widget* const widget = GetWidget();
+  // |widget| is null when this function is called before the view is added to a
+  // widget (in unit tests).
+  if (!widget) {
+    return;
+  }
+  int64_t current_display_id =
+      display::Screen::GetScreen()
+          ->GetDisplayNearestWindow(widget->GetNativeWindow())
+          .id();
+  Shell::GetRootWindowControllerWithDisplayId(current_display_id)
+      ->GetStatusAreaWidget()
+      ->phone_hub_tray()
+      ->CloseBubble();
+}
+
 BEGIN_METADATA(MultideviceFeatureOptInView, views::View)
 END_METADATA
 
diff --git a/ash/system/phonehub/multidevice_feature_opt_in_view.h b/ash/system/phonehub/multidevice_feature_opt_in_view.h
index 6c7c301..98c07e72 100644
--- a/ash/system/phonehub/multidevice_feature_opt_in_view.h
+++ b/ash/system/phonehub/multidevice_feature_opt_in_view.h
@@ -43,6 +43,7 @@
   // Calculates whether this view should be visible and updates its visibility
   // accordingly.
   void UpdateVisibility(bool was_visible);
+  void ClosePhoneHubBubble();
 
   phonehub::MultideviceFeatureAccessManager*
       multidevice_feature_access_manager_;
diff --git a/ash/system/phonehub/phone_hub_tray_unittest.cc b/ash/system/phonehub/phone_hub_tray_unittest.cc
index 8e01e887..533ba41 100644
--- a/ash/system/phonehub/phone_hub_tray_unittest.cc
+++ b/ash/system/phonehub/phone_hub_tray_unittest.cc
@@ -331,6 +331,9 @@
   GetMultideviceFeatureAccessManager()->SetCameraRollAccessStatusInternal(
       AccessStatus::kAccessGranted);
 
+  // Bubble has been dismissed, opening again.
+  ClickTrayButton();
+
   // This view should be dismissed.
   EXPECT_FALSE(multidevice_feature_opt_in_view()->GetVisible());
 
diff --git a/ash/system/privacy/privacy_indicators_controller_unittest.cc b/ash/system/privacy/privacy_indicators_controller_unittest.cc
index 8a2de481..9977248 100644
--- a/ash/system/privacy/privacy_indicators_controller_unittest.cc
+++ b/ash/system/privacy/privacy_indicators_controller_unittest.cc
@@ -9,8 +9,8 @@
 #include "ash/constants/ash_constants.h"
 #include "ash/system/message_center/ash_message_popup_collection.h"
 #include "ash/system/message_center/unified_message_center_bubble.h"
-#include "ash/system/message_center/unified_message_center_view.h"
-#include "ash/system/message_center/unified_message_list_view.h"
+#include "ash/system/notification_center/notification_center_view.h"
+#include "ash/system/notification_center/notification_list_view.h"
 #include "ash/system/unified/unified_system_tray.h"
 #include "ash/test/ash_test_base.h"
 #include "base/bind.h"
@@ -62,8 +62,8 @@
   views::View* GetNotificationViewFromMessageCenter(const std::string& id) {
     return GetPrimaryUnifiedSystemTray()
         ->message_center_bubble()
-        ->message_center_view()
-        ->message_list_view()
+        ->notification_center_view()
+        ->notification_list_view()
         ->GetMessageViewForNotificationId(id);
   }
 
diff --git a/ash/system/time/calendar_view_unittest.cc b/ash/system/time/calendar_view_unittest.cc
index 56be474..0e348663 100644
--- a/ash/system/time/calendar_view_unittest.cc
+++ b/ash/system/time/calendar_view_unittest.cc
@@ -13,7 +13,7 @@
 #include "ash/strings/grit/ash_strings.h"
 #include "ash/style/icon_button.h"
 #include "ash/system/message_center/unified_message_center_bubble.h"
-#include "ash/system/message_center/unified_message_center_view.h"
+#include "ash/system/notification_center/notification_center_view.h"
 #include "ash/system/time/calendar_event_list_view.h"
 #include "ash/system/time/calendar_model.h"
 #include "ash/system/time/calendar_month_view.h"
@@ -2039,7 +2039,7 @@
   views::FocusManager* message_center_focus_manager() {
     return GetPrimaryUnifiedSystemTray()
         ->message_center_bubble()
-        ->message_center_view()
+        ->notification_center_view()
         ->GetFocusManager();
   }
 
diff --git a/ash/system/unified/unified_system_tray_unittest.cc b/ash/system/unified/unified_system_tray_unittest.cc
index 53e627e..d96fcf2 100644
--- a/ash/system/unified/unified_system_tray_unittest.cc
+++ b/ash/system/unified/unified_system_tray_unittest.cc
@@ -13,7 +13,7 @@
 #include "ash/shell.h"
 #include "ash/strings/grit/ash_strings.h"
 #include "ash/system/message_center/unified_message_center_bubble.h"
-#include "ash/system/message_center/unified_message_center_view.h"
+#include "ash/system/notification_center/notification_center_view.h"
 #include "ash/system/status_area_widget.h"
 #include "ash/system/status_area_widget_test_helper.h"
 #include "ash/system/time/time_tray_item_view.h"
@@ -281,7 +281,7 @@
   tray->ShowBubble();
 
   auto* message_center_view =
-      tray->message_center_bubble()->message_center_view();
+      tray->message_center_bubble()->notification_center_view();
   auto* focus_manager = message_center_view->GetFocusManager();
 
   AddNotification();
@@ -323,7 +323,7 @@
   tray->ShowBubble();
 
   auto* message_center_bubble = tray->message_center_bubble();
-  auto* message_center_view = message_center_bubble->message_center_view();
+  auto* message_center_view = message_center_bubble->notification_center_view();
 
   AddNotification();
   AddNotification();
@@ -501,7 +501,7 @@
 
   // Ensure message center is collapsed when Calendar is not being shown.
   auto* message_center_view =
-      tray->message_center_bubble()->message_center_view();
+      tray->message_center_bubble()->notification_center_view();
   EXPECT_FALSE(tray->IsShowingCalendarView());
   EXPECT_TRUE(message_center_view->collapsed());
 
diff --git a/ash/system/unified/unified_system_tray_view.cc b/ash/system/unified/unified_system_tray_view.cc
index 4dd06b0a..481a1a5 100644
--- a/ash/system/unified/unified_system_tray_view.cc
+++ b/ash/system/unified/unified_system_tray_view.cc
@@ -12,7 +12,7 @@
 #include "ash/shell.h"
 #include "ash/system/media/unified_media_controls_container.h"
 #include "ash/system/message_center/ash_message_center_lock_screen_controller.h"
-#include "ash/system/message_center/unified_message_center_view.h"
+#include "ash/system/notification_center/notification_center_view.h"
 #include "ash/system/tray/interacted_by_tap_recorder.h"
 #include "ash/system/tray/tray_constants.h"
 #include "ash/system/unified/detailed_view_controller.h"
diff --git a/ash/webui/common/resources/keyboard_diagram.html b/ash/webui/common/resources/keyboard_diagram.html
index d40dadc4..edfef08f 100644
--- a/ash/webui/common/resources/keyboard_diagram.html
+++ b/ash/webui/common/resources/keyboard_diagram.html
@@ -1,5 +1,5 @@
 <style>
-  :root {
+  :host {
     --grid-gap: max(3px, 0.5vw);
     --key-travel: 3px;
 
diff --git a/ash/webui/common/resources/keyboard_key.html b/ash/webui/common/resources/keyboard_key.html
index 77771e6d..89851ff 100644
--- a/ash/webui/common/resources/keyboard_key.html
+++ b/ash/webui/common/resources/keyboard_key.html
@@ -1,5 +1,5 @@
 <style>
-  :root {
+  :host {
     --background-color-pressed: hsl(214deg 82% 51%);
     --background-color-unpressed: hsl(218deg 92% 95%);
     --background-color-tested: hsl(214deg 82% 85%);
@@ -13,9 +13,6 @@
     --travel: var(--keyboard-key-travel, 3px);
     --foreground-color-unpressed: hsl(214deg 82% 51%);
     --foreground-color-pressed: hsl(213deg 23% 91%);
-  }
-
-  :host {
     position: relative;
   }
 
diff --git a/ash/webui/diagnostics_ui/backend/BUILD.gn b/ash/webui/diagnostics_ui/backend/BUILD.gn
index 3c81e69..e82e60d 100644
--- a/ash/webui/diagnostics_ui/backend/BUILD.gn
+++ b/ash/webui/diagnostics_ui/backend/BUILD.gn
@@ -84,6 +84,7 @@
 
   sources = [
     "cpu_usage_data_unittest.cc",
+    "input_data_event_watcher_unittest.cc",
     "input_data_provider_keyboard_unittest.cc",
     "input_data_provider_touch_unittest.cc",
     "input_data_provider_unittest.cc",
diff --git a/ash/webui/diagnostics_ui/backend/event_watcher_factory.cc b/ash/webui/diagnostics_ui/backend/event_watcher_factory.cc
index f8b3ba1..b6f1515d 100644
--- a/ash/webui/diagnostics_ui/backend/event_watcher_factory.cc
+++ b/ash/webui/diagnostics_ui/backend/event_watcher_factory.cc
@@ -2,12 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include <linux/input.h>
+#include "ash/webui/diagnostics_ui/backend/event_watcher_factory.h"
+
 #include <cstdint>
 #include <memory>
 
-#include "ash/webui/diagnostics_ui/backend/event_watcher_factory.h"
-
 #include "ash/webui/diagnostics_ui/backend/keyboard_input_data_event_watcher.h"
 #include "base/memory/weak_ptr.h"
 
diff --git a/ash/webui/diagnostics_ui/backend/input_data_event_watcher.cc b/ash/webui/diagnostics_ui/backend/input_data_event_watcher.cc
index 5047535..b9c1eef18 100644
--- a/ash/webui/diagnostics_ui/backend/input_data_event_watcher.cc
+++ b/ash/webui/diagnostics_ui/backend/input_data_event_watcher.cc
@@ -4,8 +4,105 @@
 
 #include "ash/webui/diagnostics_ui/backend/input_data_event_watcher.h"
 
+#include <errno.h>
+#include <fcntl.h>
+#include <linux/input.h>
+
+#include <cstdint>
+#include <memory>
+
+#include "base/files/file_path.h"
+#include "base/files/scoped_file.h"
+#include "base/functional/callback.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/message_loop/message_pump_for_ui.h"
+#include "base/strings/stringprintf.h"
+#include "base/task/current_thread.h"
+
 namespace ash::diagnostics {
 
-InputDataEventWatcher::~InputDataEventWatcher() = default;
+namespace {
+
+constexpr int kOpenFlags = O_NONBLOCK | O_RDWR;
+
+}
+
+InputDataEventWatcher::InputDataEventWatcher(uint32_t evdev_id,
+                                             const base::FilePath& path,
+                                             int fd)
+    : evdev_id_(evdev_id),
+      path_(path),
+      fd_(fd),
+      input_device_fd_(fd_),
+      controller_(FROM_HERE) {}
+
+InputDataEventWatcher::InputDataEventWatcher(uint32_t evdev_id)
+    : evdev_id_(evdev_id),
+      path_(base::StringPrintf("/dev/input/event%d", evdev_id_)),
+      fd_(open(path_.value().c_str(), kOpenFlags)),
+      input_device_fd_(fd_),
+      controller_(FROM_HERE) {
+  if (fd_ == -1) {
+    PLOG(ERROR) << "Unable to open event device " << evdev_id_
+                << ", not forwarding events for input diagnostics.";
+    // Leave un-Started(), so we never enable the fd watcher.
+    return;
+  }
+
+  Start();
+}
+
+InputDataEventWatcher::~InputDataEventWatcher() {
+  controller_.StopWatchingFileDescriptor();
+}
+
+void InputDataEventWatcher::Start() {
+  DoStart();
+}
+
+void InputDataEventWatcher::Stop() {
+  DoStop();
+}
+
+void InputDataEventWatcher::OnFileCanReadWithoutBlocking(int fd) {
+  DoOnFileCanReadWithoutBlocking(fd);
+}
+
+void InputDataEventWatcher::OnFileCanWriteWithoutBlocking(int fd) {
+  DoOnFileCanWriteWithoutBlocking(fd);
+}
+
+void InputDataEventWatcher::DoStart() {
+  base::CurrentUIThread::Get()->WatchFileDescriptor(
+      fd_, true, base::MessagePumpForUI::WATCH_READ, &controller_, this);
+}
+
+void InputDataEventWatcher::DoStop() {
+  controller_.StopWatchingFileDescriptor();
+}
+
+void InputDataEventWatcher::DoOnFileCanReadWithoutBlocking(int fd) {
+  while (true) {
+    input_event input;
+    ssize_t read_size = read(fd, &input, sizeof(input));
+    // Read of input_event from `fd` completed with unexpected number of bytes.
+    if (read_size != sizeof(input)) {
+      // Recoverable failure. Wait for FDWatcher to trigger
+      // `OnFileCanReadWithoutBlocking` again. EINTR occurs when read is
+      // interrupted before it can complete. EAGAIN occurs when non-blocking
+      // socket read would block.
+      if (errno == EINTR || errno == EAGAIN)
+        return;
+      // Not recoverable failure. Stop watching file descriptor.
+      if (errno != ENODEV)
+        PLOG(ERROR) << "error reading device " << path_.value();
+      Stop();
+      return;
+    }
+
+    ProcessEvent(input);
+  }
+}
 
 }  // namespace ash::diagnostics
diff --git a/ash/webui/diagnostics_ui/backend/input_data_event_watcher.h b/ash/webui/diagnostics_ui/backend/input_data_event_watcher.h
index a7742e5..76eecdf 100644
--- a/ash/webui/diagnostics_ui/backend/input_data_event_watcher.h
+++ b/ash/webui/diagnostics_ui/backend/input_data_event_watcher.h
@@ -6,21 +6,56 @@
 #define ASH_WEBUI_DIAGNOSTICS_UI_BACKEND_INPUT_DATA_EVENT_WATCHER_H_
 
 #include <linux/input.h>
+
 #include <cstdint>
 
+#include "base/files/file_path.h"
+#include "base/files/scoped_file.h"
+#include "base/functional/callback.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/memory/weak_ptr.h"
+#include "base/message_loop/message_pump_for_ui.h"
+#include "base/strings/stringprintf.h"
+#include "base/task/current_thread.h"
+
 namespace ash::diagnostics {
 
 // Interfaces for watching and dispatching relevant events from evdev to the
 // input_data_provider.
-class InputDataEventWatcher {
+class InputDataEventWatcher : public base::MessagePumpForUI::FdWatcher {
  public:
-  virtual ~InputDataEventWatcher() = 0;
+  // Constructor for unittests.
+  InputDataEventWatcher(uint32_t evdev_id, const base::FilePath& path, int fd);
+  explicit InputDataEventWatcher(uint32_t evdev_id);
+  ~InputDataEventWatcher() override;
 
   // Interpret raw `input_event` components into logical events based on the
   // event protocols and connected device. Described by kernel input event-codes
   // api. See: https://www.kernel.org/doc/Documentation/input/event-codes.txt
   // for a list of valid codes.
   virtual void ProcessEvent(const input_event& event) = 0;
+
+  void Start();
+  void Stop();
+
+ protected:
+  // base::MessagePumpForUI::FdWatcher:
+  void OnFileCanReadWithoutBlocking(int fd) override;
+  void OnFileCanWriteWithoutBlocking(int fd) override;
+
+  // Start watching file descriptor on current UI thread.
+  virtual void DoStart();
+  // Stop watching file descriptor on current UI thread.
+  virtual void DoStop();
+  virtual void DoOnFileCanReadWithoutBlocking(int fd);
+  virtual void DoOnFileCanWriteWithoutBlocking(int fd) {}
+
+  const uint32_t evdev_id_;    // input device evdev id.
+  const base::FilePath path_;  // evdev path /dev/input/event{evdev_id_}.
+  const int fd_;               // File descriptor being watched.
+  const base::ScopedFD input_device_fd_;  // base::ScopedFD to ensure closed.
+  base::MessagePumpForUI::FdWatchController controller_;
 };
 
 }  // namespace ash::diagnostics
diff --git a/ash/webui/diagnostics_ui/backend/input_data_event_watcher_unittest.cc b/ash/webui/diagnostics_ui/backend/input_data_event_watcher_unittest.cc
new file mode 100644
index 0000000..891a8d18
--- /dev/null
+++ b/ash/webui/diagnostics_ui/backend/input_data_event_watcher_unittest.cc
@@ -0,0 +1,168 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/webui/diagnostics_ui/backend/input_data_event_watcher.h"
+
+#include <fcntl.h>
+#include <linux/input-event-codes.h>
+#include <linux/input.h>
+
+#include <cstdint>
+#include <memory>
+
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/functional/callback.h"
+#include "base/logging.h"
+#include "base/posix/eintr_wrapper.h"
+#include "base/run_loop.h"
+#include "base/strings/stringprintf.h"
+#include "base/test/bind.h"
+#include "base/test/task_environment.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace ash::diagnostics {
+
+namespace {
+
+constexpr uint32_t kFakeEvdevId = 999;
+constexpr char kFakeEvdevPath[] = "/dev/input/event999";
+constexpr timeval kFakeTimeval = {.tv_sec = 1493076832, .tv_usec = 526871};
+
+// Sample of events that an InputDataEventWatcher might process.
+constexpr struct input_event kFakeKeyCaplPressAndRelease[] = {
+    // Begin press on "left alt"
+    {kFakeTimeval, EV_MSC, MSC_SCAN, 0x0},
+    {kFakeTimeval, EV_KEY, KEY_LEFTALT, 1},
+    {kFakeTimeval, EV_SYN, SYN_REPORT, 1},
+    // Begin press on "left meta"
+    {kFakeTimeval, EV_MSC, MSC_SCAN, 0x38},
+    {kFakeTimeval, EV_KEY, KEY_LEFTMETA, 1},
+    {kFakeTimeval, EV_SYN, SYN_REPORT, 1},
+    // Release press on "left meta"
+    {kFakeTimeval, EV_MSC, MSC_SCAN, 0xdb},
+    {kFakeTimeval, EV_KEY, KEY_LEFTMETA, 0},
+    {kFakeTimeval, EV_SYN, SYN_REPORT, 1},
+    // Release press on "left alt"
+    {kFakeTimeval, EV_MSC, MSC_SCAN, 0x38},
+    {kFakeTimeval, EV_KEY, KEY_LEFTALT, 0},
+    {kFakeTimeval, EV_SYN, SYN_REPORT, 1},
+    // Enable LED
+    {kFakeTimeval, EV_LED, LED_CAPSL, 1},
+    {kFakeTimeval, EV_SYN, SYN_REPORT, 1}};
+
+class FakeWatcher : public InputDataEventWatcher {
+ public:
+  FakeWatcher(uint32_t evdev_id, const base::FilePath& path, int fd)
+      : InputDataEventWatcher(evdev_id, path, fd) {}
+  ~FakeWatcher() override = default;
+
+  void SetQuitClosure(base::OnceClosure quit_closure) {
+    quit_closure_ = std::move(quit_closure);
+  }
+
+  void ProcessEvent(const input_event& event) override {
+    events.emplace_back(event);
+    if (quit_closure_) {
+      std::move(quit_closure_).Run();
+    }
+  }
+
+  // Test helpers:
+  size_t num_events_processed() { return events.size(); }
+  const input_event GetCall(int index) { return events[index]; }
+
+ private:
+  std::vector<input_event> events;
+  base::OnceClosure quit_closure_;
+};
+
+class InputDataEventWatcherTest : public testing::Test {
+ public:
+  InputDataEventWatcherTest()
+      : task_environment_(
+            std::make_unique<base::test::SingleThreadTaskEnvironment>(
+                base::test::SingleThreadTaskEnvironment::MainThreadType::UI)),
+        test_path_(base::FilePath(kFakeEvdevPath)) {}
+  InputDataEventWatcherTest(const InputDataEventWatcherTest&) = delete;
+  InputDataEventWatcherTest& operator=(const InputDataEventWatcherTest&) =
+      delete;
+  ~InputDataEventWatcherTest() override = default;
+
+  void SetUp() override { SetupWatcher(); }
+
+  void TearDown() override { TearDownWatcher(); }
+
+  // Write event to write endpoint of pipe created during setup.
+  void WriteInputEvent(const input_event& input) {
+    int write_result = write(writefd(), &input, sizeof(input));
+    if (write_result < 0)
+      PLOG(WARNING) << "write";
+    ASSERT_TRUE(write_result >= 0);
+  }
+
+  FakeWatcher* watcher() { return watcher_.get(); }
+  int readfd() { return pipefds_[0]; }
+  int writefd() { return pipefds_[1]; }
+
+  // Check expected event data matches event "processed" by FakeWatcher.
+  void VerifyInputEvent(const input_event& expected, int call_index) {
+    EXPECT_EQ(call_index + 1ul, watcher()->num_events_processed());
+    auto written_event = watcher()->GetCall(call_index);
+    EXPECT_EQ(expected.type, written_event.type);
+    EXPECT_EQ(expected.code, written_event.code);
+    EXPECT_EQ(expected.value, written_event.value);
+  }
+
+  base::test::SingleThreadTaskEnvironment* task_environment() {
+    return task_environment_.get();
+  }
+
+ protected:
+  void SetupWatcher() {
+    // Create pipe to fake having a `/dev/input/event{evdev_id}` file.
+    EXPECT_TRUE(base::CreateLocalNonBlockingPipe(pipefds_));
+    watcher_ =
+        std::make_unique<FakeWatcher>(kFakeEvdevId, test_path_, readfd());
+  }
+
+  void TearDownWatcher() {
+    watcher()->Stop();
+    watcher_.reset();
+
+    // Only close the write endpoint. InputDataEventWatcher::Stop will close
+    // down the read endpoint. Calling close on the read will cause BADF.
+    if (IGNORE_EINTR(close(writefd())) < 0)
+      PLOG(WARNING) << "close (writefd)";
+  }
+
+ private:
+  std::unique_ptr<base::test::SingleThreadTaskEnvironment> task_environment_;
+  int pipefds_[2];
+  const base::FilePath test_path_;
+  std::unique_ptr<FakeWatcher> watcher_;
+};
+
+// Verify that valid input_event can be read and
+// trigger`InputDataEventWatcher::ProcessEvent`.
+TEST_F(InputDataEventWatcherTest, ReadsInputEventsFromFd) {
+  watcher()->Start();
+  size_t write_count = 0ul;
+  for (const auto& event : kFakeKeyCaplPressAndRelease) {
+    base::RunLoop run_loop;
+    // Wait for read to trigger `InputDataEventWatcher::ProcessEvent`.
+    watcher()->SetQuitClosure(
+        base::BindLambdaForTesting([&]() { run_loop.Quit(); }));
+    WriteInputEvent(event);
+    run_loop.Run();
+    // Ensure expected event is passed to ProcessEvent.
+    VerifyInputEvent(event, write_count);
+    write_count++;
+  }
+}
+
+}  // namespace
+
+}  // namespace ash::diagnostics
diff --git a/ash/webui/diagnostics_ui/backend/input_data_provider.cc b/ash/webui/diagnostics_ui/backend/input_data_provider.cc
index 85dbb42..8a48214 100644
--- a/ash/webui/diagnostics_ui/backend/input_data_provider.cc
+++ b/ash/webui/diagnostics_ui/backend/input_data_provider.cc
@@ -6,6 +6,7 @@
 
 #include <fcntl.h>
 #include <linux/input.h>
+
 #include <vector>
 
 #include "ash/accelerators/accelerator_controller_impl.h"
diff --git a/ash/webui/diagnostics_ui/backend/input_data_provider_unittest.cc b/ash/webui/diagnostics_ui/backend/input_data_provider_unittest.cc
index 0538a38..7ac97f64 100644
--- a/ash/webui/diagnostics_ui/backend/input_data_provider_unittest.cc
+++ b/ash/webui/diagnostics_ui/backend/input_data_provider_unittest.cc
@@ -242,25 +242,33 @@
       uint32_t id,
       base::WeakPtr<KeyboardInputDataEventWatcher::Dispatcher> dispatcher,
       watchers_t& watchers)
-      : id_(id), dispatcher_(dispatcher), watchers_(watchers) {
-    EXPECT_EQ(0u, watchers_.count(id_));
-    watchers_[id_] = this;
+      : InputDataEventWatcher(id),
+        dispatcher_(dispatcher),
+        watchers_(watchers) {
+    EXPECT_EQ(0u, watchers_.count(this->evdev_id_));
+    watchers_[this->evdev_id_] = this;
   }
   ~FakeInputDataEventWatcher() override {
-    EXPECT_EQ(watchers_[id_], this);
-    watchers_.erase(id_);
+    EXPECT_EQ(watchers_[this->evdev_id_], this);
+    watchers_.erase(this->evdev_id_);
   }
 
   void PostKeyEvent(bool down, uint32_t evdev_code, uint32_t scan_code) {
     if (dispatcher_)
-      dispatcher_->SendInputKeyEvent(id_, evdev_code, scan_code, down);
+      dispatcher_->SendInputKeyEvent(this->evdev_id_, evdev_code, scan_code,
+                                     down);
   }
 
   // ProcessEvent will not be triggered by test code.
   void ProcessEvent(const input_event& event) override {}
 
+  // Only updating boolean instead of watching actual FD. FD watch tested in
+  // InputDataEventWatcher unit tests.
+  // See: ash/webui/diagnostics_ui/backend/input_data_event_watcher_unittest.cc
+  void DoStart() override {}
+  void DoStop() override {}
+
  private:
-  uint32_t id_;
   base::WeakPtr<KeyboardInputDataEventWatcher::Dispatcher> dispatcher_;
   watchers_t& watchers_;
 };
@@ -268,7 +276,7 @@
 // Utility to construct FakeInputDataEventWatcher for InputDataProvider.
 class FakeInputDataEventWatcherFactory : public EventWatcherFactory {
  public:
-  FakeInputDataEventWatcherFactory(watchers_t& watchers)
+  explicit FakeInputDataEventWatcherFactory(watchers_t& watchers)
       : watchers_(watchers) {}
   FakeInputDataEventWatcherFactory(const FakeInputDataEventWatcherFactory&) =
       delete;
diff --git a/ash/webui/diagnostics_ui/backend/keyboard_input_data_event_watcher.cc b/ash/webui/diagnostics_ui/backend/keyboard_input_data_event_watcher.cc
index 128c8ed8..9dc00ab 100644
--- a/ash/webui/diagnostics_ui/backend/keyboard_input_data_event_watcher.cc
+++ b/ash/webui/diagnostics_ui/backend/keyboard_input_data_event_watcher.cc
@@ -6,6 +6,7 @@
 
 #include <fcntl.h>
 #include <linux/input.h>
+
 #include <cstdint>
 #include <memory>
 
@@ -27,85 +28,26 @@
 }  // namespace
 
 KeyboardInputDataEventWatcher::KeyboardInputDataEventWatcher(
-    uint32_t id,
+    uint32_t evdev_id,
+    const base::FilePath& path,
+    int fd,
     base::WeakPtr<KeyboardInputDataEventWatcher::Dispatcher> dispatcher)
-    : id_(id),
-      path_(base::FilePath(base::StringPrintf("/dev/input/event%d", id_))),
-      fd_(open(path_.value().c_str(), O_RDWR | O_NONBLOCK)),
-      input_device_fd_(fd_),
-      dispatcher_(dispatcher),
-      controller_(FROM_HERE) {
-  if (fd_ == -1) {
-    PLOG(ERROR) << "Unable to open event device " << id_
-                << ", not forwarding events for input diagnostics.";
-    // Leave un-Started(), so we never enable the fd watcher.
-    return;
-  }
-
-  Start();
-}
+    : InputDataEventWatcher(evdev_id, path, fd), dispatcher_(dispatcher) {}
 
 KeyboardInputDataEventWatcher::KeyboardInputDataEventWatcher(
-    uint32_t id,
-    const base::FilePath& device_path,
-    int read_fd,
+    uint32_t evdev_id,
     base::WeakPtr<KeyboardInputDataEventWatcher::Dispatcher> dispatcher)
-    : id_(id),
-      path_(device_path),
-      fd_(read_fd),
-      input_device_fd_(fd_),
-      dispatcher_(dispatcher),
-      controller_(FROM_HERE) {}
+    : InputDataEventWatcher(evdev_id), dispatcher_(dispatcher) {}
 
 KeyboardInputDataEventWatcher::~KeyboardInputDataEventWatcher() = default;
 
-void KeyboardInputDataEventWatcher::Start() {
-  base::CurrentUIThread::Get()->WatchFileDescriptor(
-      fd_, true, base::MessagePumpForUI::WATCH_READ, &controller_, this);
-  watching_ = true;
-}
-
-void KeyboardInputDataEventWatcher::Stop() {
-  controller_.StopWatchingFileDescriptor();
-  watching_ = false;
-}
-
-void KeyboardInputDataEventWatcher::SetQuitClosureForTesting(
-    base::OnceClosure quit_closure) {
-  quit_closure_ = std::move(quit_closure);
-}
-
-void KeyboardInputDataEventWatcher::OnFileCanReadWithoutBlocking(int fd) {
-  while (true) {
-    input_event input;
-    ssize_t read_size = read(fd, &input, sizeof(input));
-    if (read_size != sizeof(input)) {
-      if (errno == EINTR || errno == EAGAIN)
-        return;
-      if (errno != ENODEV)
-        PLOG(ERROR) << "error reading device " << path_.value();
-      Stop();
-      return;
-    }
-
-    ProcessEvent(input);
-  }
-}
-
-void KeyboardInputDataEventWatcher::OnFileCanWriteWithoutBlocking(int fd) {}
-
 // Once we have an entire keypress/release, dispatch it.
 void KeyboardInputDataEventWatcher::ConvertKeyEvent(uint32_t key_code,
                                                     uint32_t key_state,
                                                     uint32_t scan_code) {
   bool down = key_state != kKeyReleaseValue;
   if (dispatcher_)
-    dispatcher_->SendInputKeyEvent(id_, key_code, scan_code, down);
-
-  // `quit_closure_` used to stop tests.
-  if (quit_closure_) {
-    std::move(quit_closure_).Run();
-  }
+    dispatcher_->SendInputKeyEvent(this->evdev_id_, key_code, scan_code, down);
 }
 
 // Process evdev event structures directly from the kernel.
diff --git a/ash/webui/diagnostics_ui/backend/keyboard_input_data_event_watcher.h b/ash/webui/diagnostics_ui/backend/keyboard_input_data_event_watcher.h
index b9c62b1c..2e6418c2 100644
--- a/ash/webui/diagnostics_ui/backend/keyboard_input_data_event_watcher.h
+++ b/ash/webui/diagnostics_ui/backend/keyboard_input_data_event_watcher.h
@@ -9,6 +9,7 @@
 #include "base/files/file_path.h"
 #include "base/files/scoped_file.h"
 #include "base/functional/callback.h"
+#include "base/memory/weak_ptr.h"
 #include "base/message_loop/message_pump_for_ui.h"
 
 namespace ash::diagnostics {
@@ -18,8 +19,7 @@
 // it has a lot of connections (ui::Cursor, full ui::DeviceEventDispatcherEvdev
 // interface) that take more room to stub out rather than just implementing
 // another evdev FdWatcher from scratch.
-class KeyboardInputDataEventWatcher : public InputDataEventWatcher,
-                                      base::MessagePumpForUI::FdWatcher {
+class KeyboardInputDataEventWatcher : public InputDataEventWatcher {
  public:
   // `KeyboardInputDataEventWatcher` calls dispatcher when a key event is ready.
   class Dispatcher {
@@ -38,14 +38,14 @@
   };
 
   KeyboardInputDataEventWatcher(
-      uint32_t id,
+      uint32_t evdev_id,
       base::WeakPtr<KeyboardInputDataEventWatcher::Dispatcher> dispatcher);
 
   // Constructor for unittests.
   KeyboardInputDataEventWatcher(
-      uint32_t id,
-      const base::FilePath& device_path,
-      const int fd,
+      uint32_t evdev_id,
+      const base::FilePath& path,
+      int fd,
       base::WeakPtr<KeyboardInputDataEventWatcher::Dispatcher> dispatcher);
 
   ~KeyboardInputDataEventWatcher() override;
@@ -53,43 +53,17 @@
   void ConvertKeyEvent(uint32_t key_code,
                        uint32_t key_state,
                        uint32_t scan_code);
-  void ProcessEvent(const input_event& input) override;
-  void Start();
-  void Stop();
 
-  void SetQuitClosureForTesting(base::OnceClosure quit_closure);
+  // InputDataEventWatcher:
+  void ProcessEvent(const input_event& input) override;
 
  protected:
-  // base::MessagePumpForUI::FdWatcher:
-  void OnFileCanReadWithoutBlocking(int fd) override;
-  void OnFileCanWriteWithoutBlocking(int fd) override;
-
-  // Device id
-  const uint32_t id_;
-
-  // Path to input device.
-  const base::FilePath path_;
-
-  // File descriptor to read.
-  const int fd_;
-
-  // Scoped auto-closer for FD.
-  const base::ScopedFD input_device_fd_;
-
-  // Whether we're polling for input on the device.
-  bool watching_ = false;
-
   // EV_ information pending for SYN_REPORT to dispatch.
   uint32_t pending_scan_code_ = 0;
   uint32_t pending_key_code_ = 0;
   uint32_t pending_key_state_ = 0;
 
-  base::OnceClosure quit_closure_;
-
   base::WeakPtr<KeyboardInputDataEventWatcher::Dispatcher> dispatcher_;
-
-  // Controller for watching the input fd.
-  base::MessagePumpForUI::FdWatchController controller_;
 };
 
 }  // namespace ash::diagnostics
diff --git a/ash/webui/diagnostics_ui/backend/keyboard_input_data_event_watcher_unittest.cc b/ash/webui/diagnostics_ui/backend/keyboard_input_data_event_watcher_unittest.cc
index bd23228..b50025e 100644
--- a/ash/webui/diagnostics_ui/backend/keyboard_input_data_event_watcher_unittest.cc
+++ b/ash/webui/diagnostics_ui/backend/keyboard_input_data_event_watcher_unittest.cc
@@ -6,9 +6,11 @@
 
 #include <errno.h>
 #include <fcntl.h>
+#include <linux/input-event-codes.h>
 #include <linux/input.h>
 #include <sys/socket.h>
 #include <unistd.h>
+
 #include <cstdint>
 #include <memory>
 
@@ -28,8 +30,7 @@
 
 namespace {
 
-constexpr char kFakeDevicePath[] = "/dev/input/test-device";
-constexpr uint32_t kFakeEvdevId{999};
+constexpr uint32_t kFakeEvdevId = 999;
 constexpr uint32_t kScanCodeKeyA = 0x1E;
 constexpr bool kKeyPressed = 1;
 constexpr bool kKeyReleased = 0;
@@ -114,6 +115,22 @@
   base::WeakPtrFactory<StubDispatcher> weak_factory_{this};
 };
 
+// FakeKeyboardInputDataEventWatcher to validate event processing.
+class FakeKeyboardInputDataEventWatcher : public KeyboardInputDataEventWatcher {
+ public:
+  FakeKeyboardInputDataEventWatcher(
+      uint32_t evdev_id,
+      base::WeakPtr<KeyboardInputDataEventWatcher::Dispatcher> dispatcher)
+      : KeyboardInputDataEventWatcher(evdev_id, dispatcher) {}
+
+  ~FakeKeyboardInputDataEventWatcher() override = default;
+
+  // Don't call the actual read functions.
+  void DoStart() override {}
+  void DoStop() override {}
+  void DoOnFileCanReadWithoutBlocking(int fd) override {}
+};
+
 class KeyboardInputDataEventWatcherTest : public testing::Test {
  public:
   KeyboardInputDataEventWatcherTest()
@@ -131,37 +148,17 @@
 
   void TearDown() override { TearDownWatcher(); }
 
-  void WriteInputEvent(const input_event& input) {
-    int write_result = write(pipefds_[1], &input, sizeof(input));
-    if (write_result < 0)
-      PLOG(WARNING) << "write";
-    ASSERT_TRUE(write_result >= 0);
-  }
-
   StubDispatcher* dispatcher() { return &dispatcher_; }
 
   KeyboardInputDataEventWatcher* watcher() { return watcher_.get(); }
 
  protected:
   void SetupWatcher() {
-    int pipe_result = (pipe2(pipefds_, O_NONBLOCK));
-    if (pipe_result < 0)
-      PLOG(WARNING) << "pipe";
-    ASSERT_EQ(0, pipe_result);
-    watcher_ = std::make_unique<KeyboardInputDataEventWatcher>(
-        kFakeEvdevId, fake_device_path, pipefds_[0],
-        dispatcher()->GetWeakPtr());
+    watcher_ = std::make_unique<FakeKeyboardInputDataEventWatcher>(
+        kFakeEvdevId, dispatcher()->GetWeakPtr());
   }
 
-  void TearDownWatcher() {
-    watcher()->Stop();
-
-    // Only close the write endpoint. InputDataEventWatcher::Stop will close
-    // down the read endpoint. Calling close on the read will cause BADF.
-    if (IGNORE_EINTR(close(pipefds_[1])) < 0)
-      PLOG(WARNING) << "close";
-    watcher_.reset();
-  }
+  void TearDownWatcher() { watcher_.reset(); }
 
   // Helper for call assertions.
   void VerifyDispatcherCall(size_t index,
@@ -175,25 +172,16 @@
 
  private:
   std::unique_ptr<base::test::SingleThreadTaskEnvironment> task_environment_;
-  base::FilePath fake_device_path{kFakeDevicePath};
   StubDispatcher dispatcher_;
-  int pipefds_[2];
-  std::unique_ptr<KeyboardInputDataEventWatcher> watcher_;
+  std::unique_ptr<FakeKeyboardInputDataEventWatcher> watcher_;
 };
 
 // Verifies that regular keydown and keyup are reported.
 TEST_F(KeyboardInputDataEventWatcherTest, StandardKeyPressDispatchesKeyEvent) {
   EXPECT_EQ(0ul, dispatcher()->CallCount());
-
-  watcher()->Start();
-  base::RunLoop run_loop;
-  watcher()->SetQuitClosureForTesting(
-      base::BindLambdaForTesting([&]() { run_loop.Quit(); }));
-
   for (const auto& input : kFakeKeyAPressAndRelease) {
-    WriteInputEvent(input);
+    watcher()->ProcessEvent(input);
   }
-  run_loop.Run();
 
   //  Two events dispatched.
   EXPECT_EQ(2ul, dispatcher()->CallCount());
@@ -209,14 +197,9 @@
 TEST_F(KeyboardInputDataEventWatcherTest, UnknownEvCodes) {
   EXPECT_EQ(0ul, dispatcher()->CallCount());
 
-  watcher()->Start();
   for (const auto& input : kUnhandledKeyboardEvdevEvents) {
-    WriteInputEvent(input);
+    watcher()->ProcessEvent(input);
   }
-  base::RunLoop run_loop;
-  watcher()->SetQuitClosureForTesting(
-      base::BindLambdaForTesting([&]() { run_loop.Quit(); }));
-  run_loop.Run();
 
   // Two events dispatched.
   EXPECT_EQ(6ul, dispatcher()->CallCount());
diff --git a/ash/webui/os_feedback_ui/os_feedback_ui.cc b/ash/webui/os_feedback_ui/os_feedback_ui.cc
index e4248f2..8c6559f 100644
--- a/ash/webui/os_feedback_ui/os_feedback_ui.cc
+++ b/ash/webui/os_feedback_ui/os_feedback_ui.cc
@@ -71,7 +71,6 @@
       {"previewImageDialogLabel", IDS_FEEDBACK_TOOL_PREVIEW_IMAGE_DIALOG_LABEL},
       {"addFileLabel", IDS_FEEDBACK_TOOL_ADD_FILE_LABEL},
       {"replaceFileLabel", IDS_FEEDBACK_TOOL_REPLACE_FILE_LABEL},
-      {"replaceFileArialLabel", IDS_FEEDBACK_TOOL_REPLACE_FILE_ARIA_LABEL},
       {"attachFileLabelTooltip", IDS_FEEDBACK_TOOL_ATTACH_FILE_LABEL_TOOLTIP},
       {"attachFileCheckboxArialLabel",
        IDS_FEEDBACK_TOOL_ATTACH_FILE_CHECKBOX_ARIA_LABEL},
diff --git a/ash/webui/os_feedback_ui/resources/file_attachment.html b/ash/webui/os_feedback_ui/resources/file_attachment.html
index 17355431..3b3e847 100644
--- a/ash/webui/os_feedback_ui/resources/file_attachment.html
+++ b/ash/webui/os_feedback_ui/resources/file_attachment.html
@@ -145,7 +145,7 @@
         [[selectedFileName_]]
       </div>
       <button id="replaceFileButton" class="file-input focusable"
-          aria-label="[[i18n('replaceFileArialLabel')]]"
+          aria-label="[[i18n('replaceFileLabel')]]"
           on-click="handleOpenFileInputClick_" tabindex="0">
         [[i18n('replaceFileLabel')]]
       </button>
diff --git a/ash/wm/client_controlled_state.cc b/ash/wm/client_controlled_state.cc
index cfee9cc..f7244e6 100644
--- a/ash/wm/client_controlled_state.cc
+++ b/ash/wm/client_controlled_state.cc
@@ -347,7 +347,7 @@
                     static_cast<const WindowSnapWMEvent*>(event)->snap_ratio())
               : (is_restoring && window_state->snap_ratio().has_value()
                      ? window_state->snap_ratio().value()
-                     : kDefaultPositionRatio);
+                     : kDefaultSnapRatio);
       gfx::Rect bounds = GetSnappedWindowBoundsInParent(window, next_state_type,
                                                         snap_ratio_to_restore);
       // We don't want Unminimize() to restore the pre-snapped state during the
diff --git a/ash/wm/default_state.cc b/ash/wm/default_state.cc
index 67142abf..f392b45 100644
--- a/ash/wm/default_state.cc
+++ b/ash/wm/default_state.cc
@@ -401,7 +401,7 @@
             ? absl::make_optional(WindowSnapWMEvent::GetFloatValueForSnapRatio(
                   static_cast<const WindowSnapWMEvent*>(event)->snap_ratio()))
             : (is_restoring ? window_state->snap_ratio()
-                            : absl::make_optional(kDefaultPositionRatio)));
+                            : absl::make_optional(kDefaultSnapRatio)));
     return;
   }
 
diff --git a/ash/wm/desks/desks_util.cc b/ash/wm/desks/desks_util.cc
index cc653e1..897e3fc 100644
--- a/ash/wm/desks/desks_util.cc
+++ b/ash/wm/desks/desks_util.cc
@@ -12,6 +12,7 @@
 #include "ash/wm/desks/desk.h"
 #include "ash/wm/desks/desks_bar_view.h"
 #include "ash/wm/desks/desks_controller.h"
+#include "ash/wm/float/float_controller.h"
 #include "ash/wm/overview/overview_controller.h"
 #include "ash/wm/overview/overview_grid.h"
 #include "ash/wm/overview/overview_session.h"
@@ -112,6 +113,16 @@
 ASH_EXPORT bool BelongsToActiveDesk(aura::Window* window) {
   DCHECK(window);
 
+  // A floated window may be associated with a desk, but they would be parented
+  // to the float container.
+  auto* window_state = WindowState::Get(window);
+  if (window_state && window_state->IsFloated()) {
+    auto* desk =
+        Shell::Get()->float_controller()->FindDeskOfFloatedWindow(window);
+    DCHECK(desk);
+    return desk->is_active();
+  }
+
   const int active_desk_id = GetActiveDeskContainerId();
   aura::Window* desk_container = GetDeskContainerForContext(window);
   return desk_container && desk_container->GetId() == active_desk_id;
diff --git a/ash/wm/desks/desks_util.h b/ash/wm/desks/desks_util.h
index c6d1f5a4..5009718 100644
--- a/ash/wm/desks/desks_util.h
+++ b/ash/wm/desks/desks_util.h
@@ -55,8 +55,10 @@
 
 ASH_EXPORT bool BelongsToActiveDesk(aura::Window* window);
 
-// If |context| is a descendent window of a desk container, return that desk
-// container, otherwise return nullptr.
+// If `context` is a descendent window of a desk container, return that desk
+// container, otherwise return nullptr. Note that this will return nullptr if
+// `context` is a descendent of the float container, even if it is associated
+// with a desk container.
 ASH_EXPORT aura::Window* GetDeskContainerForContext(aura::Window* context);
 
 // Returns true if the DesksBar widget should be created in overview mode.
diff --git a/ash/wm/float/float_controller.cc b/ash/wm/float/float_controller.cc
index 19e52a43..81375cc 100644
--- a/ash/wm/float/float_controller.cc
+++ b/ash/wm/float/float_controller.cc
@@ -599,7 +599,8 @@
   auto* desk_controller = DesksController::Get();
   // Get the active desk where the window belongs to before moving it to float
   // container.
-  DCHECK(desks_util::BelongsToActiveDesk(window));
+  DCHECK(desks_util::IsActiveDeskContainer(
+      desks_util::GetDeskContainerForContext(window)));
   const Desk* desk = desk_controller->GetTargetActiveDesk();
   auto* previously_floated_window = FindFloatedWindowOfDesk(desk);
   // Add floated window to `floated_window_info_map_`.
diff --git a/ash/wm/float/float_controller_unittest.cc b/ash/wm/float/float_controller_unittest.cc
index 797e8b2e..582141fc 100644
--- a/ash/wm/float/float_controller_unittest.cc
+++ b/ash/wm/float/float_controller_unittest.cc
@@ -315,6 +315,17 @@
   EXPECT_TRUE(WindowState::Get(window_2.get())->IsFloated());
 }
 
+// Tests that `desks_util::BelongsToActiveDesk()` works as intended.
+TEST_F(WindowFloatTest, BelongsToActiveDesk) {
+  NewDesk();
+
+  std::unique_ptr<aura::Window> window = CreateFloatedWindow();
+  EXPECT_TRUE(desks_util::BelongsToActiveDesk(window.get()));
+
+  ActivateDesk(DesksController::Get()->desks()[1].get());
+  EXPECT_FALSE(desks_util::BelongsToActiveDesk(window.get()));
+}
+
 // Test Desk removal for floating window.
 TEST_F(WindowFloatTest, FloatWindowWithDeskRemoval) {
   auto* desks_controller = DesksController::Get();
@@ -1234,6 +1245,35 @@
   EXPECT_FALSE(float_controller->IsFloatedWindowTuckedForTablet(window.get()));
 }
 
+TEST_F(TabletWindowFloatTest, UntuckWindowGestures) {
+  Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
+  // The window is magnetized to the bottom right by default.
+  std::unique_ptr<aura::Window> window = CreateFloatedWindow();
+  auto* float_controller = Shell::Get()->float_controller();
+
+  // Tuck the window in the bottom right.
+  FlingWindow(window.get(), /*left=*/false, /*up=*/false);
+  ASSERT_TRUE(float_controller->IsFloatedWindowTuckedForTablet(window.get()));
+
+  // Swipe up on the handle. Test the window is still tucked.
+  views::Widget* tuck_handle_widget =
+      float_controller->GetTuckHandleWidget(window.get());
+  const gfx::Point start(
+      tuck_handle_widget->GetWindowBoundsInScreen().CenterPoint());
+  GetEventGenerator()->GestureScrollSequence(
+      start, start + gfx::Vector2d(0, -8), base::Milliseconds(100),
+      /*steps=*/3);
+  ASSERT_TRUE(float_controller->IsFloatedWindowTuckedForTablet(window.get()));
+
+  // Swipe left on the handle. Test that it untucks and magnetizes to the bottom
+  // right.
+  GetEventGenerator()->GestureScrollSequence(
+      start, start + gfx::Vector2d(-8, 0), base::Milliseconds(100),
+      /*steps=*/3);
+  EXPECT_FALSE(float_controller->IsFloatedWindowTuckedForTablet(window.get()));
+  CheckMagnetized(window.get(), FloatController::MagnetismCorner::kBottomRight);
+}
+
 using TabletWindowFloatSplitviewTest = TabletWindowFloatTest;
 
 // Tests the expected behaviour when a window is floated when there are snapped
diff --git a/ash/wm/float/scoped_window_tucker.cc b/ash/wm/float/scoped_window_tucker.cc
index 65ce6ae..1c4108f 100644
--- a/ash/wm/float/scoped_window_tucker.cc
+++ b/ash/wm/float/scoped_window_tucker.cc
@@ -95,6 +95,44 @@
     canvas->DrawImageInt(tuck_icon, 0, 0);
   }
 
+  void OnGestureEvent(ui::GestureEvent* event) override {
+    float detail_x = 0.0, detail_y = 0.0;
+    const ui::GestureEventDetails details = event->details();
+    switch (event->type()) {
+      case ui::ET_GESTURE_SWIPE:
+        // Since ET_GESTURE_SWIPE events don't have a numeric value, set
+        // `detail_x` as an arbitrary positive or negative value.
+        detail_x = details.swipe_right() ? 1.0 : -1.0;
+        break;
+      case ui::ET_SCROLL_FLING_START:
+        detail_x = details.velocity_x();
+        detail_y = details.velocity_y();
+        break;
+      case ui::ET_GESTURE_SCROLL_BEGIN:
+        detail_x = details.scroll_x_hint();
+        detail_y = details.scroll_y_hint();
+        break;
+      case ui::ET_GESTURE_SCROLL_UPDATE:
+        detail_x = details.scroll_x();
+        detail_y = details.scroll_y();
+        break;
+      default:
+        views::Button::OnGestureEvent(event);
+        return;
+    }
+
+    // Ignore vertical gestures.
+    if (std::fabs(detail_x) <= std::fabs(detail_y))
+      return;
+
+    // Handle like a normal button press for events on the tuck handle that are
+    // obvious inward gestures.
+    if ((left_ && detail_x > 0) || (!left_ && detail_x < 0)) {
+      NotifyClick(*event);
+      event->SetHandled();
+    }
+  }
+
  private:
   // Whether the tuck handle is on the left or right edge of the screen. A
   // left tuck handle will have the chevron arrow pointing right and vice
diff --git a/ash/wm/splitview/split_view_controller.cc b/ash/wm/splitview/split_view_controller.cc
index 96bc097..2d37aa60 100644
--- a/ash/wm/splitview/split_view_controller.cc
+++ b/ash/wm/splitview/split_view_controller.cc
@@ -89,7 +89,7 @@
 constexpr float kFixedPositionRatios[] = {0.f, 0.5f, 1.0f};
 
 // The black scrim starts to fade in when the divider is moved past the two
-// optional positions (kOneThirdPositionRatio, kTwoThirdPositionRatio) and
+// optional positions (kOneThirdSnapRatio, kTwoThirdSnapRatio) and
 // reaches to its maximum opacity (kBlackScrimOpacity) after moving
 // kBlackScrimFadeInRatio of the screen width. See https://crbug.com/827730 for
 // details.
@@ -1179,7 +1179,7 @@
 }
 
 int SplitViewController::GetDefaultDividerPosition() const {
-  return GetDividerPosition(SnapPosition::kPrimary, kDefaultPositionRatio);
+  return GetDividerPosition(SnapPosition::kPrimary, kDefaultSnapRatio);
 }
 
 int SplitViewController::GetDividerPosition(SnapPosition snap_position,
@@ -1659,8 +1659,8 @@
 
   NotifyWindowResized();
 
-  if (divider_position_ < GetDividerEndPosition() * kOneThirdPositionRatio ||
-      divider_position_ > GetDividerEndPosition() * kTwoThirdPositionRatio) {
+  if (divider_position_ < GetDividerEndPosition() * kOneThirdSnapRatio ||
+      divider_position_ > GetDividerEndPosition() * kTwoThirdSnapRatio) {
     // Ending overview will also end clamshell split view.
     Shell::Get()->overview_controller()->EndOverview(
         OverviewEndAction::kSplitView);
@@ -2163,7 +2163,7 @@
   if (!IsLayoutHorizontal(root_window_))
     work_area_bounds.Transpose();
   float opacity = kBlackScrimOpacity;
-  const float ratio = kOneThirdPositionRatio - kBlackScrimFadeInRatio;
+  const float ratio = kOneThirdSnapRatio - kBlackScrimFadeInRatio;
   const int distance = std::min(std::abs(location - work_area_bounds.x()),
                                 std::abs(work_area_bounds.right() - location));
   if (distance > work_area_bounds.width() * ratio) {
@@ -2277,12 +2277,11 @@
     min_right_length = secondary_window_min_size.height();
   }
 
-  if (primary_window_distance < divider_end_position * kOneThirdPositionRatio ||
+  if (primary_window_distance < divider_end_position * kOneThirdSnapRatio ||
       primary_window_distance < min_left_length) {
     return SnapPosition::kPrimary;
   }
-  if (secondary_window_distance <
-          divider_end_position * kOneThirdPositionRatio ||
+  if (secondary_window_distance < divider_end_position * kOneThirdSnapRatio ||
       secondary_window_distance < min_right_length) {
     return SnapPosition::kSecondary;
   }
@@ -2518,10 +2517,10 @@
       static_cast<float>(min_left_size) / divider_end_position;
   const float min_size_right_ratio =
       static_cast<float>(min_right_size) / divider_end_position;
-  if (min_size_left_ratio <= kOneThirdPositionRatio)
-    out_position_ratios->push_back(kOneThirdPositionRatio);
-  if (min_size_right_ratio <= kOneThirdPositionRatio)
-    out_position_ratios->push_back(kTwoThirdPositionRatio);
+  if (min_size_left_ratio <= kOneThirdSnapRatio)
+    out_position_ratios->push_back(kOneThirdSnapRatio);
+  if (min_size_right_ratio <= kOneThirdSnapRatio)
+    out_position_ratios->push_back(kTwoThirdSnapRatio);
 }
 
 int SplitViewController::GetWindowComponentForResize(aura::Window* window) {
diff --git a/ash/wm/splitview/split_view_controller.h b/ash/wm/splitview/split_view_controller.h
index 4c27674..e687495 100644
--- a/ash/wm/splitview/split_view_controller.h
+++ b/ash/wm/splitview/split_view_controller.h
@@ -479,8 +479,8 @@
   float FindClosestPositionRatio(float distance, float length);
 
   // Gets the divider optional position ratios. The divider can always be
-  // moved to the positions in |kFixedPositionRatios|. Whether the divider can
-  // be moved to |kOneThirdPositionRatio| or |kTwoThirdPositionRatio| depends
+  // moved to the positions in `kFixedPositionRatios`. Whether the divider can
+  // be moved to `kOneThirdSnapRatio` or `kTwoThirdSnapRatio` depends
   // on the minimum size of current snapped windows.
   void GetDividerOptionalPositionRatios(
       std::vector<float>* out_position_ratios);
@@ -592,8 +592,8 @@
   int divider_position_ = -1;
 
   // The closest position ratio of divider among kFixedPositionRatios,
-  // kOneThirdPositionRatio and kTwoThirdPositionRatio based on current
-  // |divider_position_|. Used to update |divider_position_| on work area
+  // kOneThirdSnapRatio and kTwoThirdSnapRatio based on current
+  // `divider_position_`. Used to update `divider_position_` on work area
   // changes.
   float divider_closest_ratio_ = std::numeric_limits<float>::quiet_NaN();
 
diff --git a/ash/wm/tablet_mode/tablet_mode_multitask_menu.cc b/ash/wm/tablet_mode/tablet_mode_multitask_menu.cc
index 973b84c..b8b0b0e6 100644
--- a/ash/wm/tablet_mode/tablet_mode_multitask_menu.cc
+++ b/ash/wm/tablet_mode/tablet_mode_multitask_menu.cc
@@ -133,13 +133,13 @@
   views::View* clip_view =
       multitask_menu_widget_->SetContentsView(std::make_unique<views::View>());
   clip_view->SetBorder(views::CreateEmptyBorder(kWidgetOutsets.ToInsets()));
+  clip_view->SetUseDefaultFillLayout(true);
   clip_view->SetPaintToLayer(ui::LAYER_NOT_DRAWN);
   clip_view->layer()->SetFillsBoundsOpaquely(false);
   clip_view->layer()->SetMasksToBounds(true);
 
   multitask_menu_view_ = clip_view->AddChildView(
       std::make_unique<TabletModeMultitaskMenuView>(window_, callback));
-  multitask_menu_view_->SizeToPreferredSize();
 
   // TODO(sophiewen): Add shadows on `multitask_menu_view_`.
 
@@ -158,22 +158,16 @@
                                                    window_);
   multitask_menu_widget_->Show();
 
-  // Position the widget on the top center of the window and offset the view
-  // inside it.
-  const gfx::Size pref_size = multitask_menu_view_->GetPreferredSize();
-  gfx::Rect widget_bounds(
-      window_->bounds().CenterPoint().x() - pref_size.width() / 2,
-      window_->bounds().y() + kVerticalPosition, pref_size.width(),
-      pref_size.height());
-
-  views::View* clip_view = multitask_menu_widget_->GetContentsView();
-  clip_view->SetPreferredSize(pref_size);
-
-  multitask_menu_widget_->SetBounds(
-      gfx::Rect(widget_bounds.origin(), clip_view->GetPreferredSize()));
+  // Position the widget on the top center of the window.
+  const gfx::Size widget_size =
+      multitask_menu_widget_->GetContentsView()->GetPreferredSize();
+  const gfx::Point widget_origin(
+      window_->bounds().CenterPoint().x() - widget_size.width() / 2,
+      window_->bounds().y() + kVerticalPosition);
+  multitask_menu_widget_->SetBounds(gfx::Rect(widget_origin, widget_size));
 
   const gfx::Transform transform = gfx::Transform::MakeTranslation(
-      0, -pref_size.height() - kVerticalPosition);
+      0, -widget_size.height() - kVerticalPosition);
 
   ui::Layer* view_layer = multitask_menu_view_->layer();
   views::AnimationBuilder()
diff --git a/ash/wm/tablet_mode/tablet_mode_window_state.cc b/ash/wm/tablet_mode/tablet_mode_window_state.cc
index 5e11055..d7785cd 100644
--- a/ash/wm/tablet_mode/tablet_mode_window_state.cc
+++ b/ash/wm/tablet_mode/tablet_mode_window_state.cc
@@ -21,7 +21,9 @@
 #include "ash/wm/screen_pinning_controller.h"
 #include "ash/wm/splitview/split_view_utils.h"
 #include "ash/wm/tablet_mode/tablet_mode_window_manager.h"
+#include "ash/wm/window_positioning_utils.h"
 #include "ash/wm/window_properties.h"
+#include "ash/wm/window_state.h"
 #include "ash/wm/window_state_util.h"
 #include "ash/wm/window_util.h"
 #include "ash/wm/wm_event.h"
@@ -87,7 +89,8 @@
 }
 
 // Returns the maximized/full screen and/or centered bounds of a window.
-gfx::Rect GetBoundsInTabletMode(WindowState* state_object) {
+gfx::Rect GetBoundsInTabletMode(WindowState* state_object,
+                                absl::optional<float> snap_ratio) {
   aura::Window* window = state_object->window();
 
   if (state_object->IsFullscreen() || state_object->IsPinned())
@@ -96,13 +99,15 @@
   if (state_object->GetStateType() == WindowStateType::kPrimarySnapped) {
     return SplitViewController::Get(Shell::GetPrimaryRootWindow())
         ->GetSnappedWindowBoundsInParent(
-            SplitViewController::SnapPosition::kPrimary, window);
+            SplitViewController::SnapPosition::kPrimary, window,
+            snap_ratio ? *snap_ratio : kDefaultSnapRatio);
   }
 
   if (state_object->GetStateType() == WindowStateType::kSecondarySnapped) {
     return SplitViewController::Get(Shell::GetPrimaryRootWindow())
         ->GetSnappedWindowBoundsInParent(
-            SplitViewController::SnapPosition::kSecondary, window);
+            SplitViewController::SnapPosition::kSecondary, window,
+            snap_ratio ? *snap_ratio : kDefaultSnapRatio);
   }
 
   if (chromeos::wm::features::IsFloatWindowEnabled() &&
@@ -251,7 +256,8 @@
 void TabletModeWindowState::UpdateWindowPosition(
     WindowState* window_state,
     WindowState::BoundsChangeAnimationType animation_type) {
-  const gfx::Rect bounds_in_parent = GetBoundsInTabletMode(window_state);
+  const gfx::Rect bounds_in_parent =
+      GetBoundsInTabletMode(window_state, window_state->snap_ratio());
   if (bounds_in_parent == window_state->window()->GetTargetBounds())
     return;
 
@@ -307,23 +313,24 @@
       break;
     case WM_EVENT_FULLSCREEN:
       UpdateWindow(window_state, WindowStateType::kFullscreen,
-                   true /* animated */);
+                   /*animate=*/true, /*new_snap_ratio=*/absl::nullopt);
       break;
     case WM_EVENT_PIN:
       if (!Shell::Get()->screen_pinning_controller()->IsPinned()) {
         UpdateWindow(window_state, WindowStateType::kPinned,
-                     true /* animated */);
+                     /*animate=*/true, /*new_snap_ratio=*/absl::nullopt);
       }
       break;
     case WM_EVENT_PIP:
       if (!window_state->IsPip()) {
-        UpdateWindow(window_state, WindowStateType::kPip, true /* animated */);
+        UpdateWindow(window_state, WindowStateType::kPip, /*animate=*/true,
+                     /*new_snap_ratio=*/absl::nullopt);
       }
       break;
     case WM_EVENT_TRUSTED_PIN:
       if (!Shell::Get()->screen_pinning_controller()->IsPinned()) {
         UpdateWindow(window_state, WindowStateType::kTrustedPinned,
-                     true /* animated */);
+                     /*animate=*/true, /*new_snap_ratio=*/absl::nullopt);
       }
       break;
     case WM_EVENT_TOGGLE_MAXIMIZE_CAPTION:
@@ -334,7 +341,7 @@
     case WM_EVENT_MAXIMIZE:
       UpdateWindow(window_state,
                    window_state->GetMaximizedOrCenteredWindowType(),
-                   true /* animated */);
+                   /*animate=*/true, /*new_snap_ratio=*/absl::nullopt);
       return;
     case WM_EVENT_NORMAL: {
       // `WM_EVENT_NORMAL` may be restoring state from minimized.
@@ -343,7 +350,7 @@
       } else {
         UpdateWindow(window_state,
                      window_state->GetMaximizedOrCenteredWindowType(),
-                     /*animate=*/true);
+                     /*animate=*/true, /*new_snap_ratio=*/absl::nullopt);
       }
       return;
     }
@@ -358,11 +365,16 @@
         return;
 
       UpdateWindow(window_state, WindowStateType::kFloated,
-                   /*=animate=*/true);
+                   /*=animate=*/true, /*new_snap_ratio=*/absl::nullopt);
       break;
     case WM_EVENT_SNAP_PRIMARY:
     case WM_EVENT_SNAP_SECONDARY:
-      DoTabletSnap(window_state, event->type());
+      DoTabletSnap(
+          window_state, event->type(),
+          WindowSnapWMEvent::GetFloatValueForSnapRatio(
+              event->IsSnapInfoAvailable()
+                  ? static_cast<const WindowSnapWMEvent*>(event)->snap_ratio()
+                  : WindowSnapWMEvent::SnapRatio::kDefaultSnapRatio));
       return;
     case WM_EVENT_CYCLE_SNAP_PRIMARY:
       CycleTabletSnap(window_state,
@@ -374,7 +386,7 @@
       return;
     case WM_EVENT_MINIMIZE:
       UpdateWindow(window_state, WindowStateType::kMinimized,
-                   true /* animated */);
+                   /*=animate=*/true, /*new_snap_ratio=*/absl::nullopt);
       return;
     case WM_EVENT_SHOW_INACTIVE:
     case WM_EVENT_SYSTEM_UI_AREA_CHANGED:
@@ -430,17 +442,20 @@
             IsSnapped(current_state_type_)
                 ? window_state->GetStateType()
                 : window_state->GetMaximizedOrCenteredWindowType();
-        UpdateWindow(window_state, new_state, /*animated=*/true);
+        UpdateWindow(window_state, new_state, /*animate=*/true,
+                     /*new_snap_ratio=*/window_state->snap_ratio());
       }
       break;
     case WM_EVENT_WORKAREA_BOUNDS_CHANGED:
       if (current_state_type_ != WindowStateType::kMinimized)
-        UpdateBounds(window_state, true /* animated */);
+        UpdateBounds(window_state, /*animate=*/true,
+                     /*new_snap_ratio=*/window_state->snap_ratio());
       break;
     case WM_EVENT_DISPLAY_BOUNDS_CHANGED:
       // Don't animate on a screen rotation - just snap to new size.
       if (current_state_type_ != WindowStateType::kMinimized)
-        UpdateBounds(window_state, false /* animated */);
+        UpdateBounds(window_state, /*animate=*/false,
+                     /*new_snap_ratio=*/window_state->snap_ratio());
       break;
   }
 }
@@ -466,8 +481,8 @@
       current_state_type_ != WindowStateType::kFullscreen &&
       current_state_type_ != WindowStateType::kPinned &&
       current_state_type_ != WindowStateType::kTrustedPinned) {
-    UpdateWindow(window_state, state_type_on_attach_,
-                 animate_bounds_on_attach_);
+    UpdateWindow(window_state, state_type_on_attach_, animate_bounds_on_attach_,
+                 window_state->snap_ratio());
   }
 }
 
@@ -479,7 +494,8 @@
 
 void TabletModeWindowState::UpdateWindow(WindowState* window_state,
                                          WindowStateType target_state,
-                                         bool animated) {
+                                         bool animated,
+                                         absl::optional<float> new_snap_ratio) {
   aura::Window* window = window_state->window();
 
   DCHECK(target_state == WindowStateType::kMinimized ||
@@ -497,7 +513,7 @@
     if (target_state == WindowStateType::kMinimized)
       return;
     // If the state type did not change, update it accordingly.
-    UpdateBounds(window_state, animated);
+    UpdateBounds(window_state, animated, new_snap_ratio);
     return;
   }
 
@@ -520,7 +536,7 @@
     if (window_state->IsActive())
       window_state->Deactivate();
   } else {
-    UpdateBounds(window_state, animated);
+    UpdateBounds(window_state, animated, new_snap_ratio);
   }
 
   if ((window->layer()->GetTargetVisibility() ||
@@ -550,7 +566,8 @@
 }
 
 void TabletModeWindowState::UpdateBounds(WindowState* window_state,
-                                         bool animated) {
+                                         bool animated,
+                                         absl::optional<float> new_snap_ratio) {
   // Do not update window's bounds if it's in tab-dragging process. The bounds
   // will be updated later when the drag ends.
   if (window_util::IsDraggingTabs(window_state->window()))
@@ -560,7 +577,8 @@
   if (current_state_type_ == WindowStateType::kMinimized)
     return;
 
-  gfx::Rect bounds_in_parent = GetBoundsInTabletMode(window_state);
+  gfx::Rect bounds_in_parent =
+      GetBoundsInTabletMode(window_state, new_snap_ratio);
   // If we have a target bounds rectangle, we center it and set it
   // accordingly.
   if (!bounds_in_parent.IsEmpty() &&
@@ -595,7 +613,7 @@
   // If |window| is already snapped in |snap_position|, then unsnap |window|.
   if (window == split_view_controller->GetSnappedWindow(snap_position)) {
     UpdateWindow(window_state, window_state->GetMaximizedOrCenteredWindowType(),
-                 /*animated=*/true);
+                 /*animate=*/true, /*new_snap_ratio=*/absl::nullopt);
     window_state->ReadOutWindowCycleSnapAction(
         IDS_WM_RESTORE_SNAPPED_WINDOW_ON_SHORTCUT);
     return;
@@ -614,7 +632,8 @@
 }
 
 void TabletModeWindowState::DoTabletSnap(WindowState* window_state,
-                                         WMEventType snap_event_type) {
+                                         WMEventType snap_event_type,
+                                         absl::optional<float> new_snap_ratio) {
   DCHECK(snap_event_type == WM_EVENT_SNAP_PRIMARY ||
          snap_event_type == WM_EVENT_SNAP_SECONDARY);
 
@@ -637,7 +656,7 @@
   split_view_controller->OnWindowSnapWMEvent(window, snap_event_type);
 
   // Change window state and bounds to the snapped window state and bounds.
-  UpdateWindow(window_state, new_state_type, /*animated=*/false);
+  UpdateWindow(window_state, new_state_type, /*animate=*/false, new_snap_ratio);
 }
 
 void TabletModeWindowState::DoRestore(WindowState* window_state) {
@@ -645,13 +664,16 @@
   if (chromeos::IsSnappedWindowStateType(restore_state)) {
     window_state->set_snap_action_source(
         WindowSnapActionSource::kSnapByWindowStateRestore);
-    DoTabletSnap(window_state, restore_state == WindowStateType::kPrimarySnapped
-                                   ? WM_EVENT_SNAP_PRIMARY
-                                   : WM_EVENT_SNAP_SECONDARY);
+    DoTabletSnap(window_state,
+                 restore_state == WindowStateType::kPrimarySnapped
+                     ? WM_EVENT_SNAP_PRIMARY
+                     : WM_EVENT_SNAP_SECONDARY,
+                 window_state->snap_ratio());
     return;
   }
 
-  UpdateWindow(window_state, restore_state, /*animate=*/true);
+  UpdateWindow(window_state, restore_state, /*animate=*/true,
+               /*new_snap_ratio=*/absl::nullopt);
 }
 
 }  // namespace ash
diff --git a/ash/wm/tablet_mode/tablet_mode_window_state.h b/ash/wm/tablet_mode/tablet_mode_window_state.h
index 2343b14..cbf27547 100644
--- a/ash/wm/tablet_mode/tablet_mode_window_state.h
+++ b/ash/wm/tablet_mode/tablet_mode_window_state.h
@@ -63,34 +63,41 @@
   void set_ignore_wm_events(bool ignore) { ignore_wm_events_ = ignore; }
 
  private:
-  // Updates the window to |new_state_type| and resulting bounds:
+  // Updates the window to `new_state_type` and resulting bounds:
   // Either full screen, maximized centered or minimized. If the state does not
-  // change, only the bounds will be changed. If |animate| is set, the bound
-  // change get animated.
+  // change, only the bounds will be changed. If `animate` is set, the bound
+  // change get animated. If `new_snap_ratio` is set, uses it to update snapped
+  // window bounds.
   void UpdateWindow(WindowState* window_state,
                     chromeos::WindowStateType new_state_type,
-                    bool animate);
+                    bool animate,
+                    absl::optional<float> new_snap_ratio);
 
-  // If |target_state| is PRIMARY/SECONDARY_SNAPPED and the window can be
-  // snapped, returns |target_state|. Otherwise depending on the capabilities
-  // of the window either returns |WindowStateType::kMaximized| or
-  // |WindowStateType::kNormal|.
+  // If `target_state` is PRIMARY/SECONDARY_SNAPPED and the window can be
+  // snapped, returns `target_state`. Otherwise depending on the capabilities
+  // of the window either returns `WindowStateType::kMaximized` or
+  // `WindowStateType::kNormal`.
   chromeos::WindowStateType GetSnappedWindowStateType(
       WindowState* window_state,
       chromeos::WindowStateType target_state);
 
   // Updates the bounds to the maximum possible bounds according to the current
-  // window state. If |animated| is set we animate the change.
-  void UpdateBounds(WindowState* window_state, bool animated);
+  // window state. If `animate` is set we animate the change. If
+  // `new_snap_ratio` is set, uses it to update snapped window bounds.
+  void UpdateBounds(WindowState* window_state,
+                    bool animate,
+                    absl::optional<float> new_snap_ratio);
 
-  // Handles Alt+[ if |snap_position| is
-  // |SplitViewController::SnapPosition::kPrimary|; handles // Alt+] if
-  // |snap_position| is |SplitViewController::SnapPosition::kSecondary|.
+  // Handles Alt+[ if `snap_position` is
+  // `SplitViewController::SnapPosition::kPrimary`; handles // Alt+] if
+  // `snap_position` is `SplitViewController::SnapPosition::kSecondary`.
   void CycleTabletSnap(WindowState* window_state,
                        SplitViewController::SnapPosition snap_position);
 
   // Snap the window in tablet split view if it can be snapped.
-  void DoTabletSnap(WindowState* window_state, WMEventType snap_event_type);
+  void DoTabletSnap(WindowState* window_state,
+                    WMEventType snap_event_type,
+                    absl::optional<float> new_snap_ratio);
 
   // Called by `WM_EVENT_RESTORE`, or a `WM_EVENT_NORMAL` that is restoring.
   // Restores to the state in `window_states`'s restore history.
diff --git a/ash/wm/window_positioning_utils.cc b/ash/wm/window_positioning_utils.cc
index 170cc77..91a2e99 100644
--- a/ash/wm/window_positioning_utils.cc
+++ b/ash/wm/window_positioning_utils.cc
@@ -119,7 +119,7 @@
 
 gfx::Rect GetDefaultSnappedWindowBoundsInParent(aura::Window* window,
                                                 SnapViewType type) {
-  return GetSnappedWindowBoundsInParent(window, type, kDefaultPositionRatio);
+  return GetSnappedWindowBoundsInParent(window, type, kDefaultSnapRatio);
 }
 
 gfx::Rect GetSnappedWindowBounds(const gfx::Rect& work_area,
diff --git a/ash/wm/window_positioning_utils.h b/ash/wm/window_positioning_utils.h
index 8703551..1a0fbd57 100644
--- a/ash/wm/window_positioning_utils.h
+++ b/ash/wm/window_positioning_utils.h
@@ -26,7 +26,13 @@
 // We force at least this many DIPs for any window on the screen.
 const int kMinimumOnScreenArea = 25;
 
-const float kDefaultSnapRatio = 0.5f;
+// The target snap ratio for a snapped window. A window with
+// `kOneThirdSnapRatio` will occupy one thirds of the screen,
+// `kTwoThirdSnapRatio` will occupy two thirds of the screen, and
+// `kDefaultSnapRatio` will occupy the default half of the screen.
+constexpr float kOneThirdSnapRatio = 0.33f;
+constexpr float kDefaultSnapRatio = 0.5f;
+constexpr float kTwoThirdSnapRatio = 0.67f;
 
 // In clamshell mode, users can snap left/right for horizontal display and
 // top/bottom for vertical display. For primary-landscape-oriented display,
diff --git a/ash/wm/window_state.h b/ash/wm/window_state.h
index d246375..a4c53c5f 100644
--- a/ash/wm/window_state.h
+++ b/ash/wm/window_state.h
@@ -43,11 +43,6 @@
 class WindowStateObserver;
 class WMEvent;
 
-// TODO(crbug.com/1323394): Consider moving to a WindowState constants file.
-constexpr float kOneThirdPositionRatio = 0.33f;
-constexpr float kDefaultPositionRatio = 0.5f;
-constexpr float kTwoThirdPositionRatio = 0.67f;
-
 // WindowState manages and defines ash specific window state and
 // behavior. Ash specific per-window state (such as ones that controls
 // window manager behavior) and ash specific window behavior (such as
diff --git a/ash/wm/wm_event.cc b/ash/wm/wm_event.cc
index 9d98ebf..dd756c5 100644
--- a/ash/wm/wm_event.cc
+++ b/ash/wm/wm_event.cc
@@ -4,6 +4,8 @@
 
 #include "ash/wm/wm_event.h"
 
+#include "ash/wm/window_positioning_utils.h"
+
 namespace ash {
 
 WMEvent::WMEvent(WMEventType type) : type_(type) {
@@ -141,13 +143,13 @@
     WindowSnapWMEvent::SnapRatio snap_ratio) {
   switch (snap_ratio) {
     case WindowSnapWMEvent::SnapRatio::kOneThirdSnapRatio:
-      return kOneThirdPositionRatio;
+      return kOneThirdSnapRatio;
     case WindowSnapWMEvent::SnapRatio::kDefaultSnapRatio:
-      return kDefaultPositionRatio;
+      return kDefaultSnapRatio;
     case WindowSnapWMEvent::SnapRatio::kTwoThirdSnapRatio:
-      return kTwoThirdPositionRatio;
+      return kTwoThirdSnapRatio;
     default:
-      return kDefaultPositionRatio;
+      return kDefaultSnapRatio;
   }
 }
 
diff --git a/base/check_op.cc b/base/check_op.cc
index 635c56b..d84055b 100644
--- a/base/check_op.cc
+++ b/base/check_op.cc
@@ -9,8 +9,6 @@
 #include <cstdio>
 #include <sstream>
 
-#include "base/logging.h"
-
 namespace logging {
 
 char* CheckOpValueStr(int v) {
@@ -63,12 +61,6 @@
   return strdup(v.c_str());
 }
 
-char* CheckOpValueStr(float f) {
-  char buf[50];
-  snprintf(buf, sizeof(buf), "%.6f", f);
-  return strdup(buf);
-}
-
 char* CheckOpValueStr(double v) {
   char buf[50];
   snprintf(buf, sizeof(buf), "%.6lf", v);
@@ -90,61 +82,4 @@
   free(v2_str);
 }
 
-#if !CHECK_WILL_STREAM()
-
-void CheckOpFailureStr(char* v1_str, char* v2_str) {
-  LOG(FATAL) << "Check failed (" << v1_str << " vs. " << v2_str << ")";
-  __builtin_unreachable();
-}
-
-template <>
-[[noreturn]] BASE_EXPORT void CheckOpFailure<int, int>(int v1, int v2) {
-  CheckOpFailureStr(CheckOpValueStr(v1), CheckOpValueStr(v2));
-}
-
-template <>
-[[noreturn]] BASE_EXPORT void CheckOpFailure<unsigned, unsigned>(unsigned v1,
-                                                                 unsigned v2) {
-  CheckOpFailureStr(CheckOpValueStr(v1), CheckOpValueStr(v2));
-}
-
-template <>
-[[noreturn]] BASE_EXPORT void CheckOpFailure<long, long>(long v1, long v2) {
-  CheckOpFailureStr(CheckOpValueStr(v1), CheckOpValueStr(v2));
-}
-
-template <>
-[[noreturn]] BASE_EXPORT void CheckOpFailure<unsigned long, unsigned long>(
-    unsigned long v1,
-    unsigned long v2) {
-  CheckOpFailureStr(CheckOpValueStr(v1), CheckOpValueStr(v2));
-}
-
-template <>
-[[noreturn]] BASE_EXPORT void CheckOpFailure<long long, long long>(
-    long long v1,
-    long long v2) {
-  CheckOpFailureStr(CheckOpValueStr(v1), CheckOpValueStr(v2));
-}
-
-template <>
-[[noreturn]] BASE_EXPORT void
-CheckOpFailure<unsigned long long, unsigned long long>(unsigned long long v1,
-                                                       unsigned long long v2) {
-  CheckOpFailureStr(CheckOpValueStr(v1), CheckOpValueStr(v2));
-}
-
-template <>
-[[noreturn]] BASE_EXPORT void CheckOpFailure<float, float>(float v1, float v2) {
-  CheckOpFailureStr(CheckOpValueStr(v1), CheckOpValueStr(v2));
-}
-
-template <>
-[[noreturn]] BASE_EXPORT void CheckOpFailure<double, double>(double v1,
-                                                             double v2) {
-  CheckOpFailureStr(CheckOpValueStr(v1), CheckOpValueStr(v2));
-}
-
-#endif  // !CHECK_WILL_STREAM()
-
 }  // namespace logging
diff --git a/base/check_op.h b/base/check_op.h
index bba96480..9b07a691 100644
--- a/base/check_op.h
+++ b/base/check_op.h
@@ -45,7 +45,6 @@
 BASE_EXPORT char* CheckOpValueStr(unsigned long long v);
 BASE_EXPORT char* CheckOpValueStr(const void* v);
 BASE_EXPORT char* CheckOpValueStr(std::nullptr_t v);
-BASE_EXPORT char* CheckOpValueStr(float v);
 BASE_EXPORT char* CheckOpValueStr(double v);
 BASE_EXPORT char* CheckOpValueStr(const std::string& v);
 
@@ -159,92 +158,8 @@
 
 #if !CHECK_WILL_STREAM()
 
-// This implements optimized versions of CHECK_OP that crash without logging
-// streams, but still logs the parameter values for CHECK_EQ(param1, param2).
-// There are many specializations of CheckOpFailure because the code size
-// generated for the generic CheckOpFailureStr(CheckOpValueStr(v1),
-// CheckOpValueStr(v2)) is significantly larger than a single call to
-// CheckOpFailure<int,int>(v1, v2) for instance.
-//
-// These instantiations match the fundamental types provided by CheckOpValueStr.
-
-[[noreturn]] BASE_EXPORT void CheckOpFailureStr(char* v1_str, char* v2_str);
-
-template <typename T, typename U>
-[[noreturn]] void CheckOpFailure(T v1, U v2) {
-  CheckOpFailureStr(CheckOpValueStr(v1), CheckOpValueStr(v2));
-}
-
-template <>
-[[noreturn]] BASE_EXPORT void CheckOpFailure(int v1, int v2);
-
-template <>
-[[noreturn]] BASE_EXPORT void CheckOpFailure(unsigned v1, unsigned v2);
-
-template <>
-[[noreturn]] BASE_EXPORT void CheckOpFailure(long v1, long v2);
-
-template <>
-[[noreturn]] BASE_EXPORT void CheckOpFailure(unsigned long v1,
-                                             unsigned long v2);
-
-template <>
-[[noreturn]] BASE_EXPORT void CheckOpFailure(long long v1, long long v2);
-
-template <>
-[[noreturn]] BASE_EXPORT void CheckOpFailure(unsigned long long v1,
-                                             unsigned long long v2);
-
-template <>
-[[noreturn]] BASE_EXPORT void CheckOpFailure(float v1, float v2);
-
-template <>
-[[noreturn]] BASE_EXPORT void CheckOpFailure(double v1, double v2);
-
-// This optimized version of CHECK_OP() crashes inside CheapCheck##name##Impl if
-// the condition is false and optimizes out stream parameters regardless. See
-// CHECK_OP_FUNCTION_IMPL() for differences with the unoptimized version.
-#define CHECK_OP(name, op, val1, val2)                           \
-  switch (0)                                                     \
-  case 0:                                                        \
-  default:                                                       \
-    if (::logging::CheapCheck##name##Impl((val1), (val2)), true) \
-      ;                                                          \
-    else                                                         \
-      EAT_CHECK_STREAM_PARAMS()
-
-// The second overload avoids address-taking of static members for
-// fundamental types.
-#define DEFINE_CHEAP_CHECK_OP_IMPL(name, op)                                \
-  template <typename T, typename U,                                         \
-            std::enable_if_t<!std::is_fundamental<T>::value ||              \
-                                 !std::is_fundamental<U>::value,            \
-                             int> = 0>                                      \
-  constexpr ALWAYS_INLINE void CheapCheck##name##Impl(const T& v1,          \
-                                                      const U& v2) {        \
-    if (ANALYZER_ASSUME_TRUE(v1 op v2))                                     \
-      return;                                                               \
-    ::logging::CheckOpFailureStr(CheckOpValueStr(v1), CheckOpValueStr(v2)); \
-  }                                                                         \
-  template <typename T, typename U,                                         \
-            std::enable_if_t<std::is_fundamental<T>::value &&               \
-                                 std::is_fundamental<U>::value,             \
-                             int> = 0>                                      \
-  constexpr ALWAYS_INLINE void CheapCheck##name##Impl(T v1, U v2) {         \
-    if (ANALYZER_ASSUME_TRUE(v1 op v2))                                     \
-      return;                                                               \
-    ::logging::CheckOpFailure(v1, v2);                                      \
-  }
-
-// clang-format off
-DEFINE_CHEAP_CHECK_OP_IMPL(EQ, ==)
-DEFINE_CHEAP_CHECK_OP_IMPL(NE, !=)
-DEFINE_CHEAP_CHECK_OP_IMPL(LE, <=)
-DEFINE_CHEAP_CHECK_OP_IMPL(LT, < )
-DEFINE_CHEAP_CHECK_OP_IMPL(GE, >=)
-DEFINE_CHEAP_CHECK_OP_IMPL(GT, > )
-#undef DEFINE_CHEAP_CHECK_OP_IMPL
-// clang-format on
+// Discard log strings to reduce code bloat.
+#define CHECK_OP(name, op, val1, val2) CHECK((val1)op(val2))
 
 #else
 
diff --git a/base/check_unittest.cc b/base/check_unittest.cc
index bbf0a291..9e5fdb11 100644
--- a/base/check_unittest.cc
+++ b/base/check_unittest.cc
@@ -353,9 +353,11 @@
 struct StructWithOstream {
   bool operator==(const StructWithOstream& o) const { return &o == this; }
 };
+#if CHECK_WILL_STREAM()
 std::ostream& operator<<(std::ostream& out, const StructWithOstream&) {
   return out << "ostream";
 }
+#endif  // CHECK_WILL_STREAM()
 
 struct StructWithToString {
   bool operator==(const StructWithToString& o) const { return &o == this; }
@@ -368,10 +370,12 @@
   }
   std::string ToString() const { return "ToString"; }
 };
+#if CHECK_WILL_STREAM()
 std::ostream& operator<<(std::ostream& out,
                          const StructWithToStringAndOstream&) {
   return out << "ostream";
 }
+#endif  // CHECK_WILL_STREAM()
 
 struct StructWithToStringNotStdString {
   struct PseudoString {};
@@ -381,10 +385,12 @@
   }
   PseudoString ToString() const { return PseudoString(); }
 };
+#if CHECK_WILL_STREAM()
 std::ostream& operator<<(std::ostream& out,
                          const StructWithToStringNotStdString::PseudoString&) {
   return out << "ToString+ostream";
 }
+#endif  // CHECK_WILL_STREAM()
 
 TEST_F(CheckTest, OstreamVsToString) {
   StructWithOstream a, b;
diff --git a/base/win/scoped_handle_unittest.cc b/base/win/scoped_handle_unittest.cc
index c35b8d58..10368896 100644
--- a/base/win/scoped_handle_unittest.cc
+++ b/base/win/scoped_handle_unittest.cc
@@ -27,13 +27,13 @@
 namespace {
 
 std::string FailureMessage(const std::string& msg) {
-#if !defined(DEBUG) && defined(OFFICIAL_BUILD)
+#if defined(NDEBUG) && defined(OFFICIAL_BUILD)
   // Official release builds strip all fatal messages for saving binary size,
   // see base/check.h.
   return "";
 #else
   return msg;
-#endif  // !defined(DEBUG) && defined(OFFICIAL_BUILD)
+#endif  // defined(NDEBUG) && defined(OFFICIAL_BUILD)
 }
 
 // Death tests don't seem to work on Windows 7 32-bit native with hooks enabled.
diff --git a/build/OWNERS b/build/OWNERS
index f05fd4517..802f2fa 100644
--- a/build/OWNERS
+++ b/build/OWNERS
@@ -3,6 +3,7 @@
 # by emailing lsc-policy@chromium.org when this list changes.
 agrieve@chromium.org
 brucedawson@chromium.org
+dpranke@google.com
 jochen@chromium.org
 sdefresne@chromium.org
 thakis@chromium.org
diff --git a/build/android/pylib/local/emulator/avd.py b/build/android/pylib/local/emulator/avd.py
index bdcf590..4de18a9 100644
--- a/build/android/pylib/local/emulator/avd.py
+++ b/build/android/pylib/local/emulator/avd.py
@@ -279,9 +279,19 @@
                         *self._config.system_image_name.split(';'))
 
   @property
+  def _root_ini_path(self):
+    """The <avd_name>.ini file."""
+    return os.path.join(self._avd_home, '%s.ini' % self._config.avd_name)
+
+  @property
   def _config_ini_path(self):
+    """The config.ini file under _avd_dir."""
     return os.path.join(self._avd_dir, 'config.ini')
 
+  @property
+  def _features_ini_path(self):
+    return os.path.join(self._emulator_home, 'advancedFeatures.ini')
+
   def Create(self,
              force=False,
              snapshot=False,
@@ -345,20 +355,15 @@
       logging.info('Modifying AVD configuration.')
 
       # Clear out any previous configuration or state from this AVD.
-      root_ini = os.path.join(android_avd_home,
-                              '%s.ini' % self._config.avd_name)
-      features_ini = os.path.join(self._emulator_home, 'advancedFeatures.ini')
-      avd_dir = self._avd_dir
+      with ini.update_ini_file(self._root_ini_path) as r_ini_contents:
+        r_ini_contents['path.rel'] = 'avd/%s.avd' % self._config.avd_name
 
-      with ini.update_ini_file(root_ini) as root_ini_contents:
-        root_ini_contents['path.rel'] = 'avd/%s.avd' % self._config.avd_name
-
-      with ini.update_ini_file(features_ini) as features_ini_contents:
+      with ini.update_ini_file(self._features_ini_path) as f_ini_contents:
         # features_ini file will not be refreshed by avdmanager during
         # creation. So explicitly clear its content to exclude any leftover
         # from previous creation.
-        features_ini_contents.clear()
-        features_ini_contents.update(self.avd_settings.advanced_features)
+        f_ini_contents.clear()
+        f_ini_contents.update(self.avd_settings.advanced_features)
 
       with ini.update_ini_file(self._config_ini_path) as config_ini_contents:
         # Update avd_properties first so that they won't override settings
@@ -383,7 +388,7 @@
 
         config_ini_contents['hw.sdCard'] = 'yes'
         if self.avd_settings.sdcard.size:
-          sdcard_path = os.path.join(avd_dir, _SDCARD_NAME)
+          sdcard_path = os.path.join(self._avd_dir, _SDCARD_NAME)
           mksdcard_path = os.path.join(os.path.dirname(self._emulator_path),
                                        'mksdcard')
           cmd_helper.RunCmd([
@@ -421,7 +426,7 @@
       instance = _AvdInstance(self._emulator_path, self._emulator_home,
                               self._config)
       # Enable debug for snapshot when it is set to True
-      debug_tags = 'init,snapshot' if snapshot else None
+      debug_tags = 'time,init,snapshot' if snapshot else None
       # Installing privileged apks requires modifying the system
       # image.
       writable_system = bool(privileged_apk_tuples)
@@ -473,7 +478,7 @@
       # operation in some circumstances (beyond the obvious -read-only ones),
       # and there seems to be no mechanism by which it gets closed or deleted.
       # See https://bit.ly/2pWQTH7 for context.
-      multiInstanceLockFile = os.path.join(avd_dir, 'multiinstance.lock')
+      multiInstanceLockFile = os.path.join(self._avd_dir, 'multiinstance.lock')
       if os.path.exists(multiInstanceLockFile):
         os.unlink(multiInstanceLockFile)
 
@@ -485,17 +490,19 @@
           'install_mode':
           'copy',
           'data': [{
-              'dir': os.path.relpath(avd_dir, self._emulator_home)
+              'dir': os.path.relpath(self._avd_dir, self._emulator_home)
           }, {
-              'file': os.path.relpath(root_ini, self._emulator_home)
+              'file':
+              os.path.relpath(self._root_ini_path, self._emulator_home)
           }, {
-              'file': os.path.relpath(features_ini, self._emulator_home)
+              'file':
+              os.path.relpath(self._features_ini_path, self._emulator_home)
           }],
       }
 
       logging.info('Creating AVD CIPD package.')
-      logging.debug('ensure file content: %s',
-                    json.dumps(package_def_content, indent=2))
+      logging.info('ensure file content: %s',
+                   json.dumps(package_def_content, indent=2))
 
       with tempfile_ext.TemporaryFileName(suffix='.json') as package_def_path:
         with open(package_def_path, 'w') as package_def_file:
@@ -664,6 +671,11 @@
      * Emulator instance can be booted correctly.
      * The snapshot can be loaded successfully.
     """
+    # Update the absolute avd path in root_ini file
+    with ini.update_ini_file(self._root_ini_path) as r_ini_contents:
+      r_ini_contents['path'] = self._avd_dir
+
+    # Update hardware settings.
     config_files = [self._config_ini_path]
     # The file hardware.ini within each snapshot need to be updated as well.
     hw_ini_glob_pattern = os.path.join(self._avd_dir, 'snapshots', '*',
diff --git a/build/config/android/config.gni b/build/config/android/config.gni
index 3d5db17..2b3d2a84 100644
--- a/build/config/android/config.gni
+++ b/build/config/android/config.gni
@@ -43,7 +43,7 @@
 
     # The default to use for android:minSdkVersion for targets that do
     # not explicitly set it.
-    default_min_sdk_version = 23
+    default_min_sdk_version = 24
 
     # Static analysis can be either "on" or "off" or "build_server". This
     # controls how android lint, error-prone, bytecode checks are run. This
diff --git a/build/config/fuchsia/BUILD.gn b/build/config/fuchsia/BUILD.gn
index 55f837c..1becaa43 100644
--- a/build/config/fuchsia/BUILD.gn
+++ b/build/config/fuchsia/BUILD.gn
@@ -48,11 +48,7 @@
   ]
 
   if (fuchsia_additional_boot_images == []) {
-    data += [
-      "${boot_image_root}/qemu/qemu-kernel.kernel",
-      "${boot_image_root}/qemu/storage-full.blk",
-      "${boot_image_root}/qemu/zircon-a.zbi",
-    ]
+    data += [ "${boot_image_root}" ]
   }
 
   foreach(fuchsia_additional_boot_image, fuchsia_additional_boot_images) {
diff --git a/build/config/fuchsia/config.gni b/build/config/fuchsia/config.gni
index 67a8dda2..1efe24cc 100644
--- a/build/config/fuchsia/config.gni
+++ b/build/config/fuchsia/config.gni
@@ -5,4 +5,4 @@
 assert(is_fuchsia)
 
 # Compute the path to the arch-specific boot image directory.
-boot_image_root = "//third_party/fuchsia-sdk/images/${target_cpu}"
+boot_image_root = "//third_party/fuchsia-sdk/images/"
diff --git a/build/fuchsia/boot_data.py b/build/fuchsia/boot_data.py
index f70c35a..df9e45c 100644
--- a/build/fuchsia/boot_data.py
+++ b/build/fuchsia/boot_data.py
@@ -59,24 +59,24 @@
     raise Exception('Failed to provision ssh keys')
 
 
-def GetTargetFile(filename, target_arch, target_type):
+def GetTargetFile(filename, image_path):
   """Computes a path to |filename| in the Fuchsia boot image directory specific
-  to |target_type| and |target_arch|."""
+  to |image_path|."""
 
-  return os.path.join(common.IMAGES_ROOT, target_arch, target_type, filename)
+  return os.path.join(common.IMAGES_ROOT, image_path, filename)
 
 
 def GetSSHConfigPath():
   return os.path.join(_SSH_CONFIG_DIR, 'sshconfig')
 
 
-def GetBootImage(output_dir, target_arch, target_type):
+def GetBootImage(output_dir, image_path, image_name):
   """"Gets a path to the Zircon boot image, with the SSH client public key
   added."""
   ProvisionSSH()
   authkeys_path = _GetAuthorizedKeysPath()
   zbi_tool = common.GetHostToolPathFromPlatform('zbi')
-  image_source_path = GetTargetFile('zircon-a.zbi', target_arch, target_type)
+  image_source_path = GetTargetFile(image_name, image_path)
   image_dest_path = os.path.join(output_dir, 'gen', 'fuchsia-with-keys.zbi')
 
   cmd = [
@@ -97,11 +97,11 @@
   ]
 
 
-def AssertBootImagesExist(arch, platform):
-  assert os.path.exists(GetTargetFile('zircon-a.zbi', arch, platform)), \
+def AssertBootImagesExist(image_path):
+  assert os.path.exists(GetTargetFile('fuchsia.zbi', image_path)), \
       'This checkout is missing the files necessary for\n' \
       'booting this configuration of Fuchsia.\n' \
       'To check out the files, add this entry to the "custom_vars"\n' \
       'section of your .gclient file:\n\n' \
-      '    "checkout_fuchsia_boot_images": "%s.%s"\n\n' % \
-           (platform, arch)
+      '    "checkout_fuchsia_boot_images": "%s"\n\n' % \
+           image_path
diff --git a/build/fuchsia/common.py b/build/fuchsia/common.py
index 73c14cd2..b7c95b3d 100644
--- a/build/fuchsia/common.py
+++ b/build/fuchsia/common.py
@@ -14,6 +14,7 @@
     os.path.join(os.path.dirname(__file__), os.pardir, os.pardir))
 IMAGES_ROOT = os.path.join(
     DIR_SOURCE_ROOT, 'third_party', 'fuchsia-sdk', 'images')
+PRODUCT_BUNDLE_SIGNATURE_FILE = os.path.join(IMAGES_ROOT, '.product_bundle')
 SDK_ROOT = os.path.join(DIR_SOURCE_ROOT, 'third_party', 'fuchsia-sdk', 'sdk')
 
 # The number of seconds to wait when trying to attach to a target.
diff --git a/build/fuchsia/emu_target.py b/build/fuchsia/emu_target.py
index ce2ee26e..9093ef1 100644
--- a/build/fuchsia/emu_target.py
+++ b/build/fuchsia/emu_target.py
@@ -25,7 +25,7 @@
 class EmuTarget(target.Target):
   LOCAL_ADDRESS = 'localhost'
 
-  def __init__(self, out_dir, target_cpu, logs_dir):
+  def __init__(self, out_dir, target_cpu, logs_dir, image):
     """out_dir: The directory which will contain the files that are
                    generated to support the emulator deployment.
     target_cpu: The emulated target CPU architecture.
@@ -37,6 +37,29 @@
     self._target_context = None
     self._ffx_target = None
 
+    self._pb_path = self._GetPbPath(image)
+    metadata = self._GetEmuMetadata()
+    self._disk_image = metadata['disk_images'][0]
+    self._kernel = metadata['kernel']
+    self._ramdisk = metadata['initial_ramdisk']
+
+  def _GetPbPath(self, image):
+    if not image:
+      image = 'terminal.qemu-%s' % self._target_cpu
+    if not os.path.exists(common.PRODUCT_BUNDLE_SIGNATURE_FILE):
+      raise FileNotFoundError('There are no product bundles downloaded. Add '
+                              'the images and run "gclient sync" again.')
+    with open(common.PRODUCT_BUNDLE_SIGNATURE_FILE, 'r') as f:
+      signature = json.load(f)
+    if image not in signature['images']:
+      raise FileNotFoundError(f'Product bundle {image} is not downloaded. Add '
+                              'the image and run "gclient sync" again.')
+    return os.path.join(common.IMAGES_ROOT, signature['path'], image, 'images')
+
+  def _GetEmuMetadata(self):
+    with open(os.path.join(self._pb_path, 'product_bundle.json')) as f:
+      return json.load(f)['data']['manifests']['emu']
+
   def __enter__(self):
     return self
 
diff --git a/build/fuchsia/fvdl_target.py b/build/fuchsia/fvdl_target.py
index f8af9ca..724ebcf 100644
--- a/build/fuchsia/fvdl_target.py
+++ b/build/fuchsia/fvdl_target.py
@@ -42,27 +42,19 @@
   def __init__(self, out_dir, target_cpu, require_kvm, enable_graphics,
                hardware_gpu, with_network, cpu_cores, ram_size_mb, logs_dir,
                custom_image):
-    super(FvdlTarget, self).__init__(out_dir, target_cpu, logs_dir)
+
+    super(FvdlTarget, self).__init__(out_dir, target_cpu, logs_dir,
+                                     custom_image)
     self._require_kvm = require_kvm
     self._enable_graphics = enable_graphics
     self._hardware_gpu = hardware_gpu
     self._with_network = with_network
     self._cpu_cores = cpu_cores
     self._ram_size_mb = ram_size_mb
-    self._custom_image = custom_image
 
     self._host = None
     self._pid = None
 
-    if custom_image:
-      components = custom_image.split('.')
-      if len(components) != 2:
-        raise ValueError("Invalid custom_image name:", custom_image)
-      self._image_type, self._image_arch = components
-    else:
-      self._image_arch = self._GetTargetSdkArch()
-      self._image_type = boot_data.TARGET_TYPE_QEMU
-
     # Use a temp file for vdl output.
     self._vdl_output_file = tempfile.NamedTemporaryFile()
 
@@ -102,14 +94,11 @@
     boot_data.ProvisionSSH()
     self._host_ssh_port = common.GetAvailableTcpPort()
     kernel_image = common.EnsurePathExists(
-        boot_data.GetTargetFile('qemu-kernel.kernel', self._image_arch,
-                                self._image_type))
+        boot_data.GetTargetFile(self._kernel, self._pb_path))
     zbi_image = common.EnsurePathExists(
-        boot_data.GetTargetFile('zircon-a.zbi', self._image_arch,
-                                self._image_type))
+        boot_data.GetTargetFile(self._ramdisk, self._pb_path))
     fvm_image = common.EnsurePathExists(
-        boot_data.GetTargetFile('storage-full.blk', self._image_arch,
-                                self._image_type))
+        boot_data.GetTargetFile(self._disk_image, self._pb_path))
     aemu_path = common.EnsurePathExists(
         os.path.join(common.GetHostToolPathFromPlatform('aemu_internal'),
                      'emulator'))
diff --git a/build/fuchsia/fvdl_target_test.py b/build/fuchsia/fvdl_target_test.py
index 554e3b96..77df45e 100755
--- a/build/fuchsia/fvdl_target_test.py
+++ b/build/fuchsia/fvdl_target_test.py
@@ -16,6 +16,12 @@
 from ffx_session import FfxRunner
 from fvdl_target import FvdlTarget, _SSH_KEY_DIR
 
+_EMU_METADATA = {
+    "disk_images": ["fuchsia.blk"],
+    "initial_ramdisk": "fuchsia.zbi",
+    "kernel": "fuchsia.bin"
+}
+
 
 @mock.patch.object(FfxRunner, 'daemon_stop')
 class TestBuildCommandFvdlTarget(unittest.TestCase):
@@ -33,6 +39,8 @@
                           cpu_cores=10)
     common.EnsurePathExists = mock.MagicMock(return_value='image')
     boot_data.ProvisionSSH = mock.MagicMock()
+    FvdlTarget._GetPbPath = mock.MagicMock(return_value='path')
+    FvdlTarget._GetEmuMetadata = mock.MagicMock(return_value=_EMU_METADATA)
     FvdlTarget._Shutdown = mock.MagicMock()
 
   def testBasicEmuCommand(self, mock_daemon_stop):
diff --git a/build/fuchsia/linux_internal.sdk.sha1 b/build/fuchsia/linux_internal.sdk.sha1
index ab42ed4..c04839b 100644
--- a/build/fuchsia/linux_internal.sdk.sha1
+++ b/build/fuchsia/linux_internal.sdk.sha1
@@ -1 +1 @@
-10.20221101.0.1
+10.20221101.1.1
diff --git a/build/fuchsia/qemu_target.py b/build/fuchsia/qemu_target.py
index 890b5a36..da3458f8 100644
--- a/build/fuchsia/qemu_target.py
+++ b/build/fuchsia/qemu_target.py
@@ -17,8 +17,8 @@
 import sys
 import tempfile
 
-from common import GetHostArchFromPlatform, GetEmuRootForPlatform
-from common import EnsurePathExists
+from common import EnsurePathExists, GetHostArchFromPlatform, \
+                   GetEmuRootForPlatform
 from qemu_image import ExecQemuImgWithRetry
 from target import FuchsiaTargetException
 
@@ -40,7 +40,7 @@
 
   def __init__(self, out_dir, target_cpu, cpu_cores, require_kvm, ram_size_mb,
                logs_dir):
-    super(QemuTarget, self).__init__(out_dir, target_cpu, logs_dir)
+    super(QemuTarget, self).__init__(out_dir, target_cpu, logs_dir, None)
     self._cpu_cores=cpu_cores
     self._require_kvm=require_kvm
     self._ram_size_mb=ram_size_mb
@@ -76,18 +76,15 @@
       return False
 
   def _BuildQemuConfig(self):
-    boot_data.AssertBootImagesExist(self._GetTargetSdkArch(), 'qemu')
+    boot_data.AssertBootImagesExist(self._pb_path)
 
     emu_command = [
         '-kernel',
-        EnsurePathExists(
-            boot_data.GetTargetFile('qemu-kernel.kernel',
-                                    self._GetTargetSdkArch(),
-                                    boot_data.TARGET_TYPE_QEMU)),
+        EnsurePathExists(boot_data.GetTargetFile(self._kernel, self._pb_path)),
         '-initrd',
         EnsurePathExists(
-            boot_data.GetBootImage(self._out_dir, self._GetTargetSdkArch(),
-                                   boot_data.TARGET_TYPE_QEMU)),
+            boot_data.GetBootImage(self._out_dir, self._pb_path,
+                                   self._ramdisk)),
         '-m',
         str(self._ram_size_mb),
         '-smp',
@@ -98,8 +95,8 @@
         '-snapshot',
         '-drive',
         'file=%s,format=qcow2,if=none,id=blobstore,snapshot=on,cache=unsafe' %
-        _EnsureBlobstoreQcowAndReturnPath(self._out_dir,
-                                          self._GetTargetSdkArch()),
+        _EnsureBlobstoreQcowAndReturnPath(self._out_dir, self._disk_image,
+                                          self._pb_path),
         '-object',
         'iothread,id=iothread0',
         '-device',
@@ -228,15 +225,14 @@
   return hasher.hexdigest()
 
 
-def _EnsureBlobstoreQcowAndReturnPath(out_dir, target_arch):
+def _EnsureBlobstoreQcowAndReturnPath(out_dir, kernel, image_path):
   """Returns a file containing the Fuchsia blobstore in a QCOW format,
   with extra buffer space added for growth."""
 
   qimg_tool = os.path.join(common.GetEmuRootForPlatform('qemu'),
                            'bin', 'qemu-img')
   fvm_tool = common.GetHostToolPathFromPlatform('fvm')
-  blobstore_path = boot_data.GetTargetFile('storage-full.blk', target_arch,
-                                           'qemu')
+  blobstore_path = boot_data.GetTargetFile(kernel, image_path)
   qcow_path = os.path.join(out_dir, 'gen', 'blobstore.qcow')
 
   # Check a hash of the blobstore to determine if we can re-use an existing
diff --git a/build/fuchsia/test/ffx_integration.py b/build/fuchsia/test/ffx_integration.py
index 9ec0b54a..ab81175 100644
--- a/build/fuchsia/test/ffx_integration.py
+++ b/build/fuchsia/test/ffx_integration.py
@@ -90,10 +90,6 @@
                  with_network: bool,
                  logs_dir: Optional[str] = None) -> None:
         if product_bundle:
-
-            # TODO(fxb/111222): Remove when SDK images' names align with ffx's.
-            if product_bundle == 'workstation_eng.qemu-x64-release':
-                product_bundle = 'workstation_eng.qemu-x64'
             self._product_bundle = product_bundle
         else:
             target_cpu = get_host_arch()
@@ -124,29 +120,13 @@
     @staticmethod
     def _check_ssh_config_file() -> None:
         """Checks for ssh keys and generates them if they are missing."""
+
         script_path = os.path.join(SDK_ROOT, 'bin', 'fuchsia-common.sh')
         check_cmd = [
             'bash', '-c', f'. {script_path}; check-fuchsia-ssh-config'
         ]
         subprocess.run(check_cmd, check=True)
 
-    def _download_product_bundle_if_necessary(self) -> None:
-        """Download the image for a given product bundle."""
-
-        # Check if the product bundle has already been downloaded.
-        # TODO: remove when `ffx product-bundle get` doesn't automatically
-        # redownload.
-        list_cmd = run_ffx_command(('product-bundle', 'list'),
-                                   capture_output=True)
-        sdk_version = run_ffx_command(('sdk', 'version'),
-                                      capture_output=True).stdout.strip()
-        for line in list_cmd.stdout.splitlines():
-            if (self._product_bundle in line and sdk_version in line
-                    and '*' in line):
-                return
-
-        run_ffx_command(('product-bundle', 'get', self._product_bundle))
-
     def __enter__(self) -> str:
         """Start the emulator.
 
@@ -158,7 +138,6 @@
         if self._scoped_pb_metadata:
             self._scoped_pb_metadata.__enter__()
         self._check_ssh_config_file()
-        self._download_product_bundle_if_necessary()
         emu_command = [
             'emu', 'start', self._product_bundle, '--name', self._node_name
         ]
diff --git a/build/fuchsia/test/run_test.py b/build/fuchsia/test/run_test.py
index 2e4ab33..ee232805 100755
--- a/build/fuchsia/test/run_test.py
+++ b/build/fuchsia/test/run_test.py
@@ -71,8 +71,8 @@
     if not runner_args.out_dir:
         raise ValueError('--out-dir must be specified.')
 
-    if runner_args.target_id and not runner_args.device:
-        parser.error('-d is required when --target-id is used')
+    if runner_args.target_id:
+        runner_args.device = True
 
     with ExitStack() as stack:
         if running_unattended():
diff --git a/build/fuchsia/update_product_bundles.py b/build/fuchsia/update_product_bundles.py
new file mode 100755
index 0000000..5010624
--- /dev/null
+++ b/build/fuchsia/update_product_bundles.py
@@ -0,0 +1,157 @@
+#!/usr/bin/env vpython3
+# Copyright 2022 The Chromium Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+"""Updates the Fuchsia product bundles to the given revision. Should be used
+in a 'hooks_os' entry so that it only runs when .gclient's target_os includes
+'fuchsia'."""
+
+import argparse
+import json
+import logging
+import os
+import sys
+import tempfile
+
+import common
+import ffx_session
+import log_manager
+
+_PRODUCT_BUNDLES = [
+    'core.x64-dfv2',
+    'terminal.qemu-arm64',
+    'terminal.qemu-x64',
+    'workstation_eng.chromebook-x64',
+    'workstation_eng.chromebook-x64-dfv2',
+    'workstation_eng.qemu-x64',
+]
+
+_IMAGE_TO_PRODUCT_BUNDLE = {
+    'core.x64-dfv2-release': 'core.x64-dfv2',
+    'qemu.arm64': 'terminal.qemu-arm64',
+    'qemu.x64': 'terminal.qemu-x64',
+    'workstation_eng.chromebook-x64-dfv2-release':
+    'workstation_eng.chromebook-x64-dfv2',
+    'workstation_eng.chromebook-x64-release': 'workstation_eng.chromebook-x64',
+    'workstation_eng.qemu-x64-release': 'workstation_eng.qemu-x64',
+}
+
+
+# TODO(crbug/1361089): Remove when the old scripts have been deprecated.
+def convert_to_product_bundle(images_list):
+  """Convert image names in the SDK to product bundle names."""
+
+  product_bundle_list = []
+  for image in images_list:
+    product_bundle_list.append(_IMAGE_TO_PRODUCT_BUNDLE.get(image, image))
+  return product_bundle_list
+
+
+def get_hash_from_sdk():
+  """Retrieve version info from the SDK."""
+
+  version_file = os.path.join(common.SDK_ROOT, 'meta', 'manifest.json')
+  if not os.path.exists(version_file):
+    raise RuntimeError('Could not detect version file. Make sure the SDK has '
+                       'been downloaded')
+  with open(version_file, 'r') as f:
+    return json.load(f)['id']
+
+
+def download_product_bundle(product_bundle, ffx_runner):
+  """Download product bundles using the SDK."""
+
+  logging.info('Downloading Fuchsia product bundle %s', product_bundle)
+  ffx_runner.run_ffx(('product-bundle', 'get', product_bundle))
+
+
+def main():
+  parser = argparse.ArgumentParser()
+  parser.add_argument('--verbose',
+                      '-v',
+                      action='store_true',
+                      help='Enable debug-level logging.')
+  parser.add_argument(
+      'product_bundles',
+      type=str,
+      help='List of product bundles to download, represented as a comma '
+      'separated list.')
+  args = parser.parse_args()
+
+  logging.basicConfig(level=logging.DEBUG if args.verbose else logging.INFO)
+
+  # Check whether there's Fuchsia support for this platform.
+  common.GetHostOsFromPlatform()
+
+  signature_filename = os.path.join(common.PRODUCT_BUNDLE_SIGNATURE_FILE)
+  curr_signature = {}
+  if os.path.exists(signature_filename):
+    with open(signature_filename, 'r') as f:
+      curr_signature = json.load(f)
+
+  new_sdk_hash = get_hash_from_sdk()
+  new_signature = {'sdk_hash': new_sdk_hash}
+
+  new_product_bundles = convert_to_product_bundle(
+      args.product_bundles.split(','))
+  for pb in new_product_bundles:
+    if pb not in _PRODUCT_BUNDLES:
+      raise ValueError('%s is not part of the Fuchsia product bundle.' % pb)
+
+  with tempfile.TemporaryDirectory() as tmpdirname:
+    ffx_runner = ffx_session.FfxRunner(log_manager.LogManager(None))
+    with ffx_runner.scoped_config('pbms.storage.path', common.IMAGES_ROOT):
+
+      # If SDK versions match, remove the product bundles that are no longer
+      # needed and download missing ones.
+      if curr_signature.get('sdk_hash') == new_sdk_hash:
+        curr_signature.get('sdk_hash')
+        new_signature['path'] = curr_signature.get('path')
+        new_product_bundle_hash = []
+
+        for image in curr_signature.get('images', []):
+          if image in new_product_bundles:
+            new_product_bundle_hash.append(image)
+          else:
+            logging.info('Removing no longer needed Fuchsia image %s' % image)
+            ffx_runner.run_ffx(('product-bundle', 'remove', '-f', image))
+
+        bundles_to_download = set(new_product_bundles) - \
+                              set(curr_signature.get('images', []))
+        for bundle in bundles_to_download:
+          download_product_bundle(bundle, ffx_runner)
+        new_product_bundle_hash.extend(bundles_to_download)
+        new_signature['images'] = new_product_bundle_hash
+
+        with open(signature_filename, 'w') as f:
+          f.write(json.dumps(new_signature))
+        return 0
+
+      # If SDK versions do not match, remove all existing product bundles
+      # and download the ones required.
+      for pb in curr_signature.get('images', []):
+        ffx_runner.run_ffx(('product-bundle', 'remove', '-f', pb))
+
+      curr_subdir = []
+      if os.path.exists(common.IMAGES_ROOT):
+        curr_subdir = os.listdir(common.IMAGES_ROOT)
+      common.MakeCleanDirectory(common.IMAGES_ROOT)
+
+      for pb in new_product_bundles:
+        download_product_bundle(pb, ffx_runner)
+      new_signature['images'] = new_product_bundles
+
+      new_subdir = os.listdir(common.IMAGES_ROOT)
+      subdir_diff = set(new_subdir) - set(curr_subdir)
+      if len(subdir_diff) != 1:
+        raise RuntimeError(f'Expected one new created subdirectory but got '
+                           '{subdir_diff} instead.')
+      new_signature['path'] = list(subdir_diff)[0]
+
+      with open(signature_filename, 'w') as f:
+        f.write(json.dumps(new_signature))
+  return 0
+
+
+if __name__ == '__main__':
+  sys.exit(main())
diff --git a/build/install-build-deps.sh b/build/install-build-deps.sh
index 003a222..dfe8843 100755
--- a/build/install-build-deps.sh
+++ b/build/install-build-deps.sh
@@ -97,19 +97,20 @@
 
 distro_codename=$(lsb_release --codename --short)
 distro_id=$(lsb_release --id --short)
-# TODO(crbug.com/1199405): Remove 14.04 (trusty) and 16.04 (xenial).
-supported_codenames="(trusty|xenial|bionic|disco|eoan|focal|groovy|jammy)"
+# TODO(crbug.com/1199405): Remove 16.04 (xenial).
+supported_codenames="(xenial|bionic|disco|eoan|focal|groovy|jammy)"
 supported_ids="(Debian)"
 if [ 0 -eq "${do_unsupported-0}" ] && [ 0 -eq "${do_quick_check-0}" ] ; then
   if [[ ! $distro_codename =~ $supported_codenames &&
         ! $distro_id =~ $supported_ids ]]; then
     echo -e "ERROR: The only supported distros are\n" \
-      "\tUbuntu 14.04 LTS (trusty with EoL April 2022)\n" \
       "\tUbuntu 16.04 LTS (xenial with EoL April 2024)\n" \
       "\tUbuntu 18.04 LTS (bionic with EoL April 2028)\n" \
-      "\tUbuntu 20.04 LTS (focal with Eol April 2030)\n" \
+      "\tUbuntu 20.04 LTS (focal with EoL April 2030)\n" \
+      "\tUbuntu 19.04 (disco)\n" \
+      "\tUbuntu 19.10 (eoan)\n" \
       "\tUbuntu 20.10 (groovy)\n" \
-      "\tUbuntu 22.04 LTS (jammy with Eol April 2032)\n" \
+      "\tUbuntu 22.04 LTS (jammy with EoL April 2032)\n" \
       "\tDebian 10 (buster) or later" >&2
     exit 1
   fi
@@ -156,6 +157,7 @@
   devscripts
   fakeroot
   flex
+  fuse
   git-core
   gperf
   libasound2-dev
@@ -317,6 +319,7 @@
 
 # 32-bit libraries needed for a 32-bit build
 lib32_list="$lib32_list
+  fuse:i386
   libasound2:i386
   libatk-bridge2.0-0:i386
   libatk1.0-0:i386
@@ -432,14 +435,6 @@
 fi
 
 case $distro_codename in
-  trusty)
-    backwards_compatible_list+=" \
-      libgbm-dev-lts-trusty
-      libgl1-mesa-dev-lts-trusty
-      libgl1-mesa-glx-lts-trusty:i386
-      libgles2-mesa-dev-lts-trusty
-      mesa-common-dev-lts-trusty"
-    ;;
   xenial)
     backwards_compatible_list+=" \
       libgbm-dev-lts-xenial
@@ -455,12 +450,8 @@
           linux-libc-dev-armhf-cross
           g++-arm-linux-gnueabihf"
 
-# Work around for dependency issue Ubuntu/Trusty: http://crbug.com/435056
+# Work around for dependency issue Ubuntu: http://crbug.com/435056
 case $distro_codename in
-  trusty)
-    arm_list+=" g++-4.8-multilib-arm-linux-gnueabihf
-                gcc-4.8-multilib-arm-linux-gnueabihf"
-    ;;
   xenial|bionic)
     arm_list+=" g++-5-multilib-arm-linux-gnueabihf
                 gcc-5-multilib-arm-linux-gnueabihf
@@ -615,7 +606,7 @@
 # that are part of v8 need to be compiled with -m32 which means
 # that basic multilib support is needed.
 if file -L /sbin/init | grep -q 'ELF 64-bit'; then
-  # gcc-multilib conflicts with the arm cross compiler (at least in trusty) but
+  # gcc-multilib conflicts with the arm cross compiler but
   # g++-X.Y-multilib gives us the 32-bit support that we need. Find out the
   # appropriate value of X and Y by seeing what version the current
   # distribution's g++-multilib package depends on.
@@ -816,4 +807,4 @@
   for CHROMIUM_LOCALE in ${CHROMIUM_LOCALES}; do
     sudo locale-gen ${CHROMIUM_LOCALE}
   done
-fi
+fi
\ No newline at end of file
diff --git a/cc/BUILD.gn b/cc/BUILD.gn
index bc0b076c..96e1c03 100644
--- a/cc/BUILD.gn
+++ b/cc/BUILD.gn
@@ -676,7 +676,6 @@
 
   sources = [
     "base/delayed_unique_notifier_unittest.cc",
-    "base/float_quad_unittest.cc",
     "base/histograms_unittest.cc",
     "base/index_rect_unittest.cc",
     "base/list_container_unittest.cc",
diff --git a/cc/base/float_quad_unittest.cc b/cc/base/float_quad_unittest.cc
deleted file mode 100644
index 313bcc3..0000000
--- a/cc/base/float_quad_unittest.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2011 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/base/math_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/geometry/quad_f.h"
-#include "ui/gfx/geometry/rect_f.h"
-#include "ui/gfx/geometry/transform.h"
-
-namespace cc {
-namespace {
-
-// TODO(danakj) Move this test to ui/gfx/ when we don't need MathUtil::MapQuad.
-TEST(FloatQuadTest, IsRectilinearTest) {
-  const int kNumRectilinear = 8;
-  gfx::Transform rectilinear_trans[kNumRectilinear];
-  rectilinear_trans[1].Rotate(90.f);
-  rectilinear_trans[2].Rotate(180.f);
-  rectilinear_trans[3].Rotate(270.f);
-  rectilinear_trans[4].Skew(0.00000000001f, 0.0f);
-  rectilinear_trans[5].Skew(0.0f, 0.00000000001f);
-  rectilinear_trans[6].Scale(0.00001f, 0.00001f);
-  rectilinear_trans[6].Rotate(180.f);
-  rectilinear_trans[7].Scale(100000.f, 100000.f);
-  rectilinear_trans[7].Rotate(180.f);
-
-  gfx::QuadF original(
-      gfx::RectF(0.01010101f, 0.01010101f, 100.01010101f, 100.01010101f));
-
-  for (int i = 0; i < kNumRectilinear; ++i) {
-    bool clipped = false;
-    gfx::QuadF quad =
-        MathUtil::MapQuad(rectilinear_trans[i], original, &clipped);
-    ASSERT_TRUE(!clipped) << "case " << i;
-    EXPECT_TRUE(quad.IsRectilinear()) << "case " << i;
-  }
-
-  const int kNumNonRectilinear = 10;
-  gfx::Transform non_rectilinear_trans[kNumNonRectilinear];
-  non_rectilinear_trans[0].Rotate(359.9999f);
-  non_rectilinear_trans[1].Rotate(0.0000001f);
-  non_rectilinear_trans[2].Rotate(89.9999f);
-  non_rectilinear_trans[3].Rotate(90.00001f);
-  non_rectilinear_trans[4].Rotate(179.9999f);
-  non_rectilinear_trans[5].Rotate(180.00001f);
-  non_rectilinear_trans[6].Rotate(269.9999f);
-  non_rectilinear_trans[7].Rotate(270.0001f);
-  non_rectilinear_trans[8].Skew(0.00001f, 0.0f);
-  non_rectilinear_trans[9].Skew(0.0f, 0.00001f);
-
-  for (int i = 0; i < kNumNonRectilinear; ++i) {
-    bool clipped = false;
-    gfx::QuadF quad =
-        MathUtil::MapQuad(non_rectilinear_trans[i], original, &clipped);
-    ASSERT_TRUE(!clipped) << "case " << i;
-    EXPECT_FALSE(quad.IsRectilinear()) << "case " << i;
-  }
-}
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/paint/paint_shader.cc b/cc/paint/paint_shader.cc
index ee909e0..dcda62b 100644
--- a/cc/paint/paint_shader.cc
+++ b/cc/paint/paint_shader.cc
@@ -75,14 +75,16 @@
   return shader;
 }
 
-sk_sp<PaintShader> PaintShader::MakeLinearGradient(const SkPoint points[],
-                                                   const SkColor4f colors[],
-                                                   const SkScalar pos[],
-                                                   int count,
-                                                   SkTileMode mode,
-                                                   uint32_t flags,
-                                                   const SkMatrix* local_matrix,
-                                                   SkColor4f fallback_color) {
+sk_sp<PaintShader> PaintShader::MakeLinearGradient(
+    const SkPoint points[],
+    const SkColor4f colors[],
+    const SkScalar pos[],
+    int count,
+    SkTileMode mode,
+    SkGradientShader::Interpolation interpolation,
+    uint32_t flags,
+    const SkMatrix* local_matrix,
+    SkColor4f fallback_color) {
   sk_sp<PaintShader> shader(new PaintShader(Type::kLinearGradient));
 
   // There are always two points, the start and the end.
@@ -91,20 +93,23 @@
   shader->SetColorsAndPositions(colors, pos, count);
   shader->SetMatrixAndTiling(local_matrix, mode, mode);
   shader->SetFlagsAndFallback(flags, fallback_color);
+  shader->SetGradientInterpolation(interpolation);
 
   shader->ResolveSkObjects();
   return shader;
 }
 
-sk_sp<PaintShader> PaintShader::MakeRadialGradient(const SkPoint& center,
-                                                   SkScalar radius,
-                                                   const SkColor4f colors[],
-                                                   const SkScalar pos[],
-                                                   int count,
-                                                   SkTileMode mode,
-                                                   uint32_t flags,
-                                                   const SkMatrix* local_matrix,
-                                                   SkColor4f fallback_color) {
+sk_sp<PaintShader> PaintShader::MakeRadialGradient(
+    const SkPoint& center,
+    SkScalar radius,
+    const SkColor4f colors[],
+    const SkScalar pos[],
+    int count,
+    SkTileMode mode,
+    SkGradientShader::Interpolation interpolation,
+    uint32_t flags,
+    const SkMatrix* local_matrix,
+    SkColor4f fallback_color) {
   sk_sp<PaintShader> shader(new PaintShader(Type::kRadialGradient));
 
   shader->center_ = center;
@@ -112,6 +117,7 @@
   shader->SetColorsAndPositions(colors, pos, count);
   shader->SetMatrixAndTiling(local_matrix, mode, mode);
   shader->SetFlagsAndFallback(flags, fallback_color);
+  shader->SetGradientInterpolation(interpolation);
 
   shader->ResolveSkObjects();
   return shader;
@@ -126,6 +132,7 @@
     const SkScalar pos[],
     int count,
     SkTileMode mode,
+    SkGradientShader::Interpolation interpolation,
     uint32_t flags,
     const SkMatrix* local_matrix,
     SkColor4f fallback_color) {
@@ -138,22 +145,25 @@
   shader->SetColorsAndPositions(colors, pos, count);
   shader->SetMatrixAndTiling(local_matrix, mode, mode);
   shader->SetFlagsAndFallback(flags, fallback_color);
+  shader->SetGradientInterpolation(interpolation);
 
   shader->ResolveSkObjects();
   return shader;
 }
 
-sk_sp<PaintShader> PaintShader::MakeSweepGradient(SkScalar cx,
-                                                  SkScalar cy,
-                                                  const SkColor4f colors[],
-                                                  const SkScalar pos[],
-                                                  int color_count,
-                                                  SkTileMode mode,
-                                                  SkScalar start_degrees,
-                                                  SkScalar end_degrees,
-                                                  uint32_t flags,
-                                                  const SkMatrix* local_matrix,
-                                                  SkColor4f fallback_color) {
+sk_sp<PaintShader> PaintShader::MakeSweepGradient(
+    SkScalar cx,
+    SkScalar cy,
+    const SkColor4f colors[],
+    const SkScalar pos[],
+    int color_count,
+    SkTileMode mode,
+    SkScalar start_degrees,
+    SkScalar end_degrees,
+    SkGradientShader::Interpolation interpolation,
+    uint32_t flags,
+    const SkMatrix* local_matrix,
+    SkColor4f fallback_color) {
   sk_sp<PaintShader> shader(new PaintShader(Type::kSweepGradient));
 
   shader->center_ = SkPoint::Make(cx, cy);
@@ -162,6 +172,7 @@
   shader->SetColorsAndPositions(colors, pos, color_count);
   shader->SetMatrixAndTiling(local_matrix, mode, mode);
   shader->SetFlagsAndFallback(flags, fallback_color);
+  shader->SetGradientInterpolation(interpolation);
 
   shader->ResolveSkObjects();
   return shader;
@@ -386,13 +397,6 @@
   SkSamplingOptions sampling(
       PaintFlags::FilterQualityToSkSamplingOptions(quality));
 
-  // TODO(crbug/1308932): Remove this helper vector colors and make all
-  // SkColor4f.
-  std::vector<SkColor> colors;
-  colors.reserve(colors.size());
-  for (auto& c : colors_)
-    colors.push_back(c.toSkColor());
-
   switch (shader_type_) {
     case Type::kEmpty:
       return SkShaders::Empty();
@@ -401,12 +405,10 @@
       break;
     case Type::kLinearGradient: {
       SkPoint points[2] = {start_point_, end_point_};
-      // TODO(crbug/1308932): Remove this helper vector colors and make all
-      // SkColor4f.
       return SkGradientShader::MakeLinear(
-          points, colors.data(),
+          points, colors_.data(), nullptr /*sk_sp<SkColorSpace>*/,
           positions_.empty() ? nullptr : positions_.data(),
-          static_cast<int>(colors.size()), tx_, flags_,
+          static_cast<int>(colors_.size()), tx_, gradient_interpolation_,
           base::OptionalToPtr(local_matrix_));
     }
     case Type::kRadialGradient:
@@ -414,14 +416,14 @@
           center_, start_radius_, colors_.data(),
           nullptr /*sk_sp<SkColorSpace>*/,
           positions_.empty() ? nullptr : positions_.data(),
-          static_cast<int>(colors_.size()), tx_, flags_,
+          static_cast<int>(colors_.size()), tx_, gradient_interpolation_,
           base::OptionalToPtr(local_matrix_));
     case Type::kTwoPointConicalGradient:
       return SkGradientShader::MakeTwoPointConical(
           start_point_, start_radius_, end_point_, end_radius_, colors_.data(),
           nullptr /*sk_sp<SkColorSpace>*/,
           positions_.empty() ? nullptr : positions_.data(),
-          static_cast<int>(colors_.size()), tx_, flags_,
+          static_cast<int>(colors_.size()), tx_, gradient_interpolation_,
           base::OptionalToPtr(local_matrix_));
     case Type::kSweepGradient:
       return SkGradientShader::MakeSweep(
@@ -429,7 +431,7 @@
           nullptr /*sk_sp<SkColorSpace>*/,
           positions_.empty() ? nullptr : positions_.data(),
           static_cast<int>(colors_.size()), tx_, start_degrees_, end_degrees_,
-          flags_, base::OptionalToPtr(local_matrix_));
+          gradient_interpolation_, base::OptionalToPtr(local_matrix_));
     case Type::kImage:
       if (sk_cached_image_) {
         return sk_cached_image_->makeShader(tx_, ty_, sampling,
diff --git a/cc/paint/paint_shader.h b/cc/paint/paint_shader.h
index 1cc771ec..9344725 100644
--- a/cc/paint/paint_shader.h
+++ b/cc/paint/paint_shader.h
@@ -16,6 +16,7 @@
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/skia/include/core/SkImage.h"
 #include "third_party/skia/include/core/SkScalar.h"
+#include "third_party/skia/include/effects/SkGradientShader.h"
 #include "ui/gfx/geometry/size_f.h"
 
 class SkShader;
@@ -62,6 +63,7 @@
       const SkScalar* pos,
       int count,
       SkTileMode mode,
+      SkGradientShader::Interpolation interpolation = DefaultInterpolation(),
       uint32_t flags = 0,
       const SkMatrix* local_matrix = nullptr,
       SkColor4f fallback_color = SkColors::kTransparent);
@@ -73,6 +75,7 @@
       const SkScalar pos[],
       int color_count,
       SkTileMode mode,
+      SkGradientShader::Interpolation interpolation = DefaultInterpolation(),
       uint32_t flags = 0,
       const SkMatrix* local_matrix = nullptr,
       SkColor4f fallback_color = SkColors::kTransparent);
@@ -86,6 +89,7 @@
       const SkScalar pos[],
       int color_count,
       SkTileMode mode,
+      SkGradientShader::Interpolation interpolation = DefaultInterpolation(),
       uint32_t flags = 0,
       const SkMatrix* local_matrix = nullptr,
       SkColor4f fallback_color = SkColors::kTransparent);
@@ -99,6 +103,7 @@
       SkTileMode mode,
       SkScalar start_degrees,
       SkScalar end_degrees,
+      SkGradientShader::Interpolation interpolation = DefaultInterpolation(),
       uint32_t flags = 0,
       const SkMatrix* local_matrix = nullptr,
       SkColor4f fallback_color = SkColors::kTransparent);
@@ -183,6 +188,11 @@
   FRIEND_TEST_ALL_PREFIXES(PaintOpBufferTest, PaintRecordShaderSerialization);
   FRIEND_TEST_ALL_PREFIXES(PaintOpBufferTest, RecordShadersCached);
 
+  static SkGradientShader::Interpolation DefaultInterpolation() {
+    SkGradientShader::Interpolation default_interpolation;
+    return default_interpolation;
+  }
+
   explicit PaintShader(Type type);
 
   bool GetClampedRasterizationTileRect(const SkMatrix& ctm,
@@ -231,6 +241,9 @@
                              int count);
   void SetMatrixAndTiling(const SkMatrix* matrix, SkTileMode tx, SkTileMode ty);
   void SetFlagsAndFallback(uint32_t flags, SkColor4f fallback_color);
+  void SetGradientInterpolation(SkGradientShader::Interpolation interpolation) {
+    gradient_interpolation_ = interpolation;
+  }
 
   Type shader_type_ = Type::kShaderCount;
 
@@ -263,6 +276,8 @@
   std::vector<SkColor4f> colors_;
   std::vector<SkScalar> positions_;
 
+  SkGradientShader::Interpolation gradient_interpolation_;
+
   // Cached intermediates, for Paint objects that may not be thread-safe
   sk_sp<SkPicture> sk_cached_picture_;
   sk_sp<SkImage> sk_cached_image_;
diff --git a/chrome/android/expectations/lint-baseline.xml b/chrome/android/expectations/lint-baseline.xml
index f4ef3020..389e15e 100644
--- a/chrome/android/expectations/lint-baseline.xml
+++ b/chrome/android/expectations/lint-baseline.xml
@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 7.4.0-alpha05" type="baseline" client="" dependencies="true" name="" variant="all" version="7.4.0-alpha05">
+<issues format="6" by="lint 8.0.0-alpha06" type="baseline" client="" dependencies="true" name="" variant="all" version="8.0.0-alpha06">
 
     <issue
         id="LintError"
-        message="../../chrome/android/expectations/lint-baseline.xml (relative to /usr/local/google/home/wnwen/z1/src/out/Debug) does not exist"
+        message="../../chrome/android/expectations/lint-baseline.xml (relative to /usr/local/google/code/clankium/src/out/Lint-Default) does not exist"
         errorLine1="  &lt;baseline file=&quot;../../chrome/android/expectations/lint-baseline.xml&quot;/>"
         errorLine2="  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
@@ -13,14 +13,25 @@
     </issue>
 
     <issue
-        id="ResourceType"
-        message="Expected resource of type styleable"
-        errorLine1="        TypedArray attrs = mContext.getTheme().obtainStyledAttributes(popupLayoutAttrs);"
-        errorLine2="                                                                      ~~~~~~~~~~~~~~~~">
+        id="GestureBackNavigation"
+        message="If intercepting back events, this should be handled through the registration of callbacks on the window level; Please see https://developer.android.com/about/versions/13/features/predictive-back-gesture"
+        errorLine1="            if (keyCode == KeyEvent.KEYCODE_BACK) {"
+        errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/content/public/android/java/src/org/chromium/content/browser/selection/LegacyPastePopupMenu.java"
-            line="52"
-            column="71"/>
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/findinpage/FindToolbar.java"
+            line="138"
+            column="28"/>
+    </issue>
+
+    <issue
+        id="GestureBackNavigation"
+        message="If intercepting back events, this should be handled through the registration of callbacks on the window level; Please see https://developer.android.com/about/versions/13/features/predictive-back-gesture"
+        errorLine1="        } else if (keyCode == KeyEvent.KEYCODE_BACK) {"
+        errorLine2="                              ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="../../chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediator.java"
+            line="1143"
+            column="31"/>
     </issue>
 
     <issue
@@ -29,7 +40,7 @@
         errorLine1="                R.style.SelectPopupDialog, SELECT_DIALOG_ATTRS);"
         errorLine2="                                           ~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/content/public/android/java/src/org/chromium/content/browser/input/SelectPopupDialog.java"
+            file="../../content/public/android/java/src/org/chromium/content/browser/input/SelectPopupDialog.java"
             line="115"
             column="44"/>
     </issue>
@@ -40,40 +51,18 @@
         errorLine1="        StatusIconResource statusIcon = icon == 0 ? null : new StatusIconResource(icon, tint);"
         errorLine2="                                                                                        ~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusMediator.java"
-            line="523"
+            file="../../chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusMediator.java"
+            line="490"
             column="89"/>
     </issue>
 
     <issue
-        id="ResourceType"
-        message="Expected resource of type styleable"
-        errorLine1="        TypedArray ta = context.obtainStyledAttributes(getThemeOverlayStyleResourceId(), attrs);"
-        errorLine2="                                                                                         ~~~~~">
-        <location
-            file="$SRC/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiThemeProvider.java"
-            line="532"
-            column="90"/>
-    </issue>
-
-    <issue
-        id="BlockedPrivateApi"
-        message="Reflective access to getViolationClass is forbidden when targeting API 32 and above"
-        errorLine1="                        violationInfoClass.getDeclaredMethod(&quot;getViolationClass&quot;);"
-        errorLine2="                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/components/strictmode/android/java/src/org/chromium/components/strictmode/ReflectiveThreadStrictModeInterceptor.java"
-            line="122"
-            column="25"/>
-    </issue>
-
-    <issue
         id="DiscouragedPrivateApi"
         message="Reflective access to sPackageManager, which is not part of the public SDK and therefore likely to change in future Android releases"
         errorLine1="            Field packageManagerField = activityThreadClass.getDeclaredField(&quot;sPackageManager&quot;);"
         errorLine2="                                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/embedder_support/android/java/src/org/chromium/components/embedder_support/application/FontPreloadingWorkaround.java"
+            file="../../components/embedder_support/android/java/src/org/chromium/components/embedder_support/application/FontPreloadingWorkaround.java"
             line="68"
             column="41"/>
     </issue>
@@ -84,7 +73,7 @@
         errorLine1="        Field violationTimingField = StrictMode.class.getDeclaredField(&quot;violationsBeingTimed&quot;);"
         errorLine2="                                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/strictmode/android/java/src/org/chromium/components/strictmode/ReflectiveThreadStrictModeInterceptor.java"
+            file="../../components/strictmode/android/java/src/org/chromium/components/strictmode/ReflectiveThreadStrictModeInterceptor.java"
             line="104"
             column="38"/>
     </issue>
@@ -95,7 +84,7 @@
         errorLine1="            field = StrictMode.ThreadPolicy.class.getDeclaredField(&quot;mask&quot;);"
         errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/weblayer/browser/java/org/chromium/weblayer_private/interfaces/StrictModeWorkaround.java"
+            file="../../weblayer/browser/java/org/chromium/weblayer_private/interfaces/StrictModeWorkaround.java"
             line="32"
             column="21"/>
     </issue>
@@ -106,19 +95,8 @@
         errorLine1="                resources.getIdentifier(&quot;status_bar_height&quot;, &quot;dimen&quot;, &quot;android&quot;);"
         errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/password_manager/AccountChooserDialog.java"
-            line="247"
-            column="17"/>
-    </issue>
-
-    <issue
-        id="InternalInsetResource"
-        message="Using internal inset dimension resource `status_bar_height` is not supported"
-        errorLine1="                mContext.getResources().getIdentifier(&quot;status_bar_height&quot;, &quot;dimen&quot;, &quot;android&quot;);"
-        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/content/public/android/java/src/org/chromium/content/browser/selection/LegacyPastePopupMenu.java"
-            line="64"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/password_manager/AccountChooserDialog.java"
+            line="249"
             column="17"/>
     </issue>
 
@@ -128,8 +106,8 @@
         errorLine1="                mActivity.getResources().getIdentifier(&quot;status_bar_height&quot;, &quot;dimen&quot;, &quot;android&quot;);"
         errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/customtabs/PartialCustomTabHeightStrategy.java"
-            line="752"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/customtabs/PartialCustomTabHeightStrategy.java"
+            line="868"
             column="17"/>
     </issue>
 
@@ -139,949 +117,850 @@
         errorLine1="        int statusBarId = resources.getIdentifier(&quot;status_bar_height&quot;, &quot;dimen&quot;, &quot;android&quot;);"
         errorLine2="                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/tab/TabUtils.java"
-            line="75"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/tab/TabUtils.java"
+            line="118"
             column="27"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 24 (current min is 23): `isCleartextTrafficPermitted`"
-        errorLine1="            return NetworkSecurityPolicyProxy.getInstance().isCleartextTrafficPermitted(host);"
-        errorLine2="                                                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/net/android/java/src/org/chromium/net/AndroidNetworkLibrary.java"
-            line="382"
-            column="61"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 26 (current min is 23): `getChannelIdForOrigin`"
+        message="Call requires API level 26 (current min is 24): `getChannelIdForOrigin`"
         errorLine1="                SiteChannelsManager.getInstance().getChannelIdForOrigin(mOrigin.toString());"
         errorLine2="                                                  ~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/android/webapps/launchpad/java/src/org/chromium/chrome/browser/webapps/launchpad/AppManagementMenuPermissionsMediator.java"
+            file="../../chrome/browser/android/webapps/launchpad/java/src/org/chromium/chrome/browser/webapps/launchpad/AppManagementMenuPermissionsMediator.java"
             line="107"
             column="51"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 26 (current min is 23): `getInstance`"
+        message="Call requires API level 26 (current min is 24): `getInstance`"
         errorLine1="                SiteChannelsManager.getInstance().getChannelIdForOrigin(mOrigin.toString());"
         errorLine2="                                    ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/android/webapps/launchpad/java/src/org/chromium/chrome/browser/webapps/launchpad/AppManagementMenuPermissionsMediator.java"
+            file="../../chrome/browser/android/webapps/launchpad/java/src/org/chromium/chrome/browser/webapps/launchpad/AppManagementMenuPermissionsMediator.java"
             line="107"
             column="37"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 26 (current min is 23): `shouldQueryAutofillSuggestion`"
+        message="Call requires API level 26 (current min is 24): `shouldQueryAutofillSuggestion`"
         errorLine1="        if (mAutofillMenuItemTitle != 0 &amp;&amp; mAutofillProvider.shouldQueryAutofillSuggestion()) {"
         errorLine2="                                                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/android_autofill/browser/java/src/org/chromium/components/autofill/AutofillActionModeCallback.java"
-            line="39"
+            file="../../components/android_autofill/browser/java/src/org/chromium/components/autofill/AutofillActionModeCallback.java"
+            line="43"
             column="62"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 26 (current min is 23): `queryAutofillSuggestion`"
+        message="Call requires API level 26 (current min is 24): `queryAutofillSuggestion`"
         errorLine1="            mAutofillProvider.queryAutofillSuggestion();"
         errorLine2="                              ~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/android_autofill/browser/java/src/org/chromium/components/autofill/AutofillActionModeCallback.java"
-            line="51"
+            file="../../components/android_autofill/browser/java/src/org/chromium/components/autofill/AutofillActionModeCallback.java"
+            line="55"
             column="31"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `addDirectAction`"
+        message="Call requires API level 29 (current min is 24): `addDirectAction`"
         errorLine1="            reporter.addDirectAction(ONBOARDING_ACTION)"
         errorLine2="                     ~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandler.java"
-            line="78"
-            column="22"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 29 (current min is 23): `withParameter`"
-        errorLine1="                    .withParameter(ACTION_NAME, Type.STRING, /* required= */ false)"
-        errorLine2="                     ~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandler.java"
-            line="79"
-            column="22"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 29 (current min is 23): `withParameter`"
-        errorLine1="                    .withParameter(EXPERIMENT_IDS, Type.STRING, /* required= */ false)"
-        errorLine2="                     ~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandler.java"
-            line="80"
-            column="22"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 29 (current min is 23): `withResult`"
-        errorLine1="                    .withResult(AA_ACTION_RESULT, Type.BOOLEAN);"
-        errorLine2="                     ~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandler.java"
-            line="81"
-            column="22"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 29 (current min is 23): `addDirectAction`"
-        errorLine1="            reporter.addDirectAction(ONBOARDING_AND_START_ACTION)"
-        errorLine2="                     ~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandler.java"
-            line="82"
-            column="22"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 29 (current min is 23): `withParameter`"
-        errorLine1="                    .withParameter(ACTION_NAME, Type.STRING, /* required= */ true)"
-        errorLine2="                     ~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandler.java"
-            line="83"
-            column="22"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 29 (current min is 23): `withParameter`"
-        errorLine1="                    .withParameter(USER_NAME, Type.STRING, /* required= */ false)"
-        errorLine2="                     ~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandler.java"
-            line="84"
-            column="22"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 29 (current min is 23): `withParameter`"
-        errorLine1="                    .withParameter(EXPERIMENT_IDS, Type.STRING, /* required= */ false)"
-        errorLine2="                     ~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandler.java"
-            line="85"
-            column="22"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 29 (current min is 23): `withParameter`"
-        errorLine1="                    .withParameter(SHOW_ERROR_ON_FAILURE, Type.BOOLEAN, /* required= */ false)"
-        errorLine2="                     ~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandler.java"
-            line="86"
-            column="22"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 29 (current min is 23): `withResult`"
-        errorLine1="                    .withResult(AA_ACTION_RESULT, Type.BOOLEAN);"
-        errorLine2="                     ~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandler.java"
+            file="../../chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandler.java"
             line="87"
             column="22"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `addDirectAction`"
-        errorLine1="            reporter.addDirectAction(FETCH_WEBSITE_ACTIONS)"
+        message="Call requires API level 29 (current min is 24): `withParameter`"
+        errorLine1="                    .withParameter(ACTION_NAME, Type.STRING, /* required= */ false)"
+        errorLine2="                     ~~~~~~~~~~~~~">
+        <location
+            file="../../chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandler.java"
+            line="88"
+            column="22"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 24): `withParameter`"
+        errorLine1="                    .withParameter(EXPERIMENT_IDS, Type.STRING, /* required= */ false)"
+        errorLine2="                     ~~~~~~~~~~~~~">
+        <location
+            file="../../chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandler.java"
+            line="89"
+            column="22"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 24): `withResult`"
+        errorLine1="                    .withResult(AA_ACTION_RESULT, Type.BOOLEAN);"
+        errorLine2="                     ~~~~~~~~~~">
+        <location
+            file="../../chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandler.java"
+            line="90"
+            column="22"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 24): `addDirectAction`"
+        errorLine1="            reporter.addDirectAction(ONBOARDING_AND_START_ACTION)"
         errorLine2="                     ~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandler.java"
+            file="../../chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandler.java"
+            line="91"
+            column="22"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 24): `withParameter`"
+        errorLine1="                    .withParameter(ACTION_NAME, Type.STRING, /* required= */ true)"
+        errorLine2="                     ~~~~~~~~~~~~~">
+        <location
+            file="../../chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandler.java"
+            line="92"
+            column="22"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 24): `withParameter`"
+        errorLine1="                    .withParameter(USER_NAME, Type.STRING, /* required= */ false)"
+        errorLine2="                     ~~~~~~~~~~~~~">
+        <location
+            file="../../chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandler.java"
             line="93"
             column="22"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `withParameter`"
-        errorLine1="                    .withParameter(USER_NAME, Type.STRING, /* required= */ false)"
+        message="Call requires API level 29 (current min is 24): `withParameter`"
+        errorLine1="                    .withParameter(EXPERIMENT_IDS, Type.STRING, /* required= */ false)"
         errorLine2="                     ~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandler.java"
+            file="../../chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandler.java"
             line="94"
             column="22"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `withParameter`"
-        errorLine1="                    .withParameter(EXPERIMENT_IDS, Type.STRING, /* required= */ false)"
+        message="Call requires API level 29 (current min is 24): `withParameter`"
+        errorLine1="                    .withParameter(SHOW_ERROR_ON_FAILURE, Type.BOOLEAN, /* required= */ false)"
         errorLine2="                     ~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandler.java"
+            file="../../chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandler.java"
             line="95"
             column="22"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `withResult`"
-        errorLine1="                    .withResult(FETCH_WEBSITE_ACTIONS_RESULT, Type.BOOLEAN);"
+        message="Call requires API level 29 (current min is 24): `withResult`"
+        errorLine1="                    .withResult(AA_ACTION_RESULT, Type.BOOLEAN);"
         errorLine2="                     ~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandler.java"
+            file="../../chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandler.java"
             line="96"
             column="22"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `addDirectAction`"
+        message="Call requires API level 29 (current min is 24): `addDirectAction`"
+        errorLine1="            reporter.addDirectAction(FETCH_WEBSITE_ACTIONS)"
+        errorLine2="                     ~~~~~~~~~~~~~~~">
+        <location
+            file="../../chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandler.java"
+            line="101"
+            column="22"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 24): `withParameter`"
+        errorLine1="                    .withParameter(USER_NAME, Type.STRING, /* required= */ false)"
+        errorLine2="                     ~~~~~~~~~~~~~">
+        <location
+            file="../../chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandler.java"
+            line="102"
+            column="22"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 24): `withParameter`"
+        errorLine1="                    .withParameter(EXPERIMENT_IDS, Type.STRING, /* required= */ false)"
+        errorLine2="                     ~~~~~~~~~~~~~">
+        <location
+            file="../../chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandler.java"
+            line="103"
+            column="22"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 24): `withResult`"
+        errorLine1="                    .withResult(FETCH_WEBSITE_ACTIONS_RESULT, Type.BOOLEAN);"
+        errorLine2="                     ~~~~~~~~~~">
+        <location
+            file="../../chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandler.java"
+            line="104"
+            column="22"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 24): `addDirectAction`"
         errorLine1="                    Definition definition = reporter.addDirectAction(name)"
         errorLine2="                                                     ~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandler.java"
-            line="102"
+            file="../../chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandler.java"
+            line="110"
             column="54"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `withParameter`"
+        message="Call requires API level 29 (current min is 24): `withParameter`"
         errorLine1="                                                    .withParameter(EXPERIMENT_IDS, Type.STRING,"
         errorLine2="                                                     ~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandler.java"
-            line="103"
+            file="../../chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandler.java"
+            line="111"
             column="54"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `withResult`"
+        message="Call requires API level 29 (current min is 24): `withResult`"
         errorLine1="                                                    .withResult(AA_ACTION_RESULT, Type.BOOLEAN);"
         errorLine2="                                                     ~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandler.java"
-            line="105"
+            file="../../chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandler.java"
+            line="113"
             column="54"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `withParameter`"
+        message="Call requires API level 29 (current min is 24): `withParameter`"
         errorLine1="                        definition.withParameter(required, Type.STRING, /* required= */ true);"
         errorLine2="                                   ~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandler.java"
-            line="110"
+            file="../../chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandler.java"
+            line="118"
             column="36"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `withParameter`"
+        message="Call requires API level 29 (current min is 24): `withParameter`"
         errorLine1="                        definition.withParameter(optional, Type.STRING, /* required= */ false);"
         errorLine2="                                   ~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandler.java"
-            line="113"
+            file="../../chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandler.java"
+            line="121"
             column="36"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 24 (current min is 23): `hasScreenLockConfigured`"
-        errorLine1="                    if (mMode == Mode.SERVER_LINK || hasScreenLockConfigured(getContext())) {"
-        errorLine2="                                                     ~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/features/cablev2_authenticator/java/src/org/chromium/chrome/browser/webauth/authenticator/CableAuthenticatorUI.java"
-            line="267"
-            column="54"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 24 (current min is 23): `hasScreenLockConfigured`"
-        errorLine1="                    if (event == Event.RESUMED &amp;&amp; hasScreenLockConfigured(getContext())) {"
-        errorLine2="                                                  ~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/features/cablev2_authenticator/java/src/org/chromium/chrome/browser/webauth/authenticator/CableAuthenticatorUI.java"
-            line="275"
-            column="51"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 26 (current min is 23): `deleteLegacyChannels`"
+        message="Call requires API level 26 (current min is 24): `deleteLegacyChannels`"
         errorLine1="            mChannelsInitializer.deleteLegacyChannels();"
         errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/channels/ChannelsUpdater.java"
+            file="../../chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/channels/ChannelsUpdater.java"
             line="73"
             column="34"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 26 (current min is 23): `initializeStartupChannels`"
+        message="Call requires API level 26 (current min is 24): `initializeStartupChannels`"
         errorLine1="            mChannelsInitializer.initializeStartupChannels();"
         errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/channels/ChannelsUpdater.java"
+            file="../../chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/channels/ChannelsUpdater.java"
             line="74"
             column="34"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 26 (current min is 23): `updateLocale`"
+        message="Call requires API level 26 (current min is 24): `updateLocale`"
         errorLine1="            mChannelsInitializer.updateLocale(ContextUtils.getApplicationContext().getResources());"
         errorLine2="                                 ~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/channels/ChannelsUpdater.java"
+            file="../../chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/channels/ChannelsUpdater.java"
             line="83"
             column="34"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 26 (current min is 23): `onFrameworkExitedPictureInPicture`"
+        message="Call requires API level 26 (current min is 24): `onFrameworkExitedPictureInPicture`"
         errorLine1="            mFullscreenVideoPictureInPictureController.onFrameworkExitedPictureInPicture();"
-        errorLine2="                                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        errorLine2="                                                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java"
-            line="1156"
-            column="41"/>
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java"
+            line="1176"
+            column="56"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 26 (current min is 23): `FullscreenVideoPictureInPictureController`"
-        errorLine1="            mFullscreenVideoPictureInPictureController = new FullscreenVideoPictureInPictureController("
-        errorLine2="                                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        message="Call requires API level 26 (current min is 24): `FullscreenVideoPictureInPictureController`"
+        errorLine1="                    new FullscreenVideoPictureInPictureController("
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java"
-            line="1165"
-            column="43"/>
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java"
+            line="1186"
+            column="21"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 26 (current min is 23): `attemptPictureInPicture`"
+        message="Call requires API level 26 (current min is 24): `attemptPictureInPicture`"
         errorLine1="        mFullscreenVideoPictureInPictureController.attemptPictureInPicture();"
-        errorLine2="                                    ~~~~~~~~~~~~~~~~~~~~~~~">
+        errorLine2="                                                   ~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java"
-            line="1180"
-            column="37"/>
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java"
+            line="1201"
+            column="52"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 26 (current min is 23): `onFrameworkExitedPictureInPicture`"
+        message="Call requires API level 26 (current min is 24): `onFrameworkExitedPictureInPicture`"
         errorLine1="            mFullscreenVideoPictureInPictureController.onFrameworkExitedPictureInPicture();"
-        errorLine2="                                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        errorLine2="                                                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java"
-            line="1255"
-            column="41"/>
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java"
+            line="1276"
+            column="56"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 26 (current min is 23): `getInstance`"
+        message="Call requires API level 26 (current min is 24): `getInstance`"
         errorLine1="        return SiteChannelsManager.getInstance();"
         errorLine2="                                   ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeAppModule.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeAppModule.java"
             line="76"
             column="36"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 24 (current min is 23): `GCMBackgroundTask`"
-        errorLine1="                return new GCMBackgroundTask();"
-        errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/background_task_scheduler/ChromeBackgroundTaskFactory.java"
-            line="60"
-            column="24"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 26 (current min is 23): `getChannelIdForOrigin`"
+        message="Call requires API level 26 (current min is 24): `getChannelIdForOrigin`"
         errorLine1="        return SiteChannelsManager.getInstance().getChannelIdForOrigin(origin);"
         errorLine2="                                                 ~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/site_settings/ChromeSiteSettingsDelegate.java"
-            line="127"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/site_settings/ChromeSiteSettingsDelegate.java"
+            line="146"
             column="50"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 26 (current min is 23): `getInstance`"
+        message="Call requires API level 26 (current min is 24): `getInstance`"
         errorLine1="        return SiteChannelsManager.getInstance().getChannelIdForOrigin(origin);"
         errorLine2="                                   ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/site_settings/ChromeSiteSettingsDelegate.java"
-            line="127"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/site_settings/ChromeSiteSettingsDelegate.java"
+            line="146"
             column="36"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 24 (current min is 23): `create`"
-        errorLine1="        mMultiInstanceManager = MultiInstanceManager.create(this, getTabModelOrchestratorSupplier(),"
-        errorLine2="                                                     ~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java"
-            line="458"
-            column="54"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 25 (current min is 23): `reportNewTabShortcutUsed`"
+        message="Call requires API level 25 (current min is 24): `reportNewTabShortcutUsed`"
         errorLine1="                        reportNewTabShortcutUsed(false);"
         errorLine2="                        ~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java"
-            line="1511"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java"
+            line="1594"
             column="25"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 25 (current min is 23): `reportNewTabShortcutUsed`"
+        message="Call requires API level 25 (current min is 24): `reportNewTabShortcutUsed`"
         errorLine1="                            reportNewTabShortcutUsed(true);"
         errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java"
-            line="1551"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java"
+            line="1634"
             column="29"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 24 (current min is 23): `isTabModelMergingEnabled`"
-        errorLine1="                mMultiInstanceManager != null &amp;&amp; mMultiInstanceManager.isTabModelMergingEnabled();"
-        errorLine2="                                                                       ~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java"
-            line="1813"
-            column="72"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 24 (current min is 23): `initialize`"
-        errorLine1="            mMultiInstanceManager.initialize(assignedIndex, getTaskId());"
-        errorLine2="                                  ~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java"
-            line="1842"
-            column="35"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 24 (current min is 23): `allocInstanceId`"
-        errorLine1="            mWindowId = mMultiInstanceManager.allocInstanceId(windowId, getTaskId(), preferNew);"
-        errorLine2="                                              ~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java"
-            line="2006"
-            column="47"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 24 (current min is 23): `isStartedUpCorrectly`"
-        errorLine1="                &amp;&amp; !mMultiInstanceManager.isStartedUpCorrectly(getTaskId())) {"
-        errorLine2="                                          ~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java"
-            line="2015"
-            column="43"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 25 (current min is 23): `reportNewTabShortcutUsed`"
+        message="Call requires API level 25 (current min is 24): `reportNewTabShortcutUsed`"
         errorLine1="            reportNewTabShortcutUsed(false);"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java"
-            line="2046"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java"
+            line="2131"
             column="13"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 25 (current min is 23): `reportNewTabShortcutUsed`"
+        message="Call requires API level 25 (current min is 24): `reportNewTabShortcutUsed`"
         errorLine1="                reportNewTabShortcutUsed(true);"
         errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java"
-            line="2060"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java"
+            line="2145"
             column="17"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 24 (current min is 23): `createShortcutGroup`"
-        errorLine1="        data.addAll(KeyboardShortcuts.createShortcutGroup(this));"
-        errorLine2="                                      ~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java"
-            line="2692"
-            column="39"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 29 (current min is 23): `clearAllContentCaptureData`"
+        message="Call requires API level 29 (current min is 24): `clearAllContentCaptureData`"
         errorLine1="            contentCaptureController.clearAllContentCaptureData();"
         errorLine2="                                     ~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/content_capture/ContentCaptureHistoryDeletionObserver.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/content_capture/ContentCaptureHistoryDeletionObserver.java"
             line="30"
             column="38"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `clearContentCaptureDataForURLs`"
+        message="Call requires API level 29 (current min is 24): `clearContentCaptureDataForURLs`"
         errorLine1="                    contentCaptureController.clearContentCaptureDataForURLs(deletedURLs);"
         errorLine2="                                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/content_capture/ContentCaptureHistoryDeletionObserver.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/content_capture/ContentCaptureHistoryDeletionObserver.java"
             line="35"
             column="46"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `notifyViewAppeared`"
+        message="Call requires API level 29 (current min is 24): `notifyViewAppeared`"
         errorLine1="        return notifyViewAppeared(parentPlatformSessionData, data);"
         errorLine2="               ~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCapturedTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCapturedTask.java"
             line="23"
             column="16"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Extending NotificationTask requires API level 29 (current min is 23): `NotificationTask`"
+        message="Extending NotificationTask requires API level 29 (current min is 24): `NotificationTask`"
         errorLine1="class ContentRemovedTask extends NotificationTask {"
         errorLine2="                                 ~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentRemovedTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/ContentRemovedTask.java"
             line="12"
             column="34"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `NotificationTask`"
+        message="Call requires API level 29 (current min is 24): `NotificationTask`"
         errorLine1="        super(session, platformSession);"
         errorLine2="        ~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentRemovedTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/ContentRemovedTask.java"
             line="17"
             column="9"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `log`"
+        message="Call requires API level 29 (current min is 24): `log`"
         errorLine1="        log(&quot;ContentRemovedTask.removeContent&quot;);"
         errorLine2="        ~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentRemovedTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/ContentRemovedTask.java"
             line="27"
             column="9"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `buildCurrentSession`"
+        message="Call requires API level 29 (current min is 24): `buildCurrentSession`"
         errorLine1="        PlatformSessionData platformSessionData = buildCurrentSession();"
         errorLine2="                                                  ~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentRemovedTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/ContentRemovedTask.java"
             line="28"
             column="51"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `getInstance`"
+        message="Call requires API level 29 (current min is 24): `getInstance`"
         errorLine1="        PlatformAPIWrapper.getInstance().notifyViewsDisappeared("
         errorLine2="                           ~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentRemovedTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/ContentRemovedTask.java"
             line="30"
             column="28"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `notifyViewsDisappeared`"
+        message="Call requires API level 29 (current min is 24): `notifyViewsDisappeared`"
         errorLine1="        PlatformAPIWrapper.getInstance().notifyViewsDisappeared("
         errorLine2="                                         ~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentRemovedTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/ContentRemovedTask.java"
             line="30"
             column="42"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Field requires API level 29 (current min is 23): `contentCaptureSession`"
+        message="Field requires API level 29 (current min is 24): `contentCaptureSession`"
         errorLine1="                platformSessionData.contentCaptureSession,"
         errorLine2="                                    ~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentRemovedTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/ContentRemovedTask.java"
             line="31"
             column="37"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `getRootPlatformSessionData`"
+        message="Call requires API level 29 (current min is 24): `getRootPlatformSessionData`"
         errorLine1="                mPlatformSession.getRootPlatformSessionData().autofillId, mRemovedIds);"
         errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentRemovedTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/ContentRemovedTask.java"
             line="32"
             column="34"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Field requires API level 29 (current min is 23): `autofillId`"
+        message="Field requires API level 29 (current min is 24): `autofillId`"
         errorLine1="                mPlatformSession.getRootPlatformSessionData().autofillId, mRemovedIds);"
         errorLine2="                                                              ~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentRemovedTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/ContentRemovedTask.java"
             line="32"
             column="63"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Field requires API level 29 (current min is 23): `mPlatformSession`"
+        message="Field requires API level 29 (current min is 24): `mPlatformSession`"
         errorLine1="                mPlatformSession.getRootPlatformSessionData().autofillId, mRemovedIds);"
         errorLine2="                ~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentRemovedTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/ContentRemovedTask.java"
             line="32"
             column="17"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `getInstance`"
+        message="Call requires API level 29 (current min is 24): `getInstance`"
         errorLine1="        AutofillId autofillId = PlatformAPIWrapper.getInstance().newAutofillId("
         errorLine2="                                                   ~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentUpdateTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/ContentUpdateTask.java"
             line="28"
             column="52"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `newAutofillId`"
+        message="Call requires API level 29 (current min is 24): `newAutofillId`"
         errorLine1="        AutofillId autofillId = PlatformAPIWrapper.getInstance().newAutofillId("
         errorLine2="                                                                 ~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentUpdateTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/ContentUpdateTask.java"
             line="28"
             column="66"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Field requires API level 29 (current min is 23): `contentCaptureSession`"
+        message="Field requires API level 29 (current min is 24): `contentCaptureSession`"
         errorLine1="                parentPlatformSessionData.contentCaptureSession,"
         errorLine2="                                          ~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentUpdateTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/ContentUpdateTask.java"
             line="29"
             column="43"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `getRootPlatformSessionData`"
+        message="Call requires API level 29 (current min is 24): `getRootPlatformSessionData`"
         errorLine1="                mPlatformSession.getRootPlatformSessionData().autofillId, data.getId());"
         errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentUpdateTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/ContentUpdateTask.java"
             line="30"
             column="34"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Field requires API level 29 (current min is 23): `autofillId`"
+        message="Field requires API level 29 (current min is 24): `autofillId`"
         errorLine1="                mPlatformSession.getRootPlatformSessionData().autofillId, data.getId());"
         errorLine2="                                                              ~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentUpdateTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/ContentUpdateTask.java"
             line="30"
             column="63"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Field requires API level 29 (current min is 23): `mPlatformSession`"
+        message="Field requires API level 29 (current min is 24): `mPlatformSession`"
         errorLine1="                mPlatformSession.getRootPlatformSessionData().autofillId, data.getId());"
         errorLine2="                ~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentUpdateTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/ContentUpdateTask.java"
             line="30"
             column="17"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `getInstance`"
+        message="Call requires API level 29 (current min is 24): `getInstance`"
         errorLine1="        PlatformAPIWrapper.getInstance().notifyViewTextChanged("
         errorLine2="                           ~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentUpdateTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/ContentUpdateTask.java"
             line="31"
             column="28"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `notifyViewTextChanged`"
+        message="Call requires API level 29 (current min is 24): `notifyViewTextChanged`"
         errorLine1="        PlatformAPIWrapper.getInstance().notifyViewTextChanged("
         errorLine2="                                         ~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentUpdateTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/ContentUpdateTask.java"
             line="31"
             column="42"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Field requires API level 29 (current min is 23): `contentCaptureSession`"
+        message="Field requires API level 29 (current min is 24): `contentCaptureSession`"
         errorLine1="                parentPlatformSessionData.contentCaptureSession, autofillId, data.getValue());"
         errorLine2="                                          ~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentUpdateTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/ContentUpdateTask.java"
             line="32"
             column="43"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 30 (current min is 23): `collectAndWriteAnrs`"
+        message="Call requires API level 30 (current min is 24): `collectAndWriteAnrs`"
         errorLine1="            List&lt;Pair&lt;File, String>> anrFiles = AnrCollector.collectAndWriteAnrs(anrDir);"
         errorLine2="                                                             ~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/minidump_uploader/android/java/src/org/chromium/components/minidump_uploader/CrashFileManager.java"
-            line="366"
+            file="../../components/minidump_uploader/android/java/src/org/chromium/components/minidump_uploader/CrashFileManager.java"
+            line="373"
             column="62"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `getDownloadUriForFileName`"
+        message="Call requires API level 29 (current min is 24): `getDownloadUriForFileName`"
         errorLine1="        return getDownloadUriForFileName(fileName) != null;"
         errorLine2="               ~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/download/internal/common/android/java/src/org/chromium/components/download/DownloadCollectionBridge.java"
+            file="../../components/download/internal/common/android/java/src/org/chromium/components/download/DownloadCollectionBridge.java"
             line="244"
             column="16"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `createPendingParams`"
+        message="Call requires API level 29 (current min is 24): `createPendingParams`"
         errorLine1="                createPendingParams(fileName, mimeType, originalUrl, referrer);"
         errorLine2="                ~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/download/internal/common/android/java/src/org/chromium/components/download/DownloadCollectionBridge.java"
+            file="../../components/download/internal/common/android/java/src/org/chromium/components/download/DownloadCollectionBridge.java"
             line="345"
             column="17"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `getDownloadUriForFileName`"
+        message="Call requires API level 29 (current min is 24): `getDownloadUriForFileName`"
         errorLine1="                Uri uri = DownloadCollectionBridge.getDownloadUriForFileName(file.getName());"
         errorLine2="                                                   ~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/download/DuplicateDownloadClickableSpan.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/download/DuplicateDownloadClickableSpan.java"
             line="56"
             column="52"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Extending NotificationTask requires API level 29 (current min is 23): `NotificationTask`"
+        message="Extending NotificationTask requires API level 29 (current min is 24): `NotificationTask`"
         errorLine1="public class FaviconUpdateTask extends NotificationTask {"
         errorLine2="                                       ~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/FaviconUpdateTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/FaviconUpdateTask.java"
             line="12"
             column="40"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `NotificationTask`"
+        message="Call requires API level 29 (current min is 24): `NotificationTask`"
         errorLine1="        super(session, platformSession);"
         errorLine2="        ~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/FaviconUpdateTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/FaviconUpdateTask.java"
             line="14"
             column="9"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `log`"
+        message="Call requires API level 29 (current min is 24): `log`"
         errorLine1="        log(&quot;FaviconUpdateTask.updateFavicon&quot;);"
         errorLine2="        ~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/FaviconUpdateTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/FaviconUpdateTask.java"
             line="23"
             column="9"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `buildCurrentSession`"
+        message="Call requires API level 29 (current min is 24): `buildCurrentSession`"
         errorLine1="        PlatformSessionData parentPlatformSessionData = buildCurrentSession();"
         errorLine2="                                                        ~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/FaviconUpdateTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/FaviconUpdateTask.java"
             line="24"
             column="57"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `getInstance`"
+        message="Call requires API level 29 (current min is 24): `getInstance`"
         errorLine1="        PlatformAPIWrapper.getInstance().notifyFaviconUpdated("
         errorLine2="                           ~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/FaviconUpdateTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/FaviconUpdateTask.java"
             line="26"
             column="28"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `notifyFaviconUpdated`"
+        message="Call requires API level 29 (current min is 24): `notifyFaviconUpdated`"
         errorLine1="        PlatformAPIWrapper.getInstance().notifyFaviconUpdated("
         errorLine2="                                         ~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/FaviconUpdateTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/FaviconUpdateTask.java"
             line="26"
             column="42"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Field requires API level 29 (current min is 23): `contentCaptureSession`"
+        message="Field requires API level 29 (current min is 24): `contentCaptureSession`"
         errorLine1="                parentPlatformSessionData.contentCaptureSession, mSession.get(0).getFavicon());"
         errorLine2="                                          ~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/FaviconUpdateTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/FaviconUpdateTask.java"
             line="27"
             column="43"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Field requires API level 29 (current min is 23): `mSession`"
+        message="Field requires API level 29 (current min is 24): `mSession`"
         errorLine1="                parentPlatformSessionData.contentCaptureSession, mSession.get(0).getFavicon());"
         errorLine2="                                                                 ~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/FaviconUpdateTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/FaviconUpdateTask.java"
             line="27"
             column="66"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 24 (current min is 23): `getLocale`"
-        errorLine1="        return getLocale(ContextUtils.getApplicationContext()).toLanguageTag();"
-        errorLine2="               ~~~~~~~~~">
-        <location
-            file="$SRC/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedServiceBridge.java"
-            line="95"
-            column="16"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 29 (current min is 23): `addDirectAction`"
+        message="Call requires API level 29 (current min is 24): `addDirectAction`"
         errorLine1="            reporter.addDirectAction(ACTION_ID).withParameter("
         errorLine2="                     ~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/directactions/FindInPageDirectActionHandler.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/directactions/FindInPageDirectActionHandler.java"
             line="35"
             column="22"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `withParameter`"
+        message="Call requires API level 29 (current min is 24): `withParameter`"
         errorLine1="            reporter.addDirectAction(ACTION_ID).withParameter("
         errorLine2="                                                ~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/directactions/FindInPageDirectActionHandler.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/directactions/FindInPageDirectActionHandler.java"
             line="35"
             column="49"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 26 (current min is 23): `setPasteAsPlainTextMenuItemTitle`"
+        message="Call requires API level 26 (current min is 24): `setPasteAsPlainTextMenuItemTitle`"
         errorLine1="            SelectionPopupControllerImpl.setPasteAsPlainTextMenuItemTitle(menu);"
         errorLine2="                                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/content/public/android/java/src/org/chromium/content/browser/selection/FloatingPastePopupMenu.java"
+            file="../../content/public/android/java/src/org/chromium/content/browser/selection/FloatingPastePopupMenu.java"
             line="96"
             column="42"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Field requires API level 26 (current min is 23): `CREATOR`"
+        message="Call requires API level 31 (current min is 26): `setAutoEnterEnabled`"
+        errorLine1="            ApiHelperForS.setAutoEnterEnabled(builder, true);"
+        errorLine2="                          ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/media/FullscreenVideoPictureInPictureController.java"
+            line="430"
+            column="27"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 26): `setAutoEnterEnabled`"
+        errorLine1="            ApiHelperForS.setAutoEnterEnabled(builder, false);"
+        errorLine2="                          ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/media/FullscreenVideoPictureInPictureController.java"
+            line="432"
+            column="27"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 26 (current min is 24): `CREATOR`"
         errorLine1="          _arg0 = data.createTypedArrayList(org.chromium.components.autofill_public.ViewType.CREATOR);"
         errorLine2="                                                                                             ~~~~~~~">
         <location
@@ -1092,1507 +971,902 @@
 
     <issue
         id="NewApi"
-        message="Call requires API level 24 (current min is 23): `isUserVerifyingPlatformAuthenticatorAvailable`"
-        errorLine1="        mAuthenticator.isUserVerifyingPlatformAuthenticatorAvailable((isUVPAA) -> {"
-        errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/components/webauthn/android/java/src/org/chromium/components/webauthn/InternalAuthenticator.java"
-            line="116"
-            column="24"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 26 (current min is 23): `onLocaleChanged`"
+        message="Call requires API level 26 (current min is 24): `onLocaleChanged`"
         errorLine1="        WebLayerNotificationChannels.onLocaleChanged();"
         errorLine2="                                     ~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/weblayer/browser/java/org/chromium/weblayer_private/LocaleChangedBroadcastReceiver.java"
+            file="../../weblayer/browser/java/org/chromium/weblayer_private/LocaleChangedBroadcastReceiver.java"
             line="35"
             column="38"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 24 (current min is 23): `addMetadataToFormat`"
-        errorLine1="            hdrMetadata.addMetadataToFormat(format);"
-        errorLine2="                        ~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/media/base/android/java/src/org/chromium/media/MediaFormatBuilder.java"
-            line="22"
-            column="25"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 29 (current min is 23): `addDirectAction`"
+        message="Call requires API level 29 (current min is 24): `addDirectAction`"
         errorLine1="                reporter.addDirectAction(entry.getKey());"
         errorLine2="                         ~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/directactions/MenuDirectActionHandler.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/directactions/MenuDirectActionHandler.java"
             line="103"
             column="26"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 30 (current min is 23): `getExitReason`"
+        message="Call requires API level 30 (current min is 24): `getExitReason`"
         errorLine1="            int reason = ProcessExitReasonFromSystem.getExitReason(previousPid);"
         errorLine2="                                                     ~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/crash/MinidumpUploadServiceImpl.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/crash/MinidumpUploadServiceImpl.java"
             line="166"
             column="54"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Extending MultiInstanceManager requires API level 24 (current min is 23): `MultiInstanceManager`"
-        errorLine1="class MultiInstanceManagerApi31 extends MultiInstanceManager implements ActivityStateListener {"
-        errorLine2="                                        ~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="57"
-            column="41"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 24 (current min is 23): `MultiInstanceManager`"
-        errorLine1="        super(activity, tabModelOrchestratorSupplier, multiWindowModeStateDispatcher,"
-        errorLine2="        ~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="90"
-            column="9"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Field requires API level 24 (current min is 23): `mActivity`"
-        errorLine1="            InstanceSwitcherCoordinator.showDialog(mActivity, mModalDialogManagerSupplier.get(),"
-        errorLine2="                                                   ~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="101"
-            column="52"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 24 (current min is 23): `handleMenuOrKeyboardAction`"
-        errorLine1="        return super.handleMenuOrKeyboardAction(id, fromMenu);"
-        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="114"
-            column="22"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Field requires API level 24 (current min is 23): `mActivity`"
-        errorLine1="        TargetSelectorCoordinator.showDialog(mActivity, mModalDialogManagerSupplier.get(),"
-        errorLine2="                                             ~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="119"
-            column="46"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 24 (current min is 23): `onMultiInstanceModeStarted`"
-        errorLine1="            onMultiInstanceModeStarted();"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="129"
-            column="13"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Field requires API level 24 (current min is 23): `mActivity`"
-        errorLine1="                    mActivity, info.instanceId, /*preferNew=*/false, /*openAdjacently=*/true);"
-        errorLine2="                    ~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="131"
-            column="21"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Field requires API level 24 (current min is 23): `mActivity`"
-        errorLine1="            ReparentingTask.from(tab).begin(mActivity, intent,"
-        errorLine2="                                            ~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="132"
-            column="45"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Field requires API level 24 (current min is 23): `mMultiWindowModeStateDispatcher`"
-        errorLine1="                    mMultiWindowModeStateDispatcher.getOpenInOtherWindowActivityOptions(), null);"
-        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="133"
-            column="21"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 24 (current min is 23): `setOpenInOtherWindowIntentExtras`"
-        errorLine1="        MultiWindowUtils.setOpenInOtherWindowIntentExtras("
-        errorLine2="                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="142"
-            column="26"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Field requires API level 24 (current min is 23): `mActivity`"
-        errorLine1="                intent, mActivity, targetActivity.getClass());"
-        errorLine2="                        ~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="143"
-            column="25"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 24 (current min is 23): `onMultiInstanceModeStarted`"
-        errorLine1="        onMultiInstanceModeStarted();"
-        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="144"
-            column="9"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Field requires API level 24 (current min is 23): `mActivity`"
-        errorLine1="        ReparentingTask.from(tab).setupIntent(mActivity, intent, null);"
-        errorLine2="                                              ~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="147"
-            column="47"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Field requires API level 24 (current min is 23): `mActivity`"
-        errorLine1="        Intent intent = new Intent(mActivity, ChromeTabbedActivity.class);"
-        errorLine2="                                   ~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="155"
-            column="36"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 24 (current min is 23): `onMultiInstanceModeStarted`"
-        errorLine1="        onMultiInstanceModeStarted();"
-        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="156"
-            column="9"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 24 (current min is 23): `setOpenInOtherWindowIntentExtras`"
-        errorLine1="        MultiWindowUtils.setOpenInOtherWindowIntentExtras("
-        errorLine2="                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="157"
-            column="26"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Field requires API level 24 (current min is 23): `mActivity`"
-        errorLine1="                intent, mActivity, ChromeTabbedActivity.class);"
-        errorLine2="                        ~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="158"
-            column="25"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Field requires API level 24 (current min is 23): `mMultiWindowModeStateDispatcher`"
-        errorLine1="        if (mMultiWindowModeStateDispatcher.canEnterMultiWindowMode()"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="163"
-            column="13"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Field requires API level 24 (current min is 23): `mMultiWindowModeStateDispatcher`"
-        errorLine1="                || mMultiWindowModeStateDispatcher.isInMultiWindowMode()"
-        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="164"
-            column="20"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Field requires API level 24 (current min is 23): `mMultiWindowModeStateDispatcher`"
-        errorLine1="                || mMultiWindowModeStateDispatcher.isInMultiDisplayMode()) {"
-        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="165"
-            column="20"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Field requires API level 24 (current min is 23): `mMultiWindowModeStateDispatcher`"
-        errorLine1="            Bundle bundle = mMultiWindowModeStateDispatcher.getOpenInOtherWindowActivityOptions();"
-        errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="167"
-            column="29"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Field requires API level 24 (current min is 23): `mActivity`"
-        errorLine1="            mActivity.startActivity(intent, bundle);"
-        errorLine2="            ~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="168"
-            column="13"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Field requires API level 24 (current min is 23): `mActivity`"
-        errorLine1="            mActivity.startActivity(intent);"
-        errorLine2="            ~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="170"
-            column="13"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Field requires API level 24 (current min is 23): `mActivity`"
-        errorLine1="                if (a == mActivity) {"
-        errorLine2="                         ~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="189"
-            column="26"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Field requires API level 24 (current min is 23): `mActivity`"
-        errorLine1="        assert activity != mActivity;"
-        errorLine2="                           ~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="211"
-            column="28"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Field requires API level 24 (current min is 23): `mActivity`"
-        errorLine1="                (ActivityManager) mActivity.getSystemService(Context.ACTIVITY_SERVICE);"
-        errorLine2="                                  ~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="265"
-            column="35"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Field requires API level 24 (current min is 23): `mActivity`"
-        errorLine1="        ApplicationStatus.registerStateListenerForActivity(this, mActivity);"
-        errorLine2="                                                                 ~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="274"
-            column="66"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Field requires API level 24 (current min is 23): `mTabModelOrchestratorSupplier`"
-        errorLine1="        TabModelSelector selector = mTabModelOrchestratorSupplier.get().getTabModelSelector();"
-        errorLine2="                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="279"
-            column="37"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Field requires API level 24 (current min is 23): `mActivity`"
-        errorLine1="                (ActivityManager) mActivity.getSystemService(Context.ACTIVITY_SERVICE);"
-        errorLine2="                                  ~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="364"
-            column="35"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 24 (current min is 23): `onMultiInstanceModeStarted`"
-        errorLine1="        onMultiInstanceModeStarted();"
-        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="528"
-            column="9"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Field requires API level 24 (current min is 23): `mActivity`"
-        errorLine1="                mActivity, instanceId, /*preferNew=*/false, openAdjacently);"
-        errorLine2="                ~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="532"
-            column="17"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Field requires API level 24 (current min is 23): `mActivity`"
-        errorLine1="            mActivity.startActivity("
-        errorLine2="            ~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="534"
-            column="13"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Field requires API level 24 (current min is 23): `mMultiWindowModeStateDispatcher`"
-        errorLine1="                    intent, mMultiWindowModeStateDispatcher.getOpenInOtherWindowActivityOptions());"
-        errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="535"
-            column="29"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Field requires API level 24 (current min is 23): `mActivity`"
-        errorLine1="            mActivity.startActivity(intent);"
-        errorLine2="            ~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="537"
-            column="13"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Field requires API level 24 (current min is 23): `mTabModelOrchestratorSupplier`"
-        errorLine1="        mTabModelOrchestratorSupplier.get().cleanupInstance(instanceId);"
-        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="559"
-            column="9"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Field requires API level 24 (current min is 23): `mActivity`"
-        errorLine1="        ActivityManager am = (ActivityManager) mActivity.getSystemService(Context.ACTIVITY_SERVICE);"
-        errorLine2="                                               ~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="565"
-            column="48"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Field requires API level 24 (current min is 23): `mTabModelOrchestratorSupplier`"
-        errorLine1="        return mTabModelOrchestratorSupplier.get()"
-        errorLine2="               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="570"
-            column="16"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 24 (current min is 23): `onDestroy`"
-        errorLine1="        super.onDestroy();"
-        errorLine2="              ~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="585"
-            column="15"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 24 (current min is 23): `onResumeWithNative`"
-        errorLine1="        super.onResumeWithNative();"
-        errorLine2="              ~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java"
-            line="600"
-            column="15"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 24 (current min is 23): `setOpenInOtherWindowIntentExtras`"
-        errorLine1="        MultiWindowUtils.setOpenInOtherWindowIntentExtras(intent, mActivity, targetActivity);"
-        errorLine2="                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiWindowModeStateDispatcherImpl.java"
-            line="90"
-            column="26"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 26 (current min is 23): `isValidSiteChannelId`"
+        message="Call requires API level 26 (current min is 24): `isValidSiteChannelId`"
         errorLine1="        if (channelId == null || !SiteChannelsManager.isValidSiteChannelId(channelId)) {"
         errorLine2="                                                      ~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridge.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridge.java"
             line="417"
             column="55"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 26 (current min is 23): `toSiteOrigin`"
+        message="Call requires API level 26 (current min is 24): `toSiteOrigin`"
         errorLine1="        return SiteChannelsManager.toSiteOrigin(channelId);"
         errorLine2="                                   ~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridge.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridge.java"
             line="420"
             column="36"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 28 (current min is 23): `getBitmapFromIcon`"
+        message="Call requires API level 28 (current min is 24): `getBitmapFromIcon`"
         errorLine1="        return getBitmapFromIcon(notification.getLargeIcon());"
         errorLine2="               ~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/usage_stats/NotificationSuspender.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/usage_stats/NotificationSuspender.java"
             line="146"
             column="16"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 28 (current min is 23): `getBitmapFromIcon`"
+        message="Call requires API level 28 (current min is 24): `getBitmapFromIcon`"
         errorLine1="        return getBitmapFromIcon(notification.getSmallIcon());"
         errorLine2="               ~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/usage_stats/NotificationSuspender.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/usage_stats/NotificationSuspender.java"
             line="151"
             column="16"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 26 (current min is 23): `ChannelsInitializer`"
+        message="Call requires API level 26 (current min is 24): `ChannelsInitializer`"
         errorLine1="        ChannelsInitializer channelsInitializer = new ChannelsInitializer(notificationManagerProxy,"
         errorLine2="                                                  ~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/NotificationWrapperBuilderFactory.java"
+            file="../../chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/NotificationWrapperBuilderFactory.java"
             line="46"
             column="51"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 26 (current min is 23): `getInstance`"
+        message="Call requires API level 26 (current min is 24): `getInstance`"
         errorLine1="                ChromeChannelDefinitions.getInstance(), context.getResources());"
         errorLine2="                                         ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/NotificationWrapperBuilderFactory.java"
+            file="../../chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/NotificationWrapperBuilderFactory.java"
             line="47"
             column="42"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 30 (current min is 23): `getMaximumWindowMetricsBounds`"
+        message="Call requires API level 30 (current min is 24): `getMaximumWindowMetricsBounds`"
         errorLine1="        Rect rect = ApiHelperForR.getMaximumWindowMetricsBounds(windowManager);"
         errorLine2="                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/ui/android/java/src/org/chromium/ui/display/PhysicalDisplayAndroid.java"
+            file="../../ui/android/java/src/org/chromium/ui/display/PhysicalDisplayAndroid.java"
             line="166"
             column="35"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 30 (current min is 23): `getDisplay`"
-        errorLine1="        updateCommon(size, displayMetrics.density, ApiHelperForR.getDisplay(mWindowContext));"
-        errorLine2="                                                                 ~~~~~~~~~~">
+        message="Call requires API level 30 (current min is 24): `getDisplay`"
+        errorLine1="                ApiHelperForR.getDisplay(mWindowContext));"
+        errorLine2="                              ~~~~~~~~~~">
         <location
-            file="$SRC/ui/android/java/src/org/chromium/ui/display/PhysicalDisplayAndroid.java"
-            line="169"
-            column="66"/>
+            file="../../ui/android/java/src/org/chromium/ui/display/PhysicalDisplayAndroid.java"
+            line="170"
+            column="31"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 31 (current min is 26): `setAutoEnterEnabled`"
-        errorLine1="            ApiHelperForS.setAutoEnterEnabled(builder, true);"
-        errorLine2="                          ~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/media/FullscreenVideoPictureInPictureController.java"
-            line="426"
-            column="27"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 31 (current min is 26): `setAutoEnterEnabled`"
-        errorLine1="            ApiHelperForS.setAutoEnterEnabled(builder, false);"
-        errorLine2="                          ~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/media/FullscreenVideoPictureInPictureController.java"
-            line="428"
-            column="27"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 26 (current min is 23): `createNotificationChannel`"
+        message="Call requires API level 26 (current min is 24): `createNotificationChannel`"
         errorLine1="                mNotificationManager.createNotificationChannel();"
         errorLine2="                                     ~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/PriceMessageService.java"
+            file="../../chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/PriceMessageService.java"
             line="242"
             column="38"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Extending NotificationTask requires API level 29 (current min is 23): `NotificationTask`"
+        message="Extending NotificationTask requires API level 29 (current min is 24): `NotificationTask`"
         errorLine1="abstract class ProcessContentCaptureDataTask extends NotificationTask {"
         errorLine2="                                                     ~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/ProcessContentCaptureDataTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/ProcessContentCaptureDataTask.java"
             line="16"
             column="54"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `NotificationTask`"
+        message="Call requires API level 29 (current min is 24): `NotificationTask`"
         errorLine1="        super(session, platformSession);"
         errorLine2="        ~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/ProcessContentCaptureDataTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/ProcessContentCaptureDataTask.java"
             line="25"
             column="9"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `log`"
+        message="Call requires API level 29 (current min is 24): `log`"
         errorLine1="        log(&quot;ProcessContentTaskBase.processContent&quot;);"
         errorLine2="        ~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/ProcessContentCaptureDataTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/ProcessContentCaptureDataTask.java"
             line="35"
             column="9"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `buildCurrentSession`"
+        message="Call requires API level 29 (current min is 24): `buildCurrentSession`"
         errorLine1="        PlatformSessionData platformSessionData = buildCurrentSession();"
         errorLine2="                                                  ~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/ProcessContentCaptureDataTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/ProcessContentCaptureDataTask.java"
             line="36"
             column="51"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `createOrGetSession`"
+        message="Call requires API level 29 (current min is 24): `createOrGetSession`"
         errorLine1="                createOrGetSession(parentPlatformSessionData, data);"
         errorLine2="                ~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/ProcessContentCaptureDataTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/ProcessContentCaptureDataTask.java"
             line="45"
             column="17"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `PlatformSessionData`"
+        message="Call requires API level 29 (current min is 24): `PlatformSessionData`"
         errorLine1="            PlatformSessionData platformSessionData = new PlatformSessionData("
         errorLine2="                                                      ~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/ProcessContentCaptureDataTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/ProcessContentCaptureDataTask.java"
             line="64"
             column="55"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Field requires API level 29 (current min is 23): `contentCaptureSession`"
+        message="Field requires API level 29 (current min is 24): `contentCaptureSession`"
         errorLine1="                    parentPlatformSessionData.contentCaptureSession, autofillId);"
         errorLine2="                                              ~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/ProcessContentCaptureDataTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/ProcessContentCaptureDataTask.java"
             line="65"
             column="47"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 30 (current min is 23): `getExitReason`"
+        message="Call requires API level 30 (current min is 24): `getExitReason`"
         errorLine1="        recordAsEnumHistogram(umaName, getExitReason(pid));"
         errorLine2="                                       ~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/crash/android/java/src/org/chromium/components/crash/browser/ProcessExitReasonFromSystem.java"
+            file="../../components/crash/android/java/src/org/chromium/components/crash/browser/ProcessExitReasonFromSystem.java"
             line="80"
             column="40"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `getInstance`"
+        message="Call requires API level 29 (current min is 24): `getInstance`"
         errorLine1="                () -> PlatformContentCaptureController.getInstance()));"
         errorLine2="                                                       ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java"
-            line="285"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java"
+            line="277"
             column="56"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 24 (current min is 23): `logEGLShaderCacheSizeHistogram`"
-        errorLine1="                ProcessInitializationHandler::logEGLShaderCacheSizeHistogram);"
-        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java"
-            line="428"
-            column="17"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 29 (current min is 23): `getInstance`"
+        message="Call requires API level 29 (current min is 24): `getInstance`"
         errorLine1="                PlatformContentCaptureController.getInstance();"
         errorLine2="                                                 ~~~~~~~~~~~">
         <location
-            file="$SRC/weblayer/browser/java/org/chromium/weblayer_private/ProfileImpl.java"
-            line="279"
+            file="../../weblayer/browser/java/org/chromium/weblayer_private/ProfileImpl.java"
+            line="281"
             column="50"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `clearAllContentCaptureData`"
+        message="Call requires API level 29 (current min is 24): `clearAllContentCaptureData`"
         errorLine1="                    controller.clearAllContentCaptureData();"
         errorLine2="                               ~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/weblayer/browser/java/org/chromium/weblayer_private/ProfileImpl.java"
-            line="283"
+            file="../../weblayer/browser/java/org/chromium/weblayer_private/ProfileImpl.java"
+            line="285"
             column="32"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `onPerformDirectAction`"
+        message="Call requires API level 29 (current min is 24): `onPerformDirectAction`"
         errorLine1="        mDirectActionInitializer.onPerformDirectAction("
         errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java"
-            line="999"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java"
+            line="1037"
             column="34"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `onGetDirectActions`"
+        message="Call requires API level 29 (current min is 24): `onGetDirectActions`"
         errorLine1="        mDirectActionInitializer.onGetDirectActions(cancellationSignal, callback);"
         errorLine2="                                 ~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java"
-            line="1014"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java"
+            line="1052"
             column="34"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `DirectActionInitializer`"
+        message="Call requires API level 29 (current min is 24): `DirectActionInitializer`"
         errorLine1="        mDirectActionInitializer = new DirectActionInitializer(mActivity, mActivityType,"
         errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java"
-            line="1396"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java"
+            line="1496"
             column="36"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 28 (current min is 23): `onSelectionModified`"
+        message="Call requires API level 28 (current min is 24): `onSelectionModified`"
         errorLine1="                        mSmartSelectionEventProcessor.onSelectionModified("
         errorLine2="                                                      ~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java"
-            line="432"
+            file="../../content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java"
+            line="434"
             column="55"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 28 (current min is 23): `onSelectionAction`"
+        message="Call requires API level 28 (current min is 24): `onSelectionAction`"
         errorLine1="                        mSmartSelectionEventProcessor.onSelectionAction(mLastSelectedText,"
         errorLine2="                                                      ~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java"
-            line="436"
+            file="../../content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java"
+            line="438"
             column="55"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 28 (current min is 23): `onSelectionStarted`"
+        message="Call requires API level 28 (current min is 24): `onSelectionStarted`"
         errorLine1="                        mSmartSelectionEventProcessor.onSelectionStarted("
         errorLine2="                                                      ~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java"
-            line="443"
+            file="../../content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java"
+            line="445"
             column="55"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 26 (current min is 23): `setPasteAsPlainTextMenuItemTitle`"
+        message="Call requires API level 26 (current min is 24): `setPasteAsPlainTextMenuItemTitle`"
         errorLine1="        setPasteAsPlainTextMenuItemTitle(menu);"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java"
-            line="807"
+            file="../../content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java"
+            line="783"
             column="9"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 28 (current min is 23): `onSelectionAction`"
+        message="Call requires API level 28 (current min is 24): `onSelectionAction`"
         errorLine1="            mSmartSelectionEventProcessor.onSelectionAction(mLastSelectedText, mLastSelectionOffset,"
         errorLine2="                                          ~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java"
-            line="937"
+            file="../../content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java"
+            line="913"
             column="43"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 28 (current min is 23): `onSelectionAction`"
+        message="Call requires API level 28 (current min is 24): `onSelectionAction`"
         errorLine1="                mSmartSelectionEventProcessor.onSelectionAction(mLastSelectedText,"
         errorLine2="                                              ~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java"
-            line="1464"
+            file="../../content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java"
+            line="1440"
             column="47"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 28 (current min is 23): `onSelectionModified`"
+        message="Call requires API level 28 (current min is 24): `onSelectionModified`"
         errorLine1="                mSmartSelectionEventProcessor.onSelectionModified("
         errorLine2="                                              ~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java"
-            line="1611"
+            file="../../content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java"
+            line="1586"
             column="47"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Extending NotificationTask requires API level 29 (current min is 23): `NotificationTask`"
+        message="Extending NotificationTask requires API level 29 (current min is 24): `NotificationTask`"
         errorLine1="class SessionRemovedTask extends NotificationTask {"
         errorLine2="                                 ~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/SessionRemovedTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/SessionRemovedTask.java"
             line="12"
             column="34"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `NotificationTask`"
+        message="Call requires API level 29 (current min is 24): `NotificationTask`"
         errorLine1="        super(session, platformSession);"
         errorLine2="        ~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/SessionRemovedTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/SessionRemovedTask.java"
             line="14"
             column="9"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `log`"
+        message="Call requires API level 29 (current min is 24): `log`"
         errorLine1="        log(&quot;SessionRemovedTask.removeSession&quot;);"
         errorLine2="        ~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/SessionRemovedTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/SessionRemovedTask.java"
             line="23"
             column="9"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `getFrameIdToPlatformSessionData`"
+        message="Call requires API level 29 (current min is 24): `getFrameIdToPlatformSessionData`"
         errorLine1="                mPlatformSession.getFrameIdToPlatformSessionData().remove(mSession.get(0).getId());"
         errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/SessionRemovedTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/SessionRemovedTask.java"
             line="25"
             column="34"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Field requires API level 29 (current min is 23): `mPlatformSession`"
+        message="Field requires API level 29 (current min is 24): `mPlatformSession`"
         errorLine1="                mPlatformSession.getFrameIdToPlatformSessionData().remove(mSession.get(0).getId());"
         errorLine2="                ~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/SessionRemovedTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/SessionRemovedTask.java"
             line="25"
             column="17"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Field requires API level 29 (current min is 23): `mSession`"
+        message="Field requires API level 29 (current min is 24): `mSession`"
         errorLine1="                mPlatformSession.getFrameIdToPlatformSessionData().remove(mSession.get(0).getId());"
         errorLine2="                                                                          ~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/SessionRemovedTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/SessionRemovedTask.java"
             line="25"
             column="75"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `destroyContentCaptureSession`"
+        message="Call requires API level 29 (current min is 24): `destroyContentCaptureSession`"
         errorLine1="        PlatformAPIWrapper.getInstance().destroyContentCaptureSession("
         errorLine2="                                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/SessionRemovedTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/SessionRemovedTask.java"
             line="27"
             column="42"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `getInstance`"
+        message="Call requires API level 29 (current min is 24): `getInstance`"
         errorLine1="        PlatformAPIWrapper.getInstance().destroyContentCaptureSession("
         errorLine2="                           ~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/SessionRemovedTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/SessionRemovedTask.java"
             line="27"
             column="28"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Field requires API level 29 (current min is 23): `contentCaptureSession`"
+        message="Field requires API level 29 (current min is 24): `contentCaptureSession`"
         errorLine1="                removedPlatformSessionData.contentCaptureSession);"
         errorLine2="                                           ~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/SessionRemovedTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/SessionRemovedTask.java"
             line="28"
             column="44"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `getRootPlatformSessionData`"
+        message="Call requires API level 29 (current min is 24): `getRootPlatformSessionData`"
         errorLine1="                mPlatformSession.getRootPlatformSessionData();"
         errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/SessionRemovedTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/SessionRemovedTask.java"
             line="30"
             column="34"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Field requires API level 29 (current min is 23): `mPlatformSession`"
+        message="Field requires API level 29 (current min is 24): `mPlatformSession`"
         errorLine1="                mPlatformSession.getRootPlatformSessionData();"
         errorLine2="                ~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/SessionRemovedTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/SessionRemovedTask.java"
             line="30"
             column="17"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Field requires API level 29 (current min is 23): `mSession`"
+        message="Field requires API level 29 (current min is 24): `mSession`"
         errorLine1="        if (mSession.size() > 2) {"
         errorLine2="            ~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/SessionRemovedTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/SessionRemovedTask.java"
             line="34"
             column="13"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `getFrameIdToPlatformSessionData`"
+        message="Call requires API level 29 (current min is 24): `getFrameIdToPlatformSessionData`"
         errorLine1="                    mPlatformSession.getFrameIdToPlatformSessionData().get(mSession.get(1).getId());"
         errorLine2="                                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/SessionRemovedTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/SessionRemovedTask.java"
             line="36"
             column="38"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Field requires API level 29 (current min is 23): `mPlatformSession`"
+        message="Field requires API level 29 (current min is 24): `mPlatformSession`"
         errorLine1="                    mPlatformSession.getFrameIdToPlatformSessionData().get(mSession.get(1).getId());"
         errorLine2="                    ~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/SessionRemovedTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/SessionRemovedTask.java"
             line="36"
             column="21"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Field requires API level 29 (current min is 23): `mSession`"
+        message="Field requires API level 29 (current min is 24): `mSession`"
         errorLine1="                    mPlatformSession.getFrameIdToPlatformSessionData().get(mSession.get(1).getId());"
         errorLine2="                                                                           ~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/SessionRemovedTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/SessionRemovedTask.java"
             line="36"
             column="76"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `getInstance`"
+        message="Call requires API level 29 (current min is 24): `getInstance`"
         errorLine1="        PlatformAPIWrapper.getInstance().notifyViewDisappeared("
         errorLine2="                           ~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/SessionRemovedTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/SessionRemovedTask.java"
             line="39"
             column="28"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `notifyViewDisappeared`"
+        message="Call requires API level 29 (current min is 24): `notifyViewDisappeared`"
         errorLine1="        PlatformAPIWrapper.getInstance().notifyViewDisappeared("
         errorLine2="                                         ~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/SessionRemovedTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/SessionRemovedTask.java"
             line="39"
             column="42"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Field requires API level 29 (current min is 23): `contentCaptureSession`"
+        message="Field requires API level 29 (current min is 24): `contentCaptureSession`"
         errorLine1="                parentPlatformSessionData.contentCaptureSession,"
         errorLine2="                                          ~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/SessionRemovedTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/SessionRemovedTask.java"
             line="40"
             column="43"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Field requires API level 29 (current min is 23): `autofillId`"
+        message="Field requires API level 29 (current min is 24): `autofillId`"
         errorLine1="                removedPlatformSessionData.autofillId);"
         errorLine2="                                           ~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/SessionRemovedTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/SessionRemovedTask.java"
             line="41"
             column="44"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `addDirectAction`"
+        message="Call requires API level 29 (current min is 24): `addDirectAction`"
         errorLine1="        if (isAvailable()) reporter.addDirectAction(mActionId);"
         errorLine2="                                    ~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/directactions/SimpleDirectActionHandler.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/directactions/SimpleDirectActionHandler.java"
             line="24"
             column="37"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 26 (current min is 23): `setTextClassifier`"
+        message="Call requires API level 26 (current min is 24): `setTextClassifier`"
         errorLine1="        mProvider.setTextClassifier(textClassifier);"
         errorLine2="                  ~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/content/public/android/java/src/org/chromium/content/browser/selection/SmartSelectionClient.java"
+            file="../../content/public/android/java/src/org/chromium/content/browser/selection/SmartSelectionClient.java"
             line="127"
             column="19"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 26 (current min is 23): `getTextClassifier`"
+        message="Call requires API level 26 (current min is 24): `getTextClassifier`"
         errorLine1="        return mProvider.getTextClassifier();"
         errorLine2="                         ~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/content/public/android/java/src/org/chromium/content/browser/selection/SmartSelectionClient.java"
+            file="../../content/public/android/java/src/org/chromium/content/browser/selection/SmartSelectionClient.java"
             line="132"
             column="26"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 26 (current min is 23): `sendSmartSelectionRequest`"
+        message="Call requires API level 26 (current min is 24): `sendSmartSelectionRequest`"
         errorLine1="        sendSmartSelectionRequest(RequestType.SUGGEST_AND_CLASSIFY, text, start, end);"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/content/public/android/java/src/org/chromium/content/browser/selection/SmartSelectionProvider.java"
+            file="../../content/public/android/java/src/org/chromium/content/browser/selection/SmartSelectionProvider.java"
             line="82"
             column="9"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 26 (current min is 23): `sendSmartSelectionRequest`"
+        message="Call requires API level 26 (current min is 24): `sendSmartSelectionRequest`"
         errorLine1="        sendSmartSelectionRequest(RequestType.CLASSIFY, text, start, end);"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/content/public/android/java/src/org/chromium/content/browser/selection/SmartSelectionProvider.java"
+            file="../../content/public/android/java/src/org/chromium/content/browser/selection/SmartSelectionProvider.java"
             line="86"
             column="9"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 24 (current min is 23): `setOpenInOtherWindowIntentExtras`"
-        errorLine1="        MultiWindowUtils.setOpenInOtherWindowIntentExtras(intent, activity, targetActivity);"
-        errorLine2="                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/TabDelegate.java"
-            line="108"
-            column="26"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 24 (current min is 23): `onMultiInstanceModeStarted`"
-        errorLine1="        MultiInstanceManager.onMultiInstanceModeStarted();"
-        errorLine2="                             ~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/TabDelegate.java"
-            line="111"
-            column="30"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 26 (current min is 23): `onProvideAutoFillVirtualStructure`"
+        message="Call requires API level 26 (current min is 24): `onProvideAutoFillVirtualStructure`"
         errorLine1="        mAutofillProvider.onProvideAutoFillVirtualStructure(structure, flags);"
         errorLine2="                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java"
-            line="423"
+            file="../../weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java"
+            line="431"
             column="27"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 26 (current min is 23): `autofill`"
+        message="Call requires API level 26 (current min is 24): `autofill`"
         errorLine1="        mAutofillProvider.autofill(values);"
         errorLine2="                          ~~~~~~~~">
         <location
-            file="$SRC/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java"
-            line="428"
+            file="../../weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java"
+            line="436"
             column="27"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 26 (current min is 23): `hidePopup`"
+        message="Call requires API level 26 (current min is 24): `hidePopup`"
         errorLine1="            mAutofillProvider.hidePopup();"
         errorLine2="                              ~~~~~~~~~">
         <location
-            file="$SRC/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java"
-            line="470"
+            file="../../weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java"
+            line="478"
             column="31"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 26 (current min is 23): `destroy`"
+        message="Call requires API level 26 (current min is 24): `destroy`"
         errorLine1="            mAutofillProvider.destroy();"
         errorLine2="                              ~~~~~~~">
         <location
-            file="$SRC/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java"
-            line="1065"
+            file="../../weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java"
+            line="1088"
             column="31"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 24 (current min is 23): `mergedOnStartup`"
-        errorLine1="            MultiInstanceManager.mergedOnStartup();"
-        errorLine2="                                 ~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/app/tabmodel/TabbedModeTabModelOrchestrator.java"
-            line="48"
-            column="34"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 24 (current min is 23): `shouldMergeOnStartup`"
-        errorLine1="        if (MultiInstanceManager.shouldMergeOnStartup(activity)) {"
-        errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/app/tabmodel/TabbedModeTabModelOrchestrator.java"
-            line="98"
-            column="34"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 27 (current min is 23): `setNavigationBarScrimFraction`"
+        message="Call requires API level 27 (current min is 24): `setNavigationBarScrimFraction`"
         errorLine1="                        controller.setNavigationBarScrimFraction(scrimFraction);"
         errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java"
-            line="578"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java"
+            line="636"
             column="36"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 27 (current min is 23): `destroy`"
+        message="Call requires API level 27 (current min is 24): `destroy`"
         errorLine1="        if (mNavigationBarColorController != null) mNavigationBarColorController.destroy();"
         errorLine2="                                                                                 ~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedSystemUiCoordinator.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedSystemUiCoordinator.java"
             line="55"
             column="82"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Extending NotificationTask requires API level 29 (current min is 23): `NotificationTask`"
+        message="Extending NotificationTask requires API level 29 (current min is 24): `NotificationTask`"
         errorLine1="public class TitleUpdateTask extends NotificationTask {"
         errorLine2="                                     ~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/TitleUpdateTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/TitleUpdateTask.java"
             line="14"
             column="38"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `NotificationTask`"
+        message="Call requires API level 29 (current min is 24): `NotificationTask`"
         errorLine1="        super(null, platformSession);"
         errorLine2="        ~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/TitleUpdateTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/TitleUpdateTask.java"
             line="17"
             column="9"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `log`"
+        message="Call requires API level 29 (current min is 24): `log`"
         errorLine1="        log(&quot;TitleUpdateTask.updateTitle&quot;);"
         errorLine2="        ~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/TitleUpdateTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/TitleUpdateTask.java"
             line="27"
             column="9"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `buildCurrentSession`"
+        message="Call requires API level 29 (current min is 24): `buildCurrentSession`"
         errorLine1="        PlatformSessionData parentPlatformSessionData = buildCurrentSession();"
         errorLine2="                                                        ~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/TitleUpdateTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/TitleUpdateTask.java"
             line="30"
             column="57"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `getInstance`"
+        message="Call requires API level 29 (current min is 24): `getInstance`"
         errorLine1="        AutofillId autofillId = PlatformAPIWrapper.getInstance().newAutofillId("
         errorLine2="                                                   ~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/TitleUpdateTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/TitleUpdateTask.java"
             line="31"
             column="52"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `newAutofillId`"
+        message="Call requires API level 29 (current min is 24): `newAutofillId`"
         errorLine1="        AutofillId autofillId = PlatformAPIWrapper.getInstance().newAutofillId("
         errorLine2="                                                                 ~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/TitleUpdateTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/TitleUpdateTask.java"
             line="31"
             column="66"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Field requires API level 29 (current min is 23): `contentCaptureSession`"
+        message="Field requires API level 29 (current min is 24): `contentCaptureSession`"
         errorLine1="                parentPlatformSessionData.contentCaptureSession,"
         errorLine2="                                          ~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/TitleUpdateTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/TitleUpdateTask.java"
             line="32"
             column="43"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `getRootPlatformSessionData`"
+        message="Call requires API level 29 (current min is 24): `getRootPlatformSessionData`"
         errorLine1="                mPlatformSession.getRootPlatformSessionData().autofillId, mMainFrame.getId());"
         errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/TitleUpdateTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/TitleUpdateTask.java"
             line="33"
             column="34"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Field requires API level 29 (current min is 23): `autofillId`"
+        message="Field requires API level 29 (current min is 24): `autofillId`"
         errorLine1="                mPlatformSession.getRootPlatformSessionData().autofillId, mMainFrame.getId());"
         errorLine2="                                                              ~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/TitleUpdateTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/TitleUpdateTask.java"
             line="33"
             column="63"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Field requires API level 29 (current min is 23): `mPlatformSession`"
+        message="Field requires API level 29 (current min is 24): `mPlatformSession`"
         errorLine1="                mPlatformSession.getRootPlatformSessionData().autofillId, mMainFrame.getId());"
         errorLine2="                ~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/TitleUpdateTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/TitleUpdateTask.java"
             line="33"
             column="17"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `getInstance`"
+        message="Call requires API level 29 (current min is 24): `getInstance`"
         errorLine1="        PlatformAPIWrapper.getInstance().notifyViewTextChanged("
         errorLine2="                           ~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/TitleUpdateTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/TitleUpdateTask.java"
             line="34"
             column="28"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `notifyViewTextChanged`"
+        message="Call requires API level 29 (current min is 24): `notifyViewTextChanged`"
         errorLine1="        PlatformAPIWrapper.getInstance().notifyViewTextChanged("
         errorLine2="                                         ~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/TitleUpdateTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/TitleUpdateTask.java"
             line="34"
             column="42"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Field requires API level 29 (current min is 23): `contentCaptureSession`"
+        message="Field requires API level 29 (current min is 24): `contentCaptureSession`"
         errorLine1="                parentPlatformSessionData.contentCaptureSession, autofillId, mMainFrame.getText());"
         errorLine2="                                          ~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/content_capture/android/java/src/org/chromium/components/content_capture/TitleUpdateTask.java"
+            file="../../components/content_capture/android/java/src/org/chromium/components/content_capture/TitleUpdateTask.java"
             line="35"
             column="43"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Extending ZygotePreload requires API level 29 (current min is 23): `ZygotePreload`"
+        message="Extending ZygotePreload requires API level 29 (current min is 24): `ZygotePreload`"
         errorLine1="public class TrichromeZygotePreload extends ZygotePreload {"
         errorLine2="                                            ~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/app/TrichromeZygotePreload.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/app/TrichromeZygotePreload.java"
             line="16"
             column="45"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `doPreloadCommon`"
+        message="Call requires API level 29 (current min is 24): `doPreloadCommon`"
         errorLine1="        doPreloadCommon(appInfo);"
         errorLine2="        ~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/app/TrichromeZygotePreload.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/app/TrichromeZygotePreload.java"
             line="24"
             column="9"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 29 (current min is 23): `currentStatus`"
-        errorLine1="                                || mReader.currentStatus() == ImageReaderStatus.RUNNING));"
-        errorLine2="                                           ~~~~~~~~~~~~~">
-        <location
-            file="$SRC/ui/android/java/src/org/chromium/ui/resources/dynamics/ViewResourceAdapter.java"
-            line="449"
-            column="44"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 29 (current min is 23): `AcceleratedImageReader`"
-        errorLine1="                    mReader = new AcceleratedImageReader(scaledWidth, scaledHeight);"
-        errorLine2="                              ~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/ui/android/java/src/org/chromium/ui/resources/dynamics/ViewResourceAdapter.java"
-            line="472"
-            column="31"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 29 (current min is 23): `onLayoutChange`"
-        errorLine1="                    mReader.onLayoutChange(scaledWidth, scaledHeight);"
-        errorLine2="                            ~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/ui/android/java/src/org/chromium/ui/resources/dynamics/ViewResourceAdapter.java"
-            line="474"
-            column="29"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 24 (current min is 23): `setVrModeEnabled`"
-        errorLine1="            ApiHelperForN.setVrModeEnabled(activity, enabled,"
-        errorLine2="                          ~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrDelegateFallback.java"
-            line="240"
-            column="27"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 24 (current min is 23): `initializeNative`"
-        errorLine1="        mVrShell.initializeNative(mRequestedWebVr, VrModuleProvider.getDelegate().bootsToVr());"
-        errorLine2="                 ~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrShellDelegate.java"
-            line="934"
-            column="18"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 26 (current min is 23): `updateChannelsIfNecessary`"
+        message="Call requires API level 26 (current min is 24): `updateChannelsIfNecessary`"
         errorLine1="        WebLayerNotificationChannels.updateChannelsIfNecessary();"
         errorLine2="                                     ~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java"
-            line="333"
+            file="../../weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java"
+            line="340"
             column="38"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 26 (current min is 23): `getSplitNames`"
-        errorLine1="            String[] splitNames = ApiHelperForO.getSplitNames(appInfo);"
-        errorLine2="                                                ~~~~~~~~~~~~~">
-        <location
-            file="$SRC/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java"
-            line="987"
-            column="49"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 26 (current min is 23): `ChannelsInitializer`"
+        message="Call requires API level 26 (current min is 24): `ChannelsInitializer`"
         errorLine1="                new ChannelsInitializer(new NotificationManagerProxyImpl(appContext),"
         errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/weblayer/browser/java/org/chromium/weblayer_private/WebLayerNotificationWrapperBuilder.java"
+            file="../../weblayer/browser/java/org/chromium/weblayer_private/WebLayerNotificationWrapperBuilder.java"
             line="32"
             column="17"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 26 (current min is 23): `getInstance`"
+        message="Call requires API level 26 (current min is 24): `getInstance`"
         errorLine1="                        WebLayerNotificationChannels.getInstance(), appContext.getResources());"
         errorLine2="                                                     ~~~~~~~~~~~">
         <location
-            file="$SRC/weblayer/browser/java/org/chromium/weblayer_private/WebLayerNotificationWrapperBuilder.java"
+            file="../../weblayer/browser/java/org/chromium/weblayer_private/WebLayerNotificationWrapperBuilder.java"
             line="33"
             column="54"/>
     </issue>
 
     <issue
         id="NewApi"
-        message="Call requires API level 26 (current min is 23): `addShortcutWithShortcutManager`"
+        message="Call requires API level 26 (current min is 24): `addShortcutWithShortcutManager`"
         errorLine1="            addShortcutWithShortcutManager(id, title, icon, isIconAdaptive, shortcutIntent);"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/webapps/browser/android/java/src/org/chromium/components/webapps/WebappsUtils.java"
+            file="../../components/webapps/browser/android/java/src/org/chromium/components/webapps/WebappsUtils.java"
             line="70"
             column="13"/>
     </issue>
@@ -2603,11 +1877,11 @@
         errorLine1="            RecordHistogram.recordEnumeratedHistogram("
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationUmaHelper.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationUmaHelper.java"
             line="113"
             column="13"/>
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationUmaHelper.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationUmaHelper.java"
             line="112"
             column="9"
             message="Previous statement here"/>
@@ -2615,34 +1889,34 @@
 
     <issue
         id="WrongConstant"
-        message="Must be one of: AdaptiveToolbarButtonVariant.UNKNOWN, AdaptiveToolbarButtonVariant.NONE, AdaptiveToolbarButtonVariant.NEW_TAB, AdaptiveToolbarButtonVariant.SHARE, AdaptiveToolbarButtonVariant.VOICE, AdaptiveToolbarButtonVariant.AUTO, AdaptiveToolbarButtonVariant.PRICE_TRACKING"
+        message="Must be one of: AdaptiveToolbarButtonVariant.UNKNOWN, AdaptiveToolbarButtonVariant.NONE, AdaptiveToolbarButtonVariant.NEW_TAB, AdaptiveToolbarButtonVariant.SHARE, AdaptiveToolbarButtonVariant.VOICE, AdaptiveToolbarButtonVariant.AUTO, AdaptiveToolbarButtonVariant.PRICE_TRACKING, AdaptiveToolbarButtonVariant.READER_MODE"
         errorLine1="                &amp;&amp; variant &lt; AdaptiveToolbarButtonVariant.NUM_ENTRIES"
         errorLine2="                                                          ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveToolbarButtonController.java"
-            line="115"
+            file="../../chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveToolbarButtonController.java"
+            line="122"
             column="59"/>
     </issue>
 
     <issue
         id="WrongConstant"
-        message="Must be one of: AdaptiveToolbarButtonVariant.UNKNOWN, AdaptiveToolbarButtonVariant.NONE, AdaptiveToolbarButtonVariant.NEW_TAB, AdaptiveToolbarButtonVariant.SHARE, AdaptiveToolbarButtonVariant.VOICE, AdaptiveToolbarButtonVariant.AUTO, AdaptiveToolbarButtonVariant.PRICE_TRACKING"
+        message="Must be one of: AdaptiveToolbarButtonVariant.UNKNOWN, AdaptiveToolbarButtonVariant.NONE, AdaptiveToolbarButtonVariant.NEW_TAB, AdaptiveToolbarButtonVariant.SHARE, AdaptiveToolbarButtonVariant.VOICE, AdaptiveToolbarButtonVariant.AUTO, AdaptiveToolbarButtonVariant.PRICE_TRACKING, AdaptiveToolbarButtonVariant.READER_MODE"
         errorLine1="                    AdaptiveToolbarButtonVariant.NUM_ENTRIES);"
         errorLine2="                                                 ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveToolbarButtonController.java"
-            line="176"
+            file="../../chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveToolbarButtonController.java"
+            line="188"
             column="50"/>
     </issue>
 
     <issue
         id="WrongConstant"
-        message="Must be one of: AdaptiveToolbarButtonVariant.UNKNOWN, AdaptiveToolbarButtonVariant.NONE, AdaptiveToolbarButtonVariant.NEW_TAB, AdaptiveToolbarButtonVariant.SHARE, AdaptiveToolbarButtonVariant.VOICE, AdaptiveToolbarButtonVariant.AUTO, AdaptiveToolbarButtonVariant.PRICE_TRACKING"
+        message="Must be one of: AdaptiveToolbarButtonVariant.UNKNOWN, AdaptiveToolbarButtonVariant.NONE, AdaptiveToolbarButtonVariant.NEW_TAB, AdaptiveToolbarButtonVariant.SHARE, AdaptiveToolbarButtonVariant.VOICE, AdaptiveToolbarButtonVariant.AUTO, AdaptiveToolbarButtonVariant.PRICE_TRACKING, AdaptiveToolbarButtonVariant.READER_MODE"
         errorLine1="                    buttonVariant, AdaptiveToolbarButtonVariant.NUM_ENTRIES);"
         errorLine2="                                                                ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveToolbarButtonController.java"
-            line="204"
+            file="../../chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveToolbarButtonController.java"
+            line="219"
             column="65"/>
     </issue>
 
@@ -2652,18 +1926,18 @@
         errorLine1="                    AdaptiveToolbarRadioButtonState.NUM_ENTRIES);"
         errorLine2="                                                    ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveToolbarStats.java"
+            file="../../chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveToolbarStats.java"
             line="50"
             column="53"/>
     </issue>
 
     <issue
         id="WrongConstant"
-        message="Must be one of: AdaptiveToolbarButtonVariant.UNKNOWN, AdaptiveToolbarButtonVariant.NONE, AdaptiveToolbarButtonVariant.NEW_TAB, AdaptiveToolbarButtonVariant.SHARE, AdaptiveToolbarButtonVariant.VOICE, AdaptiveToolbarButtonVariant.AUTO, AdaptiveToolbarButtonVariant.PRICE_TRACKING"
+        message="Must be one of: AdaptiveToolbarButtonVariant.UNKNOWN, AdaptiveToolbarButtonVariant.NONE, AdaptiveToolbarButtonVariant.NEW_TAB, AdaptiveToolbarButtonVariant.SHARE, AdaptiveToolbarButtonVariant.VOICE, AdaptiveToolbarButtonVariant.AUTO, AdaptiveToolbarButtonVariant.PRICE_TRACKING, AdaptiveToolbarButtonVariant.READER_MODE"
         errorLine1="                    AdaptiveToolbarButtonVariant.NUM_ENTRIES);"
         errorLine2="                                                 ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveToolbarStats.java"
+            file="../../chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveToolbarStats.java"
             line="73"
             column="50"/>
     </issue>
@@ -2671,67 +1945,23 @@
     <issue
         id="WrongConstant"
         message="Must be one of: SettingsNavigationSource.OTHER, SettingsNavigationSource.TWA_CLEAR_DATA_DIALOG, SettingsNavigationSource.TWA_MANAGE_SPACE_ACTIVITY"
-        errorLine1="                    SettingsNavigationSource.EXTRA_KEY, SettingsNavigationSource.OTHER);"
-        errorLine2="                                             ~~~~~~~~~">
+        errorLine1="                SettingsNavigationSource.EXTRA_KEY, SettingsNavigationSource.OTHER);"
+        errorLine2="                                         ~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/AllSiteSettings.java"
-            line="281"
-            column="46"/>
+            file="../../components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/AllSiteSettings.java"
+            line="279"
+            column="42"/>
     </issue>
 
     <issue
         id="WrongConstant"
         message="Must be one of: SettingsNavigationSource.OTHER, SettingsNavigationSource.TWA_CLEAR_DATA_DIALOG, SettingsNavigationSource.TWA_MANAGE_SPACE_ACTIVITY"
-        errorLine1="            website.getExtras().putInt(SettingsNavigationSource.EXTRA_KEY, navigationSource);"
-        errorLine2="                                                                ~~~~~~~~~">
+        errorLine1="        final String extraKey = SettingsNavigationSource.EXTRA_KEY;"
+        errorLine2="                                                         ~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/AllSiteSettings.java"
-            line="282"
-            column="65"/>
-    </issue>
-
-    <issue
-        id="WrongConstant"
-        message="Must be one of: FetchFontResult.SUCCESS, FetchFontResult.FAILED_UNEXPECTED_NAME, FetchFontResult.FAILED_STATUS_CODE, FetchFontResult.FAILED_NON_UNIQUE_RESULT, FetchFontResult.FAILED_RESULT_CODE, FetchFontResult.FAILED_FILE_OPEN, FetchFontResult.FAILED_EXCEPTION, FetchFontResult.FAILED_AVOID_RETRY, FetchFontResult.SUCCESS_CACHED"
-        errorLine1="                FETCH_FONT_RESULT_HISTOGRAM, result, FetchFontResult.COUNT);"
-        errorLine2="                                                                     ~~~~~">
-        <location
-            file="$SRC/content/public/android/java/src/org/chromium/content/browser/font/AndroidFontLookupImpl.java"
-            line="368"
-            column="70"/>
-    </issue>
-
-    <issue
-        id="WrongConstant"
-        message="Must be one of: FetchFontName.GOOGLE_SANS_REGULAR, FetchFontName.GOOGLE_SANS_MEDIUM, FetchFontName.GOOGLE_SANS_BOLD, FetchFontName.NOTO_COLOR_EMOJI_COMPAT"
-        errorLine1="                result = FetchFontName.OTHER;"
-        errorLine2="                                       ~~~~~">
-        <location
-            file="$SRC/content/public/android/java/src/org/chromium/content/browser/font/AndroidFontLookupImpl.java"
-            line="388"
-            column="40"/>
-    </issue>
-
-    <issue
-        id="WrongConstant"
-        message="Must be one of: FetchFontName.GOOGLE_SANS_REGULAR, FetchFontName.GOOGLE_SANS_MEDIUM, FetchFontName.GOOGLE_SANS_BOLD, FetchFontName.NOTO_COLOR_EMOJI_COMPAT"
-        errorLine1="                FETCH_FONT_NAME_HISTOGRAM, result, FetchFontName.COUNT);"
-        errorLine2="                                           ~~~~~~">
-        <location
-            file="$SRC/content/public/android/java/src/org/chromium/content/browser/font/AndroidFontLookupImpl.java"
-            line="391"
-            column="44"/>
-    </issue>
-
-    <issue
-        id="WrongConstant"
-        message="Must be one of: FetchFontName.GOOGLE_SANS_REGULAR, FetchFontName.GOOGLE_SANS_MEDIUM, FetchFontName.GOOGLE_SANS_BOLD, FetchFontName.NOTO_COLOR_EMOJI_COMPAT"
-        errorLine1="                FETCH_FONT_NAME_HISTOGRAM, result, FetchFontName.COUNT);"
-        errorLine2="                                                                 ~~~~~">
-        <location
-            file="$SRC/content/public/android/java/src/org/chromium/content/browser/font/AndroidFontLookupImpl.java"
-            line="391"
-            column="66"/>
+            file="../../components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/AllSiteSettings.java"
+            line="285"
+            column="58"/>
     </issue>
 
     <issue
@@ -2740,7 +1970,7 @@
         errorLine1="                        &quot;CopylessPaste.CacheHit&quot;, CacheHit.WITH_ENTITY, CacheHit.NUM_ENTRIES);"
         errorLine2="                                                                                 ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/AppIndexingUtil.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/AppIndexingUtil.java"
             line="101"
             column="82"/>
     </issue>
@@ -2751,7 +1981,7 @@
         errorLine1="                    &quot;CopylessPaste.CacheHit&quot;, CacheHit.WITHOUT_ENTITY, CacheHit.NUM_ENTRIES);"
         errorLine2="                                                                                ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/AppIndexingUtil.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/AppIndexingUtil.java"
             line="106"
             column="81"/>
     </issue>
@@ -2762,7 +1992,7 @@
         errorLine1="                    &quot;CopylessPaste.CacheHit&quot;, CacheHit.MISS, CacheHit.NUM_ENTRIES);"
         errorLine2="                                                                      ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/AppIndexingUtil.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/AppIndexingUtil.java"
             line="110"
             column="71"/>
     </issue>
@@ -2773,8 +2003,8 @@
         errorLine1="                &quot;LanguageSettings.AppLanguagePrompt.Action&quot;, actionType, ActionType.NUM_ENTRIES);"
         errorLine2="                                                                                    ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/AppLanguagePromoDialog.java"
-            line="589"
+            file="../../chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/AppLanguagePromoDialog.java"
+            line="618"
             column="85"/>
     </issue>
 
@@ -2784,8 +2014,8 @@
         errorLine1="                BlockDrawForInitialTabAccuracy.COUNT);"
         errorLine2="                                               ~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ui/AppLaunchDrawBlocker.java"
-            line="277"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/ui/AppLaunchDrawBlocker.java"
+            line="323"
             column="48"/>
     </issue>
 
@@ -2795,8 +2025,8 @@
         errorLine1="                getUmaEnumForMenuItem(menuItemId), AppMenuHighlightItem.NUM_ENTRIES);"
         errorLine2="                                                                        ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java"
-            line="1004"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java"
+            line="1053"
             column="73"/>
     </issue>
 
@@ -2806,8 +2036,8 @@
         errorLine1="                getUmaEnumForMenuItem(menuItemId), AppMenuHighlightItem.NUM_ENTRIES);"
         errorLine2="                                                                        ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java"
-            line="1010"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java"
+            line="1059"
             column="73"/>
     </issue>
 
@@ -2817,8 +2047,8 @@
         errorLine1="                ConsentOutcome.NON_USER_CANCEL, ConsentOutcome.MAX_VALUE);"
         errorLine2="                               ~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/voice/AssistantVoiceSearchConsentController.java"
-            line="214"
+            file="../../chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/voice/AssistantVoiceSearchConsentController.java"
+            line="216"
             column="32"/>
     </issue>
 
@@ -2828,8 +2058,8 @@
         errorLine1="                    EligibilityFailureReason.NUM_ENTRIES);"
         errorLine2="                                             ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/voice/AssistantVoiceSearchService.java"
-            line="399"
+            file="../../chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/voice/AssistantVoiceSearchService.java"
+            line="414"
             column="46"/>
     </issue>
 
@@ -2839,7 +2069,7 @@
         errorLine1="                    GET_STATUS_UMA_HISTOGRAM, status, Status.NUM_ENTRIES);"
         errorLine2="                                                             ~~~~~~~~~~~">
         <location
-            file="$SRC/base/android/java/src/org/chromium/base/task/AsyncTask.java"
+            file="../../base/android/java/src/org/chromium/base/task/AsyncTask.java"
             line="314"
             column="62"/>
     </issue>
@@ -2850,7 +2080,7 @@
         errorLine1="                    GET_STATUS_UMA_HISTOGRAM, status, Status.NUM_ENTRIES);"
         errorLine2="                                                             ~~~~~~~~~~~">
         <location
-            file="$SRC/base/android/java/src/org/chromium/base/task/AsyncTask.java"
+            file="../../base/android/java/src/org/chromium/base/task/AsyncTask.java"
             line="352"
             column="62"/>
     </issue>
@@ -2861,7 +2091,7 @@
         errorLine1="                histogram, source, AutoDarkSettingsChangeSource.NUM_ENTRIES);"
         errorLine2="                                                                ~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/AutoDarkMetrics.java"
+            file="../../components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/AutoDarkMetrics.java"
             line="51"
             column="65"/>
     </issue>
@@ -2872,7 +2102,7 @@
         errorLine1="                    intent, EXTRA_ACTION, NotificationAction.NUM_ENTRIES);"
         errorLine2="                                                             ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/AutoFetchNotifier.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/offlinepages/AutoFetchNotifier.java"
             line="100"
             column="62"/>
     </issue>
@@ -2883,7 +2113,7 @@
         errorLine1="                                NotificationUmaTracker.ActionType.AUTO_FETCH_CANCEL)"
         errorLine2="                                                                  ~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/AutoFetchNotifier.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/offlinepages/AutoFetchNotifier.java"
             line="174"
             column="67"/>
     </issue>
@@ -2894,7 +2124,7 @@
         errorLine1="                NotificationAction.NUM_ENTRIES);"
         errorLine2="                                   ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/AutoFetchNotifier.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/offlinepages/AutoFetchNotifier.java"
             line="206"
             column="36"/>
     </issue>
@@ -2905,7 +2135,7 @@
         errorLine1="        if (currentAction == NotificationAction.NUM_ENTRIES) {"
         errorLine2="                                                ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/AutoFetchNotifier.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/offlinepages/AutoFetchNotifier.java"
             line="207"
             column="49"/>
     </issue>
@@ -2916,7 +2146,7 @@
         errorLine1="                       NotificationAction.NUM_ENTRIES)"
         errorLine2="                                          ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/AutoFetchNotifier.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/offlinepages/AutoFetchNotifier.java"
             line="223"
             column="43"/>
     </issue>
@@ -2927,7 +2157,7 @@
         errorLine1="                != NotificationAction.NUM_ENTRIES;"
         errorLine2="                                      ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/AutoFetchNotifier.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/offlinepages/AutoFetchNotifier.java"
             line="224"
             column="39"/>
     </issue>
@@ -2938,7 +2168,7 @@
         errorLine1="                    intent, EXTRA_ACTION, NotificationAction.NUM_ENTRIES);"
         errorLine2="                                                             ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/AutoFetchNotifier.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/offlinepages/AutoFetchNotifier.java"
             line="236"
             column="62"/>
     </issue>
@@ -2949,7 +2179,7 @@
         errorLine1="            if (action != NotificationAction.TAPPED &amp;&amp; action != NotificationAction.DISMISSED) {"
         errorLine2="                                             ~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/AutoFetchNotifier.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/offlinepages/AutoFetchNotifier.java"
             line="237"
             column="46"/>
     </issue>
@@ -2960,7 +2190,7 @@
         errorLine1="            if (action != NotificationAction.TAPPED) {"
         errorLine2="                                             ~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/AutoFetchNotifier.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/offlinepages/AutoFetchNotifier.java"
             line="242"
             column="46"/>
     </issue>
@@ -2971,7 +2201,7 @@
         errorLine1="        clickIntent.putExtra(TabOpenType.REUSE_TAB_ORIGINAL_URL_STRING, originalUrl);"
         errorLine2="                                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/AutoFetchNotifier.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/offlinepages/AutoFetchNotifier.java"
             line="290"
             column="42"/>
     </issue>
@@ -2982,7 +2212,7 @@
         errorLine1="        clickIntent.putExtra(TabOpenType.REUSE_TAB_MATCHING_ID_STRING, tabId);"
         errorLine2="                                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/AutoFetchNotifier.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/offlinepages/AutoFetchNotifier.java"
             line="292"
             column="42"/>
     </issue>
@@ -2993,7 +2223,7 @@
         errorLine1="        clickIntent.putExtra(EXTRA_ACTION, NotificationAction.TAPPED);"
         errorLine2="                                                              ~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/AutoFetchNotifier.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/offlinepages/AutoFetchNotifier.java"
             line="294"
             column="63"/>
     </issue>
@@ -3004,7 +2234,7 @@
         errorLine1="                NotificationAction.NUM_ENTRIES);"
         errorLine2="                                   ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/AutoFetchNotifier.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/offlinepages/AutoFetchNotifier.java"
             line="347"
             column="36"/>
     </issue>
@@ -3015,30 +2245,19 @@
         errorLine1="                NotificationAction.NUM_ENTRIES);"
         errorLine2="                                   ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/AutoFetchNotifier.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/offlinepages/AutoFetchNotifier.java"
             line="353"
             column="36"/>
     </issue>
 
     <issue
         id="WrongConstant"
-        message="Must be one of: OmniboxSuggestionUiType.DEFAULT, OmniboxSuggestionUiType.EDIT_URL_SUGGESTION, OmniboxSuggestionUiType.ANSWER_SUGGESTION, OmniboxSuggestionUiType.ENTITY_SUGGESTION, OmniboxSuggestionUiType.TAIL_SUGGESTION, OmniboxSuggestionUiType.CLIPBOARD_SUGGESTION, OmniboxSuggestionUiType.TILE_SUGGESTION, OmniboxSuggestionUiType.TILE_NAVSUGGEST, OmniboxSuggestionUiType.PEDAL_SUGGESTION"
-        errorLine1="                        OmniboxSuggestionUiType.HEADER,"
-        errorLine2="                                                ~~~~~~">
-        <location
-            file="$SRC/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteCoordinator.java"
-            line="201"
-            column="49"/>
-    </issue>
-
-    <issue
-        id="WrongConstant"
         message="Must be one of: TransmissionResult.SUCCESS, TransmissionResult.MALFORMED_PROTOBUF, TransmissionResult.REMOTE_EXCEPTION"
         errorLine1="                TransmissionResult.COUNT);"
         errorLine2="                                   ~~~~~">
         <location
-            file="$SRC/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java"
-            line="403"
+            file="../../android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java"
+            line="405"
             column="36"/>
     </issue>
 
@@ -3048,8 +2267,8 @@
         errorLine1="                LOAD_URL_SCHEME_HISTOGRAM_NAME, value, UrlScheme.COUNT);"
         errorLine2="                                                                 ~~~~~">
         <location
-            file="$SRC/android_webview/java/src/org/chromium/android_webview/AwContents.java"
-            line="2056"
+            file="../../android_webview/java/src/org/chromium/android_webview/AwContents.java"
+            line="2067"
             column="66"/>
     </issue>
 
@@ -3059,7 +2278,7 @@
         errorLine1="                &quot;Android.WebView.Callback.Counts&quot;, result, WebViewCallbackType.NUM_ENTRIES);"
         errorLine2="                                                                               ~~~~~~~~~~~">
         <location
-            file="$SRC/android_webview/java/src/org/chromium/android_webview/AwHistogramRecorder.java"
+            file="../../android_webview/java/src/org/chromium/android_webview/AwHistogramRecorder.java"
             line="47"
             column="80"/>
     </issue>
@@ -3070,8 +2289,8 @@
         errorLine1="                &quot;SafeBrowsing.WebView.AppOptIn&quot;, value, AppOptIn.COUNT);"
         errorLine2="                                                                 ~~~~~">
         <location
-            file="$SRC/android_webview/java/src/org/chromium/android_webview/safe_browsing/AwSafeBrowsingConfigHelper.java"
-            line="49"
+            file="../../android_webview/java/src/org/chromium/android_webview/safe_browsing/AwSafeBrowsingConfigHelper.java"
+            line="40"
             column="66"/>
     </issue>
 
@@ -3081,8 +2300,8 @@
         errorLine1="            case ViewType.SHOPPING_FILTER:"
         errorLine2="                          ~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java"
-            line="269"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java"
+            line="267"
             column="27"/>
     </issue>
 
@@ -3092,8 +2311,8 @@
         errorLine1="        } else if (holder.getItemViewType() == ViewType.SHOPPING_FILTER) {"
         errorLine2="                                                        ~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java"
-            line="311"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java"
+            line="309"
             column="57"/>
     </issue>
 
@@ -3103,8 +2322,8 @@
         errorLine1="                ViewType.SHOPPING_FILTER, /*bookmarkItem=*/null, /*sectionHeaderData=*/null);"
         errorLine2="                         ~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkListEntry.java"
-            line="113"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkListEntry.java"
+            line="109"
             column="26"/>
     </issue>
 
@@ -3114,8 +2333,8 @@
         errorLine1="        intent.putExtra(CustomTabIntentDataProvider.EXTRA_UI_TYPE, CustomTabsUiType.READ_LATER);"
         errorLine2="                                                                                    ~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java"
-            line="593"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java"
+            line="633"
             column="85"/>
     </issue>
 
@@ -3125,8 +2344,8 @@
         errorLine1="                        &quot;Variations.SafeModeCachedFlags.Engaged&quot;, behavior, Behavior.NUM_ENTRIES);"
         errorLine2="                                                                                     ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFlagsSafeMode.java"
-            line="90"
+            file="../../chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFlagsSafeMode.java"
+            line="93"
             column="86"/>
     </issue>
 
@@ -3136,8 +2355,8 @@
         errorLine1="                        Behavior.NOT_ENGAGED_BELOW_THRESHOLD, Behavior.NUM_ENTRIES);"
         errorLine2="                                                                       ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFlagsSafeMode.java"
-            line="94"
+            file="../../chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFlagsSafeMode.java"
+            line="97"
             column="72"/>
     </issue>
 
@@ -3147,8 +2366,8 @@
         errorLine1="                &quot;Variations.SafeModeCachedFlags.WillCache&quot;, mBehavior.get(), Behavior.NUM_ENTRIES);"
         errorLine2="                                                                                      ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFlagsSafeMode.java"
-            line="117"
+            file="../../chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFlagsSafeMode.java"
+            line="120"
             column="87"/>
     </issue>
 
@@ -3158,8 +2377,8 @@
         errorLine1="                &quot;Variations.SafeModeCachedFlags.Pause&quot;, mBehavior.get(), Behavior.NUM_ENTRIES);"
         errorLine2="                                                                                  ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFlagsSafeMode.java"
-            line="136"
+            file="../../chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFlagsSafeMode.java"
+            line="139"
             column="83"/>
     </issue>
 
@@ -3169,8 +2388,8 @@
         errorLine1="                        mBehavior.get(), Behavior.NUM_ENTRIES);"
         errorLine2="                                                  ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFlagsSafeMode.java"
-            line="183"
+            file="../../chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFlagsSafeMode.java"
+            line="186"
             column="51"/>
     </issue>
 
@@ -3180,7 +2399,7 @@
         errorLine1="                contentsShowing ? View.IMPORTANT_FOR_ACCESSIBILITY_AUTO"
         errorLine2="                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskPrompt.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskPrompt.java"
             line="530"
             column="35"/>
     </issue>
@@ -3191,7 +2410,7 @@
         errorLine1="                                : View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);"
         errorLine2="                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskPrompt.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskPrompt.java"
             line="531"
             column="35"/>
     </issue>
@@ -3202,8 +2421,8 @@
         errorLine1="                &quot;ChromiumAndroidLinker.ChildProcessZygoteState&quot;, state, ZygoteChildState.COUNT);"
         errorLine2="                                                                                         ~~~~~">
         <location
-            file="$SRC/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncherHelperImpl.java"
-            line="245"
+            file="../../content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncherHelperImpl.java"
+            line="269"
             column="90"/>
     </issue>
 
@@ -3213,8 +2432,8 @@
         errorLine1="                    HISTOGRAM_ANDROID_RESTORE_RESULT, restoreStatus, RestoreStatus.NUM_ENTRIES);"
         errorLine2="                                                                                   ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ChromeBackupAgentImpl.java"
-            line="459"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/ChromeBackupAgentImpl.java"
+            line="458"
             column="84"/>
     </issue>
 
@@ -3224,7 +2443,7 @@
         errorLine1="            map.put(ChannelId.WEBRTC_CAM_AND_MIC,"
         errorLine2="                              ~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/channels/ChromeChannelDefinitions.java"
+            file="../../chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/channels/ChromeChannelDefinitions.java"
             line="159"
             column="31"/>
     </issue>
@@ -3235,7 +2454,7 @@
         errorLine1="                    PredefinedChannel.create(ChannelId.WEBRTC_CAM_AND_MIC,"
         errorLine2="                                                       ~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/channels/ChromeChannelDefinitions.java"
+            file="../../chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/channels/ChromeChannelDefinitions.java"
             line="160"
             column="56"/>
     </issue>
@@ -3246,7 +2465,7 @@
         errorLine1="            map.put(ChannelId.VR,"
         errorLine2="                              ~~">
         <location
-            file="$SRC/chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/channels/ChromeChannelDefinitions.java"
+            file="../../chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/channels/ChromeChannelDefinitions.java"
             line="200"
             column="31"/>
     </issue>
@@ -3257,7 +2476,7 @@
         errorLine1="                    PredefinedChannel.create(ChannelId.VR, R.string.notification_category_vr,"
         errorLine2="                                                       ~~">
         <location
-            file="$SRC/chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/channels/ChromeChannelDefinitions.java"
+            file="../../chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/channels/ChromeChannelDefinitions.java"
             line="201"
             column="56"/>
     </issue>
@@ -3268,7 +2487,7 @@
         errorLine1="        assert MENU_IDS.length == Item.NUM_ENTRIES;"
         errorLine2="                                       ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuItem.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuItem.java"
             line="182"
             column="40"/>
     </issue>
@@ -3279,7 +2498,7 @@
         errorLine1="        assert STRING_IDS.length == Item.NUM_ENTRIES;"
         errorLine2="                                         ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuItem.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuItem.java"
             line="193"
             column="42"/>
     </issue>
@@ -3290,30 +2509,19 @@
         errorLine1="            RecordHistogram.recordEnumeratedHistogram(histogramName, action, Action.NUM_ENTRIES);"
         errorLine2="                                                                                    ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java"
-            line="259"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java"
+            line="257"
             column="85"/>
     </issue>
 
     <issue
         id="WrongConstant"
-        message="Must be one of: Action.OPEN_IN_NEW_TAB, Action.OPEN_IN_INCOGNITO_TAB, Action.COPY_LINK_ADDRESS, Action.COPY_EMAIL_ADDRESS, Action.COPY_LINK_TEXT, Action.SAVE_LINK, Action.SAVE_IMAGE, Action.OPEN_IMAGE, Action.OPEN_IMAGE_IN_NEW_TAB, Action.SEARCH_BY_IMAGE, Action.LOAD_ORIGINAL_IMAGE, Action.SAVE_VIDEO, Action.SHARE_IMAGE, Action.OPEN_IN_OTHER_WINDOW, Action.OPEN_IN_NEW_WINDOW, Action.SEND_EMAIL, Action.ADD_TO_CONTACTS, Action.CALL, Action.SEND_TEXT_MESSAGE, Action.COPY_PHONE_NUMBER, Action.OPEN_IN_NEW_CHROME_TAB, Action.OPEN_IN_CHROME_INCOGNITO_TAB, Action.OPEN_IN_BROWSER, Action.OPEN_IN_CHROME, Action.SHARE_LINK, Action.OPEN_IN_EPHEMERAL_TAB, Action.OPEN_IMAGE_IN_EPHEMERAL_TAB, Action.DIRECT_SHARE_LINK, Action.DIRECT_SHARE_IMAGE, Action.SEARCH_WITH_GOOGLE_LENS, Action.COPY_IMAGE, Action.SHOP_IMAGE_WITH_GOOGLE_LENS, Action.READ_LATER, Action.SHOP_WITH_GOOGLE_LENS_CHIP, Action.TRANSLATE_WITH_GOOGLE_LENS_CHIP, Action.SHARE_HIGHLIGHT, Action.REMOVE_HIGHLIGHT, Action.LEARN_MORE, Action.OPEN_IN_NEW_TAB_IN_GROUP"
-        errorLine1="                        histogramName + &quot;.PerformanceClassFast&quot;, action, Action.NUM_ENTRIES);"
-        errorLine2="                                                                                ~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java"
-            line="275"
-            column="81"/>
-    </issue>
-
-    <issue
-        id="WrongConstant"
         message="Must be one of: SelectedNewTabCreationEnum.OPEN_IN_NEW_TAB_FIRST_SELECTED_OPEN_IN_NEW_TAB, SelectedNewTabCreationEnum.OPEN_IN_NEW_TAB_FIRST_SELECTED_OPEN_IN_NEW_TAB_IN_GROUP, SelectedNewTabCreationEnum.OPEN_IN_NEW_TAB_IN_GROUP_FIRST_SELECTED_OPEN_IN_NEW_TAB, SelectedNewTabCreationEnum.OPEN_IN_NEW_TAB_IN_GROUP_FIRST_SELECTED_OPEN_IN_NEW_TAB_IN_GROUP"
         errorLine1="                    selectedNewTabCreationEnum, SelectedNewTabCreationEnum.NUM_ENTRIES);"
         errorLine2="                                                                           ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java"
-            line="304"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java"
+            line="294"
             column="76"/>
     </issue>
 
@@ -3323,8 +2531,8 @@
         errorLine1="                    &quot;MobileDownload.ContextMenu.SaveImage&quot;, type, TypeSaveImage.NUM_ENTRIES);"
         errorLine2="                                                                                ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java"
-            line="313"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java"
+            line="303"
             column="81"/>
     </issue>
 
@@ -3334,7 +2542,7 @@
         errorLine1="                availableStatus, UiAvailableTypes.NUM_ENTRIES);"
         errorLine2="                                                  ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ChromeLocalizationUtils.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/ChromeLocalizationUtils.java"
             line="133"
             column="51"/>
     </issue>
@@ -3345,7 +2553,7 @@
         errorLine1="                &quot;LanguageUsage.UI.Android.Correctness&quot;, correctStatus, UiCorrectTypes.NUM_ENTRIES);"
         errorLine2="                                                                                      ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ChromeLocalizationUtils.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/ChromeLocalizationUtils.java"
             line="140"
             column="87"/>
     </issue>
@@ -3356,7 +2564,7 @@
         errorLine1="                    UiCorrectTypes.NUM_ENTRIES);"
         errorLine2="                                   ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ChromeLocalizationUtils.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/ChromeLocalizationUtils.java"
             line="147"
             column="36"/>
     </issue>
@@ -3367,7 +2575,7 @@
         errorLine1="                    UiCorrectTypes.NUM_ENTRIES);"
         errorLine2="                                   ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ChromeLocalizationUtils.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/ChromeLocalizationUtils.java"
             line="154"
             column="36"/>
     </issue>
@@ -3378,7 +2586,7 @@
         errorLine1="                &quot;LanguageUsage.UI.Android.IsLocaleUpdated&quot;, status, LocaleUpdateStatus.NUM_ENTRIES);"
         errorLine2="                                                                                       ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ChromeLocalizationUtils.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/ChromeLocalizationUtils.java"
             line="262"
             column="88"/>
     </issue>
@@ -3389,8 +2597,8 @@
         errorLine1="                &quot;Android.Survey.SurveyFilteringResults&quot;, value, FilteringResult.NUM_ENTRIES);"
         errorLine2="                                                                                ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeSurveyController.java"
-            line="646"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeSurveyController.java"
+            line="649"
             column="81"/>
     </issue>
 
@@ -3400,8 +2608,8 @@
         errorLine1="                &quot;Android.Survey.InfoBarClosingState&quot;, value, InfoBarClosingState.NUM_ENTRIES);"
         errorLine2="                                                                                 ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeSurveyController.java"
-            line="651"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeSurveyController.java"
+            line="654"
             column="82"/>
     </issue>
 
@@ -3411,7 +2619,7 @@
         errorLine1="                    getTransitionType(type, intent, loadUrlParams.getTransitionType()));"
         errorLine2="                                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreator.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreator.java"
             line="153"
             column="53"/>
     </issue>
@@ -3422,8 +2630,8 @@
         errorLine1="                        IntentHandler.ExternalAppId.NUM_ENTRIES);"
         errorLine2="                                                    ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java"
-            line="532"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java"
+            line="539"
             column="53"/>
     </issue>
 
@@ -3433,8 +2641,8 @@
         errorLine1="                            intent, TabOpenType.REUSE_TAB_MATCHING_ID_STRING, Tab.INVALID_TAB_ID);"
         errorLine2="                                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java"
-            line="1487"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java"
+            line="1570"
             column="49"/>
     </issue>
 
@@ -3444,8 +2652,8 @@
         errorLine1="                                            intent, TabOpenType.REUSE_TAB_ORIGINAL_URL_STRING))) {"
         errorLine2="                                                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java"
-            line="1496"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java"
+            line="1579"
             column="65"/>
     </issue>
 
@@ -3455,8 +2663,8 @@
         errorLine1="        for (@DialogOption int i = DialogOption.CLEAR_HISTORY; i &lt; DialogOption.NUM_ENTRIES; i++) {"
         errorLine2="                                                                                ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/browsing_data/ClearBrowsingDataFragment.java"
-            line="227"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/browsing_data/ClearBrowsingDataFragment.java"
+            line="248"
             column="81"/>
     </issue>
 
@@ -3466,8 +2674,8 @@
         errorLine1="                        MyActivityNavigation.SEARCH_HISTORY, MyActivityNavigation.NUM_ENTRIES);"
         errorLine2="                                                                                  ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/browsing_data/ClearBrowsingDataFragmentBasic.java"
-            line="249"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/browsing_data/ClearBrowsingDataFragmentBasic.java"
+            line="209"
             column="83"/>
     </issue>
 
@@ -3477,8 +2685,8 @@
         errorLine1="                        MyActivityNavigation.NUM_ENTRIES);"
         errorLine2="                                             ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/browsing_data/ClearBrowsingDataFragmentBasic.java"
-            line="254"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/browsing_data/ClearBrowsingDataFragmentBasic.java"
+            line="214"
             column="46"/>
     </issue>
 
@@ -3488,8 +2696,8 @@
         errorLine1="                &quot;CustomTabs.PredictionStatus&quot;, outcome, PredictionStatus.NUM_ENTRIES);"
         errorLine2="                                                                         ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/customtabs/ClientManager.java"
-            line="419"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/customtabs/ClientManager.java"
+            line="460"
             column="74"/>
     </issue>
 
@@ -3499,8 +2707,8 @@
         errorLine1="                getWarmupState(session), CalledWarmup.NUM_ENTRIES);"
         errorLine2="                                                      ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/customtabs/ClientManager.java"
-            line="430"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/customtabs/ClientManager.java"
+            line="471"
             column="55"/>
     </issue>
 
@@ -3510,8 +2718,8 @@
         errorLine1="                &quot;CustomTabs.MayLaunchUrlType&quot;, value, MayLaunchUrlType.NUM_ENTRIES);"
         errorLine2="                                                                       ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/customtabs/ClientManager.java"
-            line="438"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/customtabs/ClientManager.java"
+            line="479"
             column="72"/>
     </issue>
 
@@ -3521,7 +2729,7 @@
         errorLine1="        if (ViewCompat.getLayoutDirection(this) == LAYOUT_DIRECTION_LTR) {"
         errorLine2="                                                   ~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/ClipDrawableProgressBar.java"
+            file="../../components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/ClipDrawableProgressBar.java"
             line="135"
             column="52"/>
     </issue>
@@ -3532,7 +2740,7 @@
         errorLine1="        assert status &lt; AnimationStatus.NUM_ENTRIES;"
         errorLine2="                                        ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/ClosableTabGridView.java"
+            file="../../chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/ClosableTabGridView.java"
             line="78"
             column="41"/>
     </issue>
@@ -3543,8 +2751,8 @@
         errorLine1="                HISTOGRAM_GET_FILES_RESULT, result, GetFilesResultCode.COUNT);"
         errorLine2="                                                                       ~~~~~">
         <location
-            file="$SRC/android_webview/nonembedded/java/src/org/chromium/android_webview/services/ComponentsProviderService.java"
-            line="327"
+            file="../../android_webview/nonembedded/java/src/org/chromium/android_webview/services/ComponentsProviderService.java"
+            line="330"
             column="72"/>
     </issue>
 
@@ -3554,7 +2762,7 @@
         errorLine1="                UMA_USER_STATUS_RESULT, userStatus, UserStatus.NUM_ENTRIES);"
         errorLine2="                                                               ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/tasks/ConditionalTabStripUtils.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/tasks/ConditionalTabStripUtils.java"
             line="166"
             column="64"/>
     </issue>
@@ -3565,7 +2773,7 @@
         errorLine1="                                    result, ProbeResult.RESULT_COUNT);"
         errorLine2="                                                        ~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/net/connectivitydetector/ConnectivityDetector.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/net/connectivitydetector/ConnectivityDetector.java"
             line="337"
             column="57"/>
     </issue>
@@ -3576,7 +2784,7 @@
         errorLine1="                                    result, ProbeResult.RESULT_COUNT);"
         errorLine2="                                                        ~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/net/connectivitydetector/ConnectivityDetector.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/net/connectivitydetector/ConnectivityDetector.java"
             line="341"
             column="57"/>
     </issue>
@@ -3587,7 +2795,7 @@
         errorLine1="                                mConnectionState, ConnectionState.RESULT_COUNT);"
         errorLine2="                                                                  ~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/net/connectivitydetector/ConnectivityDetector.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/net/connectivitydetector/ConnectivityDetector.java"
             line="350"
             column="67"/>
     </issue>
@@ -3598,7 +2806,7 @@
         errorLine1="        for (@Type int t = Type.CHROME_HTTP; t &lt; Type.NUM_ENTRIES; t++) {"
         errorLine2="                                                      ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/feedback/ConnectivityTask.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/feedback/ConnectivityTask.java"
             line="288"
             column="55"/>
     </issue>
@@ -3609,7 +2817,7 @@
         errorLine1="        return mResult.size() == Type.NUM_ENTRIES;"
         errorLine2="                                      ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/feedback/ConnectivityTask.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/feedback/ConnectivityTask.java"
             line="299"
             column="39"/>
     </issue>
@@ -3620,7 +2828,7 @@
         errorLine1="        for (@Type int type = Type.CHROME_HTTP; type &lt; Type.NUM_ENTRIES; type++) {"
         errorLine2="                                                            ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/feedback/ConnectivityTask.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/feedback/ConnectivityTask.java"
             line="313"
             column="61"/>
     </issue>
@@ -3631,7 +2839,7 @@
         errorLine1="                &quot;ContextMenu.LensChip.Event&quot;, chipEvent, ChipEvent.NUM_ENTRIES);"
         errorLine2="                                                                   ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuChipController.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuChipController.java"
             line="51"
             column="68"/>
     </issue>
@@ -3642,7 +2850,7 @@
         errorLine1="        for (@ContextMenuItemId int itemId = 0; itemId &lt; ContextMenuItemId.NUM_ENTRIES; itemId++) {"
         errorLine2="                                                                           ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/native_page/ContextMenuManager.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/native_page/ContextMenuManager.java"
             line="158"
             column="76"/>
     </issue>
@@ -3653,7 +2861,7 @@
         errorLine1="                getPreferenceValue(), ContextualSearchPreference.NUM_ENTRIES);"
         errorLine2="                                                                 ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchUma.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchUma.java"
             line="148"
             column="66"/>
     </issue>
@@ -3664,7 +2872,7 @@
         errorLine1="                ContextualSearchPreference.NUM_ENTRIES);"
         errorLine2="                                           ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchUma.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchUma.java"
             line="168"
             column="44"/>
     </issue>
@@ -3675,8 +2883,8 @@
         errorLine1="                wasPanelSeen ? Results.SEEN : Results.NOT_SEEN, Results.NUM_ENTRIES);"
         errorLine2="                                                                        ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchUma.java"
-            line="232"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchUma.java"
+            line="213"
             column="73"/>
     </issue>
 
@@ -3686,8 +2894,8 @@
         errorLine1="                code, QuickActionResolve.NUM_ENTRIES);"
         errorLine2="                                         ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchUma.java"
-            line="488"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchUma.java"
+            line="458"
             column="42"/>
     </issue>
 
@@ -3697,8 +2905,8 @@
         errorLine1="                wasSeen ? Results.SEEN : Results.NOT_SEEN, Results.NUM_ENTRIES);"
         errorLine2="                                                                   ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchUma.java"
-            line="513"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchUma.java"
+            line="483"
             column="68"/>
     </issue>
 
@@ -3708,8 +2916,8 @@
         errorLine1="                    &quot;Search.ContextualSearch.CardTagSeen&quot;, cardTagEnum, CardTag.NUM_ENTRIES);"
         errorLine2="                                                                                ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchUma.java"
-            line="538"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchUma.java"
+            line="508"
             column="81"/>
     </issue>
 
@@ -3719,8 +2927,8 @@
         errorLine1="                &quot;Search.ContextualSearch.CardTag&quot;, cardTagEnum, CardTag.NUM_ENTRIES);"
         errorLine2="                                                                        ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchUma.java"
-            line="541"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchUma.java"
+            line="511"
             column="73"/>
     </issue>
 
@@ -3730,18 +2938,18 @@
         errorLine1="                getPanelSeenByGestureStateCode(wasPanelSeen, wasTap), ResultsByGesture.NUM_ENTRIES);"
         errorLine2="                                                                                       ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchUma.java"
-            line="607"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchUma.java"
+            line="583"
             column="88"/>
     </issue>
 
     <issue
         id="WrongConstant"
-        message="Must be one of: CrashKeyIndex.LOADED_DYNAMIC_MODULE, CrashKeyIndex.ACTIVE_DYNAMIC_MODULE, CrashKeyIndex.APPLICATION_STATUS, CrashKeyIndex.INSTALLED_MODULES, CrashKeyIndex.EMULATED_MODULES, CrashKeyIndex.DYNAMIC_MODULE_DEX_NAME, CrashKeyIndex.PARTNER_CUSTOMIZATION_CONFIG"
+        message="Must be one of: CrashKeyIndex.LOADED_DYNAMIC_MODULE, CrashKeyIndex.ACTIVE_DYNAMIC_MODULE, CrashKeyIndex.APPLICATION_STATUS, CrashKeyIndex.INSTALLED_MODULES, CrashKeyIndex.EMULATED_MODULES, CrashKeyIndex.DYNAMIC_MODULE_DEX_NAME, CrashKeyIndex.PARTNER_CUSTOMIZATION_CONFIG, CrashKeyIndex.FIRST_RUN"
         errorLine1="        assert CrashKeyIndex.NUM_ENTRIES == KEYS.length;"
         errorLine2="                             ~~~~~~~~~~~">
         <location
-            file="$SRC/components/crash/android/java/src/org/chromium/components/crash/CrashKeys.java"
+            file="../../components/crash/android/java/src/org/chromium/components/crash/CrashKeys.java"
             line="38"
             column="30"/>
     </issue>
@@ -3752,8 +2960,8 @@
         errorLine1="                &quot;Android.WebView.DevUi.CrashList.CollectionState&quot;, state, CollectionState.COUNT);"
         errorLine2="                                                                                          ~~~~~">
         <location
-            file="$SRC/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/CrashesListFragment.java"
-            line="106"
+            file="../../android_webview/nonembedded/java/src/org/chromium/android_webview/devui/CrashesListFragment.java"
+            line="107"
             column="91"/>
     </issue>
 
@@ -3763,8 +2971,8 @@
         errorLine1="                &quot;Android.WebView.DevUi.CrashList.CrashInteraction&quot;, action, CrashInteraction.COUNT);"
         errorLine2="                                                                                             ~~~~~">
         <location
-            file="$SRC/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/CrashesListFragment.java"
-            line="130"
+            file="../../android_webview/nonembedded/java/src/org/chromium/android_webview/devui/CrashesListFragment.java"
+            line="131"
             column="94"/>
     </issue>
 
@@ -3774,7 +2982,7 @@
         errorLine1="                    status, ConnectionStatus.NUM_ENTRIES);"
         errorLine2="                                             ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivityClientConnectionKeeper.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivityClientConnectionKeeper.java"
             line="101"
             column="46"/>
     </issue>
@@ -3785,7 +2993,7 @@
         errorLine1="                    status, ConnectionStatus.NUM_ENTRIES);"
         errorLine2="                                             ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivityClientConnectionKeeper.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivityClientConnectionKeeper.java"
             line="104"
             column="46"/>
     </issue>
@@ -3796,8 +3004,8 @@
         errorLine1="                incognitoCCTCallerId, IntentHandler.IncognitoCCTCallerId.NUM_ENTRIES);"
         errorLine2="                                                                         ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivityLifecycleUmaTracker.java"
-            line="48"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivityLifecycleUmaTracker.java"
+            line="77"
             column="74"/>
     </issue>
 
@@ -3807,8 +3015,8 @@
         errorLine1="                        externalId, IntentHandler.ExternalAppId.NUM_ENTRIES);"
         errorLine2="                                                                ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivityLifecycleUmaTracker.java"
-            line="57"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivityLifecycleUmaTracker.java"
+            line="86"
             column="65"/>
     </issue>
 
@@ -3818,8 +3026,8 @@
         errorLine1="                        externalId, IntentHandler.ExternalAppId.NUM_ENTRIES);"
         errorLine2="                                                                ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivityLifecycleUmaTracker.java"
-            line="64"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivityLifecycleUmaTracker.java"
+            line="93"
             column="65"/>
     </issue>
 
@@ -3829,8 +3037,8 @@
         errorLine1="                    &quot;CustomTabs.ClientAppId&quot;, externalId, IntentHandler.ExternalAppId.NUM_ENTRIES);"
         errorLine2="                                                                                      ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivityLifecycleUmaTracker.java"
-            line="85"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivityLifecycleUmaTracker.java"
+            line="114"
             column="87"/>
     </issue>
 
@@ -3840,8 +3048,8 @@
         errorLine1="                WebContentsState.PRERENDERED_WEBCONTENTS, WebContentsState.NUM_ENTRIES);"
         errorLine2="                                                                           ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabController.java"
-            line="337"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabController.java"
+            line="345"
             column="76"/>
     </issue>
 
@@ -3851,8 +3059,8 @@
         errorLine1="                webContentsStateOnLaunch, WebContentsState.NUM_ENTRIES);"
         errorLine2="                                                           ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabController.java"
-            line="363"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabController.java"
+            line="371"
             column="60"/>
     </issue>
 
@@ -3862,8 +3070,8 @@
         errorLine1="                ParallelRequestStatus.NUM_ENTRIES);"
         errorLine2="                                      ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java"
-            line="899"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java"
+            line="943"
             column="39"/>
     </issue>
 
@@ -3873,8 +3081,8 @@
         errorLine1="                &quot;CustomTabs.CloseCause&quot;, mCloseCause, CloseCause.COUNT);"
         errorLine2="                                                                 ~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsOpenTimeRecorder.java"
-            line="77"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsOpenTimeRecorder.java"
+            line="83"
             column="66"/>
     </issue>
 
@@ -3884,7 +3092,7 @@
         errorLine1="                &quot;Download.DangerousDialog.Events&quot;, event, DangerousDownloadDialogEvent.COUNT);"
         errorLine2="                                                                                       ~~~~~">
         <location
-            file="$SRC/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/DangerousDownloadDialog.java"
+            file="../../chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/DangerousDownloadDialog.java"
             line="131"
             column="88"/>
     </issue>
@@ -3895,7 +3103,7 @@
         errorLine1="                            getDefaultBrowserUmaState(info), MobileDefaultBrowserState.NUM_ENTRIES);"
         errorLine2="                                                                                       ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/DefaultBrowserInfo.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/DefaultBrowserInfo.java"
             line="197"
             column="88"/>
     </issue>
@@ -3906,7 +3114,7 @@
         errorLine1="        record(DirectActionId.UNKNOWN);"
         errorLine2="               ~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/directactions/DirectActionUsageHistogram.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/directactions/DirectActionUsageHistogram.java"
             line="81"
             column="16"/>
     </issue>
@@ -3917,7 +3125,7 @@
         errorLine1="        record(DirectActionId.UNKNOWN);"
         errorLine2="                              ~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/directactions/DirectActionUsageHistogram.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/directactions/DirectActionUsageHistogram.java"
             line="81"
             column="31"/>
     </issue>
@@ -3928,7 +3136,7 @@
         errorLine1="        if (histogramId == null) histogramId = DirectActionId.OTHER;"
         errorLine2="                                                              ~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/directactions/DirectActionUsageHistogram.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/directactions/DirectActionUsageHistogram.java"
             line="92"
             column="63"/>
     </issue>
@@ -3939,7 +3147,7 @@
         errorLine1="        record(histogramId);"
         errorLine2="               ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/directactions/DirectActionUsageHistogram.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/directactions/DirectActionUsageHistogram.java"
             line="94"
             column="16"/>
     </issue>
@@ -3950,7 +3158,7 @@
         errorLine1="        record(histogramId);"
         errorLine2="               ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/directactions/DirectActionUsageHistogram.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/directactions/DirectActionUsageHistogram.java"
             line="94"
             column="16"/>
     </issue>
@@ -3961,7 +3169,7 @@
         errorLine1="                        NotificationUmaTracker.ActionType.TWA_NOTIFICATION_ACCEPTANCE)"
         errorLine2="                                                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/view/DisclosureNotification.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/view/DisclosureNotification.java"
             line="130"
             column="59"/>
     </issue>
@@ -3972,62 +3180,18 @@
         errorLine1="                DirectoryOption.DownloadLocationDirectoryType.NUM_ENTRIES);"
         errorLine2="                                                              ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/DownloadDirectoryProvider.java"
+            file="../../chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/DownloadDirectoryProvider.java"
             line="357"
             column="63"/>
     </issue>
 
     <issue
         id="WrongConstant"
-        message="Must be one of: DownloadLaterDialogChoice.DOWNLOAD_NOW, DownloadLaterDialogChoice.ON_WIFI, DownloadLaterDialogChoice.DOWNLOAD_LATER, DownloadLaterDialogChoice.CANCELLED"
-        errorLine1="                &quot;Download.Later.UI.DialogChoice.Main&quot;, choice, DownloadLaterDialogChoice.COUNT);"
-        errorLine2="                                                                                         ~~~~~">
-        <location
-            file="$SRC/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/DownloadLaterMetrics.java"
-            line="66"
-            column="90"/>
-    </issue>
-
-    <issue
-        id="WrongConstant"
-        message="Must be one of: DownloadLaterDialogChoice.DOWNLOAD_NOW, DownloadLaterDialogChoice.ON_WIFI, DownloadLaterDialogChoice.DOWNLOAD_LATER, DownloadLaterDialogChoice.CANCELLED"
-        errorLine1="                choice, DownloadLaterDialogChoice.COUNT);"
-        errorLine2="                                                  ~~~~~">
-        <location
-            file="$SRC/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/DownloadLaterMetrics.java"
-            line="87"
-            column="51"/>
-    </issue>
-
-    <issue
-        id="WrongConstant"
-        message="Must be one of: DownloadLaterDialogChoice.DOWNLOAD_NOW, DownloadLaterDialogChoice.ON_WIFI, DownloadLaterDialogChoice.DOWNLOAD_LATER, DownloadLaterDialogChoice.CANCELLED"
-        errorLine1="                &quot;Download.Later.UI.DialogChoice.Infobar&quot;, choice, DownloadLaterDialogChoice.COUNT);"
-        errorLine2="                                                                                            ~~~~~">
-        <location
-            file="$SRC/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/DownloadLaterMetrics.java"
-            line="97"
-            column="93"/>
-    </issue>
-
-    <issue
-        id="WrongConstant"
-        message="Must be one of: DownloadLaterUiEvent.DOWNLOAD_LATER_DIALOG_SHOW, DownloadLaterUiEvent.DOWNLOAD_LATER_DIALOG_COMPLETE, DownloadLaterUiEvent.DOWNLOAD_LATER_DIALOG_CANCEL, DownloadLaterUiEvent.DATE_TIME_PICKER_SHOW, DownloadLaterUiEvent.DATE_TIME_PICKER_COMPLETE, DownloadLaterUiEvent.DATE_TIME_PICKER_CANCEL, DownloadLaterUiEvent.DOWNLOAD_HOME_CHANGE_SCHEDULE_CLICKED, DownloadLaterUiEvent.DOWNLOAD_HOME_CHANGE_SCHEDULE_COMPLETE, DownloadLaterUiEvent.DOWNLOAD_HOME_CHANGE_SCHEDULE_CANCEL, DownloadLaterUiEvent.DOWNLOAD_INFOBAR_CHANGE_SCHEDULE_CLICKED, DownloadLaterUiEvent.DOWNLOAD_INFOBAR_CHANGE_SCHEDULE_COMPLETE, DownloadLaterUiEvent.DOWNLOAD_INFOBAR_CHANGE_SCHEDULE_CANCEL, DownloadLaterUiEvent.DOWNLOAD_LATER_DIALOG_EDIT_CLICKED"
-        errorLine1="                &quot;Download.Later.UI.Events&quot;, event, DownloadLaterUiEvent.COUNT);"
-        errorLine2="                                                                        ~~~~~">
-        <location
-            file="$SRC/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/DownloadLaterMetrics.java"
-            line="107"
-            column="73"/>
-    </issue>
-
-    <issue
-        id="WrongConstant"
         message="Must be one of: DownloadLocationDirectoryType.DEFAULT, DownloadLocationDirectoryType.ADDITIONAL, DownloadLocationDirectoryType.ERROR"
         errorLine1="                directoryOption.type, DirectoryOption.DownloadLocationDirectoryType.NUM_ENTRIES);"
         errorLine2="                                                                                    ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/DownloadLocationDialogCoordinator.java"
+            file="../../chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/DownloadLocationDialogCoordinator.java"
             line="280"
             column="85"/>
     </issue>
@@ -4038,7 +3202,7 @@
         errorLine1="                DownloadLocationSuggestionEvent.COUNT);"
         errorLine2="                                                ~~~~~">
         <location
-            file="$SRC/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/DownloadLocationDialogMetrics.java"
+            file="../../chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/DownloadLocationDialogMetrics.java"
             line="50"
             column="49"/>
     </issue>
@@ -4049,7 +3213,7 @@
         errorLine1="                option.type, DirectoryOption.DownloadLocationDirectoryType.NUM_ENTRIES);"
         errorLine2="                                                                           ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/settings/DownloadLocationPreferenceAdapter.java"
+            file="../../chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/settings/DownloadLocationPreferenceAdapter.java"
             line="106"
             column="76"/>
     </issue>
@@ -4060,8 +3224,8 @@
         errorLine1="        int state = downloadItem.getDownloadInfo().state();"
         errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java"
-            line="1419"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java"
+            line="1381"
             column="21"/>
     </issue>
 
@@ -4071,8 +3235,8 @@
         errorLine1="        return (state == DownloadState.INTERRUPTED &amp;&amp; !downloadItem.getDownloadInfo().isResumable())"
         errorLine2="                ~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java"
-            line="1420"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java"
+            line="1382"
             column="17"/>
     </issue>
 
@@ -4082,8 +3246,8 @@
         errorLine1="                || state == DownloadState.CANCELLED;"
         errorLine2="                   ~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java"
-            line="1421"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java"
+            line="1383"
             column="20"/>
     </issue>
 
@@ -4093,7 +3257,7 @@
         errorLine1="                                    DirectoryOption.DownloadLocationDirectoryType.NUM_ENTRIES);"
         errorLine2="                                                                                  ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadMetrics.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/download/DownloadMetrics.java"
             line="106"
             column="83"/>
     </issue>
@@ -4104,7 +3268,7 @@
         errorLine1="                    ServiceStopped.NUM_ENTRIES);"
         errorLine2="                                   ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationUmaHelper.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationUmaHelper.java"
             line="115"
             column="36"/>
     </issue>
@@ -4115,7 +3279,7 @@
         errorLine1="                ForegroundLifecycle.NUM_ENTRIES);"
         errorLine2="                                    ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationUmaHelper.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationUmaHelper.java"
             line="127"
             column="37"/>
     </issue>
@@ -4126,7 +3290,7 @@
         errorLine1="                    StateAtCancel.NUM_ENTRIES);"
         errorLine2="                                  ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationUmaHelper.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationUmaHelper.java"
             line="141"
             column="35"/>
     </issue>
@@ -4137,7 +3301,7 @@
         errorLine1="                    StateAtCancel.NUM_ENTRIES);"
         errorLine2="                                  ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationUmaHelper.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationUmaHelper.java"
             line="145"
             column="35"/>
     </issue>
@@ -4148,29 +3312,18 @@
         errorLine1="                &quot;MobileDownload.DownloadResumption&quot;, type, UmaDownloadResumption.NUM_ENTRIES);"
         errorLine2="                                                                                 ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationUmaHelper.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationUmaHelper.java"
             line="155"
             column="82"/>
     </issue>
 
     <issue
         id="WrongConstant"
-        message="Must be one of: OmniboxSuggestionUiType.DEFAULT, OmniboxSuggestionUiType.EDIT_URL_SUGGESTION, OmniboxSuggestionUiType.ANSWER_SUGGESTION, OmniboxSuggestionUiType.ENTITY_SUGGESTION, OmniboxSuggestionUiType.TAIL_SUGGESTION, OmniboxSuggestionUiType.CLIPBOARD_SUGGESTION, OmniboxSuggestionUiType.TILE_SUGGESTION, OmniboxSuggestionUiType.TILE_NAVSUGGEST, OmniboxSuggestionUiType.PEDAL_SUGGESTION"
-        errorLine1="        return (info.type == OmniboxSuggestionUiType.HEADER &amp;&amp; info.groupId == groupId);"
-        errorLine2="                                                     ~~~~~~">
-        <location
-            file="$SRC/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/DropdownItemViewInfoListManager.java"
-            line="98"
-            column="54"/>
-    </issue>
-
-    <issue
-        id="WrongConstant"
         message="Must be one of: DuplicateDownloadDialogEvent.DUPLICATE_DOWNLOAD_DIALOG_SHOW, DuplicateDownloadDialogEvent.DUPLICATE_DOWNLOAD_DIALOG_CONFIRM, DuplicateDownloadDialogEvent.DUPLICATE_DOWNLOAD_DIALOG_CANCEL, DuplicateDownloadDialogEvent.DUPLICATE_DOWNLOAD_DIALOG_LINK_CLICKED, DuplicateDownloadDialogEvent.DUPLICATE_DOWNLOAD_DIALOG_DISMISS"
         errorLine1="                event, DuplicateDownloadDialogEvent.COUNT);"
         errorLine2="                                                    ~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/download/DuplicateDownloadDialog.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/download/DuplicateDownloadDialog.java"
             line="188"
             column="53"/>
     </issue>
@@ -4181,7 +3334,7 @@
         errorLine1="                ExploreSitesCatalogUpdateRequestSource.NUM_ENTRIES);"
         errorLine2="                                                       ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesBackgroundTask.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesBackgroundTask.java"
             line="74"
             column="56"/>
     </issue>
@@ -4192,52 +3345,19 @@
         errorLine1="                ExploreSitesCategory.CategoryType.NUM_ENTRIES);"
         errorLine2="                                                  ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryCardView.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryCardView.java"
             line="293"
             column="51"/>
     </issue>
 
     <issue
         id="WrongConstant"
-        message="Must be one of: AiaIntent.FALLBACK_USED, AiaIntent.SERP, AiaIntent.OTHER"
-        errorLine1="                    AiaIntent.FALLBACK_USED, AiaIntent.NUM_ENTRIES);"
-        errorLine2="                                                       ~~~~~~~~~~~">
-        <location
-            file="$SRC/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalNavigationHandler.java"
-            line="428"
-            column="56"/>
-    </issue>
-
-    <issue
-        id="WrongConstant"
-        message="Must be one of: AiaIntent.FALLBACK_USED, AiaIntent.SERP, AiaIntent.OTHER"
-        errorLine1="                AiaIntent.OTHER, AiaIntent.NUM_ENTRIES);"
-        errorLine2="                                           ~~~~~~~~~~~">
-        <location
-            file="$SRC/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalNavigationHandler.java"
-            line="1086"
-            column="44"/>
-    </issue>
-
-    <issue
-        id="WrongConstant"
-        message="Must be one of: AiaIntent.FALLBACK_USED, AiaIntent.SERP, AiaIntent.OTHER"
-        errorLine1="                    AiaIntent.SERP, AiaIntent.NUM_ENTRIES);"
-        errorLine2="                                              ~~~~~~~~~~~">
-        <location
-            file="$SRC/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalNavigationHandler.java"
-            line="1118"
-            column="47"/>
-    </issue>
-
-    <issue
-        id="WrongConstant"
         message="Must be one of: StreamTabId.DEFAULT, StreamTabId.FOR_YOU, StreamTabId.FOLLOWING"
         errorLine1="        if (mTabToStreamMap.size() &lt;= tabId) tabId = 0;"
         errorLine2="                                                     ~">
         <location
-            file="$SRC/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java"
-            line="372"
+            file="../../chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java"
+            line="434"
             column="54"/>
     </issue>
 
@@ -4247,8 +3367,8 @@
         errorLine1="        mSectionHeaderModel.set(SectionHeaderListProperties.CURRENT_TAB_INDEX_KEY, tabId);"
         errorLine2="                                                                                   ~~~~~">
         <location
-            file="$SRC/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java"
-            line="373"
+            file="../../chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java"
+            line="435"
             column="84"/>
     </issue>
 
@@ -4258,8 +3378,8 @@
         errorLine1="                    storageRequest.getStorageRequestType(), StorageRequestType.NUM_ENTRIES);"
         errorLine2="                                                                               ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/FilePersistedTabDataStorage.java"
-            line="557"
+            file="../../chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/FilePersistedTabDataStorage.java"
+            line="605"
             column="80"/>
     </issue>
 
@@ -4269,7 +3389,7 @@
         errorLine1="                &quot;Android.DownloadManager.Filter&quot;, selectedTab, DownloadFilter.Type.NUM_ENTRIES);"
         errorLine2="                                                                                   ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/metrics/FilterChangeLogger.java"
+            file="../../chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/metrics/FilterChangeLogger.java"
             line="24"
             column="84"/>
     </issue>
@@ -4280,7 +3400,7 @@
         errorLine1="            if (filter &lt; 0 || filter >= FilterType.NUM_ENTRIES) filter = FilterType.NONE;"
         errorLine2="                                                   ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/filter/Filters.java"
+            file="../../chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/filter/Filters.java"
             line="104"
             column="52"/>
     </issue>
@@ -4291,8 +3411,8 @@
         errorLine1="            return LayoutType.COUNT;"
         errorLine2="                              ~~~~~">
         <location
-            file="$SRC/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/FlagsFragment.java"
-            line="507"
+            file="../../android_webview/nonembedded/java/src/org/chromium/android_webview/devui/FlagsFragment.java"
+            line="513"
             column="31"/>
     </issue>
 
@@ -4302,29 +3422,18 @@
         errorLine1="                &quot;GCM.WebPushReceived.DeviceState&quot;, state, WebPushDeviceState.NUM_ENTRIES);"
         errorLine2="                                                                             ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/GcmUma.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/services/gcm/GcmUma.java"
             line="63"
             column="78"/>
     </issue>
 
     <issue
         id="WrongConstant"
-        message="Must be one of: UmaPermission.UNKNOWN, UmaPermission.HIGH_ACCURACY_APP_YES_DOMAIN_YES_LOCATION, UmaPermission.HIGH_ACCURACY_APP_YES_DOMAIN_YES_NO_LOCATION, UmaPermission.HIGH_ACCURACY_APP_YES_DOMAIN_PROMPT_LOCATION, UmaPermission.HIGH_ACCURACY_APP_YES_DOMAIN_PROMPT_NO_LOCATION, UmaPermission.HIGH_ACCURACY_APP_YES_DOMAIN_BLOCKED, UmaPermission.HIGH_ACCURACY_APP_PROMPT_DOMAIN_YES, UmaPermission.HIGH_ACCURACY_APP_PROMPT_DOMAIN_PROMPT, UmaPermission.HIGH_ACCURACY_APP_PROMPT_DOMAIN_BLOCKED, UmaPermission.HIGH_ACCURACY_APP_BLOCKED_DOMAIN_YES, UmaPermission.HIGH_ACCURACY_APP_BLOCKED_DOMAIN_PROMPT, UmaPermission.HIGH_ACCURACY_APP_BLOCKED_DOMAIN_BLOCKED, UmaPermission.BATTERY_SAVING_APP_YES_DOMAIN_YES_LOCATION, UmaPermission.BATTERY_SAVING_APP_YES_DOMAIN_YES_NO_LOCATION, UmaPermission.BATTERY_SAVING_APP_YES_DOMAIN_PROMPT_LOCATION, UmaPermission.BATTERY_SAVING_APP_YES_DOMAIN_PROMPT_NO_LOCATION, UmaPermission.BATTERY_SAVING_APP_YES_DOMAIN_BLOCKED, UmaPermission.BATTERY_SAVING_APP_PROMPT_DOMAIN_YES, UmaPermission.BATTERY_SAVING_APP_PROMPT_DOMAIN_PROMPT, UmaPermission.BATTERY_SAVING_APP_PROMPT_DOMAIN_BLOCKED, UmaPermission.BATTERY_SAVING_APP_BLOCKED_DOMAIN_YES, UmaPermission.BATTERY_SAVING_APP_BLOCKED_DOMAIN_PROMPT, UmaPermission.BATTERY_SAVING_APP_BLOCKED_DOMAIN_BLOCKED, UmaPermission.GPS_ONLY_APP_YES_DOMAIN_YES_LOCATION, UmaPermission.GPS_ONLY_APP_YES_DOMAIN_YES_NO_LOCATION, UmaPermission.GPS_ONLY_APP_YES_DOMAIN_PROMPT_LOCATION, UmaPermission.GPS_ONLY_APP_YES_DOMAIN_PROMPT_NO_LOCATION, UmaPermission.GPS_ONLY_APP_YES_DOMAIN_BLOCKED, UmaPermission.GPS_ONLY_APP_PROMPT_DOMAIN_YES, UmaPermission.GPS_ONLY_APP_PROMPT_DOMAIN_PROMPT, UmaPermission.GPS_ONLY_APP_PROMPT_DOMAIN_BLOCKED, UmaPermission.GPS_ONLY_APP_BLOCKED_DOMAIN_YES, UmaPermission.GPS_ONLY_APP_BLOCKED_DOMAIN_PROMPT, UmaPermission.GPS_ONLY_APP_BLOCKED_DOMAIN_BLOCKED, UmaPermission.LOCATION_OFF_APP_YES_DOMAIN_YES, UmaPermission.LOCATION_OFF_APP_YES_DOMAIN_PROMPT, UmaPermission.LOCATION_OFF_APP_YES_DOMAIN_BLOCKED, UmaPermission.LOCATION_OFF_APP_PROMPT_DOMAIN_YES, UmaPermission.LOCATION_OFF_APP_PROMPT_DOMAIN_PROMPT, UmaPermission.LOCATION_OFF_APP_PROMPT_DOMAIN_BLOCKED, UmaPermission.LOCATION_OFF_APP_BLOCKED_DOMAIN_YES, UmaPermission.LOCATION_OFF_APP_BLOCKED_DOMAIN_PROMPT, UmaPermission.LOCATION_OFF_APP_BLOCKED_DOMAIN_BLOCKED, UmaPermission.UNSUITABLE_URL, UmaPermission.NOT_HTTPS"
-        errorLine1="                &quot;Geolocation.Header.PermissionState&quot;, result, UmaPermission.NUM_ENTRIES);"
-        errorLine2="                                                                            ~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeader.java"
-            line="718"
-            column="77"/>
-    </issue>
-
-    <issue
-        id="WrongConstant"
         message="Must be one of: GestureNavigationDirection.BACK, GestureNavigationDirection.FORWARD"
         errorLine1="                GestureNavigationDirection.NUM_ENTRIES);"
         errorLine2="                                           ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/GestureNavMetrics.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/gesturenav/GestureNavMetrics.java"
             line="52"
             column="44"/>
     </issue>
@@ -4335,7 +3444,7 @@
         errorLine1="                IS_SYSTEM_LANGUAGE_HISTOGRAM, status, OverrideLanguageStatus.NUM_ENTRIES);"
         errorLine2="                                                                             ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/GlobalAppLocaleController.java"
+            file="../../chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/GlobalAppLocaleController.java"
             line="154"
             column="78"/>
     </issue>
@@ -4346,29 +3455,18 @@
         errorLine1="                return detail.rendererPriority();"
         errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/android_webview/glue/java/src/com/android/webview/chromium/GlueApiHelperForO.java"
+            file="../../android_webview/glue/java/src/com/android/webview/chromium/GlueApiHelperForO.java"
             line="45"
             column="24"/>
     </issue>
 
     <issue
         id="WrongConstant"
-        message="Must be one of: OmniboxSuggestionUiType.DEFAULT, OmniboxSuggestionUiType.EDIT_URL_SUGGESTION, OmniboxSuggestionUiType.ANSWER_SUGGESTION, OmniboxSuggestionUiType.ENTITY_SUGGESTION, OmniboxSuggestionUiType.TAIL_SUGGESTION, OmniboxSuggestionUiType.CLIPBOARD_SUGGESTION, OmniboxSuggestionUiType.TILE_SUGGESTION, OmniboxSuggestionUiType.TILE_NAVSUGGEST, OmniboxSuggestionUiType.PEDAL_SUGGESTION"
-        errorLine1="        return OmniboxSuggestionUiType.HEADER;"
-        errorLine2="                                       ~~~~~~">
-        <location
-            file="$SRC/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/header/HeaderProcessor.java"
-            line="36"
-            column="40"/>
-    </issue>
-
-    <issue
-        id="WrongConstant"
         message="Must be one of: HomepageLocationType.POLICY_NTP, HomepageLocationType.POLICY_OTHER, HomepageLocationType.PARTNER_PROVIDED_NTP, HomepageLocationType.PARTNER_PROVIDED_OTHER, HomepageLocationType.USER_CUSTOMIZED_NTP, HomepageLocationType.USER_CUSTOMIZED_OTHER, HomepageLocationType.DEFAULT_NTP"
         errorLine1="                homepageLocationType, HomepageLocationType.NUM_ENTRIES);"
         errorLine2="                                                           ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/homepage/HomepageManager.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/homepage/HomepageManager.java"
             line="308"
             column="60"/>
     </issue>
@@ -4379,8 +3477,8 @@
         errorLine1="    private ProfileDataCache mProfileDataCache[] = new ProfileDataCache[IdentityDiscState.MAX];"
         errorLine2="                                                                                          ~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/identity_disc/IdentityDiscController.java"
-            line="81"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/identity_disc/IdentityDiscController.java"
+            line="83"
             column="91"/>
     </issue>
 
@@ -4390,8 +3488,8 @@
         errorLine1="        for (int i = 0; i &lt; IdentityDiscState.MAX; i++) {"
         errorLine2="                                              ~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/identity_disc/IdentityDiscController.java"
-            line="221"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/identity_disc/IdentityDiscController.java"
+            line="229"
             column="47"/>
     </issue>
 
@@ -4401,8 +3499,8 @@
         errorLine1="        for (int i = 0; i &lt; IdentityDiscState.MAX; i++) {"
         errorLine2="                                              ~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/identity_disc/IdentityDiscController.java"
-            line="287"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/identity_disc/IdentityDiscController.java"
+            line="295"
             column="47"/>
     </issue>
 
@@ -4412,7 +3510,7 @@
         errorLine1="                action, ImageDescriptionsDialogAction.NUM_ENTRIES);"
         errorLine2="                                                      ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/image_descriptions/android/java/src/org/chromium/chrome/browser/image_descriptions/ImageDescriptionsDialog.java"
+            file="../../chrome/browser/image_descriptions/android/java/src/org/chromium/chrome/browser/image_descriptions/ImageDescriptionsDialog.java"
             line="274"
             column="55"/>
     </issue>
@@ -4423,8 +3521,8 @@
         errorLine1="                    &amp;&amp; incognitoCCTChromeClientId &lt; IntentHandler.IncognitoCCTCallerId.NUM_ENTRIES);"
         errorLine2="                                                                                       ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/customtabs/IncognitoCustomTabIntentDataProvider.java"
-            line="179"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/customtabs/IncognitoCustomTabIntentDataProvider.java"
+            line="177"
             column="88"/>
     </issue>
 
@@ -4434,8 +3532,8 @@
         errorLine1="                &quot;MobileIntent.PageLoadDueToExternalApp&quot;, externalId, ExternalAppId.NUM_ENTRIES);"
         errorLine2="                                                                                   ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java"
-            line="486"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java"
+            line="520"
             column="84"/>
     </issue>
 
@@ -4445,8 +3543,8 @@
         errorLine1="                intent, TabOpenType.REUSE_TAB_MATCHING_ID_STRING, Tab.INVALID_TAB_ID);"
         errorLine2="                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java"
-            line="1105"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java"
+            line="1158"
             column="37"/>
     </issue>
 
@@ -4456,7 +3554,7 @@
         errorLine1="                INITIATION_STATUS_HISTOGRAM, initStatus, ULPInitiationStatus.NUM_ENTRIES);"
         errorLine2="                                                                             ~~~~~~~~~~~">
         <location
-            file="$SRC/components/language/android/java/src/org/chromium/components/language/LanguageProfileMetricsLogger.java"
+            file="../../components/language/android/java/src/org/chromium/components/language/LanguageProfileMetricsLogger.java"
             line="46"
             column="78"/>
     </issue>
@@ -4467,7 +3565,7 @@
         errorLine1="                    initStatus, ULPInitiationStatus.NUM_ENTRIES);"
         errorLine2="                                                    ~~~~~~~~~~~">
         <location
-            file="$SRC/components/language/android/java/src/org/chromium/components/language/LanguageProfileMetricsLogger.java"
+            file="../../components/language/android/java/src/org/chromium/components/language/LanguageProfileMetricsLogger.java"
             line="49"
             column="53"/>
     </issue>
@@ -4478,7 +3576,7 @@
         errorLine1="                    initStatus, ULPInitiationStatus.NUM_ENTRIES);"
         errorLine2="                                                    ~~~~~~~~~~~">
         <location
-            file="$SRC/components/language/android/java/src/org/chromium/components/language/LanguageProfileMetricsLogger.java"
+            file="../../components/language/android/java/src/org/chromium/components/language/LanguageProfileMetricsLogger.java"
             line="52"
             column="53"/>
     </issue>
@@ -4489,7 +3587,7 @@
         errorLine1="                enumCode, LanguageSplitInstallStatus.NUM_ENTRIES);"
         errorLine2="                                                     ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/LanguageSplitInstaller.java"
+            file="../../chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/LanguageSplitInstaller.java"
             line="197"
             column="54"/>
     </issue>
@@ -4500,7 +3598,7 @@
         errorLine1="                &quot;LanguageSettings.PageImpression&quot;, pageType, LanguageSettingsPageType.NUM_ENTRIES);"
         errorLine2="                                                                                      ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/LanguagesManager.java"
+            file="../../chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/LanguagesManager.java"
             line="398"
             column="87"/>
     </issue>
@@ -4511,7 +3609,7 @@
         errorLine1="                &quot;LanguageSettings.Actions&quot;, actionType, LanguageSettingsActionType.NUM_ENTRIES);"
         errorLine2="                                                                                   ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/LanguagesManager.java"
+            file="../../chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/LanguagesManager.java"
             line="406"
             column="84"/>
     </issue>
@@ -4522,7 +3620,7 @@
         errorLine1="                    LAUNCH_CAUSE_HISTOGRAM, cause, LaunchCause.NUM_ENTRIES);"
         errorLine2="                                                               ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/app/metrics/LaunchCauseMetrics.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/app/metrics/LaunchCauseMetrics.java"
             line="198"
             column="64"/>
     </issue>
@@ -4533,7 +3631,7 @@
         errorLine1="                        LAUNCH_CAUSE_HISTOGRAM, cause, LaunchCause.NUM_ENTRIES);"
         errorLine2="                                                                   ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/app/metrics/LaunchCauseMetrics.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/app/metrics/LaunchCauseMetrics.java"
             line="207"
             column="68"/>
     </issue>
@@ -4544,8 +3642,8 @@
         errorLine1="            mScrollDirection = ScrollDirection.UNKNOWN;"
         errorLine2="                               ~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java"
-            line="373"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java"
+            line="434"
             column="32"/>
     </issue>
 
@@ -4555,8 +3653,8 @@
         errorLine1="            mScrollDirection = ScrollDirection.UNKNOWN;"
         errorLine2="                                               ~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java"
-            line="373"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java"
+            line="434"
             column="48"/>
     </issue>
 
@@ -4566,8 +3664,8 @@
         errorLine1="            if (mScrollDirection != ScrollDirection.UNKNOWN) {"
         errorLine2="                                                    ~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java"
-            line="388"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java"
+            line="449"
             column="53"/>
     </issue>
 
@@ -4577,8 +3675,8 @@
         errorLine1="            if (mScrollDirection == ScrollDirection.UNKNOWN) return;"
         errorLine2="                                                    ~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java"
-            line="394"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java"
+            line="455"
             column="53"/>
     </issue>
 
@@ -4588,8 +3686,8 @@
         errorLine1="            int direction = ScrollDirection.UNKNOWN;"
         errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java"
-            line="435"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java"
+            line="496"
             column="29"/>
     </issue>
 
@@ -4599,8 +3697,8 @@
         errorLine1="            int direction = ScrollDirection.UNKNOWN;"
         errorLine2="                                            ~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java"
-            line="435"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java"
+            line="496"
             column="45"/>
     </issue>
 
@@ -4610,8 +3708,8 @@
         errorLine1="                direction = ScrollDirection.LEFT;"
         errorLine2="                ~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java"
-            line="441"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java"
+            line="502"
             column="17"/>
     </issue>
 
@@ -4621,7 +3719,7 @@
         errorLine1="                histogramName, reason, LensSupportStatus.NUM_ENTRIES);"
         errorLine2="                                                         ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/lens/java/src/org/chromium/chrome/browser/lens/LensMetrics.java"
+            file="../../chrome/browser/lens/java/src/org/chromium/chrome/browser/lens/LensMetrics.java"
             line="55"
             column="58"/>
     </issue>
@@ -4632,7 +3730,7 @@
         errorLine1="                ShareDestination.NUM_ENTRIES);"
         errorLine2="                                 ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/LightweightReactionsMetrics.java"
+            file="../../chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/LightweightReactionsMetrics.java"
             line="160"
             column="34"/>
     </issue>
@@ -4643,7 +3741,7 @@
         errorLine1="                DeviceOrientation.NUM_ENTRIES);"
         errorLine2="                                  ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/LightweightReactionsMetrics.java"
+            file="../../chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/LightweightReactionsMetrics.java"
             line="234"
             column="35"/>
     </issue>
@@ -4654,7 +3752,7 @@
         errorLine1="        assert funnelState &lt; LightweightReactionsFunnel.NUM_ENTRIES;"
         errorLine2="                                                        ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/LightweightReactionsMetrics.java"
+            file="../../chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/LightweightReactionsMetrics.java"
             line="274"
             column="57"/>
     </issue>
@@ -4665,7 +3763,7 @@
         errorLine1="                &quot;LightweightReactions.Funnel&quot;, funnelState, LightweightReactionsFunnel.NUM_ENTRIES);"
         errorLine2="                                                                                       ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/LightweightReactionsMetrics.java"
+            file="../../chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/LightweightReactionsMetrics.java"
             line="278"
             column="88"/>
     </issue>
@@ -4676,8 +3774,8 @@
         errorLine1="                &quot;Android.OmniboxFocusReason&quot;, reason, OmniboxFocusReason.NUM_ENTRIES);"
         errorLine2="                                                                         ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediator.java"
-            line="999"
+            file="../../chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediator.java"
+            line="1005"
             column="74"/>
     </issue>
 
@@ -4687,7 +3785,7 @@
         errorLine1="                &quot;Sharing.LongScreenshots.Event&quot;, action, LongScreenshotsEvent.COUNT);"
         errorLine2="                                                                              ~~~~~">
         <location
-            file="$SRC/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/long_screenshots/LongScreenshotsMetrics.java"
+            file="../../chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/long_screenshots/LongScreenshotsMetrics.java"
             line="80"
             column="79"/>
     </issue>
@@ -4698,7 +3796,7 @@
         errorLine1="                status, BitmapGenerationStatus.COUNT);"
         errorLine2="                                               ~~~~~">
         <location
-            file="$SRC/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/long_screenshots/LongScreenshotsMetrics.java"
+            file="../../chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/long_screenshots/LongScreenshotsMetrics.java"
             line="89"
             column="48"/>
     </issue>
@@ -4709,8 +3807,8 @@
         errorLine1="                &quot;Android.WebView.DevUi.MenuSelection&quot;, selectedMenuItem, MenuChoice.COUNT);"
         errorLine2="                                                                                    ~~~~~">
         <location
-            file="$SRC/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/MainActivity.java"
-            line="80"
+            file="../../android_webview/nonembedded/java/src/org/chromium/android_webview/devui/MainActivity.java"
+            line="81"
             column="85"/>
     </issue>
 
@@ -4720,8 +3818,8 @@
         errorLine1="                FragmentNavigation.COUNT);"
         errorLine2="                                   ~~~~~">
         <location
-            file="$SRC/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/MainActivity.java"
-            line="136"
+            file="../../android_webview/nonembedded/java/src/org/chromium/android_webview/devui/MainActivity.java"
+            line="137"
             column="36"/>
     </issue>
 
@@ -4731,8 +3829,8 @@
         errorLine1="        return (state &amp; StateProperty.FLOATING) != 0;"
         errorLine2="                                      ~~~~~~~~">
         <location
-            file="$SRC/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingMediator.java"
-            line="728"
+            file="../../chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingMediator.java"
+            line="732"
             column="39"/>
     </issue>
 
@@ -4742,7 +3840,7 @@
         errorLine1="        int FLOATING_BAR = BAR | HIDDEN_SHEET | FLOATING; // == 13"
         errorLine2="                                                ~~~~~~~~">
         <location
-            file="$SRC/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingProperties.java"
+            file="../../chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingProperties.java"
             line="68"
             column="49"/>
     </issue>
@@ -4753,7 +3851,7 @@
         errorLine1="        int FLOATING_SHEET = BAR | VISIBLE_SHEET | FLOATING; // == 11"
         errorLine2="                                                   ~~~~~~~~">
         <location
-            file="$SRC/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingProperties.java"
+            file="../../chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingProperties.java"
             line="69"
             column="52"/>
     </issue>
@@ -4764,7 +3862,7 @@
         errorLine1="        if (ViewCompat.getLayoutDirection(this) == View.LAYOUT_DIRECTION_RTL) {"
         errorLine2="                                                   ~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/MaterialProgressBar.java"
+            file="../../components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/MaterialProgressBar.java"
             line="232"
             column="52"/>
     </issue>
@@ -4775,7 +3873,7 @@
         errorLine1="                : ChromeChannelDefinitions.ChannelId.WEBRTC_CAM_AND_MIC;"
         errorLine2="                                                     ~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/media/MediaCaptureNotificationServiceImpl.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/media/MediaCaptureNotificationServiceImpl.java"
             line="180"
             column="54"/>
     </issue>
@@ -4786,8 +3884,8 @@
         errorLine1="            for (@HWEncoder int codecProperties = 0; codecProperties &lt; HWEncoder.NUM_ENTRIES;"
         errorLine2="                                                                                 ~~~~~~~~~~~">
         <location
-            file="$SRC/media/base/android/java/src/org/chromium/media/MediaCodecUtil.java"
-            line="630"
+            file="../../media/base/android/java/src/org/chromium/media/MediaCodecUtil.java"
+            line="603"
             column="82"/>
     </issue>
 
@@ -4797,7 +3895,7 @@
         errorLine1="                &quot;MediaLauncherActivity.MediaType&quot;, mediaType, MediaType.NUM_ENTRIES);"
         errorLine2="                                                                        ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/media/MediaLauncherActivity.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/media/MediaLauncherActivity.java"
             line="54"
             column="73"/>
     </issue>
@@ -4808,7 +3906,7 @@
         errorLine1="        if (mediaType == MediaType.UNKNOWN) {"
         errorLine2="                                   ~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/media/MediaLauncherActivity.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/media/MediaLauncherActivity.java"
             line="56"
             column="36"/>
     </issue>
@@ -4819,7 +3917,7 @@
         errorLine1="        if (source == Source.INVALID || source >= Source.NUM_ENTRIES) return;"
         errorLine2="                                                         ~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaNotificationUma.java"
+            file="../../components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaNotificationUma.java"
             line="43"
             column="58"/>
     </issue>
@@ -4830,7 +3928,7 @@
         errorLine1="                &quot;Media.Notification.Click&quot;, source, Source.NUM_ENTRIES);"
         errorLine2="                                                           ~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaNotificationUma.java"
+            file="../../components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaNotificationUma.java"
             line="45"
             column="60"/>
     </issue>
@@ -4841,7 +3939,7 @@
         errorLine1="                action, CastNotificationControls.NUM_ENTRIES);"
         errorLine2="                                                 ~~~~~~~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/MediaRouteUmaRecorder.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/MediaRouteUmaRecorder.java"
             line="67"
             column="50"/>
     </issue>
@@ -4852,7 +3950,7 @@
         errorLine1="                action, FullScreenControls.NUM_ENTRIES);"
         errorLine2="                                           ~~~~~~~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/MediaRouteUmaRecorder.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/MediaRouteUmaRecorder.java"
             line="77"
             column="44"/>
     </issue>
@@ -4863,7 +3961,7 @@
         errorLine1="                    &quot;Media.Session.Play&quot;, action, MediaSessionActionSource.NUM_ENTRIES);"
         errorLine2="                                                                           ~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaSessionUma.java"
+            file="../../components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaSessionUma.java"
             line="32"
             column="76"/>
     </issue>
@@ -4874,7 +3972,7 @@
         errorLine1="                    &quot;Media.Session.Pause&quot;, action, MediaSessionActionSource.NUM_ENTRIES);"
         errorLine2="                                                                            ~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaSessionUma.java"
+            file="../../components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaSessionUma.java"
             line="39"
             column="77"/>
     </issue>
@@ -4885,7 +3983,7 @@
         errorLine1="                    &quot;Media.Session.Stop&quot;, action, MediaSessionActionSource.NUM_ENTRIES);"
         errorLine2="                                                                           ~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaSessionUma.java"
+            file="../../components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaSessionUma.java"
             line="46"
             column="76"/>
     </issue>
@@ -4896,7 +3994,7 @@
         errorLine1="        if (TextUtils.isEmpty(mimeType)) return MediaLauncherActivity.MediaType.UNKNOWN;"
         errorLine2="                                                                                ~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/media/MediaViewerUtils.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/media/MediaViewerUtils.java"
             line="170"
             column="81"/>
     </issue>
@@ -4907,7 +4005,7 @@
         errorLine1="        if (pieces.length != 2) return MediaLauncherActivity.MediaType.UNKNOWN;"
         errorLine2="                                                                       ~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/media/MediaViewerUtils.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/media/MediaViewerUtils.java"
             line="173"
             column="72"/>
     </issue>
@@ -4918,7 +4016,7 @@
         errorLine1="                return MediaLauncherActivity.MediaType.UNKNOWN;"
         errorLine2="                                                       ~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/media/MediaViewerUtils.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/media/MediaViewerUtils.java"
             line="183"
             column="56"/>
     </issue>
@@ -4929,7 +4027,7 @@
         errorLine1="                mHistogramName, notification, Notification.NUM_ENTRIES);"
         errorLine2="                                                           ~~~~~~~~~~~">
         <location
-            file="$SRC/base/android/java/src/org/chromium/base/memory/MemoryPressureUma.java"
+            file="../../base/android/java/src/org/chromium/base/memory/MemoryPressureUma.java"
             line="110"
             column="60"/>
     </issue>
@@ -4940,7 +4038,7 @@
         errorLine1="                &quot;MerchantTrust.Message.ClearReason&quot;, clearReason, MessageClearReason.MAX_VALUE + 1);"
         errorLine2="                                                                                     ~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustMetrics.java"
+            file="../../chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustMetrics.java"
             line="106"
             column="86"/>
     </issue>
@@ -4951,7 +4049,7 @@
         errorLine1="                BottomSheetOpenedSource.MAX_VALUE + 1);"
         errorLine2="                                        ~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustMetrics.java"
+            file="../../chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustMetrics.java"
             line="290"
             column="41"/>
     </issue>
@@ -4962,8 +4060,8 @@
         errorLine1="        return direction != ScrollDirection.UNKNOWN &amp;&amp; mCurrentState == State.IDLE;"
         errorLine2="                                            ~~~~~~~">
         <location
-            file="$SRC/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerMediator.java"
-            line="237"
+            file="../../components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerMediator.java"
+            line="267"
             column="45"/>
     </issue>
 
@@ -4973,8 +4071,8 @@
         errorLine1="                MessageDisableReason.MAX_VALUE + 1);"
         errorLine2="                                     ~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MessageService.java"
-            line="145"
+            file="../../chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MessageService.java"
+            line="146"
             column="38"/>
     </issue>
 
@@ -4984,8 +4082,8 @@
         errorLine1="                        .setMax(ParsingLogResult.COUNT)"
         errorLine2="                                                 ~~~~~">
         <location
-            file="$SRC/android_webview/nonembedded/java/src/org/chromium/android_webview/services/MetricsBridgeService.java"
-            line="83"
+            file="../../android_webview/nonembedded/java/src/org/chromium/android_webview/services/MetricsBridgeService.java"
+            line="84"
             column="50"/>
     </issue>
 
@@ -4995,8 +4093,8 @@
         errorLine1="                        .setNumBuckets(ParsingLogResult.COUNT + 1)"
         errorLine2="                                                        ~~~~~">
         <location
-            file="$SRC/android_webview/nonembedded/java/src/org/chromium/android_webview/services/MetricsBridgeService.java"
-            line="84"
+            file="../../android_webview/nonembedded/java/src/org/chromium/android_webview/services/MetricsBridgeService.java"
+            line="85"
             column="57"/>
     </issue>
 
@@ -5006,8 +4104,8 @@
         errorLine1="                        .setMax(RetrieveMetricsTaskStatus.COUNT)"
         errorLine2="                                                          ~~~~~">
         <location
-            file="$SRC/android_webview/nonembedded/java/src/org/chromium/android_webview/services/MetricsBridgeService.java"
-            line="120"
+            file="../../android_webview/nonembedded/java/src/org/chromium/android_webview/services/MetricsBridgeService.java"
+            line="121"
             column="59"/>
     </issue>
 
@@ -5017,8 +4115,8 @@
         errorLine1="                        .setNumBuckets(ParsingLogResult.COUNT + 1)"
         errorLine2="                                                        ~~~~~">
         <location
-            file="$SRC/android_webview/nonembedded/java/src/org/chromium/android_webview/services/MetricsBridgeService.java"
-            line="121"
+            file="../../android_webview/nonembedded/java/src/org/chromium/android_webview/services/MetricsBridgeService.java"
+            line="122"
             column="57"/>
     </issue>
 
@@ -5028,8 +4126,8 @@
         errorLine1="                list.add(logRetrieveMetricsTaskStatus(RetrieveMetricsTaskStatus.SUCCESS));"
         errorLine2="                                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/android_webview/nonembedded/java/src/org/chromium/android_webview/services/MetricsBridgeService.java"
-            line="203"
+            file="../../android_webview/nonembedded/java/src/org/chromium/android_webview/services/MetricsBridgeService.java"
+            line="205"
             column="55"/>
     </issue>
 
@@ -5039,8 +4137,8 @@
         errorLine1="                list.add(logRetrieveMetricsTaskStatus(RetrieveMetricsTaskStatus.SUCCESS));"
         errorLine2="                                                                                ~~~~~~~">
         <location
-            file="$SRC/android_webview/nonembedded/java/src/org/chromium/android_webview/services/MetricsBridgeService.java"
-            line="203"
+            file="../../android_webview/nonembedded/java/src/org/chromium/android_webview/services/MetricsBridgeService.java"
+            line="205"
             column="81"/>
     </issue>
 
@@ -5050,8 +4148,8 @@
         errorLine1="                &quot;Download.MixedContentDialog.Events&quot;, event, MixedContentDownloadDialogEvent.COUNT);"
         errorLine2="                                                                                             ~~~~~">
         <location
-            file="$SRC/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/MixedContentDownloadDialog.java"
-            line="121"
+            file="../../chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/MixedContentDownloadDialog.java"
+            line="116"
             column="94"/>
     </issue>
 
@@ -5061,7 +4159,7 @@
         errorLine1="                            SecurityFilteredTouchResult.NUM_ENTRIES);"
         errorLine2="                                                        ~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/modaldialog/android/java/src/org/chromium/components/browser_ui/modaldialog/ModalDialogView.java"
+            file="../../components/browser_ui/modaldialog/android/java/src/org/chromium/components/browser_ui/modaldialog/ModalDialogView.java"
             line="245"
             column="57"/>
     </issue>
@@ -5072,7 +4170,7 @@
         errorLine1="                status, ContentSuggestionsDisplayStatus.NUM_ENTRIES);"
         errorLine2="                                                        ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageUma.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageUma.java"
             line="296"
             column="57"/>
     </issue>
@@ -5083,7 +4181,7 @@
         errorLine1="                NightModeEnabledReason.NUM_ENTRIES);"
         errorLine2="                                       ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/NightModeMetrics.java"
+            file="../../chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/NightModeMetrics.java"
             line="67"
             column="40"/>
     </issue>
@@ -5094,7 +4192,7 @@
         errorLine1="                &quot;Android.DarkTheme.Preference.State&quot;, theme, ThemeType.NUM_ENTRIES);"
         errorLine2="                                                                       ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/NightModeMetrics.java"
+            file="../../chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/NightModeMetrics.java"
             line="86"
             column="72"/>
     </issue>
@@ -5105,7 +4203,7 @@
         errorLine1="                &quot;Android.DarkTheme.ThemeSettingsEntry&quot;, entry, ThemeSettingsEntry.NUM_ENTRIES);"
         errorLine2="                                                                                  ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/NightModeMetrics.java"
+            file="../../chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/NightModeMetrics.java"
             line="116"
             column="83"/>
     </issue>
@@ -5116,7 +4214,7 @@
         errorLine1="                NoteShareDestination.NUM_ENTRIES);"
         errorLine2="                                     ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationMetrics.java"
+            file="../../chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationMetrics.java"
             line="119"
             column="38"/>
     </issue>
@@ -5127,7 +4225,7 @@
         errorLine1="        assert funnelState &lt; NoteCreationFunnel.NUM_ENTRIES;"
         errorLine2="                                                ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationMetrics.java"
+            file="../../chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationMetrics.java"
             line="159"
             column="49"/>
     </issue>
@@ -5138,7 +4236,7 @@
         errorLine1="                &quot;NoteCreation.Funnel&quot;, funnelState, NoteCreationFunnel.NUM_ENTRIES);"
         errorLine2="                                                                       ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationMetrics.java"
+            file="../../chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationMetrics.java"
             line="163"
             column="72"/>
     </issue>
@@ -5149,7 +4247,7 @@
         errorLine1="                ? PendingIntent.getBroadcast(applicationContext, requestCode, intent, flags)"
         errorLine2="                                                                                      ~~~~~">
         <location
-            file="$SRC/chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/NotificationIntentInterceptor.java"
+            file="../../chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/NotificationIntentInterceptor.java"
             line="169"
             column="87"/>
     </issue>
@@ -5160,30 +4258,30 @@
         errorLine1="                : PendingIntent.getActivity(applicationContext, requestCode, intent, flags);"
         errorLine2="                                                                                     ~~~~~">
         <location
-            file="$SRC/chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/NotificationIntentInterceptor.java"
+            file="../../chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/NotificationIntentInterceptor.java"
             line="170"
             column="86"/>
     </issue>
 
     <issue
         id="WrongConstant"
-        message="Must be one of: SystemNotificationType.UNKNOWN, SystemNotificationType.DOWNLOAD_FILES, SystemNotificationType.DOWNLOAD_PAGES, SystemNotificationType.CLOSE_INCOGNITO, SystemNotificationType.CONTENT_SUGGESTION, SystemNotificationType.MEDIA_CAPTURE, SystemNotificationType.PHYSICAL_WEB, SystemNotificationType.MEDIA, SystemNotificationType.SITES, SystemNotificationType.SYNC, SystemNotificationType.WEBAPK, SystemNotificationType.BROWSER_ACTIONS, SystemNotificationType.WEBAPP_ACTIONS, SystemNotificationType.OFFLINE_CONTENT_SUGGESTION, SystemNotificationType.TRUSTED_WEB_ACTIVITY_SITES, SystemNotificationType.OFFLINE_PAGES, SystemNotificationType.SEND_TAB_TO_SELF, SystemNotificationType.UPDATES, SystemNotificationType.CLICK_TO_CALL, SystemNotificationType.SHARED_CLIPBOARD, SystemNotificationType.SMS_FETCHER, SystemNotificationType.PERMISSION_REQUESTS, SystemNotificationType.PERMISSION_REQUESTS_HIGH, SystemNotificationType.ANNOUNCEMENT, SystemNotificationType.SHARE_SAVE_IMAGE, SystemNotificationType.TWA_DISCLOSURE_INITIAL, SystemNotificationType.TWA_DISCLOSURE_SUBSEQUENT, SystemNotificationType.CHROME_REENGAGEMENT_1, SystemNotificationType.CHROME_REENGAGEMENT_2, SystemNotificationType.CHROME_REENGAGEMENT_3, SystemNotificationType.PRICE_DROP_ALERTS, SystemNotificationType.WEBAPK_INSTALL_IN_PROGRESS, SystemNotificationType.WEBAPK_INSTALL_COMPLETE, SystemNotificationType.PRICE_DROP_ALERTS_CHROME_MANAGED, SystemNotificationType.PRICE_DROP_ALERTS_USER_MANAGED, SystemNotificationType.CHROME_TIPS, SystemNotificationType.BLUETOOTH, SystemNotificationType.USB"
+        message="Must be one of: SystemNotificationType.UNKNOWN, SystemNotificationType.DOWNLOAD_FILES, SystemNotificationType.DOWNLOAD_PAGES, SystemNotificationType.CLOSE_INCOGNITO, SystemNotificationType.CONTENT_SUGGESTION, SystemNotificationType.MEDIA_CAPTURE, SystemNotificationType.PHYSICAL_WEB, SystemNotificationType.MEDIA, SystemNotificationType.SITES, SystemNotificationType.SYNC, SystemNotificationType.WEBAPK, SystemNotificationType.BROWSER_ACTIONS, SystemNotificationType.WEBAPP_ACTIONS, SystemNotificationType.OFFLINE_CONTENT_SUGGESTION, SystemNotificationType.TRUSTED_WEB_ACTIVITY_SITES, SystemNotificationType.OFFLINE_PAGES, SystemNotificationType.SEND_TAB_TO_SELF, SystemNotificationType.UPDATES, SystemNotificationType.CLICK_TO_CALL, SystemNotificationType.SHARED_CLIPBOARD, SystemNotificationType.SMS_FETCHER, SystemNotificationType.PERMISSION_REQUESTS, SystemNotificationType.PERMISSION_REQUESTS_HIGH, SystemNotificationType.ANNOUNCEMENT, SystemNotificationType.SHARE_SAVE_IMAGE, SystemNotificationType.TWA_DISCLOSURE_INITIAL, SystemNotificationType.TWA_DISCLOSURE_SUBSEQUENT, SystemNotificationType.CHROME_REENGAGEMENT_1, SystemNotificationType.CHROME_REENGAGEMENT_2, SystemNotificationType.CHROME_REENGAGEMENT_3, SystemNotificationType.PRICE_DROP_ALERTS, SystemNotificationType.WEBAPK_INSTALL_IN_PROGRESS, SystemNotificationType.WEBAPK_INSTALL_COMPLETE, SystemNotificationType.PRICE_DROP_ALERTS_CHROME_MANAGED, SystemNotificationType.PRICE_DROP_ALERTS_USER_MANAGED, SystemNotificationType.CHROME_TIPS, SystemNotificationType.BLUETOOTH, SystemNotificationType.USB, SystemNotificationType.UPM_ERROR"
         errorLine1="                SystemNotificationType.NUM_ENTRIES);"
         errorLine2="                                       ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/NotificationUmaTracker.java"
-            line="277"
+            file="../../chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/NotificationUmaTracker.java"
+            line="278"
             column="40"/>
     </issue>
 
     <issue
         id="WrongConstant"
-        message="Must be one of: SystemNotificationType.UNKNOWN, SystemNotificationType.DOWNLOAD_FILES, SystemNotificationType.DOWNLOAD_PAGES, SystemNotificationType.CLOSE_INCOGNITO, SystemNotificationType.CONTENT_SUGGESTION, SystemNotificationType.MEDIA_CAPTURE, SystemNotificationType.PHYSICAL_WEB, SystemNotificationType.MEDIA, SystemNotificationType.SITES, SystemNotificationType.SYNC, SystemNotificationType.WEBAPK, SystemNotificationType.BROWSER_ACTIONS, SystemNotificationType.WEBAPP_ACTIONS, SystemNotificationType.OFFLINE_CONTENT_SUGGESTION, SystemNotificationType.TRUSTED_WEB_ACTIVITY_SITES, SystemNotificationType.OFFLINE_PAGES, SystemNotificationType.SEND_TAB_TO_SELF, SystemNotificationType.UPDATES, SystemNotificationType.CLICK_TO_CALL, SystemNotificationType.SHARED_CLIPBOARD, SystemNotificationType.SMS_FETCHER, SystemNotificationType.PERMISSION_REQUESTS, SystemNotificationType.PERMISSION_REQUESTS_HIGH, SystemNotificationType.ANNOUNCEMENT, SystemNotificationType.SHARE_SAVE_IMAGE, SystemNotificationType.TWA_DISCLOSURE_INITIAL, SystemNotificationType.TWA_DISCLOSURE_SUBSEQUENT, SystemNotificationType.CHROME_REENGAGEMENT_1, SystemNotificationType.CHROME_REENGAGEMENT_2, SystemNotificationType.CHROME_REENGAGEMENT_3, SystemNotificationType.PRICE_DROP_ALERTS, SystemNotificationType.WEBAPK_INSTALL_IN_PROGRESS, SystemNotificationType.WEBAPK_INSTALL_COMPLETE, SystemNotificationType.PRICE_DROP_ALERTS_CHROME_MANAGED, SystemNotificationType.PRICE_DROP_ALERTS_USER_MANAGED, SystemNotificationType.CHROME_TIPS, SystemNotificationType.BLUETOOTH, SystemNotificationType.USB"
+        message="Must be one of: SystemNotificationType.UNKNOWN, SystemNotificationType.DOWNLOAD_FILES, SystemNotificationType.DOWNLOAD_PAGES, SystemNotificationType.CLOSE_INCOGNITO, SystemNotificationType.CONTENT_SUGGESTION, SystemNotificationType.MEDIA_CAPTURE, SystemNotificationType.PHYSICAL_WEB, SystemNotificationType.MEDIA, SystemNotificationType.SITES, SystemNotificationType.SYNC, SystemNotificationType.WEBAPK, SystemNotificationType.BROWSER_ACTIONS, SystemNotificationType.WEBAPP_ACTIONS, SystemNotificationType.OFFLINE_CONTENT_SUGGESTION, SystemNotificationType.TRUSTED_WEB_ACTIVITY_SITES, SystemNotificationType.OFFLINE_PAGES, SystemNotificationType.SEND_TAB_TO_SELF, SystemNotificationType.UPDATES, SystemNotificationType.CLICK_TO_CALL, SystemNotificationType.SHARED_CLIPBOARD, SystemNotificationType.SMS_FETCHER, SystemNotificationType.PERMISSION_REQUESTS, SystemNotificationType.PERMISSION_REQUESTS_HIGH, SystemNotificationType.ANNOUNCEMENT, SystemNotificationType.SHARE_SAVE_IMAGE, SystemNotificationType.TWA_DISCLOSURE_INITIAL, SystemNotificationType.TWA_DISCLOSURE_SUBSEQUENT, SystemNotificationType.CHROME_REENGAGEMENT_1, SystemNotificationType.CHROME_REENGAGEMENT_2, SystemNotificationType.CHROME_REENGAGEMENT_3, SystemNotificationType.PRICE_DROP_ALERTS, SystemNotificationType.WEBAPK_INSTALL_IN_PROGRESS, SystemNotificationType.WEBAPK_INSTALL_COMPLETE, SystemNotificationType.PRICE_DROP_ALERTS_CHROME_MANAGED, SystemNotificationType.PRICE_DROP_ALERTS_USER_MANAGED, SystemNotificationType.CHROME_TIPS, SystemNotificationType.BLUETOOTH, SystemNotificationType.USB, SystemNotificationType.UPM_ERROR"
         errorLine1="                &quot;Mobile.SystemNotification.Dismiss&quot;, type, SystemNotificationType.NUM_ENTRIES);"
         errorLine2="                                                                                  ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/NotificationUmaTracker.java"
-            line="324"
+            file="../../chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/NotificationUmaTracker.java"
+            line="325"
             column="83"/>
     </issue>
 
@@ -5193,19 +4291,19 @@
         errorLine1="                &quot;Mobile.SystemNotification.Action.Click&quot;, actionType, ActionType.NUM_ENTRIES);"
         errorLine2="                                                                                 ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/NotificationUmaTracker.java"
-            line="368"
+            file="../../chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/NotificationUmaTracker.java"
+            line="369"
             column="82"/>
     </issue>
 
     <issue
         id="WrongConstant"
-        message="Must be one of: SystemNotificationType.UNKNOWN, SystemNotificationType.DOWNLOAD_FILES, SystemNotificationType.DOWNLOAD_PAGES, SystemNotificationType.CLOSE_INCOGNITO, SystemNotificationType.CONTENT_SUGGESTION, SystemNotificationType.MEDIA_CAPTURE, SystemNotificationType.PHYSICAL_WEB, SystemNotificationType.MEDIA, SystemNotificationType.SITES, SystemNotificationType.SYNC, SystemNotificationType.WEBAPK, SystemNotificationType.BROWSER_ACTIONS, SystemNotificationType.WEBAPP_ACTIONS, SystemNotificationType.OFFLINE_CONTENT_SUGGESTION, SystemNotificationType.TRUSTED_WEB_ACTIVITY_SITES, SystemNotificationType.OFFLINE_PAGES, SystemNotificationType.SEND_TAB_TO_SELF, SystemNotificationType.UPDATES, SystemNotificationType.CLICK_TO_CALL, SystemNotificationType.SHARED_CLIPBOARD, SystemNotificationType.SMS_FETCHER, SystemNotificationType.PERMISSION_REQUESTS, SystemNotificationType.PERMISSION_REQUESTS_HIGH, SystemNotificationType.ANNOUNCEMENT, SystemNotificationType.SHARE_SAVE_IMAGE, SystemNotificationType.TWA_DISCLOSURE_INITIAL, SystemNotificationType.TWA_DISCLOSURE_SUBSEQUENT, SystemNotificationType.CHROME_REENGAGEMENT_1, SystemNotificationType.CHROME_REENGAGEMENT_2, SystemNotificationType.CHROME_REENGAGEMENT_3, SystemNotificationType.PRICE_DROP_ALERTS, SystemNotificationType.WEBAPK_INSTALL_IN_PROGRESS, SystemNotificationType.WEBAPK_INSTALL_COMPLETE, SystemNotificationType.PRICE_DROP_ALERTS_CHROME_MANAGED, SystemNotificationType.PRICE_DROP_ALERTS_USER_MANAGED, SystemNotificationType.CHROME_TIPS, SystemNotificationType.BLUETOOTH, SystemNotificationType.USB"
+        message="Must be one of: SystemNotificationType.UNKNOWN, SystemNotificationType.DOWNLOAD_FILES, SystemNotificationType.DOWNLOAD_PAGES, SystemNotificationType.CLOSE_INCOGNITO, SystemNotificationType.CONTENT_SUGGESTION, SystemNotificationType.MEDIA_CAPTURE, SystemNotificationType.PHYSICAL_WEB, SystemNotificationType.MEDIA, SystemNotificationType.SITES, SystemNotificationType.SYNC, SystemNotificationType.WEBAPK, SystemNotificationType.BROWSER_ACTIONS, SystemNotificationType.WEBAPP_ACTIONS, SystemNotificationType.OFFLINE_CONTENT_SUGGESTION, SystemNotificationType.TRUSTED_WEB_ACTIVITY_SITES, SystemNotificationType.OFFLINE_PAGES, SystemNotificationType.SEND_TAB_TO_SELF, SystemNotificationType.UPDATES, SystemNotificationType.CLICK_TO_CALL, SystemNotificationType.SHARED_CLIPBOARD, SystemNotificationType.SMS_FETCHER, SystemNotificationType.PERMISSION_REQUESTS, SystemNotificationType.PERMISSION_REQUESTS_HIGH, SystemNotificationType.ANNOUNCEMENT, SystemNotificationType.SHARE_SAVE_IMAGE, SystemNotificationType.TWA_DISCLOSURE_INITIAL, SystemNotificationType.TWA_DISCLOSURE_SUBSEQUENT, SystemNotificationType.CHROME_REENGAGEMENT_1, SystemNotificationType.CHROME_REENGAGEMENT_2, SystemNotificationType.CHROME_REENGAGEMENT_3, SystemNotificationType.PRICE_DROP_ALERTS, SystemNotificationType.WEBAPK_INSTALL_IN_PROGRESS, SystemNotificationType.WEBAPK_INSTALL_COMPLETE, SystemNotificationType.PRICE_DROP_ALERTS_CHROME_MANAGED, SystemNotificationType.PRICE_DROP_ALERTS_USER_MANAGED, SystemNotificationType.CHROME_TIPS, SystemNotificationType.BLUETOOTH, SystemNotificationType.USB, SystemNotificationType.UPM_ERROR"
         errorLine1="        RecordHistogram.recordEnumeratedHistogram(name, type, SystemNotificationType.NUM_ENTRIES);"
         errorLine2="                                                                                     ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/NotificationUmaTracker.java"
-            line="504"
+            file="../../chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/NotificationUmaTracker.java"
+            line="505"
             column="86"/>
     </issue>
 
@@ -5215,7 +4313,7 @@
         errorLine1="                surfaceState, UmaEnum.NUM_ENTRIES);"
         errorLine2="                                      ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/indicator/OfflineIndicatorControllerV2.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/offlinepages/indicator/OfflineIndicatorControllerV2.java"
             line="268"
             column="39"/>
     </issue>
@@ -5226,7 +4324,7 @@
         errorLine1="        for (int i = 0; i &lt; Filters.FilterType.NUM_ENTRIES; i++) {"
         errorLine2="                                               ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/metrics/OfflineItemStartupLogger.java"
+            file="../../chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/metrics/OfflineItemStartupLogger.java"
             line="62"
             column="48"/>
     </issue>
@@ -5237,7 +4335,7 @@
         errorLine1="                &quot;OfflinePages.TabRestore&quot;, tabRestoreType, TabRestoreType.NUM_ENTRIES);"
         errorLine2="                                                                          ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java"
             line="949"
             column="75"/>
     </issue>
@@ -5248,8 +4346,8 @@
         errorLine1="                        ReadCacheResult.SUCCESS, ReadCacheResult.NUM_ENTRIES);"
         errorLine2="                                                                 ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/optimization_guide/android/java/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuidePushNotificationManager.java"
-            line="141"
+            file="../../chrome/browser/optimization_guide/android/java/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuidePushNotificationManager.java"
+            line="139"
             column="66"/>
     </issue>
 
@@ -5259,8 +4357,8 @@
         errorLine1="                        ReadCacheResult.INVALID_PROTO_ERROR, ReadCacheResult.NUM_ENTRIES);"
         errorLine2="                                                                             ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/optimization_guide/android/java/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuidePushNotificationManager.java"
-            line="144"
+            file="../../chrome/browser/optimization_guide/android/java/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuidePushNotificationManager.java"
+            line="142"
             column="78"/>
     </issue>
 
@@ -5270,8 +4368,8 @@
         errorLine1="                        ReadCacheResult.BASE64_ERROR, ReadCacheResult.NUM_ENTRIES);"
         errorLine2="                                                                      ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/optimization_guide/android/java/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuidePushNotificationManager.java"
-            line="148"
+            file="../../chrome/browser/optimization_guide/android/java/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuidePushNotificationManager.java"
+            line="146"
             column="71"/>
     </issue>
 
@@ -5281,7 +4379,7 @@
         errorLine1="                &quot;BrowserServices.VerificationResult&quot;, result, VerificationResult.NUM_ENTRIES);"
         errorLine2="                                                                                 ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/android/browserservices/metrics/java/src/org/chromium/chrome/browser/browserservices/metrics/OriginVerifierMetricsRecorder.java"
+            file="../../chrome/browser/android/browserservices/metrics/java/src/org/chromium/chrome/browser/browserservices/metrics/OriginVerifierMetricsRecorder.java"
             line="38"
             column="82"/>
     </issue>
@@ -5292,8 +4390,8 @@
         errorLine1="        for (@PanelState int state = PanelState.UNDEFINED; state &lt; PanelState.NUM_ENTRIES;"
         errorLine2="                                                                              ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelBase.java"
-            line="754"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelBase.java"
+            line="783"
             column="79"/>
     </issue>
 
@@ -5303,8 +4401,8 @@
         errorLine1="        for (@PanelState int state = PanelState.UNDEFINED; state &lt; PanelState.NUM_ENTRIES;"
         errorLine2="                                                                              ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelBase.java"
-            line="870"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelBase.java"
+            line="899"
             column="79"/>
     </issue>
 
@@ -5314,7 +4412,7 @@
         errorLine1="                DiscoverabilityAction.NUM_ENTRIES);"
         errorLine2="                                      ~~~~~~~~~~~">
         <location
-            file="$SRC/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoDiscoverabilityMetrics.java"
+            file="../../components/page_info/android/java/src/org/chromium/components/page_info/PageInfoDiscoverabilityMetrics.java"
             line="48"
             column="39"/>
     </issue>
@@ -5325,8 +4423,8 @@
         errorLine1="                userAction, PasswordCheckUserAction.COUNT);"
         errorLine2="                                                    ~~~~~">
         <location
-            file="$SRC/chrome/browser/password_check/android/java/src/org/chromium/chrome/browser/password_check/PasswordCheckMetricsRecorder.java"
-            line="27"
+            file="../../chrome/browser/password_check/android/java/src/org/chromium/chrome/browser/password_check/PasswordCheckMetricsRecorder.java"
+            line="24"
             column="53"/>
     </issue>
 
@@ -5336,8 +4434,8 @@
         errorLine1="                    PasswordCheckResolutionAction.COUNT);"
         errorLine2="                                                  ~~~~~">
         <location
-            file="$SRC/chrome/browser/password_check/android/java/src/org/chromium/chrome/browser/password_check/PasswordCheckMetricsRecorder.java"
-            line="45"
+            file="../../chrome/browser/password_check/android/java/src/org/chromium/chrome/browser/password_check/PasswordCheckMetricsRecorder.java"
+            line="42"
             column="51"/>
     </issue>
 
@@ -5347,8 +4445,8 @@
         errorLine1="                    PasswordCheckResolutionAction.COUNT);"
         errorLine2="                                                  ~~~~~">
         <location
-            file="$SRC/chrome/browser/password_check/android/java/src/org/chromium/chrome/browser/password_check/PasswordCheckMetricsRecorder.java"
-            line="50"
+            file="../../chrome/browser/password_check/android/java/src/org/chromium/chrome/browser/password_check/PasswordCheckMetricsRecorder.java"
+            line="47"
             column="51"/>
     </issue>
 
@@ -5358,8 +4456,8 @@
         errorLine1="                    PasswordCheckResolutionAction.COUNT);"
         errorLine2="                                                  ~~~~~">
         <location
-            file="$SRC/chrome/browser/password_check/android/java/src/org/chromium/chrome/browser/password_check/PasswordCheckMetricsRecorder.java"
-            line="54"
+            file="../../chrome/browser/password_check/android/java/src/org/chromium/chrome/browser/password_check/PasswordCheckMetricsRecorder.java"
+            line="51"
             column="51"/>
     </issue>
 
@@ -5369,7 +4467,7 @@
         errorLine1="        if (boolCapability.length != PhotoCapabilityBool.NUM_ENTRIES"
         errorLine2="                                                         ~~~~~~~~~~~">
         <location
-            file="$SRC/media/capture/video/android/java/src/org/chromium/media/PhotoCapabilities.java"
+            file="../../media/capture/video/android/java/src/org/chromium/media/PhotoCapabilities.java"
             line="26"
             column="58"/>
     </issue>
@@ -5380,7 +4478,7 @@
         errorLine1="                || doubleCapability.length != PhotoCapabilityDouble.NUM_ENTRIES"
         errorLine2="                                                                    ~~~~~~~~~~~">
         <location
-            file="$SRC/media/capture/video/android/java/src/org/chromium/media/PhotoCapabilities.java"
+            file="../../media/capture/video/android/java/src/org/chromium/media/PhotoCapabilities.java"
             line="27"
             column="69"/>
     </issue>
@@ -5391,7 +4489,7 @@
         errorLine1="                || intCapability.length != PhotoCapabilityInt.NUM_ENTRIES"
         errorLine2="                                                              ~~~~~~~~~~~">
         <location
-            file="$SRC/media/capture/video/android/java/src/org/chromium/media/PhotoCapabilities.java"
+            file="../../media/capture/video/android/java/src/org/chromium/media/PhotoCapabilities.java"
             line="28"
             column="63"/>
     </issue>
@@ -5402,7 +4500,7 @@
         errorLine1="                || meteringMode.length != MeteringModeType.NUM_ENTRIES"
         errorLine2="                                                           ~~~~~~~~~~~">
         <location
-            file="$SRC/media/capture/video/android/java/src/org/chromium/media/PhotoCapabilities.java"
+            file="../../media/capture/video/android/java/src/org/chromium/media/PhotoCapabilities.java"
             line="29"
             column="60"/>
     </issue>
@@ -5413,7 +4511,7 @@
         errorLine1="                || meteringModeArray.length != MeteringModeType.NUM_ENTRIES) {"
         errorLine2="                                                                ~~~~~~~~~~~">
         <location
-            file="$SRC/media/capture/video/android/java/src/org/chromium/media/PhotoCapabilities.java"
+            file="../../media/capture/video/android/java/src/org/chromium/media/PhotoCapabilities.java"
             line="30"
             column="65"/>
     </issue>
@@ -5424,7 +4522,7 @@
         errorLine1="                        || fillLightModeArray[i] >= AndroidFillLightMode.NUM_ENTRIES) {"
         errorLine2="                                                                         ~~~~~~~~~~~">
         <location
-            file="$SRC/media/capture/video/android/java/src/org/chromium/media/PhotoCapabilities.java"
+            file="../../media/capture/video/android/java/src/org/chromium/media/PhotoCapabilities.java"
             line="36"
             column="74"/>
     </issue>
@@ -5435,7 +4533,7 @@
         errorLine1="            if (meteringMode[i] &lt; 0 || meteringMode[i] >= AndroidMeteringMode.NUM_ENTRIES) {"
         errorLine2="                                                                              ~~~~~~~~~~~">
         <location
-            file="$SRC/media/capture/video/android/java/src/org/chromium/media/PhotoCapabilities.java"
+            file="../../media/capture/video/android/java/src/org/chromium/media/PhotoCapabilities.java"
             line="42"
             column="79"/>
     </issue>
@@ -5446,7 +4544,7 @@
         errorLine1="                        || meteringModeArray[i][j] >= AndroidMeteringMode.NUM_ENTRIES) {"
         errorLine2="                                                                          ~~~~~~~~~~~">
         <location
-            file="$SRC/media/capture/video/android/java/src/org/chromium/media/PhotoCapabilities.java"
+            file="../../media/capture/video/android/java/src/org/chromium/media/PhotoCapabilities.java"
             line="50"
             column="75"/>
     </issue>
@@ -5457,7 +4555,7 @@
         errorLine1="        mMeteringModeArray = new int[MeteringModeType.NUM_ENTRIES][];"
         errorLine2="                                                      ~~~~~~~~~~~">
         <location
-            file="$SRC/media/capture/video/android/java/src/org/chromium/media/PhotoCapabilities.java"
+            file="../../media/capture/video/android/java/src/org/chromium/media/PhotoCapabilities.java"
             line="61"
             column="55"/>
     </issue>
@@ -5468,7 +4566,7 @@
         errorLine1="        if (capability &lt; 0 || capability >= PhotoCapabilityBool.NUM_ENTRIES) {"
         errorLine2="                                                                ~~~~~~~~~~~">
         <location
-            file="$SRC/media/capture/video/android/java/src/org/chromium/media/PhotoCapabilities.java"
+            file="../../media/capture/video/android/java/src/org/chromium/media/PhotoCapabilities.java"
             line="70"
             column="65"/>
     </issue>
@@ -5479,7 +4577,7 @@
         errorLine1="        if (capability &lt; 0 || capability >= PhotoCapabilityDouble.NUM_ENTRIES) {"
         errorLine2="                                                                  ~~~~~~~~~~~">
         <location
-            file="$SRC/media/capture/video/android/java/src/org/chromium/media/PhotoCapabilities.java"
+            file="../../media/capture/video/android/java/src/org/chromium/media/PhotoCapabilities.java"
             line="78"
             column="67"/>
     </issue>
@@ -5490,7 +4588,7 @@
         errorLine1="        if (capability &lt; 0 || capability >= PhotoCapabilityInt.NUM_ENTRIES) {"
         errorLine2="                                                               ~~~~~~~~~~~">
         <location
-            file="$SRC/media/capture/video/android/java/src/org/chromium/media/PhotoCapabilities.java"
+            file="../../media/capture/video/android/java/src/org/chromium/media/PhotoCapabilities.java"
             line="86"
             column="64"/>
     </issue>
@@ -5501,7 +4599,7 @@
         errorLine1="        if (type &lt; 0 || type >= MeteringModeType.NUM_ENTRIES) {"
         errorLine2="                                                 ~~~~~~~~~~~">
         <location
-            file="$SRC/media/capture/video/android/java/src/org/chromium/media/PhotoCapabilities.java"
+            file="../../media/capture/video/android/java/src/org/chromium/media/PhotoCapabilities.java"
             line="100"
             column="50"/>
     </issue>
@@ -5512,7 +4610,7 @@
         errorLine1="        if (type &lt; 0 || type >= MeteringModeType.NUM_ENTRIES) {"
         errorLine2="                                                 ~~~~~~~~~~~">
         <location
-            file="$SRC/media/capture/video/android/java/src/org/chromium/media/PhotoCapabilities.java"
+            file="../../media/capture/video/android/java/src/org/chromium/media/PhotoCapabilities.java"
             line="108"
             column="50"/>
     </issue>
@@ -5523,7 +4621,7 @@
         errorLine1="        public boolean mBoolCapability[] = new boolean[PhotoCapabilityBool.NUM_ENTRIES];"
         errorLine2="                                                                           ~~~~~~~~~~~">
         <location
-            file="$SRC/media/capture/video/android/java/src/org/chromium/media/PhotoCapabilities.java"
+            file="../../media/capture/video/android/java/src/org/chromium/media/PhotoCapabilities.java"
             line="116"
             column="76"/>
     </issue>
@@ -5534,7 +4632,7 @@
         errorLine1="        public double mDoubleCapability[] = new double[PhotoCapabilityDouble.NUM_ENTRIES];"
         errorLine2="                                                                             ~~~~~~~~~~~">
         <location
-            file="$SRC/media/capture/video/android/java/src/org/chromium/media/PhotoCapabilities.java"
+            file="../../media/capture/video/android/java/src/org/chromium/media/PhotoCapabilities.java"
             line="117"
             column="78"/>
     </issue>
@@ -5545,7 +4643,7 @@
         errorLine1="        public int mIntCapability[] = new int[PhotoCapabilityInt.NUM_ENTRIES];"
         errorLine2="                                                                 ~~~~~~~~~~~">
         <location
-            file="$SRC/media/capture/video/android/java/src/org/chromium/media/PhotoCapabilities.java"
+            file="../../media/capture/video/android/java/src/org/chromium/media/PhotoCapabilities.java"
             line="118"
             column="66"/>
     </issue>
@@ -5556,7 +4654,7 @@
         errorLine1="        public int mMeteringMode[] = new int[MeteringModeType.NUM_ENTRIES];"
         errorLine2="                                                              ~~~~~~~~~~~">
         <location
-            file="$SRC/media/capture/video/android/java/src/org/chromium/media/PhotoCapabilities.java"
+            file="../../media/capture/video/android/java/src/org/chromium/media/PhotoCapabilities.java"
             line="120"
             column="63"/>
     </issue>
@@ -5567,7 +4665,7 @@
         errorLine1="        public int mMeteringModeArray[][] = new int[MeteringModeType.NUM_ENTRIES][];"
         errorLine2="                                                                     ~~~~~~~~~~~">
         <location
-            file="$SRC/media/capture/video/android/java/src/org/chromium/media/PhotoCapabilities.java"
+            file="../../media/capture/video/android/java/src/org/chromium/media/PhotoCapabilities.java"
             line="121"
             column="70"/>
     </issue>
@@ -5578,7 +4676,7 @@
         errorLine1="                PriceTrackingState.COUNT);"
         errorLine2="                                   ~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkMetrics.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkMetrics.java"
             line="29"
             column="36"/>
     </issue>
@@ -5589,7 +4687,7 @@
         errorLine1="                PriceTrackingState.COUNT);"
         errorLine2="                                   ~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkMetrics.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkMetrics.java"
             line="37"
             column="36"/>
     </issue>
@@ -5600,8 +4698,8 @@
         errorLine1="                mPrivacySandboxReferrer, PrivacySandboxReferrer.COUNT);"
         errorLine2="                                                                ~~~~~">
         <location
-            file="$SRC/chrome/browser/privacy_sandbox/android/java/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandboxSettingsFragment.java"
-            line="186"
+            file="../../chrome/browser/privacy_sandbox/android/java/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandboxSettingsFragment.java"
+            line="130"
             column="65"/>
     </issue>
 
@@ -5611,8 +4709,8 @@
         errorLine1="                referrer, PrivacySandboxReferrer.COUNT);"
         errorLine2="                                                 ~~~~~">
         <location
-            file="$SRC/chrome/browser/privacy_sandbox/android/java/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandboxSettingsFragmentV3.java"
-            line="111"
+            file="../../chrome/browser/privacy_sandbox/android/java/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandboxSettingsFragmentV3.java"
+            line="112"
             column="50"/>
     </issue>
 
@@ -5622,7 +4720,7 @@
         errorLine1="        RecordHistogram.recordEnumeratedHistogram(umaName, reason, ExitReason.NUM_ENTRIES);"
         errorLine2="                                                                              ~~~~~~~~~~~">
         <location
-            file="$SRC/components/crash/android/java/src/org/chromium/components/crash/browser/ProcessExitReasonFromSystem.java"
+            file="../../components/crash/android/java/src/org/chromium/components/crash/browser/ProcessExitReasonFromSystem.java"
             line="137"
             column="79"/>
     </issue>
@@ -5633,8 +4731,8 @@
         errorLine1="                ShowQueryTilesSegmentationResultComparison.NUM_ENTRIES);"
         errorLine2="                                                           ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/query_tiles/QueryTileUtils.java"
-            line="202"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/query_tiles/QueryTileUtils.java"
+            line="216"
             column="60"/>
     </issue>
 
@@ -5644,8 +4742,8 @@
         errorLine1="                ShowQueryTilesSegmentationResult.NUM_ENTRIES);"
         errorLine2="                                                 ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/query_tiles/QueryTileUtils.java"
-            line="216"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/query_tiles/QueryTileUtils.java"
+            line="230"
             column="50"/>
     </issue>
 
@@ -5655,8 +4753,8 @@
         errorLine1="        return segmentationResult;"
         errorLine2="               ~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/query_tiles/QueryTileUtils.java"
-            line="255"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/query_tiles/QueryTileUtils.java"
+            line="269"
             column="16"/>
     </issue>
 
@@ -5666,8 +4764,8 @@
         errorLine1="        return segmentationResult;"
         errorLine2="               ~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/query_tiles/QueryTileUtils.java"
-            line="255"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/query_tiles/QueryTileUtils.java"
+            line="269"
             column="16"/>
     </issue>
 
@@ -5677,7 +4775,7 @@
         errorLine1="        mButtons = new ArrayList&lt;>(Collections.nCopies(ThemeType.NUM_ENTRIES, null));"
         errorLine2="                                                                 ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/settings/RadioButtonGroupThemePreference.java"
+            file="../../chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/settings/RadioButtonGroupThemePreference.java"
             line="54"
             column="66"/>
     </issue>
@@ -5688,7 +4786,7 @@
         errorLine1="        assert ThemeType.NUM_ENTRIES == 3;"
         errorLine2="                         ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/settings/RadioButtonGroupThemePreference.java"
+            file="../../chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/settings/RadioButtonGroupThemePreference.java"
             line="81"
             column="26"/>
     </issue>
@@ -5699,7 +4797,7 @@
         errorLine1="        for (int i = 0; i &lt; ThemeType.NUM_ENTRIES; i++) {"
         errorLine2="                                      ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/settings/RadioButtonGroupThemePreference.java"
+            file="../../chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/settings/RadioButtonGroupThemePreference.java"
             line="114"
             column="39"/>
     </issue>
@@ -5710,7 +4808,7 @@
         errorLine1="        assert mSetting >= 0 &amp;&amp; mSetting &lt; ThemeType.NUM_ENTRIES : &quot;No matching setting found.&quot;;"
         errorLine2="                                                     ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/settings/RadioButtonGroupThemePreference.java"
+            file="../../chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/settings/RadioButtonGroupThemePreference.java"
             line="121"
             column="54"/>
     </issue>
@@ -5721,7 +4819,7 @@
         errorLine1="        mButtons = new ArrayList&lt;>(Collections.nCopies(VideoPreviewsType.NUM_ENTRIES, null));"
         errorLine2="                                                                         ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/settings/RadioButtonGroupVideoPreviewsPreference.java"
+            file="../../chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/settings/RadioButtonGroupVideoPreviewsPreference.java"
             line="38"
             column="74"/>
     </issue>
@@ -5732,7 +4830,7 @@
         errorLine1="        assert VideoPreviewsType.NUM_ENTRIES == 3;"
         errorLine2="                                 ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/settings/RadioButtonGroupVideoPreviewsPreference.java"
+            file="../../chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/settings/RadioButtonGroupVideoPreviewsPreference.java"
             line="49"
             column="34"/>
     </issue>
@@ -5743,7 +4841,7 @@
         errorLine1="        for (int i = 0; i &lt; VideoPreviewsType.NUM_ENTRIES; i++) {"
         errorLine2="                                              ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/settings/RadioButtonGroupVideoPreviewsPreference.java"
+            file="../../chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/settings/RadioButtonGroupVideoPreviewsPreference.java"
             line="70"
             column="47"/>
     </issue>
@@ -5754,7 +4852,7 @@
         errorLine1="                &amp;&amp; mSetting &lt; VideoPreviewsType.NUM_ENTRIES : &quot;No matching setting found.&quot;;"
         errorLine2="                                                ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/settings/RadioButtonGroupVideoPreviewsPreference.java"
+            file="../../chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/settings/RadioButtonGroupVideoPreviewsPreference.java"
             line="77"
             column="49"/>
     </issue>
@@ -5765,7 +4863,7 @@
         errorLine1="                &quot;FeedVideoPreviewsPreferenceUserActions&quot;, mSetting, VideoPreviewsType.NUM_ENTRIES);"
         errorLine2="                                                                                      ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/settings/RadioButtonGroupVideoPreviewsPreference.java"
+            file="../../chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/settings/RadioButtonGroupVideoPreviewsPreference.java"
             line="80"
             column="87"/>
     </issue>
@@ -5776,8 +4874,8 @@
         errorLine1="            new ArrayMap&lt;>(FaviconLocality.NUM_ENTRIES);"
         errorLine2="                                           ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java"
-            line="127"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java"
+            line="126"
             column="44"/>
     </issue>
 
@@ -5787,8 +4885,8 @@
         errorLine1="                        OtherSessionsActions.COLLAPSE_SESSION, OtherSessionsActions.NUM_ENTRIES);"
         errorLine2="                                                                                    ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java"
-            line="332"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java"
+            line="331"
             column="85"/>
     </issue>
 
@@ -5798,8 +4896,8 @@
         errorLine1="                        OtherSessionsActions.EXPAND_SESSION, OtherSessionsActions.NUM_ENTRIES);"
         errorLine2="                                                                                  ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java"
-            line="335"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java"
+            line="334"
             column="83"/>
     </issue>
 
@@ -5809,8 +4907,8 @@
         errorLine1="                    OtherSessionsActions.LINK_CLICKED, OtherSessionsActions.NUM_ENTRIES);"
         errorLine2="                                                                            ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java"
-            line="348"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java"
+            line="347"
             column="77"/>
     </issue>
 
@@ -5820,8 +4918,8 @@
         errorLine1="                        OtherSessionsActions.OPEN_ALL, OtherSessionsActions.NUM_ENTRIES);"
         errorLine2="                                                                            ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java"
-            line="359"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java"
+            line="358"
             column="77"/>
     </issue>
 
@@ -5831,8 +4929,8 @@
         errorLine1="                        OtherSessionsActions.HIDE_FOR_NOW, OtherSessionsActions.NUM_ENTRIES);"
         errorLine2="                                                                                ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java"
-            line="365"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java"
+            line="364"
             column="81"/>
     </issue>
 
@@ -5842,8 +4940,8 @@
         errorLine1="                OtherSessionsActions.MENU_INITIALIZED, OtherSessionsActions.NUM_ENTRIES);"
         errorLine2="                                                                            ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java"
-            line="767"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java"
+            line="764"
             column="77"/>
     </issue>
 
@@ -5853,8 +4951,8 @@
         errorLine1="        return GroupType.NUM_ENTRIES;"
         errorLine2="                         ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java"
-            line="891"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java"
+            line="888"
             column="26"/>
     </issue>
 
@@ -5864,8 +4962,8 @@
         errorLine1="                        OtherSessionsActions.HAS_FOREIGN_DATA, OtherSessionsActions.NUM_ENTRIES);"
         errorLine2="                                                                                    ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java"
-            line="913"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java"
+            line="910"
             column="85"/>
     </issue>
 
@@ -5875,8 +4973,8 @@
         errorLine1="        return ChildType.NUM_ENTRIES;"
         errorLine2="                         ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java"
-            line="953"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java"
+            line="950"
             column="26"/>
     </issue>
 
@@ -5886,7 +4984,7 @@
         errorLine1="                permissionsEnum, Permissions.NUM_ENTRIES);"
         errorLine2="                                             ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/RelatedSearchesUma.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/RelatedSearchesUma.java"
             line="72"
             column="46"/>
     </issue>
@@ -5897,7 +4995,7 @@
         errorLine1="                scrollAndClickStatus, Permissions.NUM_ENTRIES);"
         errorLine2="                                                  ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/RelatedSearchesUma.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/RelatedSearchesUma.java"
             line="170"
             column="51"/>
     </issue>
@@ -5908,8 +5006,8 @@
         errorLine1="                    false, url, params.getTransitionType());"
         errorLine2="                                ~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/tasks/ReturnToChromeUtil.java"
-            line="354"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/tasks/ReturnToChromeUtil.java"
+            line="361"
             column="33"/>
     </issue>
 
@@ -5919,8 +5017,8 @@
         errorLine1="                ShowChromeStartSegmentationResult.NUM_ENTRIES);"
         errorLine2="                                                  ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/tasks/ReturnToChromeUtil.java"
-            line="751"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/tasks/ReturnToChromeUtil.java"
+            line="776"
             column="51"/>
     </issue>
 
@@ -5930,8 +5028,8 @@
         errorLine1="                ShowChromeStartSegmentationResultComparison.NUM_ENTRIES);"
         errorLine2="                                                            ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/tasks/ReturnToChromeUtil.java"
-            line="811"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/tasks/ReturnToChromeUtil.java"
+            line="836"
             column="61"/>
     </issue>
 
@@ -5941,7 +5039,7 @@
         errorLine1="        } else if (NoArgOperation.INSTALL == operation) {"
         errorLine2="                                  ~~~~~~~">
         <location
-            file="$SRC/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/screenshot/ScreenshotShareSheetMediator.java"
+            file="../../chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/screenshot/ScreenshotShareSheetMediator.java"
             line="91"
             column="35"/>
     </issue>
@@ -5952,7 +5050,7 @@
         errorLine1="                &quot;Sharing.ScreenshotFallback.Action&quot;, action, ScreenshotShareSheetAction.COUNT);"
         errorLine2="                                                                                        ~~~~~">
         <location
-            file="$SRC/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/screenshot/ScreenshotShareSheetMetrics.java"
+            file="../../chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/screenshot/ScreenshotShareSheetMetrics.java"
             line="41"
             column="89"/>
     </issue>
@@ -5963,7 +5061,7 @@
         errorLine1="        setNoArgOperationListener(NoArgOperation.INSTALL, R.id.edit, noArgOperationCallback);"
         errorLine2="                                                 ~~~~~~~">
         <location
-            file="$SRC/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/screenshot/ScreenshotShareSheetView.java"
+            file="../../chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/screenshot/ScreenshotShareSheetView.java"
             line="39"
             column="50"/>
     </issue>
@@ -5974,7 +5072,7 @@
         errorLine1="                &quot;Sharing.ScrollCapture.BitmapGeneratorStatus&quot;, status, BitmapGeneratorStatus.COUNT);"
         errorLine2="                                                                                             ~~~~~">
         <location
-            file="$SRC/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/scroll_capture/ScrollCaptureCallbackDelegate.java"
+            file="../../chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/scroll_capture/ScrollCaptureCallbackDelegate.java"
             line="210"
             column="94"/>
     </issue>
@@ -5985,7 +5083,7 @@
         errorLine1="                &quot;Android.SearchEngineChoice.Events&quot;, event, Events.MAX);"
         errorLine2="                                                                   ~~~">
         <location
-            file="$SRC/chrome/browser/search_engines/android/java/src/org/chromium/chrome/browser/search_engines/SearchEngineChoiceMetrics.java"
+            file="../../chrome/browser/search_engines/android/java/src/org/chromium/chrome/browser/search_engines/SearchEngineChoiceMetrics.java"
             line="64"
             column="68"/>
     </issue>
@@ -5996,7 +5094,7 @@
         errorLine1="                &quot;Android.SearchEngineChoice.EventsV2&quot;, event, EventsV2.MAX);"
         errorLine2="                                                                       ~~~">
         <location
-            file="$SRC/chrome/browser/search_engines/android/java/src/org/chromium/chrome/browser/search_engines/SearchEngineChoiceMetrics.java"
+            file="../../chrome/browser/search_engines/android/java/src/org/chromium/chrome/browser/search_engines/SearchEngineChoiceMetrics.java"
             line="74"
             column="72"/>
     </issue>
@@ -6007,8 +5105,8 @@
         errorLine1="                &quot;AndroidSearchEngineLogo.Events&quot;, event, Events.MAX);"
         errorLine2="                                                                ~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/SearchEngineLogoUtils.java"
-            line="333"
+            file="../../chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/SearchEngineLogoUtils.java"
+            line="342"
             column="65"/>
     </issue>
 
@@ -6018,8 +5116,8 @@
         errorLine1="                &quot;Android.SelectFileDialogContentSelected&quot;, action, FileSelectedAction.COUNT);"
         errorLine2="                                                                                      ~~~~~">
         <location
-            file="$SRC/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java"
-            line="1202"
+            file="../../ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java"
+            line="1223"
             column="87"/>
     </issue>
 
@@ -6029,7 +5127,7 @@
         errorLine1="    private int[] mPendingCommits = new int[ServicificationStartup.NUM_ENTRIES];"
         errorLine2="                                                                   ~~~~~~~~~~~">
         <location
-            file="$SRC/content/public/android/java/src/org/chromium/content/browser/ServicificationStartupUma.java"
+            file="../../content/public/android/java/src/org/chromium/content/browser/ServicificationStartupUma.java"
             line="38"
             column="68"/>
     </issue>
@@ -6040,7 +5138,7 @@
         errorLine1="        for (int i = 0; i &lt; ServicificationStartup.NUM_ENTRIES; i++) {"
         errorLine2="                                                   ~~~~~~~~~~~">
         <location
-            file="$SRC/content/public/android/java/src/org/chromium/content/browser/ServicificationStartupUma.java"
+            file="../../content/public/android/java/src/org/chromium/content/browser/ServicificationStartupUma.java"
             line="95"
             column="52"/>
     </issue>
@@ -6051,7 +5149,7 @@
         errorLine1="                &quot;Servicification.Startup2&quot;, startupMode, ServicificationStartup.NUM_ENTRIES);"
         errorLine2="                                                                                ~~~~~~~~~~~">
         <location
-            file="$SRC/content/public/android/java/src/org/chromium/content/browser/ServicificationStartupUma.java"
+            file="../../content/public/android/java/src/org/chromium/content/browser/ServicificationStartupUma.java"
             line="111"
             column="81"/>
     </issue>
@@ -6062,7 +5160,7 @@
         errorLine1="                ANY_SHARE_HISTOGRAM_NAME, source, ShareSourceAndroid.COUNT);"
         errorLine2="                                                                     ~~~~~">
         <location
-            file="$SRC/components/browser_ui/share/android/java/src/org/chromium/components/browser_ui/share/ShareHelper.java"
+            file="../../components/browser_ui/share/android/java/src/org/chromium/components/browser_ui/share/ShareHelper.java"
             line="447"
             column="70"/>
     </issue>
@@ -6073,7 +5171,7 @@
         errorLine1="                    confirmIntent, NotificationUmaTracker.ActionType.SHARING_CONFIRM);"
         errorLine2="                                                                     ~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/sharing/SharingNotificationUtil.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/sharing/SharingNotificationUtil.java"
             line="86"
             column="70"/>
     </issue>
@@ -6084,7 +5182,7 @@
         errorLine1="                    cancelIntent, NotificationUmaTracker.ActionType.SHARING_CANCEL);"
         errorLine2="                                                                    ~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/sharing/SharingNotificationUtil.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/sharing/SharingNotificationUtil.java"
             line="90"
             column="69"/>
     </issue>
@@ -6095,8 +5193,8 @@
         errorLine1="                foundBuyableProductAnnotation, FoundBuyableProductAnnotation.NUM_ENTRIES);"
         errorLine2="                                                                             ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/ShoppingPersistedTabData.java"
-            line="668"
+            file="../../chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/ShoppingPersistedTabData.java"
+            line="681"
             column="78"/>
     </issue>
 
@@ -6106,30 +5204,19 @@
         errorLine1="                FoundBuyableProduct.NUM_ENTRIES);"
         errorLine2="                                    ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/ShoppingPersistedTabData.java"
-            line="710"
+            file="../../chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/ShoppingPersistedTabData.java"
+            line="727"
             column="37"/>
     </issue>
 
     <issue
         id="WrongConstant"
-        message="Must be one of: Type.ALL_SITES, Type.ADS, Type.AUGMENTED_REALITY, Type.AUTOMATIC_DOWNLOADS, Type.BACKGROUND_SYNC, Type.BLUETOOTH, Type.BLUETOOTH_SCANNING, Type.CAMERA, Type.CLIPBOARD, Type.COOKIES, Type.IDLE_DETECTION, Type.DEVICE_LOCATION, Type.JAVASCRIPT, Type.MICROPHONE, Type.NFC, Type.NOTIFICATIONS, Type.POPUPS, Type.PROTECTED_MEDIA, Type.SENSORS, Type.SOUND, Type.USB, Type.VIRTUAL_REALITY, Type.USE_STORAGE, Type.AUTO_DARK_WEB_CONTENT, Type.REQUEST_DESKTOP_SITE, Type.FEDERATED_IDENTITY_API"
-        errorLine1="        for (@SiteSettingsCategory.Type int i = 0; i &lt; SiteSettingsCategory.Type.NUM_ENTRIES; i++) {"
-        errorLine2="                                                                                 ~~~~~~~~~~~">
-        <location
-            file="$SRC/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleCategorySettings.java"
-            line="213"
-            column="82"/>
-    </issue>
-
-    <issue
-        id="WrongConstant"
         message="Must be one of: SettingsNavigationSource.OTHER, SettingsNavigationSource.TWA_CLEAR_DATA_DIALOG, SettingsNavigationSource.TWA_MANAGE_SPACE_ACTIVITY"
         errorLine1="                        SettingsNavigationSource.EXTRA_KEY, SettingsNavigationSource.OTHER);"
         errorLine2="                                                 ~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleCategorySettings.java"
-            line="434"
+            file="../../components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleCategorySettings.java"
+            line="462"
             column="50"/>
     </issue>
 
@@ -6139,8 +5226,8 @@
         errorLine1="                        SettingsNavigationSource.EXTRA_KEY, navigationSource);"
         errorLine2="                                                 ~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleCategorySettings.java"
-            line="436"
+            file="../../components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleCategorySettings.java"
+            line="464"
             column="50"/>
     </issue>
 
@@ -6150,8 +5237,8 @@
         errorLine1="                    type &lt; SiteSettingsCategory.Type.NUM_ENTRIES; type++) {"
         errorLine2="                                                     ~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleCategorySettings.java"
-            line="469"
+            file="../../components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleCategorySettings.java"
+            line="501"
             column="54"/>
     </issue>
 
@@ -6161,8 +5248,8 @@
         errorLine1="                &quot;Android.RequestDesktopSite.Changed&quot;, layout, SiteLayout.NUM_ENTRIES);"
         errorLine2="                                                                         ~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleCategorySettings.java"
-            line="1161"
+            file="../../components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleCategorySettings.java"
+            line="1271"
             column="74"/>
     </issue>
 
@@ -6172,8 +5259,8 @@
         errorLine1="                SettingsNavigationSource.EXTRA_KEY, SettingsNavigationSource.OTHER);"
         errorLine2="                                         ~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java"
-            line="1159"
+            file="../../components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java"
+            line="1221"
             column="42"/>
     </issue>
 
@@ -6183,8 +5270,8 @@
         errorLine1="                navigationSource, SettingsNavigationSource.NUM_ENTRIES);"
         errorLine2="                                                           ~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java"
-            line="1161"
+            file="../../components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java"
+            line="1223"
             column="60"/>
     </issue>
 
@@ -6194,7 +5281,7 @@
         errorLine1="        for (@SiteSettingsCategory.Type int type = 0; type &lt; SiteSettingsCategory.Type.NUM_ENTRIES;"
         errorLine2="                                                                                       ~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettings.java"
+            file="../../components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettings.java"
             line="52"
             column="88"/>
     </issue>
@@ -6205,7 +5292,7 @@
         errorLine1="        for (@Type int prefCategory = 0; prefCategory &lt; Type.NUM_ENTRIES; prefCategory++) {"
         errorLine2="                                                             ~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettings.java"
+            file="../../components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettings.java"
             line="65"
             column="62"/>
     </issue>
@@ -6216,7 +5303,7 @@
         errorLine1="        for (@Type int i = Type.ALL_SITES; i &lt; Type.NUM_ENTRIES; i++) {"
         errorLine2="                                                    ~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsCategory.java"
+            file="../../components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsCategory.java"
             line="132"
             column="53"/>
     </issue>
@@ -6227,7 +5314,7 @@
         errorLine1="        for (@Type int i = Type.ALL_SITES; i &lt; Type.NUM_ENTRIES; i++) {"
         errorLine2="                                                    ~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsCategory.java"
+            file="../../components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsCategory.java"
             line="143"
             column="53"/>
     </issue>
@@ -6238,7 +5325,7 @@
         errorLine1="                &quot;SpecialLocale.PromotionDialog&quot;, mChoice, UserChoice.NUM_ENTRIES);"
         errorLine2="                                                                     ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/search_engines/android/java/src/org/chromium/chrome/browser/search_engines/SogouPromoDialog.java"
+            file="../../chrome/browser/search_engines/android/java/src/org/chromium/chrome/browser/search_engines/SogouPromoDialog.java"
             line="139"
             column="70"/>
     </issue>
@@ -6249,29 +5336,18 @@
         errorLine1="                &quot;Browser.PaintPreview.TabbedPlayer.ExitCause&quot;, exitCause, ExitCause.COUNT);"
         errorLine2="                                                                                    ~~~~~">
         <location
-            file="$SRC/chrome/browser/paint_preview/android/java/src/org/chromium/chrome/browser/paint_preview/StartupPaintPreviewMetrics.java"
+            file="../../chrome/browser/paint_preview/android/java/src/org/chromium/chrome/browser/paint_preview/StartupPaintPreviewMetrics.java"
             line="131"
             column="85"/>
     </issue>
 
     <issue
         id="WrongConstant"
-        message="Must be one of: ApiCall.ADD_WEB_MESSAGE_LISTENER, ApiCall.CLEAR_PROXY_OVERRIDE, ApiCall.GET_PROXY_CONTROLLER, ApiCall.GET_SAFE_BROWSING_PRIVACY_POLICY_URL, ApiCall.GET_SERVICE_WORKER_CONTROLLER, ApiCall.GET_SERVICE_WORKER_WEB_SETTINGS, ApiCall.GET_TRACING_CONTROLLER, ApiCall.GET_WEBCHROME_CLIENT, ApiCall.GET_WEBVIEW_CLIENT, ApiCall.GET_WEBVIEW_RENDERER, ApiCall.GET_WEBVIEW_RENDERER_CLIENT, ApiCall.INIT_SAFE_BROWSING, ApiCall.INSERT_VISUAL_STATE_CALLBACK, ApiCall.IS_MULTI_PROCESS_ENABLED, ApiCall.JS_REPLY_POST_MESSAGE, ApiCall.POST_MESSAGE_TO_MAIN_FRAME, ApiCall.REMOVE_WEB_MESSAGE_LISTENER, ApiCall.SERVICE_WORKER_SETTINGS_GET_ALLOW_CONTENT_ACCESS, ApiCall.SERVICE_WORKER_SETTINGS_GET_ALLOW_FILE_ACCESS, ApiCall.SERVICE_WORKER_SETTINGS_GET_BLOCK_NETWORK_LOADS, ApiCall.SERVICE_WORKER_SETTINGS_GET_CACHE_MODE, ApiCall.SERVICE_WORKER_SETTINGS_SET_ALLOW_CONTENT_ACCESS, ApiCall.SERVICE_WORKER_SETTINGS_SET_ALLOW_FILE_ACCESS, ApiCall.SERVICE_WORKER_SETTINGS_SET_BLOCK_NETWORK_LOADS, ApiCall.SERVICE_WORKER_SETTINGS_SET_CACHE_MODE, ApiCall.SET_PROXY_OVERRIDE, ApiCall.SET_SAFE_BROWSING_ALLOWLIST_DEPRECATED_NAME, ApiCall.SET_SERVICE_WORKER_CLIENT, ApiCall.SET_WEBVIEW_RENDERER_CLIENT, ApiCall.TRACING_CONTROLLER_IS_TRACING, ApiCall.TRACING_CONTROLLER_START, ApiCall.TRACING_CONTROLLER_STOP, ApiCall.WEB_MESSAGE_GET_DATA, ApiCall.WEB_MESSAGE_GET_PORTS, ApiCall.WEB_MESSAGE_PORT_CLOSE, ApiCall.WEB_MESSAGE_PORT_POST_MESSAGE, ApiCall.WEB_MESSAGE_PORT_SET_CALLBACK, ApiCall.WEB_MESSAGE_PORT_SET_CALLBACK_WITH_HANDLER, ApiCall.WEB_RESOURCE_REQUEST_IS_REDIRECT, ApiCall.WEB_SETTINGS_GET_DISABLED_ACTION_MODE_MENU_ITEMS, ApiCall.WEB_SETTINGS_GET_FORCE_DARK, ApiCall.WEB_SETTINGS_GET_FORCE_DARK_BEHAVIOR, ApiCall.WEB_SETTINGS_GET_OFFSCREEN_PRE_RASTER, ApiCall.WEB_SETTINGS_GET_SAFE_BROWSING_ENABLED, ApiCall.WEB_SETTINGS_GET_WILL_SUPPRESS_ERROR_PAGE, ApiCall.WEB_SETTINGS_SET_DISABLED_ACTION_MODE_MENU_ITEMS, ApiCall.WEB_SETTINGS_SET_FORCE_DARK, ApiCall.WEB_SETTINGS_SET_FORCE_DARK_BEHAVIOR, ApiCall.WEB_SETTINGS_SET_OFFSCREEN_PRE_RASTER, ApiCall.WEB_SETTINGS_SET_SAFE_BROWSING_ENABLED, ApiCall.WEB_SETTINGS_SET_WILL_SUPPRESS_ERROR_PAGE, ApiCall.WEBVIEW_RENDERER_TERMINATE, ApiCall.ADD_DOCUMENT_START_SCRIPT, ApiCall.REMOVE_DOCUMENT_START_SCRIPT, ApiCall.SET_SAFE_BROWSING_ALLOWLIST, ApiCall.SET_PROXY_OVERRIDE_REVERSE_BYPASS, ApiCall.WEB_SETTINGS_SET_REQUESTED_WITH_HEADER_MODE, ApiCall.WEB_SETTINGS_GET_REQUESTED_WITH_HEADER_MODE, ApiCall.SERVICE_WORKER_SETTINGS_SET_REQUESTED_WITH_HEADER_MODE, ApiCall.SERVICE_WORKER_SETTINGS_GET_REQUESTED_WITH_HEADER_MODE, ApiCall.GET_VARIATIONS_HEADER"
-        errorLine1="                &quot;Android.WebView.AndroidX.ApiCall&quot;, apiCall, ApiCall.COUNT);"
-        errorLine2="                                                                     ~~~~~">
-        <location
-            file="$SRC/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebViewChromiumFactory.java"
-            line="230"
-            column="70"/>
-    </issue>
-
-    <issue
-        id="WrongConstant"
         message="Must be one of: ScrollDirection.LEFT, ScrollDirection.RIGHT, ScrollDirection.UP, ScrollDirection.DOWN"
         errorLine1="    private int mDirection = ScrollDirection.UNKNOWN;"
         errorLine2="                             ~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
+            file="../../components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
             line="111"
             column="30"/>
     </issue>
@@ -6282,7 +5358,7 @@
         errorLine1="    private int mDirection = ScrollDirection.UNKNOWN;"
         errorLine2="                                             ~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
+            file="../../components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
             line="111"
             column="46"/>
     </issue>
@@ -6293,7 +5369,7 @@
         errorLine1="                    &amp;&amp; mDirection != ScrollDirection.UNKNOWN) {"
         errorLine2="                       ~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
+            file="../../components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
             line="160"
             column="24"/>
     </issue>
@@ -6304,7 +5380,7 @@
         errorLine1="                    &amp;&amp; mDirection != ScrollDirection.UNKNOWN) {"
         errorLine2="                                                     ~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
+            file="../../components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
             line="160"
             column="54"/>
     </issue>
@@ -6315,7 +5391,7 @@
         errorLine1="                mDirection = ScrollDirection.UNKNOWN;"
         errorLine2="                ~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
+            file="../../components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
             line="162"
             column="17"/>
     </issue>
@@ -6326,7 +5402,7 @@
         errorLine1="                mDirection = ScrollDirection.UNKNOWN;"
         errorLine2="                             ~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
+            file="../../components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
             line="162"
             column="30"/>
     </issue>
@@ -6337,7 +5413,7 @@
         errorLine1="                mDirection = ScrollDirection.UNKNOWN;"
         errorLine2="                                             ~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
+            file="../../components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
             line="162"
             column="46"/>
     </issue>
@@ -6348,7 +5424,7 @@
         errorLine1="        if (mDirection == ScrollDirection.UNKNOWN &amp;&amp; shouldRecognizeSwipe(e1, e2)) {"
         errorLine2="            ~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
+            file="../../components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
             line="193"
             column="13"/>
     </issue>
@@ -6359,7 +5435,7 @@
         errorLine1="        if (mDirection == ScrollDirection.UNKNOWN &amp;&amp; shouldRecognizeSwipe(e1, e2)) {"
         errorLine2="                                          ~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
+            file="../../components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
             line="193"
             column="43"/>
     </issue>
@@ -6370,7 +5446,7 @@
         errorLine1="            int direction = ScrollDirection.UNKNOWN;"
         errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
+            file="../../components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
             line="198"
             column="29"/>
     </issue>
@@ -6381,7 +5457,7 @@
         errorLine1="            int direction = ScrollDirection.UNKNOWN;"
         errorLine2="                                            ~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
+            file="../../components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
             line="198"
             column="45"/>
     </issue>
@@ -6392,7 +5468,7 @@
         errorLine1="                direction = tx > 0.f ? ScrollDirection.RIGHT : ScrollDirection.LEFT;"
         errorLine2="                ~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
+            file="../../components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
             line="205"
             column="17"/>
     </issue>
@@ -6403,7 +5479,7 @@
         errorLine1="            if (direction != ScrollDirection.UNKNOWN &amp;&amp; mHandler.isSwipeEnabled(direction)) {"
         errorLine2="                                             ~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
+            file="../../components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
             line="210"
             column="46"/>
     </issue>
@@ -6414,7 +5490,7 @@
         errorLine1="                mDirection = direction;"
         errorLine2="                ~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
+            file="../../components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
             line="211"
             column="17"/>
     </issue>
@@ -6425,7 +5501,7 @@
         errorLine1="        if (mDirection != ScrollDirection.UNKNOWN) {"
         errorLine2="            ~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
+            file="../../components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
             line="217"
             column="13"/>
     </issue>
@@ -6436,7 +5512,7 @@
         errorLine1="        if (mDirection != ScrollDirection.UNKNOWN) {"
         errorLine2="                                          ~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
+            file="../../components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
             line="217"
             column="43"/>
     </issue>
@@ -6447,7 +5523,7 @@
         errorLine1="        if (mDirection != ScrollDirection.UNKNOWN) {"
         errorLine2="            ~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
+            file="../../components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
             line="230"
             column="13"/>
     </issue>
@@ -6458,7 +5534,7 @@
         errorLine1="        if (mDirection != ScrollDirection.UNKNOWN) {"
         errorLine2="                                          ~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
+            file="../../components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
             line="230"
             column="43"/>
     </issue>
@@ -6469,7 +5545,7 @@
         errorLine1="            mHandler.onFling(mDirection, e2, e2.getRawX() - mMotionStartPoint.x,"
         errorLine2="                             ~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
+            file="../../components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
             line="231"
             column="30"/>
     </issue>
@@ -6480,7 +5556,7 @@
         errorLine1="            mHandler.onFling(mDirection, e2, e2.getRawX() - mMotionStartPoint.x,"
         errorLine2="                             ~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
+            file="../../components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java"
             line="231"
             column="30"/>
     </issue>
@@ -6491,8 +5567,8 @@
         errorLine1="        if (authErrorCode &lt; 0 || authErrorCode >= GoogleServiceAuthError.State.NUM_ENTRIES) {"
         errorLine2="                                                                               ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/sync/android/java/src/org/chromium/chrome/browser/sync/SyncServiceImpl.java"
-            line="97"
+            file="../../chrome/browser/sync/android/java/src/org/chromium/chrome/browser/sync/SyncServiceImpl.java"
+            line="96"
             column="80"/>
     </issue>
 
@@ -6502,8 +5578,8 @@
         errorLine1="                UMA_THUMBNAIL_FETCHING_RESULT, result, ThumbnailFetchingResult.NUM_ENTRIES);"
         errorLine2="                                                                               ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManager.java"
-            line="497"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManager.java"
+            line="540"
             column="80"/>
     </issue>
 
@@ -6513,8 +5589,8 @@
         errorLine1="                    ConditionalTabStripUtils.ReasonToShow.NUM_ENTRIES);"
         errorLine2="                                                          ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediator.java"
-            line="598"
+            file="../../chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediator.java"
+            line="593"
             column="59"/>
     </issue>
 
@@ -6524,7 +5600,7 @@
         errorLine1="            return IntentHandler.BringToFrontSource.INVALID;"
         errorLine2="                                                    ~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/app/metrics/TabbedActivityLaunchCauseMetrics.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/app/metrics/TabbedActivityLaunchCauseMetrics.java"
             line="143"
             column="53"/>
     </issue>
@@ -6535,7 +5611,7 @@
         errorLine1="                IntentHandler.BringToFrontSource.INVALID);"
         errorLine2="                                                 ~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/app/metrics/TabbedActivityLaunchCauseMetrics.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/app/metrics/TabbedActivityLaunchCauseMetrics.java"
             line="146"
             column="50"/>
     </issue>
@@ -6546,7 +5622,7 @@
         errorLine1="                TranslateAssistContentResult.NUM_ENTRIES);"
         errorLine2="                                             ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/translate/TranslateAssistContent.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/translate/TranslateAssistContent.java"
             line="68"
             column="46"/>
     </issue>
@@ -6557,7 +5633,7 @@
         errorLine1="                &quot;Translate.TranslateTabIntentResult&quot;, result, TranslateTabIntentResult.NUM_ENTRIES);"
         errorLine2="                                                                                       ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/translate/TranslateIntentHandler.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/translate/TranslateIntentHandler.java"
             line="82"
             column="88"/>
     </issue>
@@ -6568,7 +5644,7 @@
         errorLine1="        assert Type.NUM_ENTRIES == 3;"
         errorLine2="                    ~~~~~~~~~~~">
         <location
-            file="$SRC/components/translate/content/android/java/src/org/chromium/components/translate/TranslateOptions.java"
+            file="../../components/translate/content/android/java/src/org/chromium/components/translate/TranslateOptions.java"
             line="105"
             column="21"/>
     </issue>
@@ -6579,7 +5655,7 @@
         errorLine1="        mOptions = new boolean[Type.NUM_ENTRIES];"
         errorLine2="                                    ~~~~~~~~~~~">
         <location
-            file="$SRC/components/translate/content/android/java/src/org/chromium/components/translate/TranslateOptions.java"
+            file="../../components/translate/content/android/java/src/org/chromium/components/translate/TranslateOptions.java"
             line="106"
             column="37"/>
     </issue>
@@ -6590,7 +5666,7 @@
         errorLine1="        extras.putInt(SettingsNavigationSource.EXTRA_KEY,"
         errorLine2="                                               ~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/browserservices/TrustedWebActivitySettingsLauncher.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/browserservices/TrustedWebActivitySettingsLauncher.java"
             line="108"
             column="48"/>
     </issue>
@@ -6601,7 +5677,7 @@
         errorLine1="        args.putInt(SettingsNavigationSource.EXTRA_KEY, navigationSource);"
         errorLine2="                                             ~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/browserservices/TrustedWebActivitySettingsLauncher.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/browserservices/TrustedWebActivitySettingsLauncher.java"
             line="121"
             column="46"/>
     </issue>
@@ -6612,7 +5688,7 @@
         errorLine1="                DelegatedNotificationSmallIconFallback.NUM_ENTRIES);"
         errorLine2="                                                       ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/android/browserservices/metrics/java/src/org/chromium/chrome/browser/browserservices/metrics/TrustedWebActivityUmaRecorder.java"
+            file="../../chrome/browser/android/browserservices/metrics/java/src/org/chromium/chrome/browser/browserservices/metrics/TrustedWebActivityUmaRecorder.java"
             line="159"
             column="56"/>
     </issue>
@@ -6623,8 +5699,8 @@
         errorLine1="                &quot;TrustedWebActivity.ShareTargetRequest&quot;, method, ShareRequestMethod.NUM_ENTRIES);"
         errorLine2="                                                                                    ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/android/browserservices/metrics/java/src/org/chromium/chrome/browser/browserservices/metrics/TrustedWebActivityUmaRecorder.java"
-            line="181"
+            file="../../chrome/browser/android/browserservices/metrics/java/src/org/chromium/chrome/browser/browserservices/metrics/TrustedWebActivityUmaRecorder.java"
+            line="191"
             column="85"/>
     </issue>
 
@@ -6634,8 +5710,8 @@
         errorLine1="                    PermissionChanged.NUM_ENTRIES);"
         errorLine2="                                      ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/android/browserservices/metrics/java/src/org/chromium/chrome/browser/browserservices/metrics/TrustedWebActivityUmaRecorder.java"
-            line="218"
+            file="../../chrome/browser/android/browserservices/metrics/java/src/org/chromium/chrome/browser/browserservices/metrics/TrustedWebActivityUmaRecorder.java"
+            line="228"
             column="39"/>
     </issue>
 
@@ -6645,8 +5721,8 @@
         errorLine1="                AudioPermissionState.NUM_ENTRIES);"
         errorLine2="                                     ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/metrics/UmaSessionStats.java"
-            line="148"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/metrics/UmaSessionStats.java"
+            line="133"
             column="38"/>
     </issue>
 
@@ -6656,7 +5732,7 @@
         errorLine1="                &quot;Android.DownloadManager.List.View.Action&quot;, action, ViewAction.NUM_ENTRIES);"
         errorLine2="                                                                               ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/metrics/UmaUtils.java"
+            file="../../chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/metrics/UmaUtils.java"
             line="119"
             column="80"/>
     </issue>
@@ -6667,7 +5743,7 @@
         errorLine1="                &quot;Android.DownloadManager.Menu.Action&quot;, action, MenuAction.NUM_ENTRIES);"
         errorLine2="                                                                          ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/metrics/UmaUtils.java"
+            file="../../chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/metrics/UmaUtils.java"
             line="152"
             column="75"/>
     </issue>
@@ -6678,7 +5754,7 @@
         errorLine1="                    filterType, Filters.FilterType.NUM_ENTRIES);"
         errorLine2="                                                   ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/metrics/UmaUtils.java"
+            file="../../chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/metrics/UmaUtils.java"
             line="189"
             column="52"/>
     </issue>
@@ -6689,7 +5765,7 @@
         errorLine1="                &quot;Android.Download.Rename.Dialog.Action&quot;, action, RenameDialogAction.NUM_ENTRIES);"
         errorLine2="                                                                                    ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/metrics/UmaUtils.java"
+            file="../../chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/metrics/UmaUtils.java"
             line="248"
             column="85"/>
     </issue>
@@ -6700,7 +5776,7 @@
         errorLine1="                    &quot;GoogleUpdate.StartUp.State&quot;, mStatus.updateState, UpdateState.NUM_ENTRIES);"
         errorLine2="                                                                                   ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/omaha/UpdateStatusProvider.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/omaha/UpdateStatusProvider.java"
             line="224"
             column="84"/>
     </issue>
@@ -6711,8 +5787,8 @@
         errorLine1="                    mCaptureFormat.getHeight(), mCaptureFormat.getPixelFormat(), 2 /* maxImages */);"
         errorLine2="                                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/media/capture/video/android/java/src/org/chromium/media/VideoCaptureCamera2.java"
-            line="1074"
+            file="../../media/capture/video/android/java/src/org/chromium/media/VideoCaptureCamera2.java"
+            line="1072"
             column="49"/>
     </issue>
 
@@ -6722,7 +5798,7 @@
         errorLine1="                UserAction.NUM_ENTRIES);"
         errorLine2="                           ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/video_tutorials/android/java/src/org/chromium/chrome/browser/video_tutorials/metrics/VideoTutorialMetrics.java"
+            file="../../chrome/browser/video_tutorials/android/java/src/org/chromium/chrome/browser/video_tutorials/metrics/VideoTutorialMetrics.java"
             line="74"
             column="28"/>
     </issue>
@@ -6733,7 +5809,7 @@
         errorLine1="                WatchState.NUM_ENTRIES);"
         errorLine2="                           ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/video_tutorials/android/java/src/org/chromium/chrome/browser/video_tutorials/metrics/VideoTutorialMetrics.java"
+            file="../../chrome/browser/video_tutorials/android/java/src/org/chromium/chrome/browser/video_tutorials/metrics/VideoTutorialMetrics.java"
             line="86"
             column="28"/>
     </issue>
@@ -6744,7 +5820,7 @@
         errorLine1="                &quot;VideoTutorials.LanguagePicker.Action&quot;, action, LanguagePickerAction.NUM_ENTRIES);"
         errorLine2="                                                                                     ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/video_tutorials/android/java/src/org/chromium/chrome/browser/video_tutorials/metrics/VideoTutorialMetrics.java"
+            file="../../chrome/browser/video_tutorials/android/java/src/org/chromium/chrome/browser/video_tutorials/metrics/VideoTutorialMetrics.java"
             line="92"
             column="86"/>
     </issue>
@@ -6755,8 +5831,8 @@
         errorLine1="                &quot;VoiceInteraction.StartEventSource&quot;, source, VoiceInteractionSource.NUM_ENTRIES);"
         errorLine2="                                                                                    ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/voice/VoiceRecognitionHandler.java"
-            line="1085"
+            file="../../chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/voice/VoiceRecognitionHandler.java"
+            line="1092"
             column="85"/>
     </issue>
 
@@ -6766,8 +5842,8 @@
         errorLine1="                &quot;VoiceInteraction.StartEventTarget&quot;, target, VoiceIntentTarget.NUM_ENTRIES);"
         errorLine2="                                                                               ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/voice/VoiceRecognitionHandler.java"
-            line="1087"
+            file="../../chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/voice/VoiceRecognitionHandler.java"
+            line="1094"
             column="80"/>
     </issue>
 
@@ -6777,8 +5853,8 @@
         errorLine1="                &quot;VoiceInteraction.FinishEventSource&quot;, source, VoiceInteractionSource.NUM_ENTRIES);"
         errorLine2="                                                                                     ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/voice/VoiceRecognitionHandler.java"
-            line="1101"
+            file="../../chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/voice/VoiceRecognitionHandler.java"
+            line="1108"
             column="86"/>
     </issue>
 
@@ -6788,8 +5864,8 @@
         errorLine1="                &quot;VoiceInteraction.FinishEventTarget&quot;, target, VoiceIntentTarget.NUM_ENTRIES);"
         errorLine2="                                                                                ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/voice/VoiceRecognitionHandler.java"
-            line="1103"
+            file="../../chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/voice/VoiceRecognitionHandler.java"
+            line="1110"
             column="81"/>
     </issue>
 
@@ -6799,8 +5875,8 @@
         errorLine1="                VoiceInteractionSource.NUM_ENTRIES);"
         errorLine2="                                       ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/voice/VoiceRecognitionHandler.java"
-            line="1117"
+            file="../../chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/voice/VoiceRecognitionHandler.java"
+            line="1124"
             column="40"/>
     </issue>
 
@@ -6810,8 +5886,8 @@
         errorLine1="                &quot;VoiceInteraction.DismissedEventTarget&quot;, target, VoiceIntentTarget.NUM_ENTRIES);"
         errorLine2="                                                                                   ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/voice/VoiceRecognitionHandler.java"
-            line="1119"
+            file="../../chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/voice/VoiceRecognitionHandler.java"
+            line="1126"
             column="84"/>
     </issue>
 
@@ -6821,8 +5897,8 @@
         errorLine1="                &quot;VoiceInteraction.FailureEventSource&quot;, source, VoiceInteractionSource.NUM_ENTRIES);"
         errorLine2="                                                                                      ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/voice/VoiceRecognitionHandler.java"
-            line="1133"
+            file="../../chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/voice/VoiceRecognitionHandler.java"
+            line="1140"
             column="87"/>
     </issue>
 
@@ -6832,8 +5908,8 @@
         errorLine1="                &quot;VoiceInteraction.FailureEventTarget&quot;, target, VoiceIntentTarget.NUM_ENTRIES);"
         errorLine2="                                                                                 ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/voice/VoiceRecognitionHandler.java"
-            line="1135"
+            file="../../chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/voice/VoiceRecognitionHandler.java"
+            line="1142"
             column="82"/>
     </issue>
 
@@ -6843,8 +5919,8 @@
         errorLine1="                VoiceInteractionSource.NUM_ENTRIES);"
         errorLine2="                                       ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/voice/VoiceRecognitionHandler.java"
-            line="1149"
+            file="../../chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/voice/VoiceRecognitionHandler.java"
+            line="1156"
             column="40"/>
     </issue>
 
@@ -6854,8 +5930,8 @@
         errorLine1="                &quot;VoiceInteraction.UnexpectedResultTarget&quot;, target, VoiceIntentTarget.NUM_ENTRIES);"
         errorLine2="                                                                                     ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/voice/VoiceRecognitionHandler.java"
-            line="1151"
+            file="../../chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/voice/VoiceRecognitionHandler.java"
+            line="1158"
             column="86"/>
     </issue>
 
@@ -6865,8 +5941,8 @@
         errorLine1="                    AssistantActionPerformed.NUM_ENTRIES);"
         errorLine2="                                             ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/voice/VoiceRecognitionHandler.java"
-            line="1166"
+            file="../../chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/voice/VoiceRecognitionHandler.java"
+            line="1173"
             column="46"/>
     </issue>
 
@@ -6876,8 +5952,8 @@
         errorLine1="                permissionsState, AudioPermissionState.NUM_ENTRIES);"
         errorLine2="                                                       ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/voice/VoiceRecognitionHandler.java"
-            line="1257"
+            file="../../chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/voice/VoiceRecognitionHandler.java"
+            line="1264"
             column="56"/>
     </issue>
 
@@ -6887,7 +5963,7 @@
         errorLine1="                            .createNotificationWrapperBuilder(ChromeChannelDefinitions.ChannelId.VR)"
         errorLine2="                                                                                                 ~~">
         <location
-            file="$SRC/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrFallbackUtils.java"
+            file="../../chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrFallbackUtils.java"
             line="33"
             column="98"/>
     </issue>
@@ -6898,7 +5974,7 @@
         errorLine1="                WEBCONTENTS_STATUS_HISTOGRAM, status, WebContentsStatus.NUM_ENTRIES);"
         errorLine2="                                                                        ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/WarmupManager.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/WarmupManager.java"
             line="383"
             column="73"/>
     </issue>
@@ -6909,7 +5985,7 @@
         errorLine1="                HISTOGRAM_UPDATE_REQUEST_SENT, type, UpdateRequestSent.NUM_ENTRIES);"
         errorLine2="                                                                       ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/android/browserservices/metrics/java/src/org/chromium/chrome/browser/browserservices/metrics/WebApkUmaRecorder.java"
+            file="../../chrome/browser/android/browserservices/metrics/java/src/org/chromium/chrome/browser/browserservices/metrics/WebApkUmaRecorder.java"
             line="116"
             column="72"/>
     </issue>
@@ -6920,7 +5996,7 @@
         errorLine1="                HISTOGRAM_UPDATE_REQUEST_QUEUED, times, UpdateRequestQueued.NUM_ENTRIES);"
         errorLine2="                                                                            ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/android/browserservices/metrics/java/src/org/chromium/chrome/browser/browserservices/metrics/WebApkUmaRecorder.java"
+            file="../../chrome/browser/android/browserservices/metrics/java/src/org/chromium/chrome/browser/browserservices/metrics/WebApkUmaRecorder.java"
             line="126"
             column="77"/>
     </issue>
@@ -6931,8 +6007,8 @@
         errorLine1="                GooglePlayInstallResult.NUM_ENTRIES);"
         errorLine2="                                        ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/android/browserservices/metrics/java/src/org/chromium/chrome/browser/browserservices/metrics/WebApkUmaRecorder.java"
-            line="168"
+            file="../../chrome/browser/android/browserservices/metrics/java/src/org/chromium/chrome/browser/browserservices/metrics/WebApkUmaRecorder.java"
+            line="175"
             column="41"/>
     </issue>
 
@@ -6942,8 +6018,8 @@
         errorLine1="                GooglePlayInstallResult.NUM_ENTRIES);"
         errorLine2="                                        ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/android/browserservices/metrics/java/src/org/chromium/chrome/browser/browserservices/metrics/WebApkUmaRecorder.java"
-            line="185"
+            file="../../chrome/browser/android/browserservices/metrics/java/src/org/chromium/chrome/browser/browserservices/metrics/WebApkUmaRecorder.java"
+            line="192"
             column="41"/>
     </issue>
 
@@ -6953,7 +6029,7 @@
         errorLine1="                ThemeSettingsEntry.AUTO_DARK_MODE_DIALOG);"
         errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/WebContentsDarkModeMessageController.java"
+            file="../../chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/WebContentsDarkModeMessageController.java"
             line="323"
             column="36"/>
     </issue>
@@ -6964,7 +6040,7 @@
         errorLine1="                &quot;Blink.Sms.Receive.Infobar&quot;, action, InfobarAction.NUM_ENTRIES);"
         errorLine2="                                                                   ~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/sms/android/java/src/org/chromium/components/browser_ui/sms/WebOTPServiceUma.java"
+            file="../../components/browser_ui/sms/android/java/src/org/chromium/components/browser_ui/sms/WebOTPServiceUma.java"
             line="30"
             column="68"/>
     </issue>
@@ -6975,7 +6051,7 @@
         errorLine1="        RecordHistogram.recordEnumeratedHistogram(&quot;Android.WebView.ApiCall&quot;, sample, ApiCall.COUNT);"
         errorLine2="                                                                                             ~~~~~">
         <location
-            file="$SRC/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java"
+            file="../../android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java"
             line="243"
             column="94"/>
     </issue>
@@ -6986,8 +6062,8 @@
         errorLine1="                &quot;Android.WebView.SafeMode.ExecutionResult&quot;, result, SafeModeExecutionResult.COUNT);"
         errorLine2="                                                                                            ~~~~~">
         <location
-            file="$SRC/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java"
-            line="537"
+            file="../../android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java"
+            line="541"
             column="93"/>
     </issue>
 
@@ -6997,7 +6073,7 @@
         errorLine1="        final Switch umaSwitch = mView.findViewById(R.id.fre_uma_dialog_switch);"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fre/FreUMADialogCoordinator.java"
+            file="../../chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fre/FreUMADialogCoordinator.java"
             line="56"
             column="9"/>
     </issue>
@@ -7008,8 +6084,8 @@
         errorLine1="            &lt;Switch"
         errorLine2="            ^">
         <location
-            file="$SRC/chrome/browser/ui/android/signin/java/res/layout/fre_uma_dialog.xml"
-            line="33"
+            file="../../chrome/browser/ui/android/signin/java/res/layout/fre_uma_dialog.xml"
+            line="35"
             column="13"/>
     </issue>
 
@@ -7019,95 +6095,18 @@
         errorLine1="    android:width=&quot;360dp&quot;"
         errorLine2="                   ~~~~~">
         <location
-            file="$SRC/chrome/android/java/res/drawable/adaptive_toolbar_preference_header.xml"
-            line="7"
+            file="../../chrome/android/java/res/drawable/adaptive_toolbar_preference_header.xml"
+            line="9"
             column="20"/>
     </issue>
 
     <issue
-        id="UnsafeOptInUsageError"
-        message="This declaration is opt-in and its usage should be marked with `@com.google.android.material.badge.ExperimentalBadgeUtils` or `@OptIn(markerClass = com.google.android.material.badge.ExperimentalBadgeUtils.class)`"
-        errorLine1="            BadgeUtils.detachBadgeDrawable(mBadge, mAnchor);"
-        errorLine2="                       ~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/sections/SectionHeaderView.java"
-            line="99"
-            column="24"/>
-    </issue>
-
-    <issue
-        id="UnsafeOptInUsageError"
-        message="This declaration is opt-in and its usage should be marked with `@com.google.android.material.badge.ExperimentalBadgeUtils` or `@OptIn(markerClass = com.google.android.material.badge.ExperimentalBadgeUtils.class)`"
-        errorLine1="            BadgeUtils.detachBadgeDrawable(mBadge, mAnchor);"
-        errorLine2="                                           ~~~~~~">
-        <location
-            file="$SRC/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/sections/SectionHeaderView.java"
-            line="99"
-            column="44"/>
-    </issue>
-
-    <issue
-        id="UnsafeOptInUsageError"
-        message="This declaration is opt-in and its usage should be marked with `@com.google.android.material.badge.ExperimentalBadgeUtils` or `@OptIn(markerClass = com.google.android.material.badge.ExperimentalBadgeUtils.class)`"
-        errorLine1="            BadgeUtils.detachBadgeDrawable(mBadge, mAnchor);"
-        errorLine2="                                                   ~~~~~~~">
-        <location
-            file="$SRC/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/sections/SectionHeaderView.java"
-            line="99"
-            column="52"/>
-    </issue>
-
-    <issue
-        id="UnsafeOptInUsageError"
-        message="This declaration is opt-in and its usage should be marked with `@com.google.android.material.badge.ExperimentalBadgeUtils` or `@OptIn(markerClass = com.google.android.material.badge.ExperimentalBadgeUtils.class)`"
-        errorLine1="                BadgeUtils.attachBadgeDrawable(mBadge, mAnchor);"
-        errorLine2="                           ~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/sections/SectionHeaderView.java"
-            line="107"
-            column="28"/>
-    </issue>
-
-    <issue
-        id="UnsafeOptInUsageError"
-        message="This declaration is opt-in and its usage should be marked with `@com.google.android.material.badge.ExperimentalBadgeUtils` or `@OptIn(markerClass = com.google.android.material.badge.ExperimentalBadgeUtils.class)`"
-        errorLine1="                BadgeUtils.attachBadgeDrawable(mBadge, mAnchor);"
-        errorLine2="                                               ~~~~~~">
-        <location
-            file="$SRC/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/sections/SectionHeaderView.java"
-            line="107"
-            column="48"/>
-    </issue>
-
-    <issue
-        id="UnsafeOptInUsageError"
-        message="This declaration is opt-in and its usage should be marked with `@com.google.android.material.badge.ExperimentalBadgeUtils` or `@OptIn(markerClass = com.google.android.material.badge.ExperimentalBadgeUtils.class)`"
-        errorLine1="                BadgeUtils.attachBadgeDrawable(mBadge, mAnchor);"
-        errorLine2="                                                       ~~~~~~~">
-        <location
-            file="$SRC/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/sections/SectionHeaderView.java"
-            line="107"
-            column="56"/>
-    </issue>
-
-    <issue
-        id="UnsupportedChromeOsCameraSystemFeature"
-        message="You should look for any camera available on the device, not just the rear"
-        errorLine1="        return pm.hasSystemFeature(PackageManager.FEATURE_CAMERA)"
-        errorLine2="               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/base/android/java/src/org/chromium/base/SysUtils.java"
-            line="159"
-            column="16"/>
-    </issue>
-
-    <issue
         id="VisibleForTests"
         message="This method should only be accessed from tests or within private scope"
         errorLine1="                IconProvider.getIcon(context, R.drawable.gm_filled_location_on_24),"
         errorLine2="                             ~~~~~~~">
         <location
-            file="$SRC/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/AddressAccessorySheetCoordinator.java"
+            file="../../chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/AddressAccessorySheetCoordinator.java"
             line="39"
             column="30"/>
     </issue>
@@ -7118,8 +6117,8 @@
         errorLine1="            if (mBypassIsReadyToPayServiceInTest) app.bypassIsReadyToPayServiceInTest();"
         errorLine2="                                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/payments/content/android/java/src/org/chromium/components/payments/AndroidPaymentAppFinder.java"
-            line="555"
+            file="../../components/payments/content/android/java/src/org/chromium/components/payments/AndroidPaymentAppFinder.java"
+            line="565"
             column="55"/>
     </issue>
 
@@ -7129,8 +6128,8 @@
         errorLine1="        mHandler.onOptionsItemSelected(id, mHighlightedItemId != null &amp;&amp; mHighlightedItemId == id);"
         errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenu.java"
-            line="392"
+            file="../../chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenu.java"
+            line="395"
             column="18"/>
     </issue>
 
@@ -7140,8 +6139,8 @@
         errorLine1="                CombinedPolicyProvider.get().registerProvider(new AwPolicyProvider(appContext));"
         errorLine2="                                                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java"
-            line="155"
+            file="../../android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java"
+            line="157"
             column="63"/>
     </issue>
 
@@ -7151,8 +6150,8 @@
         errorLine1="                new AwViewAndroidDelegate(mContainerView, mContentsClient, mScrollOffsetManager);"
         errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/android_webview/java/src/org/chromium/android_webview/AwContents.java"
-            line="1490"
+            file="../../android_webview/java/src/org/chromium/android_webview/AwContents.java"
+            line="1505"
             column="17"/>
     </issue>
 
@@ -7162,8 +6161,8 @@
         errorLine1="        LoadUrlParams params = LoadUrlParams.createLoadHttpPostParams(url, postData);"
         errorLine2="                                             ~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/android_webview/java/src/org/chromium/android_webview/AwContents.java"
-            line="2027"
+            file="../../android_webview/java/src/org/chromium/android_webview/AwContents.java"
+            line="2038"
             column="46"/>
     </issue>
 
@@ -7173,8 +6172,8 @@
         errorLine1="        mWebContents.evaluateJavaScriptForTests(script, jsCallback);"
         errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/android_webview/java/src/org/chromium/android_webview/AwContents.java"
-            line="3038"
+            file="../../android_webview/java/src/org/chromium/android_webview/AwContents.java"
+            line="3043"
             column="22"/>
     </issue>
 
@@ -7184,8 +6183,8 @@
         errorLine1="        return FindAddress.findAddress(addr);"
         errorLine2="                           ~~~~~~~~~~~">
         <location
-            file="$SRC/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java"
-            line="172"
+            file="../../android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java"
+            line="173"
             column="28"/>
     </issue>
 
@@ -7195,7 +6194,7 @@
         errorLine1="class AwWebContentsDelegateAdapter extends AwWebContentsDelegate {"
         errorLine2="                                           ~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/android_webview/java/src/org/chromium/android_webview/AwWebContentsDelegateAdapter.java"
+            file="../../android_webview/java/src/org/chromium/android_webview/AwWebContentsDelegateAdapter.java"
             line="36"
             column="44"/>
     </issue>
@@ -7206,8 +6205,8 @@
         errorLine1="                if (mAwContents.getNavigationController() == null) return;"
         errorLine2="                                ~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/android_webview/java/src/org/chromium/android_webview/AwWebContentsDelegateAdapter.java"
-            line="190"
+            file="../../android_webview/java/src/org/chromium/android_webview/AwWebContentsDelegateAdapter.java"
+            line="188"
             column="33"/>
     </issue>
 
@@ -7217,8 +6216,8 @@
         errorLine1="                        mAwContents.getNavigationController().continuePendingReload();"
         errorLine2="                                    ~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/android_webview/java/src/org/chromium/android_webview/AwWebContentsDelegateAdapter.java"
-            line="194"
+            file="../../android_webview/java/src/org/chromium/android_webview/AwWebContentsDelegateAdapter.java"
+            line="192"
             column="37"/>
     </issue>
 
@@ -7228,8 +6227,8 @@
         errorLine1="                        mAwContents.getNavigationController().cancelPendingReload();"
         errorLine2="                                    ~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/android_webview/java/src/org/chromium/android_webview/AwWebContentsDelegateAdapter.java"
-            line="198"
+            file="../../android_webview/java/src/org/chromium/android_webview/AwWebContentsDelegateAdapter.java"
+            line="196"
             column="37"/>
     </issue>
 
@@ -7239,8 +6238,8 @@
         errorLine1="                    AwWebContentsDelegateJni.get().filesSelectedInChooser("
         errorLine2="                                                   ~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/android_webview/java/src/org/chromium/android_webview/AwWebContentsDelegateAdapter.java"
-            line="229"
+            file="../../android_webview/java/src/org/chromium/android_webview/AwWebContentsDelegateAdapter.java"
+            line="227"
             column="52"/>
     </issue>
 
@@ -7250,8 +6249,8 @@
         errorLine1="            AwWebContentsDelegateJni.get().filesSelectedInChooser("
         errorLine2="                                           ~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/android_webview/java/src/org/chromium/android_webview/AwWebContentsDelegateAdapter.java"
-            line="369"
+            file="../../android_webview/java/src/org/chromium/android_webview/AwWebContentsDelegateAdapter.java"
+            line="367"
             column="44"/>
     </issue>
 
@@ -7261,8 +6260,8 @@
         errorLine1="                            0, new VisualStateCallback() {"
         errorLine2="                                   ~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java"
-            line="158"
+            file="../../android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java"
+            line="155"
             column="36"/>
     </issue>
 
@@ -7272,7 +6271,7 @@
         errorLine1="        int playerState = mediaStatus.getPlayerState();"
         errorLine2="                                      ~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/BaseNotificationController.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/BaseNotificationController.java"
             line="69"
             column="39"/>
     </issue>
@@ -7283,7 +6282,7 @@
         errorLine1="        if (playerState == MediaStatus.PLAYER_STATE_PAUSED"
         errorLine2="                                       ~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/BaseNotificationController.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/BaseNotificationController.java"
             line="70"
             column="40"/>
     </issue>
@@ -7294,7 +6293,7 @@
         errorLine1="                || playerState == MediaStatus.PLAYER_STATE_PLAYING) {"
         errorLine2="                                              ~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/BaseNotificationController.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/BaseNotificationController.java"
             line="71"
             column="47"/>
     </issue>
@@ -7305,7 +6304,7 @@
         errorLine1="            mNotificationBuilder.setPaused(playerState != MediaStatus.PLAYER_STATE_PLAYING);"
         errorLine2="                                                                      ~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/BaseNotificationController.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/BaseNotificationController.java"
             line="72"
             column="71"/>
     </issue>
@@ -7316,8 +6315,8 @@
         errorLine1="                &amp;&amp; mOverlayPanelManager.get().getActivePanel() != null) {"
         errorLine2="                                              ~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ui/BottomSheetManager.java"
-            line="312"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/ui/BottomSheetManager.java"
+            line="358"
             column="47"/>
     </issue>
 
@@ -7327,8 +6326,8 @@
         errorLine1="            mOverlayPanelManager.get().getActivePanel().closePanel("
         errorLine2="                                       ~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ui/BottomSheetManager.java"
-            line="313"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/ui/BottomSheetManager.java"
+            line="359"
             column="40"/>
     </issue>
 
@@ -7338,8 +6337,8 @@
         errorLine1="        BrowserImplJni.get().addTab(mNativeBrowser, tab.getNativeTab());"
         errorLine2="                                                        ~~~~~~~~~~~~">
         <location
-            file="$SRC/weblayer/browser/java/org/chromium/weblayer_private/BrowserImpl.java"
-            line="359"
+            file="../../weblayer/browser/java/org/chromium/weblayer_private/BrowserImpl.java"
+            line="344"
             column="57"/>
     </issue>
 
@@ -7349,8 +6348,8 @@
         errorLine1="        BrowserImplJni.get().setActiveTab(mNativeBrowser, tab != null ? tab.getNativeTab() : 0);"
         errorLine2="                                                                            ~~~~~~~~~~~~">
         <location
-            file="$SRC/weblayer/browser/java/org/chromium/weblayer_private/BrowserImpl.java"
-            line="454"
+            file="../../weblayer/browser/java/org/chromium/weblayer_private/BrowserImpl.java"
+            line="439"
             column="77"/>
     </issue>
 
@@ -7360,7 +6359,7 @@
         errorLine1="        return new CastOptions.Builder()"
         errorLine2="               ~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/CastOptionsProvider.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/CastOptionsProvider.java"
             line="20"
             column="16"/>
     </issue>
@@ -7371,7 +6370,7 @@
         errorLine1="                .setCastMediaOptions(null)"
         errorLine2="                 ~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/CastOptionsProvider.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/CastOptionsProvider.java"
             line="21"
             column="18"/>
     </issue>
@@ -7382,7 +6381,7 @@
         errorLine1="                .setEnableReconnectionService(false)"
         errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/CastOptionsProvider.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/CastOptionsProvider.java"
             line="22"
             column="18"/>
     </issue>
@@ -7393,7 +6392,7 @@
         errorLine1="                .setLaunchOptions(new LaunchOptions.Builder().setRelaunchIfRunning(true).build())"
         errorLine2="                 ~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/CastOptionsProvider.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/CastOptionsProvider.java"
             line="23"
             column="18"/>
     </issue>
@@ -7404,7 +6403,7 @@
         errorLine1="                .setLaunchOptions(new LaunchOptions.Builder().setRelaunchIfRunning(true).build())"
         errorLine2="                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/CastOptionsProvider.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/CastOptionsProvider.java"
             line="23"
             column="35"/>
     </issue>
@@ -7415,7 +6414,7 @@
         errorLine1="                .setLaunchOptions(new LaunchOptions.Builder().setRelaunchIfRunning(true).build())"
         errorLine2="                                                              ~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/CastOptionsProvider.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/CastOptionsProvider.java"
             line="23"
             column="63"/>
     </issue>
@@ -7426,7 +6425,7 @@
         errorLine1="                .setLaunchOptions(new LaunchOptions.Builder().setRelaunchIfRunning(true).build())"
         errorLine2="                                                                                         ~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/CastOptionsProvider.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/CastOptionsProvider.java"
             line="23"
             column="90"/>
     </issue>
@@ -7437,7 +6436,7 @@
         errorLine1="                .setResumeSavedSession(false)"
         errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/CastOptionsProvider.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/CastOptionsProvider.java"
             line="24"
             column="18"/>
     </issue>
@@ -7448,7 +6447,7 @@
         errorLine1="                .setStopReceiverApplicationWhenEndingSession(true)"
         errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/CastOptionsProvider.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/CastOptionsProvider.java"
             line="25"
             column="18"/>
     </issue>
@@ -7459,7 +6458,7 @@
         errorLine1="                .build();"
         errorLine2="                 ~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/CastOptionsProvider.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/CastOptionsProvider.java"
             line="26"
             column="18"/>
     </issue>
@@ -7470,8 +6469,8 @@
         errorLine1="        IntentHandler.setTestIntentsEnabled("
         errorLine2="                      ~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java"
-            line="927"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java"
+            line="946"
             column="23"/>
     </issue>
 
@@ -7481,7 +6480,7 @@
         errorLine1="        DownloadManagerService.getDownloadManagerService().onDownloadFailed(downloadItem, reason);"
         errorLine2="                                                           ~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/download/ChromeDownloadDelegate.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/download/ChromeDownloadDelegate.java"
             line="184"
             column="60"/>
     </issue>
@@ -7492,8 +6491,8 @@
         errorLine1="            mOverviewListLayout = (OverviewListLayout) mLayoutManager.getOverviewListLayout();"
         errorLine2="                                                                      ~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java"
-            line="965"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java"
+            line="1041"
             column="71"/>
     </issue>
 
@@ -7503,7 +6502,7 @@
         errorLine1="                IconProvider.getIcon(context, R.drawable.infobar_autofill_cc),"
         errorLine2="                             ~~~~~~~">
         <location
-            file="$SRC/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/CreditCardAccessorySheetCoordinator.java"
+            file="../../chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/CreditCardAccessorySheetCoordinator.java"
             line="37"
             column="30"/>
     </issue>
@@ -7514,7 +6513,7 @@
         errorLine1="        mConnection.cleanUpSession(sessionToken);"
         errorLine2="                    ~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnectionServiceImpl.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnectionServiceImpl.java"
             line="104"
             column="21"/>
     </issue>
@@ -7525,7 +6524,7 @@
         errorLine1="                    mDownloadNotificationService.notifyDownloadPaused(entry.id, entry.fileName,"
         errorLine2="                                                 ~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadBroadcastManagerImpl.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/download/DownloadBroadcastManagerImpl.java"
             line="139"
             column="50"/>
     </issue>
@@ -7536,7 +6535,7 @@
         errorLine1="                    mDownloadNotificationService.notifyDownloadCanceled("
         errorLine2="                                                 ~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadBroadcastManagerImpl.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/download/DownloadBroadcastManagerImpl.java"
             line="153"
             column="50"/>
     </issue>
@@ -7547,7 +6546,7 @@
         errorLine1="        Set&lt;String> entries = DownloadManagerService.getStoredDownloadInfo("
         errorLine2="                                                     ~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadSharedPreferenceHelper.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/download/DownloadSharedPreferenceHelper.java"
             line="134"
             column="54"/>
     </issue>
@@ -7558,7 +6557,7 @@
         errorLine1="    private static final Api.ClientKey&lt;FidoClient> APP_CLIENT_KEY = new Api.ClientKey&lt;>();"
         errorLine2="                                                                    ~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/webauthn/android/java/src/org/chromium/components/webauthn/Fido2ApiCall.java"
+            file="../../components/webauthn/android/java/src/org/chromium/components/webauthn/Fido2ApiCall.java"
             line="94"
             column="69"/>
     </issue>
@@ -7569,7 +6568,7 @@
         errorLine1="    private static final Api.ClientKey&lt;FidoClient> BROWSER_CLIENT_KEY = new Api.ClientKey&lt;>();"
         errorLine2="                                                                        ~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/webauthn/android/java/src/org/chromium/components/webauthn/Fido2ApiCall.java"
+            file="../../components/webauthn/android/java/src/org/chromium/components/webauthn/Fido2ApiCall.java"
             line="106"
             column="73"/>
     </issue>
@@ -7580,7 +6579,7 @@
         errorLine1="                extends Api.AbstractClientBuilder&lt;FidoClient, ApiOptions.NoOptions> {"
         errorLine2="                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/webauthn/android/java/src/org/chromium/components/webauthn/Fido2ApiCall.java"
+            file="../../components/webauthn/android/java/src/org/chromium/components/webauthn/Fido2ApiCall.java"
             line="344"
             column="25"/>
     </issue>
@@ -7591,7 +6590,7 @@
         errorLine1="        MediaInfo mediaInfo = new MediaInfo.Builder(mMediaUrl)"
         errorLine2="                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/remoting/FlingingControllerAdapter.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/remoting/FlingingControllerAdapter.java"
             line="75"
             column="31"/>
     </issue>
@@ -7602,7 +6601,7 @@
         errorLine1="                                      .setContentType(&quot;*/*&quot;)"
         errorLine2="                                       ~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/remoting/FlingingControllerAdapter.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/remoting/FlingingControllerAdapter.java"
             line="76"
             column="40"/>
     </issue>
@@ -7613,7 +6612,7 @@
         errorLine1="                                      .setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)"
         errorLine2="                                       ~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/remoting/FlingingControllerAdapter.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/remoting/FlingingControllerAdapter.java"
             line="77"
             column="40"/>
     </issue>
@@ -7624,7 +6623,7 @@
         errorLine1="                                      .build();"
         errorLine2="                                       ~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/remoting/FlingingControllerAdapter.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/remoting/FlingingControllerAdapter.java"
             line="78"
             column="40"/>
     </issue>
@@ -7635,7 +6634,7 @@
         errorLine1="            if (mediaStatus.getPlayerState() == MediaStatus.PLAYER_STATE_IDLE"
         errorLine2="                            ~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/remoting/FlingingControllerAdapter.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/remoting/FlingingControllerAdapter.java"
             line="146"
             column="29"/>
     </issue>
@@ -7646,7 +6645,7 @@
         errorLine1="            if (mediaStatus.getPlayerState() == MediaStatus.PLAYER_STATE_IDLE"
         errorLine2="                                                            ~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/remoting/FlingingControllerAdapter.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/remoting/FlingingControllerAdapter.java"
             line="146"
             column="61"/>
     </issue>
@@ -7657,7 +6656,7 @@
         errorLine1="                    &amp;&amp; mediaStatus.getIdleReason() == MediaStatus.IDLE_REASON_FINISHED) {"
         errorLine2="                                   ~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/remoting/FlingingControllerAdapter.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/remoting/FlingingControllerAdapter.java"
             line="147"
             column="36"/>
     </issue>
@@ -7668,7 +6667,7 @@
         errorLine1="                    &amp;&amp; mediaStatus.getIdleReason() == MediaStatus.IDLE_REASON_FINISHED) {"
         errorLine2="                                                                  ~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/remoting/FlingingControllerAdapter.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/remoting/FlingingControllerAdapter.java"
             line="147"
             column="67"/>
     </issue>
@@ -7679,7 +6678,7 @@
         errorLine1="                        remoteMediaClient.isPlaying(), mediaStatus.getPlaybackRate());"
         errorLine2="                                                                   ~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/remoting/FlingingControllerAdapter.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/remoting/FlingingControllerAdapter.java"
             line="153"
             column="68"/>
     </issue>
@@ -7687,12 +6686,12 @@
     <issue
         id="VisibleForTests"
         message="This method should only be accessed from tests or within private scope"
-        errorLine1="                            ImageFetcher.resizeImage(bitmap, params.width, params.height));"
-        errorLine2="                                         ~~~~~~~~~~~">
+        errorLine1="                                ImageFetcher.resizeImage(bitmap, params.width, params.height));"
+        errorLine2="                                             ~~~~~~~~~~~">
         <location
-            file="$SRC/components/image_fetcher/android/java/src/org/chromium/components/image_fetcher/ImageFetcherBridge.java"
-            line="96"
-            column="42"/>
+            file="../../components/image_fetcher/android/java/src/org/chromium/components/image_fetcher/ImageFetcherBridge.java"
+            line="97"
+            column="46"/>
     </issue>
 
     <issue
@@ -7701,7 +6700,7 @@
         errorLine1="                                IncognitoNotificationServiceImpl.getRemoveAllIncognitoTabsIntent("
         errorLine2="                                                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationManager.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationManager.java"
             line="55"
             column="66"/>
     </issue>
@@ -7712,7 +6711,7 @@
         errorLine1="            ClickableSpan[] spans = getClickableSpans();"
         errorLine2="                                    ~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/infobars/android/java/src/org/chromium/components/infobars/InfoBarMessageView.java"
+            file="../../components/infobars/android/java/src/org/chromium/components/infobars/InfoBarMessageView.java"
             line="39"
             column="37"/>
     </issue>
@@ -7723,8 +6722,8 @@
         errorLine1="                assert mExternalNavHandler.canExternalAppHandleUrl(url);"
         errorLine2="                                           ~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/external_intents/android/java/src/org/chromium/components/external_intents/InterceptNavigationDelegateImpl.java"
-            line="169"
+            file="../../components/external_intents/android/java/src/org/chromium/components/external_intents/InterceptNavigationDelegateImpl.java"
+            line="191"
             column="44"/>
     </issue>
 
@@ -7734,8 +6733,8 @@
         errorLine1="        int resId = mExternalNavHandler.canExternalAppHandleUrl(url)"
         errorLine2="                                        ~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/external_intents/android/java/src/org/chromium/components/external_intents/InterceptNavigationDelegateImpl.java"
-            line="333"
+            file="../../components/external_intents/android/java/src/org/chromium/components/external_intents/InterceptNavigationDelegateImpl.java"
+            line="381"
             column="41"/>
     </issue>
 
@@ -7745,8 +6744,8 @@
         errorLine1="        } else if (animationsEnabled() &amp;&amp; !hasExplicitNextLayout()) {"
         errorLine2="                   ~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromePhone.java"
-            line="108"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromePhone.java"
+            line="114"
             column="20"/>
     </issue>
 
@@ -7756,8 +6755,8 @@
         errorLine1="        boolean animate = !tabRemoved &amp;&amp; animationsEnabled();"
         errorLine2="                                         ~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromePhone.java"
-            line="129"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromePhone.java"
+            line="135"
             column="42"/>
     </issue>
 
@@ -7767,8 +6766,8 @@
         errorLine1="        } else if (animationsEnabled()) {"
         errorLine2="                   ~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromePhone.java"
-            line="143"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromePhone.java"
+            line="149"
             column="20"/>
     </issue>
 
@@ -7778,7 +6777,7 @@
         errorLine1="        return mStatus.getPlayerState();"
         errorLine2="                       ~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/MediaStatusBridge.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/MediaStatusBridge.java"
             line="37"
             column="24"/>
     </issue>
@@ -7789,7 +6788,7 @@
         errorLine1="        return mStatus.getIdleReason();"
         errorLine2="                       ~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/MediaStatusBridge.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/MediaStatusBridge.java"
             line="51"
             column="24"/>
     </issue>
@@ -7800,7 +6799,7 @@
         errorLine1="        MediaInfo info = mStatus.getMediaInfo();"
         errorLine2="                                 ~~~~~~~~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/MediaStatusBridge.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/MediaStatusBridge.java"
             line="60"
             column="34"/>
     </issue>
@@ -7811,7 +6810,7 @@
         errorLine1="        return mStatus.isMediaCommandSupported(MediaStatus.COMMAND_PAUSE);"
         errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/MediaStatusBridge.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/MediaStatusBridge.java"
             line="74"
             column="24"/>
     </issue>
@@ -7822,7 +6821,7 @@
         errorLine1="        return mStatus.isMediaCommandSupported(MediaStatus.COMMAND_PAUSE);"
         errorLine2="                                                           ~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/MediaStatusBridge.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/MediaStatusBridge.java"
             line="74"
             column="60"/>
     </issue>
@@ -7833,7 +6832,7 @@
         errorLine1="        return mStatus.isMediaCommandSupported(MediaStatus.COMMAND_TOGGLE_MUTE);"
         errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/MediaStatusBridge.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/MediaStatusBridge.java"
             line="82"
             column="24"/>
     </issue>
@@ -7844,7 +6843,7 @@
         errorLine1="        return mStatus.isMediaCommandSupported(MediaStatus.COMMAND_TOGGLE_MUTE);"
         errorLine2="                                                           ~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/MediaStatusBridge.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/MediaStatusBridge.java"
             line="82"
             column="60"/>
     </issue>
@@ -7855,7 +6854,7 @@
         errorLine1="        return mStatus.isMediaCommandSupported(MediaStatus.COMMAND_SET_VOLUME);"
         errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/MediaStatusBridge.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/MediaStatusBridge.java"
             line="90"
             column="24"/>
     </issue>
@@ -7866,7 +6865,7 @@
         errorLine1="        return mStatus.isMediaCommandSupported(MediaStatus.COMMAND_SET_VOLUME);"
         errorLine2="                                                           ~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/MediaStatusBridge.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/MediaStatusBridge.java"
             line="90"
             column="60"/>
     </issue>
@@ -7877,7 +6876,7 @@
         errorLine1="        return mStatus.isMediaCommandSupported(MediaStatus.COMMAND_SEEK);"
         errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/MediaStatusBridge.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/MediaStatusBridge.java"
             line="98"
             column="24"/>
     </issue>
@@ -7888,7 +6887,7 @@
         errorLine1="        return mStatus.isMediaCommandSupported(MediaStatus.COMMAND_SEEK);"
         errorLine2="                                                           ~~~~~~~~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/MediaStatusBridge.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/MediaStatusBridge.java"
             line="98"
             column="60"/>
     </issue>
@@ -7899,7 +6898,7 @@
         errorLine1="        return mStatus.isMute();"
         errorLine2="                       ~~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/MediaStatusBridge.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/MediaStatusBridge.java"
             line="106"
             column="24"/>
     </issue>
@@ -7910,7 +6909,7 @@
         errorLine1="        return mStatus.getStreamVolume();"
         errorLine2="                       ~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/MediaStatusBridge.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/MediaStatusBridge.java"
             line="116"
             column="24"/>
     </issue>
@@ -7921,7 +6920,7 @@
         errorLine1="        MediaInfo info = mStatus.getMediaInfo();"
         errorLine2="                                 ~~~~~~~~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/MediaStatusBridge.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/MediaStatusBridge.java"
             line="125"
             column="34"/>
     </issue>
@@ -7932,7 +6931,7 @@
         errorLine1="        return mStatus.getStreamPosition();"
         errorLine2="                       ~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/media_router/browser/android/java/src/org/chromium/components/media_router/MediaStatusBridge.java"
+            file="../../components/media_router/browser/android/java/src/org/chromium/components/media_router/MediaStatusBridge.java"
             line="136"
             column="24"/>
     </issue>
@@ -7943,7 +6942,7 @@
         errorLine1="                    ((ChromeTabbedActivity) activity).saveState();"
         errorLine2="                                                      ~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManager.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManager.java"
             line="428"
             column="55"/>
     </issue>
@@ -7954,7 +6953,7 @@
         errorLine1="                NavigationControllerImplJni.get().getNavigationController(tab.getNativeTab());"
         errorLine2="                                                                              ~~~~~~~~~~~~">
         <location
-            file="$SRC/weblayer/browser/java/org/chromium/weblayer_private/NavigationControllerImpl.java"
+            file="../../weblayer/browser/java/org/chromium/weblayer_private/NavigationControllerImpl.java"
             line="42"
             column="79"/>
     </issue>
@@ -7965,7 +6964,7 @@
         errorLine1="                NewTabCallbackProxyJni.get().createNewTabCallbackProxy(this, tab.getNativeTab());"
         errorLine2="                                                                                 ~~~~~~~~~~~~">
         <location
-            file="$SRC/weblayer/browser/java/org/chromium/weblayer_private/NewTabCallbackProxy.java"
+            file="../../weblayer/browser/java/org/chromium/weblayer_private/NewTabCallbackProxy.java"
             line="26"
             column="82"/>
     </issue>
@@ -7976,8 +6975,8 @@
         errorLine1="        return DownloadManagerService.getStoredDownloadInfo(sharedPrefs, type);"
         errorLine2="                                      ~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/download/OMADownloadHandler.java"
-            line="922"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/download/OMADownloadHandler.java"
+            line="921"
             column="39"/>
     </issue>
 
@@ -7987,7 +6986,7 @@
         errorLine1="        return VersionNumberGetter.getInstance().getCurrentlyUsedVersion(getContext());"
         errorLine2="                                   ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/omaha/OmahaBase.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/omaha/OmahaBase.java"
             line="322"
             column="36"/>
     </issue>
@@ -7998,7 +6997,7 @@
         errorLine1="            String appId = getRequestGenerator().getAppId();"
         errorLine2="                                                 ~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/omaha/OmahaBase.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/omaha/OmahaBase.java"
             line="350"
             column="50"/>
     </issue>
@@ -8009,7 +7008,7 @@
         errorLine1="            mContent.destroy();"
         errorLine2="                     ~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanel.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanel.java"
             line="549"
             column="22"/>
     </issue>
@@ -8020,7 +7019,7 @@
         errorLine1="                IconProvider.getIcon(context, R.drawable.ic_vpn_key_grey),"
         errorLine2="                             ~~~~~~~">
         <location
-            file="$SRC/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetCoordinator.java"
+            file="../../chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetCoordinator.java"
             line="43"
             column="30"/>
     </issue>
@@ -8031,7 +7030,7 @@
         errorLine1="        getTab().setIcon(IconProvider.getIcon("
         errorLine2="                                      ~~~~~~~">
         <location
-            file="$SRC/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetCoordinator.java"
+            file="../../chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetCoordinator.java"
             line="66"
             column="39"/>
     </issue>
@@ -8042,8 +7041,8 @@
         errorLine1="        String distillerUrl = DomDistillerUrlUtils.getDistillerViewUrlFromUrl("
         errorLine2="                                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManager.java"
-            line="642"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManager.java"
+            line="668"
             column="52"/>
     </issue>
 
@@ -8053,8 +7052,8 @@
         errorLine1="                new SettingsSecureBasedIdentificationGenerator(getContext()), false);"
         errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/omaha/RequestGenerator.java"
-            line="45"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/omaha/RequestGenerator.java"
+            line="44"
             column="17"/>
     </issue>
 
@@ -8064,7 +7063,7 @@
         errorLine1="                new SettingsSecureBasedIdentificationGenerator(ContextUtils.getApplicationContext())"
         errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/rlz/RlzPingHandler.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/rlz/RlzPingHandler.java"
             line="40"
             column="17"/>
     </issue>
@@ -8075,8 +7074,8 @@
         errorLine1="        mSearchBox.beginQuery(searchType, getOptionalIntentQuery(),"
         errorLine2="                   ~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivity.java"
-            line="405"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivity.java"
+            line="424"
             column="20"/>
     </issue>
 
@@ -8086,7 +7085,7 @@
         errorLine1="        Intent intent = getShareLinkIntent(params);"
         errorLine2="                        ~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/share/ShareHelper.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/share/ShareHelper.java"
             line="63"
             column="25"/>
     </issue>
@@ -8097,7 +7096,7 @@
         errorLine1="            ShareHelper.setLastShareComponentName(mProfile, component);"
         errorLine2="                        ~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetPropertyModelBuilder.java"
+            file="../../chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetPropertyModelBuilder.java"
             line="233"
             column="25"/>
     </issue>
@@ -8105,22 +7104,11 @@
     <issue
         id="VisibleForTests"
         message="This method should only be accessed from tests or within package private scope"
-        errorLine1="        SigninPreferencesManager.getInstance().setNewTabPageSigninPromoSuppressionPeriodStart("
-        errorLine2="                                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SignInPromo.java"
-            line="87"
-            column="48"/>
-    </issue>
-
-    <issue
-        id="VisibleForTests"
-        message="This method should only be accessed from tests or within package private scope"
         errorLine1="                                      .getNewTabPageSigninPromoSuppressionPeriodStart();"
         errorLine2="                                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SignInPromo.java"
-            line="103"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SignInPromo.java"
+            line="94"
             column="40"/>
     </issue>
 
@@ -8130,8 +7118,8 @@
         errorLine1="        SigninPreferencesManager.getInstance().clearNewTabPageSigninPromoSuppressionPeriodStart();"
         errorLine2="                                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SignInPromo.java"
-            line="110"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SignInPromo.java"
+            line="101"
             column="48"/>
     </issue>
 
@@ -8141,8 +7129,8 @@
         errorLine1="                &amp;&amp; clickedTab.getVisiblePercentage() >= 1.f"
         errorLine2="                              ~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java"
-            line="983"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java"
+            line="1011"
             column="31"/>
     </issue>
 
@@ -8152,7 +7140,7 @@
         errorLine1="                requestId, new AwContents.VisualStateCallback() {"
         errorLine2="                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebViewChromium.java"
+            file="../../android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebViewChromium.java"
             line="50"
             column="32"/>
     </issue>
@@ -8163,7 +7151,7 @@
         errorLine1="        getDownloadNotificationService().notifyDownloadCanceled(id, false);"
         errorLine2="                                         ~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/download/SystemDownloadNotifier.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/download/SystemDownloadNotifier.java"
             line="87"
             column="42"/>
     </issue>
@@ -8174,8 +7162,8 @@
         errorLine1="                getDownloadNotificationService().notifyDownloadProgress(info.getContentId(),"
         errorLine2="                                                 ~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/download/SystemDownloadNotifier.java"
-            line="173"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/download/SystemDownloadNotifier.java"
+            line="163"
             column="50"/>
     </issue>
 
@@ -8185,8 +7173,8 @@
         errorLine1="                getDownloadNotificationService().notifyDownloadPaused(info.getContentId(),"
         errorLine2="                                                 ~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/download/SystemDownloadNotifier.java"
-            line="181"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/download/SystemDownloadNotifier.java"
+            line="171"
             column="50"/>
     </issue>
 
@@ -8196,8 +7184,8 @@
         errorLine1="                        getDownloadNotificationService().notifyDownloadSuccessful("
         errorLine2="                                                         ~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/download/SystemDownloadNotifier.java"
-            line="188"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/download/SystemDownloadNotifier.java"
+            line="178"
             column="58"/>
     </issue>
 
@@ -8207,8 +7195,8 @@
         errorLine1="                getDownloadNotificationService().notifyDownloadFailed(info.getContentId(),"
         errorLine2="                                                 ~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/download/SystemDownloadNotifier.java"
-            line="203"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/download/SystemDownloadNotifier.java"
+            line="193"
             column="50"/>
     </issue>
 
@@ -8218,8 +7206,8 @@
         errorLine1="                getDownloadNotificationService().notifyDownloadPaused(info.getContentId(),"
         errorLine2="                                                 ~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/download/SystemDownloadNotifier.java"
-            line="208"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/download/SystemDownloadNotifier.java"
+            line="198"
             column="50"/>
     </issue>
 
@@ -8229,8 +7217,8 @@
         errorLine1="                                != mTabSwitcherAnimationTabStackDrawable.getTabCount();"
         errorLine2="                                                                         ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java"
-            line="1605"
+            file="../../chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java"
+            line="1609"
             column="74"/>
     </issue>
 
@@ -8240,8 +7228,8 @@
         errorLine1="        return mToolbarLayout.getLocationBar();"
         errorLine2="                              ~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java"
-            line="645"
+            file="../../chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java"
+            line="677"
             column="31"/>
     </issue>
 
@@ -8251,7 +7239,7 @@
         errorLine1="                        VersionNumberGetter.getInstance().getLatestKnownVersion(context);"
         errorLine2="                                            ~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/omaha/UpdateStatusProvider.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/omaha/UpdateStatusProvider.java"
             line="295"
             column="45"/>
     </issue>
@@ -8262,7 +7250,7 @@
         errorLine1="                requestId, callback == null ? null : new AwContents.VisualStateCallback() {"
         errorLine2="                                                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java"
+            file="../../android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java"
             line="976"
             column="58"/>
     </issue>
@@ -8273,7 +7261,7 @@
         errorLine1="                mAwContents.getWebContents()));"
         errorLine2="                            ~~~~~~~~~~~~~~">
         <location
-            file="$SRC/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java"
+            file="../../android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java"
             line="1836"
             column="29"/>
     </issue>
@@ -8284,8 +7272,8 @@
         errorLine1="        list.add(new StorageInfo(host, type, size));"
         errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreferenceBridge.java"
-            line="72"
+            file="../../components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreferenceBridge.java"
+            line="73"
             column="18"/>
     </issue>
 
@@ -8295,8 +7283,8 @@
         errorLine1="                .put(origin, new LocalStorageInfo(origin, size, important));"
         errorLine2="                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreferenceBridge.java"
-            line="90"
+            file="../../components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreferenceBridge.java"
+            line="91"
             column="30"/>
     </issue>
 
@@ -8306,8 +7294,8 @@
         errorLine1="        list.add(new ChosenObjectInfo(contentSettingsType, origin, name, object, isManaged));"
         errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreferenceBridge.java"
-            line="145"
+            file="../../components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreferenceBridge.java"
+            line="166"
             column="18"/>
     </issue>
 
@@ -8317,7 +7305,7 @@
         errorLine1="            return GcmNetworkManager.getInstance(context);"
         errorLine2="                                     ~~~~~~~~~~~">
         <location
-            file="$SRC/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskSchedulerGcmNetworkManager.java"
+            file="../../components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskSchedulerGcmNetworkManager.java"
             line="249"
             column="38"/>
     </issue>
@@ -8325,12 +7313,12 @@
     <issue
         id="UseAppTint"
         message="Must use `app:tint` instead of `android:tint`"
-        errorLine1="        android:tint=&quot;@macro/drag_handlebar_color&quot; />"
-        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        errorLine1="            android:tint=&quot;@macro/drag_handlebar_color&quot; />"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/res/layout/custom_tabs_handle_view.xml"
-            line="20"
-            column="9"/>
+            file="../../chrome/android/java/res/layout/custom_tabs_handle_view.xml"
+            line="27"
+            column="13"/>
     </issue>
 
     <issue
@@ -8339,8 +7327,8 @@
         errorLine1="        android:tint=&quot;@macro/checked_item&quot;"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/multiwindow/java/res/layout/instance_switcher_item.xml"
-            line="82"
+            file="../../chrome/browser/ui/android/multiwindow/java/res/layout/instance_switcher_item.xml"
+            line="84"
             column="9"/>
     </issue>
 
@@ -8350,7 +7338,7 @@
         errorLine1="            android:tint=&quot;@color/photo_picker_tile_bg_color&quot; />"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/photo_picker/android/java/res/layout/photo_picker_bitmap_view.xml"
+            file="../../components/browser_ui/photo_picker/android/java/res/layout/photo_picker_bitmap_view.xml"
             line="109"
             column="13"/>
     </issue>
@@ -8361,8 +7349,8 @@
         errorLine1="            android:tint=&quot;@color/default_icon_color_baseline&quot;"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/res/layout/search_widget_template.xml"
-            line="42"
+            file="../../chrome/android/java/res/layout/search_widget_template.xml"
+            line="44"
             column="13"/>
     </issue>
 
@@ -8372,7 +7360,7 @@
         errorLine1="                return res.getDrawable(id, null);"
         errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java"
+            file="../../base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java"
             line="311"
             column="24"/>
     </issue>
@@ -8383,7 +7371,7 @@
         errorLine1="        Drawable mInlineTitleIcon = context.getDrawable(mGooglePayDrawableId);"
         errorLine2="                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskPrompt.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskPrompt.java"
             line="299"
             column="37"/>
     </issue>
@@ -8394,7 +7382,7 @@
         errorLine1="                    iconDrawable = mContext.getDrawable(iconResId);"
         errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchQuickActionControl.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchQuickActionControl.java"
             line="311"
             column="36"/>
     </issue>
@@ -8405,8 +7393,8 @@
         errorLine1="        Drawable clearTextIcon = getContext().getDrawable(R.drawable.ic_clear_text);"
         errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/FlagsFragment.java"
-            line="172"
+            file="../../android_webview/nonembedded/java/src/org/chromium/android_webview/devui/FlagsFragment.java"
+            line="178"
             column="34"/>
     </issue>
 
@@ -8416,7 +7404,7 @@
         errorLine1="            final Drawable statusIcon = mContext.getDrawable(R.drawable.ic_cloud_offline_24dp);"
         errorLine2="                                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/indicator/OfflineIndicatorControllerV2.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/offlinepages/indicator/OfflineIndicatorControllerV2.java"
             line="138"
             column="41"/>
     </issue>
@@ -8427,7 +7415,7 @@
         errorLine1="            final Drawable statusIcon = mContext.getDrawable(R.drawable.ic_globe_24dp);"
         errorLine2="                                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/indicator/OfflineIndicatorControllerV2.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/offlinepages/indicator/OfflineIndicatorControllerV2.java"
             line="159"
             column="41"/>
     </issue>
@@ -8438,20 +7426,20 @@
         errorLine1="            Drawable drawable = context.getDrawable(R.drawable.toolbar_hairline);"
         errorLine2="                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListRecyclerView.java"
-            line="232"
+            file="../../chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListRecyclerView.java"
+            line="231"
             column="33"/>
     </issue>
 
     <issue
         id="UseCompatLoadingForDrawables"
         message="Use `AppCompatResources.getDrawable()`"
-        errorLine1="        Drawable drawable = context.getDrawable("
-        errorLine2="                            ^">
+        errorLine1="        GradientDrawable drawable = (GradientDrawable) context.getDrawable("
+        errorLine2="                                                       ^">
         <location
-            file="$SRC/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java"
-            line="415"
-            column="29"/>
+            file="../../chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java"
+            line="371"
+            column="56"/>
     </issue>
 
     <issue
@@ -8460,8 +7448,8 @@
         errorLine1="            super(context.getDrawable(R.drawable.ntp_search_box));"
         errorLine2="                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java"
-            line="2791"
+            file="../../chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java"
+            line="2589"
             column="19"/>
     </issue>
 
@@ -8471,7 +7459,7 @@
         errorLine1="            android:drawableTop=&quot;@drawable/ic_action_home&quot;"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/android_webview/nonembedded/java/res_devui/layout/activity_main.xml"
+            file="../../android_webview/nonembedded/java/res_devui/layout/activity_main.xml"
             line="50"
             column="13"/>
     </issue>
@@ -8482,7 +7470,7 @@
         errorLine1="            android:drawableTop=&quot;@drawable/ic_alert_error&quot;"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/android_webview/nonembedded/java/res_devui/layout/activity_main.xml"
+            file="../../android_webview/nonembedded/java/res_devui/layout/activity_main.xml"
             line="60"
             column="13"/>
     </issue>
@@ -8493,7 +7481,7 @@
         errorLine1="            android:drawableTop=&quot;@drawable/ic_flag&quot;"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/android_webview/nonembedded/java/res_devui/layout/activity_main.xml"
+            file="../../android_webview/nonembedded/java/res_devui/layout/activity_main.xml"
             line="70"
             column="13"/>
     </issue>
@@ -8504,8 +7492,8 @@
         errorLine1="    android:drawableEnd=&quot;@drawable/exclamation_triangle&quot;"
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/res/layout/os_version_unsupported_text.xml"
-            line="15"
+            file="../../chrome/android/java/res/layout/os_version_unsupported_text.xml"
+            line="17"
             column="5"/>
     </issue>
 
@@ -8515,7 +7503,7 @@
         errorLine1="        android:drawableStart=&quot;@drawable/ic_alert_error&quot;"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/android_webview/nonembedded/java/res_devui/layout/persistent_error_message.xml"
+            file="../../android_webview/nonembedded/java/res_devui/layout/persistent_error_message.xml"
             line="26"
             column="9"/>
     </issue>
@@ -8526,8 +7514,8 @@
         errorLine1="        android:drawableStart=&quot;@drawable/ic_error&quot;"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/share/android/java/res/layout/qrcode_camera_error_layout.xml"
-            line="27"
+            file="../../chrome/browser/share/android/java/res/layout/qrcode_camera_error_layout.xml"
+            line="29"
             column="9"/>
     </issue>
 
@@ -8537,8 +7525,8 @@
         errorLine1="                    android:drawableTop=&quot;@drawable/edit_icon&quot;"
         errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/share/android/java/res/layout/screenshot_share_sheet.xml"
-            line="49"
+            file="../../chrome/browser/share/android/java/res/layout/screenshot_share_sheet.xml"
+            line="51"
             column="21"/>
     </issue>
 
@@ -8548,8 +7536,8 @@
         errorLine1="                    android:drawableTint=&quot;@color/default_icon_color_tint_list&quot;"
         errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/share/android/java/res/layout/screenshot_share_sheet.xml"
-            line="50"
+            file="../../chrome/browser/share/android/java/res/layout/screenshot_share_sheet.xml"
+            line="52"
             column="21"/>
     </issue>
 
@@ -8559,8 +7547,8 @@
         errorLine1="                    android:drawableTop=&quot;@drawable/delete_icon&quot;"
         errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/share/android/java/res/layout/screenshot_share_sheet.xml"
-            line="60"
+            file="../../chrome/browser/share/android/java/res/layout/screenshot_share_sheet.xml"
+            line="62"
             column="21"/>
     </issue>
 
@@ -8570,8 +7558,8 @@
         errorLine1="                    android:drawableTint=&quot;@color/default_icon_color_tint_list&quot;"
         errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/share/android/java/res/layout/screenshot_share_sheet.xml"
-            line="61"
+            file="../../chrome/browser/share/android/java/res/layout/screenshot_share_sheet.xml"
+            line="63"
             column="21"/>
     </issue>
 
@@ -8581,8 +7569,8 @@
         errorLine1="                    android:drawableTop=&quot;@drawable/save_icon&quot;"
         errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/share/android/java/res/layout/screenshot_share_sheet.xml"
-            line="71"
+            file="../../chrome/browser/share/android/java/res/layout/screenshot_share_sheet.xml"
+            line="73"
             column="21"/>
     </issue>
 
@@ -8592,8 +7580,8 @@
         errorLine1="                    android:drawableTint=&quot;@color/default_icon_color_tint_list&quot;"
         errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/share/android/java/res/layout/screenshot_share_sheet.xml"
-            line="72"
+            file="../../chrome/browser/share/android/java/res/layout/screenshot_share_sheet.xml"
+            line="74"
             column="21"/>
     </issue>
 
@@ -8603,8 +7591,8 @@
         errorLine1="                    android:drawableTop=&quot;@drawable/share_icon&quot;"
         errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/share/android/java/res/layout/screenshot_share_sheet.xml"
-            line="82"
+            file="../../chrome/browser/share/android/java/res/layout/screenshot_share_sheet.xml"
+            line="84"
             column="21"/>
     </issue>
 
@@ -8614,30 +7602,19 @@
         errorLine1="                    android:drawableTint=&quot;@color/default_icon_color_tint_list&quot;"
         errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/share/android/java/res/layout/screenshot_share_sheet.xml"
-            line="83"
+            file="../../chrome/browser/share/android/java/res/layout/screenshot_share_sheet.xml"
+            line="85"
             column="21"/>
     </issue>
 
     <issue
-        id="UnspecifiedImmutableFlag"
-        message="Missing `PendingIntent` mutability flag"
-        errorLine1="                intent, PendingIntent.FLAG_UPDATE_CURRENT);"
-        errorLine2="                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/media/MediaCaptureNotificationServiceImpl.java"
-            line="342"
-            column="25"/>
-    </issue>
-
-    <issue
         id="DataExtractionRules"
         message="The attribute `android:allowBackup` is deprecated from Android 12 and higher and may be removed in future versions. Consider adding the attribute `android:dataExtractionRules` specifying an `@xml` resource which configures cloud backups and device transfers on Android 12 and higher."
-        errorLine1="  &lt;application android:name=&quot;org.chromium.chrome.browser.base.SplitMonochromeApplication&quot; android:icon=&quot;@drawable/ic_launcher&quot; android:roundIcon=&quot;@drawable/ic_launcher_round&quot; android:label=&quot;@string/app_name&quot; android:largeHeap=&quot;false&quot; android:manageSpaceActivity=&quot;@string/manage_space_activity&quot; android:supportsRtl=&quot;true&quot; android:zygotePreloadName=&quot;org.chromium.content_public.app.ZygotePreload&quot; android:allowBackup=&quot;false&quot; android:networkSecurityConfig=&quot;@xml/network_security_config&quot; android:allowAudioPlaybackCapture=&quot;false&quot; android:appComponentFactory=&quot;org.chromium.chrome.browser.base.SplitCompatAppComponentFactory&quot; android:multiArch=&quot;true&quot; android:extractNativeLibs=&quot;false&quot; android:use32bitAbi=&quot;true&quot;>"
+        errorLine1="  &lt;application android:name=&quot;org.chromium.chrome.browser.base.SplitMonochromeApplication&quot; android:icon=&quot;@drawable/ic_launcher&quot; android:roundIcon=&quot;@drawable/ic_launcher_round&quot; android:label=&quot;@string/app_name&quot; android:largeHeap=&quot;false&quot; android:manageSpaceActivity=&quot;@string/manage_space_activity&quot; android:supportsRtl=&quot;true&quot; android:zygotePreloadName=&quot;org.chromium.content_public.app.ZygotePreload&quot; android:allowBackup=&quot;false&quot; android:networkSecurityConfig=&quot;@xml/network_security_config&quot; android:allowAudioPlaybackCapture=&quot;false&quot; android:appComponentFactory=&quot;org.chromium.chrome.browser.base.SplitCompatAppComponentFactory&quot; android:enableOnBackInvokedCallback=&quot;true&quot; android:multiArch=&quot;true&quot; android:extractNativeLibs=&quot;false&quot; android:use32bitAbi=&quot;true&quot;>"
         errorLine2="                                                                                                                                                                                                                                                                                                                                                                                                                                ~~~~~">
         <location
             file="gen/chrome/android/monochrome_public_bundle__lint/gen/chrome/android/manifest/monochrome_public_bundle__base_bundle_module/AndroidManifest.xml"
-            line="228"
+            line="232"
             column="417"/>
     </issue>
 
@@ -8647,8 +7624,8 @@
         errorLine1="            notifyDataSetChanged();"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/AppLanguagePromoDialog.java"
-            line="201"
+            file="../../chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/AppLanguagePromoDialog.java"
+            line="217"
             column="13"/>
     </issue>
 
@@ -8658,8 +7635,8 @@
         errorLine1="        notifyDataSetChanged();"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java"
-            line="204"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java"
+            line="202"
             column="9"/>
     </issue>
 
@@ -8669,8 +7646,8 @@
         errorLine1="        notifyDataSetChanged();"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java"
-            line="375"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java"
+            line="369"
             column="9"/>
     </issue>
 
@@ -8680,8 +7657,8 @@
         errorLine1="        notifyDataSetChanged();"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java"
-            line="425"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java"
+            line="419"
             column="9"/>
     </issue>
 
@@ -8691,8 +7668,8 @@
         errorLine1="        if (mElements != null) notifyDataSetChanged();"
         errorLine2="                               ~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java"
-            line="438"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java"
+            line="432"
             column="32"/>
     </issue>
 
@@ -8702,8 +7679,8 @@
         errorLine1="            mAdapter.notifyDataSetChanged();"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManager.java"
-            line="104"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManager.java"
+            line="107"
             column="13"/>
     </issue>
 
@@ -8713,7 +7690,7 @@
         errorLine1="                    notifyDataSetChanged();"
         errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/ContentLanguagesPreference.java"
+            file="../../chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/ContentLanguagesPreference.java"
             line="119"
             column="21"/>
     </issue>
@@ -8724,7 +7701,7 @@
         errorLine1="        notifyDataSetChanged();"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/DateDividedAdapter.java"
+            file="../../components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/DateDividedAdapter.java"
             line="551"
             column="9"/>
     </issue>
@@ -8735,7 +7712,7 @@
         errorLine1="        notifyDataSetChanged();"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/DateDividedAdapter.java"
+            file="../../components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/DateDividedAdapter.java"
             line="574"
             column="9"/>
     </issue>
@@ -8746,7 +7723,7 @@
         errorLine1="        notifyDataSetChanged();"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/DateDividedAdapter.java"
+            file="../../components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/DateDividedAdapter.java"
             line="611"
             column="9"/>
     </issue>
@@ -8757,7 +7734,7 @@
         errorLine1="        notifyDataSetChanged();"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/DateDividedAdapter.java"
+            file="../../components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/DateDividedAdapter.java"
             line="646"
             column="9"/>
     </issue>
@@ -8768,7 +7745,7 @@
         errorLine1="        if (notifyDataSetChanged) notifyDataSetChanged();"
         errorLine2="                                  ~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/DateDividedAdapter.java"
+            file="../../components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/DateDividedAdapter.java"
             line="660"
             column="35"/>
     </issue>
@@ -8779,7 +7756,7 @@
         errorLine1="        notifyDataSetChanged();"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/DateDividedAdapter.java"
+            file="../../components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/DateDividedAdapter.java"
             line="781"
             column="9"/>
     </issue>
@@ -8790,8 +7767,8 @@
         errorLine1="            mPagerAdapter.notifyDataSetChanged();"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java"
-            line="203"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java"
+            line="217"
             column="13"/>
     </issue>
 
@@ -8801,8 +7778,8 @@
         errorLine1="        notifyDataSetChanged();"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryAdapter.java"
-            line="134"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/history/HistoryAdapter.java"
+            line="137"
             column="9"/>
     </issue>
 
@@ -8812,7 +7789,7 @@
         errorLine1="            notifyDataSetChanged();"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/LanguageAskPrompt.java"
+            file="../../chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/LanguageAskPrompt.java"
             line="209"
             column="13"/>
     </issue>
@@ -8823,7 +7800,7 @@
         errorLine1="                notifyDataSetChanged();"
         errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/LanguageListBaseAdapter.java"
+            file="../../chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/LanguageListBaseAdapter.java"
             line="136"
             column="17"/>
     </issue>
@@ -8834,7 +7811,7 @@
         errorLine1="        notifyDataSetChanged();"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/LanguageListBaseAdapter.java"
+            file="../../chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/LanguageListBaseAdapter.java"
             line="204"
             column="9"/>
     </issue>
@@ -8845,7 +7822,7 @@
         errorLine1="        notifyDataSetChanged();"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/LanguageListBaseAdapter.java"
+            file="../../chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/LanguageListBaseAdapter.java"
             line="215"
             column="9"/>
     </issue>
@@ -8856,7 +7833,7 @@
         errorLine1="        noteCarousel.getAdapter().notifyDataSetChanged();"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationDialog.java"
+            file="../../chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationDialog.java"
             line="129"
             column="9"/>
     </issue>
@@ -8867,7 +7844,7 @@
         errorLine1="        notifyDataSetChanged();"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/contacts_picker/android/java/src/org/chromium/components/browser_ui/contacts_picker/PickerAdapter.java"
+            file="../../components/browser_ui/contacts_picker/android/java/src/org/chromium/components/browser_ui/contacts_picker/PickerAdapter.java"
             line="169"
             column="9"/>
     </issue>
@@ -8878,7 +7855,7 @@
         errorLine1="        notifyDataSetChanged();"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/contacts_picker/android/java/src/org/chromium/components/browser_ui/contacts_picker/PickerAdapter.java"
+            file="../../components/browser_ui/contacts_picker/android/java/src/org/chromium/components/browser_ui/contacts_picker/PickerAdapter.java"
             line="196"
             column="9"/>
     </issue>
@@ -8889,7 +7866,7 @@
         errorLine1="        notifyDataSetChanged();"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/contacts_picker/android/java/src/org/chromium/components/browser_ui/contacts_picker/PickerAdapter.java"
+            file="../../components/browser_ui/contacts_picker/android/java/src/org/chromium/components/browser_ui/contacts_picker/PickerAdapter.java"
             line="213"
             column="9"/>
     </issue>
@@ -8900,7 +7877,7 @@
         errorLine1="        notifyDataSetChanged();"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/contacts_picker/android/java/src/org/chromium/components/browser_ui/contacts_picker/PickerAdapter.java"
+            file="../../components/browser_ui/contacts_picker/android/java/src/org/chromium/components/browser_ui/contacts_picker/PickerAdapter.java"
             line="342"
             column="9"/>
     </issue>
@@ -8911,7 +7888,7 @@
         errorLine1="        mPickerAdapter.notifyDataSetChanged();"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/contacts_picker/android/java/src/org/chromium/components/browser_ui/contacts_picker/PickerCategoryView.java"
+            file="../../components/browser_ui/contacts_picker/android/java/src/org/chromium/components/browser_ui/contacts_picker/PickerCategoryView.java"
             line="212"
             column="9"/>
     </issue>
@@ -8922,7 +7899,7 @@
         errorLine1="            mPickerAdapter.notifyDataSetChanged();"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/photo_picker/android/java/src/org/chromium/components/browser_ui/photo_picker/PickerCategoryView.java"
+            file="../../components/browser_ui/photo_picker/android/java/src/org/chromium/components/browser_ui/photo_picker/PickerCategoryView.java"
             line="259"
             column="13"/>
     </issue>
@@ -8933,7 +7910,7 @@
         errorLine1="            mPickerAdapter.notifyDataSetChanged();"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/photo_picker/android/java/src/org/chromium/components/browser_ui/photo_picker/PickerCategoryView.java"
+            file="../../components/browser_ui/photo_picker/android/java/src/org/chromium/components/browser_ui/photo_picker/PickerCategoryView.java"
             line="395"
             column="13"/>
     </issue>
@@ -8944,7 +7921,7 @@
         errorLine1="        mPickerAdapter.notifyDataSetChanged();"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/photo_picker/android/java/src/org/chromium/components/browser_ui/photo_picker/PickerCategoryView.java"
+            file="../../components/browser_ui/photo_picker/android/java/src/org/chromium/components/browser_ui/photo_picker/PickerCategoryView.java"
             line="455"
             column="9"/>
     </issue>
@@ -8955,7 +7932,7 @@
         errorLine1="        &lt;LinearLayout"
         errorLine2="         ~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/photo_picker/android/java/res/layout/photo_picker_bitmap_view.xml"
+            file="../../components/browser_ui/photo_picker/android/java/res/layout/photo_picker_bitmap_view.xml"
             line="37"
             column="10"/>
     </issue>
@@ -8966,7 +7943,7 @@
         errorLine1="    &lt;LinearLayout"
         errorLine2="     ~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/photo_picker/android/java/res/layout/photo_picker_bitmap_view.xml"
+            file="../../components/browser_ui/photo_picker/android/java/res/layout/photo_picker_bitmap_view.xml"
             line="94"
             column="6"/>
     </issue>
@@ -8977,8 +7954,8 @@
         errorLine1="  &lt;LinearLayout"
         errorLine2="   ~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/share/android/java/res/layout/qrcode_camera_error_layout.xml"
-            line="11"
+            file="../../chrome/browser/share/android/java/res/layout/qrcode_camera_error_layout.xml"
+            line="13"
             column="4"/>
     </issue>
 
@@ -8988,8 +7965,8 @@
         errorLine1="                    assert reachesWindowCallback(activity.getWindow().getCallback());"
         errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/base/android/java/src/org/chromium/base/ApplicationStatus.java"
-            line="301"
+            file="../../base/android/java/src/org/chromium/base/ApplicationStatus.java"
+            line="351"
             column="28"/>
     </issue>
 
@@ -8999,8 +7976,8 @@
         errorLine1="            assert verifyCoherency("
         errorLine2="                   ^">
         <location
-            file="$SRC/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/AutocompleteResult.java"
-            line="273"
+            file="../../components/omnibox/browser/android/java/src/org/chromium/components/omnibox/AutocompleteResult.java"
+            line="222"
             column="20"/>
     </issue>
 
@@ -9010,7 +7987,7 @@
         errorLine1="            assert mNotificationId == getRemotingNotificationIdFromClient();"
         errorLine2="                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/weblayer/browser/java/org/chromium/weblayer_private/media/MediaRouterClientImpl.java"
+            file="../../weblayer/browser/java/org/chromium/weblayer_private/media/MediaRouterClientImpl.java"
             line="144"
             column="39"/>
     </issue>
@@ -9021,7 +7998,7 @@
         errorLine1="                assert notificationInfo.id == getNotificationId();"
         errorLine2="                                              ~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/weblayer/browser/java/org/chromium/weblayer_private/media/MediaSessionManager.java"
+            file="../../weblayer/browser/java/org/chromium/weblayer_private/media/MediaSessionManager.java"
             line="60"
             column="47"/>
     </issue>
@@ -9032,7 +8009,7 @@
         errorLine1="        assert SyncService.get() != null;"
         errorLine2="               ~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseActivity.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseActivity.java"
             line="46"
             column="16"/>
     </issue>
@@ -9043,7 +8020,7 @@
         errorLine1="        assert SyncService.get() != null;"
         errorLine2="               ~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseDialogFragment.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseDialogFragment.java"
             line="82"
             column="16"/>
     </issue>
@@ -9054,40 +8031,29 @@
         errorLine1="        assert SyncService.get() != null;"
         errorLine2="               ~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettings.java"
-            line="660"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettings.java"
+            line="658"
             column="16"/>
     </issue>
 
     <issue
         id="AssertionSideEffect"
         message="Assertion condition has a side effect: sValuesReturned.boolValues.put(preferenceName, flag)"
-        errorLine1="            assert CachedFeatureFlags.isEnabled(ChromeFeatureList.INSTANT_START);"
-        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        errorLine1="            assert ChromeFeatureList.sInstantStart.isEnabled();"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/pseudotab/PseudoTab.java"
-            line="301"
+            file="../../chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/pseudotab/PseudoTab.java"
+            line="300"
             column="20"/>
     </issue>
 
     <issue
         id="AssertionSideEffect"
-        message="Assertion condition has a side effect: sValuesReturned.boolValues.put(preferenceName, flag)"
-        errorLine1="        assert CachedFeatureFlags.isEnabled(ChromeFeatureList.INSTANT_START)"
-        errorLine2="               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/pseudotab/PseudoTab.java"
-            line="335"
-            column="16"/>
-    </issue>
-
-    <issue
-        id="AssertionSideEffect"
         message="Assertion condition has a side effect: sHaveAccessNetworkState =&#xA;                    ApiCompatibilityUtils.checkPermission(ContextUtils.getApplicationContext(),&#xA;                            Manifest.permission.ACCESS_NETWORK_STATE, Process.myPid(),&#xA;                            Process.myUid())&#xA;                    == PackageManager.PERMISSION_GRANTED"
         errorLine1="        assert isSupported();"
         errorLine2="               ~~~~~~~~~~~~~">
         <location
-            file="$SRC/base/android/java/src/org/chromium/base/RadioUtils.java"
+            file="../../base/android/java/src/org/chromium/base/RadioUtils.java"
             line="80"
             column="16"/>
     </issue>
@@ -9098,7 +8064,7 @@
         errorLine1="        assert isSupported();"
         errorLine2="               ~~~~~~~~~~~~~">
         <location
-            file="$SRC/base/android/java/src/org/chromium/base/RadioUtils.java"
+            file="../../base/android/java/src/org/chromium/base/RadioUtils.java"
             line="105"
             column="16"/>
     </issue>
@@ -9109,7 +8075,7 @@
         errorLine1="        assert isSupported();"
         errorLine2="               ~~~~~~~~~~~~~">
         <location
-            file="$SRC/base/android/java/src/org/chromium/base/RadioUtils.java"
+            file="../../base/android/java/src/org/chromium/base/RadioUtils.java"
             line="131"
             column="16"/>
     </issue>
@@ -9120,7 +8086,7 @@
         errorLine1="        assert SyncService.get() != null;"
         errorLine2="               ~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/signin/SyncPromoView.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/signin/SyncPromoView.java"
             line="59"
             column="16"/>
     </issue>
@@ -9131,8 +8097,8 @@
         errorLine1="        assert TabUiFeatureUtilities.ENABLE_SEARCH_CHIP.getValue();"
         errorLine2="               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java"
-            line="1569"
+            file="../../chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java"
+            line="1766"
             column="16"/>
     </issue>
 
@@ -9142,8 +8108,8 @@
         errorLine1="&lt;FrameLayout"
         errorLine2="^">
         <location
-            file="$SRC/chrome/android/java/res/layout/signin_activity.xml"
-            line="5"
+            file="../../chrome/android/java/res/layout/signin_activity.xml"
+            line="7"
             column="1"/>
     </issue>
 
@@ -9153,8 +8119,8 @@
         errorLine1="    &lt;macro name=&quot;suggestion_url_color&quot;>@macro/default_text_color_link&lt;/macro>"
         errorLine2="           ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/omnibox/java/res/values/colors.xml"
-            line="10"
+            file="../../chrome/browser/ui/android/omnibox/java/res/values/colors.xml"
+            line="12"
             column="12"/>
     </issue>
 
@@ -9164,8 +8130,8 @@
         errorLine1="    &lt;macro name=&quot;default_bg_color_elev_0&quot;>?attr/colorSurface&lt;/macro>"
         errorLine2="           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/styles/android/java/res/values/semantic_colors_dynamic.xml"
-            line="7"
+            file="../../components/browser_ui/styles/android/java/res/values/semantic_colors_dynamic.xml"
+            line="9"
             column="12"/>
     </issue>
 
@@ -9175,7 +8141,7 @@
         errorLine1="                    dir.getAbsolutePath(), dir.getUsableSpace(), dir.getTotalSpace(), type);"
         errorLine2="                                               ~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/DownloadDirectoryProvider.java"
+            file="../../chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/DownloadDirectoryProvider.java"
             line="156"
             column="48"/>
     </issue>
@@ -9186,7 +8152,7 @@
         errorLine1="            mFreeSpace = Environment.getExternalStorageDirectory().getUsableSpace();"
         errorLine2="                                                                   ~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/download/OMADownloadHandler.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/download/OMADownloadHandler.java"
             line="348"
             column="68"/>
     </issue>
@@ -9197,7 +8163,7 @@
         errorLine1="        return Environment.getDataDirectory().getUsableSpace();"
         errorLine2="                                              ~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java"
             line="240"
             column="47"/>
     </issue>
@@ -9208,7 +8174,7 @@
         errorLine1="                        defaultDownloadDir.getAbsolutePath(), defaultDownloadDir.getUsableSpace(),"
         errorLine2="                                                                                 ~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/storage/StorageSummaryProvider.java"
+            file="../../chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/storage/StorageSummaryProvider.java"
             line="88"
             column="82"/>
     </issue>
@@ -9219,7 +8185,7 @@
         errorLine1="        &lt;EditText"
         errorLine2="         ~~~~~~~~">
         <location
-            file="$SRC/android_webview/nonembedded/java/res_devui/layout/fragment_flags.xml"
+            file="../../android_webview/nonembedded/java/res_devui/layout/fragment_flags.xml"
             line="25"
             column="10"/>
     </issue>
@@ -9230,8 +8196,8 @@
         errorLine1="    public boolean onTouchEvent(MotionEvent e) {"
         errorLine2="                   ~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/accessibility_tab_switcher/AccessibilityTabModelListItem.java"
-            line="463"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/accessibility_tab_switcher/AccessibilityTabModelListItem.java"
+            line="464"
             column="20"/>
     </issue>
 
@@ -9241,8 +8207,8 @@
         errorLine1="            row.setDragHandleOnTouchListener((v, event) -> {"
         errorLine2="                                             ^">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java"
-            line="294"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java"
+            line="292"
             column="46"/>
     </issue>
 
@@ -9252,8 +8218,8 @@
         errorLine1="        mDragHandle.setOnTouchListener(l);"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkRow.java"
-            line="321"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkRow.java"
+            line="323"
             column="9"/>
     </issue>
 
@@ -9263,7 +8229,7 @@
         errorLine1="    public boolean onTouchEvent(MotionEvent e) {"
         errorLine2="                   ~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/bottomsheet/android/internal/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheet.java"
+            file="../../components/browser_ui/bottomsheet/android/internal/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheet.java"
             line="286"
             column="20"/>
     </issue>
@@ -9274,7 +8240,7 @@
         errorLine1="        textView.setOnTouchListener((View v, MotionEvent event) -> {"
         errorLine2="        ^">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/browsing_data/ClearBrowsingDataCheckBoxPreference.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/browsing_data/ClearBrowsingDataCheckBoxPreference.java"
             line="54"
             column="9"/>
     </issue>
@@ -9285,7 +8251,7 @@
         errorLine1="        textView.setOnTouchListener((View v, MotionEvent event) -> {"
         errorLine2="                                    ^">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/browsing_data/ClearBrowsingDataCheckBoxPreference.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/browsing_data/ClearBrowsingDataCheckBoxPreference.java"
             line="54"
             column="37"/>
     </issue>
@@ -9296,8 +8262,8 @@
         errorLine1="    public boolean onTouchEvent(MotionEvent e) {"
         errorLine2="                   ~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java"
-            line="645"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java"
+            line="752"
             column="20"/>
     </issue>
 
@@ -9307,8 +8273,8 @@
         errorLine1="    public boolean onTouchEvent(MotionEvent event) {"
         errorLine2="                   ~~~~~~~~~~~~">
         <location
-            file="$SRC/components/embedder_support/android/java/src/org/chromium/components/embedder_support/view/ContentView.java"
-            line="367"
+            file="../../components/embedder_support/android/java/src/org/chromium/components/embedder_support/view/ContentView.java"
+            line="379"
             column="20"/>
     </issue>
 
@@ -9318,7 +8284,7 @@
         errorLine1="        menuBtn.setOnTouchListener(menuPopupButtonHelper);"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/ui/tablet/emptybackground/EmptyBackgroundViewTablet.java"
+            file="../../chrome/android/java/src/org/chromium/chrome/browser/ui/tablet/emptybackground/EmptyBackgroundViewTablet.java"
             line="98"
             column="9"/>
     </issue>
@@ -9329,8 +8295,8 @@
         errorLine1="            editText.setOnTouchListener((View v, MotionEvent event) -> {"
         errorLine2="            ^">
         <location
-            file="$SRC/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/FlagsFragment.java"
-            line="185"
+            file="../../android_webview/nonembedded/java/src/org/chromium/android_webview/devui/FlagsFragment.java"
+            line="191"
             column="13"/>
     </issue>
 
@@ -9340,8 +8306,8 @@
         errorLine1="            editText.setOnTouchListener((View v, MotionEvent event) -> {"
         errorLine2="                                        ^">
         <location
-            file="$SRC/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/FlagsFragment.java"
-            line="185"
+            file="../../android_webview/nonembedded/java/src/org/chromium/android_webview/devui/FlagsFragment.java"
+            line="191"
             column="41"/>
     </issue>
 
@@ -9351,8 +8317,8 @@
         errorLine1="            editText.setOnTouchListener(null);"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/FlagsFragment.java"
-            line="200"
+            file="../../android_webview/nonembedded/java/src/org/chromium/android_webview/devui/FlagsFragment.java"
+            line="206"
             column="13"/>
     </issue>
 
@@ -9362,8 +8328,8 @@
         errorLine1="    public boolean onTouchEvent(final MotionEvent event) {"
         errorLine2="                   ~~~~~~~~~~~~">
         <location
-            file="$SRC/android_webview/java/src/org/chromium/android_webview/FullScreenView.java"
-            line="91"
+            file="../../android_webview/java/src/org/chromium/android_webview/FullScreenView.java"
+            line="106"
             column="20"/>
     </issue>
 
@@ -9373,7 +8339,7 @@
         errorLine1="    public boolean onTouchEvent(MotionEvent event) {"
         errorLine2="                   ~~~~~~~~~~~~">
         <location
-            file="$SRC/components/infobars/android/java/src/org/chromium/components/infobars/InfoBarMessageView.java"
+            file="../../components/infobars/android/java/src/org/chromium/components/infobars/InfoBarMessageView.java"
             line="32"
             column="20"/>
     </issue>
@@ -9384,7 +8350,7 @@
         errorLine1="        holder.mStartIcon.setOnTouchListener((v, event) -> {"
         errorLine2="        ^">
         <location
-            file="$SRC/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/LanguageListBaseAdapter.java"
+            file="../../chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/LanguageListBaseAdapter.java"
             line="177"
             column="9"/>
     </issue>
@@ -9395,7 +8361,7 @@
         errorLine1="        holder.mStartIcon.setOnTouchListener((v, event) -> {"
         errorLine2="                                             ^">
         <location
-            file="$SRC/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/LanguageListBaseAdapter.java"
+            file="../../chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/LanguageListBaseAdapter.java"
             line="177"
             column="46"/>
     </issue>
@@ -9406,7 +8372,7 @@
         errorLine1="        mMenuImageButton.setOnTouchListener(mAppMenuButtonHelper);"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButton.java"
+            file="../../chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButton.java"
             line="79"
             column="9"/>
     </issue>
@@ -9417,7 +8383,7 @@
         errorLine1="        View.OnTouchListener onTouchListener = (View v, MotionEvent ev) -> {"
         errorLine2="                                               ^">
         <location
-            file="$SRC/components/browser_ui/modaldialog/android/java/src/org/chromium/components/browser_ui/modaldialog/ModalDialogView.java"
+            file="../../components/browser_ui/modaldialog/android/java/src/org/chromium/components/browser_ui/modaldialog/ModalDialogView.java"
             line="228"
             column="48"/>
     </issue>
@@ -9428,7 +8394,7 @@
         errorLine1="        positiveButton.setOnTouchListener(onTouchListener);"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/modaldialog/android/java/src/org/chromium/components/browser_ui/modaldialog/ModalDialogView.java"
+            file="../../components/browser_ui/modaldialog/android/java/src/org/chromium/components/browser_ui/modaldialog/ModalDialogView.java"
             line="258"
             column="9"/>
     </issue>
@@ -9439,7 +8405,7 @@
         errorLine1="        negativeButton.setOnTouchListener(onTouchListener);"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/modaldialog/android/java/src/org/chromium/components/browser_ui/modaldialog/ModalDialogView.java"
+            file="../../components/browser_ui/modaldialog/android/java/src/org/chromium/components/browser_ui/modaldialog/ModalDialogView.java"
             line="260"
             column="9"/>
     </issue>
@@ -9450,7 +8416,7 @@
         errorLine1="    public boolean onTouchEvent(MotionEvent event) {"
         errorLine2="                   ~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_component/NoSwipeViewPager.java"
+            file="../../chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_component/NoSwipeViewPager.java"
             line="24"
             column="20"/>
     </issue>
@@ -9461,7 +8427,7 @@
         errorLine1="            public boolean onTouch(View v, MotionEvent event) {"
         errorLine2="                           ~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/photo_picker/android/java/src/org/chromium/components/browser_ui/photo_picker/PickerVideoPlayer.java"
+            file="../../components/browser_ui/photo_picker/android/java/src/org/chromium/components/browser_ui/photo_picker/PickerVideoPlayer.java"
             line="242"
             column="28"/>
     </issue>
@@ -9472,7 +8438,7 @@
         errorLine1="    public boolean onTouchEvent(MotionEvent event) {"
         errorLine2="                   ~~~~~~~~~~~~">
         <location
-            file="$SRC/components/paint_preview/player/android/java/src/org/chromium/components/paintpreview/player/frame/PlayerFrameView.java"
+            file="../../components/paint_preview/player/android/java/src/org/chromium/components/paintpreview/player/frame/PlayerFrameView.java"
             line="143"
             column="20"/>
     </issue>
@@ -9483,7 +8449,7 @@
         errorLine1="    public boolean onTouchEvent(MotionEvent e) {"
         errorLine2="                   ~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/scrim/ScrimView.java"
+            file="../../components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/scrim/ScrimView.java"
             line="79"
             column="20"/>
     </issue>
@@ -9494,7 +8460,7 @@
         errorLine1="        mEmptyViewWrapper.setOnTouchListener((v, event) -> true);"
         errorLine2="                                             ~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/selectable_list/SelectableListLayout.java"
+            file="../../components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/selectable_list/SelectableListLayout.java"
             line="232"
             column="46"/>
     </issue>
@@ -9505,8 +8471,8 @@
         errorLine1="    public boolean onTouchEvent(MotionEvent event) {"
         errorLine2="                   ~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainer.java"
-            line="283"
+            file="../../chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainer.java"
+            line="447"
             column="20"/>
     </issue>
 
@@ -9516,8 +8482,8 @@
         errorLine1="    public boolean onTouchEvent(MotionEvent ev) {"
         errorLine2="                   ~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java"
-            line="522"
+            file="../../chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java"
+            line="531"
             column="20"/>
     </issue>
 
@@ -9527,7 +8493,7 @@
         errorLine1="    public boolean onTouchEvent(MotionEvent event) {"
         errorLine2="                   ~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/bottomsheet/android/internal/java/src/org/chromium/components/browser_ui/bottomsheet/TouchRestrictingFrameLayout.java"
+            file="../../components/browser_ui/bottomsheet/android/internal/java/src/org/chromium/components/browser_ui/bottomsheet/TouchRestrictingFrameLayout.java"
             line="46"
             column="20"/>
     </issue>
@@ -9538,7 +8504,7 @@
         errorLine1="            public boolean onTouch(View view, MotionEvent event) {"
         errorLine2="                           ~~~~~~~">
         <location
-            file="$SRC/weblayer/browser/java/org/chromium/weblayer_private/WebContentsGestureStateTracker.java"
+            file="../../weblayer/browser/java/org/chromium/weblayer_private/WebContentsGestureStateTracker.java"
             line="48"
             column="28"/>
     </issue>
@@ -9549,8 +8515,8 @@
         errorLine1="                android:clickable=&quot;true&quot;"
         errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/contacts_picker/android/java/res/layout/contacts_list_item_view.xml"
-            line="49"
+            file="../../components/browser_ui/contacts_picker/android/java/res/layout/contacts_list_item_view.xml"
+            line="51"
             column="17"/>
     </issue>
 
@@ -9560,8 +8526,8 @@
         errorLine1="                android:clickable=&quot;true&quot;"
         errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/contacts_picker/android/java/res/layout/contacts_list_item_view.xml"
-            line="73"
+            file="../../components/browser_ui/contacts_picker/android/java/res/layout/contacts_list_item_view.xml"
+            line="75"
             column="17"/>
     </issue>
 
@@ -9571,8 +8537,8 @@
         errorLine1="                android:clickable=&quot;true&quot;"
         errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/contacts_picker/android/java/res/layout/contacts_list_item_view.xml"
-            line="97"
+            file="../../components/browser_ui/contacts_picker/android/java/res/layout/contacts_list_item_view.xml"
+            line="99"
             column="17"/>
     </issue>
 
@@ -9582,8 +8548,8 @@
         errorLine1="        android:clickable=&quot;true&quot;"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/photo_picker/android/java/res/layout/photo_picker_dialog.xml"
-            line="41"
+            file="../../components/browser_ui/photo_picker/android/java/res/layout/photo_picker_dialog.xml"
+            line="43"
             column="9"/>
     </issue>
 
@@ -9593,8 +8559,8 @@
         errorLine1="            android:clickable=&quot;true&quot; >"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/android/java/res/layout/search_activity.xml"
-            line="28"
+            file="../../chrome/android/java/res/layout/search_activity.xml"
+            line="30"
             column="13"/>
     </issue>
 
@@ -9604,8 +8570,8 @@
         errorLine1="    android:clickable=&quot;true&quot;"
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chrome/browser/ui/android/toolbar/java/res/layout/start_top_toolbar.xml"
-            line="13"
+            file="../../chrome/browser/ui/android/toolbar/java/res/layout/start_top_toolbar.xml"
+            line="15"
             column="5"/>
     </issue>
 
@@ -9615,8 +8581,8 @@
         errorLine1="        android:clickable=&quot;true&quot;"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/photo_picker/android/java/res/layout/video_player.xml"
-            line="37"
+            file="../../components/browser_ui/photo_picker/android/java/res/layout/video_player.xml"
+            line="39"
             column="9"/>
     </issue>
 
@@ -9626,8 +8592,8 @@
         errorLine1="                android:clickable=&quot;true&quot;"
         errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/photo_picker/android/java/res/layout/video_player.xml"
-            line="99"
+            file="../../components/browser_ui/photo_picker/android/java/res/layout/video_player.xml"
+            line="101"
             column="17"/>
     </issue>
 
@@ -9637,30 +8603,9 @@
         errorLine1="                android:clickable=&quot;true&quot;"
         errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/browser_ui/photo_picker/android/java/res/layout/video_player.xml"
-            line="124"
+            file="../../components/browser_ui/photo_picker/android/java/res/layout/video_player.xml"
+            line="126"
             column="17"/>
     </issue>
 
-    <issue
-        id="GestureBackNavigation"
-        message="If intercepting back events, this should be handled through the registration of callbacks on the window level; Please see https://developer.android.com/about/versions/13/features/predictive-back-gesture"
-        errorLine1="            if (keyCode == KeyEvent.KEYCODE_BACK) {"
-        errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/android/java/src/org/chromium/chrome/browser/findinpage/FindToolbar.java"
-            line="137"
-            column="28"/>
-    </issue>
-
-    <issue
-        id="GestureBackNavigation"
-        message="If intercepting back events, this should be handled through the registration of callbacks on the window level; Please see https://developer.android.com/about/versions/13/features/predictive-back-gesture"
-        errorLine1="        } else if (keyCode == KeyEvent.KEYCODE_BACK) {"
-        errorLine2="                              ~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="$SRC/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediator.java"
-            line="1143"
-            column="31"/>
-    </issue>
 </issues>
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java
index 3414065e..b58f78c 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java
@@ -67,7 +67,7 @@
 @RunWith(BaseRobolectricTestRunner.class)
 @Features.EnableFeatures({ChromeFeatureList.TAB_STRIP_IMPROVEMENTS,
         ChromeFeatureList.GRID_TAB_SWITCHER_FOR_TABLETS, ChromeFeatureList.TAB_GROUPS_FOR_TABLETS})
-@Config(manifest = Config.NONE, sdk = Build.VERSION_CODES.M, qualifiers = "sw600dp")
+@Config(manifest = Config.NONE, sdk = Build.VERSION_CODES.N, qualifiers = "sw600dp")
 public class StripLayoutHelperTest {
     @Rule
     public TestRule mFeaturesProcessorRule = new Features.JUnitProcessor();
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripStackerUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripStackerUnitTest.java
index 095d88a..47004eb 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripStackerUnitTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripStackerUnitTest.java
@@ -25,7 +25,7 @@
 
 /** Tests for {@link StripStacker}. */
 @RunWith(BaseRobolectricTestRunner.class)
-@Config(manifest = Config.NONE, sdk = Build.VERSION_CODES.M, qualifiers = "sw600dp")
+@Config(manifest = Config.NONE, sdk = Build.VERSION_CODES.N, qualifiers = "sw600dp")
 public class StripStackerUnitTest {
     private static final float TAB_WIDTH = 25;
     private static final float CACHED_TAB_WIDTH = 30;
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CloseButtonNavigatorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CloseButtonNavigatorTest.java
index 2588b652..9703c0f2 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CloseButtonNavigatorTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CloseButtonNavigatorTest.java
@@ -51,7 +51,7 @@
  * Tests for {@link CloseButtonNavigator}.
  */
 @RunWith(ParameterizedRobolectricTestRunner.class)
-@Config(sdk = Build.VERSION_CODES.M, manifest = Config.NONE)
+@Config(sdk = Build.VERSION_CODES.N, manifest = Config.NONE)
 public class CloseButtonNavigatorTest {
     @Parameters
     public static Collection<Object[]> data() {
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt
index 7a535ce..65ca7c895 100644
--- a/chrome/android/profiles/newest.txt
+++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-109.0.5391.0_rc-r2-merged.afdo.bz2
+chromeos-chrome-amd64-109.0.5391.0_rc-r3-merged.afdo.bz2
diff --git a/chrome/android/webapk/shell_apk/AndroidManifest.xml b/chrome/android/webapk/shell_apk/AndroidManifest.xml
index b19e6be..1750aee 100644
--- a/chrome/android/webapk/shell_apk/AndroidManifest.xml
+++ b/chrome/android/webapk/shell_apk/AndroidManifest.xml
@@ -24,7 +24,7 @@
     {{{raw_manifest_tags}}}
 
     <uses-sdk
-        android:minSdkVersion="23"
+        android:minSdkVersion="24"
         android:targetSdkVersion="33" />
 
     <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
diff --git a/chrome/android/webapk/shell_apk/current_version/current_version.gni b/chrome/android/webapk/shell_apk/current_version/current_version.gni
index 0bebd748..71680a06 100644
--- a/chrome/android/webapk/shell_apk/current_version/current_version.gni
+++ b/chrome/android/webapk/shell_apk/current_version/current_version.gni
@@ -12,4 +12,4 @@
 # //chrome/android/webapk/shell_apk:webapk is changed. This includes
 # Java files, Android resource files and AndroidManifest.xml. Does not affect
 # Chrome.apk
-current_shell_apk_version = 156
+current_shell_apk_version = 157
diff --git a/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/h2o/LaunchTest.java b/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/h2o/LaunchTest.java
index 0540a271..c3a3aeff 100644
--- a/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/h2o/LaunchTest.java
+++ b/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/h2o/LaunchTest.java
@@ -87,32 +87,6 @@
     }
 
     /**
-     * Test launching via a deep link on pre-N Android.
-     * Check:
-     * 1) That the host browser was launched.
-     * 2) That no activities have been enabled/disabled.
-     */
-    @Test
-    @Config(sdk = Build.VERSION_CODES.M)
-    public void testDeepLinkPreN() {
-        registerWebApk(true /* isNewStyleWebApk */);
-
-        final String deepLinkUrl = "https://pwa.rocks/deep.html";
-
-        Intent launchIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(deepLinkUrl));
-        launchIntent.setPackage(sWebApkPackageName);
-
-        ArrayList<Intent> launchedIntents =
-                launchAndCheckBrowserLaunched(false /* opaqueMainActivityInitiallyEnabled */,
-                        launchIntent, H2OTransparentLauncherActivity.class,
-                        HostBrowserUtils.MINIMUM_REQUIRED_CHROMIUM_VERSION_NEW_SPLASH);
-        Assert.assertEquals(1, launchedIntents.size());
-        assertIntentIsForBrowserLaunch(launchedIntents.get(0), deepLinkUrl);
-
-        assertOnlyEnabledMainIntentHandler(H2OMainActivity.class);
-    }
-
-    /**
      * Test launching via a deep link on Android N+.
      * Check:
      * 1) That the host browser was launched.
@@ -423,40 +397,6 @@
      * Test {@link H2OOpaqueMainActivity#checkComponentEnabled()} when:
      * - Component enabled setting is default
      * AND
-     * - Android API level < N
-     */
-    @Test
-    @Config(sdk = Build.VERSION_CODES.M)
-    public void testCheckH2OOpaqueMainActivityEnabledPreN() {
-        changeWebApkActivityEnabledSetting(mPackageManager, H2OOpaqueMainActivity.class,
-                PackageManager.COMPONENT_ENABLED_STATE_DEFAULT);
-        Assert.assertFalse(H2OOpaqueMainActivity.checkComponentEnabled(
-                RuntimeEnvironment.application, false /* isNewStyleWebApk */));
-        Assert.assertFalse(H2OOpaqueMainActivity.checkComponentEnabled(
-                RuntimeEnvironment.application, true /* isNewStyleWebApk */));
-    }
-
-    /**
-     * Test {@link H2OMainActivity#checkComponentEnabled()} when:
-     * - Component enabled setting is default
-     * AND
-     * - Android API level < N
-     */
-    @Test
-    @Config(sdk = Build.VERSION_CODES.M)
-    public void testCheckH2oMainActivityEnabledPreN() {
-        changeWebApkActivityEnabledSetting(mPackageManager, H2OMainActivity.class,
-                PackageManager.COMPONENT_ENABLED_STATE_DEFAULT);
-        Assert.assertTrue(H2OMainActivity.checkComponentEnabled(
-                RuntimeEnvironment.application, false /* isNewStyleWebApk */));
-        Assert.assertTrue(H2OMainActivity.checkComponentEnabled(
-                RuntimeEnvironment.application, true /* isNewStyleWebApk */));
-    }
-
-    /**
-     * Test {@link H2OOpaqueMainActivity#checkComponentEnabled()} when:
-     * - Component enabled setting is default
-     * AND
      * - Android API level >= N
      */
     @Test
@@ -548,22 +488,6 @@
         assertFalse(containsSiteSettingsDynamicShortcut(shortcutManager));
     }
 
-    /** Tests that we do not attempt to add a shortcut on Android versions lower than N. */
-    @Test
-    @Config(sdk = Build.VERSION_CODES.M)
-    public void testDoesNotAddSiteSettingsWhenSdkLow() {
-        registerApkForSiteSettings(true /*enableInMetadata*/, true /*addCategory*/);
-
-        Intent launchIntent = new Intent(Intent.ACTION_MAIN);
-        launchIntent.setPackage(sWebApkPackageName);
-
-        launchAndCheckBrowserLaunched(false /* opaqueMainActivityInitiallyEnabled */, launchIntent,
-                H2OMainActivity.class, SITE_SETTINGS_COMPATIBLE_BROWSER_VERSION);
-
-        // There is no shortcut manager in Android L. Therefore if
-        // this test passes, then we did not attempt to add the shortcut.
-    }
-
     private static boolean containsSiteSettingsDynamicShortcut(ShortcutManager shortcutManager) {
         List<String> shortcutIDs = shortcutManager.getDynamicShortcuts()
                                            .stream()
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index a8b65c5b..6dd4bd1df 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -1957,11 +1957,11 @@
       </message>
       <message name="IDS_PROMPT_DOWNLOAD_SENSITIVE_CONTENT_WARNING"
         desc="Message shown in the download shelf when a download contains sensitive content, and the admin has chosen to warn the user">
-        <ph name="FILE_NAME">$1<ex>bla.exe</ex></ph> has sensitive content
+        Your organization's policies aren't met
       </message>
       <message name="IDS_PROMPT_DOWNLOAD_SENSITIVE_CONTENT_BLOCKED"
         desc="Message shown in the download shelf when a download contains sensitive content, and the admin has chosen to block the file">
-        <ph name="FILE_NAME">$1<ex>bla.exe</ex></ph> has sensitive or dangerous content. Ask its owner to fix.
+        Your organization's policies aren't met
       </message>
       <message name="IDS_PROMPT_DOWNLOAD_DEEP_SCANNED_OPENED_DANGEROUS"
         desc="Message shown in the download shelf when a download is finished being scanned, and issues were found">
@@ -2016,10 +2016,10 @@
         This file is dangerous
       </message>
       <message name="IDS_BLOCK_REASON_SENSITIVE_CONTENT_WARNING" desc="Message shown to the user on chrome://downloads page to explain this download is showing a warning because it contains sensitive content">
-        This file has sensitive content
+        Your organization's policies aren't met
       </message>
       <message name="IDS_SENSITIVE_CONTENT_BLOCKED_DESCRIPTION" desc="Message shown to the user on chrome://downloads page to explain this download is blocked because it contains sensitive content">
-        This file has sensitive or dangerous content. Ask its owner to fix.
+        Your organization's policies aren't met
       </message>
       <message name="IDS_BLOCKED_TOO_LARGE_DESCRIPTION" desc="Message shown to the user on chrome://downloads page to explain this download is blocked because it is too large for deep scanning">
         This file is too big for a security check. You can open files up to 50 MB.
@@ -9955,6 +9955,10 @@
         desc="Used to indicate that the speech recognition service did not get permission to use the microphone.">
         Voice search has been turned off.
       </message>
+      <message name="IDS_NEW_TAB_VOICE_LEARN_MORE_ACCESSIBILITY_LABEL"
+        desc="Text read by screen readers for a link that links to a Help article about using a microphone.">
+        Learn more about using a microphone
+      </message>
       <message name="IDS_NEW_TAB_VOICE_READY"
         desc="Used to indicate that the speech recognition service has started and is waiting for user input.">
         Speak now
@@ -13328,18 +13332,18 @@
     </message>
     <message name="IDS_DEEP_SCANNING_DIALOG_UPLOAD_FAILURE_MESSAGE" desc="Message shown in tab modal dialog after performing a deep scan of uploaded data when it doesn't comply with enterprise security policies">
       {NUM_FILES, plural,
-        =0 {This data has sensitive or dangerous content. Remove this content and try again.}
-        =1 {This file has sensitive or dangerous content. Remove this content and try again.}
-       other {These files have sensitive or dangerous content. Remove this content and try again.}}
+        =0 {This data or your device doesn’t meet some of your organization’s security policies. Check with your admin on what needs to be fixed.}
+        =1 {This file or your device doesn’t meet some of your organization’s security policies. Check with your admin on what needs to be fixed.}
+      other {These files don't meet some of your organization’s security policies. Check with your admin on what needs to be fixed.}}
     </message>
     <message name="IDS_DEEP_SCANNING_DIALOG_UPLOAD_WARNING_MESSAGE" desc="Message shown in tab modal dialog after performing a deep scan of uploaded data when it doesn't comply with enterprise security policies to warn the user and allow them to proceed or not">
       {NUM_FILES, plural,
-        =0 {This data has sensitive or dangerous content}
-        =1 {This file has sensitive or dangerous content}
-      other {These files have sensitive or dangerous content}}
+        =0 {This data or your device doesn’t meet some of your organization’s security policies. Check with your admin on what needs to be fixed.}
+        =1 {This file or your device doesn’t meet some of your organization’s security policies. Check with your admin on what needs to be fixed.}
+      other {These files don't meet some of your organization’s security policies. Check with your admin on what needs to be fixed.}}
     </message>
     <message name="IDS_DEEP_SCANNING_DIALOG_PRINT_WARNING_MESSAGE" desc="Message shown in tab modal dialog after performing a deep scan of a printed document when it doesn't comply with enterprise security policies">
-        This document has sensitive content.
+        This document or your device doesn’t meet some of your organization’s security policies. Check with your admin on what needs to be fixed.
     </message>
     <message name="IDS_DEEP_SCANNING_DIALOG_TIMEOUT_MESSAGE" desc="Message shown in tab modal dialog after a deep scan times out.">
       Something went wrong. Scanning could not be completed. Please try again.
diff --git a/chrome/app/generated_resources_grd/IDS_BLOCK_REASON_SENSITIVE_CONTENT_WARNING.png.sha1 b/chrome/app/generated_resources_grd/IDS_BLOCK_REASON_SENSITIVE_CONTENT_WARNING.png.sha1
index e9717fad..df1e7290 100644
--- a/chrome/app/generated_resources_grd/IDS_BLOCK_REASON_SENSITIVE_CONTENT_WARNING.png.sha1
+++ b/chrome/app/generated_resources_grd/IDS_BLOCK_REASON_SENSITIVE_CONTENT_WARNING.png.sha1
@@ -1 +1 @@
-45b8bf361bf54e1a70c4e517f2a092463471e8b7
\ No newline at end of file
+e275e07ec45b0cba3b67ebfa7e8e05b1e4273c76
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_DEEP_SCANNING_DIALOG_PRINT_WARNING_MESSAGE.png.sha1 b/chrome/app/generated_resources_grd/IDS_DEEP_SCANNING_DIALOG_PRINT_WARNING_MESSAGE.png.sha1
index bf92716b..6d2ee61 100644
--- a/chrome/app/generated_resources_grd/IDS_DEEP_SCANNING_DIALOG_PRINT_WARNING_MESSAGE.png.sha1
+++ b/chrome/app/generated_resources_grd/IDS_DEEP_SCANNING_DIALOG_PRINT_WARNING_MESSAGE.png.sha1
@@ -1 +1 @@
-6d8494be88bf19b95962abb59a6e08251299df4f
\ No newline at end of file
+3436f060c2b0384ab1cd75c219e25546a04d183b
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_DEEP_SCANNING_DIALOG_UPLOAD_FAILURE_MESSAGE.png.sha1 b/chrome/app/generated_resources_grd/IDS_DEEP_SCANNING_DIALOG_UPLOAD_FAILURE_MESSAGE.png.sha1
index da0da9ae..0d5e38a 100644
--- a/chrome/app/generated_resources_grd/IDS_DEEP_SCANNING_DIALOG_UPLOAD_FAILURE_MESSAGE.png.sha1
+++ b/chrome/app/generated_resources_grd/IDS_DEEP_SCANNING_DIALOG_UPLOAD_FAILURE_MESSAGE.png.sha1
@@ -1 +1 @@
-de765b26412f9cd6fa1398ad0fc3e56bb43c28ed
\ No newline at end of file
+10b6fc3885d047b0f4b294fb2efeb902bded0f67
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_DEEP_SCANNING_DIALOG_UPLOAD_WARNING_MESSAGE.png.sha1 b/chrome/app/generated_resources_grd/IDS_DEEP_SCANNING_DIALOG_UPLOAD_WARNING_MESSAGE.png.sha1
index cfdc67dc..0d5e38a 100644
--- a/chrome/app/generated_resources_grd/IDS_DEEP_SCANNING_DIALOG_UPLOAD_WARNING_MESSAGE.png.sha1
+++ b/chrome/app/generated_resources_grd/IDS_DEEP_SCANNING_DIALOG_UPLOAD_WARNING_MESSAGE.png.sha1
@@ -1 +1 @@
-2dbef815533e3dddee5671e14566bbb2b696a74d
\ No newline at end of file
+10b6fc3885d047b0f4b294fb2efeb902bded0f67
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_NEW_TAB_VOICE_LEARN_MORE_ACCESSIBILITY_LABEL.png.sha1 b/chrome/app/generated_resources_grd/IDS_NEW_TAB_VOICE_LEARN_MORE_ACCESSIBILITY_LABEL.png.sha1
new file mode 100644
index 0000000..8ed204fa
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_NEW_TAB_VOICE_LEARN_MORE_ACCESSIBILITY_LABEL.png.sha1
@@ -0,0 +1 @@
+32f55642db50438fec47ec1cb3de83d394d95e52
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_PROMPT_DOWNLOAD_SENSITIVE_CONTENT_BLOCKED.png.sha1 b/chrome/app/generated_resources_grd/IDS_PROMPT_DOWNLOAD_SENSITIVE_CONTENT_BLOCKED.png.sha1
index d737f8a..59274b7 100644
--- a/chrome/app/generated_resources_grd/IDS_PROMPT_DOWNLOAD_SENSITIVE_CONTENT_BLOCKED.png.sha1
+++ b/chrome/app/generated_resources_grd/IDS_PROMPT_DOWNLOAD_SENSITIVE_CONTENT_BLOCKED.png.sha1
@@ -1 +1 @@
-59258678ee356a96708120bf74f6883cedd32c63
\ No newline at end of file
+8aef68863d9576435712b0869e948730fdcfc7ac
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_PROMPT_DOWNLOAD_SENSITIVE_CONTENT_WARNING.png.sha1 b/chrome/app/generated_resources_grd/IDS_PROMPT_DOWNLOAD_SENSITIVE_CONTENT_WARNING.png.sha1
index 3dbb04f..59274b7 100644
--- a/chrome/app/generated_resources_grd/IDS_PROMPT_DOWNLOAD_SENSITIVE_CONTENT_WARNING.png.sha1
+++ b/chrome/app/generated_resources_grd/IDS_PROMPT_DOWNLOAD_SENSITIVE_CONTENT_WARNING.png.sha1
@@ -1 +1 @@
-ae96f6ed0f31b53aa8db27434af0bc522ee9d4e5
\ No newline at end of file
+8aef68863d9576435712b0869e948730fdcfc7ac
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_SENSITIVE_CONTENT_BLOCKED_DESCRIPTION.png.sha1 b/chrome/app/generated_resources_grd/IDS_SENSITIVE_CONTENT_BLOCKED_DESCRIPTION.png.sha1
index 2536d844..df1e7290 100644
--- a/chrome/app/generated_resources_grd/IDS_SENSITIVE_CONTENT_BLOCKED_DESCRIPTION.png.sha1
+++ b/chrome/app/generated_resources_grd/IDS_SENSITIVE_CONTENT_BLOCKED_DESCRIPTION.png.sha1
@@ -1 +1 @@
-a1234d4ee475f15e26a4f616fa3aef87a503ab91
\ No newline at end of file
+e275e07ec45b0cba3b67ebfa7e8e05b1e4273c76
\ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 03bed95..8913b22 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -14,6 +14,7 @@
 import("//chrome/browser/buildflags.gni")
 import("//chrome/browser/downgrade/buildflags.gni")
 import("//chrome/common/features.gni")
+import("//chrome/services/speech/buildflags/buildflags.gni")
 import("//chromeos/ash/components/assistant/assistant.gni")
 import("//components/captive_portal/core/features.gni")
 import("//components/feed/features.gni")
@@ -608,6 +609,8 @@
     "history/top_sites_factory.h",
     "history/web_history_service_factory.cc",
     "history/web_history_service_factory.h",
+    "history_clusters/history_clusters_image_fetcher.cc",
+    "history_clusters/history_clusters_image_fetcher.h",
     "history_clusters/history_clusters_metrics_logger.cc",
     "history_clusters/history_clusters_metrics_logger.h",
     "history_clusters/history_clusters_service_factory.cc",
@@ -2236,6 +2239,7 @@
     "//components/policy/core/browser",
     "//components/policy/proto",
     "//components/power_bookmarks/core",
+    "//components/power_bookmarks/storage",
     "//components/pref_registry",
     "//components/prefs",
     "//components/privacy_sandbox",
@@ -3467,6 +3471,7 @@
       "//components/payments/content/android:jni_headers",
       "//components/permissions/android:native",
       "//components/power_bookmarks/core",
+      "//components/power_bookmarks/storage",
       "//components/power_scheduler",
       "//components/query_tiles",
       "//components/reading_list/features:flags",
@@ -5399,6 +5404,10 @@
     if (enable_cros_libassistant) {
       deps += [ "//chromeos/ash/services/libassistant/public/mojom" ]
     }
+
+    if (enable_server_based_recognition) {
+      deps += [ "//chrome/services/speech/internal:lib" ]
+    }
   } else {  # Non - Ash.
     sources += [
       "enterprise/reporting/cloud_profile_reporting_service.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 7320e545..4da1d52 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -887,6 +887,7 @@
 const char kLacrosPrimaryInternalName[] = "lacros-primary";
 const char kLacrosSupportInternalName[] = "lacros-support";
 const char kLacrosStabilityInternalName[] = "lacros-stability";
+const char kLacrosWaylandLoggingInternalName[] = "lacros-wayland-logging";
 const char kWebAppsCrosapiInternalName[] = "web-apps-crosapi";
 const char kArcEnableVirtioBlkForDataInternalName[] =
     "arc-enable-virtio-blk-for-data";
@@ -3767,10 +3768,6 @@
          chrome::android::kRelatedSearchesAlternateUx,
          kRelatedSearchesAlternateUxVariations,
          "RelatedSearchesAlternateUx")},
-    {"related-searches-simplified-ux",
-     flag_descriptions::kRelatedSearchesSimplifiedUxName,
-     flag_descriptions::kRelatedSearchesSimplifiedUxDescription, kOsAndroid,
-     FEATURE_VALUE_TYPE(chrome::android::kRelatedSearchesSimplifiedUx)},
 #endif  // BUILDFLAG(IS_ANDROID)
     {"show-autofill-type-predictions",
      flag_descriptions::kShowAutofillTypePredictionsName,
@@ -4056,6 +4053,10 @@
     {kLacrosStabilityInternalName, flag_descriptions::kLacrosStabilityName,
      flag_descriptions::kLacrosStabilityDescription, kOsCrOS,
      MULTI_VALUE_TYPE(kLacrosStabilityChoices)},
+    {kLacrosWaylandLoggingInternalName,
+     flag_descriptions::kLacrosWaylandLoggingName,
+     flag_descriptions::kLacrosWaylandLoggingDescription, kOsCrOS,
+     FEATURE_VALUE_TYPE(ash::features::kLacrosWaylandLogging)},
     {kPreferDcheckInternalName, flag_descriptions::kPreferDcheckName,
      flag_descriptions::kPreferDcheckDescription, kOsCrOS,
      MULTI_VALUE_TYPE(kPreferDcheckChoices)},
@@ -6612,6 +6613,13 @@
      FEATURE_VALUE_TYPE(features::kAutoDisableAccessibility)},
 
 #if BUILDFLAG(IS_ANDROID)
+    {"enable-auto-disable-accessibility-v2",
+     flag_descriptions::kEnableAutoDisableAccessibilityV2Name,
+     flag_descriptions::kEnableAutoDisableAccessibilityV2Description,
+     kOsAndroid, FEATURE_VALUE_TYPE(features::kAutoDisableAccessibilityV2)},
+#endif
+
+#if BUILDFLAG(IS_ANDROID)
     {"cct-incognito", flag_descriptions::kCCTIncognitoName,
      flag_descriptions::kCCTIncognitoDescription, kOsAndroid,
      FEATURE_VALUE_TYPE(chrome::android::kCCTIncognito)},
diff --git a/chrome/browser/android/webapk/webapk_update_data_fetcher.cc b/chrome/browser/android/webapk/webapk_update_data_fetcher.cc
index ec06608..32d41407 100644
--- a/chrome/browser/android/webapk/webapk_update_data_fetcher.cc
+++ b/chrome/browser/android/webapk/webapk_update_data_fetcher.cc
@@ -176,9 +176,9 @@
   // will treat the manifest with different id as the one of another WebAPK.
   if (base::FeatureList::IsEnabled(webapps::features::kWebApkUniqueId) &&
       !web_manifest_id_.is_empty() && web_manifest_id_ != new_manifest_id) {
-    UMA_HISTOGRAM_BOOLEAN("WebApk.UniqueId.FoundDifferentId.ManifestUrl",
+    UMA_HISTOGRAM_BOOLEAN("WebApk.Update.UniqueIdDifferent.ManifestUrl",
                           web_manifest_url_ == data.manifest_url);
-    UMA_HISTOGRAM_BOOLEAN("WebApk.UniqueId.FoundDifferentId.StartUrl",
+    UMA_HISTOGRAM_BOOLEAN("WebApk.Update.UniqueIdDifferent.StartUrl",
                           start_url_ == data.manifest.start_url);
     return;
   }
diff --git a/chrome/browser/ash/crosapi/browser_manager.cc b/chrome/browser/ash/crosapi/browser_manager.cc
index 8a1d2a5..035a039 100644
--- a/chrome/browser/ash/crosapi/browser_manager.cc
+++ b/chrome/browser/ash/crosapi/browser_manager.cc
@@ -12,6 +12,7 @@
 #include <utility>
 #include <vector>
 
+#include "ash/constants/ash_features.h"
 #include "ash/constants/ash_switches.h"
 #include "ash/public/cpp/notification_utils.h"
 #include "ash/strings/grit/ash_strings.h"
@@ -789,6 +790,10 @@
   options.environment["CHROME_VERSION_EXTRA"] =
       version_info::GetChannelString(update_channel);
 
+  if (base::FeatureList::IsEnabled(ash::features::kLacrosWaylandLogging)) {
+    options.environment["WAYLAND_DEBUG"] = "1";
+  }
+
   std::string additional_env =
       base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
           ash::switches::kLacrosChromeAdditionalEnv);
diff --git a/chrome/browser/ash/login/easy_unlock/easy_unlock_service.cc b/chrome/browser/ash/login/easy_unlock/easy_unlock_service.cc
index 712c7ee..541153c 100644
--- a/chrome/browser/ash/login/easy_unlock/easy_unlock_service.cc
+++ b/chrome/browser/ash/login/easy_unlock/easy_unlock_service.cc
@@ -42,7 +42,6 @@
 #include "chromeos/ash/components/proximity_auth/proximity_auth_system.h"
 #include "chromeos/ash/components/proximity_auth/screenlock_bridge.h"
 #include "chromeos/dbus/power/power_manager_client.h"
-#include "chromeos/dbus/power_manager/idle.pb.h"
 #include "components/account_id/account_id.h"
 #include "components/pref_registry/pref_registry_syncable.h"
 #include "components/prefs/pref_registry_simple.h"
@@ -116,22 +115,6 @@
 
  private:
   // PowerManagerClient::Observer:
-  void ScreenIdleStateChanged(
-      const power_manager::ScreenIdleState& proto) override {
-    if (!base::FeatureList::IsEnabled(
-            ash::features::kSmartLockBluetoothScreenOffFix)) {
-      return;
-    }
-
-    if (proto.off()) {
-      service_->OnScreenOff();
-      return;
-    }
-
-    service_->OnScreenOffDone();
-    service_->UpdateAppState();
-  }
-
   void SuspendImminent(power_manager::SuspendImminent::Reason reason) override {
     service_->PrepareForSuspend();
   }
@@ -836,7 +819,7 @@
   }
 }
 
-void EasyUnlockService::OnSuspendOrScreenOff() {
+void EasyUnlockService::PrepareForSuspend() {
   if (base::FeatureList::IsEnabled(ash::features::kSmartLockUIRevamp)) {
     if (smart_lock_state_ && *smart_lock_state_ != SmartLockState::kInactive) {
       ShowInitialSmartLockState();
@@ -846,10 +829,6 @@
       UpdateSmartLockState(SmartLockState::kConnectingToPhone);
     }
   }
-}
-
-void EasyUnlockService::PrepareForSuspend() {
-  OnSuspendOrScreenOff();
 
   if (proximity_auth_system_)
     proximity_auth_system_->OnSuspend();
@@ -860,28 +839,6 @@
     proximity_auth_system_->OnSuspendDone();
 }
 
-void EasyUnlockService::OnScreenOff() {
-  if (!base::FeatureList::IsEnabled(
-          ash::features::kSmartLockBluetoothScreenOffFix)) {
-    return;
-  }
-
-  OnSuspendOrScreenOff();
-
-  if (proximity_auth_system_)
-    proximity_auth_system_->OnScreenOff();
-}
-
-void EasyUnlockService::OnScreenOffDone() {
-  if (!base::FeatureList::IsEnabled(
-          ash::features::kSmartLockBluetoothScreenOffFix)) {
-    return;
-  }
-
-  if (proximity_auth_system_)
-    proximity_auth_system_->OnScreenOffDone();
-}
-
 void EasyUnlockService::EnsureTpmKeyPresentIfNeeded() {
   if (tpm_key_checked_ || GetType() != TYPE_REGULAR || GetAccountId().empty() ||
       GetHardlockState() == SmartLockStateHandler::NO_PAIRING) {
diff --git a/chrome/browser/ash/login/easy_unlock/easy_unlock_service.h b/chrome/browser/ash/login/easy_unlock/easy_unlock_service.h
index c9fa4da..9868196 100644
--- a/chrome/browser/ash/login/easy_unlock/easy_unlock_service.h
+++ b/chrome/browser/ash/login/easy_unlock/easy_unlock_service.h
@@ -280,22 +280,12 @@
       bool success,
       const EasyUnlockDeviceKeyDataList& key_data_list);
 
-  // Called inside PrepareForSuspend() and OnScreenOff() to handle shared Smart
-  // Lock state updates.
-  void OnSuspendOrScreenOff();
-
   // Updates the service to state for handling system suspend.
   void PrepareForSuspend();
 
   // Called when the system resumes from a suspended state.
   void OnSuspendDone();
 
-  // Update the service to state for handling when the screen turns off.
-  void OnScreenOff();
-
-  // Called when the system resumes after the screen turns back on.
-  void OnScreenOffDone();
-
   void EnsureTpmKeyPresentIfNeeded();
 
   // Determines whether failure to unlock with phone should be handled as an
diff --git a/chrome/browser/ash/login/easy_unlock/easy_unlock_service_regular_unittest.cc b/chrome/browser/ash/login/easy_unlock/easy_unlock_service_regular_unittest.cc
index 7cec28c..c794429 100644
--- a/chrome/browser/ash/login/easy_unlock/easy_unlock_service_regular_unittest.cc
+++ b/chrome/browser/ash/login/easy_unlock/easy_unlock_service_regular_unittest.cc
@@ -43,7 +43,6 @@
 #include "chromeos/ash/services/secure_channel/public/cpp/client/fake_secure_channel_client.h"
 #include "chromeos/dbus/power/fake_power_manager_client.h"
 #include "chromeos/dbus/power/power_manager_client.h"
-#include "chromeos/dbus/power_manager/idle.pb.h"
 #include "components/account_id/account_id.h"
 #include "components/signin/public/identity_manager/account_info.h"
 #include "components/sync_preferences/testing_pref_service_syncable.h"
@@ -334,15 +333,6 @@
     easy_unlock_service_regular_->ResetSmartLockState();
   }
 
-  void SetScreenIdleStateAndWait(bool is_screen_dimmed, bool is_off) {
-    power_manager::ScreenIdleState screen_idle_state;
-    screen_idle_state.set_dimmed(is_screen_dimmed);
-    screen_idle_state.set_off(is_off);
-    chromeos::FakePowerManagerClient::Get()->SendScreenIdleStateChanged(
-        screen_idle_state);
-    base::RunLoop().RunUntilIdle();
-  }
-
   // Must outlive TestingProfiles.
   content::BrowserTaskEnvironment task_environment_;
 
@@ -716,26 +706,6 @@
             fake_lock_handler_->smart_lock_state().value());
 }
 
-TEST_F(EasyUnlockServiceRegularTest, OnScreenOff) {
-  base::test::ScopedFeatureList feature_list(
-      features::kSmartLockBluetoothScreenOffFix);
-  InitializeService(/*should_initialize_all_dependencies=*/true);
-  SetScreenLockState(/*is_locked=*/true);
-  EasyUnlockService* service = easy_unlock_service_regular_.get();
-
-  // Dimming screen shouldn't reset Smart Lock state.
-  service->UpdateSmartLockState(SmartLockState::kPhoneAuthenticated);
-  EXPECT_EQ(SmartLockState::kPhoneAuthenticated,
-            fake_lock_handler_->smart_lock_state().value());
-  SetScreenIdleStateAndWait(/*is_screen_dimmed=*/true, /*is_off=*/false);
-  EXPECT_EQ(SmartLockState::kPhoneAuthenticated,
-            fake_lock_handler_->smart_lock_state().value());
-
-  SetScreenIdleStateAndWait(/*is_screen_dimmed=*/false, /*is_off=*/true);
-  EXPECT_EQ(SmartLockState::kConnectingToPhone,
-            fake_lock_handler_->smart_lock_state().value());
-}
-
 TEST_F(EasyUnlockServiceRegularTest, HandleAuthFailureInUpdateSmartLockState) {
   InitializeService(/*should_initialize_all_dependencies=*/true);
   SetScreenLockState(/*is_locked=*/true);
diff --git a/chrome/browser/ash/login/users/default_user_image/default_user_images.cc b/chrome/browser/ash/login/users/default_user_image/default_user_images.cc
index aacffcd1..7e774723 100644
--- a/chrome/browser/ash/login/users/default_user_image/default_user_images.cc
+++ b/chrome/browser/ash/login/users/default_user_image/default_user_images.cc
@@ -345,13 +345,28 @@
 const int kHistogramImagesCount =
     kDefaultImagesCount + kHistogramSpecialImagesMaxCount;
 
-GURL GetDefaultImageUrl(int index) {
+ui::ResourceScaleFactor GetAdjustedScaleFactorForDefaultImage(
+    int index,
+    ui::ResourceScaleFactor scale_factor) {
+  ui::ResourceScaleFactor max_scale_factor =
+      GetMaximumScaleFactorForDefaultImage(index);
+  if (max_scale_factor == ui::k100Percent)
+    return max_scale_factor;
+
+  return scale_factor;
+}
+
+GURL GetDefaultImageUrl(
+    int index,
+    ui::ResourceScaleFactor scale_factor /*= ui::k200Percent*/) {
   DCHECK(index >= 0 && index < kDefaultImagesCount);
 
   if (ash::features::IsAvatarsCloudMigrationEnabled()) {
-    // TODO(b/244369871): Support 1x/2x images based on pixel density.
+    ui::ResourceScaleFactor adjusted_scale_factor =
+        GetAdjustedScaleFactorForDefaultImage(index, scale_factor);
     auto scale_factor_prefix =
-        GetUrlPrefixForScaleFactor(GetMaximumScaleFactorForDefaultImage(index));
+        GetUrlPrefixForScaleFactor(adjusted_scale_factor);
+
     return GURL(base::StrCat({kGstaticImagePrefix, scale_factor_prefix,
                               kDefaultImageInfo[index].path}));
   }
@@ -387,7 +402,9 @@
          kDefaultImageInfo[index].eligibility == Eligibility::kEligible;
 }
 
-DefaultUserImage GetDefaultUserImage(int index) {
+DefaultUserImage GetDefaultUserImage(
+    int index,
+    ui::ResourceScaleFactor scale_factor /*= ui::k200Percent*/) {
   DCHECK(IsValidIndex(index));
   int description_message_id = kDefaultImageInfo[index].description_message_id;
   std::u16string title = description_message_id
@@ -395,7 +412,7 @@
                              : std::u16string();
 
   return {index, std::move(title),
-          default_user_image::GetDefaultImageUrl(index),
+          default_user_image::GetDefaultImageUrl(index, scale_factor),
           GetDeprecatedDefaultImageSourceInfo(index)};
 }
 
diff --git a/chrome/browser/ash/login/users/default_user_image/default_user_images.h b/chrome/browser/ash/login/users/default_user_image/default_user_images.h
index 3afe52fd..8f7fee7 100644
--- a/chrome/browser/ash/login/users/default_user_image/default_user_images.h
+++ b/chrome/browser/ash/login/users/default_user_image/default_user_images.h
@@ -14,6 +14,7 @@
 #include "ash/public/cpp/default_user_image.h"
 #include "base/values.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
+#include "ui/base/resource/resource_bundle.h"
 #include "url/gurl.h"
 
 namespace gfx {
@@ -53,10 +54,20 @@
 // Number of possible histogram values for user images.
 extern const int kHistogramImagesCount;
 
+// Returns the effective scale factor for a default user image with the
+// specified index. This accounts for some default user images only being
+// available in limited resolutions.
+ui::ResourceScaleFactor GetAdjustedScaleFactorForDefaultImage(
+    int index,
+    ui::ResourceScaleFactor scale_factor);
+
 // Returns the URL to a default user image with the specified index. If the
 // index is invalid, returns the default user image for index 0 (anonymous
-// avatar image).
-GURL GetDefaultImageUrl(int index);
+// avatar image). The resource URL will take into account the `scale_factor`
+// requested and the available resolutions for the image index. The image
+// resolution default is 2x except for images without available 2x versions.
+GURL GetDefaultImageUrl(int index,
+                        ui::ResourceScaleFactor scale_factor = ui::k200Percent);
 
 // Returns bitmap of default user image with specified index.
 const gfx::ImageSkia& GetDefaultImageDeprecated(int index);
@@ -73,7 +84,12 @@
 // Returns true if `index` is a in the current set of default images.
 bool IsInCurrentImageSet(int index);
 
-DefaultUserImage GetDefaultUserImage(int index);
+// Returns the default user image at the specified `index` with the
+// specified `scale_factor` when possible (otherwise, with the max
+// available resolution).
+DefaultUserImage GetDefaultUserImage(
+    int index,
+    ui::ResourceScaleFactor scale_factor = ui::k200Percent);
 
 // Returns a vector of current |DefaultUserImage|.
 std::vector<DefaultUserImage> GetCurrentImageSet();
diff --git a/chrome/browser/ash/web_applications/projector_app/untrusted_projector_ui_config.cc b/chrome/browser/ash/web_applications/projector_app/untrusted_projector_ui_config.cc
index fb9bd22..f5d65871 100644
--- a/chrome/browser/ash/web_applications/projector_app/untrusted_projector_ui_config.cc
+++ b/chrome/browser/ash/web_applications/projector_app/untrusted_projector_ui_config.cc
@@ -50,6 +50,9 @@
   source->AddBoolean(
       "isViewerUseSecondaryAccountEnabled",
       ash::features::IsProjectorViewerUseSecondaryAccountEnabled());
+  source->AddBoolean(
+      "isInternalServerSideSpeechRecognitionEnabled",
+      ash::features::IsInternalServerSideSpeechRecognitionEnabled());
   source->AddString("appLocale", g_browser_process->GetApplicationLocale());
 }
 
diff --git a/chrome/browser/download/download_ui_model.cc b/chrome/browser/download/download_ui_model.cc
index ee27c17a..4b091e4 100644
--- a/chrome/browser/download/download_ui_model.cc
+++ b/chrome/browser/download/download_ui_model.cc
@@ -314,11 +314,11 @@
       return l10n_util::GetStringFUTF16(
           IDS_PROMPT_DOWNLOAD_BLOCKED_PASSWORD_PROTECTED, filename, offset);
     case download::DOWNLOAD_DANGER_TYPE_SENSITIVE_CONTENT_WARNING:
-      return l10n_util::GetStringFUTF16(
-          IDS_PROMPT_DOWNLOAD_SENSITIVE_CONTENT_WARNING, filename, offset);
+      return l10n_util::GetStringUTF16(
+          IDS_PROMPT_DOWNLOAD_SENSITIVE_CONTENT_WARNING);
     case download::DOWNLOAD_DANGER_TYPE_SENSITIVE_CONTENT_BLOCK:
-      return l10n_util::GetStringFUTF16(
-          IDS_PROMPT_DOWNLOAD_SENSITIVE_CONTENT_BLOCKED, filename, offset);
+      return l10n_util::GetStringUTF16(
+          IDS_PROMPT_DOWNLOAD_SENSITIVE_CONTENT_BLOCKED);
     case download::DOWNLOAD_DANGER_TYPE_PROMPT_FOR_SCANNING:
       return l10n_util::GetStringFUTF16(IDS_PROMPT_DEEP_SCANNING, filename,
                                         offset);
diff --git a/chrome/browser/download/notification/download_item_notification.cc b/chrome/browser/download/notification/download_item_notification.cc
index 443b9b6..110cad1 100644
--- a/chrome/browser/download/notification/download_item_notification.cc
+++ b/chrome/browser/download/notification/download_item_notification.cc
@@ -974,12 +974,12 @@
           IDS_PROMPT_DOWNLOAD_BLOCKED_PASSWORD_PROTECTED, elided_filename);
     }
     case download::DOWNLOAD_DANGER_TYPE_SENSITIVE_CONTENT_WARNING: {
-      return l10n_util::GetStringFUTF16(
-          IDS_PROMPT_DOWNLOAD_SENSITIVE_CONTENT_WARNING, elided_filename);
+      return l10n_util::GetStringUTF16(
+          IDS_PROMPT_DOWNLOAD_SENSITIVE_CONTENT_WARNING);
     }
     case download::DOWNLOAD_DANGER_TYPE_SENSITIVE_CONTENT_BLOCK: {
-      return l10n_util::GetStringFUTF16(
-          IDS_PROMPT_DOWNLOAD_SENSITIVE_CONTENT_BLOCKED, elided_filename);
+      return l10n_util::GetStringUTF16(
+          IDS_PROMPT_DOWNLOAD_SENSITIVE_CONTENT_BLOCKED);
     }
     case download::DOWNLOAD_DANGER_TYPE_BLOCKED_UNSUPPORTED_FILETYPE:
     case download::DOWNLOAD_DANGER_TYPE_PROMPT_FOR_SCANNING: {
diff --git a/chrome/browser/enterprise/connectors/analysis/content_analysis_dialog_browsertest.cc b/chrome/browser/enterprise/connectors/analysis/content_analysis_dialog_browsertest.cc
index 5d75797..32fb9c5 100644
--- a/chrome/browser/enterprise/connectors/analysis/content_analysis_dialog_browsertest.cc
+++ b/chrome/browser/enterprise/connectors/analysis/content_analysis_dialog_browsertest.cc
@@ -942,7 +942,9 @@
       std::make_unique<MockDelegate>(), FinalContentAnalysisResult::WARNING);
   EXPECT_EQ(nullptr, dialog->GetSideIconSpinnerForTesting());
   EXPECT_EQ(dialog->GetMessageForTesting()->GetText(),
-            u"This data has sensitive or dangerous content");
+            u"This data or your device doesn’t meet some of your organization’s"
+            u" security policies. Check with your admin on what needs to be "
+            u"fixed.");
 }
 
 IN_PROC_BROWSER_TEST_F(ContentAnalysisDialogPlainTests, TestOpenInBlockState) {
@@ -950,8 +952,9 @@
       std::make_unique<MockDelegate>(), FinalContentAnalysisResult::FAILURE);
   EXPECT_EQ(nullptr, dialog->GetSideIconSpinnerForTesting());
   EXPECT_EQ(dialog->GetMessageForTesting()->GetText(),
-            u"This data has sensitive or dangerous content. Remove this "
-            u"content and try again.");
+            u"This data or your device doesn’t meet some of your organization’s"
+            u" security policies. Check with your admin on what needs to be "
+            u"fixed.");
 }
 
 IN_PROC_BROWSER_TEST_F(ContentAnalysisDialogPlainTests,
diff --git a/chrome/browser/enterprise/connectors/file_system/box_api_call_flow.cc b/chrome/browser/enterprise/connectors/file_system/box_api_call_flow.cc
index 67fd321..58569abc 100644
--- a/chrome/browser/enterprise/connectors/file_system/box_api_call_flow.cc
+++ b/chrome/browser/enterprise/connectors/file_system/box_api_call_flow.cc
@@ -100,7 +100,7 @@
 bool VerifyChunkedUploadParts(const base::Value& parts) {
   DCHECK(parts.is_dict()) << parts;
   DCHECK(parts.FindPath("parts")->is_list()) << parts;
-  auto parts_list = parts.FindPath("parts")->GetListDeprecated();
+  const auto& parts_list = parts.FindPath("parts")->GetList();
   DCHECK(!parts_list.empty());
   for (auto p = parts_list.begin(); p != parts_list.end(); ++p) {
     DCHECK(p->is_dict()) << parts;
@@ -114,27 +114,24 @@
 
 using Box = enterprise_connectors::BoxApiCallFlow;
 
-bool ExtractEntriesList(const Box::ParseResult& result,
-                        base::Value::ConstListView* list) {
+const base::Value::List* ExtractEntriesList(const Box::ParseResult& result) {
   if (!result.has_value()) {
-    return false;
+    return nullptr;
   }
 
   const base::Value* entries = result->GetDict().Find("entries");
   if (!entries || !entries->is_list()) {
-    return false;
+    return nullptr;
   }
 
-  CHECK(list);
-  *list = entries->GetListDeprecated();
-  return true;
+  return &entries->GetList();
 }
 
 std::string ExtractUploadedFileId(const Box::ParseResult& result) {
-  base::Value::ConstListView list;
+  const base::Value::List* list = ExtractEntriesList(result);
   std::string file_id;
-  if (ExtractEntriesList(result, &list) && !list.empty()) {
-    file_id = ExtractId(list.front());
+  if (list && !list->empty()) {
+    file_id = ExtractId(list->front());
   }
   LOG_PARSE_FAIL_IF(file_id.empty(), ERROR, "ExtractUploadedFileId", result);
   return file_id;
@@ -358,13 +355,13 @@
 }
 
 void BoxFindUpstreamFolderApiCallFlow::OnSuccessJsonParsed(ParseResult result) {
-  base::Value::ConstListView list;
+  const base::Value::List* list = ExtractEntriesList(result);
   std::string folder_id;
-  bool extracted = ExtractEntriesList(result, &list);
-  LOG_PARSE_FAIL_IF(!extracted, ERROR, "FindUpstreamFolder", result);
+  LOG_PARSE_FAIL_IF(!list, ERROR, "FindUpstreamFolder", result);
 
-  if (extracted && !list.empty()) {
-    folder_id = ExtractId(list.front());
+  bool extracted = list != nullptr;
+  if (list && !list->empty()) {
+    folder_id = ExtractId(list->front());
     extracted = !folder_id.empty();
   }
   std::move(callback_).Run(Response{extracted, net::HTTP_OK}, folder_id);
@@ -436,10 +433,8 @@
     base::Value* conflict_folders_list =
         result->FindListPath("context_info.conflicts");
     if (box_error_code && *box_error_code == "item_name_in_use" &&
-        conflict_folders_list &&
-        conflict_folders_list->GetListDeprecated().size() > 0) {
-      folder_info_dict = absl::make_optional<base::Value>(
-          conflict_folders_list->GetListDeprecated()[0].Clone());
+        conflict_folders_list && conflict_folders_list->GetList().size() > 0) {
+      folder_info_dict = conflict_folders_list->GetList()[0].Clone();
     }
   }
 
diff --git a/chrome/browser/enterprise/connectors/file_system/box_uploader.cc b/chrome/browser/enterprise/connectors/file_system/box_uploader.cc
index c3bc55f1..e1089d7b 100644
--- a/chrome/browser/enterprise/connectors/file_system/box_uploader.cc
+++ b/chrome/browser/enterprise/connectors/file_system/box_uploader.cc
@@ -648,8 +648,7 @@
     return;
   }
   uploaded_parts_.Append(std::move(part_info));
-  chunks_handler_->ContinueToReadChunk(
-      uploaded_parts_.GetListDeprecated().size() + 1);
+  chunks_handler_->ContinueToReadChunk(uploaded_parts_.GetList().size() + 1);
 }
 
 void BoxChunkedUploader::OnFileCompletelyUploaded(
diff --git a/chrome/browser/enterprise/connectors/file_system/service_settings.cc b/chrome/browser/enterprise/connectors/file_system/service_settings.cc
index 7e049bd..7f258c7 100644
--- a/chrome/browser/enterprise/connectors/file_system/service_settings.cc
+++ b/chrome/browser/enterprise/connectors/file_system/service_settings.cc
@@ -51,9 +51,9 @@
   url_matcher_ = std::make_unique<url_matcher::URLMatcher>();
   URLMatchingID id(0);
   const base::Value* enable = settings_value.FindListKey(kKeyEnable);
-  if (enable && enable->is_list() && !enable->GetListDeprecated().empty()) {
+  if (enable && enable->is_list() && !enable->GetList().empty()) {
     filters_validated_ = true;
-    for (const base::Value& value : enable->GetListDeprecated()) {
+    for (const base::Value& value : enable->GetList()) {
       filters_validated_ &=
           AddUrlPatternSettings(value, /* enabled = */ true, &id);
     }
@@ -65,8 +65,8 @@
   }
 
   const base::Value* disable = settings_value.FindListKey(kKeyDisable);
-  if (disable && disable->is_list() && !disable->GetListDeprecated().empty()) {
-    for (const base::Value& value : disable->GetListDeprecated()) {
+  if (disable && disable->is_list() && !disable->GetList().empty()) {
+    for (const base::Value& value : disable->GetList()) {
       filters_validated_ &=
           AddUrlPatternSettings(value, /* enabled = */ false, &id);
     }
@@ -224,7 +224,7 @@
 
   URLPatternSettings setting;
   bool has_wildcard = false;
-  for (const base::Value& mime_type : mime_types->GetListDeprecated()) {
+  for (const base::Value& mime_type : mime_types->GetList()) {
     if (mime_type.is_string()) {
       const std::string& m = mime_type.GetString();
       setting.mime_types.insert(m);
diff --git a/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_unittest.cc b/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_unittest.cc
index 1b9ea98..6a4fd42 100644
--- a/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_unittest.cc
+++ b/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_unittest.cc
@@ -373,7 +373,7 @@
     function->set_extension(&extension);
     function->set_has_callback(true);
 
-    std::unique_ptr<base::Value> result =
+    absl::optional<base::Value> result =
         api_test_utils::RunFunctionAndReturnSingleResult(
             function.get(), "[]" /* args */, browser_context());
     ASSERT_TRUE(result);
@@ -429,7 +429,7 @@
     function->set_extension(&extension);
     function->set_has_callback(true);
 
-    std::unique_ptr<base::Value> result =
+    absl::optional<base::Value> result =
         api_test_utils::RunFunctionAndReturnSingleResult(
             function.get(), "[]" /* args */, browser_context());
     ASSERT_TRUE(result);
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc b/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc
index f37e6e9c..d66be2d 100644
--- a/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc
+++ b/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc
@@ -703,7 +703,7 @@
     scoped_refptr<ExtensionFunction> function(
         new api::DeveloperPrivateLoadUnpackedFunction());
     function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
-    std::unique_ptr<base::Value> result =
+    absl::optional<base::Value> result =
         api_test_utils::RunFunctionAndReturnSingleResult(
             function.get(),
             "[{\"failQuietly\": true, \"populateError\": true}]", profile());
@@ -730,7 +730,7 @@
     scoped_refptr<ExtensionFunction> function(
         new api::DeveloperPrivateLoadUnpackedFunction());
     function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
-    std::unique_ptr<base::Value> result =
+    absl::optional<base::Value> result =
         api_test_utils::RunFunctionAndReturnSingleResult(
             function.get(),
             "[{\"failQuietly\": true, \"populateError\": true}]", profile());
@@ -762,7 +762,7 @@
     scoped_refptr<ExtensionFunction> function(
         new api::DeveloperPrivateLoadUnpackedFunction());
     function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
-    std::unique_ptr<base::Value> result =
+    absl::optional<base::Value> result =
         api_test_utils::RunFunctionAndReturnSingleResult(
             function.get(),
             "[{\"failQuietly\": true, \"populateError\": true}]", profile());
@@ -795,7 +795,7 @@
     scoped_refptr<ExtensionFunction> function(
         new api::DeveloperPrivateLoadUnpackedFunction());
     function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
-    std::unique_ptr<base::Value> result =
+    absl::optional<base::Value> result =
         api_test_utils::RunFunctionAndReturnSingleResult(
             function.get(),
             "[{\"failQuietly\": true, \"populateError\": true}]", profile());
@@ -815,7 +815,7 @@
     scoped_refptr<ExtensionFunction> function(
         new api::DeveloperPrivateLoadUnpackedFunction());
     function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
-    std::unique_ptr<base::Value> result =
+    absl::optional<base::Value> result =
         api_test_utils::RunFunctionAndReturnSingleResult(
             function.get(),
             "[{\"failQuietly\": true, \"populateError\": true}]", profile());
@@ -844,7 +844,7 @@
     scoped_refptr<ExtensionFunction> function(
         new api::DeveloperPrivateLoadUnpackedFunction());
     function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
-    std::unique_ptr<base::Value> result =
+    absl::optional<base::Value> result =
         api_test_utils::RunFunctionAndReturnSingleResult(
             function.get(),
             "[{\"failQuietly\": true, \"populateError\": true}]", profile());
@@ -996,7 +996,7 @@
     // retry GUID populated.
     auto function = base::MakeRefCounted<api::DeveloperPrivateReloadFunction>();
     function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
-    std::unique_ptr<base::Value> result =
+    absl::optional<base::Value> result =
         api_test_utils::RunFunctionAndReturnSingleResult(
             function.get(), reload_args, profile());
     ASSERT_TRUE(result);
@@ -1086,7 +1086,7 @@
     auto function = base::MakeRefCounted<
         api::DeveloperPrivateNotifyDragInstallInProgressFunction>();
     function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
-    std::unique_ptr<base::Value> result =
+    absl::optional<base::Value> result =
         api_test_utils::RunFunctionAndReturnSingleResult(function.get(), "[]",
                                                          profile());
   }
@@ -1098,7 +1098,7 @@
         base::MakeRefCounted<api::DeveloperPrivateLoadUnpackedFunction>();
     function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
     TestExtensionRegistryObserver observer(registry());
-    std::unique_ptr<base::Value> result =
+    absl::optional<base::Value> result =
         api_test_utils::RunFunctionAndReturnSingleResult(
             function.get(), kLoadUnpackedArgs, profile());
     ASSERT_TRUE(result);
diff --git a/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_api_ash_unittest.cc b/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_api_ash_unittest.cc
index c1b77b0..1fd4db75 100644
--- a/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_api_ash_unittest.cc
+++ b/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_api_ash_unittest.cc
@@ -140,7 +140,7 @@
   auto function = base::MakeRefCounted<
       EnterpriseDeviceAttributesGetDirectoryDeviceIdFunction>();
 
-  std::unique_ptr<base::Value> result =
+  absl::optional<base::Value> result =
       api_test_utils::RunFunctionAndReturnSingleResult(
           function.get(), /*args=*/"[]", profile_.get());
   ASSERT_TRUE(result->is_string());
@@ -153,7 +153,7 @@
   auto function = base::MakeRefCounted<
       EnterpriseDeviceAttributesGetDeviceSerialNumberFunction>();
 
-  std::unique_ptr<base::Value> result =
+  absl::optional<base::Value> result =
       api_test_utils::RunFunctionAndReturnSingleResult(
           function.get(), /*args=*/"[]", profile_.get());
   ASSERT_TRUE(result->is_string());
@@ -165,7 +165,7 @@
   auto function = base::MakeRefCounted<
       EnterpriseDeviceAttributesGetDeviceAssetIdFunction>();
 
-  std::unique_ptr<base::Value> result =
+  absl::optional<base::Value> result =
       api_test_utils::RunFunctionAndReturnSingleResult(
           function.get(), /*args=*/"[]", profile_.get());
   ASSERT_TRUE(result->is_string());
@@ -178,7 +178,7 @@
   auto function = base::MakeRefCounted<
       EnterpriseDeviceAttributesGetDeviceAnnotatedLocationFunction>();
 
-  std::unique_ptr<base::Value> result =
+  absl::optional<base::Value> result =
       api_test_utils::RunFunctionAndReturnSingleResult(
           function.get(), /*args=*/"[]", profile_.get());
   ASSERT_TRUE(result->is_string());
@@ -191,7 +191,7 @@
   auto function = base::MakeRefCounted<
       EnterpriseDeviceAttributesGetDeviceHostnameFunction>();
 
-  std::unique_ptr<base::Value> result =
+  absl::optional<base::Value> result =
       api_test_utils::RunFunctionAndReturnSingleResult(
           function.get(), /*args=*/"[]", profile_.get());
   ASSERT_TRUE(result->is_string());
diff --git a/chrome/browser/extensions/api/enterprise_hardware_platform/enterprise_hardware_platform_api_unittest.cc b/chrome/browser/extensions/api/enterprise_hardware_platform/enterprise_hardware_platform_api_unittest.cc
index a446e55..c931e2b 100644
--- a/chrome/browser/extensions/api/enterprise_hardware_platform/enterprise_hardware_platform_api_unittest.cc
+++ b/chrome/browser/extensions/api/enterprise_hardware_platform/enterprise_hardware_platform_api_unittest.cc
@@ -61,7 +61,7 @@
       prefs::kEnterpriseHardwarePlatformAPIEnabled,
       std::make_unique<base::Value>(true));
 
-  std::unique_ptr<base::Value> result =
+  absl::optional<base::Value> result =
       api_test_utils::RunFunctionAndReturnSingleResult(function(), "[]",
                                                        browser_context());
   ASSERT_TRUE(result);
diff --git a/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_browsertest.cc b/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_browsertest.cc
index d8134ff..10c56d4 100644
--- a/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_browsertest.cc
+++ b/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_browsertest.cc
@@ -283,7 +283,8 @@
   }
 
   bool BuiltInDnsClientPlatformDefault() {
-#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_ANDROID)
+#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_ANDROID) || \
+    BUILDFLAG(IS_WIN)
     return true;
 #else
     return false;
diff --git a/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_unittest.cc b/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_unittest.cc
index 731f065..054983c 100644
--- a/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_unittest.cc
+++ b/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_unittest.cc
@@ -441,7 +441,8 @@
   }
 
   bool BuiltInDnsClientPlatformDefault() {
-#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_ANDROID)
+#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_ANDROID) || \
+    BUILDFLAG(IS_WIN)
     return true;
 #else
     return false;
@@ -912,7 +913,7 @@
 
  protected:
   void SetUp() override {
-    ExtensionApiUnittest::SetUp();
+    EnterpriseReportingPrivateGetContextInfoTest::SetUp();
     HRESULT hr = CoCreateInstance(CLSID_NetFwPolicy2, nullptr, CLSCTX_ALL,
                                   IID_PPV_ARGS(&firewall_policy_));
     EXPECT_FALSE(FAILED(hr));
diff --git a/chrome/browser/extensions/api/language_settings_private/language_settings_private_api_unittest.cc b/chrome/browser/extensions/api/language_settings_private/language_settings_private_api_unittest.cc
index c8eccc8..29d2c92f 100644
--- a/chrome/browser/extensions/api/language_settings_private/language_settings_private_api_unittest.cc
+++ b/chrome/browser/extensions/api/language_settings_private/language_settings_private_api_unittest.cc
@@ -175,10 +175,10 @@
   auto function = base::MakeRefCounted<
       LanguageSettingsPrivateGetSpellcheckDictionaryStatusesFunction>();
 
-  std::unique_ptr<base::Value> actual =
+  absl::optional<base::Value> actual =
       api_test_utils::RunFunctionAndReturnSingleResult(function.get(), "[]",
                                                        profile());
-  EXPECT_TRUE(actual) << function->GetError();
+  ASSERT_TRUE(actual) << function->GetError();
 
   base::Value::List expected;
   base::Value::Dict expected_status;
@@ -226,12 +226,12 @@
   auto function = base::MakeRefCounted<
       LanguageSettingsPrivateGetAlwaysTranslateLanguagesFunction>();
 
-  std::unique_ptr<base::Value> result =
+  absl::optional<base::Value> result =
       api_test_utils::RunFunctionAndReturnSingleResult(function.get(), "[]",
                                                        profile());
 
-  ASSERT_NE(nullptr, result) << function->GetError();
-  EXPECT_TRUE(result->is_list());
+  ASSERT_TRUE(result) << function->GetError();
+  ASSERT_TRUE(result->is_list());
 
   ASSERT_EQ(result->GetList().size(), always_translate_languages.size());
   for (size_t i = 0; i < result->GetList().size(); i++) {
@@ -258,7 +258,7 @@
   auto function = base::MakeRefCounted<
       LanguageSettingsPrivateSetTranslateTargetLanguageFunction>();
 
-  std::unique_ptr<base::Value> result =
+  absl::optional<base::Value> result =
       api_test_utils::RunFunctionAndReturnSingleResult(function.get(),
                                                        "[\"af\"]", profile());
   ASSERT_EQ(translate_prefs_->GetRecentTargetLanguage(), "af");
@@ -280,12 +280,12 @@
   auto function = base::MakeRefCounted<
       LanguageSettingsPrivateGetNeverTranslateLanguagesFunction>();
 
-  std::unique_ptr<base::Value> result =
+  absl::optional<base::Value> result =
       api_test_utils::RunFunctionAndReturnSingleResult(function.get(), "[]",
                                                        profile());
 
-  ASSERT_NE(nullptr, result) << function->GetError();
-  EXPECT_TRUE(result->is_list());
+  ASSERT_TRUE(result) << function->GetError();
+  ASSERT_TRUE(result->is_list());
 
   ASSERT_EQ(result->GetList().size(), never_translate_languages.size());
   for (size_t i = 0; i < result->GetList().size(); i++) {
@@ -392,12 +392,12 @@
   auto function =
       base::MakeRefCounted<LanguageSettingsPrivateGetLanguageListFunction>();
 
-  std::unique_ptr<base::Value> result =
+  absl::optional<base::Value> result =
       api_test_utils::RunFunctionAndReturnSingleResult(function.get(), "[]",
                                                        profile());
 
-  ASSERT_NE(nullptr, result) << function->GetError();
-  EXPECT_TRUE(result->is_list());
+  ASSERT_TRUE(result) << function->GetError();
+  ASSERT_TRUE(result->is_list());
 
   size_t languages_to_test_found_count = 0;
   for (auto& language_val : result->GetList()) {
@@ -546,12 +546,12 @@
 
   auto function = base::MakeRefCounted<
       LanguageSettingsPrivateGetInputMethodListsFunction>();
-  std::unique_ptr<base::Value> result =
+  absl::optional<base::Value> result =
       api_test_utils::RunFunctionAndReturnSingleResult(function.get(), "[]",
                                                        profile());
 
-  ASSERT_NE(nullptr, result) << function->GetError();
-  EXPECT_TRUE(result->is_dict());
+  ASSERT_TRUE(result) << function->GetError();
+  ASSERT_TRUE(result->is_dict());
 
   base::Value* input_methods = result->FindListKey("thirdPartyExtensionImes");
   ASSERT_NE(input_methods, nullptr);
diff --git a/chrome/browser/extensions/api/storage/storage_session_unittest.cc b/chrome/browser/extensions/api/storage/storage_session_unittest.cc
index f206ee8..333274d8 100644
--- a/chrome/browser/extensions/api/storage/storage_session_unittest.cc
+++ b/chrome/browser/extensions/api/storage/storage_session_unittest.cc
@@ -49,7 +49,7 @@
 
   // Returns the session storage of the given extension with the associated
   // profile.
-  std::unique_ptr<base::Value> GetStorage(
+  absl::optional<base::Value> GetStorage(
       scoped_refptr<const Extension> extension);
 
   // ExtensionServiceTestBase:
@@ -71,7 +71,7 @@
       profile()));
 }
 
-std::unique_ptr<base::Value> SessionStorageApiUnittest::GetStorage(
+absl::optional<base::Value> SessionStorageApiUnittest::GetStorage(
     scoped_refptr<const Extension> extension) {
   scoped_refptr<ExtensionFunction> function =
       base::MakeRefCounted<StorageStorageAreaGetFunction>();
diff --git a/chrome/browser/favicon/favicon_utils.cc b/chrome/browser/favicon/favicon_utils.cc
index 1d6b311..b3efd15 100644
--- a/chrome/browser/favicon/favicon_utils.cc
+++ b/chrome/browser/favicon/favicon_utils.cc
@@ -186,15 +186,6 @@
            actual_url.host_piece() == chrome::kChromeUINewTabHost;
   }
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-  // Themify menu favicon for CrOS Terminal home page.
-  if (!base::FeatureList::IsEnabled(
-          chromeos::features::kTerminalMultiProfile) &&
-      actual_url.SchemeIs(content::kChromeUIUntrustedScheme)) {
-    return actual_url.host_piece() == chrome::kChromeUIUntrustedTerminalHost;
-  }
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
-
   return false;
 }
 
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index d0b95a4..ed191361 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -1745,6 +1745,11 @@
     "expiry_milestone": 110
   },
   {
+    "name": "enable-auto-disable-accessibility-v2",
+    "owners": [ "jacklynch@google.com", "//ui/accessibility/OWNERS" ],
+    "expiry_milestone": 120
+  },
+  {
     "name": "enable-autofill-credit-card-authentication",
     "owners": [ "jsaul@google.com", "siyua" ],
     "expiry_milestone": 112
@@ -4264,7 +4269,7 @@
   {
     "name": "ios-new-post-restore-experience",
     "owners": [ "scottyoder@google.com", "bling-flags@google.com" ],
-    "expiry_milestone": 109
+    "expiry_milestone": 110
   },
   {
     "name": "ios-password-manager-cross-origin-iframe-support",
@@ -4307,7 +4312,7 @@
   {
     "name": "isolated-app-origins",
     "owners": [ "peletskyi@google.com", "desktop-pwas-team@google.com" ],
-    "expiry_milestone": 109
+    "expiry_milestone": 115
   },
   {
     "name": "isolation-by-default",
@@ -4429,6 +4434,14 @@
     "expiry_milestone": 130
   },
   {
+    "name": "lacros-wayland-logging",
+    "owners": [ "erikchen", "lacros-team@google.com" ],
+    // Once Lacros is launched, this flag can be removed. Until then, this
+    // absolutely must not expire. We do not yet have a launch milestone.
+    // TODO(https://crbug.com/1148474).
+    "expiry_milestone": 130
+  },
+  {
     "name": "large-favicon-from-google",
     "owners": [
       "bttk"
@@ -4780,7 +4793,7 @@
   {
     "name": "new-overflow-menu-share-chrome-action",
     "owners": [ "scottyoder@google.com", "bling-flags@google.com" ],
-    "expiry_milestone": 108
+    "expiry_milestone": 110
   },
   {
     "name": "new-overflow-menu-simple-destination-icons",
@@ -6139,22 +6152,22 @@
   {
     "name": "shared-highlighting-manager",
     "owners": ["jeffreycohen", "kristipark", "cheickcisse@google.com"],
-    "expiry_milestone": 108
+    "expiry_milestone": 111
   },
   {
     "name": "shared-highlighting-refined-blocklist",
     "owners": ["jeffreycohen", "chrome-with-friends-robots@google.com" ],
-    "expiry_milestone": 108
+    "expiry_milestone": 111
   },
   {
     "name": "shared-highlighting-refined-maxcontextwords",
     "owners": ["wissemgamra", "jeffreycohen", "chrome-with-friends-robots@google.com" ],
-    "expiry_milestone": 108
+    "expiry_milestone": 111
   },
   {
     "name": "shared-highlighting-v2",
     "owners": ["jeffreycohen", "kristipark", "cheickcisse@google.com", "chrome-with-friends-robots@google.com"],
-    "expiry_milestone": 108
+    "expiry_milestone": 111
   },
   {
     "name": "sharing-desktop-screenshots",
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 100b7e4..31124b2 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -834,6 +834,13 @@
     "turned off or if an extension which uses accessibility APIs no longer "
     "needs them.";
 
+const char kEnableAutoDisableAccessibilityV2Name[] =
+    "Auto-disable Accessibility V2";
+const char kEnableAutoDisableAccessibilityV2Description[] =
+    "Automatically disable accessibility when Android reports no assistive "
+    "technologies are running. Might break accessibility for assistive "
+    "technologies without isAccessibilityTool set.";
+
 const char kEnableAutofillAddressSavePromptName[] =
     "Autofill Address Save Prompts";
 const char kEnableAutofillAddressSavePromptDescription[] =
@@ -3918,12 +3925,6 @@
     "Enables showing related searches suggestions in a carousel in the "
     "peeking bar of the bottom sheet on Android.";
 
-const char kRelatedSearchesSimplifiedUxName[] =
-    "Enables showing Related Searches in a simplified user experience.";
-const char kRelatedSearchesSimplifiedUxDescription[] =
-    "Enables showing related searches with a simplified form of the normal "
-    "user experience treatment.";
-
 const char kRelatedSearchesUiName[] =
     "Forces showing of the Related Searches UI on Android";
 const char kRelatedSearchesUiDescription[] =
@@ -5631,6 +5632,11 @@
     "first restart can take some time to setup lacros-chrome. Please DO NOT "
     "attempt to turn off the device during the restart.";
 
+const char kLacrosWaylandLoggingName[] = "Lacros wayland logging";
+const char kLacrosWaylandLoggingDescription[] =
+    "Enables wayland logging for Lacros. This generates a significant amount "
+    "of logs on disk. Logs are cleared after two restarts.";
+
 const char kLacrosProfileMigrationForAnyUserName[] =
     "Lacros profile migration for any user";
 const char kLacrosProfileMigrationForAnyUserDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 8fa909ec..5b6b680 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -177,6 +177,9 @@
 extern const char kEnableAutoDisableAccessibilityName[];
 extern const char kEnableAutoDisableAccessibilityDescription[];
 
+extern const char kEnableAutoDisableAccessibilityV2Name[];
+extern const char kEnableAutoDisableAccessibilityV2Description[];
+
 extern const char kAutofillAlwaysReturnCloudTokenizedCardName[];
 extern const char kAutofillAlwaysReturnCloudTokenizedCardDescription[];
 
@@ -2249,9 +2252,6 @@
 extern const char kRelatedSearchesInBarName[];
 extern const char kRelatedSearchesInBarDescription[];
 
-extern const char kRelatedSearchesSimplifiedUxName[];
-extern const char kRelatedSearchesSimplifiedUxDescription[];
-
 extern const char kRelatedSearchesUiName[];
 extern const char kRelatedSearchesUiDescription[];
 
@@ -3247,6 +3247,9 @@
 extern const char kLacrosSupportName[];
 extern const char kLacrosSupportDescription[];
 
+extern const char kLacrosWaylandLoggingName[];
+extern const char kLacrosWaylandLoggingDescription[];
+
 extern const char kLauncherItemSuggestName[];
 extern const char kLauncherItemSuggestDescription[];
 
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc
index f9b4cf4..a99258c 100644
--- a/chrome/browser/flags/android/chrome_feature_list.cc
+++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -278,7 +278,6 @@
     &kRelatedSearches,
     &kRelatedSearchesAlternateUx,
     &kRelatedSearchesInBar,
-    &kRelatedSearchesSimplifiedUx,
     &kRelatedSearchesUi,
     &kRequestDesktopSiteDefaults,
     &kRequestDesktopSiteDefaultsControl,
@@ -907,10 +906,6 @@
              "RelatedSearchesInBar",
              base::FEATURE_ENABLED_BY_DEFAULT);
 
-BASE_FEATURE(kRelatedSearchesSimplifiedUx,
-             "RelatedSearchesSimplifiedUx",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
 BASE_FEATURE(kRelatedSearchesUi,
              "RelatedSearchesUi",
              base::FEATURE_ENABLED_BY_DEFAULT);
diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser/flags/android/chrome_feature_list.h
index 472e4a7..f8e40032 100644
--- a/chrome/browser/flags/android/chrome_feature_list.h
+++ b/chrome/browser/flags/android/chrome_feature_list.h
@@ -128,7 +128,6 @@
 BASE_DECLARE_FEATURE(kRelatedSearches);
 BASE_DECLARE_FEATURE(kRelatedSearchesAlternateUx);
 BASE_DECLARE_FEATURE(kRelatedSearchesInBar);
-BASE_DECLARE_FEATURE(kRelatedSearchesSimplifiedUx);
 BASE_DECLARE_FEATURE(kRelatedSearchesUi);
 BASE_DECLARE_FEATURE(kRequestDesktopSiteDefaults);
 BASE_DECLARE_FEATURE(kRequestDesktopSiteDefaultsControl);
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
index 5c40ba8d..f49b52b2 100644
--- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
+++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -510,7 +510,6 @@
     public static final String RELATED_SEARCHES = "RelatedSearches";
     public static final String RELATED_SEARCHES_ALTERNATE_UX = "RelatedSearchesAlternateUx";
     public static final String RELATED_SEARCHES_IN_BAR = "RelatedSearchesInBar";
-    public static final String RELATED_SEARCHES_SIMPLIFIED_UX = "RelatedSearchesSimplifiedUx";
     public static final String RELATED_SEARCHES_UI = "RelatedSearchesUi";
     public static final String REQUEST_DESKTOP_SITE_DEFAULTS = "RequestDesktopSiteDefaults";
     public static final String REQUEST_DESKTOP_SITE_DEFAULTS_CONTROL =
diff --git a/chrome/browser/history_clusters/history_clusters_image_fetcher.cc b/chrome/browser/history_clusters/history_clusters_image_fetcher.cc
new file mode 100644
index 0000000..8d5cf19
--- /dev/null
+++ b/chrome/browser/history_clusters/history_clusters_image_fetcher.cc
@@ -0,0 +1,121 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/history_clusters/history_clusters_image_fetcher.h"
+#include <string>
+
+#include "base/i18n/case_conversion.h"
+#include "base/memory/ref_counted.h"
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/profiles/profile.h"
+#include "components/omnibox/browser/autocomplete_input.h"
+#include "components/omnibox/browser/autocomplete_match.h"
+#include "components/omnibox/browser/autocomplete_provider_listener.h"
+#include "components/omnibox/browser/search_provider.h"
+
+namespace history_clusters {
+
+// A one-time use object that uses Suggest to get an image URL corresponding
+// to `search_query` and `entity_id`. This is a hacky temporary implementation,
+// ideally this should be replaced by persisted Suggest-provided entities.
+class HistoryClustersImageFetcher::SuggestEntityImageURLFetcher
+    : public AutocompleteProviderListener {
+ public:
+  SuggestEntityImageURLFetcher(
+      Profile* profile,
+      ChromeAutocompleteProviderClient* autocomplete_provider_client,
+      const std::u16string& search_query,
+      const std::string& entity_id)
+      : profile_(profile),
+        search_query_(base::i18n::ToLower(search_query)),
+        entity_id_(entity_id),
+        // TODO(tommycli): Replace the `SearchProvider` usage with
+        // `RemoteSuggestionsService`.
+        search_provider_(
+            base::MakeRefCounted<SearchProvider>(autocomplete_provider_client,
+                                                 this)) {}
+  SuggestEntityImageURLFetcher(const SuggestEntityImageURLFetcher&) = delete;
+
+  // `callback` is called with the result.
+  void Start(base::OnceCallback<void(const GURL&)> callback) {
+    DCHECK(!callback_);
+    callback_ = std::move(callback);
+
+    AutocompleteInput autocomplete_input(
+        search_query_, metrics::OmniboxEventProto::OTHER,
+        ChromeAutocompleteSchemeClassifier(profile_));
+    search_provider_->Start(autocomplete_input, /*minimal_changes=*/false);
+
+    if (search_provider_->done())
+      ProcessMatches();
+  }
+
+  void OnProviderUpdate(bool updated_matches,
+                        const AutocompleteProvider* provider) override {
+    if (search_provider_->done())
+      ProcessMatches();
+  }
+
+ private:
+  void ProcessMatches() {
+    DCHECK(search_provider_->done());
+    DCHECK(callback_);
+    for (const auto& match : search_provider_->matches()) {
+      // TODO(tommycli): `entity_id_` is not used yet, because it's always
+      // empty right now.
+      if (match.image_url.is_valid() &&
+          base::i18n::ToLower(match.contents) == search_query_) {
+        std::move(callback_).Run(match.image_url);
+        break;
+      }
+    }
+
+    // If we didn't find any matching images, still notify the caller.
+    if (!callback_.is_null())
+      std::move(callback_).Run(GURL());
+  }
+
+  const raw_ptr<Profile> profile_;
+
+  // The search query and entity ID we are searching for.
+  const std::u16string search_query_;
+  const std::string entity_id_;
+
+  // The result callback to be called once we get the answer.
+  base::OnceCallback<void(const GURL&)> callback_;
+
+  // Our internally owned one-time-use search provider.
+  scoped_refptr<AutocompleteProvider> search_provider_;
+};
+
+HistoryClustersImageFetcher::HistoryClustersImageFetcher(Profile* profile)
+    : profile_(profile), autocomplete_provider_client_(profile) {}
+
+HistoryClustersImageFetcher::~HistoryClustersImageFetcher() = default;
+
+void HistoryClustersImageFetcher::FetchImageFor(
+    const std::u16string& search_query,
+    const std::string& entity_id,
+    ResultCallback callback) {
+  auto fetcher = std::make_unique<SuggestEntityImageURLFetcher>(
+      profile_, &autocomplete_provider_client_, search_query, entity_id);
+
+  // Use a raw pointer temporary so we can give ownership of the unique_ptr to
+  // the callback and have a well defined SuggestEntityImageURLFetcher lifetime.
+  auto* fetcher_raw_ptr = fetcher.get();
+  fetcher_raw_ptr->Start(base::BindOnce(
+      &HistoryClustersImageFetcher::OnImageFetched, weak_factory_.GetWeakPtr(),
+      std::move(fetcher), std::move(callback)));
+}
+
+void HistoryClustersImageFetcher::OnImageFetched(
+    std::unique_ptr<SuggestEntityImageURLFetcher> fetcher,
+    ResultCallback callback,
+    const GURL& image_url) {
+  std::move(callback).Run(image_url);
+
+  // `fetcher` is owned by this method and will be deleted now.
+}
+
+}  // namespace history_clusters
diff --git a/chrome/browser/history_clusters/history_clusters_image_fetcher.h b/chrome/browser/history_clusters/history_clusters_image_fetcher.h
new file mode 100644
index 0000000..84cd2cd
--- /dev/null
+++ b/chrome/browser/history_clusters/history_clusters_image_fetcher.h
@@ -0,0 +1,51 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_HISTORY_CLUSTERS_HISTORY_CLUSTERS_IMAGE_FETCHER_H_
+#define CHROME_BROWSER_HISTORY_CLUSTERS_HISTORY_CLUSTERS_IMAGE_FETCHER_H_
+
+#include <string>
+
+#include "base/memory/weak_ptr.h"
+#include "chrome/browser/autocomplete/chrome_autocomplete_provider_client.h"
+#include "chrome/browser/profiles/profile.h"
+
+namespace history_clusters {
+
+// Used to get the image URL associated with a cluster. It doesn't actually
+// fetch the image, that's up to the UI to do.
+class HistoryClustersImageFetcher {
+ public:
+  using ResultCallback = base::OnceCallback<void(const GURL& image_url)>;
+
+  explicit HistoryClustersImageFetcher(Profile* profile);
+  HistoryClustersImageFetcher(const HistoryClustersImageFetcher&) = delete;
+  HistoryClustersImageFetcher& operator=(const HistoryClustersImageFetcher&) =
+      delete;
+
+  ~HistoryClustersImageFetcher();
+
+  // Fetches an image appropriate for `search_query` and `entity_id`, returning
+  // the result asynchronously to `callback`.
+  void FetchImageFor(const std::u16string& search_query,
+                     const std::string& entity_id,
+                     ResultCallback callback);
+
+ private:
+  class SuggestEntityImageURLFetcher;
+
+  // Callback for `FetchImageFor`.
+  void OnImageFetched(std::unique_ptr<SuggestEntityImageURLFetcher> fetcher,
+                      ResultCallback callback,
+                      const GURL& image_url);
+
+  Profile* const profile_;
+  ChromeAutocompleteProviderClient autocomplete_provider_client_;
+
+  base::WeakPtrFactory<HistoryClustersImageFetcher> weak_factory_{this};
+};
+
+}  // namespace history_clusters
+
+#endif  // CHROME_BROWSER_HISTORY_CLUSTERS_HISTORY_CLUSTERS_IMAGE_FETCHER_H_
diff --git a/chrome/browser/local_discovery/service_discovery_client_impl.cc b/chrome/browser/local_discovery/service_discovery_client_impl.cc
index 94650b7..653d460 100644
--- a/chrome/browser/local_discovery/service_discovery_client_impl.cc
+++ b/chrome/browser/local_discovery/service_discovery_client_impl.cc
@@ -7,6 +7,7 @@
 
 #include "base/bind.h"
 #include "base/check_op.h"
+#include "base/containers/contains.h"
 #include "base/location.h"
 #include "base/notreached.h"
 #include "base/task/single_thread_task_runner.h"
@@ -148,10 +149,11 @@
     return;
   }
 
+  if (!base::Contains(services_, record->name()))
+    return;
+
   DCHECK(record->type() == net::dns_protocol::kTypeSRV ||
          record->type() == net::dns_protocol::kTypeTXT);
-  DCHECK(services_.find(record->name()) != services_.end());
-
   if (record->type() == net::dns_protocol::kTypeSRV) {
     if (update == net::MDnsListener::RECORD_REMOVED)
       RemoveSRV(record->name());
diff --git a/chrome/browser/lookalikes/lookalike_url_navigation_throttle_browsertest.cc b/chrome/browser/lookalikes/lookalike_url_navigation_throttle_browsertest.cc
index 51e9f15f..02fc86c 100644
--- a/chrome/browser/lookalikes/lookalike_url_navigation_throttle_browsertest.cc
+++ b/chrome/browser/lookalikes/lookalike_url_navigation_throttle_browsertest.cc
@@ -150,7 +150,7 @@
             GetInterstitialType(web_contents));
   EXPECT_FALSE(IsUrlShowing(browser));
 
-  console_observer.Wait();
+  ASSERT_TRUE(console_observer.Wait());
   EXPECT_TRUE(
       base::MatchPattern(console_observer.GetMessageAt(0u), kConsoleMessage));
 }
diff --git a/chrome/browser/media/android/cdm/media_drm_origin_id_manager.cc b/chrome/browser/media/android/cdm/media_drm_origin_id_manager.cc
index 5bca6de..8a76524 100644
--- a/chrome/browser/media/android/cdm/media_drm_origin_id_manager.cc
+++ b/chrome/browser/media/android/cdm/media_drm_origin_id_manager.cc
@@ -12,7 +12,11 @@
 #include "base/json/values_util.h"
 #include "base/logging.h"
 #include "base/memory/raw_ptr.h"
+#include "base/memory/scoped_refptr.h"
 #include "base/metrics/histogram_macros.h"
+#include "base/task/single_thread_task_runner.h"
+#include "base/task/task_traits.h"
+#include "base/task/thread_pool.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
 #include "base/values.h"
@@ -24,6 +28,7 @@
 #include "content/public/browser/network_service_instance.h"
 #include "content/public/browser/provision_fetcher_factory.h"
 #include "media/base/android/media_drm_bridge.h"
+#include "media/base/bind_to_current_loop.h"
 #include "media/base/media_switches.h"
 #include "media/base/provision_fetcher.h"
 #include "services/network/public/cpp/network_connection_tracker.h"
@@ -171,32 +176,25 @@
 class MediaDrmProvisionHelper {
  public:
   using ProvisionedOriginIdCB = base::OnceCallback<void(
-      bool success,
       const MediaDrmOriginIdManager::MediaDrmOriginId& origin_id)>;
 
-  MediaDrmProvisionHelper() {
+  explicit MediaDrmProvisionHelper(
+      std::unique_ptr<network::PendingSharedURLLoaderFactory>
+          pending_shared_url_loader_factory) {
     DVLOG(1) << __func__;
     DCHECK(media::MediaDrmBridge::IsPerOriginProvisioningSupported());
+    DCHECK(pending_shared_url_loader_factory);
+    create_fetcher_cb_ =
+        base::BindRepeating(&content::CreateProvisionFetcher,
+                            network::SharedURLLoaderFactory::Create(
+                                std::move(pending_shared_url_loader_factory)));
   }
 
   void Provision(ProvisionedOriginIdCB callback) {
     DVLOG(1) << __func__;
 
-    auto* network_context_manager =
-        g_browser_process->system_network_context_manager();
-    if (!network_context_manager) {
-      // system_network_context_manager() returns nullptr in unit tests.
-      DLOG(WARNING) << "Failed to provision origin ID as no "
-                       "system_network_context_manager";
-      std::move(callback).Run(false, absl::nullopt);
-      return;
-    }
-
     complete_callback_ = std::move(callback);
     origin_id_ = base::UnguessableToken::Create();
-    create_fetcher_cb_ = base::BindRepeating(
-        &content::CreateProvisionFetcher,
-        network_context_manager->GetSharedURLLoaderFactory());
 
     // Try provisioning for L3 first.
     media_drm_bridge_ = media::MediaDrmBridge::CreateWithoutSessionSupport(
@@ -251,8 +249,7 @@
     const bool success = L1_success || L3_success;
     LOG_IF(WARNING, !success) << "Failed to provision origin ID";
     std::move(complete_callback_)
-        .Run(success,
-             success ? absl::make_optional(origin_id_) : absl::nullopt);
+        .Run(success ? absl::make_optional(origin_id_) : absl::nullopt);
     delete this;
   }
 
@@ -262,6 +259,40 @@
   scoped_refptr<media::MediaDrmBridge> media_drm_bridge_;
 };
 
+// Provisioning runs on a separate background sequence. This kicks off the
+// process, calling |callback| when done. |provisioning_result_cb_for_testing|
+// is provided for testing.
+void StartProvisioning(
+    std::unique_ptr<network::PendingSharedURLLoaderFactory>
+        pending_shared_url_loader_factory,
+    MediaDrmOriginIdManager::ProvisioningResultCB
+        provisioning_result_cb_for_testing,
+    MediaDrmProvisionHelper::ProvisionedOriginIdCB callback) {
+  DVLOG(1) << __func__;
+
+  if (provisioning_result_cb_for_testing) {
+    // MediaDrm can't provision an origin ID during unittests, so create a new
+    // origin ID and pretend it was provisioned or not depending on the result
+    // from |provisioning_result_cb_for_testing|.
+    std::move(callback).Run(
+        provisioning_result_cb_for_testing.Run()
+            ? absl::make_optional(base::UnguessableToken::Create())
+            : absl::nullopt);
+    return;
+  }
+
+  if (!pending_shared_url_loader_factory) {
+    // No fetcher available, so don't bother trying to provision.
+    std::move(callback).Run(absl::nullopt);
+    return;
+  }
+
+  // MediaDrmProvisionHelper will delete itself when it's done.
+  auto* helper =
+      new MediaDrmProvisionHelper(std::move(pending_shared_url_loader_factory));
+  helper->Provision(std::move(callback));
+}
+
 }  // namespace
 
 // Watch for the device being connected to a network and call
@@ -378,9 +409,10 @@
     return;
   }
 
-  // Attempt to pre-provision more origin IDs in the near future.
+  // Attempt to pre-provision more origin IDs in the near future. This can
+  // be done on a low priority sequence in the background.
   is_provisioning_ = true;
-  StartProvisioningAsync();
+  StartProvisioningAsync(/*run_in_background=*/true);
 }
 
 void MediaDrmOriginIdManager::GetOriginId(ProvisionedOriginIdCB callback) {
@@ -390,12 +422,15 @@
   // See if there is one already pre-provisioned that can be used.
   base::UnguessableToken origin_id = TakeFirstOriginId(pref_service_);
 
-  // Start a task to pre-provision more origin IDs if we are currently not doing
-  // so. If there is one available then we need to replace it. If there are
-  // none, we need one.
+  // Start a task to pre-provision more origin IDs if we are currently
+  // not doing so.
   if (!is_provisioning_) {
     is_provisioning_ = true;
-    StartProvisioningAsync();
+
+    // If there is an origin ID available then we need to replace it, but this
+    // can be done in the background. If there are none available, we need one
+    // now as the user is trying to play protected content.
+    StartProvisioningAsync(/*run_in_background=*/!origin_id.is_empty());
   }
 
   // If no pre-provisioned origin ID currently available, so save the callback
@@ -410,48 +445,60 @@
                           origin_id);
 }
 
-void MediaDrmOriginIdManager::StartProvisioningAsync() {
-  DVLOG(1) << __func__;
+void MediaDrmOriginIdManager::StartProvisioningAsync(bool run_in_background) {
+  DVLOG(1) << __func__ << " run_in_background: " << run_in_background;
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   DCHECK(is_provisioning_);
 
-  // Run StartProvisioning() later, on this thread.
-  base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::BindOnce(&MediaDrmOriginIdManager::StartProvisioning,
-                                weak_factory_.GetWeakPtr()));
-}
+  // Run StartProvisioning() later. This is done on a separate thread to avoid
+  // scroll jank, especially when pre-provisioning is happening (as the origin
+  // IDs aren't needed for the current page, so it can run at low priority).
+  // However, if a user needs a provisioned origin ID immediately, then run at
+  // higher priority. See crbug.com/1366106 for details.
+  const base::TaskPriority priority = run_in_background
+                                          ? base::TaskPriority::BEST_EFFORT
+                                          : base::TaskPriority::USER_VISIBLE;
 
-void MediaDrmOriginIdManager::StartProvisioning() {
-  DVLOG(1) << __func__;
-  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-  DCHECK(is_provisioning_);
-
-  if (provisioning_result_cb_for_testing_) {
-    // MediaDrm can't provision an origin ID during unittests, so create a new
-    // origin ID and pretend it was provisioned or not depending on the result
-    // from |provisioning_result_cb_for_testing_|.
-    OriginIdProvisioned(provisioning_result_cb_for_testing_.Run(),
-                        base::UnguessableToken::Create());
-    return;
+  // Provisioning requires accessing the network to handle the actual
+  // provisioning request. If access is not currently available, then the
+  // request will fail and OriginIdProvisioned() will setup a observer
+  // for when network access is available again. When testing the network
+  // is not accessible, but prefer to call |provisioning_result_cb_for_testing_|
+  // from the generated sequence.
+  std::unique_ptr<network::PendingSharedURLLoaderFactory>
+      pending_shared_url_loader_factory;
+  auto* network_context_manager =
+      g_browser_process->system_network_context_manager();
+  if (network_context_manager) {
+    // Fetching the license will run on a different sequence, so clone
+    // SharedURLLoaderFactory to create an unbound one that can be used
+    // on any thread/sequence.
+    pending_shared_url_loader_factory =
+        network_context_manager->GetSharedURLLoaderFactory()->Clone();
   }
 
-  // MediaDrmProvisionHelper will delete itself when it's done.
-  auto* helper = new MediaDrmProvisionHelper();
-  helper->Provision(
-      base::BindOnce(&MediaDrmOriginIdManager::OriginIdProvisioned,
-                     weak_factory_.GetWeakPtr()));
+  // Note that MediaDrmBridge requires the use of SingleThreadTaskRunner.
+  scoped_refptr<base::SingleThreadTaskRunner> provisioning_task_runner =
+      base::ThreadPool::CreateSingleThreadTaskRunner(
+          {base::MayBlock(), priority});
+  provisioning_task_runner->PostTask(
+      FROM_HERE,
+      base::BindOnce(&StartProvisioning,
+                     std::move(pending_shared_url_loader_factory),
+                     provisioning_result_cb_for_testing_,
+                     media::BindToCurrentLoop(base::BindOnce(
+                         &MediaDrmOriginIdManager::OriginIdProvisioned,
+                         weak_factory_.GetWeakPtr()))));
 }
 
 void MediaDrmOriginIdManager::OriginIdProvisioned(
-    bool success,
     const MediaDrmOriginId& origin_id) {
   DVLOG(1) << __func__
-           << " origin_id: " << (origin_id ? origin_id->ToString() : "null")
-           << ", success: " << success;
+           << " origin_id: " << (origin_id ? origin_id->ToString() : "null");
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   DCHECK(is_provisioning_);
 
-  if (!success) {
+  if (!origin_id) {
     // Unable to provision an origin ID, most likely due to being unable to
     // connect to a provisioning server. Set up a NetworkObserver to detect when
     // we're connected to a network so that we can try again. If there is
@@ -484,7 +531,6 @@
   // Success, for at least one level. Pass |origin_id| to the first requestor if
   // somebody is waiting for it. Otherwise add it to the list of available
   // origin IDs in the preference.
-  DCHECK(origin_id);
   if (!pending_provisioned_origin_id_cbs_.empty()) {
     std::move(pending_provisioned_origin_id_cbs_.front())
         .Run(GetOriginIdStatus::kSuccessWithNewlyProvisionedOriginId,
@@ -504,8 +550,12 @@
     }
   }
 
-  // Create another pre-provisioned origin ID asynchronously.
-  StartProvisioningAsync();
+  // Create another pre-provisioned origin ID asynchronously. If there is
+  // no pending requestor, then this is simply pre-provisioning another one,
+  // and can be safely run in the background. If there is a request, run
+  // at higher priority to quickly satisfy the request.
+  StartProvisioningAsync(
+      /*run_in_background=*/pending_provisioned_origin_id_cbs_.empty());
 }
 
 void MediaDrmOriginIdManager::RecordCountOfPreprovisionedOriginIds() {
diff --git a/chrome/browser/media/android/cdm/media_drm_origin_id_manager.h b/chrome/browser/media/android/cdm/media_drm_origin_id_manager.h
index 15c8b69..1be9938 100644
--- a/chrome/browser/media/android/cdm/media_drm_origin_id_manager.h
+++ b/chrome/browser/media/android/cdm/media_drm_origin_id_manager.h
@@ -75,15 +75,13 @@
   // MediaDrmOriginIdManagerFactory.
   explicit MediaDrmOriginIdManager(PrefService* pref_service);
 
-  // Asynchronously call StartProvisioning().
-  void StartProvisioningAsync();
-
-  // Pre-provision one origin ID, calling OriginIdProvisioned() when done.
-  void StartProvisioning();
+  // Asynchronously call StartProvisioning() on a sequence using different
+  // priorities, depending on |run_in_background|.
+  void StartProvisioningAsync(bool run_in_background);
 
   // Called when provisioning of |origin_id| is done. The provisioning of
-  // |origin_id| was successful if |success| is true.
-  void OriginIdProvisioned(bool success, const MediaDrmOriginId& origin_id);
+  // |origin_id| was successful if |origin_id| is not nullopt.
+  void OriginIdProvisioned(const MediaDrmOriginId& origin_id);
 
   // If called, record the current number of pre-provisioned origin IDs to UMA.
   void RecordCountOfPreprovisionedOriginIds();
diff --git a/chrome/browser/payments/android/java/src/org/chromium/chrome/browser/payments/AutofillContactTest.java b/chrome/browser/payments/android/java/src/org/chromium/chrome/browser/payments/AutofillContactTest.java
index 7299f3b..28cbe9c 100644
--- a/chrome/browser/payments/android/java/src/org/chromium/chrome/browser/payments/AutofillContactTest.java
+++ b/chrome/browser/payments/android/java/src/org/chromium/chrome/browser/payments/AutofillContactTest.java
@@ -28,7 +28,7 @@
  * Parametrized unit tests for the AutofillContact class.
  */
 @RunWith(ParameterizedRobolectricTestRunner.class)
-@Config(sdk = Build.VERSION_CODES.M, manifest = Config.NONE)
+@Config(sdk = Build.VERSION_CODES.N, manifest = Config.NONE)
 public class AutofillContactTest {
     @Parameters
     public static Collection<Object[]> data() {
diff --git a/chrome/browser/power_bookmarks/power_bookmark_service_factory.cc b/chrome/browser/power_bookmarks/power_bookmark_service_factory.cc
index 43c4617b..27e811a 100644
--- a/chrome/browser/power_bookmarks/power_bookmark_service_factory.cc
+++ b/chrome/browser/power_bookmarks/power_bookmark_service_factory.cc
@@ -4,9 +4,13 @@
 
 #include "chrome/browser/power_bookmarks/power_bookmark_service_factory.h"
 
+#include "base/files/file_path.h"
+#include "base/task/task_traits.h"
+#include "base/task/thread_pool.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "components/power_bookmarks/core/power_bookmark_service.h"
+#include "content/public/browser/browser_context.h"
 
 // static
 power_bookmarks::PowerBookmarkService*
@@ -33,5 +37,9 @@
 KeyedService* PowerBookmarkServiceFactory::BuildServiceInstanceFor(
     content::BrowserContext* context) const {
   return new power_bookmarks::PowerBookmarkService(
-      BookmarkModelFactory::GetInstance()->GetForBrowserContext(context));
+      BookmarkModelFactory::GetInstance()->GetForBrowserContext(context),
+      context->GetPath().AppendASCII("power_bookmarks"),
+      base::ThreadPool::CreateSequencedTaskRunner(
+          {base::MayBlock(), base::TaskPriority::USER_BLOCKING,
+           base::TaskShutdownBehavior::BLOCK_SHUTDOWN}));
 }
diff --git a/chrome/browser/printing/print_browsertest.cc b/chrome/browser/printing/print_browsertest.cc
index 8e77e74..be2a27e 100644
--- a/chrome/browser/printing/print_browsertest.cc
+++ b/chrome/browser/printing/print_browsertest.cc
@@ -211,6 +211,8 @@
     auto context = MakeDefaultTestPrintingContext(delegate, skip_system_calls,
                                                   printer_name_);
 
+    if (failed_error_for_new_document_)
+      context->SetNewDocumentFails();
     if (access_denied_errors_for_new_document_)
       context->SetNewDocumentBlockedByPermissions();
 #if BUILDFLAG(IS_WIN)
@@ -244,6 +246,10 @@
     printer_name_ = printer_name;
   }
 
+  void SetFailedErrorOnNewDocument(bool cause_errors) {
+    failed_error_for_new_document_ = cause_errors;
+  }
+
   void SetAccessDeniedErrorOnNewDocument(bool cause_errors) {
     access_denied_errors_for_new_document_ = cause_errors;
   }
@@ -282,6 +288,7 @@
 
  private:
   std::string printer_name_;
+  bool failed_error_for_new_document_ = false;
   bool access_denied_errors_for_new_document_ = false;
 #if BUILDFLAG(IS_WIN)
   bool access_denied_errors_for_render_page_ = false;
@@ -2546,6 +2553,11 @@
   }
 #endif
 
+  void PrimeForErrorsInNewDocument() {
+    test_printing_context_factory()->SetFailedErrorOnNewDocument(
+        /*cause_errors=*/true);
+  }
+
   void PrimeForAccessDeniedErrorsInNewDocument() {
     test_printing_context_factory()->SetAccessDeniedErrorOnNewDocument(
         /*cause_errors=*/true);
@@ -2974,6 +2986,46 @@
   EXPECT_EQ(print_job_destruction_count(), 1);
 }
 
+IN_PROC_BROWSER_TEST_P(SystemAccessProcessPrintBrowserTest,
+                       StartPrintingFails) {
+  AddPrinter("printer1");
+  SetPrinterNameForSubsequentContexts("printer1");
+  PrimeForErrorsInNewDocument();
+
+  ASSERT_TRUE(embedded_test_server()->Started());
+  GURL url(embedded_test_server()->GetURL("/printing/test3.html"));
+  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
+
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  ASSERT_TRUE(web_contents);
+  SetUpPrintViewManager(web_contents);
+
+  // There are no callbacks for tracking in-browser printing.  The only
+  // message is to wait for the one print job to be destroyed to ensure
+  // printing finished cleanly before completing the test.  So only need
+  // to override the number of expected messages for OOP.
+  if (GetParam() != PrintBackendFeatureVariation::kInBrowserProcess) {
+    // The test sequence for this is:
+    // - A print job is started, but that fails.
+    // - An error dialog is shown.
+    // - Wait for the one print job to be destroyed, to ensure printing
+    //   finished cleanly before completing the test.
+    // This results in a total of 3 calls.
+    SetNumExpectedMessages(/*num=*/3);
+  }
+
+  PrintAfterPreviewIsReadyAndLoaded();
+
+  EXPECT_EQ(start_printing_result(), mojom::ResultCode::kFailed);
+  // TODO(crbug.com/1375018)  Update once in-browser failure is fixed to notify
+  // user of error.
+  EXPECT_EQ(
+      error_dialog_shown_count(),
+      GetParam() == PrintBackendFeatureVariation::kInBrowserProcess ? 0u : 1u);
+  EXPECT_EQ(print_job_destruction_count(), 1);
+}
+
 IN_PROC_BROWSER_TEST_F(SystemAccessProcessSandboxedServicePrintBrowserTest,
                        StartPrintingAccessDenied) {
   AddPrinter("printer1");
@@ -3293,6 +3345,57 @@
   EXPECT_FALSE(print_backend_service_use_detected());
 }
 
+// TODO(crbug.com/1361032)  Enable once crash after processing error from
+// PrintingContext::NewDocument() is resolved.
+IN_PROC_BROWSER_TEST_P(SystemAccessProcessPrintBrowserTest,
+                       DISABLED_StartBasicPrintFails) {
+  AddPrinter("printer1");
+  SetPrinterNameForSubsequentContexts("printer1");
+  PrimeForErrorsInNewDocument();
+
+  ASSERT_TRUE(embedded_test_server()->Started());
+  GURL url(embedded_test_server()->GetURL("/printing/test3.html"));
+  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
+
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  ASSERT_TRUE(web_contents);
+  SetUpPrintViewManager(web_contents);
+
+  if (GetParam() == PrintBackendFeatureVariation::kInBrowserProcess) {
+    // There are only partial overrides to track most steps in the printing
+    // pipeline, so the test sequence for this is:
+    // - Gets default settings.
+    // - Asks user for settings.
+    // - Wait for the one print job to be destroyed, to ensure printing
+    //   finished cleanly before completing the test.
+    // This results in a total of 3 calls.
+    SetNumExpectedMessages(/*num=*/3);
+  } else {
+    // The test sequence for this is:
+    // - Gets default settings.
+    // - Asks user for settings.
+    // - A print job is started, which fails.
+    // - An error dialog is shown.
+    // - Wait for the one print job to be destroyed, to ensure printing
+    //   finished cleanly before completing the test.
+    // This results in a total of 5 calls.
+    SetNumExpectedMessages(/*num=*/5);
+  }
+
+  StartBasicPrint(web_contents);
+
+  WaitUntilCallbackReceived();
+
+  EXPECT_EQ(start_printing_result(), mojom::ResultCode::kFailed);
+  // TODO(crbug.com/1375018)  Update once in-browser failure is fixed to notify
+  // user of error.
+  EXPECT_EQ(
+      error_dialog_shown_count(),
+      GetParam() == PrintBackendFeatureVariation::kInBrowserProcess ? 0u : 1u);
+  EXPECT_EQ(print_job_destruction_count(), 1);
+}
+
 // macOS and Linux currently have to invoke a system dialog from within the
 // browser process.  There is not a callback to capture the result in these
 // cases.
diff --git a/chrome/browser/printing/print_job_worker.cc b/chrome/browser/printing/print_job_worker.cc
index ec5386f5..d6b338aa 100644
--- a/chrome/browser/printing/print_job_worker.cc
+++ b/chrome/browser/printing/print_job_worker.cc
@@ -145,6 +145,14 @@
   print_job_ = print_job;
 }
 
+std::unique_ptr<PrintSettings> PrintJobWorker::GetPdfSettings() {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  DCHECK_EQ(page_number_, PageNumber::npos());
+
+  printing_context_->UsePdfSettings();
+  return printing_context_->TakeAndResetSettings();
+}
+
 void PrintJobWorker::GetDefaultSettings(SettingsCallback callback) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   DCHECK_EQ(page_number_, PageNumber::npos());
diff --git a/chrome/browser/printing/print_job_worker.h b/chrome/browser/printing/print_job_worker.h
index a35dbb5..74476288 100644
--- a/chrome/browser/printing/print_job_worker.h
+++ b/chrome/browser/printing/print_job_worker.h
@@ -50,6 +50,9 @@
 
   /* The following functions may only be called before calling SetPrintJob(). */
 
+  // Initializes the print settings for PDF. Must be called on the UI thread.
+  std::unique_ptr<PrintSettings> GetPdfSettings();
+
   // Initializes the default print settings. Must be called on the UI thread.
   void GetDefaultSettings(SettingsCallback callback);
 
diff --git a/chrome/browser/printing/print_view_manager_base.cc b/chrome/browser/printing/print_view_manager_base.cc
index 3fbf4fae..97870bf 100644
--- a/chrome/browser/printing/print_view_manager_base.cc
+++ b/chrome/browser/printing/print_view_manager_base.cc
@@ -551,13 +551,21 @@
         queue_->CreatePrinterQuery(render_frame_host->GetGlobalId());
   }
 
+  // Sometimes it is desired to get the PDF settings as opposed to the settings
+  // of the default system print driver.
+#if BUILDFLAG(ENABLE_PRINT_CONTENT_ANALYSIS)
+  bool want_pdf_settings = snapshotting_for_content_analysis_;
+#else
+  bool want_pdf_settings = false;
+#endif
+
   // Loads default settings. This is asynchronous, only the mojo message sender
   // will hang until the settings are retrieved.
   auto* printer_query_ptr = printer_query.get();
   printer_query_ptr->GetDefaultSettings(
       base::BindOnce(&OnDidGetDefaultPrintSettings, queue_,
                      std::move(printer_query), std::move(callback_wrapper)),
-      !render_process_host->IsPdf());
+      !render_process_host->IsPdf(), want_pdf_settings);
 }
 
 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
diff --git a/chrome/browser/printing/printer_query.cc b/chrome/browser/printing/printer_query.cc
index fce5d24d..8ad9aaf8 100644
--- a/chrome/browser/printing/printer_query.cc
+++ b/chrome/browser/printing/printer_query.cc
@@ -114,13 +114,24 @@
 }
 
 void PrinterQuery::GetDefaultSettings(base::OnceClosure callback,
-                                      bool is_modifiable) {
+                                      bool is_modifiable,
+                                      bool want_pdf_settings) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   StartWorker();
 
-  // Real work is done in PrintJobWorker::GetDefaultSettings().
+  // Real work is done in `PrintJobWorker`.
   is_print_dialog_box_shown_ = false;
+
+  if (want_pdf_settings) {
+    // `PrintJobWorker::GetPdfSettings()` is always guaranteed to succeed.
+    std::unique_ptr<PrintSettings> pdf_settings = worker_->GetPdfSettings();
+    DCHECK(pdf_settings);
+    PostSettingsDone(std::move(callback), is_modifiable,
+                     std::move(pdf_settings), mojom::ResultCode::kSuccess);
+    return;
+  }
+
   // `this` is owned by `callback`, so `base::Unretained()` is safe.
   worker_->GetDefaultSettings(
       base::BindOnce(&PrinterQuery::PostSettingsDone, base::Unretained(this),
diff --git a/chrome/browser/printing/printer_query.h b/chrome/browser/printing/printer_query.h
index a054936..d3fba2dd 100644
--- a/chrome/browser/printing/printer_query.h
+++ b/chrome/browser/printing/printer_query.h
@@ -52,7 +52,9 @@
   // Initializes the printing context. It is fine to call this function multiple
   // times to reinitialize the settings.
   // Caller has to ensure that `this` is alive until `callback` is run.
-  void GetDefaultSettings(base::OnceClosure callback, bool is_modifiable);
+  void GetDefaultSettings(base::OnceClosure callback,
+                          bool is_modifiable,
+                          bool want_pdf_settings);
   void GetSettingsFromUser(uint32_t expected_page_count,
                            bool has_selection,
                            mojom::MarginType margin_type,
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn b/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn
index 49e3fd2..88f48a5 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn
@@ -138,6 +138,7 @@
   "common/panel_bridge.js",
   "common/panel_command.js",
   "common/panel_menu_data.js",
+  "common/role_type.js",
   "common/spannable.js",
   "common/tree_dumper.js",
   "common/tts_base.js",
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/output/output_role_info.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/output/output_role_info.js
index 6a027b68..90b95a6b 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/output/output_role_info.js
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/output/output_role_info.js
@@ -6,13 +6,17 @@
  * @fileoverview Roel information for the Output module.
  */
 
+import {AbstractRole, ChromeVoxRole} from '../../common/role_type.js';
+
 import {OutputContextOrder} from './output_types.js';
 
+const RoleType = chrome.automation.RoleType;
+
 /**
  * Metadata about supported automation roles.
  * @const {Object<{msgId: string,
  *                 earconId: (string|undefined),
- *                 inherits: (string|undefined),
+ *                 inherits: (ChromeVoxRole|undefined),
  *                 verboseAncestry: (boolean|undefined),
  *                 contextOrder: (OutputContextOrder|undefined),
  *                 ignoreAncestry: (boolean|undefined)}>}
@@ -26,124 +30,132 @@
  * be desirable when wanting start and end span-like output.
  */
 export const OutputRoleInfo = {
-  abbr: {msgId: 'tag_abbr', inherits: 'abstractContainer'},
+  abbr: {msgId: 'tag_abbr', inherits: AbstractRole.CONTAINER},
   alert: {msgId: 'role_alert'},
   alertDialog:
       {msgId: 'role_alertdialog', contextOrder: OutputContextOrder.FIRST},
-  article: {msgId: 'role_article', inherits: 'abstractItem'},
-  application: {msgId: 'role_application', inherits: 'abstractContainer'},
-  audio: {msgId: 'tag_audio', inherits: 'abstractFormFieldContainer'},
-  banner: {msgId: 'role_banner', inherits: 'abstractContainer'},
+  article: {msgId: 'role_article', inherits: AbstractRole.ITEM},
+  application: {msgId: 'role_application', inherits: AbstractRole.CONTAINER},
+  audio: {msgId: 'tag_audio', inherits: AbstractRole.FORM_FIELD_CONTAINER},
+  banner: {msgId: 'role_banner', inherits: AbstractRole.CONTAINER},
   button: {msgId: 'role_button', earconId: 'BUTTON'},
   buttonDropDown: {msgId: 'role_button', earconId: 'BUTTON'},
   checkBox: {msgId: 'role_checkbox'},
-  columnHeader: {msgId: 'role_columnheader', inherits: 'cell'},
+  columnHeader: {msgId: 'role_columnheader', inherits: RoleType.CELL},
   comboBoxMenuButton: {msgId: 'role_combobox', earconId: 'LISTBOX'},
   comboBoxGrouping:
-      {msgId: 'role_combobox', inherits: 'abstractFormFieldContainer'},
+      {msgId: 'role_combobox', inherits: AbstractRole.FORM_FIELD_CONTAINER},
   comboBoxSelect: {
     msgId: 'role_button',
     earconId: 'POP_UP_BUTTON',
-    inherits: 'comboBoxMenuButton',
+    inherits: RoleType.COMBO_BOX_MENU_BUTTON,
   },
-  complementary: {msgId: 'role_complementary', inherits: 'abstractContainer'},
+  complementary:
+      {msgId: 'role_complementary', inherits: AbstractRole.CONTAINER},
   comment: {
     msgId: 'role_comment',
     contextOrder: OutputContextOrder.FIRST_AND_LAST,
     verboseAncestry: true,
-    inherits: 'abstractSpan',
+    inherits: AbstractRole.SPAN,
   },
   contentDeletion: {
     msgId: 'role_content_deletion',
     contextOrder: OutputContextOrder.FIRST_AND_LAST,
     verboseAncestry: true,
-    inherits: 'abstractSpan',
+    inherits: AbstractRole.SPAN,
   },
   contentInsertion: {
     msgId: 'role_content_insertion',
     contextOrder: OutputContextOrder.FIRST_AND_LAST,
     verboseAncestry: true,
-    inherits: 'abstractSpan',
+    inherits: AbstractRole.SPAN,
   },
-  contentInfo: {msgId: 'role_contentinfo', inherits: 'abstractContainer'},
-  date: {msgId: 'input_type_date', inherits: 'abstractFormFieldContainer'},
-  definition: {msgId: 'role_definition', inherits: 'abstractContainer'},
-  descriptionList: {msgId: 'role_description_list', inherits: 'abstractList'},
+  contentInfo: {msgId: 'role_contentinfo', inherits: AbstractRole.CONTAINER},
+  date: {msgId: 'input_type_date', inherits: AbstractRole.FORM_FIELD_CONTAINER},
+  definition: {msgId: 'role_definition', inherits: AbstractRole.CONTAINER},
+  descriptionList:
+      {msgId: 'role_description_list', inherits: AbstractRole.LIST},
   descriptionListDetail:
-      {msgId: 'role_description_list_detail', inherits: 'abstractItem'},
+      {msgId: 'role_description_list_detail', inherits: AbstractRole.ITEM},
   dialog: {
     msgId: 'role_dialog',
     contextOrder: OutputContextOrder.DIRECTED,
     ignoreAncestry: true,
   },
-  directory: {msgId: 'role_directory', inherits: 'abstractContainer'},
-  docAbstract: {msgId: 'role_doc_abstract', inherits: 'abstractSpan'},
+  directory: {msgId: 'role_directory', inherits: AbstractRole.CONTAINER},
+  docAbstract: {msgId: 'role_doc_abstract', inherits: AbstractRole.SPAN},
   docAcknowledgments:
-      {msgId: 'role_doc_acknowledgments', inherits: 'abstractSpan'},
-  docAfterword: {msgId: 'role_doc_afterword', inherits: 'abstractContainer'},
-  docAppendix: {msgId: 'role_doc_appendix', inherits: 'abstractSpan'},
+      {msgId: 'role_doc_acknowledgments', inherits: AbstractRole.SPAN},
+  docAfterword: {msgId: 'role_doc_afterword', inherits: AbstractRole.CONTAINER},
+  docAppendix: {msgId: 'role_doc_appendix', inherits: AbstractRole.SPAN},
   docBackLink:
-      {msgId: 'role_doc_back_link', earconId: 'LINK', inherits: 'link'},
+      {msgId: 'role_doc_back_link', earconId: 'LINK', inherits: RoleType.LINK},
   docBiblioEntry: {
     msgId: 'role_doc_biblio_entry',
     earconId: 'LIST_ITEM',
-    inherits: 'abstractItem',
+    inherits: AbstractRole.ITEM,
   },
-  docBibliography: {msgId: 'role_doc_bibliography', inherits: 'abstractSpan'},
+  docBibliography:
+      {msgId: 'role_doc_bibliography', inherits: AbstractRole.SPAN},
   docBiblioRef:
-      {msgId: 'role_doc_biblio_ref', earconId: 'LINK', inherits: 'link'},
-  docChapter: {msgId: 'role_doc_chapter', inherits: 'abstractSpan'},
-  docColophon: {msgId: 'role_doc_colophon', inherits: 'abstractSpan'},
-  docConclusion: {msgId: 'role_doc_conclusion', inherits: 'abstractSpan'},
-  docCover: {msgId: 'role_doc_cover', inherits: 'image'},
-  docCredit: {msgId: 'role_doc_credit', inherits: 'abstractSpan'},
-  docCredits: {msgId: 'role_doc_credits', inherits: 'abstractSpan'},
-  docDedication: {msgId: 'role_doc_dedication', inherits: 'abstractSpan'},
+      {msgId: 'role_doc_biblio_ref', earconId: 'LINK', inherits: RoleType.LINK},
+  docChapter: {msgId: 'role_doc_chapter', inherits: AbstractRole.SPAN},
+  docColophon: {msgId: 'role_doc_colophon', inherits: AbstractRole.SPAN},
+  docConclusion: {msgId: 'role_doc_conclusion', inherits: AbstractRole.SPAN},
+  docCover: {msgId: 'role_doc_cover', inherits: RoleType.IMAGE},
+  docCredit: {msgId: 'role_doc_credit', inherits: AbstractRole.SPAN},
+  docCredits: {msgId: 'role_doc_credits', inherits: AbstractRole.SPAN},
+  docDedication: {msgId: 'role_doc_dedication', inherits: AbstractRole.SPAN},
   docEndnote: {
     msgId: 'role_doc_endnote',
     earconId: 'LIST_ITEM',
-    inherits: 'abstractItem',
+    inherits: AbstractRole.ITEM,
   },
-  docEndnotes:
-      {msgId: 'role_doc_endnotes', earconId: 'LISTBOX', inherits: 'list'},
-  docEpigraph: {msgId: 'role_doc_epigraph', inherits: 'abstractSpan'},
-  docEpilogue: {msgId: 'role_doc_epilogue', inherits: 'abstractSpan'},
-  docErrata: {msgId: 'role_doc_errata', inherits: 'abstractSpan'},
-  docExample: {msgId: 'role_doc_example', inherits: 'abstractSpan'},
+  docEndnotes: {
+    msgId: 'role_doc_endnotes',
+    earconId: 'LISTBOX',
+    inherits: RoleType.LIST,
+  },
+  docEpigraph: {msgId: 'role_doc_epigraph', inherits: AbstractRole.SPAN},
+  docEpilogue: {msgId: 'role_doc_epilogue', inherits: AbstractRole.SPAN},
+  docErrata: {msgId: 'role_doc_errata', inherits: AbstractRole.SPAN},
+  docExample: {msgId: 'role_doc_example', inherits: AbstractRole.SPAN},
   docFootnote: {
     msgId: 'role_doc_footnote',
     earconId: 'LIST_ITEM',
-    inherits: 'abstractItem',
+    inherits: AbstractRole.ITEM,
   },
-  docForeword: {msgId: 'role_doc_foreword', inherits: 'abstractSpan'},
-  docGlossary: {msgId: 'role_doc_glossary', inherits: 'abstractSpan'},
+  docForeword: {msgId: 'role_doc_foreword', inherits: AbstractRole.SPAN},
+  docGlossary: {msgId: 'role_doc_glossary', inherits: AbstractRole.SPAN},
   docGlossRef:
-      {msgId: 'role_doc_gloss_ref', earconId: 'LINK', inherits: 'link'},
-  docIndex: {msgId: 'role_doc_index', inherits: 'abstractSpan'},
-  docIntroduction: {msgId: 'role_doc_introduction', inherits: 'abstractSpan'},
-  docNoteRef: {msgId: 'role_doc_note_ref', earconId: 'LINK', inherits: 'link'},
-  docNotice: {msgId: 'role_doc_notice', inherits: 'abstractSpan'},
-  docPageBreak: {msgId: 'role_doc_page_break', inherits: 'abstractSpan'},
-  docPageFooter: {msgId: 'role_doc_page_footer', inherits: 'abstractSpan'},
-  docPageHeader: {msgId: 'role_doc_page_header', inherits: 'abstractSpan'},
-  docPageList: {msgId: 'role_doc_page_list', inherits: 'abstractSpan'},
-  docPart: {msgId: 'role_doc_part', inherits: 'abstractSpan'},
-  docPreface: {msgId: 'role_doc_preface', inherits: 'abstractSpan'},
-  docPrologue: {msgId: 'role_doc_prologue', inherits: 'abstractSpan'},
-  docPullquote: {msgId: 'role_doc_pullquote', inherits: 'abstractSpan'},
-  docQna: {msgId: 'role_doc_qna', inherits: 'abstractSpan'},
-  docSubtitle: {msgId: 'role_doc_subtitle', inherits: 'heading'},
-  docTip: {msgId: 'role_doc_tip', inherits: 'abstractSpan'},
-  docToc: {msgId: 'role_doc_toc', inherits: 'abstractSpan'},
-  document: {msgId: 'role_document', inherits: 'abstractContainer'},
-  form: {msgId: 'role_form', inherits: 'abstractContainer'},
+      {msgId: 'role_doc_gloss_ref', earconId: 'LINK', inherits: RoleType.LINK},
+  docIndex: {msgId: 'role_doc_index', inherits: AbstractRole.SPAN},
+  docIntroduction:
+      {msgId: 'role_doc_introduction', inherits: AbstractRole.SPAN},
+  docNoteRef:
+      {msgId: 'role_doc_note_ref', earconId: 'LINK', inherits: RoleType.LINK},
+  docNotice: {msgId: 'role_doc_notice', inherits: AbstractRole.SPAN},
+  docPageBreak: {msgId: 'role_doc_page_break', inherits: AbstractRole.SPAN},
+  docPageFooter: {msgId: 'role_doc_page_footer', inherits: AbstractRole.SPAN},
+  docPageHeader: {msgId: 'role_doc_page_header', inherits: AbstractRole.SPAN},
+  docPageList: {msgId: 'role_doc_page_list', inherits: AbstractRole.SPAN},
+  docPart: {msgId: 'role_doc_part', inherits: AbstractRole.SPAN},
+  docPreface: {msgId: 'role_doc_preface', inherits: AbstractRole.SPAN},
+  docPrologue: {msgId: 'role_doc_prologue', inherits: AbstractRole.SPAN},
+  docPullquote: {msgId: 'role_doc_pullquote', inherits: AbstractRole.SPAN},
+  docQna: {msgId: 'role_doc_qna', inherits: AbstractRole.SPAN},
+  docSubtitle: {msgId: 'role_doc_subtitle', inherits: RoleType.HEADING},
+  docTip: {msgId: 'role_doc_tip', inherits: AbstractRole.SPAN},
+  docToc: {msgId: 'role_doc_toc', inherits: AbstractRole.SPAN},
+  document: {msgId: 'role_document', inherits: AbstractRole.CONTAINER},
+  form: {msgId: 'role_form', inherits: AbstractRole.CONTAINER},
   graphicsDocument:
-      {msgId: 'role_graphics_document', inherits: 'abstractContainer'},
+      {msgId: 'role_graphics_document', inherits: AbstractRole.CONTAINER},
   graphicsObject:
-      {msgId: 'role_graphics_object', inherits: 'abstractContainer'},
-  graphicsSymbol: {msgId: 'role_graphics_symbol', inherits: 'image'},
-  grid: {msgId: 'role_grid', inherits: 'table'},
-  group: {msgId: 'role_group', inherits: 'abstractContainer'},
+      {msgId: 'role_graphics_object', inherits: AbstractRole.CONTAINER},
+  graphicsSymbol: {msgId: 'role_graphics_symbol', inherits: RoleType.IMAGE},
+  grid: {msgId: 'role_grid', inherits: RoleType.TABLE},
+  group: {msgId: 'role_group', inherits: AbstractRole.CONTAINER},
   heading: {
     msgId: 'role_heading',
   },
@@ -151,24 +163,28 @@
     msgId: 'role_img',
   },
   imeCandidate: {msgId: 'ime_candidate', ignoreAncestry: true},
-  inputTime: {msgId: 'input_type_time', inherits: 'abstractFormFieldContainer'},
+  inputTime:
+      {msgId: 'input_type_time', inherits: AbstractRole.FORM_FIELD_CONTAINER},
   link: {msgId: 'role_link', earconId: 'LINK'},
-  list: {msgId: 'role_list', inherits: 'abstractList'},
+  list: {msgId: 'role_list', inherits: AbstractRole.LIST},
   listBox: {msgId: 'role_listbox', earconId: 'LISTBOX'},
   listBoxOption: {msgId: 'role_listitem', earconId: 'LIST_ITEM'},
-  listGrid: {msgId: 'role_list_grid', inherits: 'table'},
-  listItem:
-      {msgId: 'role_listitem', earconId: 'LIST_ITEM', inherits: 'abstractItem'},
-  log: {msgId: 'role_log', inherits: 'abstractNameFromContents'},
-  main: {msgId: 'role_main', inherits: 'abstractContainer'},
+  listGrid: {msgId: 'role_list_grid', inherits: RoleType.TABLE},
+  listItem: {
+    msgId: 'role_listitem',
+    earconId: 'LIST_ITEM',
+    inherits: AbstractRole.ITEM,
+  },
+  log: {msgId: 'role_log', inherits: AbstractRole.NAME_FROM_CONTENTS},
+  main: {msgId: 'role_main', inherits: AbstractRole.CONTAINER},
   mark: {
     msgId: 'role_mark',
     contextOrder: OutputContextOrder.FIRST_AND_LAST,
     verboseAncestry: true,
-    inherits: 'abstractContainer',
+    inherits: AbstractRole.CONTAINER,
   },
-  marquee: {msgId: 'role_marquee', inherits: 'abstractNameFromContents'},
-  math: {msgId: 'role_math', inherits: 'abstractContainer'},
+  marquee: {msgId: 'role_marquee', inherits: AbstractRole.NAME_FROM_CONTENTS},
+  math: {msgId: 'role_math', inherits: AbstractRole.CONTAINER},
   menu: {
     msgId: 'role_menu',
     contextOrder: OutputContextOrder.FIRST,
@@ -182,54 +198,55 @@
   menuItemRadio: {msgId: 'role_menuitemradio'},
   menuListOption: {msgId: 'role_menuitem'},
   menuListPopup: {msgId: 'role_menu'},
-  meter: {msgId: 'role_meter', inherits: 'abstractRange'},
-  navigation: {msgId: 'role_navigation', inherits: 'abstractContainer'},
-  note: {msgId: 'role_note', inherits: 'abstractContainer'},
+  meter: {msgId: 'role_meter', inherits: AbstractRole.RANGE},
+  navigation: {msgId: 'role_navigation', inherits: AbstractRole.CONTAINER},
+  note: {msgId: 'role_note', inherits: AbstractRole.CONTAINER},
   progressIndicator:
-      {msgId: 'role_progress_indicator', inherits: 'abstractRange'},
+      {msgId: 'role_progress_indicator', inherits: AbstractRole.RANGE},
   popUpButton: {
     msgId: 'role_button',
     earconId: 'POP_UP_BUTTON',
-    inherits: 'comboBoxMenuButton',
+    inherits: RoleType.COMBO_BOX_MENU_BUTTON,
   },
   radioButton: {msgId: 'role_radio'},
   radioGroup:
-      {msgId: 'role_radiogroup', inherits: 'abstractFormFieldContainer'},
-  region: {msgId: 'role_region', inherits: 'abstractContainer'},
+      {msgId: 'role_radiogroup', inherits: AbstractRole.FORM_FIELD_CONTAINER},
+  region: {msgId: 'role_region', inherits: AbstractRole.CONTAINER},
   row: {msgId: 'role_row'},
-  rowHeader: {msgId: 'role_rowheader', inherits: 'cell'},
-  scrollBar: {msgId: 'role_scrollbar', inherits: 'abstractRange'},
-  section: {msgId: 'role_region', inherits: 'abstractContainer'},
-  search: {msgId: 'role_search', inherits: 'abstractContainer'},
-  separator: {msgId: 'role_separator', inherits: 'abstractContainer'},
-  slider: {msgId: 'role_slider', inherits: 'abstractRange', earconId: 'SLIDER'},
+  rowHeader: {msgId: 'role_rowheader', inherits: RoleType.CELL},
+  scrollBar: {msgId: 'role_scrollbar', inherits: AbstractRole.RANGE},
+  section: {msgId: 'role_region', inherits: AbstractRole.CONTAINER},
+  search: {msgId: 'role_search', inherits: AbstractRole.CONTAINER},
+  separator: {msgId: 'role_separator', inherits: AbstractRole.CONTAINER},
+  slider:
+      {msgId: 'role_slider', inherits: AbstractRole.RANGE, earconId: 'SLIDER'},
   spinButton: {
     msgId: 'role_spinbutton',
-    inherits: 'abstractRange',
+    inherits: AbstractRole.RANGE,
     earconId: 'LISTBOX',
   },
-  splitter: {msgId: 'role_separator', inherits: 'abstractSpan'},
-  status: {msgId: 'role_status', inherits: 'abstractNameFromContents'},
-  subscript: {msgId: 'role_subscript', inherits: 'abstractSpan'},
+  splitter: {msgId: 'role_separator', inherits: AbstractRole.SPAN},
+  status: {msgId: 'role_status', inherits: AbstractRole.NAME_FROM_CONTENTS},
+  subscript: {msgId: 'role_subscript', inherits: AbstractRole.SPAN},
   suggestion: {
     msgId: 'role_suggestion',
     contextOrder: OutputContextOrder.FIRST_AND_LAST,
     verboseAncestry: true,
-    inherits: 'abstractSpan',
+    inherits: AbstractRole.SPAN,
   },
-  superscript: {msgId: 'role_superscript', inherits: 'abstractSpan'},
-  tab: {msgId: 'role_tab', inherits: 'abstractContainer'},
-  tabList: {msgId: 'role_tablist', inherits: 'abstractFormFieldContainer'},
-  tabPanel: {msgId: 'role_tabpanel', inherits: 'abstractContainer'},
+  superscript: {msgId: 'role_superscript', inherits: AbstractRole.SPAN},
+  tab: {msgId: 'role_tab', inherits: AbstractRole.CONTAINER},
+  tabList: {msgId: 'role_tablist', inherits: AbstractRole.FORM_FIELD_CONTAINER},
+  tabPanel: {msgId: 'role_tabpanel', inherits: AbstractRole.CONTAINER},
   searchBox: {msgId: 'role_search', earconId: 'EDITABLE_TEXT'},
   textField: {msgId: 'input_type_text', earconId: 'EDITABLE_TEXT'},
   textFieldWithComboBox: {msgId: 'role_combobox', earconId: 'EDITABLE_TEXT'},
-  time: {msgId: 'tag_time', inherits: 'abstractFormFieldContainer'},
-  timer: {msgId: 'role_timer', inherits: 'abstractNameFromContents'},
+  time: {msgId: 'tag_time', inherits: AbstractRole.FORM_FIELD_CONTAINER},
+  timer: {msgId: 'role_timer', inherits: AbstractRole.NAME_FROM_CONTENTS},
   toolbar: {msgId: 'role_toolbar', ignoreAncestry: true},
-  toggleButton: {msgId: 'role_toggle_button', inherits: 'checkBox'},
+  toggleButton: {msgId: 'role_toggle_button', inherits: RoleType.CHECK_BOX},
   tree: {msgId: 'role_tree'},
   treeItem: {msgId: 'role_treeitem'},
-  video: {msgId: 'tag_video', inherits: 'abstractFormFieldContainer'},
+  video: {msgId: 'tag_video', inherits: AbstractRole.FORM_FIELD_CONTAINER},
   window: {ignoreAncestry: true},
 };
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/common/role_type.js b/chrome/browser/resources/chromeos/accessibility/chromevox/common/role_type.js
new file mode 100644
index 0000000..7b6f8fe
--- /dev/null
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/common/role_type.js
@@ -0,0 +1,22 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview Augments chrome.automation.RoleType with abstract types for
+ * ChromeVox.
+ */
+
+/** @enum {string} */
+export const AbstractRole = {
+  CONTAINER: 'abstractContainer',
+  FORM_FIELD_CONTAINER: 'abstractFormFieldContainer',
+  ITEM: 'abstractItem',
+  LIST: 'abstractList',
+  NAME_FROM_CONTENTS: 'abstractNameFromContents',
+  RANGE: 'abstractRange',
+  SPAN: 'abstractSpan',
+};
+
+/** @typedef {!chrome.automation.RoleType|!AbstractRole} */
+export let ChromeVoxRole;
diff --git a/chrome/browser/resources/nearby_share/shared/nearby_device.html b/chrome/browser/resources/nearby_share/shared/nearby_device.html
index f49b05b..b9bd1abc 100644
--- a/chrome/browser/resources/nearby_share/shared/nearby_device.html
+++ b/chrome/browser/resources/nearby_share/shared/nearby_device.html
@@ -8,7 +8,7 @@
     cursor: pointer;
     display: flex;
     height: 40px;
-    margin-block-end: 6px;
+    margin: 3px;
     padding-block-end: 6px;
     padding-block-start: 6px;
     padding-inline-end: 9px;
@@ -19,9 +19,8 @@
     outline: none;
   }
 
-  :host(:focus) #wrapper,
-  :host([is-selected]:focus) #wrapper {
-    border-color: var(--cros-color-secondary);
+  :host(:focus) #wrapper {
+    box-shadow: 0 0 0 2px var(--cros-focus-aura-color);
   }
 
   :host([is-selected]) #wrapper {
diff --git a/chrome/browser/resources/new_tab_page/lens_form.html b/chrome/browser/resources/new_tab_page/lens_form.html
index 5855cfc..af96ade 100644
--- a/chrome/browser/resources/new_tab_page/lens_form.html
+++ b/chrome/browser/resources/new_tab_page/lens_form.html
@@ -22,5 +22,6 @@
     <input name="ep" value="[[uploadUrlEntrypoint_]]"></input>
     <input name="hl" value="[[language_]]"></input>
     <input name="st" value="[[startTime_]]"><input>
+    <input name="cd" value="[[clientData_]]"><input>
   </form>
 </div>
diff --git a/chrome/browser/resources/new_tab_page/lens_form.ts b/chrome/browser/resources/new_tab_page/lens_form.ts
index aa0c46c6..9a25a45 100644
--- a/chrome/browser/resources/new_tab_page/lens_form.ts
+++ b/chrome/browser/resources/new_tab_page/lens_form.ts
@@ -4,6 +4,7 @@
 
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
+import {loadTimeData} from './i18n_setup.js';
 import {getTemplate} from './lens_form.html.js';
 
 /** Lens service endpoint for the Upload by File action. */
@@ -98,7 +99,11 @@
         readOnly: true,
         value: window.navigator.language,
       },
-      startTime_: String,
+      clientData_: {
+        type: String,
+        readOnly: true,
+        value: loadTimeData.getString('realboxLensVariations'),
+      },
     };
   }
 
@@ -106,6 +111,7 @@
   private uploadFileAction_: string = UPLOAD_FILE_ACTION;
   private uploadUrl_: string = '';
   private startTime_: string|null = null;
+  private clientData_: string;
 
   openSystemFilePicker() {
     this.$.fileInput.click();
@@ -153,6 +159,7 @@
     action.searchParams.set('ep', UPLOAD_FILE_ENTRYPOINT);
     action.searchParams.set('hl', this.language_);
     action.searchParams.set('st', this.startTime_.toString());
+    action.searchParams.set('cd', this.clientData_);
     this.uploadFileAction_ = action.toString();
 
     this.dispatchLoading_(LensSubmitType.FILE);
diff --git a/chrome/browser/resources/new_tab_page/voice_search_overlay.html b/chrome/browser/resources/new_tab_page/voice_search_overlay.html
index 668def5..434b4263 100644
--- a/chrome/browser/resources/new_tab_page/voice_search_overlay.html
+++ b/chrome/browser/resources/new_tab_page/voice_search_overlay.html
@@ -210,11 +210,13 @@
             attr-for-selected="link" fallback-selection="none">
           <span link="none"></span>
           <a link="learn-more" target="_blank" href="[[helpUrl_]]"
-              on-click="onLearnMoreClick_" on-keydown="onLinkKeydown_"><!--
+              on-click="onLearnMoreClick_" on-keydown="onLinkKeydown_"
+              aria-label="$i18nPolymer{learnMoreA11yLabel}"><!--
             -->$i18n{learnMore}
           </a>
           <a link="details" target="_blank" href="[[helpUrl_]]"
-              on-keydown="onLinkKeydown_"><!--
+              on-keydown="onLinkKeydown_"
+              aria-label="$i18nPolymer{learnMoreA11yLabel}"><!--
             -->$i18n{details}
           </a>
           <a link="try-again" id="retryLink" href="#"
diff --git a/chrome/browser/resources/password_manager/password_manager_proxy.ts b/chrome/browser/resources/password_manager/password_manager_proxy.ts
index 142ef75..cc9d726 100644
--- a/chrome/browser/resources/password_manager/password_manager_proxy.ts
+++ b/chrome/browser/resources/password_manager/password_manager_proxy.ts
@@ -150,19 +150,11 @@
   }
 
   getSavedPasswordList() {
-    return new Promise<chrome.passwordsPrivate.PasswordUiEntry[]>(resolve => {
-      chrome.passwordsPrivate.getSavedPasswordList(passwords => {
-        resolve(chrome.runtime.lastError ? [] : passwords);
-      });
-    });
+    return chrome.passwordsPrivate.getSavedPasswordList().catch(() => []);
   }
 
   getBlockedSitesList() {
-    return new Promise<BlockedSite[]>(resolve => {
-      chrome.passwordsPrivate.getPasswordExceptionList(exceptions => {
-        resolve(chrome.runtime.lastError ? [] : exceptions);
-      });
-    });
+    return chrome.passwordsPrivate.getPasswordExceptionList().catch(() => []);
   }
 
   getPasswordCheckStatus() {
diff --git a/chrome/browser/resources/settings/autofill_page/merge_passwords_store_copies_mixin.ts b/chrome/browser/resources/settings/autofill_page/merge_passwords_store_copies_mixin.ts
index 1a0232b4..dcbba404 100644
--- a/chrome/browser/resources/settings/autofill_page/merge_passwords_store_copies_mixin.ts
+++ b/chrome/browser/resources/settings/autofill_page/merge_passwords_store_copies_mixin.ts
@@ -50,7 +50,7 @@
             this.notifySplices('savedPasswords', passwordList);
           };
 
-          PasswordManagerImpl.getInstance().getSavedPasswordList(
+          PasswordManagerImpl.getInstance().getSavedPasswordList().then(
               this.setSavedPasswordsListener_);
           PasswordManagerImpl.getInstance().addSavedPasswordListChangedListener(
               this.setSavedPasswordsListener_);
diff --git a/chrome/browser/resources/settings/autofill_page/password_manager_proxy.ts b/chrome/browser/resources/settings/autofill_page/password_manager_proxy.ts
index a52879a6..31bd2a5f 100644
--- a/chrome/browser/resources/settings/autofill_page/password_manager_proxy.ts
+++ b/chrome/browser/resources/settings/autofill_page/password_manager_proxy.ts
@@ -41,10 +41,9 @@
 
   /**
    * Request the list of saved passwords.
-   * TODO(https://crbug.com/919483): Return a promise instead of taking a
-   * callback argument.
+   * @return A promise that resolves with the list of saved passwords.
    */
-  getSavedPasswordList(callback: SavedPasswordListChangedListener): void;
+  getSavedPasswordList(): Promise<chrome.passwordsPrivate.PasswordUiEntry[]>;
 
   /**
    * Log that the Passwords page was accessed from the Chrome Settings WebUI.
@@ -115,10 +114,9 @@
 
   /**
    * Request the list of password exceptions.
-   * TODO(https://crbug.com/919483): Return a promise instead of taking a
-   * callback argument.
+   * @return A promise that resolves with the list of password exceptions.
    */
-  getExceptionList(callback: PasswordExceptionListChangedListener): void;
+  getExceptionList(): Promise<chrome.passwordsPrivate.ExceptionEntry[]>;
 
   /**
    * Should remove the password exception and notify that the list has changed.
@@ -376,8 +374,8 @@
         listener);
   }
 
-  getSavedPasswordList(callback: SavedPasswordListChangedListener) {
-    chrome.passwordsPrivate.getSavedPasswordList(callback);
+  getSavedPasswordList() {
+    return chrome.passwordsPrivate.getSavedPasswordList();
   }
 
   recordPasswordsPageAccessInSettings() {
@@ -422,8 +420,8 @@
         listener);
   }
 
-  getExceptionList(callback: PasswordExceptionListChangedListener) {
-    chrome.passwordsPrivate.getPasswordExceptionList(callback);
+  getExceptionList() {
+    return chrome.passwordsPrivate.getPasswordExceptionList();
   }
 
   removeException(id: number) {
diff --git a/chrome/browser/resources/settings/autofill_page/passwords_section.ts b/chrome/browser/resources/settings/autofill_page/passwords_section.ts
index 95681c1..c838d1b 100644
--- a/chrome/browser/resources/settings/autofill_page/passwords_section.ts
+++ b/chrome/browser/resources/settings/autofill_page/passwords_section.ts
@@ -359,7 +359,8 @@
     };
 
     // Request initial data.
-    this.passwordManager_.getExceptionList(this.setPasswordExceptionsListener_);
+    this.passwordManager_.getExceptionList().then(
+        this.setPasswordExceptionsListener_);
 
     // Listen for changes.
     this.passwordManager_.addExceptionListChangedListener(
diff --git a/chrome/browser/speech/chrome_speech_recognition_service.h b/chrome/browser/speech/chrome_speech_recognition_service.h
index 3cc602ae..1609398 100644
--- a/chrome/browser/speech/chrome_speech_recognition_service.h
+++ b/chrome/browser/speech/chrome_speech_recognition_service.h
@@ -40,6 +40,9 @@
       mojo::PendingReceiver<media::mojom::AudioSourceSpeechRecognitionContext>
           receiver) override;
 
+ protected:
+  content::BrowserContext* context() { return context_; }
+
  private:
   // Launches the speech recognition service in a sandboxed utility process.
   void LaunchIfNotRunning();
@@ -48,7 +51,7 @@
   base::FilePath GetSodaConfigPath(PrefService* prefs);
 
   // The browser context associated with the keyed service.
-  const raw_ptr<content::BrowserContext> context_;
+  raw_ptr<content::BrowserContext> context_;
 
   // The remote to the speech recognition service. The browser will not launch a
   // new speech recognition service process if this remote is already bound.
diff --git a/chrome/browser/speech/cros_speech_recognition_service.cc b/chrome/browser/speech/cros_speech_recognition_service.cc
index b0365459..7908e01 100644
--- a/chrome/browser/speech/cros_speech_recognition_service.cc
+++ b/chrome/browser/speech/cros_speech_recognition_service.cc
@@ -4,17 +4,26 @@
 
 #include "chrome/browser/speech/cros_speech_recognition_service.h"
 
+#include "ash/constants/ash_features.h"
 #include "base/files/file_path.h"
 #include "base/types/optional_util.h"
 #include "chrome/services/speech/audio_source_fetcher_impl.h"
+#include "chrome/services/speech/buildflags/buildflags.h"
 #include "chrome/services/speech/cros_speech_recognition_recognizer_impl.h"
 #include "components/soda/constants.h"
 #include "components/soda/soda_installer.h"
+#include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
+#include "content/public/browser/storage_partition.h"
 #include "media/base/media_switches.h"
 #include "media/mojo/mojom/speech_recognition.mojom.h"
 #include "media/mojo/mojom/speech_recognition_service.mojom.h"
+#include "services/network/public/cpp/shared_url_loader_factory.h"
+
+#if BUILDFLAG(ENABLE_SERVER_BASED_RECOGNITION_RECOGNIZER)
+#include "chrome/services/speech/internal/server_based_recognition_recognizer.h"
+#endif  // BUILDFLAG(ENABLE_SERVER_BASED_RECOGNITION_RECOGNIZER)
 
 namespace speech {
 
@@ -94,50 +103,91 @@
     mojo::PendingRemote<media::mojom::SpeechRecognitionRecognizerClient> client,
     media::mojom::SpeechRecognitionOptionsPtr options,
     BindRecognizerCallback callback) {
-  if (options->is_server_based) {
-    // TODO(b/245614967): when kInternalServerSideSpeechRecognition
-    // feature flag is enabled, create the appropriate recognition recognizer
-    // here.
+  if (!options->is_server_based) {
+    base::FilePath binary_path, languagepack_path;
+    PopulateFilePaths(base::OptionalToPtr(options->language), binary_path,
+                      languagepack_path);
+
+    // CrosSpeechRecognitionService runs on browser UI thread.
+    // Create AudioSourceFetcher on browser IO thread to avoid UI jank.
+    // Note that its CrosSpeechRecognitionRecognizer must also run
+    // on the IO thread. If CrosSpeechRecognitionService is moved away from
+    // browser UI thread, we can call AudioSourceFetcherImpl::Create directly.
+    content::GetIOThreadTaskRunner({})->PostTask(
+        FROM_HERE,
+        base::BindOnce(
+            &CrosSpeechRecognitionService::
+                CreateAudioSourceFetcherForOnDeviceRecognitionOnIOThread,
+            weak_factory_.GetWeakPtr(), std::move(fetcher_receiver),
+            std::move(client), std::move(options), binary_path,
+            languagepack_path));
+    std::move(callback).Run(
+        CrosSpeechRecognitionRecognizerImpl::IsMultichannelSupported());
+    return;
+  }
+#if BUILDFLAG(ENABLE_SERVER_BASED_RECOGNITION_RECOGNIZER)
+  if (!ash::features::IsInternalServerSideSpeechRecognitionEnabled()) {
+    // A request is made for a service that has not been enabled.
     mojo::ReportBadMessage(kInvalidSpeechRecogntionOptions);
     return;
   }
-
-  base::FilePath binary_path, languagepack_path;
-  PopulateFilePaths(base::OptionalToPtr(options->language), binary_path,
-                    languagepack_path);
-
-  // CrosSpeechRecognitionService runs on browser UI thread.
-  // Create AudioSourceFetcher on browser IO thread to avoid UI jank.
-  // Note that its CrosSpeechRecognitionRecognizer must also run
-  // on the IO thread. If CrosSpeechRecognitionService is moved away from
-  // browser UI thread, we can call AudioSourceFetcherImpl::Create directly.
   content::GetIOThreadTaskRunner({})->PostTask(
       FROM_HERE,
       base::BindOnce(
-          &CrosSpeechRecognitionService::CreateAudioSourceFetcherOnIOThread,
+          &CrosSpeechRecognitionService::
+              CreateAudioSourceFetcherForServerBasedRecognitionOnIOThread,
           weak_factory_.GetWeakPtr(), std::move(fetcher_receiver),
-          std::move(client), std::move(options), binary_path,
-          languagepack_path));
-  std::move(callback).Run(
-      CrosSpeechRecognitionRecognizerImpl::IsMultichannelSupported());
+          std::move(client), std::move(options),
+          context()
+              ->GetDefaultStoragePartition()
+              ->GetURLLoaderFactoryForBrowserProcessIOThread()));
+  std::move(callback).Run(/*is_multichannel_supported=*/false);
+  return;
+#else
+  mojo::ReportBadMessage(kInvalidSpeechRecogntionOptions);
+#endif  // BUILDFLAG(ENABLE_SERVER_BASED_RECOGNITION_RECOGNIZER)
 }
 
-void CrosSpeechRecognitionService::CreateAudioSourceFetcherOnIOThread(
-    mojo::PendingReceiver<media::mojom::AudioSourceFetcher> fetcher_receiver,
-    mojo::PendingRemote<media::mojom::SpeechRecognitionRecognizerClient> client,
-    media::mojom::SpeechRecognitionOptionsPtr options,
-    const base::FilePath& binary_path,
-    const base::FilePath& languagepack_path) {
+void CrosSpeechRecognitionService::
+    CreateAudioSourceFetcherForOnDeviceRecognitionOnIOThread(
+        mojo::PendingReceiver<media::mojom::AudioSourceFetcher>
+            fetcher_receiver,
+        mojo::PendingRemote<media::mojom::SpeechRecognitionRecognizerClient>
+            client,
+        media::mojom::SpeechRecognitionOptionsPtr options,
+        const base::FilePath& binary_path,
+        const base::FilePath& languagepack_path) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-  // Cache `is_server_based` since it is used after `options` gets moved.
-  const bool is_server_based = options->is_server_based;
+  DCHECK(!options->is_server_based);
   AudioSourceFetcherImpl::Create(
       std::move(fetcher_receiver),
       std::make_unique<CrosSpeechRecognitionRecognizerImpl>(
           std::move(client), std::move(options), binary_path,
           languagepack_path),
       CrosSpeechRecognitionRecognizerImpl::IsMultichannelSupported(),
-      is_server_based);
+      /*is_server_based=*/false);
+}
+
+void CrosSpeechRecognitionService::
+    CreateAudioSourceFetcherForServerBasedRecognitionOnIOThread(
+        mojo::PendingReceiver<media::mojom::AudioSourceFetcher>
+            fetcher_receiver,
+        mojo::PendingRemote<media::mojom::SpeechRecognitionRecognizerClient>
+            client,
+        media::mojom::SpeechRecognitionOptionsPtr options,
+        std::unique_ptr<network::PendingSharedURLLoaderFactory>
+            pending_loader_factory) {
+#if BUILDFLAG(ENABLE_SERVER_BASED_RECOGNITION_RECOGNIZER)
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+  DCHECK(options->is_server_based);
+  AudioSourceFetcherImpl::Create(
+      std::move(fetcher_receiver),
+      std::make_unique<ServerBasedRecognitionRecognizer>(
+          std::move(client), std::move(options),
+          network::SharedURLLoaderFactory::Create(
+              std::move(pending_loader_factory))),
+      /*is_multichannel_supported=*/false, /*is_server_based=*/true);
+#endif  // BUILDFLAG(ENABLE_SERVER_BASED_RECOGNITION_RECOGNIZER)
 }
 
 }  // namespace speech
diff --git a/chrome/browser/speech/cros_speech_recognition_service.h b/chrome/browser/speech/cros_speech_recognition_service.h
index 4600347..5d9b73fb 100644
--- a/chrome/browser/speech/cros_speech_recognition_service.h
+++ b/chrome/browser/speech/cros_speech_recognition_service.h
@@ -5,6 +5,8 @@
 #ifndef CHROME_BROWSER_SPEECH_CROS_SPEECH_RECOGNITION_SERVICE_H_
 #define CHROME_BROWSER_SPEECH_CROS_SPEECH_RECOGNITION_SERVICE_H_
 
+#include <memory>
+
 #include "base/bind.h"
 #include "base/files/file_path.h"
 #include "chrome/browser/speech/chrome_speech_recognition_service.h"
@@ -17,6 +19,10 @@
 class BrowserContext;
 }  // namespace content
 
+namespace network {
+class PendingSharedURLLoaderFactory;
+}  // namespace network
+
 namespace speech {
 
 // Provides a Mojo endpoint in the browser for the CROS system. This uses ML
@@ -58,7 +64,7 @@
       BindRecognizerCallback callback) override;
 
  private:
-  void CreateAudioSourceFetcherOnIOThread(
+  void CreateAudioSourceFetcherForOnDeviceRecognitionOnIOThread(
       mojo::PendingReceiver<media::mojom::AudioSourceFetcher> fetcher_receiver,
       mojo::PendingRemote<media::mojom::SpeechRecognitionRecognizerClient>
           client,
@@ -66,6 +72,14 @@
       const base::FilePath& binary_path,
       const base::FilePath& languagepack_path);
 
+  void CreateAudioSourceFetcherForServerBasedRecognitionOnIOThread(
+      mojo::PendingReceiver<media::mojom::AudioSourceFetcher> fetcher_receiver,
+      mojo::PendingRemote<media::mojom::SpeechRecognitionRecognizerClient>
+          client,
+      media::mojom::SpeechRecognitionOptionsPtr options,
+      std::unique_ptr<network::PendingSharedURLLoaderFactory>
+          pending_loader_factory);
+
   mojo::ReceiverSet<media::mojom::AudioSourceSpeechRecognitionContext>
       audio_source_speech_recognition_contexts_;
   mojo::ReceiverSet<media::mojom::SpeechRecognitionContext>
diff --git a/chrome/browser/supervised_user/supervised_user_extension_unittest.cc b/chrome/browser/supervised_user/supervised_user_extension_unittest.cc
index 21554475c..7f34a04 100644
--- a/chrome/browser/supervised_user/supervised_user_extension_unittest.cc
+++ b/chrome/browser/supervised_user/supervised_user_extension_unittest.cc
@@ -150,7 +150,7 @@
     auto function = base::MakeRefCounted<
         WebstorePrivateIsPendingCustodianApprovalFunction>();
 
-    std::unique_ptr<base::Value> result(RunFunctionAndReturnSingleResult(
+    absl::optional<base::Value> result(RunFunctionAndReturnSingleResult(
         function.get(), "[\"" + extension_id + "\"]", browser_context()));
     return result->GetBool();
   }
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index acf41a30..4643799b 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -5302,6 +5302,7 @@
       "//components/payments/content:utils",
       "//components/payments/core",
       "//components/power_bookmarks/core:core",
+      "//components/power_bookmarks/storage",
       "//components/qr_code_generator",
       "//components/reading_list/features:flags",
       "//components/services/app_service/public/cpp:intents",
diff --git a/chrome/browser/ui/android/omnibox/java/res/layout/location_status_incognito_badge.xml b/chrome/browser/ui/android/omnibox/java/res/layout/location_status_incognito_badge.xml
index 811c9d6..8be6cc02 100644
--- a/chrome/browser/ui/android/omnibox/java/res/layout/location_status_incognito_badge.xml
+++ b/chrome/browser/ui/android/omnibox/java/res/layout/location_status_incognito_badge.xml
@@ -12,5 +12,7 @@
     android:layout_height="wrap_content"
     android:layout_gravity="center_vertical"
     android:visibility="gone"
+    android:paddingStart="@dimen/incognito_badge_lateral_padding"
+    android:paddingEnd="@dimen/incognito_badge_lateral_padding"
     android:contentDescription="@string/accessibility_incognito_badge"
     app:srcCompat="@drawable/location_bar_incognito_badge" />
diff --git a/chrome/browser/ui/android/omnibox/java/res/values/dimens.xml b/chrome/browser/ui/android/omnibox/java/res/values/dimens.xml
index a4ca937..bc0d4b6 100644
--- a/chrome/browser/ui/android/omnibox/java/res/values/dimens.xml
+++ b/chrome/browser/ui/android/omnibox/java/res/values/dimens.xml
@@ -37,6 +37,7 @@
     <dimen name="location_bar_start_padding">4dp</dimen>
     <dimen name="location_bar_end_padding">8dp</dimen>
     <dimen name="fake_search_box_lateral_padding">10dp</dimen>
+    <dimen name="incognito_badge_lateral_padding">4dp</dimen>
     <dimen name="location_bar_status_icon_width">24dp</dimen>
     <dimen name="location_bar_status_icon_bg_size">32dp</dimen>
     <dimen name="location_bar_icon_end_padding">0dp</dimen>
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusView.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusView.java
index 43d3c17..bd00296 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusView.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusView.java
@@ -182,7 +182,12 @@
                     .setDuration(mAnimationsEnabled ? getIconAnimationDuration() : 0)
                     .alpha(0.0f)
                     .withEndAction(() -> {
+                        // We need to set the icon and the icon's background to be GONE saparately,
+                        // not their parent FrameView, because if we set their parent FrameView to
+                        // be GONE, later on even we set the icon to be VISIBLE, the icon won't show
+                        // up since its parent is GONE.
                         mIconView.setVisibility(View.GONE);
+                        mIconBackground.setVisibility(View.GONE);
                         mIconView.setAlpha(1f);
                         mAnimatingStatusIconHide = false;
                         allowBrowserControlsHide();
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusViewTest.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusViewTest.java
index dfe952a8..74233e3 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusViewTest.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusViewTest.java
@@ -156,6 +156,39 @@
     @MediumTest
     @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE)
     @Feature({"Omnibox"})
+    public void statusView_goneWhenIncognitoBadgeVisible() {
+        // Set location_bar_status_icon is VISIBLE in the beginning.
+        runOnUiThreadBlocking(() -> {
+            mStatusModel.set(StatusProperties.STATUS_ICON_RESOURCE,
+                    new StatusIconResource(R.drawable.ic_search, 0));
+        });
+        onView(withId(R.id.location_bar_status_icon)).check((view, e) -> {
+            assertEquals(View.VISIBLE, view.getVisibility());
+        });
+
+        // Verify that the incognito badge is not inflated by default.
+        assertFalse(mStatusModel.get(StatusProperties.INCOGNITO_BADGE_VISIBLE));
+        onView(withId(R.id.location_bar_incognito_badge)).check(doesNotExist());
+
+        // Set incognito badge visible.
+        runOnUiThreadBlocking(
+                () -> { mStatusModel.set(StatusProperties.INCOGNITO_BADGE_VISIBLE, true); });
+        onView(withId(R.id.location_bar_incognito_badge)).check(matches(isCompletelyDisplayed()));
+
+        runOnUiThreadBlocking(
+                () -> { mStatusModel.set(StatusProperties.STATUS_ICON_RESOURCE, null); });
+        onView(withId(R.id.location_bar_status_icon)).check((view, e) -> {
+            assertEquals(View.GONE, view.getVisibility());
+        });
+        onView(withId(R.id.location_bar_status_icon_bg)).check((view, e) -> {
+            assertEquals(View.GONE, view.getVisibility());
+        });
+    }
+
+    @Test
+    @MediumTest
+    @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE)
+    @Feature({"Omnibox"})
     public void testSearchEngineLogo_incognito_noMarginEnd() {
         // Set incognito badge visible.
         runOnUiThreadBlocking(
diff --git a/chrome/browser/ui/ash/network/tether_notification_presenter.cc b/chrome/browser/ui/ash/network/tether_notification_presenter.cc
index c5c6398..67265da 100644
--- a/chrome/browser/ui/ash/network/tether_notification_presenter.cc
+++ b/chrome/browser/ui/ash/network/tether_notification_presenter.cc
@@ -90,7 +90,7 @@
   return gfx::CanvasImageSource::MakeImageSkia<
       network_icon::SignalStrengthImageSource>(
       network_icon::BARS, gfx::kGoogleBlue500, kTetherSignalIconSize,
-      normalized_signal_strength);
+      normalized_signal_strength, 5);
 }
 
 }  // namespace
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index 756168ec..88572ad 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -1076,15 +1076,6 @@
 }
 
 bool Browser::ShouldDisplayFavicon(content::WebContents* web_contents) const {
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-  // Display favicons for the Terminal app.
-  if (base::FeatureList::IsEnabled(chromeos::features::kTerminalMultiProfile) &&
-      app_controller_ && app_controller_->system_app() &&
-      app_controller_->app_id() == guest_os::kTerminalSystemAppId) {
-    return true;
-  }
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
-
   // Remove for all other tabbed web apps.
   if (app_controller_ && app_controller_->has_tab_strip())
     return false;
diff --git a/chrome/browser/ui/views/web_apps/web_app_detailed_install_dialog.cc b/chrome/browser/ui/views/web_apps/web_app_detailed_install_dialog.cc
index 7e7b123..50a45d4 100644
--- a/chrome/browser/ui/views/web_apps/web_app_detailed_install_dialog.cc
+++ b/chrome/browser/ui/views/web_apps/web_app_detailed_install_dialog.cc
@@ -124,8 +124,6 @@
         },
         this));
 
-    SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY);
-
     ink_drop_container_ =
         AddChildView(std::make_unique<views::InkDropContainerView>());
   }
diff --git a/chrome/browser/ui/webui/history_clusters/history_clusters_handler.cc b/chrome/browser/ui/webui/history_clusters/history_clusters_handler.cc
index 1002edd..d6b72e9 100644
--- a/chrome/browser/ui/webui/history_clusters/history_clusters_handler.cc
+++ b/chrome/browser/ui/webui/history_clusters/history_clusters_handler.cc
@@ -11,6 +11,7 @@
 #include "base/bind.h"
 #include "base/containers/contains.h"
 #include "base/feature_list.h"
+#include "base/functional/bind.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
@@ -18,6 +19,7 @@
 #include "base/time/time_to_iso8601.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/history/history_service_factory.h"
+#include "chrome/browser/history_clusters/history_clusters_image_fetcher.h"
 #include "chrome/browser/history_clusters/history_clusters_metrics_logger.h"
 #include "chrome/browser/history_clusters/history_clusters_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
@@ -307,6 +309,10 @@
       SyncServiceFactory::GetForProfile(profile_);
   browsing_history_service_ = std::make_unique<history::BrowsingHistoryService>(
       this, local_history, sync_service);
+
+  if (GetConfig().images) {
+    image_fetcher_ = std::make_unique<HistoryClustersImageFetcher>(profile);
+  }
 }
 
 HistoryClustersHandler::~HistoryClustersHandler() = default;
@@ -387,9 +393,8 @@
   if (query_clusters_state_) {
     DCHECK_EQ(query, query_clusters_state_->query());
     query_clusters_state_->LoadNextBatchOfClusters(
-        base::BindOnce(&QueryClustersResultToMojom, profile_)
-            .Then(base::BindOnce(&HistoryClustersHandler::OnClustersQueryResult,
-                                 weak_ptr_factory_.GetWeakPtr())));
+        base::BindOnce(&HistoryClustersHandler::OnGotClustersBatch,
+                       weak_ptr_factory_.GetWeakPtr()));
   }
 }
 
@@ -503,8 +508,37 @@
   return profile_;
 }
 
-void HistoryClustersHandler::OnClustersQueryResult(
-    mojom::QueryResultPtr query_result) {
+void HistoryClustersHandler::OnGotClustersBatch(
+    const std::string& query,
+    const std::vector<history::Cluster> clusters_batch,
+    bool can_load_more,
+    bool is_continuation) {
+  // Kick off a bunch of image fetch requests if this feature is enabled.
+  if (image_fetcher_) {
+    DCHECK(GetConfig().images);
+
+    for (size_t i = 0; i < clusters_batch.size(); ++i) {
+      size_t cluster_index =
+          query_clusters_state_->number_clusters_sent_to_page() + i;
+
+      // TODO(tommycli): We should really filter this to only request it for
+      // Search-labelled clusters.
+      auto& cluster = clusters_batch[i];
+      if (!cluster.raw_label || cluster.raw_label->empty())
+        continue;
+
+      // TODO(tommycli): Populate this with the actual entity ID once available.
+      std::string entity_id;
+      image_fetcher_->FetchImageFor(
+          *cluster.raw_label, entity_id,
+          base::BindOnce(&HistoryClustersHandler::OnImageFetchedForCluster,
+                         weak_ptr_factory_.GetWeakPtr(), cluster_index));
+    }
+  }
+
+  auto query_result =
+      QueryClustersResultToMojom(profile_, query, std::move(clusters_batch),
+                                 can_load_more, is_continuation);
   page_->OnClustersQueryResult(std::move(query_result));
 
   // The user loading their first set of clusters should start the timer for
@@ -512,6 +546,13 @@
   LaunchJourneysSurvey();
 }
 
+void HistoryClustersHandler::OnImageFetchedForCluster(size_t cluster_index,
+                                                      const GURL& image_url) {
+  if (!image_url.is_valid())
+    return;
+  page_->OnClusterImageUpdated(cluster_index, image_url);
+}
+
 void HistoryClustersHandler::LaunchJourneysSurvey() {
   // All the below is to attempt launch a survey, after loading the first set of
   // clusters.
diff --git a/chrome/browser/ui/webui/history_clusters/history_clusters_handler.h b/chrome/browser/ui/webui/history_clusters/history_clusters_handler.h
index 3a94997b..62cbae3f 100644
--- a/chrome/browser/ui/webui/history_clusters/history_clusters_handler.h
+++ b/chrome/browser/ui/webui/history_clusters/history_clusters_handler.h
@@ -13,6 +13,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/scoped_observation.h"
 #include "chrome/browser/history/profile_based_browsing_history_driver.h"
+#include "chrome/browser/history_clusters/history_clusters_image_fetcher.h"
 #include "components/history/core/browser/browsing_history_service.h"
 #include "components/history/core/browser/history_types.h"
 #include "components/history_clusters/core/history_clusters_service.h"
@@ -99,9 +100,15 @@
   Profile* GetProfile() override;
 
  private:
-  // Called with the result of querying clusters. Subsequently, `query_result`
+  // Called with the result of querying clusters. Subsequently, the result is
   // is sent to the JS to update the UI.
-  void OnClustersQueryResult(mojom::QueryResultPtr query_result);
+  void OnGotClustersBatch(const std::string& query,
+                          const std::vector<history::Cluster> clusters_batch,
+                          bool can_load_more,
+                          bool is_continuation);
+
+  // Callback for images fetched for clusters.
+  void OnImageFetchedForCluster(size_t cluster_index, const GURL& image_url);
 
   // Launches the Journeys survey, if user is eligible.
   void LaunchJourneysSurvey();
@@ -146,6 +153,9 @@
   // also empty, and that's okay and desirable.
   std::string last_query_issued_;
 
+  // Used to fetch relevant images for clusters.
+  std::unique_ptr<HistoryClustersImageFetcher> image_fetcher_;
+
   base::WeakPtrFactory<HistoryClustersHandler> weak_ptr_factory_{this};
 };
 
diff --git a/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc b/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc
index 3150e4b..c1241d5 100644
--- a/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc
+++ b/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc
@@ -271,6 +271,7 @@
       {"details", IDS_NEW_TAB_VOICE_DETAILS},
       {"languageError", IDS_NEW_TAB_VOICE_LANGUAGE_ERROR},
       {"learnMore", IDS_LEARN_MORE},
+      {"learnMoreA11yLabel", IDS_NEW_TAB_VOICE_LEARN_MORE_ACCESSIBILITY_LABEL},
       {"listening", IDS_NEW_TAB_VOICE_LISTENING},
       {"networkError", IDS_NEW_TAB_VOICE_NETWORK_ERROR},
       {"noTranslation", IDS_NEW_TAB_VOICE_NO_TRANSLATION},
diff --git a/chrome/browser/ui/webui/realbox/realbox_handler.cc b/chrome/browser/ui/webui/realbox/realbox_handler.cc
index b98a5e31..4eadbb54 100644
--- a/chrome/browser/ui/webui/realbox/realbox_handler.cc
+++ b/chrome/browser/ui/webui/realbox/realbox_handler.cc
@@ -4,6 +4,8 @@
 
 #include "chrome/browser/ui/webui/realbox/realbox_handler.h"
 
+#include "base/base64.h"
+#include "base/base64url.h"
 #include "base/bind.h"
 #include "base/containers/contains.h"
 #include "base/metrics/histogram_macros.h"
@@ -53,9 +55,11 @@
 #include "components/search_engines/template_url_service.h"
 #include "components/sessions/content/session_tab_helper.h"
 #include "components/strings/grit/components_strings.h"
+#include "components/variations/variations_client.h"
 #include "components/vector_icons/vector_icons.h"
 #include "content/public/browser/web_ui_data_source.h"
 #include "net/cookies/cookie_util.h"
+#include "realbox_handler.h"
 #include "third_party/metrics_proto/omnibox_focus_type.pb.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/webui/resource_path.h"
@@ -284,6 +288,30 @@
       CreateAutocompleteMatches(result, bookmark_model));
 }
 
+std::string GetBase64UrlVariations(Profile* profile) {
+  variations::VariationsClient* provider = profile->GetVariationsClient();
+
+  variations::mojom::VariationsHeadersPtr headers =
+      provider->GetVariationsHeaders();
+  if (headers.is_null()) {
+    return std::string();
+  }
+  const std::string variations_base64 = headers->headers_map.at(
+      variations::mojom::GoogleWebVisibility::FIRST_PARTY);
+
+  // Variations headers are base64 encoded, however, we're attaching the value
+  // to a URL query parameter so they need to be base64url encoded.
+  std::string variations_decoded;
+  base::Base64Decode(variations_base64, &variations_decoded);
+
+  std::string variations_base64url;
+  base::Base64UrlEncode(variations_decoded,
+                        base::Base64UrlEncodePolicy::OMIT_PADDING,
+                        &variations_base64url);
+
+  return variations_base64url;
+}
+
 }  // namespace
 
 // static
@@ -323,6 +351,7 @@
       "realboxLensSearch",
       base::FeatureList::IsEnabled(ntp_features::kNtpRealboxLensSearch) &&
           profile->GetPrefs()->GetBoolean(prefs::kLensDesktopNTPSearchEnabled));
+  source->AddString("realboxLensVariations", GetBase64UrlVariations(profile));
 }
 
 // static
diff --git a/chrome/browser/ui/webui/realbox/realbox_handler_unittest.cc b/chrome/browser/ui/webui/realbox/realbox_handler_unittest.cc
new file mode 100644
index 0000000..e263178
--- /dev/null
+++ b/chrome/browser/ui/webui/realbox/realbox_handler_unittest.cc
@@ -0,0 +1,79 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "realbox_handler.h"
+
+#include "base/test/scoped_feature_list.h"
+#include "chrome/test/base/testing_profile.h"
+#include "components/search/ntp_features.h"
+#include "components/variations/scoped_variations_ids_provider.h"
+#include "components/variations/variations_ids_provider.h"
+#include "content/public/test/browser_task_environment.h"
+#include "content/public/test/test_web_ui_data_source.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+class RealboxHandlerTest : public ::testing::Test {
+ public:
+  RealboxHandlerTest() = default;
+
+  RealboxHandlerTest(const RealboxHandlerTest&) = delete;
+  RealboxHandlerTest& operator=(const RealboxHandlerTest&) = delete;
+  ~RealboxHandlerTest() override = default;
+
+  content::TestWebUIDataSource* source() { return source_.get(); }
+  TestingProfile* profile() { return profile_.get(); }
+
+ private:
+  content::BrowserTaskEnvironment task_environment_;
+  std::unique_ptr<content::TestWebUIDataSource> source_;
+  std::unique_ptr<TestingProfile> profile_;
+  variations::ScopedVariationsIdsProvider scoped_variations_ids_provider_{
+      variations::VariationsIdsProvider::Mode::kUseSignedInState};
+
+  void SetUp() override {
+    source_ = content::TestWebUIDataSource::Create("test-data-source");
+
+    TestingProfile::Builder profile_builder;
+    profile_ = profile_builder.Build();
+
+    ASSERT_EQ(
+        variations::VariationsIdsProvider::ForceIdsResult::SUCCESS,
+        variations::VariationsIdsProvider::GetInstance()->ForceVariationIds(
+            /*variation_ids=*/{"100"}, /*command_line_variation_ids=*/""));
+  }
+};
+
+TEST_F(RealboxHandlerTest, RealboxLensSearchIsFalseWhenDisabled) {
+  base::test::ScopedFeatureList scoped_feature_list_;
+  scoped_feature_list_.InitWithFeaturesAndParameters(
+      /*enabled_features=*/{},
+      /*disabled_features=*/{ntp_features::kNtpRealboxLensSearch});
+
+  RealboxHandler::SetupWebUIDataSource(source()->GetWebUIDataSource(),
+                                       profile());
+
+  EXPECT_FALSE(
+      source()->GetLocalizedStrings()->FindBool("realboxLensSearch").value());
+}
+
+TEST_F(RealboxHandlerTest, RealboxLensSearchIsTrueWhenEnabled) {
+  base::test::ScopedFeatureList scoped_feature_list_;
+  scoped_feature_list_.InitWithFeaturesAndParameters(
+      /*enabled_features=*/{{ntp_features::kNtpRealboxLensSearch, {{}}}},
+      /*disabled_features=*/{});
+
+  RealboxHandler::SetupWebUIDataSource(source()->GetWebUIDataSource(),
+                                       profile());
+
+  EXPECT_TRUE(
+      source()->GetLocalizedStrings()->FindBool("realboxLensSearch").value());
+}
+
+TEST_F(RealboxHandlerTest, RealboxLensVariationsContainsVariations) {
+  RealboxHandler::SetupWebUIDataSource(source()->GetWebUIDataSource(),
+                                       profile());
+
+  EXPECT_EQ("CGQ", *source()->GetLocalizedStrings()->FindString(
+                       "realboxLensVariations"));
+}
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index 51d6185..64f5e7be 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-main-1667303747-59fad421c328617ec0ce7aa90a9890772dd537f4.profdata
+chrome-linux-main-1667325602-24baf7d9c4a7f692605b6379030d642525a7b5e0.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index 5f997ae..fc35bede 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-main-1667303747-0382897567d2532d1d06faa5b42a228866e076c1.profdata
+chrome-mac-main-1667325602-8ad8a54bc896cded135836622d2ebae681727c57.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index ec66532..d1867f6 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1667314645-4ab448ff0ceee7e470574eb88603e0863606684e.profdata
+chrome-win32-main-1667325482-84ea94c1acd59453f32718a11150886e2df3f125.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 79a80f11..0416b5cc 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1667314645-d086e5bdb062721f30f0176adb953e61d398384e.profdata
+chrome-win64-main-1667325482-740e85a882ee64b2166fc4a2b4daed7b0302e5e9.profdata
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
index 90ba252..67d4bcf0 100644
--- a/chrome/common/chrome_features.cc
+++ b/chrome/common/chrome_features.cc
@@ -99,7 +99,8 @@
 // Enables the built-in DNS resolver.
 BASE_FEATURE(kAsyncDns,
              "AsyncDns",
-#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_ANDROID)
+#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_ANDROID) || \
+    BUILDFLAG(IS_WIN)
              base::FEATURE_ENABLED_BY_DEFAULT
 #else
              base::FEATURE_DISABLED_BY_DEFAULT
diff --git a/chrome/services/speech/buildflags/BUILD.gn b/chrome/services/speech/buildflags/BUILD.gn
index b3dab6f..2cf7a2e 100644
--- a/chrome/services/speech/buildflags/BUILD.gn
+++ b/chrome/services/speech/buildflags/BUILD.gn
@@ -13,5 +13,6 @@
   flags = [
     "ENABLE_SPEECH_SERVICE=$enable_speech_service",
     "ENABLE_BROWSER_SPEECH_SERVICE=$enable_browser_speech_service",
+    "ENABLE_SERVER_BASED_RECOGNITION_RECOGNIZER=$enable_server_based_recognition",
   ]
 }
diff --git a/chrome/services/speech/buildflags/buildflags.gni b/chrome/services/speech/buildflags/buildflags.gni
index a3918ea3..1ee3735 100644
--- a/chrome/services/speech/buildflags/buildflags.gni
+++ b/chrome/services/speech/buildflags/buildflags.gni
@@ -2,6 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import("//build/config/chrome_build.gni")
 import("//build/config/chromeos/ui_mode.gni")
 
 declare_args() {
@@ -21,6 +22,10 @@
   # * not implemented, and corresponding features don't exist as part of Chrome
   #   (e.g. Android, where Live Caption is instead a system feature).
   enable_browser_speech_service = enable_speech_service && !is_chromeos
+
+  # Whether the server based speech recognition recognizer is available.
+  # Currently only available in official builds for ash ChromeOS.
+  enable_server_based_recognition = is_chromeos_ash && is_chrome_branded
 }
 
 assert(enable_speech_service || !enable_browser_speech_service)
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index d32d0c1..c386988 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -6111,6 +6111,10 @@
     "//v8",
   ]
 
+  if (enable_server_based_recognition) {
+    deps += [ "//chrome/services/speech/internal:unit_tests" ]
+  }
+
   public_deps = []
 
   if (is_win) {
@@ -6952,6 +6956,7 @@
       "../browser/ui/webui/metrics_reporter/mock_metrics_reporter.h",
       "../browser/ui/webui/new_tab_page/new_tab_page_handler_unittest.cc",
       "../browser/ui/webui/privacy_sandbox/privacy_sandbox_dialog_handler_unittest.cc",
+      "../browser/ui/webui/realbox/realbox_handler_unittest.cc",
       "../browser/ui/webui/sanitized_image_source_unittest.cc",
       "../browser/ui/webui/settings/downloads_handler_unittest.cc",
       "../browser/ui/webui/settings/hats_handler_unittest.cc",
diff --git a/chrome/test/base/browser_with_test_window_test.h b/chrome/test/base/browser_with_test_window_test.h
index 8638e51..7916f19 100644
--- a/chrome/test/base/browser_with_test_window_test.h
+++ b/chrome/test/base/browser_with_test_window_test.h
@@ -14,6 +14,8 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/test/base/test_browser_window.h"
 #include "chrome/test/base/testing_profile.h"
+#include "components/variations/scoped_variations_ids_provider.h"
+#include "components/variations/variations_client.h"
 #include "content/public/test/browser_task_environment.h"
 #include "content/public/test/test_renderer_host.h"
 #include "services/network/test/test_url_loader_factory.h"
@@ -271,6 +273,10 @@
 
   // Whether the browser is part of a hosted app.
   const bool hosted_app_;
+
+  // Initialize the variations provider.
+  variations::ScopedVariationsIdsProvider scoped_variations_ids_provider_{
+      variations::VariationsIdsProvider::Mode::kUseSignedInState};
 };
 
 #endif  // CHROME_TEST_BASE_BROWSER_WITH_TEST_WINDOW_TEST_H_
diff --git a/chrome/test/data/webui/chromeos/os_feedback_ui/file_attachment_test.js b/chrome/test/data/webui/chromeos/os_feedback_ui/file_attachment_test.js
index 89d89ff..393b192 100644
--- a/chrome/test/data/webui/chromeos/os_feedback_ui/file_attachment_test.js
+++ b/chrome/test/data/webui/chromeos/os_feedback_ui/file_attachment_test.js
@@ -87,7 +87,7 @@
     // Verify the i18n string is added.
     assertTrue(page.i18nExists('addFileLabel'));
     // Verify the replace file label is in the page.
-    assertEquals('Replace', getElementContent('#replaceFileButton'));
+    assertEquals('Replace file', getElementContent('#replaceFileButton'));
     // The addFileContainer should be visible when no file is selected.
     assertTrue(isVisible(getElement('#addFileContainer')));
     // The replaceFileContainer should be invisible when no file is selected.
@@ -175,7 +175,7 @@
     // The aria label of the replace file button is set.
     assertEquals('Replace file', getElement('#replaceFileButton').ariaLabel);
     // Verify the i18n string is added.
-    assertTrue(page.i18nExists('replaceFileArialLabel'));
+    assertTrue(page.i18nExists('replaceFileLabel'));
     // Verify the image container is not visible for non-image files.
     const selectedImageButton = getElement('#selectedImageButton');
     assertFalse(isVisible(selectedImageButton));
diff --git a/chrome/test/data/webui/new_tab_page/lens_form_test.ts b/chrome/test/data/webui/new_tab_page/lens_form_test.ts
index 0b90e9ba..d041a3a 100644
--- a/chrome/test/data/webui/new_tab_page/lens_form_test.ts
+++ b/chrome/test/data/webui/new_tab_page/lens_form_test.ts
@@ -6,7 +6,7 @@
 import 'chrome://new-tab-page/new_tab_page.js';
 
 import {LensErrorType, LensFormElement, LensSubmitType} from 'chrome://new-tab-page/lazy_load.js';
-import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
+import {assertEquals, assertFalse, assertGT, assertTrue} from 'chrome://webui-test/chai_assert.js';
 
 suite('LensFormTest', () => {
   let lensForm: LensFormElement;
@@ -146,6 +146,22 @@
     assertEquals('1001', st);
   });
 
+  test(
+      'submit url should set client data param to a non-empty value',
+      async () => {
+        // Arrange.
+        const file = new File([], 'file-name.png', {type: 'image/png'});
+
+        // Act.
+        dispatchFileInputChange(file);
+
+        // Assert.
+        const action = new URL(lensForm.$.fileForm.action);
+        const cd = action.searchParams.get('cd');
+        assertGT(cd?.length ?? 0, 0);
+      });
+
+
   test('submit url with valid http should submit', async () => {
     // Arrange.
     const url = 'http://www.example.com/dog.jpg';
@@ -261,6 +277,17 @@
     assertEquals('1001', input.value);
   });
 
+  test(
+      'submit url should set client data param to a non-empty value',
+      async () => {
+        // Arrange.
+        const input =
+            lensForm.$.urlForm.children.namedItem('cd') as HTMLInputElement;
+
+        // Assert.
+        assertGT(input.value.length, 0);
+      });
+
   function dispatchFileInputChangeWithDataTransfer(dataTransfer: DataTransfer) {
     lensForm.$.fileInput.files = dataTransfer.files;
     lensForm.$.fileInput.dispatchEvent(new Event('change'));
diff --git a/chrome/test/data/webui/settings/chromeos/audio_and_captions_page_tests.js b/chrome/test/data/webui/settings/chromeos/audio_and_captions_page_tests.js
new file mode 100644
index 0000000..3a4a6d2
--- /dev/null
+++ b/chrome/test/data/webui/settings/chromeos/audio_and_captions_page_tests.js
@@ -0,0 +1,47 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'chrome://os-settings/chromeos/lazy_load.js';
+
+import {DevicePageBrowserProxy, DevicePageBrowserProxyImpl, Router, routes} from 'chrome://os-settings/chromeos/os_settings.js';
+import {webUIListenerCallback} from 'chrome://resources/js/cr.m.js';
+import {getDeepActiveElement} from 'chrome://resources/js/util.js';
+import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {waitAfterNextRender, waitBeforeNextRender} from 'chrome://webui-test/polymer_test_util.js';
+import {eventToPromise, isVisible} from 'chrome://webui-test/test_util.js';
+
+import {assertEquals, assertFalse, assertTrue} from '../../chai_assert.js';
+
+suite('AudioAndCaptionsPageTests', function() {
+  let page = null;
+
+  function initPage() {
+    page = document.createElement('settings-audio-and-captions-page');
+    document.body.appendChild(page);
+  }
+
+  setup(function() {
+    PolymerTest.clearBody();
+    Router.getInstance().navigateTo(routes.A11Y_AUDIO_AND_CAPTIONS);
+  });
+
+  teardown(function() {
+    if (page) {
+      page.remove();
+    }
+    Router.getInstance().resetRouteForTesting();
+  });
+
+  test('no subpages are available in kiosk mode', function() {
+    loadTimeData.overrideValues({
+      isKioskModeActive: true,
+      showTabletModeShelfNavigationButtonsSettings: true,
+    });
+    initPage();
+    flush();
+
+    const subpageLinks = page.root.querySelectorAll('cr-link-row');
+    subpageLinks.forEach(subpageLink => assertFalse(isVisible(subpageLink)));
+  });
+});
diff --git a/chrome/test/data/webui/settings/chromeos/keyboard_and_text_input_page_tests.js b/chrome/test/data/webui/settings/chromeos/keyboard_and_text_input_page_tests.js
index 1c64903a..6748c92 100644
--- a/chrome/test/data/webui/settings/chromeos/keyboard_and_text_input_page_tests.js
+++ b/chrome/test/data/webui/settings/chromeos/keyboard_and_text_input_page_tests.js
@@ -172,6 +172,39 @@
         page.computeDictationLocaleSubtitle_());
   });
 
+  test('some parts are hidden in kiosk mode', function() {
+    loadTimeData.overrideValues({
+      isKioskModeActive: true,
+      showTabletModeShelfNavigationButtonsSettings: true,
+    });
+    initPage();
+    flush();
+
+    const subpageLinks = page.root.querySelectorAll('cr-link-row');
+    subpageLinks.forEach(subpageLink => assertFalse(isVisible(subpageLink)));
+  });
+
+  test('Deep link to switch access', async () => {
+    loadTimeData.overrideValues({
+      isKioskModeActive: false,
+    });
+    initPage();
+
+    const params = new URLSearchParams();
+    params.append('settingId', '1522');
+    Router.getInstance().navigateTo(
+        routes.A11Y_KEYBOARD_AND_TEXT_INPUT, params);
+
+    flush();
+
+    const deepLinkElement = page.shadowRoot.querySelector('#enableSwitchAccess')
+                                .shadowRoot.querySelector('cr-toggle');
+    await waitAfterNextRender(deepLinkElement);
+    assertEquals(
+        deepLinkElement, getDeepActiveElement(),
+        'Switch access toggle should be focused for settingId=1522.');
+  });
+
   const selectorRouteList = [
     {selector: '#keyboardSubpageButton', route: routes.KEYBOARD},
   ];
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js
index 832d09f..d32a6b1 100644
--- a/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js
+++ b/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js
@@ -338,6 +338,11 @@
  ],
  ['AppManagementToggleRow', 'app_management/toggle_row_test.js'],
  ['AppManagementUninstallButton', 'app_management/uninstall_button_test.js'],
+ [
+   'AudioAndCaptionsPage',
+   'audio_and_captions_page_tests.js',
+   {enabled: ['features::kAccessibilityOSSettingsVisibility']},
+ ],
  ['CellularNetworksList', 'cellular_networks_list_test.js'],
  ['CellularRoamingToggleButton', 'cellular_roaming_toggle_button_test.js'],
  ['CellularSetupDialog', 'cellular_setup_dialog_test.js'],
diff --git a/chrome/test/data/webui/settings/chromeos/text_to_speech_page_tests.js b/chrome/test/data/webui/settings/chromeos/text_to_speech_page_tests.js
index 81d6fda..b275b25 100644
--- a/chrome/test/data/webui/settings/chromeos/text_to_speech_page_tests.js
+++ b/chrome/test/data/webui/settings/chromeos/text_to_speech_page_tests.js
@@ -76,4 +76,26 @@
               `${selector} should be focused`);
         });
   });
+
+  test('only allowed subpages are available in kiosk mode', function() {
+    loadTimeData.overrideValues({
+      isKioskModeActive: true,
+      showTabletModeShelfNavigationButtonsSettings: true,
+    });
+    initPage();
+    flush();
+
+    const allowed_subpages = [
+      'chromeVoxSubpageButton',
+      'selectToSpeakSubpageButton',
+      'ttsSubpageButton',
+    ];
+
+    const subpages = page.root.querySelectorAll('cr-link-row');
+    subpages.forEach(function(subpage) {
+      if (isVisible(subpage)) {
+        assertTrue(allowed_subpages.includes(subpage.id));
+      }
+    });
+  });
 });
diff --git a/chrome/test/data/webui/settings/passwords_device_section_test.ts b/chrome/test/data/webui/settings/passwords_device_section_test.ts
index 5d397e28..b0ddebd 100644
--- a/chrome/test/data/webui/settings/passwords_device_section_test.ts
+++ b/chrome/test/data/webui/settings/passwords_device_section_test.ts
@@ -11,6 +11,7 @@
 import {IronListElement, PasswordMoveToAccountDialogElement, PasswordsDeviceSectionElement} from 'chrome://settings/lazy_load.js';
 import {PasswordManagerImpl, Router, routes, StatusAction, SyncBrowserProxyImpl} from 'chrome://settings/settings.js';
 import {assertDeepEquals, assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
+import {flushTasks} from 'chrome://webui-test/polymer_test_util.js';
 import {eventToPromise, isVisible} from 'chrome://webui-test/test_util.js';
 
 import {createPasswordEntry, PasswordDeviceSectionElementFactory} from './passwords_and_autofill_fake_data.js';
@@ -39,6 +40,9 @@
   await syncBrowserProxy.whenCalled('getSyncStatus');
   await syncBrowserProxy.whenCalled('getStoredAccounts');
   await passwordManager.whenCalled('isOptedInForAccountStorage');
+  await passwordManager.whenCalled('getSavedPasswordList');
+
+  await flushTasks();
 
   return passwordsDeviceSection;
 }
diff --git a/chrome/test/data/webui/settings/passwords_section_test.ts b/chrome/test/data/webui/settings/passwords_section_test.ts
index 52c93c5..9c2062a6 100644
--- a/chrome/test/data/webui/settings/passwords_section_test.ts
+++ b/chrome/test/data/webui/settings/passwords_section_test.ts
@@ -133,8 +133,8 @@
   ];
   passwordManager.setPlaintextPassword(PASSWORD);
 
-  const passwordsSection =
-      elementFactory.createPasswordsSection(passwordManager, passwordList, []);
+  const passwordsSection = await createPasswordsSection(
+      elementFactory, passwordManager, passwordList, []);
 
   const passwordListItem = getFirstPasswordListItem(passwordsSection);
   passwordListItem.shadowRoot!
@@ -225,6 +225,23 @@
   flush();
 }
 
+/**
+ * Helper function which creates a password section with the given lists and
+ * waits for queued tasks to finish.
+ */
+async function createPasswordsSection(
+    elementFactory: PasswordSectionElementFactory,
+    passwordManager: TestPasswordManagerProxy,
+    passwordList: chrome.passwordsPrivate.PasswordUiEntry[],
+    exceptionList: chrome.passwordsPrivate.ExceptionEntry[]):
+    Promise<PasswordsSectionElement> {
+  const passwordsSection = elementFactory.createPasswordsSection(
+      passwordManager, passwordList, exceptionList);
+  await passwordManager.whenCalled('getSavedPasswordList');
+  await flushTasks();
+  return passwordsSection;
+}
+
 // TODO(crbug.com/1260310): Split into multiple test suits.
 suite('PasswordsSection', function() {
   let passwordManager: TestPasswordManagerProxy;
@@ -271,28 +288,34 @@
   });
 
   if (isMac || isWindows) {
-    test('testBiometricAuthenticationForFillingToggleVisibility', function() {
-      loadTimeData.overrideValues({biometricAuthenticationForFilling: false});
-      const passwordsSectionBiometricForFillingDisabled =
-          elementFactory.createPasswordsSection(passwordManager, [], []);
-      assertFalse(
-          isVisible(passwordsSectionBiometricForFillingDisabled.shadowRoot!
-                        .querySelector<HTMLElement>(
-                            '#biometricAuthenticationForFillingToggle')));
+    test(
+        'testBiometricAuthenticationForFillingToggleVisibility',
+        async function() {
+          loadTimeData.overrideValues(
+              {biometricAuthenticationForFilling: false});
+          const passwordsSectionBiometricForFillingDisabled =
+              await createPasswordsSection(
+                  elementFactory, passwordManager, [], []);
+          assertFalse(
+              isVisible(passwordsSectionBiometricForFillingDisabled.shadowRoot!
+                            .querySelector<HTMLElement>(
+                                '#biometricAuthenticationForFillingToggle')));
 
-      loadTimeData.overrideValues({biometricAuthenticationForFilling: true});
-      const passwordsSectionBiometricForFillingEnabled =
-          elementFactory.createPasswordsSection(passwordManager, [], []);
-      assertTrue(
-          isVisible(passwordsSectionBiometricForFillingEnabled.shadowRoot!
-                        .querySelector<HTMLElement>(
-                            '#biometricAuthenticationForFillingToggle')));
-    });
+          loadTimeData.overrideValues(
+              {biometricAuthenticationForFilling: true});
+          const passwordsSectionBiometricForFillingEnabled =
+              await createPasswordsSection(
+                  elementFactory, passwordManager, [], []);
+          assertTrue(
+              isVisible(passwordsSectionBiometricForFillingEnabled.shadowRoot!
+                            .querySelector<HTMLElement>(
+                                '#biometricAuthenticationForFillingToggle')));
+        });
 
-    test('testNoSwitchBiometricAuthBeforeFillingToggle', function() {
+    test('testNoSwitchBiometricAuthBeforeFillingToggle', async function() {
       loadTimeData.overrideValues({biometricAuthenticationForFilling: true});
       const passwordsSection =
-          elementFactory.createPasswordsSection(passwordManager, [], []);
+          await createPasswordsSection(elementFactory, passwordManager, [], []);
       const biometricAuthenticationForFillingToggle =
           passwordsSection.shadowRoot!
               .querySelector<SettingsToggleButtonElement>(
@@ -305,10 +328,10 @@
       assertEquals(initialState, afterClickState);
     });
 
-    test('testSwitchBiometricAuthBeforeFillingToggle', function() {
+    test('testSwitchBiometricAuthBeforeFillingToggle', async function() {
       loadTimeData.overrideValues({biometricAuthenticationForFilling: true});
       const passwordsSection =
-          elementFactory.createPasswordsSection(passwordManager, [], []);
+          await createPasswordsSection(elementFactory, passwordManager, [], []);
       passwordsSection.set(
           'prefs.password_manager.biometric_authentication_filling.value',
           false);
@@ -329,9 +352,9 @@
     });
   }
 
-  test('verifyNoSavedPasswords', function() {
+  test('verifyNoSavedPasswords', async function() {
     const passwordsSection =
-        elementFactory.createPasswordsSection(passwordManager, [], []);
+        await createPasswordsSection(elementFactory, passwordManager, [], []);
 
     validatePasswordList(passwordsSection, []);
 
@@ -339,7 +362,7 @@
     assertTrue(passwordsSection.$.savedPasswordsHeaders.hidden);
   });
 
-  test('verifySavedPasswordEntries', function() {
+  test('verifySavedPasswordEntries', async function() {
     const passwordList = [
       createPasswordEntry({url: 'site1.com', username: 'luigi', id: 0}),
       createPasswordEntry({url: 'longwebsite.com', username: 'peach', id: 1}),
@@ -349,8 +372,8 @@
       createPasswordEntry({url: 'site2.com', username: 'luigi', id: 5}),
     ];
 
-    const passwordsSection = elementFactory.createPasswordsSection(
-        passwordManager, passwordList, []);
+    const passwordsSection = await createPasswordsSection(
+        elementFactory, passwordManager, passwordList, []);
 
     // Assert that the data is passed into the iron list. If this fails,
     // then other expectations will also fail.
@@ -363,7 +386,7 @@
   });
 
   // Test verifies that removing a password will update the elements.
-  test('verifyPasswordListRemove', function() {
+  test('verifyPasswordListRemove', async function() {
     const passwordList = [
       createPasswordEntry(
           {url: 'anotherwebsite.com', username: 'luigi', id: 0}),
@@ -371,8 +394,8 @@
       createPasswordEntry({url: 'website.com', username: 'mario', id: 2}),
     ];
 
-    const passwordsSection = elementFactory.createPasswordsSection(
-        passwordManager, passwordList, []);
+    const passwordsSection = await createPasswordsSection(
+        elementFactory, passwordManager, passwordList, []);
 
     validatePasswordList(passwordsSection, passwordList);
     // Simulate 'longwebsite.com' being removed from the list.
@@ -399,8 +422,8 @@
     ];
     passwordManager.setPlaintextPassword(PASSWORD);
 
-    const passwordsSection = elementFactory.createPasswordsSection(
-        passwordManager, passwordList, []);
+    const passwordsSection = await createPasswordsSection(
+        elementFactory, passwordManager, passwordList, []);
 
     const passwordListItems =
         passwordsSection.shadowRoot!.querySelectorAll('password-list-item');
@@ -446,15 +469,15 @@
   });
 
   // Test verifies that adding a password will update the elements.
-  test('verifyPasswordListAdd', function() {
+  test('verifyPasswordListAdd', async function() {
     const passwordList = [
       createPasswordEntry(
           {url: 'anotherwebsite.com', username: 'luigi', id: 0}),
       createPasswordEntry({url: 'longwebsite.com', username: 'peach', id: 1}),
     ];
 
-    const passwordsSection = elementFactory.createPasswordsSection(
-        passwordManager, passwordList, []);
+    const passwordsSection = await createPasswordsSection(
+        elementFactory, passwordManager, passwordList, []);
 
     validatePasswordList(passwordsSection, passwordList);
     // Simulate 'website.com' being added to the list.
@@ -469,9 +492,9 @@
 
   // Test verifies that removing one out of two passwords for the same website
   // will update the elements.
-  test('verifyPasswordListRemoveSameWebsite', function() {
+  test('verifyPasswordListRemoveSameWebsite', async function() {
     const passwordsSection =
-        elementFactory.createPasswordsSection(passwordManager, [], []);
+        await createPasswordsSection(elementFactory, passwordManager, [], []);
 
     // Set-up initial list.
     let passwordList = [
@@ -511,8 +534,8 @@
       createPasswordEntry({url: 'six', username: 'one', id: 5}),
     ];
 
-    const passwordsSection = elementFactory.createPasswordsSection(
-        passwordManager, passwordList, []);
+    const passwordsSection = await createPasswordsSection(
+        elementFactory, passwordManager, passwordList, []);
 
     const firstNode = getFirstPasswordListItem(passwordsSection);
     assertTrue(!!firstNode);
@@ -533,13 +556,13 @@
 
   // Test verifies that 'Copy password' button is hidden for Federated
   // (passwordless) credentials. Does not test Copy button.
-  test('verifyCopyAbsentForFederatedPasswordInMenu', function() {
+  test('verifyCopyAbsentForFederatedPasswordInMenu', async function() {
     const passwordList = [
       createPasswordEntry({federationText: 'with chromium.org'}),
     ];
 
-    const passwordsSection = elementFactory.createPasswordsSection(
-        passwordManager, passwordList, []);
+    const passwordsSection = await createPasswordsSection(
+        elementFactory, passwordManager, passwordList, []);
 
     getFirstPasswordListItem(passwordsSection).$.moreActionsButton.click();
     flush();
@@ -549,12 +572,12 @@
 
   // Test verifies that 'Copy password' button is not hidden for common
   // credentials. Does not test Copy button.
-  test('verifyCopyPresentInMenu', function() {
+  test('verifyCopyPresentInMenu', async function() {
     const passwordList = [
       createPasswordEntry({url: 'one.com', username: 'hey'}),
     ];
-    const passwordsSection = elementFactory.createPasswordsSection(
-        passwordManager, passwordList, []);
+    const passwordsSection = await createPasswordsSection(
+        elementFactory, passwordManager, passwordList, []);
 
     getFirstPasswordListItem(passwordsSection).$.moreActionsButton.click();
     flush();
@@ -564,30 +587,32 @@
 
   // Test verifies that 'Edit' button is replaced to 'Details' for Federated
   // (passwordless) credentials. Does not test Details and Edit button.
-  test('verifyEditReplacedToDetailsForFederatedPasswordInMenu', function() {
-    const passwordList = [
-      createPasswordEntry({federationText: 'with chromium.org'}),
-    ];
-    const passwordsSection = elementFactory.createPasswordsSection(
-        passwordManager, passwordList, []);
+  test(
+      'verifyEditReplacedToDetailsForFederatedPasswordInMenu',
+      async function() {
+        const passwordList = [
+          createPasswordEntry({federationText: 'with chromium.org'}),
+        ];
+        const passwordsSection = await createPasswordsSection(
+            elementFactory, passwordManager, passwordList, []);
 
-    getFirstPasswordListItem(passwordsSection).$.moreActionsButton.click();
-    flush();
-    assertEquals(
-        passwordsSection.i18n('passwordViewDetails'),
-        passwordsSection.$.passwordsListHandler.$.menuEditPassword.textContent!
-            .trim());
-  });
+        getFirstPasswordListItem(passwordsSection).$.moreActionsButton.click();
+        flush();
+        assertEquals(
+            passwordsSection.i18n('passwordViewDetails'),
+            passwordsSection.$.passwordsListHandler.$.menuEditPassword
+                .textContent!.trim());
+      });
 
   // Test verifies that 'Edit' button is replaced to 'Details' for Federated
   // (passwordless) credentials.
   // Does not test Details and Edit button.
-  test('verifyDetailsForFederatedPasswordInMenu', function() {
+  test('verifyDetailsForFederatedPasswordInMenu', async function() {
     const passwordList = [
       createPasswordEntry({federationText: 'with chromium.org'}),
     ];
-    const passwordsSection = elementFactory.createPasswordsSection(
-        passwordManager, passwordList, []);
+    const passwordsSection = await createPasswordsSection(
+        elementFactory, passwordManager, passwordList, []);
 
     getFirstPasswordListItem(passwordsSection).$.moreActionsButton.click();
     flush();
@@ -600,12 +625,12 @@
   // Test verifies that 'Edit' button is shown instead of 'Details' for
   // common credentials.
   // Does not test Details and Edit button.
-  test('verifyEditButtonInMenu', function() {
+  test('verifyEditButtonInMenu', async function() {
     const passwordList = [
       createPasswordEntry({url: 'one.com', username: 'hey'}),
     ];
-    const passwordsSection = elementFactory.createPasswordsSection(
-        passwordManager, passwordList, []);
+    const passwordsSection = await createPasswordsSection(
+        elementFactory, passwordManager, passwordList, []);
 
     getFirstPasswordListItem(passwordsSection).$.moreActionsButton.click();
     flush();
@@ -615,7 +640,7 @@
             .trim());
   });
 
-  test('verifyFilterPasswords', function() {
+  test('verifyFilterPasswords', async function() {
     const passwordList = [
       createPasswordEntry({url: 'one.com', username: 'SHOW', id: 0}),
       createPasswordEntry({url: 'two.com', username: 'shower', id: 1}),
@@ -625,8 +650,8 @@
       createPasswordEntry({url: 'six-show.com', username: 'one', id: 5}),
     ];
 
-    const passwordsSection = elementFactory.createPasswordsSection(
-        passwordManager, passwordList, []);
+    const passwordsSection = await createPasswordsSection(
+        elementFactory, passwordManager, passwordList, []);
     passwordsSection.filter = 'SHow';
     flush();
 
@@ -640,7 +665,7 @@
     validatePasswordList(passwordsSection, expectedList);
   });
 
-  test('verifyFilterPasswordsWithRemoval', function() {
+  test('verifyFilterPasswordsWithRemoval', async function() {
     const passwordList = [
       createPasswordEntry({url: 'one.com', username: 'SHOW', id: 0}),
       createPasswordEntry({url: 'two.com', username: 'shower', id: 1}),
@@ -650,8 +675,8 @@
       createPasswordEntry({url: 'six-show.com', username: 'one', id: 5}),
     ];
 
-    const passwordsSection = elementFactory.createPasswordsSection(
-        passwordManager, passwordList, []);
+    const passwordsSection = await createPasswordsSection(
+        elementFactory, passwordManager, passwordList, []);
     passwordsSection.filter = 'SHow';
     flush();
 
@@ -680,7 +705,7 @@
     validatePasswordList(passwordsSection, expectedList);
   });
 
-  test('verifyFilterPasswordExceptions', function() {
+  test('verifyFilterPasswordExceptions', async function() {
     const exceptionList = [
       createExceptionEntry({url: 'docsshoW.google.com', id: 0}),
       createExceptionEntry({url: 'showmail.com', id: 1}),
@@ -690,8 +715,8 @@
       createExceptionEntry({url: 'plus.google.comshow', id: 5}),
     ];
 
-    const passwordsSection = elementFactory.createPasswordsSection(
-        passwordManager, [], exceptionList);
+    const passwordsSection = await createPasswordsSection(
+        elementFactory, passwordManager, [], exceptionList);
     passwordsSection.filter = 'shOW';
     flush();
 
@@ -707,9 +732,9 @@
         expectedExceptionList);
   });
 
-  test('verifyNoPasswordExceptions', function() {
+  test('verifyNoPasswordExceptions', async function() {
     const passwordsSection =
-        elementFactory.createPasswordsSection(passwordManager, [], []);
+        await createPasswordsSection(elementFactory, passwordManager, [], []);
 
     validateExceptionList(
         getDomRepeatChildren(passwordsSection.$.passwordExceptionsList), []);
@@ -717,7 +742,7 @@
     assertFalse(passwordsSection.$.noExceptionsLabel.hidden);
   });
 
-  test('verifyPasswordExceptions', function() {
+  test('verifyPasswordExceptions', async function() {
     const exceptionList = [
       createExceptionEntry({url: 'docs.google.com', id: 0}),
       createExceptionEntry({url: 'mail.com', id: 1}),
@@ -727,8 +752,8 @@
       createExceptionEntry({url: 'plus.google.com', id: 5}),
     ];
 
-    const passwordsSection = elementFactory.createPasswordsSection(
-        passwordManager, [], exceptionList);
+    const passwordsSection = await createPasswordsSection(
+        elementFactory, passwordManager, [], exceptionList);
 
     validateExceptionList(
         getDomRepeatChildren(passwordsSection.$.passwordExceptionsList),
@@ -738,7 +763,7 @@
   });
 
   // Test verifies that removing an exception will update the elements.
-  test('verifyPasswordExceptionRemove', function() {
+  test('verifyPasswordExceptionRemove', async function() {
     const exceptionList = [
       createExceptionEntry({url: 'docs.google.com', id: 0}),
       createExceptionEntry({url: 'mail.com', id: 1}),
@@ -748,8 +773,8 @@
       createExceptionEntry({url: 'plus.google.com', id: 5}),
     ];
 
-    const passwordsSection = elementFactory.createPasswordsSection(
-        passwordManager, [], exceptionList);
+    const passwordsSection = await createPasswordsSection(
+        elementFactory, passwordManager, [], exceptionList);
 
     validateExceptionList(
         getDomRepeatChildren(passwordsSection.$.passwordExceptionsList),
@@ -776,7 +801,7 @@
 
   // Test verifies that pressing the 'remove' button will trigger a remove
   // event. Does not actually remove any exceptions.
-  test('verifyPasswordExceptionRemoveButton', function() {
+  test('verifyPasswordExceptionRemoveButton', async function() {
     const exceptionList = [
       createExceptionEntry({url: 'docs.google.com', id: 0}),
       createExceptionEntry({url: 'mail.com', id: 1}),
@@ -786,8 +811,8 @@
       createExceptionEntry({url: 'plus.google.com', id: 5}),
     ];
 
-    const passwordsSection = elementFactory.createPasswordsSection(
-        passwordManager, [], exceptionList);
+    const passwordsSection = await createPasswordsSection(
+        elementFactory, passwordManager, [], exceptionList);
 
     const exceptions =
         getDomRepeatChildren(passwordsSection.$.passwordExceptionsList);
@@ -885,8 +910,8 @@
     const USERNAME = 'bart';
     const item = createPasswordEntry({url: URL, username: USERNAME, id: 1});
 
-    const passwordSection =
-        elementFactory.createPasswordsSection(passwordManager, [item], []);
+    const passwordSection = await createPasswordsSection(
+        elementFactory, passwordManager, [item], []);
     const passwordListItem = getFirstPasswordListItem(passwordSection);
 
     assertFalse(
@@ -910,8 +935,8 @@
     const entry = createPasswordEntry({url: 'goo.gl', username: 'bart', id: 1});
     passwordManager.setPlaintextPassword(PASSWORD);
 
-    const passwordSection =
-        elementFactory.createPasswordsSection(passwordManager, [entry], []);
+    const passwordSection = await createPasswordsSection(
+        elementFactory, passwordManager, [entry], []);
 
     getFirstPasswordListItem(passwordSection).$.moreActionsButton.click();
     passwordSection.$.passwordsListHandler.$.menuEditPassword.click();
@@ -952,11 +977,11 @@
     assertEquals('password', passwordListItem.entry.password);
   });
 
-  test('onCopyPasswordListItem', function() {
+  test('onCopyPasswordListItem', async function() {
     const expectedItem =
         createPasswordEntry({url: 'goo.gl', username: 'bart', id: 1});
-    const passwordsSection = elementFactory.createPasswordsSection(
-        passwordManager, [expectedItem], []);
+    const passwordsSection = await createPasswordsSection(
+        elementFactory, passwordManager, [expectedItem], []);
 
     getFirstPasswordListItem(passwordsSection).$.moreActionsButton.click();
     passwordsSection.$.passwordsListHandler.$.menuCopyPassword.click();
@@ -968,11 +993,11 @@
         });
   });
 
-  test('onEditPasswordListItem', function() {
+  test('onEditPasswordListItem', async function() {
     const expectedItem =
         createPasswordEntry({url: 'goo.gl', username: 'bart', id: 1});
-    const passwordsSection = elementFactory.createPasswordsSection(
-        passwordManager, [expectedItem], []);
+    const passwordsSection = await createPasswordsSection(
+        elementFactory, passwordManager, [expectedItem], []);
 
     getFirstPasswordListItem(passwordsSection).$.moreActionsButton.click();
     passwordsSection.$.passwordsListHandler.$.menuEditPassword.click();
@@ -984,11 +1009,11 @@
         });
   });
 
-  test('closingPasswordsSectionHidesUndoToast', function() {
+  test('closingPasswordsSectionHidesUndoToast', async function() {
     const passwordEntry =
         createPasswordEntry({url: 'goo.gl', username: 'bart'});
-    const passwordsSection = elementFactory.createPasswordsSection(
-        passwordManager, [passwordEntry], []);
+    const passwordsSection = await createPasswordsSection(
+        elementFactory, passwordManager, [passwordEntry], []);
     const toastManager = passwordsSection.$.passwordsListHandler.$.removalToast;
 
     // Click the remove button on the first password and assert that an undo
@@ -1006,12 +1031,12 @@
   });
 
   // Chrome offers the export option when there are passwords.
-  test('offerExportWhenPasswords', function() {
+  test('offerExportWhenPasswords', async function() {
     const passwordList = [
       createPasswordEntry({url: 'googoo.com', username: 'Larry'}),
     ];
-    const passwordsSection = elementFactory.createPasswordsSection(
-        passwordManager, passwordList, []);
+    const passwordsSection = await createPasswordsSection(
+        elementFactory, passwordManager, passwordList, []);
 
     validatePasswordList(passwordsSection, passwordList);
     assertFalse(passwordsSection.$.menuExportPassword.hidden);
@@ -1019,10 +1044,10 @@
 
   // Chrome shouldn't offer the option to export passwords if there are no
   // passwords.
-  test('noExportIfNoPasswords', function() {
+  test('noExportIfNoPasswords', async function() {
     const passwordList: chrome.passwordsPrivate.PasswordUiEntry[] = [];
-    const passwordsSection = elementFactory.createPasswordsSection(
-        passwordManager, passwordList, []);
+    const passwordsSection = await createPasswordsSection(
+        elementFactory, passwordManager, passwordList, []);
 
     validatePasswordList(passwordsSection, passwordList);
     assertTrue(passwordsSection.$.menuExportPassword.disabled);
@@ -1030,25 +1055,27 @@
 
   test(
       'importPasswordsButtonShownOnlyWhenPasswordsImportFeatureEnabled',
-      function() {
+      async function() {
         loadTimeData.overrideValues({showImportPasswords: false});
         const passwordsSectionImportPasswordsDisabled =
-            elementFactory.createPasswordsSection(passwordManager, [], []);
+            await createPasswordsSection(
+                elementFactory, passwordManager, [], []);
         assertTrue(
             passwordsSectionImportPasswordsDisabled.shadowRoot!
                 .querySelector<HTMLElement>('#menuImportPassword')!.hidden);
         loadTimeData.overrideValues({showImportPasswords: true});
         const passwordsSectionImportPasswordsEnabled =
-            elementFactory.createPasswordsSection(passwordManager, [], []);
+            await createPasswordsSection(
+                elementFactory, passwordManager, [], []);
         assertFalse(
             passwordsSectionImportPasswordsEnabled.shadowRoot!
                 .querySelector<HTMLElement>('#menuImportPassword')!.hidden);
       });
 
-  test('importButtonOpensPasswordsImportDialog', function() {
+  test('importButtonOpensPasswordsImportDialog', async function() {
     loadTimeData.overrideValues({showImportPasswords: true});
     const passwordsSection =
-        elementFactory.createPasswordsSection(passwordManager, [], []);
+        await createPasswordsSection(elementFactory, passwordManager, [], []);
     assertFalse(!!passwordsSection.shadowRoot!.querySelector<HTMLElement>(
         '#importPasswordsDialog'));
 
@@ -1067,8 +1094,8 @@
     const passwordList = [
       createPasswordEntry({url: 'googoo.com', username: 'Larry'}),
     ];
-    const passwordsSection = elementFactory.createPasswordsSection(
-        passwordManager, passwordList, []);
+    const passwordsSection = await createPasswordsSection(
+        elementFactory, passwordManager, passwordList, []);
 
     passwordsSection.$.menuExportPassword.click();
     // The export dialog calls requestExportProgressStatus() when opening.
@@ -1078,81 +1105,90 @@
   if (!(isChromeOS || isLacros)) {
     // Test verifies that the overflow menu does not offer an option to move a
     // password to the account.
-    test('noMoveToAccountOption', function() {
+    test('noMoveToAccountOption', async function() {
       const passwordsSection =
-          elementFactory.createPasswordsSection(passwordManager, [], []);
+          await createPasswordsSection(elementFactory, passwordManager, [], []);
       assertTrue(passwordsSection.$.passwordsListHandler.$
                      .menuMovePasswordToAccount.hidden);
     });
 
     // Tests that the opt-in/opt-out buttons appear for signed-in (non-sync)
     // users and that the text content changes accordingly.
-    test('changeOptInButtonsBasedOnSignInAndAccountStorageOptIn', function() {
-      const passwordsSection =
-          elementFactory.createPasswordsSection(passwordManager, [], []);
+    test(
+        'changeOptInButtonsBasedOnSignInAndAccountStorageOptIn',
+        async function() {
+          const passwordsSection = await createPasswordsSection(
+              elementFactory, passwordManager, [], []);
 
-      // Sync is disabled and the user is initially signed out.
-      simulateSyncStatus(
-          {signedIn: false, statusAction: StatusAction.NO_ACTION});
-      function isDisplayed(element: HTMLElement): boolean {
-        return !!element && !element.hidden;
-      }
-      assertFalse(
-          isDisplayed(passwordsSection.$.accountStorageButtonsContainer));
+          // Sync is disabled and the user is initially signed out.
+          simulateSyncStatus(
+              {signedIn: false, statusAction: StatusAction.NO_ACTION});
+          function isDisplayed(element: HTMLElement): boolean {
+            return !!element && !element.hidden;
+          }
+          assertFalse(
+              isDisplayed(passwordsSection.$.accountStorageButtonsContainer));
 
-      // User signs in but is not opted in yet.
-      simulateStoredAccounts([{email: 'john@gmail.com'}]);
-      passwordManager.setIsOptedInForAccountStorageAndNotify(false);
-      flush();
-      assertTrue(
-          isDisplayed(passwordsSection.$.accountStorageButtonsContainer));
-      assertTrue(isDisplayed(passwordsSection.$.optInToAccountStorageButton));
-      assertFalse(isDisplayed(passwordsSection.$.optOutOfAccountStorageButton));
-      assertTrue(isDisplayed(passwordsSection.$.accountStorageOptInBody));
-      assertFalse(isDisplayed(passwordsSection.$.accountStorageOptOutBody));
+          // User signs in but is not opted in yet.
+          simulateStoredAccounts([{email: 'john@gmail.com'}]);
+          passwordManager.setIsOptedInForAccountStorageAndNotify(false);
+          flush();
+          assertTrue(
+              isDisplayed(passwordsSection.$.accountStorageButtonsContainer));
+          assertTrue(
+              isDisplayed(passwordsSection.$.optInToAccountStorageButton));
+          assertFalse(
+              isDisplayed(passwordsSection.$.optOutOfAccountStorageButton));
+          assertTrue(isDisplayed(passwordsSection.$.accountStorageOptInBody));
+          assertFalse(isDisplayed(passwordsSection.$.accountStorageOptOutBody));
 
-      // Opt in.
-      passwordManager.setIsOptedInForAccountStorageAndNotify(true);
-      flush();
-      assertTrue(
-          isDisplayed(passwordsSection.$.accountStorageButtonsContainer));
-      assertFalse(isDisplayed(passwordsSection.$.optInToAccountStorageButton));
-      assertTrue(isDisplayed(passwordsSection.$.optOutOfAccountStorageButton));
-      assertTrue(isDisplayed(passwordsSection.$.accountStorageOptOutBody));
-      assertFalse(isDisplayed(passwordsSection.$.accountStorageOptInBody));
-      assertEquals('john@gmail.com', passwordsSection.$.accountEmail.innerText);
+          // Opt in.
+          passwordManager.setIsOptedInForAccountStorageAndNotify(true);
+          flush();
+          assertTrue(
+              isDisplayed(passwordsSection.$.accountStorageButtonsContainer));
+          assertFalse(
+              isDisplayed(passwordsSection.$.optInToAccountStorageButton));
+          assertTrue(
+              isDisplayed(passwordsSection.$.optOutOfAccountStorageButton));
+          assertTrue(isDisplayed(passwordsSection.$.accountStorageOptOutBody));
+          assertFalse(isDisplayed(passwordsSection.$.accountStorageOptInBody));
+          assertEquals(
+              'john@gmail.com', passwordsSection.$.accountEmail.innerText);
 
-      // Sign out
-      simulateStoredAccounts([]);
-      assertFalse(
-          isDisplayed(passwordsSection.$.accountStorageButtonsContainer));
-    });
+          // Sign out
+          simulateStoredAccounts([]);
+          assertFalse(
+              isDisplayed(passwordsSection.$.accountStorageButtonsContainer));
+        });
 
     // Test verifies the the account storage buttons are not shown for custom
     // passphrase users.
-    test('accountStorageButonsNotShownForCustomPassphraseUser', function() {
-      const passwordsSection =
-          elementFactory.createPasswordsSection(passwordManager, [], []);
+    test(
+        'accountStorageButonsNotShownForCustomPassphraseUser',
+        async function() {
+          const passwordsSection = await createPasswordsSection(
+              elementFactory, passwordManager, [], []);
 
-      simulateSyncStatus(
-          {signedIn: false, statusAction: StatusAction.NO_ACTION});
-      simulateStoredAccounts([{email: 'john@gmail.com'}]);
-      // Simulate custom passphrase.
-      const syncPrefs = getSyncAllPrefs();
-      syncPrefs.encryptAllData = true;
-      webUIListenerCallback('sync-prefs-changed', syncPrefs);
-      flush();
+          simulateSyncStatus(
+              {signedIn: false, statusAction: StatusAction.NO_ACTION});
+          simulateStoredAccounts([{email: 'john@gmail.com'}]);
+          // Simulate custom passphrase.
+          const syncPrefs = getSyncAllPrefs();
+          syncPrefs.encryptAllData = true;
+          webUIListenerCallback('sync-prefs-changed', syncPrefs);
+          flush();
 
-      assertTrue(
-          !passwordsSection.$.accountStorageButtonsContainer ||
-          passwordsSection.$.accountStorageButtonsContainer.hidden);
-    });
+          assertTrue(
+              !passwordsSection.$.accountStorageButtonsContainer ||
+              passwordsSection.$.accountStorageButtonsContainer.hidden);
+        });
 
     // Test verifies that enabling sync hides the buttons for account storage
     // opt-in/out and the 'device passwords' page.
-    test('enablingSyncHidesAccountStorageButtons', function() {
+    test('enablingSyncHidesAccountStorageButtons', async function() {
       const passwordsSection =
-          elementFactory.createPasswordsSection(passwordManager, [], []);
+          await createPasswordsSection(elementFactory, passwordManager, [], []);
 
       simulateAccountStorageUser(passwordManager);
       function isDisplayed(element: HTMLElement): boolean {
@@ -1170,13 +1206,13 @@
 
     // Test verifies that the button linking to the 'device passwords' page is
     // only visible when there is at least one device password.
-    test('verifyDevicePasswordsButtonVisibility', function() {
+    test('verifyDevicePasswordsButtonVisibility', async function() {
       // Set up user eligible to the account-scoped password storage, not
       // opted in and with no device passwords. Button should be hidden.
       const passwordList =
           [createPasswordEntry({inAccountStore: true, id: 10})];
-      const passwordsSection = elementFactory.createPasswordsSection(
-          passwordManager, passwordList, []);
+      const passwordsSection = await createPasswordsSection(
+          elementFactory, passwordManager, passwordList, []);
       simulateSyncStatus(
           {signedIn: false, statusAction: StatusAction.NO_ACTION});
       simulateStoredAccounts([{email: 'john@gmail.com'}]);
@@ -1201,15 +1237,15 @@
     // toast manager message.
     test(
         'passwordRemovalMessageSpecifiesStoreForAccountStorageUsers',
-        function() {
+        async function() {
           const passwordList = [
             createPasswordEntry(
                 {username: 'account', id: 0, inAccountStore: true}),
             createPasswordEntry(
                 {username: 'local', id: 1, inProfileStore: true}),
           ];
-          const passwordsSection = elementFactory.createPasswordsSection(
-              passwordManager, passwordList, []);
+          const passwordsSection = await createPasswordsSection(
+              elementFactory, passwordManager, passwordList, []);
 
           simulateAccountStorageUser(passwordManager);
 
@@ -1241,8 +1277,8 @@
     test('verifyPasswordRemoveDialogRemoveBothCopies', async function() {
       const password = createPasswordEntry(
           {id: 0, inAccountStore: true, inProfileStore: true});
-      const passwordsSection = elementFactory.createPasswordsSection(
-          passwordManager, [password], []);
+      const passwordsSection = await createPasswordsSection(
+          elementFactory, passwordManager, [password], []);
 
       simulateAccountStorageUser(passwordManager);
 
@@ -1278,8 +1314,8 @@
     test('verifyPasswordRemoveDialogRemoveSingleCopy', async function() {
       const onAccountAndDevice = createPasswordEntry(
           {id: 0, inAccountStore: true, inProfileStore: true});
-      const passwordsSection = elementFactory.createPasswordsSection(
-          passwordManager, [onAccountAndDevice], []);
+      const passwordsSection = await createPasswordsSection(
+          elementFactory, passwordManager, [onAccountAndDevice], []);
 
       simulateAccountStorageUser(passwordManager);
 
@@ -1314,7 +1350,7 @@
 
   test(
       'showPasswordCheckBannerWhenNotCheckedBeforeAndSignedInAndHavePasswords',
-      function() {
+      async function() {
         // Suppose no check done initially, non-empty list of passwords,
         // signed in.
         assertEquals(
@@ -1323,8 +1359,8 @@
         const passwordList = [
           createPasswordEntry({url: 'site1.com', username: 'luigi'}),
         ];
-        const passwordsSection = elementFactory.createPasswordsSection(
-            passwordManager, passwordList, []);
+        const passwordsSection = await createPasswordsSection(
+            elementFactory, passwordManager, passwordList, []);
         return passwordManager.whenCalled('getPasswordCheckStatus').then(() => {
           simulateSyncStatus(
               {signedIn: true, statusAction: StatusAction.NO_ACTION});
@@ -1355,8 +1391,8 @@
         ];
         pluralString.text = '1 compromised password';
 
-        const passwordsSection = elementFactory.createPasswordsSection(
-            passwordManager, passwordList, []);
+        const passwordsSection = await createPasswordsSection(
+            elementFactory, passwordManager, passwordList, []);
 
         await passwordManager.whenCalled('getInsecureCredentials');
         await pluralString.whenCalled('getPluralString');
@@ -1372,43 +1408,50 @@
                     '#checkPasswordLeakCount')!.innerText!.trim());
       });
 
-  test('showPasswordCheckLinkButtonWithoutWarningWhenNotSignedIn', function() {
-    // Suppose no check done initially, non-empty list of passwords,
-    // signed out.
-    assertEquals(
-        passwordManager.data.checkStatus.elapsedTimeSinceLastCheck, undefined);
-    const passwordList = [
-      createPasswordEntry({url: 'site1.com', username: 'luigi'}),
-    ];
-    const passwordsSection = elementFactory.createPasswordsSection(
-        passwordManager, passwordList, []);
-    simulateSyncStatus({signedIn: false, statusAction: StatusAction.NO_ACTION});
-    return passwordManager.whenCalled('getPasswordCheckStatus').then(() => {
-      flush();
-      assertTrue(passwordsSection.$.checkPasswordsBannerContainer.hidden);
-      assertTrue(passwordsSection.$.checkPasswordsButtonRow.hidden);
-      assertFalse(passwordsSection.$.checkPasswordsLinkRow.hidden);
-    });
-  });
+  test(
+      'showPasswordCheckLinkButtonWithoutWarningWhenNotSignedIn',
+      async function() {
+        // Suppose no check done initially, non-empty list of passwords,
+        // signed out.
+        assertEquals(
+            passwordManager.data.checkStatus.elapsedTimeSinceLastCheck,
+            undefined);
+        const passwordList = [
+          createPasswordEntry({url: 'site1.com', username: 'luigi'}),
+        ];
+        const passwordsSection = await createPasswordsSection(
+            elementFactory, passwordManager, passwordList, []);
+        simulateSyncStatus(
+            {signedIn: false, statusAction: StatusAction.NO_ACTION});
+        return passwordManager.whenCalled('getPasswordCheckStatus').then(() => {
+          flush();
+          assertTrue(passwordsSection.$.checkPasswordsBannerContainer.hidden);
+          assertTrue(passwordsSection.$.checkPasswordsButtonRow.hidden);
+          assertFalse(passwordsSection.$.checkPasswordsLinkRow.hidden);
+        });
+      });
 
-  test('showPasswordCheckLinkButtonWithoutWarningWhenNoPasswords', function() {
-    // Suppose no check done initially, empty list of passwords, signed
-    // in.
-    assertEquals(
-        passwordManager.data.checkStatus.elapsedTimeSinceLastCheck, undefined);
-    const passwordsSection =
-        elementFactory.createPasswordsSection(passwordManager, [], []);
-    return passwordManager.whenCalled('getPasswordCheckStatus').then(() => {
-      flush();
-      assertTrue(passwordsSection.$.checkPasswordsBannerContainer.hidden);
-      assertTrue(passwordsSection.$.checkPasswordsButtonRow.hidden);
-      assertFalse(passwordsSection.$.checkPasswordsLinkRow.hidden);
-    });
-  });
+  test(
+      'showPasswordCheckLinkButtonWithoutWarningWhenNoPasswords',
+      async function() {
+        // Suppose no check done initially, empty list of passwords, signed
+        // in.
+        assertEquals(
+            passwordManager.data.checkStatus.elapsedTimeSinceLastCheck,
+            undefined);
+        const passwordsSection = await createPasswordsSection(
+            elementFactory, passwordManager, [], []);
+        return passwordManager.whenCalled('getPasswordCheckStatus').then(() => {
+          flush();
+          assertTrue(passwordsSection.$.checkPasswordsBannerContainer.hidden);
+          assertTrue(passwordsSection.$.checkPasswordsButtonRow.hidden);
+          assertFalse(passwordsSection.$.checkPasswordsLinkRow.hidden);
+        });
+      });
 
   test(
       'showPasswordCheckLinkButtonWithoutWarningWhenNoCredentialsLeaked',
-      function() {
+      async function() {
         // Suppose no leaks initially, non-empty list of passwords, signed in.
         passwordManager.data.insecureCredentials = [];
         passwordManager.data.checkStatus.elapsedTimeSinceLastCheck =
@@ -1416,8 +1459,8 @@
         const passwordList = [
           createPasswordEntry({url: 'site1.com', username: 'luigi'}),
         ];
-        const passwordsSection = elementFactory.createPasswordsSection(
-            passwordManager, passwordList, []);
+        const passwordsSection = await createPasswordsSection(
+            elementFactory, passwordManager, passwordList, []);
         return passwordManager.whenCalled('getPasswordCheckStatus').then(() => {
           flush();
           assertTrue(passwordsSection.$.checkPasswordsBannerContainer.hidden);
@@ -1431,7 +1474,7 @@
 
   test(
       'showPasswordCheckLinkButtonWithWarningWhenSomeCredentialsLeaked',
-      function() {
+      async function() {
         // Suppose no leaks initially, non-empty list of passwords, signed in.
         passwordManager.data.insecureCredentials = [
           makeInsecureCredential(
@@ -1446,8 +1489,8 @@
         const passwordList = [
           createPasswordEntry({url: 'site1.com', username: 'luigi'}),
         ];
-        const passwordsSection = elementFactory.createPasswordsSection(
-            passwordManager, passwordList, []);
+        const passwordsSection = await createPasswordsSection(
+            elementFactory, passwordManager, passwordList, []);
         return passwordManager.whenCalled('getPasswordCheckStatus').then(() => {
           flush();
           assertTrue(passwordsSection.$.checkPasswordsBannerContainer.hidden);
@@ -1459,7 +1502,7 @@
         });
       });
 
-  test('makeWarningAppearWhenLeaksDetected', function() {
+  test('makeWarningAppearWhenLeaksDetected', async function() {
     // Suppose no leaks detected initially, non-empty list of passwords,
     // signed in.
     assertEquals(
@@ -1470,8 +1513,8 @@
       createPasswordEntry({url: 'one.com', username: 'test4', id: 0}),
       createPasswordEntry({url: 'two.com', username: 'test3', id: 1}),
     ];
-    const passwordsSection = elementFactory.createPasswordsSection(
-        passwordManager, passwordList, []);
+    const passwordsSection = await createPasswordsSection(
+        elementFactory, passwordManager, passwordList, []);
     return passwordManager.whenCalled('getPasswordCheckStatus').then(() => {
       flush();
       assertTrue(passwordsSection.$.checkPasswordsBannerContainer.hidden);
@@ -1511,15 +1554,15 @@
     });
   });
 
-  test('makeBannerDisappearWhenSignedOut', function() {
+  test('makeBannerDisappearWhenSignedOut', async function() {
     // Suppose no leaks detected initially, non-empty list of passwords,
     // signed in.
     const passwordList = [
       createPasswordEntry({url: 'one.com', username: 'test4', id: 0}),
       createPasswordEntry({url: 'two.com', username: 'test3', id: 1}),
     ];
-    const passwordsSection = elementFactory.createPasswordsSection(
-        passwordManager, passwordList, []);
+    const passwordsSection = await createPasswordsSection(
+        elementFactory, passwordManager, passwordList, []);
     return passwordManager.whenCalled('getPasswordCheckStatus').then(() => {
       simulateSyncStatus(
           {signedIn: true, statusAction: StatusAction.NO_ACTION});
@@ -1538,7 +1581,7 @@
 
   test('clickingCheckPasswordsButtonStartsCheck', async function() {
     const passwordsSection =
-        elementFactory.createPasswordsSection(passwordManager, [], []);
+        await createPasswordsSection(elementFactory, passwordManager, [], []);
     passwordsSection.shadowRoot!
         .querySelector<HTMLElement>('#checkPasswordsButton')!.click();
     flush();
@@ -1552,7 +1595,7 @@
 
   test('clickingCheckPasswordsRowStartsCheck', async function() {
     const passwordsSection =
-        elementFactory.createPasswordsSection(passwordManager, [], []);
+        await createPasswordsSection(elementFactory, passwordManager, [], []);
     passwordsSection.shadowRoot!
         .querySelector<HTMLElement>('#checkPasswordsLinkRow')!.click();
     flush();
@@ -1565,7 +1608,7 @@
   });
 
   test('hatsInformedOnOpen', async function() {
-    elementFactory.createPasswordsSection(passwordManager, [], []);
+    await createPasswordsSection(elementFactory, passwordManager, [], []);
     const interaction =
         await testHatsBrowserProxy.whenCalled('trustSafetyInteractionOccurred');
     assertEquals(TrustSafetyInteraction.OPENED_PASSWORD_MANAGER, interaction);
@@ -1574,16 +1617,16 @@
   test('passwordScriptsRefreshedOnOpen', async function() {
     loadTimeData.overrideValues(
         {enableAutomaticPasswordChangeInSettings: true});
-    elementFactory.createPasswordsSection(passwordManager, [], []);
+    await createPasswordsSection(elementFactory, passwordManager, [], []);
     Router.getInstance().navigateTo(routes.PASSWORDS);
     await passwordManager.whenCalled('refreshScriptsIfNecessary');
   });
 
   test(
       'addPasswordButtonShownOnlyWhenPasswordManagerNotDisabledByPolicy',
-      function() {
-        const passwordsSection =
-            elementFactory.createPasswordsSection(passwordManager, [], []);
+      async function() {
+        const passwordsSection = await createPasswordsSection(
+            elementFactory, passwordManager, [], []);
         const addButton =
             passwordsSection.shadowRoot!.querySelector<HTMLElement>(
                 '#addPasswordButton')!;
@@ -1600,9 +1643,9 @@
         assertFalse(addButton.style.display === 'none');
       });
 
-  test('addPasswordButtonOpensAddPasswordDialog', function() {
+  test('addPasswordButtonOpensAddPasswordDialog', async function() {
     const passwordsSection =
-        elementFactory.createPasswordsSection(passwordManager, [], []);
+        await createPasswordsSection(elementFactory, passwordManager, [], []);
     assertFalse(!!passwordsSection.shadowRoot!.querySelector<HTMLElement>(
         '#addPasswordDialog'));
 
@@ -1614,9 +1657,9 @@
     assertTrue(!!addDialog);
   });
 
-  test('trustedVaultBannerVisibilityChangesWithState', function() {
+  test('trustedVaultBannerVisibilityChangesWithState', async function() {
     const passwordsSection =
-        elementFactory.createPasswordsSection(passwordManager, [], []);
+        await createPasswordsSection(elementFactory, passwordManager, [], []);
     webUIListenerCallback(
         'trusted-vault-banner-state-changed',
         TrustedVaultBannerState.NOT_SHOWN);
@@ -1641,11 +1684,11 @@
         passwordsSection.$.trustedVaultBanner.subLabel);
   });
 
-  test('routingWithRemovalParamsShowsNotification', function() {
+  test('routingWithRemovalParamsShowsNotification', async function() {
     const passwordEntry =
         createPasswordEntry({url: 'goo.gl', username: 'bart'});
-    const passwordsSection = elementFactory.createPasswordsSection(
-        passwordManager, [passwordEntry], []);
+    const passwordsSection = await createPasswordsSection(
+        elementFactory, passwordManager, [passwordEntry], []);
     const toastManager = passwordsSection.$.passwordsListHandler.$.removalToast;
 
     const params = new URLSearchParams();
@@ -1662,11 +1705,11 @@
     assertFalse(toastManager.open);
   });
 
-  test('routingWithAuthTimeoutParamShowsRemovalDialog', function() {
+  test('routingWithAuthTimeoutParamShowsRemovalDialog', async function() {
     const passwordEntry =
         createPasswordEntry({url: 'goo.gl', username: 'bart'});
-    const passwordsSection = elementFactory.createPasswordsSection(
-        passwordManager, [passwordEntry], []);
+    const passwordsSection = await createPasswordsSection(
+        elementFactory, passwordManager, [passwordEntry], []);
     const authTimeoutDialog = passwordsSection.$.authTimeoutDialog;
 
     const params = new URLSearchParams();
diff --git a/chrome/test/data/webui/settings/test_password_manager_proxy.ts b/chrome/test/data/webui/settings/test_password_manager_proxy.ts
index 2da69af..51800cb 100644
--- a/chrome/test/data/webui/settings/test_password_manager_proxy.ts
+++ b/chrome/test/data/webui/settings/test_password_manager_proxy.ts
@@ -105,6 +105,7 @@
       'getInsecureCredentials',
       'getPasswordCheckStatus',
       'getUrlCollection',
+      'getSavedPasswordList',
       'importPasswords',
       'isAccountStoreDefault',
       'isOptedInForAccountStorage',
@@ -160,9 +161,10 @@
     this.actual_.listening.passwords--;
   }
 
-  getSavedPasswordList(callback: SavedPasswordListChangedListener) {
+  getSavedPasswordList() {
+    this.methodCalled('getSavedPasswordList');
     this.actual_.requested.passwords++;
-    callback(this.data.passwords);
+    return Promise.resolve(this.data.passwords);
   }
 
   recordPasswordsPageAccessInSettings() {}
@@ -188,9 +190,9 @@
     this.actual_.listening.exceptions--;
   }
 
-  getExceptionList(callback: PasswordExceptionListChangedListener) {
+  getExceptionList() {
     this.actual_.requested.exceptions++;
-    callback(this.data.exceptions);
+    return Promise.resolve(this.data.exceptions);
   }
 
   removeException(id: number) {
diff --git a/chrome/updater/app/server/win/com_classes.cc b/chrome/updater/app/server/win/com_classes.cc
index 4510b61..c8b2ce0 100644
--- a/chrome/updater/app/server/win/com_classes.cc
+++ b/chrome/updater/app/server/win/com_classes.cc
@@ -16,7 +16,6 @@
 #include "base/files/file_path.h"
 #include "base/logging.h"
 #include "base/memory/scoped_refptr.h"
-#include "base/notreached.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/task/bind_post_task.h"
 #include "base/task/task_traits.h"
@@ -179,7 +178,7 @@
 }
 
 HRESULT UpdaterImpl::CheckForUpdate(const wchar_t* app_id) {
-  NOTIMPLEMENTED();
+  LOG(ERROR) << "Reached unimplemented COM method: " << __func__;
   return E_NOTIMPL;
 }
 
diff --git a/chrome/updater/app/server/win/com_classes_legacy.cc b/chrome/updater/app/server/win/com_classes_legacy.cc
index 0834634c..94b3611 100644
--- a/chrome/updater/app/server/win/com_classes_legacy.cc
+++ b/chrome/updater/app/server/win/com_classes_legacy.cc
@@ -19,7 +19,6 @@
 #include "base/files/file_path.h"
 #include "base/logging.h"
 #include "base/memory/ref_counted.h"
-#include "base/notreached.h"
 #include "base/path_service.h"
 #include "base/process/launch.h"
 #include "base/process/process.h"
@@ -356,17 +355,17 @@
 
   // Overrides for IAppWeb.
   IFACEMETHODIMP get_appId(BSTR* app_id) override {
-    NOTIMPLEMENTED();
+    LOG(ERROR) << "Reached unimplemented COM method: " << __func__;
     return E_NOTIMPL;
   }
 
   IFACEMETHODIMP get_currentVersionWeb(IDispatch** current) override {
-    NOTIMPLEMENTED();
+    LOG(ERROR) << "Reached unimplemented COM method: " << __func__;
     return E_NOTIMPL;
   }
 
   IFACEMETHODIMP get_nextVersionWeb(IDispatch** next) override {
-    NOTIMPLEMENTED();
+    LOG(ERROR) << "Reached unimplemented COM method: " << __func__;
     return E_NOTIMPL;
   }
 
@@ -376,7 +375,7 @@
   }
 
   IFACEMETHODIMP cancel() override {
-    NOTIMPLEMENTED();
+    LOG(ERROR) << "Reached unimplemented COM method: " << __func__;
     return E_NOTIMPL;
   }
 
@@ -479,22 +478,22 @@
   }
 
   IFACEMETHODIMP launch() override {
-    NOTIMPLEMENTED();
+    LOG(ERROR) << "Reached unimplemented COM method: " << __func__;
     return E_NOTIMPL;
   }
 
   IFACEMETHODIMP uninstall() override {
-    NOTIMPLEMENTED();
+    LOG(ERROR) << "Reached unimplemented COM method: " << __func__;
     return E_NOTIMPL;
   }
 
   IFACEMETHODIMP get_serverInstallDataIndex(BSTR* language) override {
-    NOTIMPLEMENTED();
+    LOG(ERROR) << "Reached unimplemented COM method: " << __func__;
     return E_NOTIMPL;
   }
 
   IFACEMETHODIMP put_serverInstallDataIndex(BSTR language) override {
-    NOTIMPLEMENTED();
+    LOG(ERROR) << "Reached unimplemented COM method: " << __func__;
     return E_NOTIMPL;
   }
 
@@ -538,7 +537,7 @@
                            BSTR brand_code,
                            BSTR language,
                            BSTR ap) override {
-    NOTIMPLEMENTED();
+    LOG(ERROR) << "Reached unimplemented COM method: " << __func__;
     return E_NOTIMPL;
   }
 
@@ -552,12 +551,12 @@
   }
 
   IFACEMETHODIMP createAllInstalledApps() override {
-    NOTIMPLEMENTED();
+    LOG(ERROR) << "Reached unimplemented COM method: " << __func__;
     return E_NOTIMPL;
   }
 
   IFACEMETHODIMP get_displayLanguage(BSTR* language) override {
-    NOTIMPLEMENTED();
+    LOG(ERROR) << "Reached unimplemented COM method: " << __func__;
     return E_NOTIMPL;
   }
 
@@ -566,7 +565,7 @@
   IFACEMETHODIMP put_parentHWND(ULONG_PTR hwnd) override { return S_OK; }
 
   IFACEMETHODIMP get_length(int* number) override {
-    NOTIMPLEMENTED();
+    LOG(ERROR) << "Reached unimplemented COM method: " << __func__;
     return E_NOTIMPL;
   }
 
@@ -592,34 +591,34 @@
   }
 
   IFACEMETHODIMP download() override {
-    NOTIMPLEMENTED();
+    LOG(ERROR) << "Reached unimplemented COM method: " << __func__;
     return E_NOTIMPL;
   }
 
   IFACEMETHODIMP install() override { return S_OK; }
 
   IFACEMETHODIMP pause() override {
-    NOTIMPLEMENTED();
+    LOG(ERROR) << "Reached unimplemented COM method: " << __func__;
     return E_NOTIMPL;
   }
 
   IFACEMETHODIMP resume() override {
-    NOTIMPLEMENTED();
+    LOG(ERROR) << "Reached unimplemented COM method: " << __func__;
     return E_NOTIMPL;
   }
 
   IFACEMETHODIMP cancel() override {
-    NOTIMPLEMENTED();
+    LOG(ERROR) << "Reached unimplemented COM method: " << __func__;
     return E_NOTIMPL;
   }
 
   IFACEMETHODIMP downloadPackage(BSTR app_id, BSTR package_name) override {
-    NOTIMPLEMENTED();
+    LOG(ERROR) << "Reached unimplemented COM method: " << __func__;
     return E_NOTIMPL;
   }
 
   IFACEMETHODIMP get_currentState(VARIANT* current_state) override {
-    NOTIMPLEMENTED();
+    LOG(ERROR) << "Reached unimplemented COM method: " << __func__;
     return E_NOTIMPL;
   }
 
@@ -651,7 +650,7 @@
 
 STDMETHODIMP LegacyProcessLauncherImpl::LaunchBrowser(DWORD browser_type,
                                                       const WCHAR* url) {
-  NOTIMPLEMENTED();
+  LOG(ERROR) << "Reached unimplemented COM method: " << __func__;
   return E_NOTIMPL;
 }
 
@@ -699,7 +698,7 @@
     DWORD* server_proc_id,
     ULONG_PTR* proc_handle,
     ULONG_PTR* stdout_handle) {
-  NOTIMPLEMENTED();
+  LOG(ERROR) << "Reached unimplemented COM method: " << __func__;
   return E_NOTIMPL;
 }
 
@@ -742,7 +741,7 @@
 }
 
 STDMETHODIMP LegacyAppCommandWebImpl::get_output(BSTR* output) {
-  NOTIMPLEMENTED();
+  LOG(ERROR) << "Reached unimplemented COM method: " << __func__;
   return E_NOTIMPL;
 }
 
@@ -1204,12 +1203,12 @@
 
 // TODO(crbug.com/1344200): Implement the IDispatch methods.
 STDMETHODIMP PolicyStatusImpl::GetTypeInfoCount(UINT*) {
-  NOTIMPLEMENTED();
+  LOG(ERROR) << "Reached unimplemented COM method: " << __func__;
   return E_NOTIMPL;
 }
 
 STDMETHODIMP PolicyStatusImpl::GetTypeInfo(UINT, LCID, ITypeInfo**) {
-  NOTIMPLEMENTED();
+  LOG(ERROR) << "Reached unimplemented COM method: " << __func__;
   return E_NOTIMPL;
 }
 
@@ -1218,7 +1217,7 @@
                                              UINT,
                                              LCID,
                                              DISPID*) {
-  NOTIMPLEMENTED();
+  LOG(ERROR) << "Reached unimplemented COM method: " << __func__;
   return E_NOTIMPL;
 }
 
@@ -1230,7 +1229,7 @@
                                       VARIANT*,
                                       EXCEPINFO*,
                                       UINT*) {
-  NOTIMPLEMENTED();
+  LOG(ERROR) << "Reached unimplemented COM method: " << __func__;
   return E_NOTIMPL;
 }
 
@@ -1308,12 +1307,12 @@
 
 // TODO(crbug.com/1344200): Implement the IDispatch methods.
 STDMETHODIMP PolicyStatusValueImpl::GetTypeInfoCount(UINT*) {
-  NOTIMPLEMENTED();
+  LOG(ERROR) << "Reached unimplemented COM method: " << __func__;
   return E_NOTIMPL;
 }
 
 STDMETHODIMP PolicyStatusValueImpl::GetTypeInfo(UINT, LCID, ITypeInfo**) {
-  NOTIMPLEMENTED();
+  LOG(ERROR) << "Reached unimplemented COM method: " << __func__;
   return E_NOTIMPL;
 }
 
@@ -1322,7 +1321,7 @@
                                                   UINT,
                                                   LCID,
                                                   DISPID*) {
-  NOTIMPLEMENTED();
+  LOG(ERROR) << "Reached unimplemented COM method: " << __func__;
   return E_NOTIMPL;
 }
 
@@ -1334,7 +1333,7 @@
                                            VARIANT*,
                                            EXCEPINFO*,
                                            UINT*) {
-  NOTIMPLEMENTED();
+  LOG(ERROR) << "Reached unimplemented COM method: " << __func__;
   return E_NOTIMPL;
 }
 
diff --git a/chrome/updater/run_all_unittests.cc b/chrome/updater/run_all_unittests.cc
index b4646437..ecffbb2 100644
--- a/chrome/updater/run_all_unittests.cc
+++ b/chrome/updater/run_all_unittests.cc
@@ -26,7 +26,6 @@
 
 #include "base/base_paths.h"
 #include "base/files/file_path.h"
-#include "base/files/file_util.h"
 #include "base/path_service.h"
 #include "base/win/registry.h"
 #include "base/win/scoped_com_initializer.h"
@@ -204,10 +203,6 @@
                              false);  // enable_tickcount
         LOG(ERROR) << "A test timeout has occured in "
                    << updater::test::GetTestName();
-#if BUILDFLAG(IS_WIN)
-        const base::FilePath updater_test = updater::test::GetUpdaterTestPath();
-        PLOG_IF(0, !base::PathExists(updater_test)) << ", " << updater_test;
-#endif
         updater::test::CreateIntegrationTestCommands()->PrintLog();
       }),
       base::BindOnce(&base::TestSuite::Run, base::Unretained(&test_suite)));
diff --git a/chrome/updater/test/integration_tests.cc b/chrome/updater/test/integration_tests.cc
index 355a556..b4fcd79 100644
--- a/chrome/updater/test/integration_tests.cc
+++ b/chrome/updater/test/integration_tests.cc
@@ -33,7 +33,6 @@
 #include "chrome/updater/test/integration_tests_impl.h"
 #include "chrome/updater/test/server.h"
 #include "chrome/updater/test_scope.h"
-#include "chrome/updater/unittest_util.h"
 #include "chrome/updater/update_service.h"
 #include "chrome/updater/updater_scope.h"
 #include "chrome/updater/updater_version.h"
@@ -96,9 +95,6 @@
                          true,    // enable_thread_id
                          true,    // enable_timestamp
                          false);  // enable_tickcount
-#if BUILDFLAG(IS_WIN)
-    ASSERT_TRUE(base::PathExists(updater_path_)) << updater_path_;
-#endif
     Clean();
     ExpectClean();
     // TODO(crbug.com/1233612) - reenable the code when system tests pass.
@@ -117,9 +113,6 @@
     // TODO(crbug.com/1233612) - reenable the code when system tests pass.
     // TearDownTestService();
     Clean();
-#if BUILDFLAG(IS_WIN)
-    ASSERT_TRUE(base::PathExists(updater_path_)) << updater_path_;
-#endif
   }
 
   void CopyLog() { test_commands_->CopyLog(); }
@@ -343,7 +336,6 @@
 
  private:
   base::test::TaskEnvironment environment_;
-  const base::FilePath updater_path_ = GetUpdaterTestPath();
 };
 
 // The project's position is that component builds are not portable outside of
diff --git a/chrome/updater/test/integration_tests_win.cc b/chrome/updater/test/integration_tests_win.cc
index 2366315..32d9f0b 100644
--- a/chrome/updater/test/integration_tests_win.cc
+++ b/chrome/updater/test/integration_tests_win.cc
@@ -89,6 +89,17 @@
   kCheckActiveAndSxS = 1,
 };
 
+// Creates an instance of the class specified by `clsid` in a local server.
+template <typename ComInterface>
+HRESULT CreateLocalServer(GUID clsid,
+                          Microsoft::WRL::ComPtr<ComInterface>& server) {
+  // crbug.com/1259178 - there is known race condition between the COM server
+  // shutdown and server start up.
+  ::Sleep(kCreateUpdaterInstanceDelayMs);
+  return ::CoCreateInstance(clsid, nullptr, CLSCTX_LOCAL_SERVER,
+                            IID_PPV_ARGS(&server));
+}
+
 // Returns the root directory where the updater product is installed. This
 // is the parent directory where the versioned directories of the
 // updater instances are.
@@ -779,23 +790,24 @@
 // legacy interfaces are available. Failure to query these interfaces indicates
 // an issue with typelib registration.
 void ExpectInterfacesRegistered(UpdaterScope scope) {
-  {  // IUpdater, IGoogleUpdate3Web and IAppBundleWeb.
+  {
+    // IUpdater, IGoogleUpdate3Web and IAppBundleWeb.
     // The block is necessary so that updater_server goes out of scope and
     // releases the prefs lock before updater_internal_server tries to acquire
     // it to mode-check.
     Microsoft::WRL::ComPtr<IUnknown> updater_server;
-    ASSERT_HRESULT_SUCCEEDED(::CoCreateInstance(
+    ASSERT_HRESULT_SUCCEEDED(CreateLocalServer(
         scope == UpdaterScope::kSystem ? __uuidof(UpdaterSystemClass)
                                        : __uuidof(UpdaterUserClass),
-        nullptr, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&updater_server)));
+        updater_server));
     Microsoft::WRL::ComPtr<IUpdater> updater;
     EXPECT_HRESULT_SUCCEEDED(updater_server.As(&updater));
 
     Microsoft::WRL::ComPtr<IUnknown> updater_legacy_server;
-    ASSERT_HRESULT_SUCCEEDED(::CoCreateInstance(
+    ASSERT_HRESULT_SUCCEEDED(CreateLocalServer(
         scope == UpdaterScope::kSystem ? __uuidof(GoogleUpdate3WebSystemClass)
                                        : __uuidof(GoogleUpdate3WebUserClass),
-        nullptr, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&updater_legacy_server)));
+        updater_legacy_server));
     Microsoft::WRL::ComPtr<IGoogleUpdate3Web> google_update;
     ASSERT_HRESULT_SUCCEEDED(updater_legacy_server.As(&google_update));
     Microsoft::WRL::ComPtr<IAppBundleWeb> app_bundle;
@@ -804,12 +816,13 @@
     EXPECT_HRESULT_SUCCEEDED(dispatch.As(&app_bundle));
   }
 
-  {  // IUpdaterInternal.
+  {
+    // IUpdaterInternal.
     Microsoft::WRL::ComPtr<IUnknown> updater_internal_server;
-    ASSERT_HRESULT_SUCCEEDED(::CoCreateInstance(
+    ASSERT_HRESULT_SUCCEEDED(CreateLocalServer(
         scope == UpdaterScope::kSystem ? __uuidof(UpdaterInternalSystemClass)
                                        : __uuidof(UpdaterInternalUserClass),
-        nullptr, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&updater_internal_server)));
+        updater_internal_server));
     Microsoft::WRL::ComPtr<IUpdaterInternal> updater_internal;
     EXPECT_HRESULT_SUCCEEDED(updater_internal_server.As(&updater_internal));
   }
@@ -878,10 +891,10 @@
 void InitializeBundle(UpdaterScope scope,
                       Microsoft::WRL::ComPtr<IAppBundleWeb>& bundle_web) {
   Microsoft::WRL::ComPtr<IGoogleUpdate3Web> update3web;
-  ASSERT_HRESULT_SUCCEEDED(::CoCreateInstance(
+  ASSERT_HRESULT_SUCCEEDED(CreateLocalServer(
       scope == UpdaterScope::kSystem ? __uuidof(GoogleUpdate3WebSystemClass)
                                      : __uuidof(GoogleUpdate3WebUserClass),
-      nullptr, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&update3web)));
+      update3web));
 
   Microsoft::WRL::ComPtr<IAppBundleWeb> bundle;
   Microsoft::WRL::ComPtr<IDispatch> dispatch;
@@ -1101,9 +1114,8 @@
     return;
 
   Microsoft::WRL::ComPtr<IProcessLauncher> process_launcher;
-  ASSERT_HRESULT_SUCCEEDED(::CoCreateInstance(__uuidof(ProcessLauncherClass),
-                                              nullptr, CLSCTX_LOCAL_SERVER,
-                                              IID_PPV_ARGS(&process_launcher)));
+  ASSERT_HRESULT_SUCCEEDED(
+      CreateLocalServer(__uuidof(ProcessLauncherClass), process_launcher));
 
   constexpr wchar_t kAppId1[] = L"{831EF4D0-B729-4F61-AA34-91526481799D}";
   constexpr wchar_t kCommandId[] = L"CmdExit0";
@@ -1232,10 +1244,10 @@
 
 void ExpectLegacyPolicyStatusSucceeds(UpdaterScope scope) {
   Microsoft::WRL::ComPtr<IUnknown> policy_status_server;
-  ASSERT_HRESULT_SUCCEEDED(::CoCreateInstance(
+  ASSERT_HRESULT_SUCCEEDED(CreateLocalServer(
       scope == UpdaterScope::kSystem ? __uuidof(PolicyStatusSystemClass)
                                      : __uuidof(PolicyStatusUserClass),
-      nullptr, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&policy_status_server)));
+      policy_status_server));
   Microsoft::WRL::ComPtr<IPolicyStatus2> policy_status2;
   ASSERT_HRESULT_SUCCEEDED(policy_status_server.As(&policy_status2));
 
diff --git a/chrome/updater/tools/certificate_tag.cc b/chrome/updater/tools/certificate_tag.cc
index 719eb4d..84e85d5b 100644
--- a/chrome/updater/tools/certificate_tag.cc
+++ b/chrome/updater/tools/certificate_tag.cc
@@ -8,8 +8,7 @@
 #include "third_party/boringssl/src/include/openssl/bytestring.h"
 #include "third_party/boringssl/src/include/openssl/crypto.h"
 
-namespace updater {
-namespace tools {
+namespace updater::tools {
 
 // CBS is a structure from BoringSSL used for parsing binary and ASN.1-based
 // formats. This implementation detail is not exposed in the interface of this
@@ -483,5 +482,4 @@
   return true;
 }
 
-}  // namespace tools
-}  // namespace updater
+}  // namespace updater::tools
diff --git a/chrome/updater/unittest_util.cc b/chrome/updater/unittest_util.cc
index 8ab62e2..b7df85b 100644
--- a/chrome/updater/unittest_util.cc
+++ b/chrome/updater/unittest_util.cc
@@ -7,16 +7,13 @@
 #include <string>
 #include <utility>
 
-#include "base/base_paths.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/memory/scoped_refptr.h"
-#include "base/path_service.h"
 #include "base/process/kill.h"
 #include "base/process/process_iterator.h"
 #include "base/strings/strcat.h"
 #include "base/time/time.h"
-#include "build/build_config.h"
 #include "chrome/updater/constants.h"
 #include "chrome/updater/policy/manager.h"
 #include "chrome/updater/policy/service.h"
@@ -83,14 +80,4 @@
   return Local::DeleteDirsIfEmpty(file_path->DirName());
 }
 
-base::FilePath GetUpdaterTestPath() {
-  base::FilePath out_dir;
-  CHECK(base::PathService::Get(base::DIR_EXE, &out_dir));
-#if BUILDFLAG(IS_WIN)
-  return out_dir.Append(FILE_PATH_LITERAL("updater_test.exe"));
-#else
-  return out_dir.Append(FILE_PATH_LITERAL("updater_test"));
-#endif
-}
-
 }  // namespace updater::test
diff --git a/chrome/updater/unittest_util.h b/chrome/updater/unittest_util.h
index d674120..bd5600d 100644
--- a/chrome/updater/unittest_util.h
+++ b/chrome/updater/unittest_util.h
@@ -58,10 +58,6 @@
 bool DeleteFileAndEmptyParentDirectories(
     const absl::optional<base::FilePath>& file_path);
 
-// TODO(crbug.com/1372590) - remove function when the bug is closed.
-// Returns the path of the updater_test.exe in the "out" directory of the build.
-base::FilePath GetUpdaterTestPath();
-
 }  // namespace updater::test
 
 #endif  // CHROME_UPDATER_UNITTEST_UTIL_H_
diff --git a/chrome/updater/util.cc b/chrome/updater/util.cc
index dab9f5a..06e97ce 100644
--- a/chrome/updater/util.cc
+++ b/chrome/updater/util.cc
@@ -18,7 +18,6 @@
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
-#include "base/notreached.h"
 #include "base/path_service.h"
 #include "base/ranges/algorithm.h"
 #include "base/strings/escape.h"
diff --git a/chrome/updater/win/app_command_runner.cc b/chrome/updater/win/app_command_runner.cc
index 280fce9..ba4d06f 100644
--- a/chrome/updater/win/app_command_runner.cc
+++ b/chrome/updater/win/app_command_runner.cc
@@ -17,6 +17,7 @@
 #include "base/files/file_path.h"
 #include "base/logging.h"
 #include "base/path_service.h"
+#include "base/process/launch.h"
 #include "base/strings/strcat.h"
 #include "base/strings/string_util.h"
 #include "base/win/registry.h"
@@ -239,39 +240,34 @@
 }
 
 HRESULT AppCommandRunner::StartProcess(const base::FilePath& executable,
-                                       const std::wstring& command_line,
+                                       const std::wstring& parameters,
                                        base::Process& process) {
-  VLOG(2) << __func__ << ": " << executable << ": " << command_line;
+  VLOG(2) << __func__ << ": " << executable << ": " << parameters;
 
   if (executable.empty() || process.IsValid()) {
     return E_UNEXPECTED;
   }
 
+  // `executable` needs to be a full path to prevent `::CreateProcess` (which
+  // `base::LaunchProcess` uses internally) from using the search path for path
+  // resolution.
   if (!executable.IsAbsolute()) {
     LOG(ERROR) << __func__ << "!executable.IsAbsolute(): " << executable;
     return E_INVALIDARG;
   }
 
-  STARTUPINFOW si = {sizeof(si)};
-  PROCESS_INFORMATION pi = {0};
-  std::wstring parameters = command_line;
+  base::LaunchOptions options = {};
+  options.feedback_cursor_off = true;
+  options.start_hidden = true;
 
-  // In contrast to the following call to `::CreateProcess`,
-  // `base::Process::LaunchProcess` passes the `executable` in the
-  // `lpCommandLine` parameter to `::CreateProcess`, which uses the search path
-  // for path resolution of `executable`.
-  if (!::CreateProcess(executable.value().c_str(), &parameters[0], nullptr,
-                       nullptr, FALSE, CREATE_NO_WINDOW, nullptr, nullptr, &si,
-                       &pi)) {
+  process = base::LaunchProcess(
+      base::StrCat({L"\"", executable.value(), L"\" ", parameters}), options);
+  if (!process.IsValid()) {
     const HRESULT hr = HRESULTFromLastError();
-    LOG(ERROR) << __func__ << "::CreateProcess failed: " << hr;
+    LOG(ERROR) << __func__ << "base::LaunchProcess failed: " << hr;
     return hr;
   }
 
-  ::CloseHandle(pi.hThread);
-
-  process = base::Process(pi.hProcess);
-  CHECK(process.IsValid());
   VLOG(2) << __func__ << "Started process with PID: " << process.Pid();
   return S_OK;
 }
@@ -337,14 +333,14 @@
           << base::JoinString(parameters, L",")
           << base::JoinString(substitutions, L",");
 
-  const absl::optional<std::wstring> command_line =
+  const absl::optional<std::wstring> command_line_parameters =
       FormatAppCommandLine(parameters, substitutions);
-  if (!command_line) {
-    LOG(ERROR) << __func__ << "!command_line";
+  if (!command_line_parameters) {
+    LOG(ERROR) << __func__ << "!command_line_parameters";
     return E_INVALIDARG;
   }
 
-  return StartProcess(executable, command_line.value(), process);
+  return StartProcess(executable, command_line_parameters.value(), process);
 }
 
 }  // namespace updater
diff --git a/chrome/updater/win/app_command_runner.h b/chrome/updater/win/app_command_runner.h
index 8f7fcd3..f0a6938b 100644
--- a/chrome/updater/win/app_command_runner.h
+++ b/chrome/updater/win/app_command_runner.h
@@ -54,10 +54,10 @@
               base::Process& process) const;
 
  private:
-  // Starts a process with separate `executable` and `command_line` components.
+  // Starts a process with separate `executable` and `parameters` components.
   // `executable` needs to be an absolute path.
   static HRESULT StartProcess(const base::FilePath& executable,
-                              const std::wstring& command_line,
+                              const std::wstring& parameters,
                               base::Process& process);
 
   // Separates a command line in `command_format` into an `executable` and
diff --git a/chrome/updater/win/ui/l10n_util.cc b/chrome/updater/win/ui/l10n_util.cc
index 8a75593..96824aa 100644
--- a/chrome/updater/win/ui/l10n_util.cc
+++ b/chrome/updater/win/ui/l10n_util.cc
@@ -49,17 +49,14 @@
 
 std::wstring GetLocalizedString(UINT base_message_id) {
   // Map `base_message_id` to the base id for the current install mode.
-  std::wstring localized_string;
   UINT message_id =
       static_cast<UINT>(base_message_id + GetLanguageSelector().offset());
   const ATLSTRINGRESOURCEIMAGE* image =
       AtlGetStringResourceImage(_AtlBaseModule.GetModuleInstance(), message_id);
-  if (image) {
-    localized_string = std::wstring(image->achString, image->nLength);
-  } else {
-    NOTREACHED() << "Unable to find resource id " << message_id;
-  }
-  return localized_string;
+  if (image)
+    return std::wstring(image->achString, image->nLength);
+  NOTREACHED() << "Unable to find resource id " << message_id;
+  return std::wstring();
 }
 
 std::wstring GetLocalizedStringF(UINT base_message_id,
diff --git a/chromecast/android/lint-baseline.xml b/chromecast/android/lint-baseline.xml
index 0e8bc82..c4386ef 100644
--- a/chromecast/android/lint-baseline.xml
+++ b/chromecast/android/lint-baseline.xml
@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 7.4.0-alpha05" type="baseline" client="" dependencies="true" name="" variant="all" version="7.4.0-alpha05">
+<issues format="6" by="lint 8.0.0-alpha06" type="baseline" client="" dependencies="true" name="" variant="all" version="8.0.0-alpha06">
 
     <issue
         id="LintError"
-        message="../../chromecast/android/lint-baseline.xml (relative to /usr/local/google/home/wnwen/z1/src/out/Cast) does not exist"
+        message="../../chromecast/android/lint-baseline.xml (relative to /usr/local/google/code/clankium/src/out/Lint-Cast) does not exist"
         errorLine1="  &lt;baseline file=&quot;../../chromecast/android/lint-baseline.xml&quot;/>"
         errorLine2="  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
@@ -40,7 +40,7 @@
         errorLine1="    android:background=&quot;#FFFFFF&quot;"
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/chromecast/browser/android/apk/res/layout/cast_web_contents_activity.xml"
+            file="../../chromecast/browser/android/apk/res/layout/cast_web_contents_activity.xml"
             line="12"
             column="5"/>
     </issue>
diff --git a/chromecast/browser/cast_display_configurator.cc b/chromecast/browser/cast_display_configurator.cc
index 9e0cc10..b6fef9d 100644
--- a/chromecast/browser/cast_display_configurator.cc
+++ b/chromecast/browser/cast_display_configurator.cc
@@ -13,6 +13,7 @@
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #include "base/strings/string_number_conversions.h"
+#include "build/build_config.h"
 #include "chromecast/base/cast_features.h"
 #include "chromecast/browser/cast_touch_device_manager.h"
 #include "chromecast/chromecast_buildflags.h"
@@ -95,7 +96,7 @@
 
 CastDisplayConfigurator::CastDisplayConfigurator(CastScreen* screen)
     : delegate_(
-#if defined(USE_OZONE) && !BUILDFLAG(IS_CAST_AUDIO_ONLY)
+#if BUILDFLAG(IS_OZONE) && !BUILDFLAG(IS_CAST_AUDIO_ONLY)
           ui::OzonePlatform::GetInstance()->CreateNativeDisplayDelegate()
 #else
           nullptr
diff --git a/chromeos/BUILD.gn b/chromeos/BUILD.gn
index 1be62d3f..b5a18b1 100644
--- a/chromeos/BUILD.gn
+++ b/chromeos/BUILD.gn
@@ -193,14 +193,6 @@
     tast_disabled_tests = tast_disabled_tests_from_chrome_all
   }
 
-  tast_test("chrome_all_tast_tests_with_lacros") {
-    # To disable a specific test, add it to the
-    # tast_disabled_tests_from_chrome_all list in "tast_control.gni" and cite
-    # a bug.
-    tast_disabled_tests = tast_disabled_tests_from_chrome_all
-    deploy_lacros_chrome = true
-  }
-
   tast_test("chrome_all_tast_tests_informational") {
     enable_tast_informational_tests = true
   }
diff --git a/chromeos/ash/components/proximity_auth/proximity_auth_system.cc b/chromeos/ash/components/proximity_auth/proximity_auth_system.cc
index b0dc8ac..7794336 100644
--- a/chromeos/ash/components/proximity_auth/proximity_auth_system.cc
+++ b/chromeos/ash/components/proximity_auth/proximity_auth_system.cc
@@ -4,7 +4,6 @@
 
 #include "chromeos/ash/components/proximity_auth/proximity_auth_system.h"
 
-#include "ash/constants/ash_features.h"
 #include "chromeos/ash/components/multidevice/logging/logging.h"
 #include "chromeos/ash/components/proximity_auth/proximity_auth_client.h"
 #include "chromeos/ash/components/proximity_auth/remote_device_life_cycle_impl.h"
@@ -92,42 +91,22 @@
   PA_LOG(INFO) << "Preparing for device suspension.";
   DCHECK(!suspended_);
   suspended_ = true;
-  OnSuspendOrScreenOffChange();
+  unlock_manager_->SetRemoteDeviceLifeCycle(nullptr);
+  remote_device_life_cycle_.reset();
 }
 
 void ProximityAuthSystem::OnSuspendDone() {
   PA_LOG(INFO) << "Device resumed from suspension.";
   DCHECK(suspended_);
   suspended_ = false;
-  OnSuspendOrScreenOffChange();
-}
 
-void ProximityAuthSystem::OnScreenOff() {
-  if (!base::FeatureList::IsEnabled(
-          ash::features::kSmartLockBluetoothScreenOffFix)) {
-    return;
+  if (!ScreenlockBridge::Get()->IsLocked()) {
+    PA_LOG(INFO) << "Suspend done, but no lock screen.";
+  } else if (!started_) {
+    PA_LOG(INFO) << "Suspend done, but not system started.";
+  } else {
+    OnFocusedUserChanged(ScreenlockBridge::Get()->focused_account_id());
   }
-
-  PA_LOG(INFO) << "Screen is off.";
-  DCHECK(!screen_off_);
-  screen_off_ = true;
-  OnSuspendOrScreenOffChange();
-}
-
-void ProximityAuthSystem::OnScreenOffDone() {
-  if (!base::FeatureList::IsEnabled(
-          ash::features::kSmartLockBluetoothScreenOffFix)) {
-    return;
-  }
-
-  // It's possible to end up here when the screen is dimmed and the screen_off_
-  // boolean was not true, in which case we can return early.
-  if (!screen_off_)
-    return;
-
-  PA_LOG(INFO) << "Screen is on.";
-  screen_off_ = false;
-  OnSuspendOrScreenOffChange();
 }
 
 void ProximityAuthSystem::CancelConnectionAttempt() {
@@ -191,7 +170,7 @@
   absl::optional<ash::multidevice::RemoteDeviceRef> local_device;
   local_device = local_device_map_.at(account_id);
 
-  if (!suspended_ && !screen_off_) {
+  if (!suspended_) {
     PA_LOG(INFO) << "Creating RemoteDeviceLifeCycle for focused user: "
                  << account_id.Serialize();
     remote_device_life_cycle_ =
@@ -211,20 +190,4 @@
   return std::string();
 }
 
-void ProximityAuthSystem::OnSuspendOrScreenOffChange() {
-  if (suspended_ || screen_off_) {
-    unlock_manager_->SetRemoteDeviceLifeCycle(nullptr);
-    remote_device_life_cycle_.reset();
-    return;
-  }
-
-  if (!ScreenlockBridge::Get()->IsLocked()) {
-    PA_LOG(INFO) << "System resumed, but no lock screen.";
-  } else if (!started_) {
-    PA_LOG(INFO) << "System resumed, but ProximityAuthSystem is stopped.";
-  } else {
-    OnFocusedUserChanged(ScreenlockBridge::Get()->focused_account_id());
-  }
-}
-
 }  // namespace proximity_auth
diff --git a/chromeos/ash/components/proximity_auth/proximity_auth_system.h b/chromeos/ash/components/proximity_auth/proximity_auth_system.h
index 48ab6b6..a7258dc5 100644
--- a/chromeos/ash/components/proximity_auth/proximity_auth_system.h
+++ b/chromeos/ash/components/proximity_auth/proximity_auth_system.h
@@ -74,12 +74,6 @@
   // Called when the system wakes up from a suspended state.
   void OnSuspendDone();
 
-  // Called when the screen turns off.
-  void OnScreenOff();
-
-  // Called when the system resumes after the screen turns back on.
-  void OnScreenOffDone();
-
   // Called in order to disable attempts to get RemoteStatus from host devices.
   void CancelConnectionAttempt();
 
@@ -113,9 +107,6 @@
   void OnFocusedUserChanged(const AccountId& account_id) override;
 
  private:
-  // Called when there is a change in |suspended_| or |screen_off_|.
-  void OnSuspendOrScreenOffChange();
-
   // Lists of remote devices, keyed by user account id.
   std::map<AccountId, ash::multidevice::RemoteDeviceRefList>
       remote_devices_map_;
@@ -138,9 +129,6 @@
   // True if the system is suspended.
   bool suspended_ = false;
 
-  // True if the screen is off.
-  bool screen_off_ = false;
-
   // True if the system is started_.
   bool started_ = false;
 };
diff --git a/chromeos/ash/components/proximity_auth/proximity_auth_system_unittest.cc b/chromeos/ash/components/proximity_auth/proximity_auth_system_unittest.cc
index f6c761d..efe11af8 100644
--- a/chromeos/ash/components/proximity_auth/proximity_auth_system_unittest.cc
+++ b/chromeos/ash/components/proximity_auth/proximity_auth_system_unittest.cc
@@ -6,7 +6,6 @@
 
 #include <memory>
 
-#include "ash/constants/ash_features.h"
 #include "base/command_line.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/test_simple_task_runner.h"
@@ -199,12 +198,6 @@
     task_runner_->RunUntilIdle();
   }
 
-  void SimulateScreenOff() {
-    proximity_auth_system_->OnScreenOff();
-    proximity_auth_system_->OnScreenOffDone();
-    task_runner_->RunUntilIdle();
-  }
-
   FakeRemoteDeviceLifeCycle* life_cycle() {
     return proximity_auth_system_->life_cycle();
   }
@@ -444,39 +437,4 @@
       .Times(AtLeast(1));
 }
 
-TEST_F(ProximityAuthSystemTest, ScreenOff_ScreenUnlocked) {
-  base::test::ScopedFeatureList feature_list(
-      ash::features::kSmartLockBluetoothScreenOffFix);
-  UnlockScreen();
-  EXPECT_FALSE(life_cycle());
-  SimulateScreenOff();
-  EXPECT_FALSE(life_cycle());
-}
-
-TEST_F(ProximityAuthSystemTest, ScreenOff_UnregisteredUserFocused) {
-  base::test::ScopedFeatureList feature_list(
-      ash::features::kSmartLockBluetoothScreenOffFix);
-  SimulateScreenOff();
-  EXPECT_FALSE(life_cycle());
-}
-
-TEST_F(ProximityAuthSystemTest, ScreenOff_RegisteredUserFocused) {
-  base::test::ScopedFeatureList feature_list(
-      ash::features::kSmartLockBluetoothScreenOffFix);
-  FocusUser(kUser1);
-
-  {
-    InSequence sequence;
-    EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(nullptr))
-        .Times(AtLeast(1));
-    EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(NotNull()));
-    SimulateScreenOff();
-  }
-
-  EXPECT_EQ(kUser1, life_cycle()->GetRemoteDevice().user_email());
-
-  EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(nullptr))
-      .Times(AtLeast(1));
-}
-
 }  // namespace proximity_auth
diff --git a/chromeos/chromeos_strings.grd b/chromeos/chromeos_strings.grd
index 720b6463..b6a04506 100644
--- a/chromeos/chromeos_strings.grd
+++ b/chromeos/chromeos_strings.grd
@@ -3483,10 +3483,7 @@
       <message name="IDS_FEEDBACK_TOOL_ATTACH_FILES_LABEL" desc="Label for adding a screenshot and/or a filename.">
         Attach files
       </message>
-      <message name="IDS_FEEDBACK_TOOL_REPLACE_FILE_LABEL" desc="Label for replacing a file.">
-        Replace
-      </message>
-      <message name="IDS_FEEDBACK_TOOL_REPLACE_FILE_ARIA_LABEL" desc="Aria Label of the replace file button">
+      <message name="IDS_FEEDBACK_TOOL_REPLACE_FILE_LABEL" desc="Label of the replace file button">
         Replace file
       </message>
       <message name="IDS_FEEDBACK_TOOL_ADD_FILE_LABEL" desc="Label for the field of adding a file">
diff --git a/chromeos/chromeos_strings_grd/IDS_FEEDBACK_TOOL_REPLACE_FILE_ARIA_LABEL.png.sha1 b/chromeos/chromeos_strings_grd/IDS_FEEDBACK_TOOL_REPLACE_FILE_ARIA_LABEL.png.sha1
deleted file mode 100644
index c05c773..0000000
--- a/chromeos/chromeos_strings_grd/IDS_FEEDBACK_TOOL_REPLACE_FILE_ARIA_LABEL.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-b6c67bd7f2be57a8632d56ef341cda6debacdb6e
\ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_FEEDBACK_TOOL_REPLACE_FILE_LABEL.png.sha1 b/chromeos/chromeos_strings_grd/IDS_FEEDBACK_TOOL_REPLACE_FILE_LABEL.png.sha1
index 9ce6fca..837e2a5 100644
--- a/chromeos/chromeos_strings_grd/IDS_FEEDBACK_TOOL_REPLACE_FILE_LABEL.png.sha1
+++ b/chromeos/chromeos_strings_grd/IDS_FEEDBACK_TOOL_REPLACE_FILE_LABEL.png.sha1
@@ -1 +1 @@
-b9e77c3468222a22a11a2f50dc0b509a78cb7016
\ No newline at end of file
+15efeb17d24df17c91755575c0807edbcbf37900
\ No newline at end of file
diff --git a/chromeos/services/machine_learning/DIR_METADATA b/chromeos/services/machine_learning/DIR_METADATA
index 52fe2b8d..7265f43 100644
--- a/chromeos/services/machine_learning/DIR_METADATA
+++ b/chromeos/services/machine_learning/DIR_METADATA
@@ -1,4 +1,4 @@
-monorail {
-  component: "UI>ML>Service"
+buganizer: {
+  component_id: 1179044
 }
 team_email: "ml-service-team@google.com"
diff --git a/chromeos/tast_control.gni b/chromeos/tast_control.gni
index 20e7181..9a7deb0 100644
--- a/chromeos/tast_control.gni
+++ b/chromeos/tast_control.gni
@@ -318,7 +318,6 @@
   # https://crbug.com/1373329
   "peripherals.LaunchAppFromSettings.scan",
   "policy.AllowedLanguages",
-  "terminal.Crosh",
 
   # https://crbug.com/1374943
   "hwsec.CrossVersionLogin",
diff --git a/components/assist_ranker/DIR_METADATA b/components/assist_ranker/DIR_METADATA
index 67c16ad..2b2d26b 100644
--- a/components/assist_ranker/DIR_METADATA
+++ b/components/assist_ranker/DIR_METADATA
@@ -1,3 +1,3 @@
-monorail {
-  component: "UI>ML"
+buganizer: {
+  component_id: 1257105
 }
diff --git a/components/autofill/core/browser/payments/credit_card_access_manager.cc b/components/autofill/core/browser/payments/credit_card_access_manager.cc
index 31b3100..c361f5f 100644
--- a/components/autofill/core/browser/payments/credit_card_access_manager.cc
+++ b/components/autofill/core/browser/payments/credit_card_access_manager.cc
@@ -1192,11 +1192,13 @@
     case UnmaskAuthFlowType::kNone:
       flow_type = AutofillMetrics::VirtualCardUnmaskFlowType::kUnspecified;
       break;
-    case UnmaskAuthFlowType::kCvc:
     case UnmaskAuthFlowType::kFido:
     case UnmaskAuthFlowType::kCvcThenFido:
     case UnmaskAuthFlowType::kCvcFallbackFromFido:
       NOTREACHED();
+      ABSL_FALLTHROUGH_INTENDED;
+    case UnmaskAuthFlowType::kCvc:
+      // TODO(crbug/1370329): Add a flow type for the CVC flow for metrics.
       Reset();
       return;
   }
diff --git a/components/browser_ui/accessibility/android/java/res/layout/page_zoom_slider.xml b/components/browser_ui/accessibility/android/java/res/layout/page_zoom_slider.xml
index 736e7df..61e2af3 100644
--- a/components/browser_ui/accessibility/android/java/res/layout/page_zoom_slider.xml
+++ b/components/browser_ui/accessibility/android/java/res/layout/page_zoom_slider.xml
@@ -11,6 +11,7 @@
     android:layout_height="wrap_content"
     android:elevation="@dimen/page_zoom_view_elevation"
     android:gravity="center"
+    android:maxWidth="@dimen/page_zoom_view_max_width"
     android:orientation="horizontal" >
 
     <org.chromium.ui.widget.ChromeImageButton
diff --git a/components/browser_ui/accessibility/android/java/res/values/dimens.xml b/components/browser_ui/accessibility/android/java/res/values/dimens.xml
index 98cb18a..86ee1106 100644
--- a/components/browser_ui/accessibility/android/java/res/values/dimens.xml
+++ b/components/browser_ui/accessibility/android/java/res/values/dimens.xml
@@ -13,4 +13,5 @@
     <dimen name="page_zoom_view_level_padding">12dp</dimen>
     <dimen name="page_zoom_view_elevation">4dp</dimen>
     <dimen name="page_zoom_view_corner_radius">44dp</dimen>
+    <dimen name="page_zoom_view_max_width">300dp</dimen>
 </resources>
\ No newline at end of file
diff --git a/components/cronet/android/lint-baseline.xml b/components/cronet/android/lint-baseline.xml
index de209d95..4ce94a3 100644
--- a/components/cronet/android/lint-baseline.xml
+++ b/components/cronet/android/lint-baseline.xml
@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 7.4.0-alpha05" type="baseline" client="" dependencies="true" name="" variant="all" version="7.4.0-alpha05">
+<issues format="6" by="lint 8.0.0-alpha06" type="baseline" client="" dependencies="true" name="" variant="all" version="8.0.0-alpha06">
 
     <issue
         id="LintError"
-        message="../../components/cronet/android/lint-baseline.xml (relative to /usr/local/google/home/wnwen/z1/src/out/Cronet) does not exist"
+        message="../../components/cronet/android/lint-baseline.xml (relative to /usr/local/google/code/clankium/src/out/Lint-Default) does not exist"
         errorLine1="  &lt;baseline file=&quot;../../components/cronet/android/lint-baseline.xml&quot;/>"
         errorLine2="  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
@@ -18,8 +18,8 @@
         errorLine1="@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) // TrafficStats only available on ICS"
         errorLine2="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/cronet/android/java/src/org/chromium/net/impl/JavaUrlRequest.java"
-            line="50"
+            file="../../components/cronet/android/java/src/org/chromium/net/impl/JavaUrlRequest.java"
+            line="54"
             column="1"/>
     </issue>
 
@@ -29,7 +29,7 @@
         errorLine1="        assert calledOnValidThread();"
         errorLine2="               ~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/cronet/android/java/src/org/chromium/net/urlconnection/MessageLoop.java"
+            file="../../components/cronet/android/java/src/org/chromium/net/urlconnection/MessageLoop.java"
             line="100"
             column="16"/>
     </issue>
@@ -40,7 +40,7 @@
         errorLine1="        assert calledOnValidThread();"
         errorLine2="               ~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/components/cronet/android/java/src/org/chromium/net/urlconnection/MessageLoop.java"
+            file="../../components/cronet/android/java/src/org/chromium/net/urlconnection/MessageLoop.java"
             line="143"
             column="16"/>
     </issue>
diff --git a/components/history_clusters/core/query_clusters_state.cc b/components/history_clusters/core/query_clusters_state.cc
index d3bf4ad..c4eedffe 100644
--- a/components/history_clusters/core/query_clusters_state.cc
+++ b/components/history_clusters/core/query_clusters_state.cc
@@ -149,10 +149,14 @@
   // than just doing this simple computation on the main thread.
   UpdateUniqueRawLabels(clusters);
 
+  size_t clusters_size = clusters.size();
+
+  bool is_continuation = number_clusters_sent_to_page_ > 0;
   std::move(callback).Run(query_, std::move(clusters),
                           !continuation_params.exhausted_all_visits,
-                          is_continuation_);
-  is_continuation_ = true;
+                          is_continuation);
+
+  number_clusters_sent_to_page_ += clusters_size;
 
   // Log metrics after delivering the results to the page.
   base::TimeDelta service_latency = base::TimeTicks::Now() - query_start_time;
diff --git a/components/history_clusters/core/query_clusters_state.h b/components/history_clusters/core/query_clusters_state.h
index 5ca569f..219f7a0d 100644
--- a/components/history_clusters/core/query_clusters_state.h
+++ b/components/history_clusters/core/query_clusters_state.h
@@ -54,6 +54,10 @@
   // Returns the current query the state contains.
   const std::string& query() const { return query_; }
 
+  size_t number_clusters_sent_to_page() const {
+    return number_clusters_sent_to_page_;
+  }
+
   // Used to request another batch of clusters of the same query.
   void LoadNextBatchOfClusters(ResultCallback callback);
 
@@ -111,8 +115,9 @@
   // query for the "next page".
   QueryClustersContinuationParams continuation_params_;
 
-  // True for all 'next-page' responses, but false for the first page.
-  bool is_continuation_ = false;
+  // The number of clusters that have already been sent to the page. This is
+  // updated AFTER the callback for each batch.
+  size_t number_clusters_sent_to_page_ = 0;
 
   // Used only to fast-cancel tasks in case we are destroyed.
   std::unique_ptr<HistoryClustersServiceTaskGetMostRecentClusters>
diff --git a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerViewTest.java b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerViewTest.java
index 2e505d27..be41223 100644
--- a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerViewTest.java
+++ b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerViewTest.java
@@ -156,7 +156,7 @@
     @Test
     @MediumTest
     public void testSecondaryActionMenuInvokesPopupMenuEventHandlers() {
-        PopupMenuShownListener listener = Mockito.spy(PopupMenuShownListener.class);
+        PopupMenuShownListener listener = Mockito.mock(PopupMenuShownListener.class);
         TestThreadUtils.runOnUiThreadBlocking(() -> {
             PropertyModel propertyModel =
                     new PropertyModel.Builder(MessageBannerProperties.ALL_KEYS)
diff --git a/components/metrics/metrics_log_store.cc b/components/metrics/metrics_log_store.cc
index 4ac52a3..07b729c 100644
--- a/components/metrics/metrics_log_store.cc
+++ b/components/metrics/metrics_log_store.cc
@@ -47,14 +47,34 @@
 MetricsLogStore::~MetricsLogStore() {}
 
 void MetricsLogStore::LoadPersistedUnsentLogs() {
-  initial_log_queue_.LoadPersistedUnsentLogs();
-  ongoing_log_queue_.LoadPersistedUnsentLogs();
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  {
+    MetricsLogsEventManager::ScopedNotifyLogType scoped_log_type(
+        logs_event_manager_, MetricsLog::LogType::INITIAL_STABILITY_LOG);
+    initial_log_queue_.LoadPersistedUnsentLogs();
+  }
+
+  {
+    // Note that we assume that logs loaded from the persistent storage for
+    // |ongoing_log_queue_| are of type "ongoing". They could, however, be
+    // independent logs, but we unfortunately cannot determine this since we
+    // don't persist the type of log.
+    MetricsLogsEventManager::ScopedNotifyLogType scoped_log_type(
+        logs_event_manager_, MetricsLog::LogType::ONGOING_LOG);
+    ongoing_log_queue_.LoadPersistedUnsentLogs();
+  }
+
   unsent_logs_loaded_ = true;
 }
 
 void MetricsLogStore::StoreLog(const std::string& log_data,
                                MetricsLog::LogType log_type,
                                const LogMetadata& log_metadata) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  MetricsLogsEventManager::ScopedNotifyLogType scoped_log_type(
+      logs_event_manager_, log_type);
   switch (log_type) {
     case MetricsLog::INITIAL_STABILITY_LOG:
       initial_log_queue_.StoreLog(log_data, log_metadata);
@@ -70,10 +90,19 @@
 
 void MetricsLogStore::SetAlternateOngoingLogStore(
     std::unique_ptr<UnsentLogStore> log_store) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
   DCHECK(!has_alternate_ongoing_log_store());
   DCHECK(unsent_logs_loaded_);
   alternate_ongoing_log_queue_ = std::move(log_store);
   alternate_ongoing_log_queue_->SetLogsEventManager(logs_event_manager_);
+
+  // Note that we assume that logs loaded from the persistent storage for
+  // |alternate_ongoing_log_queue_| are of type "ongoing". They could, however,
+  // be independent logs, but we unfortunately cannot determine this since we
+  // don't persist the type of log.
+  MetricsLogsEventManager::ScopedNotifyLogType scoped_log_type(
+      logs_event_manager_, MetricsLog::LogType::ONGOING_LOG);
   alternate_ongoing_log_queue_->LoadPersistedUnsentLogs();
 }
 
diff --git a/components/metrics/metrics_log_store.h b/components/metrics/metrics_log_store.h
index f9daf194..fe06342 100644
--- a/components/metrics/metrics_log_store.h
+++ b/components/metrics/metrics_log_store.h
@@ -9,6 +9,7 @@
 #include <string>
 
 #include "base/metrics/histogram_base.h"
+#include "base/sequence_checker.h"
 #include "components/metrics/log_store.h"
 #include "components/metrics/metrics_log.h"
 #include "components/metrics/metrics_logs_event_manager.h"
@@ -145,6 +146,8 @@
   // been sent yet. If initialized, all logs of type ONGOING_LOG will be stored
   // here instead of |ongoing_log_queue_|.
   std::unique_ptr<UnsentLogStore> alternate_ongoing_log_queue_;
+
+  SEQUENCE_CHECKER(sequence_checker_);
 };
 
 }  // namespace metrics
diff --git a/components/metrics/metrics_logs_event_manager.cc b/components/metrics/metrics_logs_event_manager.cc
index ba793e6..2a06ecd 100644
--- a/components/metrics/metrics_logs_event_manager.cc
+++ b/components/metrics/metrics_logs_event_manager.cc
@@ -6,8 +6,27 @@
 
 namespace metrics {
 
-MetricsLogsEventManager::MetricsLogsEventManager() = default;
+// static
+bool MetricsLogsEventManager::ScopedNotifyLogType::instance_exists_ = false;
 
+MetricsLogsEventManager::ScopedNotifyLogType::ScopedNotifyLogType(
+    MetricsLogsEventManager* logs_event_manager,
+    MetricsLog::LogType log_type)
+    : logs_event_manager_(logs_event_manager) {
+  DCHECK(!instance_exists_);
+  instance_exists_ = true;
+  if (logs_event_manager_)
+    logs_event_manager_->NotifyLogType(log_type);
+}
+
+MetricsLogsEventManager::ScopedNotifyLogType::~ScopedNotifyLogType() {
+  DCHECK(instance_exists_);
+  if (logs_event_manager_)
+    logs_event_manager_->NotifyLogType(absl::nullopt);
+  instance_exists_ = false;
+}
+
+MetricsLogsEventManager::MetricsLogsEventManager() = default;
 MetricsLogsEventManager::~MetricsLogsEventManager() = default;
 
 void MetricsLogsEventManager::AddObserver(Observer* observer) {
@@ -33,4 +52,10 @@
     observer.OnLogEvent(event, log_hash, message);
 }
 
+void MetricsLogsEventManager::NotifyLogType(
+    absl::optional<MetricsLog::LogType> log_type) {
+  for (Observer& observer : observers_)
+    observer.OnLogType(log_type);
+}
+
 }  // namespace metrics
diff --git a/components/metrics/metrics_logs_event_manager.h b/components/metrics/metrics_logs_event_manager.h
index 424c963..26983ce 100644
--- a/components/metrics/metrics_logs_event_manager.h
+++ b/components/metrics/metrics_logs_event_manager.h
@@ -7,6 +7,8 @@
 
 #include "base/observer_list.h"
 #include "base/strings/string_piece.h"
+#include "components/metrics/metrics_log.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace metrics {
 
@@ -35,12 +37,33 @@
     virtual void OnLogEvent(MetricsLogsEventManager::LogEvent event,
                             base::StringPiece log_hash,
                             base::StringPiece message) = 0;
+    virtual void OnLogType(absl::optional<MetricsLog::LogType> log_type) {}
 
    protected:
     Observer() = default;
     ~Observer() override = default;
   };
 
+  // Helper class used to indicate that UMA logs created while an instance of
+  // this class is in scope are of a certain type. Only one instance of this
+  // class should exist at a time.
+  class ScopedNotifyLogType {
+   public:
+    ScopedNotifyLogType(MetricsLogsEventManager* logs_event_manager,
+                        MetricsLog::LogType log_type);
+
+    ScopedNotifyLogType(const ScopedNotifyLogType& other) = delete;
+    ScopedNotifyLogType& operator=(const ScopedNotifyLogType& other) = delete;
+
+    ~ScopedNotifyLogType();
+
+   private:
+    MetricsLogsEventManager* const logs_event_manager_;
+
+    // Used to ensure that only one instance of this class exists at a time.
+    static bool instance_exists_;
+  };
+
   MetricsLogsEventManager();
 
   MetricsLogsEventManager(const MetricsLogsEventManager&) = delete;
@@ -72,6 +95,15 @@
                       base::StringPiece log_hash,
                       base::StringPiece message = "");
 
+  // Notifies observers that logs that are created after this function is called
+  // are of the type |log_type|. This should only be used in UMA. This info is
+  // not passed through NotifyLogCreated() because the concept of a log type
+  // only exists in UMA, and this class is intended to be re-used across
+  // different metrics collection services (e.g., UKM).
+  // Note: Typically, this should not be called directly. Consider using
+  // ScopedNotifyLogType.
+  void NotifyLogType(absl::optional<MetricsLog::LogType> log_type);
+
  private:
   base::ObserverList<Observer> observers_;
 };
diff --git a/components/metrics/metrics_service_observer.cc b/components/metrics/metrics_service_observer.cc
index c913849d..2199e44 100644
--- a/components/metrics/metrics_service_observer.cc
+++ b/components/metrics/metrics_service_observer.cc
@@ -13,6 +13,18 @@
 namespace metrics {
 namespace {
 
+std::string LogTypeToString(MetricsLog::LogType log_type) {
+  switch (log_type) {
+    case MetricsLog::LogType::INDEPENDENT_LOG:
+      return "Independent";
+    case MetricsLog::LogType::INITIAL_STABILITY_LOG:
+      return "Stability";
+    case MetricsLog::LogType::ONGOING_LOG:
+      return "Ongoing";
+  }
+  NOTREACHED();
+}
+
 std::string EventToString(MetricsLogsEventManager::LogEvent event) {
   switch (event) {
     case MetricsLogsEventManager::LogEvent::kLogStaged:
@@ -56,6 +68,11 @@
   log->hash = std::string(log_hash);
   log->timestamp = std::string(log_timestamp);
   log->data = std::string(log_data);
+  if (uma_log_type_.has_value()) {
+    DCHECK_EQ(service_type_, MetricsServiceType::UMA);
+    log->type = uma_log_type_;
+  }
+
   indexed_logs_.emplace(log->hash, log.get());
   logs_.push_back(std::move(log));
 }
@@ -79,6 +96,11 @@
   log->events.push_back(std::move(log_event));
 }
 
+void MetricsServiceObserver::OnLogType(
+    absl::optional<MetricsLog::LogType> log_type) {
+  uma_log_type_ = log_type;
+}
+
 bool MetricsServiceObserver::ExportLogsAsJson(bool include_log_proto_data,
                                               std::string* json_output) {
   base::Value::List logs_list;
@@ -86,6 +108,10 @@
   for (const std::unique_ptr<Log>& log : logs_) {
     base::Value::Dict log_dict;
 
+    if (log->type.has_value()) {
+      DCHECK_EQ(service_type_, MetricsServiceType::UMA);
+      log_dict.Set("type", LogTypeToString(log->type.value()));
+    }
     log_dict.Set("hash", base::HexEncode(log->hash.data(), log->hash.length()));
     log_dict.Set("timestamp", log->timestamp);
 
diff --git a/components/metrics/metrics_service_observer.h b/components/metrics/metrics_service_observer.h
index ae4e490..115eeea 100644
--- a/components/metrics/metrics_service_observer.h
+++ b/components/metrics/metrics_service_observer.h
@@ -73,6 +73,10 @@
 
     // A list of the events that occurred throughout the log's lifetime.
     std::vector<Event> events;
+
+    // The type of log (stability, ongoing, independent). This is only set if
+    // this log is a UMA log.
+    absl::optional<MetricsLog::LogType> type;
   };
 
   // |service_type| is the type of service this observer will be observing from.
@@ -90,6 +94,7 @@
   void OnLogEvent(MetricsLogsEventManager::LogEvent event,
                   base::StringPiece log_hash,
                   base::StringPiece message) override;
+  void OnLogType(absl::optional<MetricsLog::LogType> log_type) override;
 
   // Exports |logs_| to a JSON string and writes it to |json_output|. If
   // |include_log_proto_data| is true, the protos of the logs will be included.
@@ -99,6 +104,7 @@
   //   log_type: string, // e.g. "UMA" or "UKM"
   //   logs: [
   //     {
+  //       type?: string, // e.g. "Ongoing" (set only for UMA logs)
   //       hash: string,
   //       timestamp: string,
   //       data: string, // set if |include_log_proto_data| is true
@@ -141,6 +147,11 @@
   // An overlay on |logs_| that allows for a log to be located based on its
   // hash.
   base::flat_map<base::StringPiece, Log*> indexed_logs_;
+
+  // Keeps track of the type of UMA logs (ongoing, stability, independent) that
+  // are being created. This should only be set for UMA logs, since the concept
+  // of log type only exists in UMA.
+  absl::optional<MetricsLog::LogType> uma_log_type_;
 };
 
 }  // namespace metrics
diff --git a/components/metrics/metrics_service_observer_unittest.cc b/components/metrics/metrics_service_observer_unittest.cc
index 5d5171b1..08f59715 100644
--- a/components/metrics/metrics_service_observer_unittest.cc
+++ b/components/metrics/metrics_service_observer_unittest.cc
@@ -8,10 +8,13 @@
 #include "base/test/test_simple_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "components/metrics/metrics_log.h"
+#include "components/metrics/metrics_logs_event_manager.h"
+#include "components/metrics/metrics_pref_names.h"
 #include "components/metrics/metrics_service.h"
 #include "components/metrics/metrics_state_manager.h"
 #include "components/metrics/test/test_enabled_state_provider.h"
 #include "components/metrics/test/test_metrics_service_client.h"
+#include "components/metrics/unsent_log_store_metrics_impl.h"
 #include "components/prefs/testing_pref_service.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -296,6 +299,152 @@
   service.RemoveLogsObserver(&logs_observer);
 }
 
+// Verifies that logs created through MetricsLogStore, which is used by UMA, are
+// annotated with a type (ongoing, independent, or stability).
+TEST_F(MetricsServiceObserverTest, UmaLogType) {
+  // Verify that logs created through MetricsLogStore::StoreLog() will be
+  // annotated with a type.
+  {
+    MetricsLogsEventManager logs_event_manager;
+    TestMetricsServiceClient client;
+    MetricsLogStore test_log_store(local_state(), client.GetStorageLimits(),
+                                   client.GetUploadSigningKey(),
+                                   &logs_event_manager);
+
+    // Create a MetricsServiceObserver that will observe UMA logs from
+    // |test_log_store|, which notifies through |logs_event_manager|.
+    MetricsServiceObserver logs_observer(
+        MetricsServiceObserver::MetricsServiceType::UMA);
+    logs_event_manager.AddObserver(&logs_observer);
+
+    // Load logs from persistent storage, which is needed to internally
+    // initialize |test_log_store|. There should be no logs loaded.
+    test_log_store.LoadPersistedUnsentLogs();
+    std::vector<std::unique_ptr<MetricsServiceObserver::Log>>* logs =
+        logs_observer.logs_for_testing();
+    EXPECT_EQ(logs->size(), 0U);
+
+    test_log_store.StoreLog("Ongoing Log", MetricsLog::LogType::ONGOING_LOG,
+                            LogMetadata());
+    ASSERT_EQ(logs->size(), 1U);
+    ASSERT_TRUE(logs->back()->type.has_value());
+    EXPECT_EQ(logs->back()->type.value(), MetricsLog::LogType::ONGOING_LOG);
+    test_log_store.StoreLog(
+        "Independent Log", MetricsLog::LogType::INDEPENDENT_LOG, LogMetadata());
+    ASSERT_EQ(logs->size(), 2U);
+    ASSERT_TRUE(logs->back()->type.has_value());
+    EXPECT_EQ(logs->back()->type.value(), MetricsLog::LogType::INDEPENDENT_LOG);
+    test_log_store.StoreLog("Stability Log",
+                            MetricsLog::LogType::INITIAL_STABILITY_LOG,
+                            LogMetadata());
+    ASSERT_EQ(logs->size(), 3U);
+    ASSERT_TRUE(logs->back()->type.has_value());
+    EXPECT_EQ(logs->back()->type.value(),
+              MetricsLog::LogType::INITIAL_STABILITY_LOG);
+
+    // Store logs in persistent storage, in preparation for the next assertions.
+    test_log_store.TrimAndPersistUnsentLogs(/*overwrite_in_memory_store=*/true);
+
+    logs_event_manager.RemoveObserver(&logs_observer);
+  }
+
+  // Verify that logs loaded from persistent storage are annotated with a type.
+  {
+    MetricsLogsEventManager logs_event_manager;
+    TestMetricsServiceClient client;
+    MetricsLogStore test_log_store(local_state(), client.GetStorageLimits(),
+                                   client.GetUploadSigningKey(),
+                                   &logs_event_manager);
+
+    // Create a MetricsServiceObserver that will observe UMA logs from
+    // |test_log_store|, which notifies through |logs_event_manager|.
+    MetricsServiceObserver logs_observer(
+        MetricsServiceObserver::MetricsServiceType::UMA);
+    logs_event_manager.AddObserver(&logs_observer);
+
+    // Load logs from persistent storage, which were created previously.
+    std::vector<std::unique_ptr<MetricsServiceObserver::Log>>* logs =
+        logs_observer.logs_for_testing();
+    EXPECT_EQ(logs->size(), 0U);
+    test_log_store.LoadPersistedUnsentLogs();
+
+    // Verify that logs were observed by |logs_observer|, and that they were
+    // annotated with a type. There should be 3 logs. Note that the order in
+    // which the logs are loaded (stability first, then ongoing) is hardcoded in
+    // MetricsLogStore. Further, the "independent" log should have become an
+    // "ongoing" log (due to limitations on how logs are stored in persistent
+    // storage).
+    ASSERT_EQ(logs->size(), 3U);
+    ASSERT_TRUE(logs->at(0)->type.has_value());
+    EXPECT_EQ(logs->at(0)->type.value(),
+              MetricsLog::LogType::INITIAL_STABILITY_LOG);
+    ASSERT_TRUE(logs->at(1)->type.has_value());
+    EXPECT_EQ(logs->at(1)->type.value(), MetricsLog::LogType::ONGOING_LOG);
+    ASSERT_TRUE(logs->at(2)->type.has_value());
+    EXPECT_EQ(logs->at(2)->type.value(), MetricsLog::LogType::ONGOING_LOG);
+
+    logs_event_manager.RemoveObserver(&logs_observer);
+  }
+
+  // Verify that when loading logs from persistent storage after setting an
+  // "alternate ongoing log store", the logs are annotated with a type.
+  {
+    MetricsLogsEventManager logs_event_manager;
+    TestMetricsServiceClient client;
+    MetricsLogStore::StorageLimits storage_limits = client.GetStorageLimits();
+    MetricsLogStore test_log_store(local_state(), storage_limits,
+                                   client.GetUploadSigningKey(),
+                                   &logs_event_manager);
+
+    // Load logs from persistent storage, which is needed to internally
+    // initialize |test_log_store|. There should be 3 logs loaded (however, we
+    // do not care about them).
+    test_log_store.LoadPersistedUnsentLogs();
+
+    // Create a MetricsServiceObserver that will observe UMA logs from
+    // |test_log_store|, which notifies through |logs_event_manager|.
+    MetricsServiceObserver logs_observer(
+        MetricsServiceObserver::MetricsServiceType::UMA);
+    logs_event_manager.AddObserver(&logs_observer);
+
+    // Verify that |logs_observer| is not aware of any logs (since we started
+    // observing *after* logs from persistent storage were loaded).
+    std::vector<std::unique_ptr<MetricsServiceObserver::Log>>* logs =
+        logs_observer.logs_for_testing();
+    EXPECT_EQ(logs->size(), 0U);
+
+    // Create an UnsentLogStore, which will be used as the "alternate ongoing
+    // log store". This log store will read from the same persistent storage as
+    // a "normal" ongoing log queue.
+    auto alternate_ongoing_log_store = std::make_unique<UnsentLogStore>(
+        std::make_unique<UnsentLogStoreMetricsImpl>(), local_state(),
+        prefs::kMetricsOngoingLogs, prefs::kMetricsOngoingLogsMetadata,
+        storage_limits.min_ongoing_log_queue_count,
+        storage_limits.min_ongoing_log_queue_size,
+        storage_limits.max_ongoing_log_size, client.GetUploadSigningKey(),
+        // |logs_event_manager| will be set by |test_log_store| directly in
+        // MetricsLogStore::SetAlternateOngoingLogStore().
+        /*logs_event_manager=*/nullptr);
+
+    // Set the alternate ongoing log store of |test_log_store|. This should load
+    // logs from persistent storage.
+    test_log_store.SetAlternateOngoingLogStore(
+        std::move(alternate_ongoing_log_store));
+
+    // Verify that logs were observed by |logs_observer|, and that they were
+    // annotated with a type. There should be 2 logs. The "independent" log
+    // should have become an "ongoing" log (due to limitations on how logs are
+    // stored in persistent storage).
+    ASSERT_EQ(logs->size(), 2U);
+    ASSERT_TRUE(logs->at(0)->type.has_value());
+    EXPECT_EQ(logs->at(0)->type.value(), MetricsLog::LogType::ONGOING_LOG);
+    ASSERT_TRUE(logs->at(1)->type.has_value());
+    EXPECT_EQ(logs->at(1)->type.value(), MetricsLog::LogType::ONGOING_LOG);
+
+    logs_event_manager.RemoveObserver(&logs_observer);
+  }
+}
+
 INSTANTIATE_TEST_SUITE_P(MetricsServiceObserverExportTests,
                          MetricsServiceObserverExportTest,
                          testing::Bool());
@@ -361,6 +510,11 @@
   ASSERT_TRUE(log_value.is_dict());
   base::Value::Dict& log_dict = log_value.GetDict();
 
+  base::Value* uma_log_type = log_dict.Find("type");
+  ASSERT_TRUE(uma_log_type);
+  ASSERT_TRUE(uma_log_type->is_string());
+  EXPECT_EQ(uma_log_type->GetString(), "Ongoing");
+
   base::Value* log_hash = log_dict.Find("hash");
   ASSERT_TRUE(log_hash);
   ASSERT_TRUE(log_hash->is_string());
diff --git a/components/metrics/serialization/serialization_utils.cc b/components/metrics/serialization/serialization_utils.cc
index 174fda6..470bbe10 100644
--- a/components/metrics/serialization/serialization_utils.cc
+++ b/components/metrics/serialization/serialization_utils.cc
@@ -186,7 +186,7 @@
     return false;
 
   base::ScopedFD file_descriptor(open(filename.c_str(),
-                                      O_WRONLY | O_APPEND | O_CREAT,
+                                      O_WRONLY | O_APPEND | O_CREAT | O_CLOEXEC,
                                       READ_WRITE_ALL_FILE_FLAGS));
 
   if (file_descriptor.get() < 0) {
@@ -195,9 +195,12 @@
   }
 
   fchmod(file_descriptor.get(), READ_WRITE_ALL_FILE_FLAGS);
-  // Grab a lock to avoid chrome truncating the file
-  // underneath us. Keep the file locked as briefly as possible.
-  // Freeing file_descriptor will close the file and and remove the lock.
+  // Grab a lock to avoid chrome truncating the file underneath us. Keep the
+  // file locked as briefly as possible. Freeing file_descriptor will close the
+  // file and remove the lock IFF the process was not forked in the meantime,
+  // which will leave the flock hanging and deadlock the reporting until the
+  // forked process is killed otherwise. Thus we have to explicitly unlock the
+  // file below.
   if (HANDLE_EINTR(flock(file_descriptor.get(), LOCK_EX)) < 0) {
     DPLOG(ERROR) << "error locking: " << filename;
     return false;
@@ -208,6 +211,7 @@
   if (!base::CheckAdd(msg.length(), sizeof(uint32_t)).AssignIfValid(&size) ||
       size > kMessageMaxLength) {
     DPLOG(ERROR) << "cannot write message: too long: " << filename;
+    std::ignore = flock(file_descriptor.get(), LOCK_UN);
     return false;
   }
 
@@ -218,11 +222,13 @@
           file_descriptor.get(),
           base::as_bytes(base::make_span(&encoded_size, 1)))) {
     DPLOG(ERROR) << "error writing message length: " << filename;
+    std::ignore = flock(file_descriptor.get(), LOCK_UN);
     return false;
   }
 
   if (!base::WriteFileDescriptor(file_descriptor.get(), msg)) {
     DPLOG(ERROR) << "error writing message: " << filename;
+    std::ignore = flock(file_descriptor.get(), LOCK_UN);
     return false;
   }
 
diff --git a/components/omnibox/common/omnibox_features.cc b/components/omnibox/common/omnibox_features.cc
index 31aa5b4d..d2e0de59 100644
--- a/components/omnibox/common/omnibox_features.cc
+++ b/components/omnibox/common/omnibox_features.cc
@@ -361,7 +361,7 @@
 // given country/culture
 BASE_FEATURE(kSuggestionAnswersColorReverse,
              "SuggestionAnswersColorReverse",
-             base::FEATURE_ENABLED_BY_DEFAULT);
+             base::FEATURE_DISABLED_BY_DEFAULT);
 
 // If enabled, frequently visited sites are presented in form of a single row
 // with a carousel of tiles, instead of one URL per row.
diff --git a/components/policy/android/junit/src/org/chromium/components/policy/PolicyConverterTest.java b/components/policy/android/junit/src/org/chromium/components/policy/PolicyConverterTest.java
index 3aa47c2..ef368e6 100644
--- a/components/policy/android/junit/src/org/chromium/components/policy/PolicyConverterTest.java
+++ b/components/policy/android/junit/src/org/chromium/components/policy/PolicyConverterTest.java
@@ -24,7 +24,7 @@
  * Robolectric test for AbstractAppRestrictionsProvider.
  */
 @RunWith(BaseRobolectricTestRunner.class)
-@Config(manifest = Config.NONE, sdk = Build.VERSION_CODES.M)
+@Config(manifest = Config.NONE, sdk = Build.VERSION_CODES.N)
 public class PolicyConverterTest {
     @Rule
     public JniMocker mocker = new JniMocker();
diff --git a/components/policy/tools/syntax_check_policy_template_json.py b/components/policy/tools/syntax_check_policy_template_json.py
index 1b9188e..c4bce44 100755
--- a/components/policy/tools/syntax_check_policy_template_json.py
+++ b/components/policy/tools/syntax_check_policy_template_json.py
@@ -1806,7 +1806,8 @@
     for policy_changes in policy_change_list:
       original_policy = policy_changes['old_policy']
       new_policy = policy_changes['new_policy']
-      new_policy['name'] = policy_changes['policy']
+      if new_policy:
+        new_policy['name'] = policy_changes['policy']
       if original_policy:
         original_policy['name'] = policy_changes['policy']
         (original_released_platforms,
diff --git a/components/power_bookmarks/core/BUILD.gn b/components/power_bookmarks/core/BUILD.gn
index 3e06ffe..d0cc63ed 100644
--- a/components/power_bookmarks/core/BUILD.gn
+++ b/components/power_bookmarks/core/BUILD.gn
@@ -20,20 +20,40 @@
   public_deps = [ ":proto" ]
 
   deps = [
+    ":powers",
     "//base",
     "//base:i18n",
     "//components/bookmarks/browser",
     "//components/commerce/core:proto",
     "//components/keyed_service/core:core",
+    "//components/power_bookmarks/storage",
     "//ui/base",
     "//url",
   ]
 }
 
+static_library("powers") {
+  sources = [
+    "powers/power.cc",
+    "powers/power.h",
+    "powers/power_overview.cc",
+    "powers/power_overview.h",
+  ]
+
+  public_deps = [ ":proto" ]
+
+  deps = [
+    "//base",
+    "//url",
+  ]
+}
+
 proto_library("proto") {
   proto_in_dir = "//"
   sources = [
     "proto/power_bookmark_meta.proto",
+    "proto/power_specifics.proto",
+    "proto/save_specifics.proto",
     "proto/shopping_specifics.proto",
   ]
   deps = [ "//components/commerce/core:proto" ]
@@ -56,13 +76,16 @@
   sources = [
     "power_bookmark_service_unittest.cc",
     "power_bookmark_utils_unittest.cc",
+    "powers/power_unittest.cc",
   ]
 
   deps = [
     ":core",
+    ":powers",
     "//base/test:test_support",
     "//components/bookmarks/browser",
     "//components/bookmarks/test",
+    "//testing/gmock",
     "//testing/gtest",
   ]
 }
diff --git a/components/power_bookmarks/core/power_bookmark_service.cc b/components/power_bookmarks/core/power_bookmark_service.cc
index 080a405..47e7ec3 100644
--- a/components/power_bookmarks/core/power_bookmark_service.cc
+++ b/components/power_bookmarks/core/power_bookmark_service.cc
@@ -6,23 +6,80 @@
 
 #include "base/ranges/algorithm.h"
 #include "components/bookmarks/browser/bookmark_model.h"
+#include "components/power_bookmarks/core/power_bookmark_data_provider.h"
 #include "components/power_bookmarks/core/power_bookmark_utils.h"
+#include "components/power_bookmarks/core/powers/power.h"
+#include "components/power_bookmarks/core/powers/power_overview.h"
 #include "components/power_bookmarks/core/proto/power_bookmark_meta.pb.h"
+#include "components/power_bookmarks/storage/power_bookmark_backend.h"
 
 using bookmarks::BookmarkModel;
 using bookmarks::BookmarkNode;
 
 namespace power_bookmarks {
 
-PowerBookmarkService::PowerBookmarkService(BookmarkModel* model)
-    : model_(model) {
+PowerBookmarkService::PowerBookmarkService(
+    BookmarkModel* model,
+    const base::FilePath& database_dir,
+    scoped_refptr<base::SequencedTaskRunner> backend_task_runner)
+    : model_(model), backend_task_runner_(backend_task_runner) {
   if (model_)
     model_->AddObserver(this);
+
+  backend_ = base::SequenceBound<PowerBookmarkBackend>(backend_task_runner_,
+                                                       database_dir);
+  backend_.AsyncCall(&PowerBookmarkBackend::Init);
 }
 
 PowerBookmarkService::~PowerBookmarkService() {
   if (model_)
     model_->RemoveObserver(this);
+
+  backend_.AsyncCall(&PowerBookmarkBackend::Shutdown);
+  backend_task_runner_ = nullptr;
+}
+
+void PowerBookmarkService::GetPowersForURL(const GURL& url,
+                                           PowersCallback callback) {
+  backend_.AsyncCall(&PowerBookmarkBackend::GetPowersForURL)
+      .WithArgs(url)
+      .Then(std::move(callback));
+}
+
+void PowerBookmarkService::GetPowerOverviewsForType(
+    const PowerType& power_type,
+    PowerOverviewsCallback callback) {
+  backend_.AsyncCall(&PowerBookmarkBackend::GetPowerOverviewsForType)
+      .WithArgs(power_type)
+      .Then(std::move(callback));
+}
+
+void PowerBookmarkService::CreatePower(std::unique_ptr<Power> power,
+                                       SuccessCallback callback) {
+  backend_.AsyncCall(&PowerBookmarkBackend::CreatePower)
+      .WithArgs(std::move(power))
+      .Then(std::move(callback));
+}
+
+void PowerBookmarkService::UpdatePower(std::unique_ptr<Power> power,
+                                       SuccessCallback callback) {
+  backend_.AsyncCall(&PowerBookmarkBackend::UpdatePower)
+      .WithArgs(std::move(power))
+      .Then(std::move(callback));
+}
+
+void PowerBookmarkService::DeletePower(const base::GUID& guid,
+                                       SuccessCallback callback) {
+  backend_.AsyncCall(&PowerBookmarkBackend::DeletePower)
+      .WithArgs(guid)
+      .Then(std::move(callback));
+}
+
+void PowerBookmarkService::DeletePowersForURL(const GURL& url,
+                                              SuccessCallback callback) {
+  backend_.AsyncCall(&PowerBookmarkBackend::DeletePowersForURL)
+      .WithArgs(url)
+      .Then(std::move(callback));
 }
 
 void PowerBookmarkService::AddDataProvider(
diff --git a/components/power_bookmarks/core/power_bookmark_service.h b/components/power_bookmarks/core/power_bookmark_service.h
index fb5ec1d..3497fce 100644
--- a/components/power_bookmarks/core/power_bookmark_service.h
+++ b/components/power_bookmarks/core/power_bookmark_service.h
@@ -7,19 +7,69 @@
 
 #include <vector>
 
+#include "base/files/file_path.h"
+#include "base/functional/callback.h"
+#include "base/guid.h"
+#include "base/threading/sequence_bound.h"
 #include "components/bookmarks/browser/base_bookmark_model_observer.h"
-#include "components/bookmarks/browser/bookmark_model.h"
 #include "components/keyed_service/core/keyed_service.h"
-#include "components/power_bookmarks/core/power_bookmark_data_provider.h"
+#include "components/power_bookmarks/core/proto/save_specifics.pb.h"
+
+namespace bookmarks {
+class BookmarkModel;
+class BaseBookmarkModelObserver;
+}  // namespace bookmarks
 
 namespace power_bookmarks {
 
+class Power;
+class PowerOverview;
+class PowerBookmarkDataProvider;
+class PowerBookmarkBackend;
+
+using PowersCallback =
+    base::OnceCallback<void(std::vector<std::unique_ptr<Power>> powers)>;
+using PowerOverviewsCallback = base::OnceCallback<void(
+    std::vector<std::unique_ptr<PowerOverview>> power_overviews)>;
+using SuccessCallback = base::OnceCallback<void(bool success)>;
+
 class PowerBookmarkService : public KeyedService,
                              public bookmarks::BaseBookmarkModelObserver {
  public:
-  explicit PowerBookmarkService(bookmarks::BookmarkModel* model);
+  PowerBookmarkService(
+      bookmarks::BookmarkModel* model,
+      const base::FilePath& database_dir,
+      scoped_refptr<base::SequencedTaskRunner> backend_task_runner);
+  PowerBookmarkService(const PowerBookmarkService&) = delete;
+  PowerBookmarkService& operator=(const PowerBookmarkService&) = delete;
+
   ~PowerBookmarkService() override;
 
+  // Returns a vector of Powers for the given `url` through the given
+  // `callback`.
+  void GetPowersForURL(const GURL& url, PowersCallback callback);
+
+  // Returns a vector of PowerOverviews for the given `power_type` through the
+  // given `callback`.
+  void GetPowerOverviewsForType(const PowerType& power_type,
+                                PowerOverviewsCallback callback);
+
+  // Create the given `power` in the database. If it already exists, then it
+  // will be updated. Success of the operation is returned through the given
+  // `callback`.
+  void CreatePower(std::unique_ptr<Power> power, SuccessCallback callback);
+  // Update the given `power` in the database. If it doesn't exist, then it
+  // will be created instead. Success of the operation is returned through the
+  // given `callback`.
+  void UpdatePower(std::unique_ptr<Power> power, SuccessCallback callback);
+  // Delete the given `guid` in the database, if it exists. Success of the
+  // operation is returned through the given `callback`.
+  // TODO(crbug.com/1378793): Encapsulate the storage key if possible.
+  void DeletePower(const base::GUID& guid, SuccessCallback callback);
+  // Delete all powers for the given `url`. Success of the operation is
+  // returned through the given `callback`.
+  void DeletePowersForURL(const GURL& url, SuccessCallback callback);
+
   // Allow features to receive notification when a bookmark node is created to
   // add extra information. The `data_provider` can be removed with the remove
   // method.
@@ -35,6 +85,8 @@
 
  private:
   bookmarks::BookmarkModel* model_;
+  base::SequenceBound<PowerBookmarkBackend> backend_;
+  scoped_refptr<base::SequencedTaskRunner> backend_task_runner_;
 
   std::vector<PowerBookmarkDataProvider*> data_providers_;
 };
diff --git a/components/power_bookmarks/core/power_bookmark_service_unittest.cc b/components/power_bookmarks/core/power_bookmark_service_unittest.cc
index 8ad72eb..5c07d77 100644
--- a/components/power_bookmarks/core/power_bookmark_service_unittest.cc
+++ b/components/power_bookmarks/core/power_bookmark_service_unittest.cc
@@ -4,27 +4,52 @@
 
 #include <memory>
 
+#include "base/files/scoped_temp_dir.h"
+#include "base/task/sequenced_task_runner.h"
+#include "base/task/thread_pool.h"
+#include "base/test/mock_callback.h"
+#include "base/test/task_environment.h"
+#include "base/threading/sequenced_task_runner_handle.h"
 #include "components/bookmarks/browser/bookmark_model.h"
 #include "components/bookmarks/test/test_bookmark_client.h"
 #include "components/power_bookmarks/core/power_bookmark_data_provider.h"
 #include "components/power_bookmarks/core/power_bookmark_service.h"
+#include "components/power_bookmarks/core/powers/power.h"
+#include "components/power_bookmarks/core/powers/power_overview.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+using testing::_;
+using testing::IsEmpty;
+using testing::IsFalse;
+
 namespace power_bookmarks {
 
 class PowerBookmarkServiceTest : public testing::Test {
  protected:
   void SetUp() override {
+    ASSERT_TRUE(temp_directory_.CreateUniqueTempDir());
+
     model_ = bookmarks::TestBookmarkClient::CreateModel();
-    service_ = std::make_unique<PowerBookmarkService>(model_.get());
+    backend_task_runner_ = base::ThreadPool::CreateSequencedTaskRunner(
+        {base::MayBlock(), base::TaskPriority::BEST_EFFORT});
+
+    service_ = std::make_unique<PowerBookmarkService>(
+        model_.get(), temp_directory_.GetPath(), backend_task_runner_);
+    RunUntilIdle();
   }
 
   void TearDown() override {
-    // Manually free PowerBookmarkService because it uses BookmarkModel.
-    service_.reset();
+    ResetService();
+    RunUntilIdle();
+
+    EXPECT_TRUE(temp_directory_.Delete());
   }
 
+  void ResetService() { service_.reset(); }
+
+  void RunUntilIdle() { task_environment_.RunUntilIdle(); }
+
   PowerBookmarkService* service() { return service_.get(); }
 
   bookmarks::BookmarkModel* model() { return model_.get(); }
@@ -32,6 +57,10 @@
  private:
   std::unique_ptr<PowerBookmarkService> service_;
   std::unique_ptr<bookmarks::BookmarkModel> model_;
+
+  base::ScopedTempDir temp_directory_;
+  scoped_refptr<base::SequencedTaskRunner> backend_task_runner_;
+  base::test::TaskEnvironment task_environment_;
 };
 
 class MockDataProvider : public PowerBookmarkDataProvider {
@@ -45,8 +74,7 @@
   MockDataProvider data_provider;
   service()->AddDataProvider(&data_provider);
 
-  EXPECT_CALL(data_provider,
-              AttachMetadataForNewBookmark(testing::_, testing::_));
+  EXPECT_CALL(data_provider, AttachMetadataForNewBookmark(_, _));
 
   model()->AddNewURL(model()->bookmark_bar_node(), 0, u"Title",
                      GURL("https://example.com"));
@@ -56,9 +84,7 @@
   MockDataProvider data_provider;
   service()->AddDataProvider(&data_provider);
   service()->RemoveDataProvider(&data_provider);
-  EXPECT_CALL(data_provider,
-              AttachMetadataForNewBookmark(testing::_, testing::_))
-      .Times(0);
+  EXPECT_CALL(data_provider, AttachMetadataForNewBookmark(_, _)).Times(0);
 
   model()->AddNewURL(model()->bookmark_bar_node(), 0, u"Title",
                      GURL("https://example.com"));
@@ -76,4 +102,75 @@
                   GURL("https://example.com"));
 }
 
+TEST_F(PowerBookmarkServiceTest, Shutdown) {
+  ResetService();
+  // No errors should be thrown when shutting down the backend.
+}
+
+TEST_F(PowerBookmarkServiceTest, GetPowersForURL) {
+  base::MockCallback<PowersCallback> cb;
+  EXPECT_CALL(cb, Run(IsEmpty()));
+
+  service()->GetPowersForURL(GURL("https://google.com"), cb.Get());
+  RunUntilIdle();
+}
+
+TEST_F(PowerBookmarkServiceTest, GetPowerOverviewsForType) {
+  base::MockCallback<PowerOverviewsCallback> cb;
+  EXPECT_CALL(cb, Run(IsEmpty()));
+
+  service()->GetPowerOverviewsForType(PowerType::POWER_TYPE_MOCK, cb.Get());
+  RunUntilIdle();
+}
+
+TEST_F(PowerBookmarkServiceTest, CreatePower) {
+  base::MockCallback<SuccessCallback> cb;
+  EXPECT_CALL(cb, Run(IsFalse()));
+
+  std::unique_ptr<PowerSpecifics> power_specifics =
+      std::make_unique<PowerSpecifics>();
+  std::unique_ptr<Power> power =
+      std::make_unique<Power>(std::move(power_specifics));
+  power->set_url(GURL("https://google.com"));
+  power->set_power_type(PowerType::POWER_TYPE_MOCK);
+  service()->CreatePower(std::move(power), cb.Get());
+  RunUntilIdle();
+}
+
+TEST_F(PowerBookmarkServiceTest, UpdatePower) {
+  base::MockCallback<SuccessCallback> cb;
+  EXPECT_CALL(cb, Run(IsFalse()));
+
+  std::unique_ptr<PowerSpecifics> power_specifics =
+      std::make_unique<PowerSpecifics>();
+  std::unique_ptr<Power> power =
+      std::make_unique<Power>(std::move(power_specifics));
+  power->set_url(GURL("https://google.com"));
+  power->set_power_type(PowerType::POWER_TYPE_MOCK);
+  service()->UpdatePower(std::move(power), cb.Get());
+  RunUntilIdle();
+}
+
+TEST_F(PowerBookmarkServiceTest, DeletePower) {
+  base::MockCallback<SuccessCallback> cb;
+  EXPECT_CALL(cb, Run(IsFalse()));
+
+  std::unique_ptr<PowerSpecifics> power_specifics =
+      std::make_unique<PowerSpecifics>();
+  std::unique_ptr<Power> power =
+      std::make_unique<Power>(std::move(power_specifics));
+  power->set_url(GURL("https://google.com"));
+  power->set_power_type(PowerType::POWER_TYPE_MOCK);
+  service()->DeletePower(power->guid(), cb.Get());
+  RunUntilIdle();
+}
+
+TEST_F(PowerBookmarkServiceTest, DeletePowersForURL) {
+  base::MockCallback<SuccessCallback> cb;
+  EXPECT_CALL(cb, Run(IsFalse()));
+
+  service()->DeletePowersForURL(GURL("https://google.com"), cb.Get());
+  RunUntilIdle();
+}
+
 }  // namespace power_bookmarks
diff --git a/components/power_bookmarks/core/powers/power.cc b/components/power_bookmarks/core/powers/power.cc
new file mode 100644
index 0000000..414f2f76
--- /dev/null
+++ b/components/power_bookmarks/core/powers/power.cc
@@ -0,0 +1,49 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/power_bookmarks/core/powers/power.h"
+
+#include "components/power_bookmarks/core/proto/power_specifics.pb.h"
+
+namespace power_bookmarks {
+
+Power::Power(std::unique_ptr<PowerSpecifics> power_specifics) {
+  CHECK(power_specifics);
+  power_specifics_ = std::move(power_specifics);
+}
+
+Power::Power(SaveSpecifics& save_specifics) {
+  guid_ = base::GUID::ParseLowercase(save_specifics.guid());
+  url_ = GURL(save_specifics.url());
+  power_type_ = save_specifics.power_type();
+
+  // See:
+  // https://source.chromium.org/chromium/chromium/src/+/main:base/time/time.h;l=49-60;drc=e8d37dfe21715cd84536a1412b778e1a5a39fb0c
+  time_added_ = base::Time::FromDeltaSinceWindowsEpoch(
+      base::Microseconds(save_specifics.creation_time_usec()));
+  time_modified_ = base::Time::FromDeltaSinceWindowsEpoch(
+      base::Microseconds(save_specifics.update_time_usec()));
+
+  power_specifics_ = std::make_unique<PowerSpecifics>();
+  power_specifics_->CopyFrom(save_specifics.power_specifics());
+}
+
+Power::~Power() = default;
+
+void Power::ToSaveSpecifics(SaveSpecifics* save_specifics) {
+  save_specifics->set_guid(guid_.AsLowercaseString());
+  save_specifics->set_url(url_.spec());
+  save_specifics->set_power_type(power_type_);
+
+  // See:
+  // https://source.chromium.org/chromium/chromium/src/+/main:base/time/time.h;l=49-60;drc=e8d37dfe21715cd84536a1412b778e1a5a39fb0c
+  save_specifics->set_creation_time_usec(
+      time_added_.ToDeltaSinceWindowsEpoch().InMicroseconds());
+  save_specifics->set_update_time_usec(
+      time_modified_.ToDeltaSinceWindowsEpoch().InMicroseconds());
+
+  save_specifics->mutable_power_specifics()->CopyFrom(*power_specifics_.get());
+}
+
+}  // namespace power_bookmarks
\ No newline at end of file
diff --git a/components/power_bookmarks/core/powers/power.h b/components/power_bookmarks/core/powers/power.h
new file mode 100644
index 0000000..dfc026e
--- /dev/null
+++ b/components/power_bookmarks/core/powers/power.h
@@ -0,0 +1,64 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_POWER_BOOKMARKS_CORE_POWERS_POWER_H_
+#define COMPONENTS_POWER_BOOKMARKS_CORE_POWERS_POWER_H_
+
+#include "base/guid.h"
+#include "base/time/time.h"
+#include "components/power_bookmarks/core/proto/save_specifics.pb.h"
+#include "url/gurl.h"
+
+namespace power_bookmarks {
+
+class PowerSpecifics;
+
+// Class for the in-memory representation for Powers.
+// When writing to local storage or sync, this class is written to the
+// save_specifics proto.
+class Power {
+ public:
+  // ctor used for creating a Power in-memory.
+  explicit Power(std::unique_ptr<PowerSpecifics> power_specifics);
+  // ctor used for creating a Power from the db.
+  explicit Power(SaveSpecifics& save_specifics);
+
+  Power(const Power&) = delete;
+  Power& operator=(const Power&) = delete;
+
+  ~Power();
+
+  const base::GUID& guid() const { return guid_; }
+  void set_guid(base::GUID guid) { guid_ = guid; }
+
+  const GURL& url() const { return url_; }
+  void set_url(GURL url) { url_ = url; }
+
+  const PowerType& power_type() const { return power_type_; }
+  void set_power_type(PowerType power_type) { power_type_ = power_type; }
+
+  const base::Time time_added() const { return time_added_; }
+  void set_time_added(base::Time time_added) { time_added_ = time_added; }
+
+  const base::Time time_modified() const { return time_modified_; }
+  void set_time_modified(base::Time time_modified) {
+    time_modified_ = time_modified;
+  }
+
+  // Write the properties held in this class to save_specifics.proto.
+  // `save_specifics` will never be nullptr.
+  void ToSaveSpecifics(SaveSpecifics* save_specifics);
+
+ private:
+  base::GUID guid_;
+  GURL url_;
+  PowerType power_type_;
+  base::Time time_modified_;
+  base::Time time_added_;
+  std::unique_ptr<PowerSpecifics> power_specifics_;
+};
+
+}  // namespace power_bookmarks
+
+#endif  // COMPONENTS_POWER_BOOKMARKS_CORE_POWERS_POWER_H_
\ No newline at end of file
diff --git a/components/power_bookmarks/core/powers/power_overview.cc b/components/power_bookmarks/core/powers/power_overview.cc
new file mode 100644
index 0000000..7de00c203
--- /dev/null
+++ b/components/power_bookmarks/core/powers/power_overview.cc
@@ -0,0 +1,16 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/power_bookmarks/core/powers/power_overview.h"
+
+#include "components/power_bookmarks/core/powers/power.h"
+
+namespace power_bookmarks {
+
+PowerOverview::PowerOverview(std::unique_ptr<Power> power, size_t count)
+    : power_(std::move(power)), count_(count) {}
+
+PowerOverview::~PowerOverview() = default;
+
+}  // namespace power_bookmarks
\ No newline at end of file
diff --git a/components/power_bookmarks/core/powers/power_overview.h b/components/power_bookmarks/core/powers/power_overview.h
new file mode 100644
index 0000000..b6bc7513
--- /dev/null
+++ b/components/power_bookmarks/core/powers/power_overview.h
@@ -0,0 +1,35 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_POWER_BOOKMARKS_CORE_POWERS_POWER_OVERVIEW_H_
+#define COMPONENTS_POWER_BOOKMARKS_CORE_POWERS_POWER_OVERVIEW_H_
+
+#include <memory>
+
+namespace power_bookmarks {
+
+class Power;
+
+// Class to encapsulate an overview of a Power. This class represents the
+// "first" Power, what qualifies as first depends on the call, and the total
+// count of the Powers of the same type.
+class PowerOverview {
+ public:
+  PowerOverview(std::unique_ptr<Power> power, size_t count);
+  PowerOverview(const PowerOverview&) = delete;
+  PowerOverview& operator=(const PowerOverview&) = delete;
+
+  ~PowerOverview();
+
+  const Power* power() const { return power_.get(); }
+  size_t count() const { return count_; }
+
+ private:
+  std::unique_ptr<Power> power_;
+  size_t count_;
+};
+
+}  // namespace power_bookmarks
+
+#endif  // COMPONENTS_POWER_BOOKMARKS_CORE_POWERS_POWER_OVERVIEW_H_
diff --git a/components/power_bookmarks/core/powers/power_unittest.cc b/components/power_bookmarks/core/powers/power_unittest.cc
new file mode 100644
index 0000000..03c1380
--- /dev/null
+++ b/components/power_bookmarks/core/powers/power_unittest.cc
@@ -0,0 +1,57 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/power_bookmarks/core/powers/power.h"
+
+#include "base/guid.h"
+#include "base/time/time.h"
+#include "components/power_bookmarks/core/proto/save_specifics.pb.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace power_bookmarks {
+
+namespace {
+SaveSpecifics CreateSaveSpecifics() {
+  SaveSpecifics specifics;
+  specifics.set_guid(base::GUID::GenerateRandomV4().AsLowercaseString());
+  specifics.set_url("http://google.com/");
+  specifics.set_power_type(PowerType::POWER_TYPE_MOCK);
+  specifics.set_creation_time_usec(
+      base::Time::Now().ToDeltaSinceWindowsEpoch().InMicroseconds());
+  specifics.set_update_time_usec(
+      base::Time::Now().ToDeltaSinceWindowsEpoch().InMicroseconds());
+
+  return specifics;
+}
+}  // namespace
+
+TEST(PowerTest, CreateFromSpecifics) {
+  SaveSpecifics specifics = CreateSaveSpecifics();
+  Power power(specifics);
+
+  EXPECT_EQ(power.guid(), base::GUID::ParseLowercase(specifics.guid()));
+  EXPECT_EQ(power.url().spec(), specifics.url());
+  EXPECT_EQ(power.power_type(), specifics.power_type());
+  EXPECT_EQ(power.time_added(),
+            base::Time::FromDeltaSinceWindowsEpoch(
+                base::Microseconds(specifics.creation_time_usec())));
+  EXPECT_EQ(power.time_modified(),
+            base::Time::FromDeltaSinceWindowsEpoch(
+                base::Microseconds(specifics.update_time_usec())));
+}
+
+TEST(PowerTest, ToAndFromSpecifics) {
+  SaveSpecifics specifics = CreateSaveSpecifics();
+  Power power(specifics);
+  SaveSpecifics new_specifics;
+  power.ToSaveSpecifics(&new_specifics);
+
+  EXPECT_EQ(specifics.guid(), new_specifics.guid());
+  EXPECT_EQ(specifics.url(), new_specifics.url());
+  EXPECT_EQ(specifics.power_type(), new_specifics.power_type());
+  EXPECT_EQ(specifics.creation_time_usec(), new_specifics.creation_time_usec());
+  EXPECT_EQ(specifics.update_time_usec(), new_specifics.update_time_usec());
+}
+
+}  // namespace power_bookmarks
diff --git a/components/power_bookmarks/core/proto/power_specifics.proto b/components/power_bookmarks/core/proto/power_specifics.proto
new file mode 100644
index 0000000..09013e3b
--- /dev/null
+++ b/components/power_bookmarks/core/proto/power_specifics.proto
@@ -0,0 +1,16 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+syntax = "proto2";
+
+option java_multiple_files = true;
+option java_package = "org.chromium.components.power_bookmarks";
+
+option optimize_for = LITE_RUNTIME;
+
+package power_bookmarks;
+
+message PowerSpecifics {
+  optional string placeholder = 1;
+}
diff --git a/components/power_bookmarks/core/proto/save_specifics.proto b/components/power_bookmarks/core/proto/save_specifics.proto
new file mode 100644
index 0000000..840bbd8
--- /dev/null
+++ b/components/power_bookmarks/core/proto/save_specifics.proto
@@ -0,0 +1,41 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+syntax = "proto2";
+
+option java_multiple_files = true;
+option java_package = "org.chromium.components.power_bookmarks";
+
+option optimize_for = LITE_RUNTIME;
+
+package power_bookmarks;
+
+import "components/power_bookmarks/core/proto/power_specifics.proto";
+
+enum PowerType {
+  // All powers should have type so this should be unused.
+  POWER_TYPE_UNSPECIFIED = 0;
+  // Used for testing.
+  POWER_TYPE_MOCK = 1;
+}
+
+message SaveSpecifics {
+  // The primary key for local storage.
+  /* required */ optional string guid = 1;
+
+  // Powers associated with a URL.
+  /* required */ optional string url = 2;
+
+  // Tracks the type of the power.
+  /* required */ optional PowerType power_type = 3;
+
+  // Tracks when this was added.
+  optional int64 creation_time_usec = 4;
+
+  // Tracks when this was last modified.
+  optional int64 update_time_usec = 5;
+
+  // Power specifics.
+  /* required */ optional PowerSpecifics power_specifics = 100;
+}
diff --git a/components/power_bookmarks/storage/BUILD.gn b/components/power_bookmarks/storage/BUILD.gn
new file mode 100644
index 0000000..e9f3769
--- /dev/null
+++ b/components/power_bookmarks/storage/BUILD.gn
@@ -0,0 +1,21 @@
+# Copyright 2022 The Chromium Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+static_library("storage") {
+  sources = [
+    "empty_power_bookmark_database.cc",
+    "empty_power_bookmark_database.h",
+    "power_bookmark_backend.cc",
+    "power_bookmark_backend.h",
+    "power_bookmark_database.h",
+  ]
+
+  deps = [
+    "//base",
+    "//components/power_bookmarks/core:powers",
+    "//sql",
+    "//third_party/sqlite",
+    "//url",
+  ]
+}
diff --git a/components/power_bookmarks/storage/empty_power_bookmark_database.cc b/components/power_bookmarks/storage/empty_power_bookmark_database.cc
new file mode 100644
index 0000000..c09edb6
--- /dev/null
+++ b/components/power_bookmarks/storage/empty_power_bookmark_database.cc
@@ -0,0 +1,51 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/power_bookmarks/storage/empty_power_bookmark_database.h"
+
+#include "components/power_bookmarks/core/proto/save_specifics.pb.h"
+#include "url/origin.h"
+
+namespace power_bookmarks {
+
+EmptyPowerBookmarkDatabase::EmptyPowerBookmarkDatabase() = default;
+
+EmptyPowerBookmarkDatabase::~EmptyPowerBookmarkDatabase() = default;
+
+bool EmptyPowerBookmarkDatabase::Init() {
+  return true;
+}
+
+bool EmptyPowerBookmarkDatabase::IsOpen() {
+  return true;
+}
+
+std::vector<std::unique_ptr<Power>> EmptyPowerBookmarkDatabase::GetPowersForURL(
+    const GURL& url) {
+  return std::vector<std::unique_ptr<Power>>();
+}
+
+std::vector<std::unique_ptr<PowerOverview>>
+EmptyPowerBookmarkDatabase::GetPowerOverviewsForType(
+    const PowerType& power_type) {
+  return std::vector<std::unique_ptr<PowerOverview>>();
+}
+
+bool EmptyPowerBookmarkDatabase::CreatePower(std::unique_ptr<Power> power) {
+  return false;
+}
+
+bool EmptyPowerBookmarkDatabase::UpdatePower(std::unique_ptr<Power> power) {
+  return false;
+}
+
+bool EmptyPowerBookmarkDatabase::DeletePower(const base::GUID& guid) {
+  return false;
+}
+
+bool EmptyPowerBookmarkDatabase::DeletePowersForURL(const GURL& url) {
+  return false;
+}
+
+}  // namespace power_bookmarks
diff --git a/components/power_bookmarks/storage/empty_power_bookmark_database.h b/components/power_bookmarks/storage/empty_power_bookmark_database.h
new file mode 100644
index 0000000..be94fa14
--- /dev/null
+++ b/components/power_bookmarks/storage/empty_power_bookmark_database.h
@@ -0,0 +1,41 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_POWER_BOOKMARKS_STORAGE_EMPTY_POWER_BOOKMARK_DATABASE_H_
+#define COMPONENTS_POWER_BOOKMARKS_STORAGE_EMPTY_POWER_BOOKMARK_DATABASE_H_
+
+#include "base/files/file_path.h"
+#include "components/power_bookmarks/core/powers/power.h"
+#include "components/power_bookmarks/core/powers/power_overview.h"
+#include "components/power_bookmarks/storage/power_bookmark_database.h"
+#include "url/gurl.h"
+#include "url/origin.h"
+
+namespace power_bookmarks {
+
+// Fake database to substitute when the feature is disabled.
+class EmptyPowerBookmarkDatabase : public PowerBookmarkDatabase {
+ public:
+  EmptyPowerBookmarkDatabase();
+  EmptyPowerBookmarkDatabase(const EmptyPowerBookmarkDatabase&) = delete;
+  EmptyPowerBookmarkDatabase& operator=(const EmptyPowerBookmarkDatabase&) =
+      delete;
+
+  ~EmptyPowerBookmarkDatabase() override;
+
+  // PowerBookmarkDatabase implementation
+  bool Init() override;
+  bool IsOpen() override;
+  std::vector<std::unique_ptr<Power>> GetPowersForURL(const GURL& url) override;
+  std::vector<std::unique_ptr<PowerOverview>> GetPowerOverviewsForType(
+      const PowerType& power_type) override;
+  bool CreatePower(std::unique_ptr<Power> power) override;
+  bool UpdatePower(std::unique_ptr<Power> power) override;
+  bool DeletePower(const base::GUID& guid) override;
+  bool DeletePowersForURL(const GURL& url) override;
+};
+
+}  // namespace power_bookmarks
+
+#endif  // COMPONENTS_POWER_BOOKMARKS_STORAGE_EMPTY_POWER_BOOKMARK_DATABASE_H_
diff --git a/components/power_bookmarks/storage/power_bookmark_backend.cc b/components/power_bookmarks/storage/power_bookmark_backend.cc
new file mode 100644
index 0000000..e94e994
--- /dev/null
+++ b/components/power_bookmarks/storage/power_bookmark_backend.cc
@@ -0,0 +1,69 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/power_bookmarks/storage/power_bookmark_backend.h"
+
+#include "components/power_bookmarks/storage/empty_power_bookmark_database.h"
+
+namespace power_bookmarks {
+
+PowerBookmarkBackend::PowerBookmarkBackend(const base::FilePath& database_dir)
+    : database_dir_(database_dir) {
+  // This is constructed on the browser thread, but all other interactions
+  // happen on a background thread.
+  DETACH_FROM_SEQUENCE(sequence_checker_);
+}
+
+PowerBookmarkBackend::~PowerBookmarkBackend() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+}
+
+void PowerBookmarkBackend::Init() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  db_.reset();
+  db_ = std::make_unique<EmptyPowerBookmarkDatabase>();
+  bool success = db_->Init();
+  DCHECK(success);
+}
+
+void PowerBookmarkBackend::Shutdown() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  db_.reset();
+}
+
+std::vector<std::unique_ptr<Power>> PowerBookmarkBackend::GetPowersForURL(
+    const GURL& url) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  return db_->GetPowersForURL(url);
+}
+
+std::vector<std::unique_ptr<PowerOverview>>
+PowerBookmarkBackend::GetPowerOverviewsForType(const PowerType& power_type) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  return db_->GetPowerOverviewsForType(power_type);
+}
+
+bool PowerBookmarkBackend::CreatePower(std::unique_ptr<Power> power) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  return db_->CreatePower(std::move(power));
+}
+
+bool PowerBookmarkBackend::UpdatePower(std::unique_ptr<Power> power) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  return db_->UpdatePower(std::move(power));
+}
+
+bool PowerBookmarkBackend::DeletePower(const base::GUID& guid) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  return db_->DeletePower(guid);
+}
+
+bool PowerBookmarkBackend::DeletePowersForURL(const GURL& url) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  return db_->DeletePowersForURL(url);
+}
+
+}  // namespace power_bookmarks
diff --git a/components/power_bookmarks/storage/power_bookmark_backend.h b/components/power_bookmarks/storage/power_bookmark_backend.h
new file mode 100644
index 0000000..537c525
--- /dev/null
+++ b/components/power_bookmarks/storage/power_bookmark_backend.h
@@ -0,0 +1,63 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_POWER_BOOKMARKS_STORAGE_POWER_BOOKMARK_BACKEND_H_
+#define COMPONENTS_POWER_BOOKMARKS_STORAGE_POWER_BOOKMARK_BACKEND_H_
+
+#include <memory>
+
+#include "base/files/file_path.h"
+#include "base/sequence_checker.h"
+#include "components/power_bookmarks/storage/power_bookmark_database.h"
+
+namespace power_bookmarks {
+
+// Class responsible for marshalling calls from the browser thread which the
+// service is called from and the background thread which the database is
+// run on. Calls to this class should be posted on the background task_runner.
+class PowerBookmarkBackend {
+ public:
+  // Constructs the backend, should be called form the browser thread.
+  // Subsequent calls to the backend should be posted to the given
+  // `task_runner`.
+  explicit PowerBookmarkBackend(const base::FilePath& database_dir);
+  PowerBookmarkBackend(const PowerBookmarkBackend&) = delete;
+  PowerBookmarkBackend& operator=(const PowerBookmarkBackend&) = delete;
+  ~PowerBookmarkBackend();
+
+  void Init();
+  void Shutdown();
+
+  // Returns a vector of Powers for the given `url`.
+  std::vector<std::unique_ptr<Power>> GetPowersForURL(const GURL& url);
+
+  // Returns a vector of PowerOverviews for the given `power_type`.
+  std::vector<std::unique_ptr<PowerOverview>> GetPowerOverviewsForType(
+      const PowerType& power_type);
+
+  // Create the given `power` in the database. If it already exists, then it
+  // will be updated. Returns whether the operation was successful.
+  bool CreatePower(std::unique_ptr<Power> power);
+  // Update the given `power` in the database. If it doesn't exist, then it
+  // will be created instead. Returns whether the operation was successful.
+  bool UpdatePower(std::unique_ptr<Power> power);
+  // Delete the given `guid` in the database, if it exists. Returns whether
+  // the operation was successful.
+  bool DeletePower(const base::GUID& guid);
+  // Delete all powers for the given `url`. Success of the operation is
+  // returned through the given `callback`.
+  bool DeletePowersForURL(const GURL& url);
+
+ private:
+  const base::FilePath database_dir_;
+
+  std::unique_ptr<PowerBookmarkDatabase> db_
+      GUARDED_BY_CONTEXT(sequence_checker_);
+
+  SEQUENCE_CHECKER(sequence_checker_);
+};
+
+}  // namespace power_bookmarks
+
+#endif  // COMPONENTS_POWER_BOOKMARKS_STORAGE_POWER_BOOKMARK_BACKEND_H_
diff --git a/components/power_bookmarks/storage/power_bookmark_database.h b/components/power_bookmarks/storage/power_bookmark_database.h
new file mode 100644
index 0000000..a544b036
--- /dev/null
+++ b/components/power_bookmarks/storage/power_bookmark_database.h
@@ -0,0 +1,53 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_POWER_BOOKMARKS_STORAGE_POWER_BOOKMARK_DATABASE_H_
+#define COMPONENTS_POWER_BOOKMARKS_STORAGE_POWER_BOOKMARK_DATABASE_H_
+
+#include "base/files/file_path.h"
+#include "components/power_bookmarks/core/powers/power.h"
+#include "components/power_bookmarks/core/powers/power_overview.h"
+#include "url/gurl.h"
+#include "url/origin.h"
+
+namespace power_bookmarks {
+
+// Interface for the database layer of the Power Bookmark database.
+class PowerBookmarkDatabase {
+ public:
+  virtual ~PowerBookmarkDatabase() = default;
+
+  // Initialises internal database. Must be called prior to any other usage.
+  virtual bool Init() = 0;
+
+  // Returns whether the database is currently open.
+  virtual bool IsOpen() = 0;
+
+  // Returns a vector of Powers for the given `url`.
+  virtual std::vector<std::unique_ptr<Power>> GetPowersForURL(
+      const GURL& url) = 0;
+
+  // Returns a vector of PowerOverviews for the given `power_type`.
+  virtual std::vector<std::unique_ptr<PowerOverview>> GetPowerOverviewsForType(
+      const PowerType& power_type) = 0;
+
+  // Create the given `power` in the database. If it already exists, then it
+  // will be updated. Returns whether the operation was successful.
+  virtual bool CreatePower(std::unique_ptr<Power> power) = 0;
+
+  // Update the given `power` in the database. If it doesn't exist, then it
+  // will be created instead. Returns whether the operation was successful.
+  virtual bool UpdatePower(std::unique_ptr<Power> power) = 0;
+
+  // Delete the given `guid` in the database, if it exists. Returns whether
+  // the operation was successful.
+  virtual bool DeletePower(const base::GUID& guid) = 0;
+
+  // Delete all powers for the given `url`.
+  virtual bool DeletePowersForURL(const GURL& url) = 0;
+};
+
+}  // namespace power_bookmarks
+
+#endif  // COMPONENTS_POWER_BOOKMARKS_STORAGE_POWER_BOOKMARK_DATABASE_H_
diff --git a/components/segmentation_platform/internal/data_collection/dummy_training_data_collector.cc b/components/segmentation_platform/internal/data_collection/dummy_training_data_collector.cc
index 839c254..81df371 100644
--- a/components/segmentation_platform/internal/data_collection/dummy_training_data_collector.cc
+++ b/components/segmentation_platform/internal/data_collection/dummy_training_data_collector.cc
@@ -16,4 +16,13 @@
 
 void DummyTrainingDataCollector::ReportCollectedContinuousTrainingData() {}
 
+void DummyTrainingDataCollector::OnDecisionTime(
+    proto::SegmentId id,
+    scoped_refptr<InputContext> input_context,
+    DecisionType type) {}
+
+void DummyTrainingDataCollector::OnObservationTrigger(
+    TrainingDataCache::RequestId request_id,
+    const proto::SegmentInfo& segment_info) {}
+
 }  // namespace segmentation_platform
diff --git a/components/segmentation_platform/internal/data_collection/dummy_training_data_collector.h b/components/segmentation_platform/internal/data_collection/dummy_training_data_collector.h
index 18f861d..68d1cfc 100644
--- a/components/segmentation_platform/internal/data_collection/dummy_training_data_collector.h
+++ b/components/segmentation_platform/internal/data_collection/dummy_training_data_collector.h
@@ -20,6 +20,11 @@
   void OnModelMetadataUpdated() override;
   void OnServiceInitialized() override;
   void ReportCollectedContinuousTrainingData() override;
+  void OnDecisionTime(proto::SegmentId id,
+                      scoped_refptr<InputContext> input_context,
+                      DecisionType type) override;
+  void OnObservationTrigger(TrainingDataCache::RequestId request_id,
+                            const proto::SegmentInfo& segment_info) override;
 };
 
 }  // namespace segmentation_platform
diff --git a/components/segmentation_platform/internal/data_collection/training_data_cache.cc b/components/segmentation_platform/internal/data_collection/training_data_cache.cc
index 0f6a7d7..ed52b37 100644
--- a/components/segmentation_platform/internal/data_collection/training_data_cache.cc
+++ b/components/segmentation_platform/internal/data_collection/training_data_cache.cc
@@ -42,4 +42,20 @@
   return result;
 }
 
+absl::optional<TrainingDataCache::RequestId> TrainingDataCache::GetRequestId(
+    proto::SegmentId segment_id) {
+  // TODO(haileywang): Add a metric to record how many request at a given time
+  // every time this function is triggered.
+  absl::optional<RequestId> request_id;
+  auto it = cache.find(segment_id);
+  if (it == cache.end() or it->second.size() == 0) {
+    return request_id;
+  }
+  return it->second.begin()->first;
+}
+
+TrainingDataCache::RequestId TrainingDataCache::GenerateNextId() {
+  return request_id_generator.GenerateNextId();
+}
+
 }  // namespace segmentation_platform
diff --git a/components/segmentation_platform/internal/data_collection/training_data_cache.h b/components/segmentation_platform/internal/data_collection/training_data_cache.h
index e8e5e9d..d271c1c1 100644
--- a/components/segmentation_platform/internal/data_collection/training_data_cache.h
+++ b/components/segmentation_platform/internal/data_collection/training_data_cache.h
@@ -35,7 +35,16 @@
       proto::SegmentId segment_id,
       RequestId request_id);
 
+  // Retrieves the first request ID given a segment ID. Returns nullopt when no
+  // request ID found. This is used when uma histogram triggering happens and
+  // only segment ID is available.
+  // Note: The earliest ID created by this cache will be returned first.
+  absl::optional<RequestId> GetRequestId(proto::SegmentId segment_id);
+
+  TrainingDataCache::RequestId GenerateNextId();
+
  private:
+  RequestId::Generator request_id_generator;
   base::flat_map<proto::SegmentId,
                  base::flat_map<RequestId, proto::TrainingData>>
       cache;
diff --git a/components/segmentation_platform/internal/data_collection/training_data_collector.h b/components/segmentation_platform/internal/data_collection/training_data_collector.h
index dcc2c62..99b3db8 100644
--- a/components/segmentation_platform/internal/data_collection/training_data_collector.h
+++ b/components/segmentation_platform/internal/data_collection/training_data_collector.h
@@ -7,7 +7,11 @@
 
 #include <memory>
 
+#include "components/segmentation_platform/internal/data_collection/training_data_cache.h"
 #include "components/segmentation_platform/internal/signals/histogram_signal_handler.h"
+#include "components/segmentation_platform/public/input_context.h"
+#include "components/segmentation_platform/public/proto/model_metadata.pb.h"
+#include "components/segmentation_platform/public/proto/segmentation_platform.pb.h"
 
 class PrefService;
 
@@ -16,6 +20,7 @@
 }  // namespace base
 
 namespace segmentation_platform {
+using DecisionType = proto::TrainingOutputs::TriggerConfig::DecisionType;
 
 namespace processing {
 class FeatureListQueryProcessor;
@@ -53,6 +58,18 @@
   // collection.
   virtual void ReportCollectedContinuousTrainingData() = 0;
 
+  // Called to collect and store training input data. The data will only be
+  // uploaded once |OnObservationTrigger| is triggered.
+  virtual void OnDecisionTime(proto::SegmentId id,
+                              scoped_refptr<InputContext> input_context,
+                              DecisionType type) = 0;
+
+  // Called when a relevant uma histogram is recorded or when a time delay
+  // trigger is hit, retrieve input training data from storage, collect output
+  // training data and upload all training data.
+  virtual void OnObservationTrigger(TrainingDataCache::RequestId request_id,
+                                    const proto::SegmentInfo& segment_info) = 0;
+
   virtual ~TrainingDataCollector();
 
   // Disallow copy/assign.
diff --git a/components/segmentation_platform/internal/data_collection/training_data_collector_impl.cc b/components/segmentation_platform/internal/data_collection/training_data_collector_impl.cc
index 5627465..fe9a818 100644
--- a/components/segmentation_platform/internal/data_collection/training_data_collector_impl.cc
+++ b/components/segmentation_platform/internal/data_collection/training_data_collector_impl.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include "components/segmentation_platform/internal/data_collection/training_data_collector_impl.h"
+#include <cstdint>
 
 #include "base/logging.h"
 #include "base/metrics/metrics_hashes.h"
@@ -83,7 +84,8 @@
       signal_storage_config_(signal_storage_config),
       configs_(configs),
       clock_(clock),
-      result_prefs_(std::make_unique<SegmentationResultPrefs>(profile_prefs)) {}
+      result_prefs_(std::make_unique<SegmentationResultPrefs>(profile_prefs)),
+      training_cache_(std::make_unique<TrainingDataCache>()) {}
 
 TrainingDataCollectorImpl::~TrainingDataCollectorImpl() {
   histogram_signal_handler_->RemoveObserver(this);
@@ -143,8 +145,22 @@
         continuous_collection_segments_.insert(segment.first);
         continue;
       }
+      // TODO(haileywang): Deprecate |immediate_collection_histograms_|.
       immediate_collection_histograms_[hash_index.first].emplace(segment.first);
     }
+
+    // Set up immediate output collection for uma histogram triggers.
+    const auto& training_config =
+        segment_info.model_metadata().training_outputs().trigger_config();
+    for (int i = 0; i < training_config.observation_trigger_size(); i++) {
+      const auto& trigger = training_config.observation_trigger(i);
+      if (trigger.has_uma_trigger() &&
+          trigger.uma_trigger().has_uma_feature()) {
+        immediate_trigger_histograms_
+            [trigger.uma_trigger().uma_feature().name_hash()]
+                .emplace(segment.first);
+      }
+    }
   }
 
   ReportCollectedContinuousTrainingData();
@@ -166,6 +182,29 @@
         base::BindOnce(&TrainingDataCollectorImpl::ReportForSegmentsInfoList,
                        weak_ptr_factory_.GetWeakPtr(), std::move(param)));
   }
+
+  // Report training data for all models which output collection is triggered by
+  // |histogram_name|.
+  it = immediate_trigger_histograms_.find(hash);
+  if (it != immediate_trigger_histograms_.end()) {
+    auto segment = it->second.begin();
+    segment_info_database_->GetSegmentInfo(
+        *segment,
+        base::BindOnce(
+            &TrainingDataCollectorImpl::OnHistogramUpdatedReportForSegmentInfo,
+            weak_ptr_factory_.GetWeakPtr()));
+  }
+}
+
+void TrainingDataCollectorImpl::OnHistogramUpdatedReportForSegmentInfo(
+    absl::optional<proto::SegmentInfo> segment) {
+  if (segment.has_value()) {
+    absl::optional<TrainingDataCache::RequestId> request_id =
+        training_cache_->GetRequestId(segment.value().segment_id());
+    if (request_id.has_value()) {
+      OnObservationTrigger(request_id.value(), segment.value());
+    }
+  }
 }
 
 void TrainingDataCollectorImpl::ReportForSegmentsInfoList(
@@ -342,4 +381,120 @@
   }
 }
 
+void TrainingDataCollectorImpl::OnDecisionTime(
+    proto::SegmentId id,
+    scoped_refptr<InputContext> input_context,
+    DecisionType type) {
+  const TrainingDataCache::RequestId request_id =
+      training_cache_->GenerateNextId();
+
+  segment_info_database_->GetSegmentInfo(
+      id,
+      base::BindOnce(&TrainingDataCollectorImpl::OnGetSegmentInfoAtDecisionTime,
+                     weak_ptr_factory_.GetWeakPtr(), request_id, type));
+}
+
+void TrainingDataCollectorImpl::OnGetSegmentInfoAtDecisionTime(
+    TrainingDataCache::RequestId id,
+    DecisionType type,
+    absl::optional<proto::SegmentInfo> segment) {
+  // If no segment info has been found.
+  if (!segment.has_value())
+    return;
+
+  const proto::SegmentInfo& segment_info = segment.value();
+  if (!CanReportTrainingData(segment_info, /*include_outputs*/ false))
+    return;
+
+  // Start training data collection.
+  const auto& training_config =
+      segment_info.model_metadata().training_outputs().trigger_config();
+  if (training_config.decision_type() == type) {
+    RecordTrainingDataCollectionEvent(
+        segment_info.segment_id(),
+        stats::TrainingDataCollectionEvent::kImmediateCollectionStart);
+
+    // Generate training data inputs.
+    feature_list_query_processor_->ProcessFeatureList(
+        segment_info.model_metadata(), /*input_context*/ nullptr,
+        segment_info.segment_id(), clock_->Now(),
+        /*process_option=*/
+        FeatureListQueryProcessor::ProcessOption::kInputsOnly,
+        base::BindOnce(
+            &TrainingDataCollectorImpl::OnGetTrainingTensorsAtDecisionTime,
+            weak_ptr_factory_.GetWeakPtr(), id, segment_info));
+  }
+}
+
+void TrainingDataCollectorImpl::OnGetTrainingTensorsAtDecisionTime(
+    TrainingDataCache::RequestId request_id,
+    const proto::SegmentInfo& segment_info,
+    bool has_error,
+    const std::vector<float>& input_tensors,
+    const std::vector<float>& output_tensors) {
+  // Store inputs to cache.
+  training_cache_->StoreInputs(segment_info.segment_id(), request_id,
+                               input_tensors);
+
+  // Set up delayed output recordings based on time delay triggers defined
+  // in model metadata.
+  // TODO(haileywang): This is slightly inaccurate since the the delay timer is
+  // only started after the input training tensors are cached.
+  const auto& training_config =
+      segment_info.model_metadata().training_outputs().trigger_config();
+  for (int i = 0; i < training_config.observation_trigger_size(); i++) {
+    const auto& trigger = training_config.observation_trigger(i);
+    if (trigger.has_delay_sec()) {
+      base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+          FROM_HERE,
+          base::BindOnce(&TrainingDataCollectorImpl::OnObservationTrigger,
+                         weak_ptr_factory_.GetWeakPtr(), request_id,
+                         segment_info),
+          base::Seconds(trigger.delay_sec()));
+    }
+  }
+}
+
+void TrainingDataCollectorImpl::OnObservationTrigger(
+    TrainingDataCache::RequestId request_id,
+    const proto::SegmentInfo& segment_info) {
+  if (!CanReportTrainingData(segment_info, /*include_outputs*/ true))
+    return;
+
+  // Retrieve input tensor from cache.
+  absl::optional<proto::TrainingData> input =
+      training_cache_->GetInputsAndDelete(segment_info.segment_id(),
+                                          request_id);
+
+  if (!input.has_value())
+    return;
+
+  // Generate training data output.
+  feature_list_query_processor_->ProcessFeatureList(
+      segment_info.model_metadata(), /*input_context=*/nullptr,
+      segment_info.segment_id(), clock_->Now(),
+      /*process_option=*/
+      FeatureListQueryProcessor::ProcessOption::kOutputsOnly,
+      base::BindOnce(
+          &TrainingDataCollectorImpl::onGetOutputsOnObservationTrigger,
+          weak_ptr_factory_.GetWeakPtr(), request_id, segment_info,
+          std::vector<float>(input.value().inputs().begin(),
+                             input.value().inputs().end())));
+}
+
+void TrainingDataCollectorImpl::onGetOutputsOnObservationTrigger(
+    TrainingDataCache::RequestId request_id,
+    const proto::SegmentInfo& segment_info,
+    const std::vector<float>& cached_input_tensors,
+    bool has_error,
+    const std::vector<float>& input_tensors,
+    const std::vector<float>& output_tensors) {
+  // Upload input and output tensors.
+  // TODO(haileywang): Add state in cache for each request; never seen,
+  // fulfilled, unfullfilled. (Or make triggers cancellable callbacks)
+  // TODO(haileywang): Add usage of |ImmediaCollectionParam|.
+  OnGetTrainingTensors(absl::nullopt, segment_info, has_error,
+                       cached_input_tensors, output_tensors);
+}
+
 }  // namespace segmentation_platform
diff --git a/components/segmentation_platform/internal/data_collection/training_data_collector_impl.h b/components/segmentation_platform/internal/data_collection/training_data_collector_impl.h
index ef335f43..642d23e 100644
--- a/components/segmentation_platform/internal/data_collection/training_data_collector_impl.h
+++ b/components/segmentation_platform/internal/data_collection/training_data_collector_impl.h
@@ -13,6 +13,7 @@
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/metrics/histogram_base.h"
+#include "components/segmentation_platform/internal/data_collection/training_data_cache.h"
 #include "components/segmentation_platform/internal/data_collection/training_data_collector.h"
 #include "components/segmentation_platform/internal/database/segment_info_database.h"
 #include "components/segmentation_platform/internal/proto/model_prediction.pb.h"
@@ -43,6 +44,11 @@
   void OnModelMetadataUpdated() override;
   void OnServiceInitialized() override;
   void ReportCollectedContinuousTrainingData() override;
+  void OnDecisionTime(proto::SegmentId id,
+                      scoped_refptr<InputContext> input_context,
+                      DecisionType type) override;
+  void OnObservationTrigger(TrainingDataCache::RequestId request_id,
+                            const proto::SegmentInfo& segment_info) override;
 
   // HistogramSignalHandler::Observer implementation.
   void OnHistogramSignalUpdated(const std::string& histogram_name,
@@ -63,6 +69,29 @@
       const absl::optional<ImmediaCollectionParam>& param,
       std::unique_ptr<SegmentInfoDatabase::SegmentInfoList> segments);
 
+  void OnHistogramUpdatedReportForSegmentInfo(
+      absl::optional<proto::SegmentInfo> segment);
+
+  void OnGetSegmentInfoAtDecisionTime(
+      TrainingDataCache::RequestId id,
+      DecisionType type,
+      absl::optional<proto::SegmentInfo> segment);
+
+  void OnGetTrainingTensorsAtDecisionTime(
+      TrainingDataCache::RequestId request_id,
+      const proto::SegmentInfo& segment_info,
+      bool has_error,
+      const std::vector<float>& input_tensors,
+      const std::vector<float>& output_tensors);
+
+  void onGetOutputsOnObservationTrigger(
+      TrainingDataCache::RequestId request_id,
+      const proto::SegmentInfo& segment_info,
+      const std::vector<float>& cached_input_tensors,
+      bool has_error,
+      const std::vector<float>& input_tensors,
+      const std::vector<float>& output_tensors);
+
   void OnGetTrainingTensors(const absl::optional<ImmediaCollectionParam>& param,
                             const proto::SegmentInfo& segment_info,
                             bool has_error,
@@ -85,12 +114,19 @@
   // Helper class to read/write results to the prefs.
   std::unique_ptr<SegmentationResultPrefs> result_prefs_;
 
+  // Cache class to temporarily store training data in the observation period.
+  std::unique_ptr<TrainingDataCache> training_cache_;
+
   // Hash of histograms for immediate training data collection. When any
   // histogram hash contained in the map is recorded, a UKM message is reported
   // right away.
   base::flat_map<uint64_t, base::flat_set<proto::SegmentId>>
       immediate_collection_histograms_;
 
+  // Hash of histograms for trigger based training data collection.
+  base::flat_map<uint64_t, base::flat_set<proto::SegmentId>>
+      immediate_trigger_histograms_;
+
   // A list of segment IDs that needs to report metrics continuously.
   base::flat_set<SegmentId> continuous_collection_segments_;
 
diff --git a/components/segmentation_platform/internal/data_collection/training_data_collector_impl_unittest.cc b/components/segmentation_platform/internal/data_collection/training_data_collector_impl_unittest.cc
index 3f95d8cd8..a6a5b9ad 100644
--- a/components/segmentation_platform/internal/data_collection/training_data_collector_impl_unittest.cc
+++ b/components/segmentation_platform/internal/data_collection/training_data_collector_impl_unittest.cc
@@ -131,6 +131,33 @@
     return segment_info;
   }
 
+  proto::SegmentInfo* CreateSegmentInfoWithTriggers() {
+    test_segment_db()->AddUserActionFeature(kTestOptimizationTarget0, "action",
+                                            1, 1, proto::Aggregation::COUNT);
+
+    auto* segment_info = CreateSegment(kTestOptimizationTarget0);
+
+    // Add triggers.
+    auto* trigger = segment_info->mutable_model_metadata()
+                        ->mutable_training_outputs()
+                        ->mutable_trigger_config();
+    trigger->set_decision_type(
+        proto::TrainingOutputs_TriggerConfig_DecisionType_ONDEMAND);
+
+    // Add a time delay trigger of 1 second.
+    auto* delay_trigger = trigger->add_observation_trigger();
+    delay_trigger->set_delay_sec(5);
+    auto* uma_trigger = trigger->add_observation_trigger();
+
+    // Add a uma feature trigger based on |kHistogramName0|.
+    auto* uma_feature =
+        uma_trigger->mutable_uma_trigger()->mutable_uma_feature();
+    uma_feature->set_name(kHistogramName0);
+    uma_feature->set_name_hash(base::HashMetricName(kHistogramName0));
+
+    return segment_info;
+  }
+
   proto::SegmentInfo* CreateSegment(SegmentId segment_id) {
     auto* segment_info = test_segment_db()->FindOrCreateSegment(segment_id);
     auto* model_metadata = segment_info->mutable_model_metadata();
@@ -391,5 +418,42 @@
   ExpectUkmCount(0u);
 }
 
+// Tests that if triggers are set, data collection only happens when triggers
+// are hit.
+TEST_F(TrainingDataCollectorImplTest, DataCollectionWithTrigger) {
+  ON_CALL(*feature_list_processor(), ProcessFeatureList(_, _, _, _, _, _))
+      .WillByDefault(RunOnceCallback<5>(false, std::vector<float>{1.f},
+                                        std::vector<float>{2.f, 3.f}));
+
+  // Create a segment that contain a time delay trigger and a uma trigger.
+  CreateSegmentInfoWithTriggers();
+  Init();
+
+  // Wait for input collection to be done and cached in memory.
+  auto input_context = base::MakeRefCounted<InputContext>();
+  base::RunLoop run_loop;
+  test_recorder()->SetOnAddEntryCallback(
+      Segmentation_ModelExecution::kEntryName, run_loop.QuitClosure());
+  collector()->OnDecisionTime(
+      kTestOptimizationTarget0, input_context,
+      proto::TrainingOutputs_TriggerConfig_DecisionType_ONDEMAND);
+  task_environment()->RunUntilIdle();
+  ExpectUkmCount(0u);
+
+  // Trigger output collection and ukm data recording.
+  collector()->OnHistogramSignalUpdated(kHistogramName0, kSample);
+  run_loop.Run();
+  ExpectUkmCount(1u);
+  ExpectUkm({Segmentation_ModelExecution::kOptimizationTargetName,
+             Segmentation_ModelExecution::kModelVersionName,
+             Segmentation_ModelExecution::kInput0Name,
+             Segmentation_ModelExecution::kActualResultName,
+             Segmentation_ModelExecution::kActualResult2Name},
+            {kTestOptimizationTarget0, kModelVersion,
+             SegmentationUkmHelper::FloatToInt64(1.f),
+             SegmentationUkmHelper::FloatToInt64(2.f),
+             SegmentationUkmHelper::FloatToInt64(3.f)});
+}
+
 }  // namespace
 }  // namespace segmentation_platform
diff --git a/components/variations/service/BUILD.gn b/components/variations/service/BUILD.gn
index 8f0d055..663825ca 100644
--- a/components/variations/service/BUILD.gn
+++ b/components/variations/service/BUILD.gn
@@ -34,6 +34,8 @@
     "variations_service.h",
     "variations_service_client.cc",
     "variations_service_client.h",
+    "variations_service_utils.cc",
+    "variations_service_utils.h",
   ]
 
   deps = [
@@ -65,6 +67,7 @@
     "ui_string_overrider_unittest.cc",
     "variations_field_trial_creator_unittest.cc",
     "variations_service_unittest.cc",
+    "variations_service_utils_unittest.cc",
   ]
 
   deps = [
diff --git a/components/variations/service/variations_field_trial_creator.cc b/components/variations/service/variations_field_trial_creator.cc
index 8cfaf24..13ad7019 100644
--- a/components/variations/service/variations_field_trial_creator.cc
+++ b/components/variations/service/variations_field_trial_creator.cc
@@ -39,8 +39,8 @@
 #include "components/variations/proto/variations_seed.pb.h"
 #include "components/variations/service/buildflags.h"
 #include "components/variations/service/safe_seed_manager.h"
-#include "components/variations/service/variations_service.h"
 #include "components/variations/service/variations_service_client.h"
+#include "components/variations/service/variations_service_utils.h"
 #include "components/variations/variations_ids_provider.h"
 #include "components/variations/variations_seed_processor.h"
 #include "components/variations/variations_switches.h"
@@ -53,9 +53,6 @@
 namespace variations {
 namespace {
 
-// Maximum age permitted for a variations seed, in days.
-const int kMaxVariationsSeedAgeDays = 30;
-
 // Returns the date that should be used by the VariationsSeedProcessor to do
 // expiry and start date checks.
 base::Time GetReferenceDateForExpiryChecks(PrefService* local_state) {
@@ -556,12 +553,9 @@
     }
     return false;
   }
-
-  const base::TimeDelta seed_age = base::Time::Now() - fetch_time;
-  bool has_seed_expired = seed_age.InDays() > kMaxVariationsSeedAgeDays &&
-                          GetBuildTime() > fetch_time;
+  bool has_seed_expired = HasSeedExpiredSinceTime(fetch_time);
   if (!has_seed_expired)
-    RecordSeedFreshness(seed_age);
+    RecordSeedFreshness(base::Time::Now() - fetch_time);
   RecordSeedExpiry(is_safe_seed, has_seed_expired
                                      ? VariationsSeedExpiry::kExpired
                                      : VariationsSeedExpiry::kNotExpired);
@@ -606,50 +600,36 @@
                                 client_filterable_state->policy_restriction);
 
   VariationsSeed seed;
-  bool run_in_safe_mode = safe_seed_manager->ShouldRunInSafeMode();
-  if (run_in_safe_mode) {
-    if (GetSeedStore()->LoadSafeSeed(&seed, client_filterable_state.get())) {
-      // TODO(crbug/1261685): The expiry and milestone checks are repeated below
-      // for regular seeds. Refactor this.
-      if (HasSeedExpired(/*is_safe_seed=*/true)) {
-        RecordVariationsSeedUsage(SeedUsage::kExpiredSafeSeedNotUsed);
-        return false;
-      }
-      if (IsSeedForFutureMilestone(/*is_safe_seed=*/true)) {
-        RecordVariationsSeedUsage(
-            SeedUsage::kSafeSeedForFutureMilestoneNotUsed);
-        return false;
-      }
-      RecordVariationsSeedUsage(SeedUsage::kSafeSeedUsed);
-    } else {
-      // If Chrome should run in safe mode but the safe seed was not
-      // successfully loaded, then do not apply a seed. Fall back to client-side
-      // defaults.
-      RecordVariationsSeedUsage(SeedUsage::kUnloadableSafeSeedNotUsed);
-      return false;
-    }
-  }
 
-  std::string seed_data;
-  std::string base64_seed_signature;
-  if (!run_in_safe_mode) {
-    if (GetSeedStore()->LoadSeed(&seed, &seed_data, &base64_seed_signature)) {
-      if (HasSeedExpired(/*is_safe_seed=*/false)) {
-        RecordVariationsSeedUsage(SeedUsage::kExpiredRegularSeedNotUsed);
-        return false;
-      }
-      if (IsSeedForFutureMilestone(/*is_safe_seed=*/false)) {
-        RecordVariationsSeedUsage(
-            SeedUsage::kRegularSeedForFutureMilestoneNotUsed);
-        return false;
-      }
-      RecordVariationsSeedUsage(SeedUsage::kRegularSeedUsed);
-    } else {
-      // The regular seed was not successfully loaded, so do not apply a seed.
-      // Fall back to client-side defaults.
-      RecordVariationsSeedUsage(SeedUsage::kUnloadableRegularSeedNotUsed);
+  std::string seed_data;              // Only set if not in safe mode.
+  std::string base64_seed_signature;  // Only set if not in safe mode.
+  const bool run_in_safe_mode = safe_seed_manager->ShouldRunInSafeMode();
+  const bool seed_loaded =
+      run_in_safe_mode
+          ? GetSeedStore()->LoadSafeSeed(&seed, client_filterable_state.get())
+          : GetSeedStore()->LoadSeed(&seed, &seed_data, &base64_seed_signature);
+  if (seed_loaded) {
+    if (HasSeedExpired(/*is_safe_seed=*/run_in_safe_mode)) {
+      RecordVariationsSeedUsage(run_in_safe_mode
+                                    ? SeedUsage::kExpiredSafeSeedNotUsed
+                                    : SeedUsage::kExpiredRegularSeedNotUsed);
       return false;
     }
+    if (IsSeedForFutureMilestone(/*is_safe_seed=*/run_in_safe_mode)) {
+      RecordVariationsSeedUsage(
+          run_in_safe_mode ? SeedUsage::kSafeSeedForFutureMilestoneNotUsed
+                           : SeedUsage::kRegularSeedForFutureMilestoneNotUsed);
+      return false;
+    }
+    RecordVariationsSeedUsage(run_in_safe_mode ? SeedUsage::kSafeSeedUsed
+                                               : SeedUsage::kRegularSeedUsed);
+  } else {
+    // If Chrome should run in safe mode but the safe seed was not successfully
+    // loaded, then do not apply a seed. Fall back to client-side defaults.
+    RecordVariationsSeedUsage(run_in_safe_mode
+                                  ? SeedUsage::kUnloadableSafeSeedNotUsed
+                                  : SeedUsage::kUnloadableRegularSeedNotUsed);
+    return false;
   }
 
   // Note that passing base::Unretained(this) below is safe because the callback
@@ -729,8 +709,4 @@
   return seed_store_.get();
 }
 
-base::Time VariationsFieldTrialCreator::GetBuildTime() const {
-  return base::GetBuildTime();
-}
-
 }  // namespace variations
diff --git a/components/variations/service/variations_field_trial_creator.h b/components/variations/service/variations_field_trial_creator.h
index bab97a3f..4d677944 100644
--- a/components/variations/service/variations_field_trial_creator.h
+++ b/components/variations/service/variations_field_trial_creator.h
@@ -233,9 +233,6 @@
   // Returns the seed store. Virtual for testing.
   virtual VariationsSeedStore* GetSeedStore();
 
-  // Returns the time at which the binary was built. Virtual for testing.
-  virtual base::Time GetBuildTime() const;
-
   PrefService* local_state() { return seed_store_->local_state(); }
   const PrefService* local_state() const { return seed_store_->local_state(); }
 
diff --git a/components/variations/service/variations_field_trial_creator_unittest.cc b/components/variations/service/variations_field_trial_creator_unittest.cc
index 3ca325b9..12a5f24 100644
--- a/components/variations/service/variations_field_trial_creator_unittest.cc
+++ b/components/variations/service/variations_field_trial_creator_unittest.cc
@@ -11,6 +11,7 @@
 #include <utility>
 
 #include "base/base_switches.h"
+#include "base/build_time.h"
 #include "base/callback.h"
 #include "base/callback_helpers.h"
 #include "base/command_line.h"
@@ -23,6 +24,7 @@
 #include "base/strings/stringprintf.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/mock_entropy_provider.h"
+#include "base/test/scoped_mock_clock_override.h"
 #include "base/test/task_environment.h"
 #include "base/time/time.h"
 #include "base/version.h"
@@ -78,9 +80,9 @@
 
 // Used for similar tests.
 struct TestParams {
-  // Inputs.
-  int days;
-  const base::Time binary_build_time;
+  // Inputs in relation to the current build time.
+  const base::TimeDelta fetch_time;
+  const base::TimeDelta launch_time;
 };
 
 // Returns a seed with simple test data. The seed has a single study,
@@ -112,6 +114,12 @@
   return seed;
 }
 
+// A base::Time instance representing a time in the distant past. Here, it would
+// return the start for epoch in Unix-like system (Jan 1, 1970).
+base::Time DistantPast() {
+  return base::Time::UnixEpoch();
+}
+
 #if BUILDFLAG(IS_ANDROID)
 const char kTestSeedCountry[] = "in";
 
@@ -261,8 +269,7 @@
             UIStringOverrider()),
         enabled_state_provider_(/*consent=*/true, /*enabled=*/true),
         seed_store_(local_state),
-        safe_seed_manager_(safe_seed_manager),
-        build_time_(base::Time::Now()) {
+        safe_seed_manager_(safe_seed_manager) {
     metrics_state_manager_ = metrics::MetricsStateManager::Create(
         local_state, &enabled_state_provider_, std::wstring(), user_data_dir,
         startup_visibility);
@@ -291,7 +298,6 @@
   }
 
   TestVariationsSeedStore* seed_store() { return &seed_store_; }
-  void SetBuildTime(const base::Time& time) { build_time_ = time; }
 
  protected:
 #if BUILDFLAG(FIELDTRIAL_TESTING_ENABLED)
@@ -308,12 +314,10 @@
 
  private:
   VariationsSeedStore* GetSeedStore() override { return &seed_store_; }
-  base::Time GetBuildTime() const override { return build_time_; }
 
   metrics::TestEnabledStateProvider enabled_state_provider_;
   TestVariationsSeedStore seed_store_;
   const raw_ptr<SafeSeedManager> safe_seed_manager_;
-  base::Time build_time_;
   std::unique_ptr<metrics::MetricsStateManager> metrics_state_manager_;
 };
 
@@ -375,20 +379,23 @@
 // Verify that unexpired seeds are used.
 TEST_F(FieldTrialCreatorTest, SetUpFieldTrials_ValidSeed_NotExpired) {
   DisableTestingConfig();
-  const base::Time now = base::Time::Now();
-
   std::vector<TestParams> test_cases = {
       // Verify that when the binary is newer than the most recent seed, the
       // seed is applied as long as it was downloaded within the last 30 days.
-      {.days = 30, .binary_build_time = now},
+      {.fetch_time = -base::Days(29), .launch_time = base::Days(1)},
       // Verify that when the binary is older than the most recent seed, the
       // seed is applied even though it was downloaded more than 30 days ago.
-      {.days = 31, .binary_build_time = now - base::Days(32)}};
-
+      {.fetch_time = base::Days(1), .launch_time = base::Days(32)},
+  };
   for (const TestParams& test_case : test_cases) {
-    const base::Time seed_fetch_time = now - base::Days(test_case.days);
+    // Fast forward the clock to build time.
+    base::ScopedMockClockOverride mock_clock;
+    base::Time build_time = base::GetBuildTime();
+    mock_clock.Advance(build_time - base::Time::Now());
+
     // The seed should be used, so the safe seed manager should be informed of
     // the active seed state.
+    const base::Time seed_fetch_time = build_time + test_case.fetch_time;
     NiceMock<MockSafeSeedManager> safe_seed_manager(local_state());
     EXPECT_CALL(
         safe_seed_manager,
@@ -399,7 +406,6 @@
     TestVariationsServiceClient variations_service_client;
     TestVariationsFieldTrialCreator field_trial_creator(
         local_state(), &variations_service_client, &safe_seed_manager);
-    field_trial_creator.SetBuildTime(test_case.binary_build_time);
 
     // Simulate the seed being stored.
     local_state()->SetTime(prefs::kVariationsLastFetchTime, seed_fetch_time);
@@ -408,9 +414,10 @@
     local_state()->SetInteger(prefs::kVariationsSeedMilestone,
                               kTestSeedMilestone);
 
-    // Check that field trials are created from the seed. Since the test study
-    // has only one experiment with 100% probability weight, we must be part of
-    // it.
+    // Fast forward the clock to launch_time and check that field trials are
+    // created from the seed at launch_time. Since the test study has only one
+    // experiment with 100% probability weight, we must be part of it.
+    mock_clock.Advance(test_case.launch_time);
     base::HistogramTester histogram_tester;
     EXPECT_TRUE(field_trial_creator.SetUpFieldTrials());
     EXPECT_EQ(kTestSeedExperimentName,
@@ -419,7 +426,8 @@
     // Verify metrics.
     histogram_tester.ExpectUniqueSample("Variations.CreateTrials.SeedExpiry",
                                         VariationsSeedExpiry::kNotExpired, 1);
-    int freshness_in_minutes = test_case.days * 24 * 60;
+    int freshness_in_minutes =
+        (test_case.launch_time - test_case.fetch_time).InDays() * 24 * 60;
     histogram_tester.ExpectUniqueSample("Variations.SeedFreshness",
                                         freshness_in_minutes, 1);
     histogram_tester.ExpectUniqueSample("Variations.SeedUsage",
@@ -510,25 +518,21 @@
                                       SeedUsage::kRegularSeedUsed, 1);
 }
 
+// Verify that no seed is applied when the seed has expired.
 TEST_F(FieldTrialCreatorTest, SetUpFieldTrials_ExpiredSeed) {
   DisableTestingConfig();
 
-  // When the seed is older than 30 days and older than the binary, no field
-  // trials should be created from the seed. Hence, no active state should be
-  // passed to the safe seed manager.
+  // When the seed is has expired, no field trials should be created from the
+  // seed. Hence, no active state should be passed to the safe seed manager.
   NiceMock<MockSafeSeedManager> safe_seed_manager(local_state());
   EXPECT_CALL(safe_seed_manager, DoSetActiveSeedState(_, _, _, _, _)).Times(0);
 
   TestVariationsServiceClient variations_service_client;
   TestVariationsFieldTrialCreator field_trial_creator(
       local_state(), &variations_service_client, &safe_seed_manager);
-  const base::Time now = base::Time::Now();
-  field_trial_creator.SetBuildTime(now);
-
-  // Simulate an expired seed. For a seed to be expired, it must be older than
-  // 30 days and be older than the binary.
-  const base::Time seed_date = now - base::Days(31);
-  local_state()->SetTime(prefs::kVariationsLastFetchTime, seed_date);
+  // Simulate a seed that is fetched a long time ago and should definitely
+  // have expired.
+  local_state()->SetTime(prefs::kVariationsLastFetchTime, DistantPast());
 
   // Check that field trials are not created from the expired seed.
   base::HistogramTester histogram_tester;
@@ -559,8 +563,6 @@
   TestVariationsServiceClient variations_service_client;
   TestVariationsFieldTrialCreator field_trial_creator(
       local_state(), &variations_service_client, &safe_seed_manager);
-  const base::Time now = base::Time::Now();
-  field_trial_creator.SetBuildTime(now);
 
   // Simulate a seed from a future milestone.
   local_state()->SetInteger(prefs::kVariationsSeedMilestone,
@@ -581,19 +583,22 @@
 TEST_F(FieldTrialCreatorTest,
        SetUpFieldTrials_ValidSafeSeed_NewBinaryUsesSeed) {
   DisableTestingConfig();
-  const base::Time now = base::Time::Now();
-
   std::vector<TestParams> test_cases = {
       // Verify that when (i) safe mode is triggered and (ii) the binary is
       // newer than the safe seed, the safe seed is applied as long as it was
       // downloaded within the last 30 days.
-      {.days = 30, .binary_build_time = now},
+      {.fetch_time = -base::Days(29), .launch_time = base::Days(1)},
       // Verify that when (i) safe mode is triggered and (ii) the binary is
       // older than the safe seed, the safe seed is applied even though it was
       // downloaded more than 30 days ago.
-      {.days = 31, .binary_build_time = now - base::Days(32)}};
-
+      {.fetch_time = base::Days(1), .launch_time = base::Days(32)},
+  };
   for (const TestParams& test_case : test_cases) {
+    // Fast forward the clock to build time.
+    base::ScopedMockClockOverride mock_clock;
+    base::Time build_time = base::GetBuildTime();
+    mock_clock.Advance(build_time - base::Time::Now());
+
     // With a valid safe seed, the safe seed manager should not be informed of
     // the active seed state. This is an optimization to avoid saving a safe
     // seed when already running in safe mode.
@@ -606,16 +611,15 @@
     TestVariationsServiceClient variations_service_client;
     TestVariationsFieldTrialCreator field_trial_creator(
         local_state(), &variations_service_client, &safe_seed_manager);
-    field_trial_creator.SetBuildTime(test_case.binary_build_time);
 
     // Simulate the safe seed being stored.
-    const base::Time seed_fetch_time = now - base::Days(test_case.days);
     local_state()->SetTime(prefs::kVariationsSafeSeedFetchTime,
-                           seed_fetch_time);
+                           build_time + test_case.fetch_time);
 
-    // Check that field trials are created from the safe seed. Since the test
-    // study has only one experiment with 100% probability weight, we must be
-    // part of it.
+    // Fast forward the clock to launch_time and check that field trials are
+    // created from the safe seed. Since the test study has only one experiment
+    // with 100% probability weight, we must be part of it.
+    mock_clock.Advance(test_case.launch_time);
     base::HistogramTester histogram_tester;
     EXPECT_TRUE(field_trial_creator.SetUpFieldTrials());
     EXPECT_EQ(kTestSafeSeedExperimentName,
@@ -625,7 +629,8 @@
     histogram_tester.ExpectUniqueSample(
         "Variations.SafeMode.CreateTrials.SeedExpiry",
         VariationsSeedExpiry::kNotExpired, 1);
-    int freshness_in_minutes = test_case.days * 24 * 60;
+    int freshness_in_minutes =
+        (test_case.launch_time - test_case.fetch_time).InDays() * 24 * 60;
     histogram_tester.ExpectUniqueSample("Variations.SeedFreshness",
                                         freshness_in_minutes, 1);
     histogram_tester.ExpectUniqueSample("Variations.SeedUsage",
@@ -712,13 +717,9 @@
   TestVariationsServiceClient variations_service_client;
   TestVariationsFieldTrialCreator field_trial_creator(
       local_state(), &variations_service_client, &safe_seed_manager);
-  const base::Time now = base::Time::Now();
-  field_trial_creator.SetBuildTime(now);
-
-  // Simulate an expired seed. For a seed to be expired, it must be older than
-  // 30 days and be older than the binary.
-  const base::Time seed_date = now - base::Days(31);
-  local_state()->SetTime(prefs::kVariationsSafeSeedFetchTime, seed_date);
+  // Simulate a safe seed that is fetched a long time ago and should definitely
+  // have expired.
+  local_state()->SetTime(prefs::kVariationsSafeSeedFetchTime, DistantPast());
 
   // Check that field trials are not created from the expired seed.
   base::HistogramTester histogram_tester;
@@ -891,7 +892,6 @@
   std::unique_ptr<TestVariationsFieldTrialCreator> field_trial_creator =
       std::make_unique<TestVariationsFieldTrialCreator>(
           local_state, variations_service_client, safe_seed_manager);
-  field_trial_creator->SetBuildTime(now);
   // Simulate the seed being stored.
   local_state->SetTime(prefs::kVariationsLastFetchTime, seed_fetch_time);
   // Simulate a seed from an earlier (i.e. valid) milestone.
diff --git a/components/variations/service/variations_service_utils.cc b/components/variations/service/variations_service_utils.cc
new file mode 100644
index 0000000..5f2ecb72
--- /dev/null
+++ b/components/variations/service/variations_service_utils.cc
@@ -0,0 +1,38 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/variations/service/variations_service_utils.h"
+
+#include "base/build_time.h"
+#include "base/time/time.h"
+
+namespace variations {
+namespace {
+
+// Maximum age permitted for a variations seed, in days.
+const int kMaxVariationsSeedAgeDays = 30;
+
+// Helper function for "HasSeedExpiredSinceTime" that exposes |build_time| and
+// makes it overridable by tests.
+bool HasSeedExpiredSinceTimeHelper(base::Time fetch_time,
+                                   base::Time build_time) {
+  const base::TimeDelta seed_age = base::Time::Now() - fetch_time;
+  // base::TimeDelta::InDays() rounds down to the nearest integer, so the seed
+  // would not be considered expired if it is less than
+  // `kMaxVariationsSeedAgeDays + 1`.
+  return seed_age.InDays() > kMaxVariationsSeedAgeDays &&
+         build_time > fetch_time;
+}
+
+}  // namespace
+
+bool HasSeedExpiredSinceTime(base::Time fetch_time) {
+  return HasSeedExpiredSinceTimeHelper(fetch_time, base::GetBuildTime());
+}
+
+bool HasSeedExpiredSinceTimeHelperForTesting(base::Time fetch_time,
+                                             base::Time build_time) {
+  return HasSeedExpiredSinceTimeHelper(fetch_time, build_time);
+}
+}  // namespace variations
diff --git a/components/variations/service/variations_service_utils.h b/components/variations/service/variations_service_utils.h
new file mode 100644
index 0000000..1c531fb7
--- /dev/null
+++ b/components/variations/service/variations_service_utils.h
@@ -0,0 +1,22 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_VARIATIONS_SERVICE_VARIATIONS_SERVICE_UTILS_H_
+#define COMPONENTS_VARIATIONS_SERVICE_VARIATIONS_SERVICE_UTILS_H_
+
+namespace base {
+class Time;
+}  // namespace base
+
+namespace variations {
+
+// Returns whether a seed fetched at |fetch_time| has expired.
+bool HasSeedExpiredSinceTime(base::Time fetch_time);
+
+bool HasSeedExpiredSinceTimeHelperForTesting(base::Time fetch_time,
+                                             base::Time build_time);
+
+}  // namespace variations
+
+#endif  // COMPONENTS_VARIATIONS_SERVICE_VARIATIONS_SERVICE_UTILS_H_
diff --git a/components/variations/service/variations_service_utils_unittest.cc b/components/variations/service/variations_service_utils_unittest.cc
new file mode 100644
index 0000000..a718b83
--- /dev/null
+++ b/components/variations/service/variations_service_utils_unittest.cc
@@ -0,0 +1,40 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/variations/service/variations_service_utils.h"
+
+#include "base/time/time.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace variations {
+
+using VariationsServiceUtilsTest = ::testing::Test;
+
+// Verifies that the seed expiration status is correctly computed based on its
+// fetch time and the binary build time.
+TEST_F(VariationsServiceUtilsTest, HasSeedExpiredSinceTime) {
+  base::Time now = base::Time::Now();
+  struct {
+    const base::Time fetch_time;
+    const base::Time build_time;
+    const bool expired;
+  } test_cases[] = {
+      // Verifies that seed should NOT expire if it does NOT exceed the maximum
+      // age permitted for a variations seed.
+      {now - base::Days(30), now, false},
+      // Verifies that when the binary is newer than the seed, the seed should
+      // be considered expired if it exceeds maximum age permitted.
+      {now - base::Days(31), now, true},
+      // Verifies that when the binary is older than the seed, the seed should
+      // NOT be considered expired even when it exceeds maximum age permitted.
+      {now - base::Days(31), now - base::Days(32), false},
+  };
+  for (const auto& test : test_cases) {
+    EXPECT_EQ(HasSeedExpiredSinceTimeHelperForTesting(test.fetch_time,
+                                                      test.build_time),
+              test.expired);
+  }
+}
+
+}  // namespace variations
diff --git a/components/variations/variations_seed_store.cc b/components/variations/variations_seed_store.cc
index f88ec83..f22789fc 100644
--- a/components/variations/variations_seed_store.cc
+++ b/components/variations/variations_seed_store.cc
@@ -297,7 +297,7 @@
 }
 
 base::Time VariationsSeedStore::GetLastFetchTime() const {
-  return local_state_->GetTime(prefs::kVariationsLastFetchTime);
+  return GetLastFetchTimeFromPrefService(local_state_);
 }
 
 base::Time VariationsSeedStore::GetSafeSeedFetchTime() const {
@@ -376,6 +376,12 @@
 }
 
 // static
+base::Time VariationsSeedStore::GetLastFetchTimeFromPrefService(
+    PrefService* prefs) {
+  return prefs->GetTime(prefs::kVariationsLastFetchTime);
+}
+
+// static
 VerifySignatureResult VariationsSeedStore::VerifySeedSignatureForTesting(
     const std::string& seed_bytes,
     const std::string& base64_seed_signature) {
diff --git a/components/variations/variations_seed_store.h b/components/variations/variations_seed_store.h
index 3676ab6..f9416b1 100644
--- a/components/variations/variations_seed_store.h
+++ b/components/variations/variations_seed_store.h
@@ -117,10 +117,10 @@
                              base::Time seed_fetch_time);
 
   // Loads the last fetch time (for the latest seed) that was persisted to the
-  // store.
+  // local state.
   base::Time GetLastFetchTime() const;
 
-  // Returns the time at which the safe seed was fetched.
+  // Returns the time at which the safe seed was persisted to the local state.
   base::Time GetSafeSeedFetchTime() const;
 
   // Records |fetch_time| as the last time at which a seed was fetched
@@ -140,11 +140,15 @@
   // more efficient to call LoadSeed() prior to calling this method.
   const std::string& GetLatestSerialNumber();
 
+  PrefService* local_state() { return local_state_; }
+  const PrefService* local_state() const { return local_state_; }
+
   // Registers Local State prefs used by this class.
   static void RegisterPrefs(PrefRegistrySimple* registry);
 
-  PrefService* local_state() { return local_state_; }
-  const PrefService* local_state() const { return local_state_; }
+  // Loads the last fetch time (for the latest seed) that was persisted to
+  // |local_state|.
+  static base::Time GetLastFetchTimeFromPrefService(PrefService* local_state);
 
   static VerifySignatureResult VerifySeedSignatureForTesting(
       const std::string& seed_bytes,
diff --git a/content/browser/attribution_reporting/attribution_debug_report.cc b/content/browser/attribution_reporting/attribution_debug_report.cc
index 63bacb5..18fe199 100644
--- a/content/browser/attribution_reporting/attribution_debug_report.cc
+++ b/content/browser/attribution_reporting/attribution_debug_report.cc
@@ -22,7 +22,8 @@
 namespace {
 
 absl::optional<AttributionDebugReport::DataType> GetReportDataType(
-    StorableSource::Result result) {
+    StorableSource::Result result,
+    bool is_debug_cookie_set) {
   switch (result) {
     case StorableSource::Result::kSuccess:
     case StorableSource::Result::kInternalError:
@@ -32,6 +33,11 @@
       return absl::nullopt;
     case StorableSource::Result::kInsufficientUniqueDestinationCapacity:
       return AttributionDebugReport::DataType::kSourceDestinationLimit;
+    case StorableSource::Result::kSuccessNoised:
+      return is_debug_cookie_set
+                 ? absl::make_optional(
+                       AttributionDebugReport::DataType::kSourceNoised)
+                 : absl::nullopt;
   }
 }
 
@@ -40,6 +46,8 @@
   switch (data_type) {
     case AttributionDebugReport::DataType::kSourceDestinationLimit:
       return "source-destination-limit";
+    case AttributionDebugReport::DataType::kSourceNoised:
+      return "source-noised";
   }
 }
 
@@ -47,21 +55,26 @@
     AttributionDebugReport::DataType data_type,
     const StorableSource& source,
     absl::optional<int> max_destinations_per_source_site_reporting_origin) {
+  const CommonSourceInfo& common_info = source.common_info();
+  base::Value::Dict data_body;
+  data_body.Set("attribution_destination",
+                common_info.DestinationSite().Serialize());
+  data_body.Set("source_event_id",
+                base::NumberToString(common_info.source_event_id()));
+  if (!source.is_within_fenced_frame())
+    data_body.Set("source_site", common_info.SourceSite().Serialize());
+
   switch (data_type) {
     case AttributionDebugReport::DataType::kSourceDestinationLimit:
       DCHECK(max_destinations_per_source_site_reporting_origin);
-      const CommonSourceInfo& common_info = source.common_info();
-      base::Value::Dict data_body;
-      data_body.Set("attribution_destination",
-                    common_info.DestinationSite().Serialize());
-      data_body.Set("source_event_id",
-                    base::NumberToString(common_info.source_event_id()));
       data_body.Set("limit",
                     *max_destinations_per_source_site_reporting_origin);
-      if (!source.is_within_fenced_frame())
-        data_body.Set("source_site", common_info.SourceSite().Serialize());
-      return data_body;
+      break;
+    case AttributionDebugReport::DataType::kSourceNoised:
+      break;
   }
+
+  return data_body;
 }
 
 }  // namespace
@@ -105,8 +118,13 @@
 // static
 absl::optional<AttributionDebugReport> AttributionDebugReport::Create(
     const StorableSource& source,
+    bool is_debug_cookie_set,
     const AttributionStorage::StoreSourceResult& result) {
-  absl::optional<DataType> data_type = GetReportDataType(result.status);
+  if (!source.debug_reporting())
+    return absl::nullopt;
+
+  absl::optional<DataType> data_type =
+      GetReportDataType(result.status, is_debug_cookie_set);
   if (!data_type)
     return absl::nullopt;
 
diff --git a/content/browser/attribution_reporting/attribution_debug_report.h b/content/browser/attribution_reporting/attribution_debug_report.h
index 924cb6a..c38fadd 100644
--- a/content/browser/attribution_reporting/attribution_debug_report.h
+++ b/content/browser/attribution_reporting/attribution_debug_report.h
@@ -25,10 +25,12 @@
  public:
   enum class DataType {
     kSourceDestinationLimit,
+    kSourceNoised,
   };
 
   static absl::optional<AttributionDebugReport> Create(
       const StorableSource& source,
+      bool is_debug_cookie_set,
       const AttributionStorage::StoreSourceResult& result);
 
   ~AttributionDebugReport();
diff --git a/content/browser/attribution_reporting/attribution_debug_report_unittest.cc b/content/browser/attribution_reporting/attribution_debug_report_unittest.cc
index c739d9a8..109a852 100644
--- a/content/browser/attribution_reporting/attribution_debug_report_unittest.cc
+++ b/content/browser/attribution_reporting/attribution_debug_report_unittest.cc
@@ -15,11 +15,22 @@
 namespace content {
 namespace {
 
+TEST(AttributionDebugReportTest, NoDebugReporting_NoReportReturned) {
+  EXPECT_FALSE(AttributionDebugReport::Create(
+      SourceBuilder().Build(),
+      /*is_debug_cookie_set=*/false,
+      AttributionStorage::StoreSourceResult(
+          StorableSource::Result::kInsufficientUniqueDestinationCapacity,
+          /*min_fake_report_time=*/absl::nullopt,
+          /*max_destinations_per_source_site_reporting_origin=*/3)));
+}
+
 TEST(AttributionDebugReportTest,
      SourceDestinationLimitError_ValidReportReturned) {
   absl::optional<AttributionDebugReport> report =
       AttributionDebugReport::Create(
-          SourceBuilder().Build(),
+          SourceBuilder().SetDebugReporting(true).Build(),
+          /*is_debug_cookie_set=*/false,
           AttributionStorage::StoreSourceResult(
               StorableSource::Result::kInsufficientUniqueDestinationCapacity,
               /*min_fake_report_time=*/absl::nullopt,
@@ -48,7 +59,11 @@
 
   absl::optional<AttributionDebugReport> report =
       AttributionDebugReport::Create(
-          SourceBuilder().SetIsWithinFencedFrame(true).Build(),
+          SourceBuilder()
+              .SetDebugReporting(true)
+              .SetIsWithinFencedFrame(true)
+              .Build(),
+          /*is_debug_cookie_set=*/false,
           AttributionStorage::StoreSourceResult(
               StorableSource::Result::kInsufficientUniqueDestinationCapacity,
               /*min_fake_report_time=*/absl::nullopt,
@@ -69,19 +84,87 @@
                                       "attribution-reporting/debug/verbose"));
 }
 
-TEST(AttributionDebugReportTest, UnsupportedError_NoDebugReports) {
-  static constexpr StorableSource::Result kResults[] = {
-      StorableSource::Result::kSuccess,
-      StorableSource::Result::kInternalError,
-      StorableSource::Result::kInsufficientSourceCapacity,
-      StorableSource::Result::kExcessiveReportingOrigins,
-      StorableSource::Result::kProhibitedByBrowserPolicy,
+TEST(AttributionDebugReportTest, SourceDebugging) {
+  const struct {
+    StorableSource::Result result;
+    absl::optional<int> max_destinations_per_source_site_reporting_origin;
+    const char* expected_report_body_without_cookie;
+    const char* expected_report_body_with_cookie;
+  } kTestCases[] = {
+      {StorableSource::Result::kSuccess,
+       /*max_destinations_per_source_site_reporting_origin=*/absl::nullopt,
+       /*expected_report_body_without_cookie=*/nullptr,
+       /*expected_report_body_with_cookie=*/nullptr},
+      {StorableSource::Result::kInternalError,
+       /*max_destinations_per_source_site_reporting_origin=*/absl::nullopt,
+       /*expected_report_body_without_cookie=*/nullptr,
+       /*expected_report_body_with_cookie=*/nullptr},
+      {StorableSource::Result::kInsufficientSourceCapacity,
+       /*max_destinations_per_source_site_reporting_origin=*/absl::nullopt,
+       /*expected_report_body_without_cookie=*/nullptr,
+       /*expected_report_body_with_cookie=*/nullptr},
+      {StorableSource::Result::kProhibitedByBrowserPolicy,
+       /*max_destinations_per_source_site_reporting_origin=*/absl::nullopt,
+       /*expected_report_body_without_cookie=*/nullptr,
+       /*expected_report_body_with_cookie=*/nullptr},
+      {StorableSource::Result::kInsufficientUniqueDestinationCapacity,
+       /*max_destinations_per_source_site_reporting_origin=*/3,
+       /*expected_report_body_without_cookie=*/
+       R"json([{
+         "body": {
+           "attribution_destination": "https://conversion.test",
+           "limit": 3,
+           "source_event_id": "123",
+           "source_site": "https://impression.test"
+         },
+         "type": "source-destination-limit"
+       }])json",
+       /*expected_report_body_with_cookie=*/
+       R"json([{
+         "body": {
+           "attribution_destination": "https://conversion.test",
+           "limit": 3,
+           "source_event_id": "123",
+           "source_site": "https://impression.test"
+         },
+         "type": "source-destination-limit"
+       }])json"},
+      {StorableSource::Result::kSuccessNoised,
+       /*max_destinations_per_source_site_reporting_origin=*/absl::nullopt,
+       /*expected_report_body_without_cookie=*/nullptr,
+       /*expected_report_body_with_cookie=*/
+       R"json([{
+         "body": {
+           "attribution_destination": "https://conversion.test",
+           "source_event_id": "123",
+           "source_site": "https://impression.test"
+         },
+         "type": "source-noised"
+       }])json"},
   };
 
-  for (auto result : kResults) {
-    EXPECT_FALSE(AttributionDebugReport::Create(
-        SourceBuilder().Build(),
-        AttributionStorage::StoreSourceResult(result)));
+  for (bool is_debug_cookie_set : {false, true}) {
+    for (const auto& test_case : kTestCases) {
+      absl::optional<AttributionDebugReport> report =
+          AttributionDebugReport::Create(
+              SourceBuilder().SetDebugReporting(true).Build(),
+              is_debug_cookie_set,
+              AttributionStorage::StoreSourceResult(
+                  test_case.result,
+                  /*min_fake_report_time=*/absl::nullopt,
+                  /*max_destinations_per_source_site_reporting_origin=*/
+                  test_case.max_destinations_per_source_site_reporting_origin));
+      const char* expected_report_body =
+          is_debug_cookie_set ? test_case.expected_report_body_with_cookie
+                              : test_case.expected_report_body_without_cookie;
+      EXPECT_EQ(report.has_value(), expected_report_body != nullptr)
+          << test_case.result << ", " << is_debug_cookie_set;
+      if (expected_report_body) {
+        EXPECT_EQ(report->ReportBody(),
+                  base::test::ParseJson(expected_report_body))
+            << test_case.result << ", " << is_debug_cookie_set;
+      }
+    }
   }
 }
 
diff --git a/content/browser/attribution_reporting/attribution_internals_handler_impl.cc b/content/browser/attribution_reporting/attribution_internals_handler_impl.cc
index 38650d54..974b9d8b3 100644
--- a/content/browser/attribution_reporting/attribution_internals_handler_impl.cc
+++ b/content/browser/attribution_reporting/attribution_internals_handler_impl.cc
@@ -305,6 +305,8 @@
 
   switch (result) {
     case StorableSource::Result::kSuccess:
+    // TODO(linnan): Consider displaying source noised in internals UI.
+    case StorableSource::Result::kSuccessNoised:
       return;
     case StorableSource::Result::kInternalError:
       attributability = Attributability::kInternalError;
diff --git a/content/browser/attribution_reporting/attribution_manager_impl.cc b/content/browser/attribution_reporting/attribution_manager_impl.cc
index 63c29fd06..12ef1bf 100644
--- a/content/browser/attribution_reporting/attribution_manager_impl.cc
+++ b/content/browser/attribution_reporting/attribution_manager_impl.cc
@@ -161,9 +161,9 @@
 
 void RecordStoreSourceStatus(AttributionStorage::StoreSourceResult result) {
   static_assert(StorableSource::Result::kMaxValue ==
-                    StorableSource::Result::kProhibitedByBrowserPolicy,
-                "Bump version of Conversions.SourceStoredStatus histogram.");
-  base::UmaHistogramEnumeration("Conversions.SourceStoredStatus",
+                    StorableSource::Result::kSuccessNoised,
+                "Bump version of Conversions.SourceStoredStatus2 histogram.");
+  base::UmaHistogramEnumeration("Conversions.SourceStoredStatus2",
                                 result.status);
 }
 
@@ -480,17 +480,19 @@
 
 void AttributionManagerImpl::StoreSource(
     StorableSource source,
-    absl::optional<uint64_t> cleared_debug_key) {
+    absl::optional<uint64_t> cleared_debug_key,
+    bool is_debug_cookie_set) {
   attribution_storage_.AsyncCall(&AttributionStorage::StoreSource)
       .WithArgs(source)
       .Then(base::BindOnce(&AttributionManagerImpl::OnSourceStored,
                            weak_factory_.GetWeakPtr(), std::move(source),
-                           cleared_debug_key));
+                           cleared_debug_key, is_debug_cookie_set));
 }
 
 void AttributionManagerImpl::OnSourceStored(
     StorableSource source,
     absl::optional<uint64_t> cleared_debug_key,
+    bool is_debug_cookie_set,
     AttributionStorage::StoreSourceResult result) {
   RecordStoreSourceStatus(result);
 
@@ -501,8 +503,7 @@
 
   NotifySourcesChanged();
 
-  if (source.debug_reporting())
-    MaybeSendVerboseDebugReport(std::move(source), result);
+  MaybeSendVerboseDebugReport(source, is_debug_cookie_set, result);
 }
 
 void AttributionManagerImpl::HandleTrigger(AttributionTrigger trigger) {
@@ -595,7 +596,7 @@
             if (!allowed) {
               this->OnSourceStored(
                   std::move(source),
-                  /*cleared_debug_key=*/absl::nullopt,
+                  /*cleared_debug_key=*/absl::nullopt, is_debug_cookie_set,
                   AttributionStorage::StoreSourceResult(
                       StorableSource::Result::kProhibitedByBrowserPolicy));
               return;
@@ -607,7 +608,8 @@
               common_info.ClearDebugKey();
             }
 
-            this->StoreSource(std::move(source), cleared_debug_key);
+            this->StoreSource(std::move(source), cleared_debug_key,
+                              is_debug_cookie_set);
           },
 
           [&](AttributionTrigger trigger) {
@@ -986,10 +988,11 @@
 }
 
 void AttributionManagerImpl::MaybeSendVerboseDebugReport(
-    StorableSource source,
-    AttributionStorage::StoreSourceResult result) {
+    const StorableSource& source,
+    bool is_debug_cookie_set,
+    const AttributionStorage::StoreSourceResult& result) {
   if (absl::optional<AttributionDebugReport> debug_report =
-          AttributionDebugReport::Create(source, result)) {
+          AttributionDebugReport::Create(source, is_debug_cookie_set, result)) {
     report_sender_->SendReport(std::move(*debug_report));
   }
 }
diff --git a/content/browser/attribution_reporting/attribution_manager_impl.h b/content/browser/attribution_reporting/attribution_manager_impl.h
index 73426064..326c27e 100644
--- a/content/browser/attribution_reporting/attribution_manager_impl.h
+++ b/content/browser/attribution_reporting/attribution_manager_impl.h
@@ -155,7 +155,8 @@
   void ProcessEvents();
   void ProcessNextEvent(bool is_debug_cookie_set);
   void StoreSource(StorableSource source,
-                   absl::optional<uint64_t> cleared_debug_key);
+                   absl::optional<uint64_t> cleared_debug_key,
+                   bool is_debug_cookie_set);
   void StoreTrigger(AttributionTrigger trigger,
                     absl::optional<uint64_t> cleared_debug_key);
 
@@ -188,6 +189,7 @@
 
   void OnSourceStored(StorableSource source,
                       absl::optional<uint64_t> cleared_debug_key,
+                      bool is_debug_cookie_set,
                       AttributionStorage::StoreSourceResult result);
   void OnReportStored(AttributionTrigger trigger,
                       absl::optional<uint64_t> cleared_debug_key,
@@ -202,8 +204,9 @@
   bool IsReportAllowed(const AttributionReport&) const;
 
   void MaybeSendVerboseDebugReport(
-      StorableSource source,
-      AttributionStorage::StoreSourceResult result);
+      const StorableSource& source,
+      bool is_debug_cookie_set,
+      const AttributionStorage::StoreSourceResult& result);
 
   // Never null.
   const raw_ptr<StoragePartitionImpl> storage_partition_;
diff --git a/content/browser/attribution_reporting/attribution_manager_impl_unittest.cc b/content/browser/attribution_reporting/attribution_manager_impl_unittest.cc
index e9aa0ef..73709030 100644
--- a/content/browser/attribution_reporting/attribution_manager_impl_unittest.cc
+++ b/content/browser/attribution_reporting/attribution_manager_impl_unittest.cc
@@ -1056,7 +1056,7 @@
   base::HistogramTester histograms;
   attribution_manager_->HandleSource(SourceBuilder().Build());
   task_environment_.RunUntilIdle();
-  histograms.ExpectUniqueSample("Conversions.SourceStoredStatus",
+  histograms.ExpectUniqueSample("Conversions.SourceStoredStatus2",
                                 StorableSource::Result::kSuccess, 1);
 }
 
diff --git a/content/browser/attribution_reporting/attribution_report_network_sender_unittest.cc b/content/browser/attribution_reporting/attribution_report_network_sender_unittest.cc
index 5cf48a3..89957a3 100644
--- a/content/browser/attribution_reporting/attribution_report_network_sender_unittest.cc
+++ b/content/browser/attribution_reporting/attribution_report_network_sender_unittest.cc
@@ -905,7 +905,8 @@
 
   absl::optional<AttributionDebugReport> report =
       AttributionDebugReport::Create(
-          SourceBuilder().Build(),
+          SourceBuilder().SetDebugReporting(true).Build(),
+          /*is_debug_cookie_set=*/false,
           AttributionStorage::StoreSourceResult(
               StorableSource::Result::kInsufficientUniqueDestinationCapacity,
               /*min_fake_report_time=*/absl::nullopt,
diff --git a/content/browser/attribution_reporting/attribution_storage_sql.cc b/content/browser/attribution_reporting/attribution_storage_sql.cc
index 35b914df..622b8b8 100644
--- a/content/browser/attribution_reporting/attribution_storage_sql.cc
+++ b/content/browser/attribution_reporting/attribution_storage_sql.cc
@@ -627,8 +627,11 @@
   if (!transaction.Commit())
     return StoreSourceResult(StorableSource::Result::kInternalError);
 
-  return StoreSourceResult(StorableSource::Result::kSuccess,
-                           min_fake_report_time);
+  return StoreSourceResult(
+      attribution_logic == StoredSource::AttributionLogic::kTruthfully
+          ? StorableSource::Result::kSuccess
+          : StorableSource::Result::kSuccessNoised,
+      min_fake_report_time);
 }
 
 // Checks whether a new report is allowed to be stored for the given source
diff --git a/content/browser/attribution_reporting/attribution_storage_unittest.cc b/content/browser/attribution_reporting/attribution_storage_unittest.cc
index 4d75502..737e65a 100644
--- a/content/browser/attribution_reporting/attribution_storage_unittest.cc
+++ b/content/browser/attribution_reporting/attribution_storage_unittest.cc
@@ -932,7 +932,9 @@
 
   delegate()->set_randomized_response(
       std::vector<AttributionStorageDelegate::FakeReport>{});
-  storage()->StoreSource(TestAggregatableSourceProvider().GetBuilder().Build());
+  AttributionStorage::StoreSourceResult result = storage()->StoreSource(
+      TestAggregatableSourceProvider().GetBuilder().Build());
+  EXPECT_EQ(result.status, StorableSource::Result::kSuccessNoised);
   delegate()->set_randomized_response(absl::nullopt);
 
   EXPECT_THAT(storage()->MaybeCreateAndStoreReport(
@@ -1316,7 +1318,9 @@
   delegate()->set_randomized_response(
       std::vector<AttributionStorageDelegate::FakeReport>{
           {.trigger_data = 7, .report_time = fake_report_time}});
-  storage()->StoreSource(builder.Build());
+  AttributionStorage::StoreSourceResult result =
+      storage()->StoreSource(builder.Build());
+  EXPECT_EQ(result.status, StorableSource::Result::kSuccessNoised);
   delegate()->set_randomized_response(absl::nullopt);
 
   base::Time trigger_time = base::Time::Now();
@@ -1407,7 +1411,9 @@
     delegate()->set_randomized_response(test_case.randomized_response);
 
     auto result = storage()->StoreSource(SourceBuilder().Build());
-    EXPECT_EQ(result.status, StorableSource::Result::kSuccess);
+    EXPECT_EQ(result.status, test_case.randomized_response
+                                 ? StorableSource::Result::kSuccessNoised
+                                 : StorableSource::Result::kSuccess);
     EXPECT_EQ(result.min_fake_report_time, test_case.expected);
   }
 }
diff --git a/content/browser/attribution_reporting/attribution_test_utils.cc b/content/browser/attribution_reporting/attribution_test_utils.cc
index 87687126..bd134d5 100644
--- a/content/browser/attribution_reporting/attribution_test_utils.cc
+++ b/content/browser/attribution_reporting/attribution_test_utils.cc
@@ -1300,6 +1300,8 @@
       return out << "excessiveReportingOrigins";
     case StorableSource::Result::kProhibitedByBrowserPolicy:
       return out << "prohibitedByBrowserPolicy";
+    case StorableSource::Result::kSuccessNoised:
+      return out << "successNoised";
   }
 }
 
diff --git a/content/browser/attribution_reporting/storable_source.h b/content/browser/attribution_reporting/storable_source.h
index 5ae7395..027f2c83 100644
--- a/content/browser/attribution_reporting/storable_source.h
+++ b/content/browser/attribution_reporting/storable_source.h
@@ -24,7 +24,8 @@
     kInsufficientUniqueDestinationCapacity = 3,
     kExcessiveReportingOrigins = 4,
     kProhibitedByBrowserPolicy = 5,
-    kMaxValue = kProhibitedByBrowserPolicy,
+    kSuccessNoised = 6,
+    kMaxValue = kSuccessNoised,
   };
 
   StorableSource(CommonSourceInfo common_info,
diff --git a/content/browser/cache_storage/cache_storage_browsertest.cc b/content/browser/cache_storage/cache_storage_browsertest.cc
deleted file mode 100644
index 0291f17..0000000
--- a/content/browser/cache_storage/cache_storage_browsertest.cc
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2022 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "components/services/storage/public/cpp/constants.h"
-#include "content/public/browser/browser_context.h"
-#include "content/public/browser/storage_partition.h"
-#include "content/public/test/browser_test.h"
-#include "content/public/test/browser_test_utils.h"
-#include "content/public/test/content_browser_test.h"
-#include "content/public/test/content_browser_test_utils.h"
-#include "content/shell/browser/shell.h"
-#include "storage/browser/quota/quota_manager_impl.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "url/gurl.h"
-
-namespace content {
-
-class CacheStorageBrowserTest : public ContentBrowserTest {
- public:
-  CacheStorageBrowserTest() = default;
-
-  base::FilePath profile_path() {
-    return shell()
-        ->web_contents()
-        ->GetBrowserContext()
-        ->GetDefaultStoragePartition()
-        ->GetPath();
-  }
-};
-
-// Test for https://crbug.com/1370035 - when a CacheStorage index file without
-// bucket information is present on disk and the QuotaDatabase has't been
-// bootstrapped yet, the `CacheStorageManager::GetStorageKeys()` implementation
-// must not attempt to use the QuotaManagerProxy to lookup bucket information.
-// Doing so creates a deadlock, because `GetStorageKeys()` would wait for the
-// bucket information to be returned and the QuotaManager won't respond with
-// bucket information until the `GetStorageKeys()` call finishes (as part of the
-// bootstrapping process).
-IN_PROC_BROWSER_TEST_F(CacheStorageBrowserTest, GetStorageKeysTest) {
-  base::ScopedAllowBlockingForTesting allow_blocking;
-
-  ASSERT_TRUE(embedded_test_server()->Start());
-
-  // Set up the profile directory to have a CacheStorage index file that hasn't
-  // been migrated to contain bucket information yet.
-  base::FilePath service_worker_dir_path =
-      profile_path().Append(storage::kServiceWorkerDirectory);
-  base::FilePath cache_storage_dir_path =
-      service_worker_dir_path.Append(storage::kCacheStorageDirectory);
-
-  EXPECT_FALSE(base::PathExists(service_worker_dir_path));
-  EXPECT_TRUE(base::CreateDirectory(service_worker_dir_path));
-
-  EXPECT_FALSE(base::PathExists(cache_storage_dir_path));
-  EXPECT_TRUE(base::CreateDirectory(cache_storage_dir_path));
-
-  base::FilePath test_cache_storage_origin_path =
-      GetTestFilePath("cache_storage", "storage_key")
-          .AppendASCII("0430f1a484a0ea6d8de562488c5fbeec0111d16f");
-  EXPECT_TRUE(base::PathExists(test_cache_storage_origin_path));
-
-  EXPECT_TRUE(base::CopyDirectory(test_cache_storage_origin_path,
-                                  cache_storage_dir_path,
-                                  /*recursive=*/true));
-
-  // Navigate to any page that we can use for testing.
-  GURL empty_url(embedded_test_server()->GetURL("/empty.html"));
-  ASSERT_TRUE(NavigateToURL(shell(), empty_url));
-
-  // Assume that the WebStorage directory doesn't exist yet. This indicates that
-  // the QuotaDatabase hasn't been bootstrapped, which is a precondition for
-  // this test.
-  base::FilePath web_storage_dir_path =
-      profile_path().Append(storage::kWebStorageDirectory);
-  EXPECT_FALSE(base::PathExists(web_storage_dir_path));
-
-  // Use an API that will cause the Quota subsystem to bootstrap itself. We are
-  // testing that calling this function doesn't hang.
-  EXPECT_EQ(true, EvalJs(shell(), R"(
-        navigator.storage.estimate().then(
-          ()=>{ return true; },
-          ()=>{ return false; });)"));
-
-  // Verify that the WebStorage/QuotaManager directory was created as a result
-  // of the Javascript execution.
-  EXPECT_TRUE(base::PathExists(web_storage_dir_path.AppendASCII(
-      storage::QuotaManagerImpl::kDatabaseName)));
-}
-
-}  // namespace content
diff --git a/content/browser/devtools/protocol/webauthn_handler.cc b/content/browser/devtools/protocol/webauthn_handler.cc
index f536523b..3a222a2 100644
--- a/content/browser/devtools/protocol/webauthn_handler.cc
+++ b/content/browser/devtools/protocol/webauthn_handler.cc
@@ -272,6 +272,29 @@
   return Response::Success();
 }
 
+Response WebAuthnHandler::SetResponseOverrideBits(
+    const String& authenticator_id,
+    Maybe<bool> is_bogus_signature,
+    Maybe<bool> is_bad_uv,
+    Maybe<bool> is_bad_up) {
+  VirtualAuthenticatorManagerImpl* authenticator_manager =
+      AuthenticatorEnvironmentImpl::GetInstance()
+          ->MaybeGetVirtualAuthenticatorManager(frame_host_->frame_tree_node());
+  if (!authenticator_manager)
+    return Response::ServerError(kVirtualEnvironmentNotEnabled);
+
+  VirtualAuthenticator* authenticator;
+  Response response = FindAuthenticator(authenticator_id, &authenticator);
+  if (!response.IsSuccess())
+    return Response::InvalidParams(kAuthenticatorNotFound);
+
+  authenticator->set_bogus_signature(
+      is_bogus_signature.fromMaybe(/*default_value=*/false));
+  authenticator->set_bad_uv_bit(is_bad_uv.fromMaybe(/*default_value=*/false));
+  authenticator->set_bad_up_bit(is_bad_up.fromMaybe(/*default_value=*/false));
+  return Response::Success();
+}
+
 void WebAuthnHandler::AddCredential(
     const String& authenticator_id,
     std::unique_ptr<WebAuthn::Credential> credential,
diff --git a/content/browser/devtools/protocol/webauthn_handler.h b/content/browser/devtools/protocol/webauthn_handler.h
index 63b417a..ec0d754b 100644
--- a/content/browser/devtools/protocol/webauthn_handler.h
+++ b/content/browser/devtools/protocol/webauthn_handler.h
@@ -34,6 +34,10 @@
       std::unique_ptr<WebAuthn::VirtualAuthenticatorOptions> options,
       String* out_authenticator_id) override;
   Response RemoveVirtualAuthenticator(const String& authenticator_id) override;
+  Response SetResponseOverrideBits(const String& authenticator_id,
+                                   Maybe<bool> is_bogus_signature,
+                                   Maybe<bool> is_bad_uv,
+                                   Maybe<bool> is_bad_up) override;
   void AddCredential(const String& authenticator_id,
                      std::unique_ptr<protocol::WebAuthn::Credential> credential,
                      std::unique_ptr<AddCredentialCallback> callback) override;
diff --git a/content/browser/devtools/protocol_config.json b/content/browser/devtools/protocol_config.json
index def8724d..cf9f041 100644
--- a/content/browser/devtools/protocol_config.json
+++ b/content/browser/devtools/protocol_config.json
@@ -120,7 +120,7 @@
             },
             {
                 "domain": "WebAuthn",
-                "include": ["enable", "disable", "addVirtualAuthenticator", "removeVirtualAuthenticator", "addCredential", "removeCredential", "clearCredentials", "getCredential", "getCredentials", "setUserVerified", "setAutomaticPresenceSimulation"],
+                "include": ["enable", "disable", "addVirtualAuthenticator", "removeVirtualAuthenticator", "addCredential", "removeCredential", "clearCredentials", "getCredential", "getCredentials", "setUserVerified", "setAutomaticPresenceSimulation", "setResponseOverrideBits"],
                 "async": ["addCredential", "getCredential", "getCredentials"]
             }
         ]
diff --git a/content/browser/quota/quota_browsertest.cc b/content/browser/quota/quota_browsertest.cc
new file mode 100644
index 0000000..163a9cb
--- /dev/null
+++ b/content/browser/quota/quota_browsertest.cc
@@ -0,0 +1,235 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "build/build_config.h"
+#include "components/services/storage/public/cpp/constants.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/storage_partition.h"
+#include "content/public/test/browser_test.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "content/shell/browser/shell.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+namespace content {
+
+class QuotaBrowserTest : public ContentBrowserTest {
+ public:
+  QuotaBrowserTest() = default;
+
+  base::FilePath profile_path() {
+    return shell()
+        ->web_contents()
+        ->GetBrowserContext()
+        ->GetDefaultStoragePartition()
+        ->GetPath();
+  }
+};
+
+// TODO(crbug.com/654704): Android does not support PRE_ tests.
+#if !BUILDFLAG(IS_ANDROID)
+IN_PROC_BROWSER_TEST_F(QuotaBrowserTest, PRE_QuotaDatabaseBootstrapTest) {
+  base::ScopedAllowBlockingForTesting allow_blocking;
+
+  ASSERT_TRUE(embedded_test_server()->Start());
+  GURL empty_url(embedded_test_server()->GetURL("/empty.html"));
+  ASSERT_TRUE(NavigateToURL(shell(), empty_url));
+
+  // Call storage APIs to populate data on-disk in their legacy file paths.
+  //
+  // Cache Storage
+  EXPECT_EQ(true, EvalJs(shell(), R"(
+    new Promise((resolve) => {
+      self.caches.open("attachements")
+        .then((cache) => {
+            return cache.put("notes.txt", new Response("foo"));
+          })
+        .then(() => { resolve(true); })
+        .catch(() => { resolve(false); });
+    });)"));
+
+  // IndexedDB
+  EXPECT_EQ(true, EvalJs(shell(), R"(
+    new Promise((resolve) => {
+      const request = window.indexedDB.open('notes');
+      request.onupgradeneeded = (event) => {
+        event.target.result.createObjectStore('primary', {keyPath: 'id'});
+        event.target.transaction.commit();
+      };
+      request.onsuccess = () => resolve(true);
+      request.onerror = () => resolve(false);
+    });)"));
+
+  // FileSystem
+  EXPECT_EQ(true, EvalJs(shell(), R"(
+    new Promise((resolve, reject) => {
+      window.webkitRequestFileSystem(
+        window.TEMPORARY,
+        1024 * 1024,
+        (fs) => {
+          fs.root.getFile('file.txt', {create: true}, (entry) => {
+            entry.createWriter((writer) => {
+              writer.onwriteend = () => {
+                resolve(true);
+              };
+              writer.onerror = reject;
+              var blob = new Blob(['foo'], {type: 'text/plain'});
+              writer.write(blob);
+            }, reject);
+          }, reject);
+        }, reject);
+      });)"));
+
+  // WebSQL
+  EXPECT_EQ(true, EvalJs(shell(), R"(
+    new Promise((resolve) => {
+      let db = window.openDatabase('notes_db', "1.0", "", 1);
+      resolve(db ? true : false);
+    });)"));
+
+  // ServiceWorker
+  ASSERT_TRUE(NavigateToURL(shell(),
+                            embedded_test_server()->GetURL(
+                                "/service_worker/create_service_worker.html")));
+  EXPECT_EQ("DONE", EvalJs(shell(), "register('empty.js');"));
+
+  // Verify that the WebStorage directory and QuotaDatabase exists as a result
+  // of accessing Storage APIs.
+  base::FilePath web_storage_dir_path =
+      profile_path().Append(storage::kWebStorageDirectory);
+  EXPECT_TRUE(base::PathExists(web_storage_dir_path));
+  base::FilePath db_path = web_storage_dir_path.AppendASCII(
+      storage::QuotaManagerImpl::kDatabaseName);
+  EXPECT_TRUE(base::PathExists(db_path));
+}
+
+// Continue testing after a restart to ensure that processes to the
+// QuotaDatabase are disconnected.
+IN_PROC_BROWSER_TEST_F(QuotaBrowserTest, QuotaDatabaseBootstrapTest) {
+  base::ScopedAllowBlockingForTesting allow_blocking;
+  // Verify that calling the APIs have created files on-disk in their legacy
+  // file paths. This is done after shutdown to ensure data has been flushed to
+  // disk after javascript execution.
+  //
+  // CacheStorage
+  base::FilePath service_worker_dir =
+      profile_path().Append(storage::kServiceWorkerDirectory);
+  EXPECT_TRUE(base::PathExists(service_worker_dir));
+  base::FilePath cache_dir =
+      service_worker_dir.Append(storage::kCacheStorageDirectory);
+  EXPECT_TRUE(base::PathExists(cache_dir));
+  EXPECT_FALSE(base::IsDirectoryEmpty(cache_dir));
+
+  // IndexedDB
+  base::FilePath idb_dir = profile_path().Append(storage::kIndexedDbDirectory);
+  EXPECT_TRUE(base::PathExists(idb_dir));
+  EXPECT_FALSE(base::IsDirectoryEmpty(idb_dir));
+
+  // FileSystem
+  base::FilePath fs_dir =
+      profile_path().Append(FILE_PATH_LITERAL("File System"));
+  EXPECT_TRUE(base::PathExists(fs_dir));
+  EXPECT_FALSE(base::IsDirectoryEmpty(fs_dir));
+
+  // WebSQL
+  base::FilePath websql_dir =
+      profile_path().Append(FILE_PATH_LITERAL("databases"));
+  EXPECT_TRUE(base::PathExists(websql_dir));
+  EXPECT_FALSE(base::IsDirectoryEmpty(websql_dir));
+
+  // ServiceWorker
+  base::FilePath script_dir =
+      service_worker_dir.Append(storage::kScriptCacheDirectory);
+  EXPECT_TRUE(base::PathExists(script_dir));
+  EXPECT_FALSE(base::IsDirectoryEmpty(script_dir));
+
+  // Delete WebStorage directory to force a new database creation if one exists
+  // so it triggers the bootstrap task. This is done after shutdown to ensure
+  // files aren't accessed.
+  base::FilePath web_storage_dir_path =
+      profile_path().Append(storage::kWebStorageDirectory);
+  EXPECT_TRUE(base::DeletePathRecursively(web_storage_dir_path));
+
+  ASSERT_TRUE(embedded_test_server()->Start());
+  GURL empty_url(embedded_test_server()->GetURL("/empty.html"));
+  ASSERT_TRUE(NavigateToURL(shell(), empty_url));
+
+  // Use an API that will cause the Quota subsystem to bootstrap itself. We are
+  // testing that calling this function doesn't hang.
+  EXPECT_EQ(true, EvalJs(shell(), R"(
+    navigator.storage.estimate().then(
+      ()=>{ return true; },
+      ()=>{ return false; });)"));
+
+  // Verify that the WebStorage/QuotaManager directory was created as a result
+  // of the Javascript execution.
+  EXPECT_TRUE(base::PathExists(web_storage_dir_path));
+  base::FilePath db_path = web_storage_dir_path.AppendASCII(
+      storage::QuotaManagerImpl::kDatabaseName);
+  EXPECT_TRUE(base::PathExists(db_path));
+}
+#endif  // !BUILDFLAG(IS_ANDROID)
+
+// Test for https://crbug.com/1370035 - when a CacheStorage index file without
+// bucket information is present on disk and the QuotaDatabase has't been
+// bootstrapped yet, the `CacheStorageManager::GetStorageKeys()` implementation
+// must not attempt to use the QuotaManagerProxy to lookup bucket information.
+// Doing so creates a deadlock, because `GetStorageKeys()` would wait for the
+// bucket information to be returned and the QuotaManager won't respond with
+// bucket information until the `GetStorageKeys()` call finishes (as part of the
+// bootstrapping process).
+IN_PROC_BROWSER_TEST_F(QuotaBrowserTest,
+                       QuotaDatabaseBootstrapUnmigratedCacheStorageTest) {
+  base::ScopedAllowBlockingForTesting allow_blocking;
+  // Set up the profile directory to have a CacheStorage index file that hasn't
+  // been migrated to contain bucket information yet.
+  base::FilePath service_worker_dir_path =
+      profile_path().Append(storage::kServiceWorkerDirectory);
+  base::FilePath cache_storage_dir_path =
+      service_worker_dir_path.Append(storage::kCacheStorageDirectory);
+
+  EXPECT_FALSE(base::PathExists(service_worker_dir_path));
+  EXPECT_TRUE(base::CreateDirectory(service_worker_dir_path));
+
+  EXPECT_FALSE(base::PathExists(cache_storage_dir_path));
+  EXPECT_TRUE(base::CreateDirectory(cache_storage_dir_path));
+
+  base::FilePath test_cache_storage_origin_path =
+      GetTestFilePath("cache_storage", "storage_key")
+          .AppendASCII("0430f1a484a0ea6d8de562488c5fbeec0111d16f");
+
+  EXPECT_TRUE(base::PathExists(test_cache_storage_origin_path));
+  EXPECT_TRUE(base::CopyDirectory(test_cache_storage_origin_path,
+                                  cache_storage_dir_path,
+                                  /*recursive=*/true));
+
+  ASSERT_TRUE(embedded_test_server()->Start());
+  GURL empty_url(embedded_test_server()->GetURL("/empty.html"));
+  ASSERT_TRUE(NavigateToURL(shell(), empty_url));
+
+  // Assume that the WebStorage directory doesn't exist yet. This indicates that
+  // the QuotaDatabase hasn't been bootstrapped, which is a precondition for
+  // this test.
+  base::FilePath web_storage_dir_path =
+      profile_path().Append(storage::kWebStorageDirectory);
+  EXPECT_FALSE(base::PathExists(web_storage_dir_path));
+
+  // Use an API that will cause the Quota subsystem to bootstrap itself. We are
+  // testing that calling this function doesn't hang.
+  EXPECT_EQ(true, EvalJs(shell(), R"(
+        navigator.storage.estimate().then(
+          ()=>{ return true; },
+          ()=>{ return false; });)"));
+
+  // Verify that the WebStorage/QuotaManager directory was created as a result
+  // of the Javascript execution.
+  EXPECT_TRUE(base::PathExists(web_storage_dir_path.AppendASCII(
+      storage::QuotaManagerImpl::kDatabaseName)));
+}
+
+}  // namespace content
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc
index e6905dd..5208549 100644
--- a/content/browser/renderer_host/compositor_impl_android.cc
+++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -1013,6 +1013,8 @@
 
 void CompositorImpl::RequestPresentationTimeForNextFrame(
     PresentationTimeCallback callback) {
+  if (!host_)
+    return;
   host_->RequestPresentationTimeForNextFrame(std::move(callback));
 }
 
diff --git a/content/browser/site_per_process_hit_test_browsertest.cc b/content/browser/site_per_process_hit_test_browsertest.cc
index 6e601420..481ed9b 100644
--- a/content/browser/site_per_process_hit_test_browsertest.cc
+++ b/content/browser/site_per_process_hit_test_browsertest.cc
@@ -6910,13 +6910,7 @@
         use_scale_factor ? gfx::ScaleToEnclosingRect(rect, device_scale_factor_,
                                                      device_scale_factor_)
                          : rect;
-    // TODO(crbug.com/1359528): Add gfx::Transform::MapQuad().
-    gfx::PointF p1 = transform.MapPoint(gfx::PointF(scaled_rect.origin()));
-    gfx::PointF p2 = transform.MapPoint(gfx::PointF(scaled_rect.top_right()));
-    gfx::PointF p3 =
-        transform.MapPoint(gfx::PointF(scaled_rect.bottom_right()));
-    gfx::PointF p4 = transform.MapPoint(gfx::PointF(scaled_rect.bottom_left()));
-    return gfx::QuadF(p1, p2, p3, p4);
+    return transform.MapQuad(gfx::QuadF(gfx::RectF(scaled_rect)));
   }
 
   gfx::QuadF TransformRectToQuadF(
diff --git a/content/browser/system_dns_resolution/system_dns_resolver_browsertest.cc b/content/browser/system_dns_resolution/system_dns_resolver_browsertest.cc
index df58bf3..4b71af17 100644
--- a/content/browser/system_dns_resolution/system_dns_resolver_browsertest.cc
+++ b/content/browser/system_dns_resolution/system_dns_resolver_browsertest.cc
@@ -221,10 +221,19 @@
   EXPECT_EQ(client->result(), net::ERR_NAME_NOT_RESOLVED);
 }
 
+// TODO(crbug.com/1380163): Enable NetworkServiceResolvesOwnHostname on Fuchsia.
+#if BUILDFLAG(IS_FUCHSIA)
+#define MAYBE_NetworkServiceResolvesOwnHostname \
+  DISABLED_NetworkServiceResolvesOwnHostname
+#else
+#define MAYBE_NetworkServiceResolvesOwnHostname \
+  NetworkServiceResolvesOwnHostname
+#endif  // BUILDFLAG(IS_FUCHSIA)
+
 // Check if the system's own host name resolves, which is a slightly different
 // code path from normal resolution.
 IN_PROC_BROWSER_TEST_F(SystemDnsResolverBrowserTest,
-                       NetworkServiceResolvesOwnHostname) {
+                       MAYBE_NetworkServiceResolvesOwnHostname) {
   base::RunLoop run_loop;
   net::AddressList addr_list;
   int os_error, net_error;
diff --git a/content/browser/webauth/virtual_authenticator.h b/content/browser/webauth/virtual_authenticator.h
index 3ea4b56b..da4b43d 100644
--- a/content/browser/webauth/virtual_authenticator.h
+++ b/content/browser/webauth/virtual_authenticator.h
@@ -76,6 +76,20 @@
     is_user_verified_ = is_user_verified;
   }
 
+  // If set, overrides the signature in the authenticator response to be zero.
+  // Defaults to false.
+  void set_bogus_signature(bool is_bogus) {
+    state_->ctap2_invalid_signature = is_bogus;
+  }
+
+  // If set, overrides the UV bit in the flags in the authenticator response to
+  // be zero. Defaults to false.
+  void set_bad_uv_bit(bool is_bad_bit) { state_->unset_uv_bit = is_bad_bit; }
+
+  // If set, overrides the UP bit in the flags in the authenticator response to
+  // be zero. Defaults to false.
+  void set_bad_up_bit(bool is_bad_bit) { state_->unset_up_bit = is_bad_bit; }
+
   bool has_resident_key() const { return has_resident_key_; }
 
   device::FidoTransportProtocol transport() const { return state_->transport; }
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn
index bcc0a45..1b2023ffa 100644
--- a/content/common/BUILD.gn
+++ b/content/common/BUILD.gn
@@ -10,6 +10,7 @@
 import("//mojo/public/tools/bindings/mojom.gni")
 import("//ppapi/buildflags/buildflags.gni")
 import("//sandbox/features.gni")
+import("//testing/libfuzzer/fuzzer_test.gni")
 import("//tools/ipc_fuzzer/ipc_fuzzer.gni")
 import("features.gni")
 if (is_mac) {
@@ -729,3 +730,12 @@
     sources = [ _file ]
   }
 }
+
+fuzzer_test("content_input_actions_parser_fuzzer") {
+  sources = [ "input/actions_parser_fuzzer.cc" ]
+  deps = [
+    "//base",
+    "//content/public/common",
+    "//third_party/abseil-cpp:absl",
+  ]
+}
diff --git a/content/common/input/actions_parser_fuzzer.cc b/content/common/input/actions_parser_fuzzer.cc
new file mode 100644
index 0000000..e2b7f27
--- /dev/null
+++ b/content/common/input/actions_parser_fuzzer.cc
@@ -0,0 +1,24 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <stdint.h>
+
+#include <tuple>
+#include <utility>
+
+#include "base/json/json_reader.h"
+#include "base/strings/string_piece.h"
+#include "base/values.h"
+#include "content/common/input/actions_parser.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  absl::optional<base::Value> value = base::JSONReader::Read(
+      base::StringPiece(reinterpret_cast<const char*>(data), size));
+  if (!value)
+    return 0;
+  content::ActionsParser parser(std::move(*value));
+  std::ignore = parser.Parse();
+  return 0;
+}
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index bf6665dc..1829a86 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -190,7 +190,6 @@
 #include "third_party/blink/public/platform/web_string.h"
 #include "third_party/blink/public/platform/web_url.h"
 #include "third_party/blink/public/platform/web_url_error.h"
-#include "third_party/blink/public/platform/web_url_loader.h"
 #include "third_party/blink/public/platform/web_url_request_extra_data.h"
 #include "third_party/blink/public/platform/web_url_request_util.h"
 #include "third_party/blink/public/platform/web_url_response.h"
@@ -488,9 +487,8 @@
         blink::WebNavigationParams::PrefetchedSignedExchange>>();
 
     for (const auto& exchange : commit_params.prefetched_signed_exchanges) {
-      blink::WebURLResponse web_response;
-      blink::WebURLLoader::PopulateURLResponse(
-          exchange->inner_url, *exchange->inner_response, &web_response,
+      blink::WebURLResponse web_response = blink::WebURLResponse::Create(
+          exchange->inner_url, *exchange->inner_response,
           false /* report_security_info*/, -1 /* request_id */);
       navigation_params->prefetched_signed_exchanges.emplace_back(
           std::make_unique<
diff --git a/content/services/auction_worklet/auction_downloader.cc b/content/services/auction_worklet/auction_downloader.cc
index e1ef4b74..5fc7d12 100644
--- a/content/services/auction_worklet/auction_downloader.cc
+++ b/content/services/auction_worklet/auction_downloader.cc
@@ -293,7 +293,7 @@
         dict.Add("mimeType", response_head.mime_type);
         dict.Add("encodedDataLength", response_head.encoded_data_length);
 
-        // ref.  WebURLLoader::PopulateURLResponse
+        // ref.  WebURLResponse::Create
         dict.Add("fromCache",
                  (!response_head.load_timing.request_start_time.is_null() &&
                   response_head.response_time <
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index 88305fbc..339ccabd 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -1258,7 +1258,6 @@
     "../browser/browsing_data/conditional_cache_deletion_helper_browsertest.cc",
     "../browser/browsing_data/same_site_data_remover_impl_browsertest.cc",
     "../browser/browsing_topics/browsing_topics_browsertest.cc",
-    "../browser/cache_storage/cache_storage_browsertest.cc",
     "../browser/child_process_launcher_browsertest.cc",
     "../browser/child_process_security_policy_browsertest.cc",
     "../browser/compute_pressure/compute_pressure_origin_trial_browsertest.cc",
@@ -1375,6 +1374,7 @@
     "../browser/power_monitor_browsertest.cc",
     "../browser/preloading/prerender/prerender_browsertest.cc",
     "../browser/process_internals/process_internals_browsertest.cc",
+    "../browser/quota/quota_browsertest.cc",
     "../browser/quota/quota_change_browsertest.cc",
     "../browser/quota/quota_internals_browsertest.cc",
     "../browser/renderer_host/ancestor_throttle_browsertest.cc",
diff --git a/content/test/attribution_simulator_impl.cc b/content/test/attribution_simulator_impl.cc
index d766604..6dbf81b 100644
--- a/content/test/attribution_simulator_impl.cc
+++ b/content/test/attribution_simulator_impl.cc
@@ -372,6 +372,7 @@
     std::ostringstream reason;
     switch (result) {
       case StorableSource::Result::kSuccess:
+      case StorableSource::Result::kSuccessNoised:
         return;
       case StorableSource::Result::kInternalError:
       case StorableSource::Result::kInsufficientSourceCapacity:
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
index b6566bb..75b15824 100644
--- a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
@@ -437,6 +437,7 @@
 crbug.com/1086194 [ mac nvidia-0xfe9 ] conformance/textures/canvas_sub_rectangle/* [ RetryOnFailure ]
 
 crbug.com/1338004 [ mac nvidia-0xfe9 passthrough ] deqp/functional/gles3/multisample/fbo_4_samples.html [ RetryOnFailure ]
+crbug.com/1338004 [ mac nvidia-0xfe9 passthrough ] deqp/functional/gles3/multisample/fbo_max_samples.html [ RetryOnFailure ]
 
 # Mac AMD Retina
 # AMD Radeon HD 8870M (1002:6821)
diff --git a/docs/fuchsia/gpu_testing.md b/docs/fuchsia/gpu_testing.md
index bed87355..698015d 100644
--- a/docs/fuchsia/gpu_testing.md
+++ b/docs/fuchsia/gpu_testing.md
@@ -23,11 +23,21 @@
 
 ## Run on an physical device
 
+If ffx has already been set up to use the target device by default,
+or if there is only one discoverable device on the host:
+
 ```bash
 $ content/test/gpu/run_gpu_integration_test_fuchsia.py gpu_process
 --browser=web-engine-shell --out-dir=/path/to/outdir -d
 ```
 
+Otherwise, specify the id of the target device:
+
+```bash
+$ content/test/gpu/run_gpu_integration_test_fuchsia.py gpu_process
+--browser=web-engine-shell --out-dir=/path/to/outdir --target-id=[TARGET_ID]
+```
+
 ## Run on a device that needs packages built from Fuchsia source
 
 ```bash
@@ -43,7 +53,7 @@
 
 ```bash
 $ content/test/gpu/run_gpu_integration_test_fuchsia.py gpu_process
---browser=web-engine-shell --out-dir=/path/to/outdir -d --target-id=[::1]:8022
+--browser=web-engine-shell --out-dir=/path/to/outdir --target-id=[::1]:8022
 ```
 
 Note the this requires a remote tunnel to have been set up first.
diff --git a/docs/fuchsia/test_scripts.md b/docs/fuchsia/test_scripts.md
index 2b278b0..0c2985fa 100644
--- a/docs/fuchsia/test_scripts.md
+++ b/docs/fuchsia/test_scripts.md
@@ -4,7 +4,7 @@
 
 A new version of scripts for testing on Fuchsia is being developed
 [here](../../build/fuchsia/test/) and the plan is to migrate all use cases
-to these scripts by the end of Q322. The new scripts currently support:
+to these scripts by the end of Q422. The new scripts currently support:
 
 ## Run CFv2 gtest binaries on Fuchsia
 
@@ -44,7 +44,7 @@
 adding the command line arguments indicated above:
 
 ```bash
-$ ./build/fuchsia/test/run_test.py [TEST_BINARY] -C [OUTPUT_DIR] -d \
+$ ./build/fuchsia/test/run_test.py [TEST_BINARY] -C [OUTPUT_DIR] \
   --target-id [EMULATOR_NAME]
 ```
 
diff --git a/extensions/browser/BUILD.gn b/extensions/browser/BUILD.gn
index a13f8dc..652b505 100644
--- a/extensions/browser/BUILD.gn
+++ b/extensions/browser/BUILD.gn
@@ -1012,3 +1012,12 @@
     "//base",
   ]
 }
+
+fuzzer_test("extension_web_request_form_data_parser_fuzzer") {
+  sources = [ "api/web_request/form_data_parser_fuzzer.cc" ]
+  deps = [
+    ":browser",
+    "//base",
+    "//net",
+  ]
+}
diff --git a/extensions/browser/api/app_window/app_window_apitest.cc b/extensions/browser/api/app_window/app_window_apitest.cc
index df51933..d51e23e 100644
--- a/extensions/browser/api/app_window/app_window_apitest.cc
+++ b/extensions/browser/api/app_window/app_window_apitest.cc
@@ -131,7 +131,7 @@
 }
 
 // Fails on Ozone/X11.  https://crbug.com/1109112
-#if defined(USE_OZONE)
+#if BUILDFLAG(IS_OZONE)
 #define MAYBE_AlphaEnabledHasPermissions DISABLED_AlphaEnabledHasPermissions
 #else
 #define MAYBE_AlphaEnabledHasPermissions AlphaEnabledHasPermissions
diff --git a/extensions/browser/api/automation_internal/automation_internal_api.cc b/extensions/browser/api/automation_internal/automation_internal_api.cc
index 8c249d0..41ec586 100644
--- a/extensions/browser/api/automation_internal/automation_internal_api.cc
+++ b/extensions/browser/api/automation_internal/automation_internal_api.cc
@@ -316,7 +316,6 @@
   }
 
   AutomationWebContentsObserver::CreateForWebContents(contents);
-  contents->EnableWebContentsOnlyAccessibilityMode();
 
   ui::AXTreeID ax_tree_id = rfh->GetAXTreeID();
 
diff --git a/extensions/browser/api/dns/dns_apitest.cc b/extensions/browser/api/dns/dns_apitest.cc
index 5d76eca..8f8ca6d6 100644
--- a/extensions/browser/api/dns/dns_apitest.cc
+++ b/extensions/browser/api/dns/dns_apitest.cc
@@ -63,7 +63,7 @@
   resolve_function->set_extension(empty_extension.get());
   resolve_function->set_has_callback(true);
 
-  std::unique_ptr<base::Value> result(RunFunctionAndReturnSingleResult(
+  absl::optional<base::Value> result(RunFunctionAndReturnSingleResult(
       resolve_function.get(), "[\"127.0.0.1\"]", browser_context()));
   const base::Value::Dict& dict = result->GetDict();
 
@@ -85,7 +85,7 @@
   resolve_function->set_has_callback(true);
 
   std::string function_arguments = base::StringPrintf(R"(["%s"])", kHostname);
-  std::unique_ptr<base::Value> result(RunFunctionAndReturnSingleResult(
+  absl::optional<base::Value> result(RunFunctionAndReturnSingleResult(
       resolve_function.get(), function_arguments, browser_context()));
   const base::Value::Dict& dict = result->GetDict();
 
diff --git a/extensions/browser/api/socket/socket_apitest.cc b/extensions/browser/api/socket/socket_apitest.cc
index 78a5c83..ce37c38 100644
--- a/extensions/browser/api/socket/socket_apitest.cc
+++ b/extensions/browser/api/socket/socket_apitest.cc
@@ -23,7 +23,7 @@
   socket_create_function->set_extension(empty_extension.get());
   socket_create_function->set_has_callback(true);
 
-  std::unique_ptr<base::Value> result(RunFunctionAndReturnSingleResult(
+  absl::optional<base::Value> result(RunFunctionAndReturnSingleResult(
       socket_create_function.get(), "[\"udp\"]", browser_context()));
   const base::Value::Dict& value = result->GetDict();
   absl::optional<int> socket_id = value.FindInt("socketId");
@@ -40,7 +40,7 @@
   socket_create_function->set_extension(empty_extension.get());
   socket_create_function->set_has_callback(true);
 
-  std::unique_ptr<base::Value> result(RunFunctionAndReturnSingleResult(
+  absl::optional<base::Value> result(RunFunctionAndReturnSingleResult(
       socket_create_function.get(), "[\"tcp\"]", browser_context()));
   const base::Value::Dict& value = result->GetDict();
   absl::optional<int> socket_id = value.FindInt("socketId");
@@ -57,7 +57,7 @@
   socket_function->set_extension(empty_extension.get());
   socket_function->set_has_callback(true);
 
-  std::unique_ptr<base::Value> result(RunFunctionAndReturnSingleResult(
+  absl::optional<base::Value> result(RunFunctionAndReturnSingleResult(
       socket_function.get(), "[]", browser_context()));
 
   // If we're invoking socket tests, all we can confirm is that we have at
diff --git a/extensions/browser/api/sockets_tcp/sockets_tcp_apitest.cc b/extensions/browser/api/sockets_tcp/sockets_tcp_apitest.cc
index 86652fc1..fa6ed5b 100644
--- a/extensions/browser/api/sockets_tcp/sockets_tcp_apitest.cc
+++ b/extensions/browser/api/sockets_tcp/sockets_tcp_apitest.cc
@@ -64,7 +64,7 @@
   socket_create_function->set_extension(empty_extension.get());
   socket_create_function->set_has_callback(true);
 
-  std::unique_ptr<base::Value> result(
+  absl::optional<base::Value> result(
       api_test_utils::RunFunctionAndReturnSingleResult(
           socket_create_function.get(), "[]", browser_context()));
   ASSERT_TRUE(result);
diff --git a/extensions/browser/api/sockets_tcp_server/sockets_tcp_server_apitest.cc b/extensions/browser/api/sockets_tcp_server/sockets_tcp_server_apitest.cc
index 24f6ab64..27efc3d 100644
--- a/extensions/browser/api/sockets_tcp_server/sockets_tcp_server_apitest.cc
+++ b/extensions/browser/api/sockets_tcp_server/sockets_tcp_server_apitest.cc
@@ -30,7 +30,7 @@
   socket_create_function->set_extension(empty_extension.get());
   socket_create_function->set_has_callback(true);
 
-  std::unique_ptr<base::Value> result(
+  absl::optional<base::Value> result(
       api_test_utils::RunFunctionAndReturnSingleResult(
           socket_create_function.get(), "[]", browser_context()));
   ASSERT_TRUE(result);
diff --git a/extensions/browser/api/sockets_udp/sockets_udp_apitest.cc b/extensions/browser/api/sockets_udp/sockets_udp_apitest.cc
index 62dde5dd..1809591 100644
--- a/extensions/browser/api/sockets_udp/sockets_udp_apitest.cc
+++ b/extensions/browser/api/sockets_udp/sockets_udp_apitest.cc
@@ -38,7 +38,7 @@
   socket_create_function->set_extension(empty_extension.get());
   socket_create_function->set_has_callback(true);
 
-  std::unique_ptr<base::Value> result(
+  absl::optional<base::Value> result(
       api_test_utils::RunFunctionAndReturnSingleResult(
           socket_create_function.get(), "[]", browser_context()));
 
diff --git a/extensions/browser/api/system_display/system_display_apitest.cc b/extensions/browser/api/system_display/system_display_apitest.cc
index 03986af..d3fd820 100644
--- a/extensions/browser/api/system_display/system_display_apitest.cc
+++ b/extensions/browser/api/system_display/system_display_apitest.cc
@@ -251,7 +251,7 @@
 
   provider_->SetTouchCalibrationWillSucceed(true);
 
-  std::unique_ptr<base::Value> result(
+  absl::optional<base::Value> result(
       api_test_utils::RunFunctionAndReturnSingleResult(
           show_native_calibration.get(), "[\"" + id + "\"]",
           browser_context()));
diff --git a/extensions/browser/api/system_network/system_network_api_unittest.cc b/extensions/browser/api/system_network/system_network_api_unittest.cc
index 24fc595..a2c6058 100644
--- a/extensions/browser/api/system_network/system_network_api_unittest.cc
+++ b/extensions/browser/api/system_network/system_network_api_unittest.cc
@@ -35,7 +35,7 @@
   socket_function->set_extension(empty_extension.get());
   socket_function->set_has_callback(true);
 
-  std::unique_ptr<base::Value> result(RunFunctionAndReturnSingleResult(
+  absl::optional<base::Value> result(RunFunctionAndReturnSingleResult(
       socket_function.get(), "[]", browser_context()));
   ASSERT_TRUE(result->is_list());
 
diff --git a/extensions/browser/api/web_request/form_data_parser_fuzzer.cc b/extensions/browser/api/web_request/form_data_parser_fuzzer.cc
new file mode 100644
index 0000000..5cfbe0d5
--- /dev/null
+++ b/extensions/browser/api/web_request/form_data_parser_fuzzer.cc
@@ -0,0 +1,96 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <stdint.h>
+
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <fuzzer/FuzzedDataProvider.h>
+
+#include "base/logging.h"
+#include "base/strings/string_piece.h"
+#include "extensions/browser/api/web_request/form_data_parser.h"
+#include "net/http/http_request_headers.h"
+#include "net/http/http_util.h"
+
+using extensions::FormDataParser;
+
+namespace {
+
+// Does initialization and holds state that's shared across all runs.
+class Environment {
+ public:
+  Environment() {
+    // Disable noisy logging.
+    logging::SetMinLogLevel(logging::LOG_FATAL);
+  }
+};
+
+net::HttpRequestHeaders GenerateHttpRequestHeaders(
+    FuzzedDataProvider& provider) {
+  net::HttpRequestHeaders headers;
+  for (;;) {
+    const std::string key = provider.ConsumeRandomLengthString();
+    const std::string value = provider.ConsumeRandomLengthString();
+    if (key.empty() || !net::HttpUtil::IsValidHeaderName(key) ||
+        !net::HttpUtil::IsValidHeaderValue(value)) {
+      break;
+    }
+    headers.SetHeader(key, value);
+  }
+  return headers;
+}
+
+}  // namespace
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  static Environment env;
+  FuzzedDataProvider provider(data, size);
+
+  // Create parser sources. Per API contract, they must outlive the parser.
+  std::vector<std::string> sources;
+  for (;;) {
+    std::string source = provider.ConsumeRandomLengthString();
+    if (source.empty())
+      break;
+    sources.push_back(std::move(source));
+  }
+
+  // Create a parser with random initialization parameters.
+  std::unique_ptr<FormDataParser> parser;
+  switch (provider.ConsumeIntegralInRange<int>(0, 2)) {
+    case 0: {
+      parser = FormDataParser::Create(GenerateHttpRequestHeaders(provider));
+      break;
+    }
+    case 1: {
+      parser = FormDataParser::CreateFromContentTypeHeader(
+          /*content_type_header=*/nullptr);
+      break;
+    }
+    case 2: {
+      std::string content_type_header = provider.ConsumeRandomLengthString();
+      parser =
+          FormDataParser::CreateFromContentTypeHeader(&content_type_header);
+      break;
+    }
+  }
+  if (!parser)
+    return 0;
+
+  // Run the parser.
+  for (const auto& source : sources) {
+    parser->SetSource(source);
+
+    FormDataParser::Result result;
+    while (parser->GetNextNameValue(&result)) {
+      // Discard the result - we can't verify anything in it here.
+    }
+  }
+
+  return 0;
+}
diff --git a/extensions/browser/api_test_utils.cc b/extensions/browser/api_test_utils.cc
index f1592d0..e40fd7cf 100644
--- a/extensions/browser/api_test_utils.cc
+++ b/extensions/browser/api_test_utils.cc
@@ -114,7 +114,7 @@
   return value->Clone();
 }
 
-std::unique_ptr<base::Value> RunFunctionWithDelegateAndReturnSingleResult(
+absl::optional<base::Value> RunFunctionWithDelegateAndReturnSingleResult(
     scoped_refptr<ExtensionFunction> function,
     const std::string& args,
     std::unique_ptr<extensions::ExtensionFunctionDispatcher> dispatcher,
@@ -124,7 +124,8 @@
       << "Could not parse extension function arguments: " << args;
 
   return RunFunctionWithDelegateAndReturnSingleResult(
-      function, std::move(parsed_args), std::move(dispatcher), flags);
+      function, std::move(*parsed_args).TakeList(), std::move(dispatcher),
+      flags);
 }
 
 absl::optional<base::Value> RunFunctionWithDelegateAndReturnSingleResult(
@@ -156,14 +157,14 @@
   return nullptr;
 }
 
-std::unique_ptr<base::Value> RunFunctionAndReturnSingleResult(
+absl::optional<base::Value> RunFunctionAndReturnSingleResult(
     ExtensionFunction* function,
     const std::string& args,
     content::BrowserContext* context) {
   return RunFunctionAndReturnSingleResult(function, args, context, NONE);
 }
 
-std::unique_ptr<base::Value> RunFunctionAndReturnSingleResult(
+absl::optional<base::Value> RunFunctionAndReturnSingleResult(
     ExtensionFunction* function,
     const std::string& args,
     content::BrowserContext* context,
diff --git a/extensions/browser/api_test_utils.h b/extensions/browser/api_test_utils.h
index 9cada3d..cc8cba37 100644
--- a/extensions/browser/api_test_utils.h
+++ b/extensions/browser/api_test_utils.h
@@ -75,7 +75,7 @@
 // Run |function| with |args| and return the result. Adds an error to the
 // current test if |function| returns an error. Takes ownership of
 // |function|. The caller takes ownership of the result.
-std::unique_ptr<base::Value> RunFunctionWithDelegateAndReturnSingleResult(
+absl::optional<base::Value> RunFunctionWithDelegateAndReturnSingleResult(
     scoped_refptr<ExtensionFunction> function,
     const std::string& args,
     std::unique_ptr<ExtensionFunctionDispatcher> dispatcher,
@@ -85,20 +85,14 @@
     base::Value::List args,
     std::unique_ptr<ExtensionFunctionDispatcher> dispatcher,
     RunFunctionFlags flags);
-// DEPRECATED. Use the version above.
-std::unique_ptr<base::Value> RunFunctionWithDelegateAndReturnSingleResult(
-    scoped_refptr<ExtensionFunction> function,
-    std::unique_ptr<base::ListValue> args,
-    std::unique_ptr<ExtensionFunctionDispatcher> dispatcher,
-    RunFunctionFlags flags);
 
 // RunFunctionWithDelegateAndReturnSingleResult, except with a NULL
 // implementation of the Delegate.
-std::unique_ptr<base::Value> RunFunctionAndReturnSingleResult(
+absl::optional<base::Value> RunFunctionAndReturnSingleResult(
     ExtensionFunction* function,
     const std::string& args,
     content::BrowserContext* context);
-std::unique_ptr<base::Value> RunFunctionAndReturnSingleResult(
+absl::optional<base::Value> RunFunctionAndReturnSingleResult(
     ExtensionFunction* function,
     const std::string& args,
     content::BrowserContext* context,
diff --git a/extensions/browser/api_unittest.cc b/extensions/browser/api_unittest.cc
index 1245a2c..9b80e10 100644
--- a/extensions/browser/api_unittest.cc
+++ b/extensions/browser/api_unittest.cc
@@ -63,8 +63,11 @@
   function->set_extension(extension());
   if (contents_)
     function->SetRenderFrameHost(contents_->GetPrimaryMainFrame());
-  return std::unique_ptr<base::Value>(utils::RunFunctionAndReturnSingleResult(
-      function, args, browser_context()));
+  absl::optional<base::Value> result = utils::RunFunctionAndReturnSingleResult(
+      function, args, browser_context());
+  if (result)
+    return std::make_unique<base::Value>(std::move(*result));
+  return nullptr;
 }
 
 std::unique_ptr<base::DictionaryValue>
diff --git a/extensions/browser/api_unittest.h b/extensions/browser/api_unittest.h
index b1e2ecb..183fa9a 100644
--- a/extensions/browser/api_unittest.h
+++ b/extensions/browser/api_unittest.h
@@ -58,18 +58,21 @@
   // See also the RunFunction* methods in extension_function_test_utils.h.
 
   // Return the function result as a base::Value.
+  // TODO(crbug.com/1187001): Return absl::optional<base::Value> instead.
   std::unique_ptr<base::Value> RunFunctionAndReturnValue(
       ExtensionFunction* function,
       const std::string& args);
 
   // Return the function result as a base::DictionaryValue, or NULL.
   // This will EXPECT-fail if the result is not a DictionaryValue.
+  // TODO(crbug.com/1187061): Return absl::optional<base::Value> instead.
   std::unique_ptr<base::DictionaryValue> RunFunctionAndReturnDictionary(
       ExtensionFunction* function,
       const std::string& args);
 
   // Return the function result as a base::Value, or NULL.
   // This will EXPECT-fail if the result Value is not a list.
+  // TODO(crbug.com/1187001): Return absl::optional<base::Value> instead.
   std::unique_ptr<base::Value> RunFunctionAndReturnList(
       ExtensionFunction* function,
       const std::string& args);
diff --git a/extensions/browser/lazy_context_id.h b/extensions/browser/lazy_context_id.h
index 27b3b3e2..f1297e3 100644
--- a/extensions/browser/lazy_context_id.h
+++ b/extensions/browser/lazy_context_id.h
@@ -78,7 +78,8 @@
 
  private:
   Type type_;
-  raw_ptr<content::BrowserContext, DanglingUntriaged> context_;
+  raw_ptr<content::BrowserContext, DanglingUntriagedDegradeToNoOpWhenMTE>
+      context_;
   ExtensionId extension_id_;
   GURL service_worker_scope_;
 };
diff --git a/gpu/ipc/common/gpu_memory_buffer_impl_io_surface.cc b/gpu/ipc/common/gpu_memory_buffer_impl_io_surface.cc
index 75dff75..c095552 100644
--- a/gpu/ipc/common/gpu_memory_buffer_impl_io_surface.cc
+++ b/gpu/ipc/common/gpu_memory_buffer_impl_io_surface.cc
@@ -23,18 +23,14 @@
 
 uint32_t LockFlags(gfx::BufferUsage usage) {
   switch (usage) {
-    case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE:
-    case gfx::BufferUsage::VEA_READ_CAMERA_AND_CPU_READ_WRITE:
-      // The AvoidSync call has the property that it will not preserve the
-      // previous contents of the buffer if those contents were written by a
-      // GPU.
-      return kIOSurfaceLockAvoidSync;
     case gfx::BufferUsage::SCANOUT_VEA_CPU_READ:
       // This constant is used for buffers used by video capture. On macOS,
       // these buffers are only ever written to in the capture process,
       // directly as IOSurfaces.
       // Once they are sent to other processes, no CPU writes are performed.
       return kIOSurfaceLockReadOnly;
+    case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE:
+    case gfx::BufferUsage::VEA_READ_CAMERA_AND_CPU_READ_WRITE:
     case gfx::BufferUsage::GPU_READ:
     case gfx::BufferUsage::SCANOUT:
     case gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE:
@@ -119,7 +115,7 @@
     return true;
 
   IOReturn status = IOSurfaceLock(io_surface_, lock_flags_, nullptr);
-  DCHECK_NE(status, kIOReturnCannotLock);
+  DCHECK_NE(status, kIOReturnCannotLock) << " lock_flags_: " << lock_flags_;
   return true;
 }
 
diff --git a/infra/config/generated/builders/ci/Linux ASan LSan Low Symbols FYI Builder/properties.json b/infra/config/generated/builders/ci/Linux ASan LSan Low Symbols FYI Builder/properties.json
deleted file mode 100644
index fa1b955..0000000
--- a/infra/config/generated/builders/ci/Linux ASan LSan Low Symbols FYI Builder/properties.json
+++ /dev/null
@@ -1,89 +0,0 @@
-{
-  "$build/chromium_tests_builder_config": {
-    "builder_config": {
-      "builder_db": {
-        "entries": [
-          {
-            "builder_id": {
-              "bucket": "ci",
-              "builder": "Linux ASan LSan Low Symbols FYI Builder",
-              "project": "chromium"
-            },
-            "builder_spec": {
-              "builder_group": "chromium.memory",
-              "execution_mode": "COMPILE_AND_TEST",
-              "legacy_chromium_config": {
-                "apply_configs": [
-                  "lsan",
-                  "mb"
-                ],
-                "build_config": "Release",
-                "config": "chromium_asan",
-                "target_bits": 64
-              },
-              "legacy_gclient_config": {
-                "config": "chromium"
-              }
-            }
-          },
-          {
-            "builder_id": {
-              "bucket": "ci",
-              "builder": "Linux ASan LSan Low Symbols FYI Tests (1)",
-              "project": "chromium"
-            },
-            "builder_spec": {
-              "builder_group": "chromium.memory",
-              "execution_mode": "TEST",
-              "legacy_chromium_config": {
-                "apply_configs": [
-                  "lsan",
-                  "mb"
-                ],
-                "build_config": "Release",
-                "config": "chromium_asan",
-                "target_bits": 64
-              },
-              "legacy_gclient_config": {
-                "config": "chromium"
-              },
-              "parent": {
-                "bucket": "ci",
-                "builder": "Linux ASan LSan Low Symbols FYI Builder",
-                "project": "chromium"
-              }
-            }
-          }
-        ]
-      },
-      "builder_ids": [
-        {
-          "bucket": "ci",
-          "builder": "Linux ASan LSan Low Symbols FYI Builder",
-          "project": "chromium"
-        }
-      ],
-      "builder_ids_in_scope_for_testing": [
-        {
-          "bucket": "ci",
-          "builder": "Linux ASan LSan Low Symbols FYI Tests (1)",
-          "project": "chromium"
-        }
-      ]
-    }
-  },
-  "$build/reclient": {
-    "instance": "rbe-chromium-trusted",
-    "jobs": 500,
-    "metrics_project": "chromium-reclient-metrics"
-  },
-  "$recipe_engine/resultdb/test_presentation": {
-    "column_keys": [],
-    "grouping_keys": [
-      "status",
-      "v.test_suite"
-    ]
-  },
-  "builder_group": "chromium.memory",
-  "recipe": "chromium"
-}
\ No newline at end of file
diff --git "a/infra/config/generated/builders/ci/Linux ASan LSan Low Symbols FYI Tests \0501\051/properties.json" "b/infra/config/generated/builders/ci/Linux ASan LSan Low Symbols FYI Tests \0501\051/properties.json"
deleted file mode 100644
index 7c70482..0000000
--- "a/infra/config/generated/builders/ci/Linux ASan LSan Low Symbols FYI Tests \0501\051/properties.json"
+++ /dev/null
@@ -1,77 +0,0 @@
-{
-  "$build/chromium_tests_builder_config": {
-    "builder_config": {
-      "builder_db": {
-        "entries": [
-          {
-            "builder_id": {
-              "bucket": "ci",
-              "builder": "Linux ASan LSan Low Symbols FYI Builder",
-              "project": "chromium"
-            },
-            "builder_spec": {
-              "builder_group": "chromium.memory",
-              "execution_mode": "COMPILE_AND_TEST",
-              "legacy_chromium_config": {
-                "apply_configs": [
-                  "lsan",
-                  "mb"
-                ],
-                "build_config": "Release",
-                "config": "chromium_asan",
-                "target_bits": 64
-              },
-              "legacy_gclient_config": {
-                "config": "chromium"
-              }
-            }
-          },
-          {
-            "builder_id": {
-              "bucket": "ci",
-              "builder": "Linux ASan LSan Low Symbols FYI Tests (1)",
-              "project": "chromium"
-            },
-            "builder_spec": {
-              "builder_group": "chromium.memory",
-              "execution_mode": "TEST",
-              "legacy_chromium_config": {
-                "apply_configs": [
-                  "lsan",
-                  "mb"
-                ],
-                "build_config": "Release",
-                "config": "chromium_asan",
-                "target_bits": 64
-              },
-              "legacy_gclient_config": {
-                "config": "chromium"
-              },
-              "parent": {
-                "bucket": "ci",
-                "builder": "Linux ASan LSan Low Symbols FYI Builder",
-                "project": "chromium"
-              }
-            }
-          }
-        ]
-      },
-      "builder_ids": [
-        {
-          "bucket": "ci",
-          "builder": "Linux ASan LSan Low Symbols FYI Tests (1)",
-          "project": "chromium"
-        }
-      ]
-    }
-  },
-  "$recipe_engine/resultdb/test_presentation": {
-    "column_keys": [],
-    "grouping_keys": [
-      "status",
-      "v.test_suite"
-    ]
-  },
-  "builder_group": "chromium.memory",
-  "recipe": "chromium"
-}
\ No newline at end of file
diff --git a/infra/config/generated/cq-builders.md b/infra/config/generated/cq-builders.md
index 6bf5a405..df304825 100644
--- a/infra/config/generated/cq-builders.md
+++ b/infra/config/generated/cq-builders.md
@@ -189,13 +189,6 @@
   * [`//content/gpu/.+`](https://cs.chromium.org/chromium/src/content/gpu/)
   * [`//media/.+`](https://cs.chromium.org/chromium/src/media/)
 
-* [chromeos-kevin-rel](https://ci.chromium.org/p/chromium/builders/try/chromeos-kevin-rel) ([definition](https://cs.chromium.org/search?q=+file:/try/.*\.star$+""chromeos-kevin-rel"")) ([matching builders](https://cs.chromium.org/search?q=+file:trybots.py+""chromeos-kevin-rel""))
-
-  Location filters:
-  * [`//build/chromeos/.+`](https://cs.chromium.org/chromium/src/build/chromeos/)
-  * [`//build/config/chromeos/.*`](https://cs.chromium.org/search?q=+file:build/config/chromeos/.*)
-  * [`//chromeos/CHROMEOS_LKGM`](https://cs.chromium.org/chromium/src/chromeos/CHROMEOS_LKGM)
-
 * [dawn-android-arm-deps-rel](https://ci.chromium.org/p/chromium/builders/try/dawn-android-arm-deps-rel) ([definition](https://cs.chromium.org/search?q=+file:/try/.*\.star$+""dawn-android-arm-deps-rel"")) ([matching builders](https://cs.chromium.org/search?q=+file:trybots.py+""dawn-android-arm-deps-rel""))
 
   Location filters:
diff --git a/infra/config/generated/cq-usage/full.cfg b/infra/config/generated/cq-usage/full.cfg
index 28cd695..27f8dcdf 100644
--- a/infra/config/generated/cq-usage/full.cfg
+++ b/infra/config/generated/cq-usage/full.cfg
@@ -671,41 +671,6 @@
         }
       }
       builders {
-        name: "chromium/try/chromeos-kevin-rel"
-        location_filters {
-          gerrit_host_regexp: ".*"
-          gerrit_project_regexp: ".*"
-          path_regexp: "build/chromeos/.+"
-        }
-        location_filters {
-          gerrit_host_regexp: ".*"
-          gerrit_project_regexp: ".*"
-          path_regexp: "build/config/chromeos/.*"
-        }
-        location_filters {
-          gerrit_host_regexp: ".*"
-          gerrit_project_regexp: ".*"
-          path_regexp: "chromeos/CHROMEOS_LKGM"
-        }
-        location_filters {
-          gerrit_host_regexp: ".*"
-          gerrit_project_regexp: ".*"
-          path_regexp: "docs/.+"
-          exclude: true
-        }
-        location_filters {
-          gerrit_host_regexp: ".*"
-          gerrit_project_regexp: ".*"
-          path_regexp: "infra/config/.+"
-          exclude: true
-        }
-        location_filters {
-          gerrit_host_regexp: ".*"
-          gerrit_project_regexp: ".*"
-          path_regexp: "infra/config/generated/builders/try/chromeos-kevin-rel/.+"
-        }
-      }
-      builders {
         name: "chromium/try/chromium_presubmit"
         disable_reuse: true
       }
diff --git a/infra/config/generated/luci/commit-queue.cfg b/infra/config/generated/luci/commit-queue.cfg
index c856372..8c7d341 100644
--- a/infra/config/generated/luci/commit-queue.cfg
+++ b/infra/config/generated/luci/commit-queue.cfg
@@ -1251,38 +1251,7 @@
       }
       builders {
         name: "chromium/try/chromeos-kevin-rel"
-        location_filters {
-          gerrit_host_regexp: ".*"
-          gerrit_project_regexp: ".*"
-          path_regexp: "build/chromeos/.+"
-        }
-        location_filters {
-          gerrit_host_regexp: ".*"
-          gerrit_project_regexp: ".*"
-          path_regexp: "build/config/chromeos/.*"
-        }
-        location_filters {
-          gerrit_host_regexp: ".*"
-          gerrit_project_regexp: ".*"
-          path_regexp: "chromeos/CHROMEOS_LKGM"
-        }
-        location_filters {
-          gerrit_host_regexp: ".*"
-          gerrit_project_regexp: ".*"
-          path_regexp: "docs/.+"
-          exclude: true
-        }
-        location_filters {
-          gerrit_host_regexp: ".*"
-          gerrit_project_regexp: ".*"
-          path_regexp: "infra/config/.+"
-          exclude: true
-        }
-        location_filters {
-          gerrit_host_regexp: ".*"
-          gerrit_project_regexp: ".*"
-          path_regexp: "infra/config/generated/builders/try/chromeos-kevin-rel/.+"
-        }
+        includable_only: true
       }
       builders {
         name: "chromium/try/chromeos-octopus-rel"
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg
index 4b6e4a61..9ab4e4289 100644
--- a/infra/config/generated/luci/cr-buildbucket.cfg
+++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -11857,182 +11857,6 @@
       }
     }
     builders {
-      name: "Linux ASan LSan Low Symbols FYI Builder"
-      swarming_host: "chromium-swarm.appspot.com"
-      dimensions: "builderless:1"
-      dimensions: "cores:8"
-      dimensions: "cpu:x86-64"
-      dimensions: "free_space:standard"
-      dimensions: "os:Ubuntu-18.04"
-      dimensions: "pool:luci.chromium.ci"
-      dimensions: "ssd:1"
-      exe {
-        cipd_package: "infra/chromium/bootstrapper/${platform}"
-        cipd_version: "latest"
-        cmd: "bootstrapper"
-      }
-      properties:
-        '{'
-        '  "$bootstrap/exe": {'
-        '    "exe": {'
-        '      "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",'
-        '      "cipd_version": "refs/heads/main",'
-        '      "cmd": ['
-        '        "luciexe"'
-        '      ]'
-        '    }'
-        '  },'
-        '  "$bootstrap/properties": {'
-        '    "properties_file": "infra/config/generated/builders/ci/Linux ASan LSan Low Symbols FYI Builder/properties.json",'
-        '    "top_level_project": {'
-        '      "ref": "refs/heads/main",'
-        '      "repo": {'
-        '        "host": "chromium.googlesource.com",'
-        '        "project": "chromium/src"'
-        '      }'
-        '    }'
-        '  },'
-        '  "builder_group": "chromium.memory",'
-        '  "led_builder_is_bootstrapped": true,'
-        '  "recipe": "chromium"'
-        '}'
-      execution_timeout_secs: 10800
-      build_numbers: YES
-      service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
-      experiments {
-        key: "chromium_swarming.expose_merge_script_failures"
-        value: 100
-      }
-      experiments {
-        key: "luci.buildbucket.omit_python2"
-        value: 0
-      }
-      experiments {
-        key: "luci.recipes.use_python3"
-        value: 100
-      }
-      resultdb {
-        enable: true
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "ci_test_results"
-          test_results {}
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "gpu_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
-            }
-          }
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "blink_web_tests_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*blink_wpt_tests/.+)"
-            }
-          }
-        }
-        history_options {
-          use_invocation_timestamp: true
-        }
-      }
-    }
-    builders {
-      name: "Linux ASan LSan Low Symbols FYI Tests (1)"
-      swarming_host: "chromium-swarm.appspot.com"
-      dimensions: "builderless:1"
-      dimensions: "cores:8"
-      dimensions: "cpu:x86-64"
-      dimensions: "free_space:standard"
-      dimensions: "os:Ubuntu-18.04"
-      dimensions: "pool:luci.chromium.ci"
-      dimensions: "ssd:0"
-      exe {
-        cipd_package: "infra/chromium/bootstrapper/${platform}"
-        cipd_version: "latest"
-        cmd: "bootstrapper"
-      }
-      properties:
-        '{'
-        '  "$bootstrap/exe": {'
-        '    "exe": {'
-        '      "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",'
-        '      "cipd_version": "refs/heads/main",'
-        '      "cmd": ['
-        '        "luciexe"'
-        '      ]'
-        '    }'
-        '  },'
-        '  "$bootstrap/properties": {'
-        '    "properties_file": "infra/config/generated/builders/ci/Linux ASan LSan Low Symbols FYI Tests (1)/properties.json",'
-        '    "top_level_project": {'
-        '      "ref": "refs/heads/main",'
-        '      "repo": {'
-        '        "host": "chromium.googlesource.com",'
-        '        "project": "chromium/src"'
-        '      }'
-        '    }'
-        '  },'
-        '  "builder_group": "chromium.memory",'
-        '  "led_builder_is_bootstrapped": true,'
-        '  "recipe": "chromium"'
-        '}'
-      execution_timeout_secs: 10800
-      build_numbers: YES
-      service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
-      experiments {
-        key: "chromium_swarming.expose_merge_script_failures"
-        value: 100
-      }
-      experiments {
-        key: "luci.buildbucket.omit_python2"
-        value: 0
-      }
-      experiments {
-        key: "luci.recipes.use_python3"
-        value: 100
-      }
-      resultdb {
-        enable: true
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "ci_test_results"
-          test_results {}
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "gpu_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
-            }
-          }
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "blink_web_tests_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*blink_wpt_tests/.+)"
-            }
-          }
-        }
-        history_options {
-          use_invocation_timestamp: true
-        }
-      }
-    }
-    builders {
       name: "Linux ASan LSan Tests (1)"
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
@@ -13079,7 +12903,7 @@
       }
       experiments {
         key: "luci.buildbucket.omit_python2"
-        value: 0
+        value: 100
       }
       experiments {
         key: "luci.recipes.use_python3"
@@ -31006,7 +30830,7 @@
       }
       experiments {
         key: "luci.buildbucket.omit_python2"
-        value: 0
+        value: 100
       }
       experiments {
         key: "luci.recipes.use_python3"
@@ -31097,7 +30921,7 @@
       }
       experiments {
         key: "luci.buildbucket.omit_python2"
-        value: 0
+        value: 100
       }
       experiments {
         key: "luci.recipes.use_python3"
@@ -31188,7 +31012,7 @@
       }
       experiments {
         key: "luci.buildbucket.omit_python2"
-        value: 0
+        value: 100
       }
       experiments {
         key: "luci.recipes.use_python3"
@@ -31279,7 +31103,7 @@
       }
       experiments {
         key: "luci.buildbucket.omit_python2"
-        value: 0
+        value: 100
       }
       experiments {
         key: "luci.recipes.use_python3"
@@ -31370,7 +31194,7 @@
       }
       experiments {
         key: "luci.buildbucket.omit_python2"
-        value: 0
+        value: 100
       }
       experiments {
         key: "luci.recipes.use_python3"
@@ -31640,7 +31464,7 @@
       }
       experiments {
         key: "luci.buildbucket.omit_python2"
-        value: 0
+        value: 100
       }
       experiments {
         key: "luci.recipes.use_python3"
@@ -31731,7 +31555,7 @@
       }
       experiments {
         key: "luci.buildbucket.omit_python2"
-        value: 0
+        value: 100
       }
       experiments {
         key: "luci.recipes.use_python3"
@@ -31822,7 +31646,7 @@
       }
       experiments {
         key: "luci.buildbucket.omit_python2"
-        value: 0
+        value: 100
       }
       experiments {
         key: "luci.recipes.use_python3"
@@ -31910,7 +31734,7 @@
       }
       experiments {
         key: "luci.buildbucket.omit_python2"
-        value: 0
+        value: 100
       }
       experiments {
         key: "luci.recipes.use_python3"
@@ -32001,7 +31825,7 @@
       }
       experiments {
         key: "luci.buildbucket.omit_python2"
-        value: 0
+        value: 100
       }
       experiments {
         key: "luci.recipes.use_python3"
@@ -32089,7 +31913,7 @@
       }
       experiments {
         key: "luci.buildbucket.omit_python2"
-        value: 0
+        value: 100
       }
       experiments {
         key: "luci.recipes.use_python3"
@@ -35957,7 +35781,7 @@
       }
       experiments {
         key: "luci.buildbucket.omit_python2"
-        value: 0
+        value: 100
       }
       experiments {
         key: "luci.recipes.use_python3"
@@ -36048,7 +35872,7 @@
       }
       experiments {
         key: "luci.buildbucket.omit_python2"
-        value: 0
+        value: 100
       }
       experiments {
         key: "luci.recipes.use_python3"
@@ -36497,7 +36321,7 @@
       }
       experiments {
         key: "luci.buildbucket.omit_python2"
-        value: 0
+        value: 100
       }
       experiments {
         key: "luci.recipes.use_python3"
@@ -36673,7 +36497,7 @@
       }
       experiments {
         key: "luci.buildbucket.omit_python2"
-        value: 0
+        value: 100
       }
       experiments {
         key: "luci.recipes.use_python3"
@@ -37551,7 +37375,7 @@
       }
       experiments {
         key: "luci.buildbucket.omit_python2"
-        value: 0
+        value: 100
       }
       experiments {
         key: "luci.recipes.use_python3"
@@ -38266,7 +38090,7 @@
       }
       experiments {
         key: "luci.buildbucket.omit_python2"
-        value: 0
+        value: 100
       }
       experiments {
         key: "luci.recipes.use_python3"
@@ -38535,7 +38359,7 @@
       }
       experiments {
         key: "luci.buildbucket.omit_python2"
-        value: 0
+        value: 100
       }
       experiments {
         key: "luci.recipes.use_python3"
@@ -38624,7 +38448,7 @@
       }
       experiments {
         key: "luci.buildbucket.omit_python2"
-        value: 0
+        value: 100
       }
       experiments {
         key: "luci.recipes.use_python3"
@@ -39517,7 +39341,7 @@
       }
       experiments {
         key: "luci.buildbucket.omit_python2"
-        value: 0
+        value: 100
       }
       experiments {
         key: "luci.recipes.use_python3"
@@ -39784,7 +39608,7 @@
       }
       experiments {
         key: "luci.buildbucket.omit_python2"
-        value: 0
+        value: 100
       }
       experiments {
         key: "luci.recipes.use_python3"
@@ -40142,7 +39966,7 @@
       }
       experiments {
         key: "luci.buildbucket.omit_python2"
-        value: 0
+        value: 100
       }
       experiments {
         key: "luci.recipes.use_python3"
diff --git a/infra/config/generated/luci/luci-milo.cfg b/infra/config/generated/luci/luci-milo.cfg
index dde9bc6..133f06b 100644
--- a/infra/config/generated/luci/luci-milo.cfg
+++ b/infra/config/generated/luci/luci-milo.cfg
@@ -569,16 +569,6 @@
     short_name: "sbx"
   }
   builders {
-    name: "buildbucket/luci.chromium.ci/Linux ASan LSan Low Symbols FYI Builder"
-    category: "chromium.memory|linux|asan lsan fyi"
-    short_name: "bld"
-  }
-  builders {
-    name: "buildbucket/luci.chromium.ci/Linux ASan LSan Low Symbols FYI Tests (1)"
-    category: "chromium.memory|linux|asan lsan fyi"
-    short_name: "tst"
-  }
-  builders {
     name: "buildbucket/luci.chromium.ci/Linux MSan Builder"
     category: "chromium.memory|linux|msan"
     short_name: "bld"
@@ -11733,16 +11723,6 @@
     short_name: "sbx"
   }
   builders {
-    name: "buildbucket/luci.chromium.ci/Linux ASan LSan Low Symbols FYI Builder"
-    category: "linux|asan lsan fyi"
-    short_name: "bld"
-  }
-  builders {
-    name: "buildbucket/luci.chromium.ci/Linux ASan LSan Low Symbols FYI Tests (1)"
-    category: "linux|asan lsan fyi"
-    short_name: "tst"
-  }
-  builders {
     name: "buildbucket/luci.chromium.ci/Linux MSan Builder"
     category: "linux|msan"
     short_name: "bld"
diff --git a/infra/config/generated/luci/luci-notify.cfg b/infra/config/generated/luci/luci-notify.cfg
index 87870fb..b3f4ab3 100644
--- a/infra/config/generated/luci/luci-notify.cfg
+++ b/infra/config/generated/luci/luci-notify.cfg
@@ -764,33 +764,6 @@
     on_occurrence: FAILURE
     failed_step_regexp: "\\b(bot_update|compile|gclient runhooks|runhooks|update|\\w*nocompile_test)\\b"
     email {
-      recipients: "thomasanderson@chromium.org"
-    }
-  }
-  builders {
-    bucket: "ci"
-    name: "Linux ASan LSan Low Symbols FYI Builder"
-    repository: "https://chromium.googlesource.com/chromium/src"
-  }
-}
-notifiers {
-  notifications {
-    on_occurrence: FAILURE
-    failed_step_regexp: "\\b(bot_update|compile|gclient runhooks|runhooks|update|\\w*nocompile_test)\\b"
-    email {
-      recipients: "thomasanderson@chromium.org"
-    }
-  }
-  builders {
-    bucket: "ci"
-    name: "Linux ASan LSan Low Symbols FYI Tests (1)"
-  }
-}
-notifiers {
-  notifications {
-    on_occurrence: FAILURE
-    failed_step_regexp: "\\b(bot_update|compile|gclient runhooks|runhooks|update|\\w*nocompile_test)\\b"
-    email {
       rotation_urls: "https://chrome-ops-rotation-proxy.appspot.com/current/oncallator:chrome-build-sheriff"
     }
     template: "tree_closure_email_template"
diff --git a/infra/config/generated/luci/luci-scheduler.cfg b/infra/config/generated/luci/luci-scheduler.cfg
index 8371f00..14ab0700 100644
--- a/infra/config/generated/luci/luci-scheduler.cfg
+++ b/infra/config/generated/luci/luci-scheduler.cfg
@@ -1744,30 +1744,6 @@
   }
 }
 job {
-  id: "Linux ASan LSan Low Symbols FYI Builder"
-  realm: "ci"
-  acl_sets: "ci"
-  buildbucket {
-    server: "cr-buildbucket.appspot.com"
-    bucket: "ci"
-    builder: "Linux ASan LSan Low Symbols FYI Builder"
-  }
-}
-job {
-  id: "Linux ASan LSan Low Symbols FYI Tests (1)"
-  realm: "ci"
-  acls {
-    role: TRIGGERER
-    granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
-  }
-  acl_sets: "ci"
-  buildbucket {
-    server: "cr-buildbucket.appspot.com"
-    bucket: "ci"
-    builder: "Linux ASan LSan Low Symbols FYI Tests (1)"
-  }
-}
-job {
   id: "Linux ASan LSan Tests (1)"
   realm: "ci"
   acls {
@@ -7219,7 +7195,6 @@
   triggers: "Libfuzzer Upload Windows ASan"
   triggers: "Libfuzzer Upload iOS Catalyst Debug"
   triggers: "Linux ASan LSan Builder"
-  triggers: "Linux ASan LSan Low Symbols FYI Builder"
   triggers: "Linux Builder"
   triggers: "Linux Builder (Wayland)"
   triggers: "Linux Builder (dbg)"
diff --git a/infra/config/generated/luci/realms.cfg b/infra/config/generated/luci/realms.cfg
index 0978df0..ea59895 100644
--- a/infra/config/generated/luci/realms.cfg
+++ b/infra/config/generated/luci/realms.cfg
@@ -126,7 +126,6 @@
         values: "Android WebView N (dbg)"
         values: "Android WebView O (dbg)"
         values: "Android WebView P (dbg)"
-        values: "Linux ASan LSan Low Symbols FYI Tests (1)"
         values: "Linux ASan LSan Tests (1)"
         values: "Linux ASan Tests (sandboxed)"
         values: "Linux Chromium OS ASan LSan Tests (1)"
diff --git a/infra/config/subprojects/chromium/ci/chromium.chromiumos.star b/infra/config/subprojects/chromium/ci/chromium.chromiumos.star
index 7f01237d..31d4da4 100644
--- a/infra/config/subprojects/chromium/ci/chromium.chromiumos.star
+++ b/infra/config/subprojects/chromium/ci/chromium.chromiumos.star
@@ -22,9 +22,6 @@
     service_account = ci.DEFAULT_SERVICE_ACCOUNT,
     sheriff_rotations = sheriff_rotations.CHROMIUM,
     tree_closing = True,
-
-    # TODO(crbug.com/1362440): remove this.
-    omit_python2 = False,
 )
 
 consoles.console_view(
diff --git a/infra/config/subprojects/chromium/ci/chromium.memory.star b/infra/config/subprojects/chromium/ci/chromium.memory.star
index 3fe56c6..950bfdba 100644
--- a/infra/config/subprojects/chromium/ci/chromium.memory.star
+++ b/infra/config/subprojects/chromium/ci/chromium.memory.star
@@ -640,60 +640,3 @@
     os = os.MAC_12,
     xcode = xcode.x14main,
 )
-
-# TODO(crbug.com/1340327): Remove after experiment is over.
-linux_memory_builder(
-    name = "Linux ASan LSan Low Symbols FYI Builder",
-    branch_selector = branches.MAIN,
-    builder_spec = builder_config.builder_spec(
-        gclient_config = builder_config.gclient_config(
-            config = "chromium",
-        ),
-        chromium_config = builder_config.chromium_config(
-            config = "chromium_asan",
-            apply_configs = [
-                "lsan",
-                "mb",
-            ],
-            build_config = builder_config.build_config.RELEASE,
-            target_bits = 64,
-        ),
-    ),
-    console_view_entry = consoles.console_view_entry(
-        category = "linux|asan lsan fyi",
-        short_name = "bld",
-    ),
-    sheriff_rotations = args.ignore_default(None),
-    tree_closing = False,
-    os = os.LINUX_BIONIC,
-    ssd = True,
-)
-
-linux_memory_builder(
-    name = "Linux ASan LSan Low Symbols FYI Tests (1)",
-    branch_selector = branches.MAIN,
-    console_view_entry = consoles.console_view_entry(
-        category = "linux|asan lsan fyi",
-        short_name = "tst",
-    ),
-    builder_spec = builder_config.builder_spec(
-        execution_mode = builder_config.execution_mode.TEST,
-        gclient_config = builder_config.gclient_config(
-            config = "chromium",
-        ),
-        chromium_config = builder_config.chromium_config(
-            config = "chromium_asan",
-            apply_configs = [
-                "lsan",
-                "mb",
-            ],
-            build_config = builder_config.build_config.RELEASE,
-            target_bits = 64,
-        ),
-    ),
-    sheriff_rotations = args.ignore_default(None),
-    tree_closing = False,
-    triggered_by = ["ci/Linux ASan LSan Low Symbols FYI Builder"],
-    os = os.LINUX_BIONIC,
-    reclient_instance = None,
-)
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star b/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star
index 7a203cb2..7fe38c330 100644
--- a/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star
+++ b/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star
@@ -232,13 +232,6 @@
         "ci/chromeos-kevin-rel",
     ],
     main_list_view = "try",
-    tryjob = try_.job(
-        location_filters = [
-            "build/chromeos/.+",
-            "build/config/chromeos/.*",
-            "chromeos/CHROMEOS_LKGM",
-        ],
-    ),
     execution_timeout = 6 * time.hour,
 )
 
diff --git a/ios/chrome/app/BUILD.gn b/ios/chrome/app/BUILD.gn
index b3033ab..24ce930 100644
--- a/ios/chrome/app/BUILD.gn
+++ b/ios/chrome/app/BUILD.gn
@@ -66,6 +66,7 @@
     "post_restore_app_agent_unittest.mm",
     "safe_mode_app_state_agent_unittest.mm",
     "tab_opener_unittest.mm",
+    "variations_app_state_agent_unittest.mm",
   ]
   deps = [
     ":app",
@@ -73,6 +74,7 @@
     ":app_metrics_app_state_agent",
     ":post_restore_app_agent",
     ":safe_mode_app_state_agent",
+    ":variations_app_state_agent",
     "//base",
     "//base/test:test_support",
     "//components/metrics",
@@ -80,6 +82,7 @@
     "//components/prefs:test_support",
     "//components/sync_preferences:sync_preferences",
     "//components/sync_preferences:test_support",
+    "//components/variations",
     "//ios/chrome/app:enterprise_app_agent",
     "//ios/chrome/app/application_delegate",
     "//ios/chrome/app/application_delegate:application_delegate_internal",
@@ -237,8 +240,11 @@
   deps = [
     ":launch_screen_ui",
     "//base",
+    "//components/variations",
+    "//components/variations/service",
     "//ios/chrome/app/application_delegate:app_state_header",
     "//ios/chrome/app/application_delegate:observing_app_state_agent",
+    "//ios/chrome/browser/application_context",
   ]
 }
 
diff --git a/ios/chrome/app/DEPS b/ios/chrome/app/DEPS
index 17727fd..9347eb1 100644
--- a/ios/chrome/app/DEPS
+++ b/ios/chrome/app/DEPS
@@ -29,6 +29,7 @@
   "+components/ukm/ios",
   "+components/unified_consent",
   "+components/url_formatter",
+  "+components/variations",
   "+components/version_info",
   "+components/web_resource",
   "+ios/chrome/browser",
diff --git a/ios/chrome/app/variations_app_state_agent.mm b/ios/chrome/app/variations_app_state_agent.mm
index 7860914..fda45f1 100644
--- a/ios/chrome/app/variations_app_state_agent.mm
+++ b/ios/chrome/app/variations_app_state_agent.mm
@@ -5,17 +5,67 @@
 #import "ios/chrome/app/variations_app_state_agent.h"
 
 #import "base/mac/foundation_util.h"
+#import "base/time/time.h"
+#import "components/variations/service/variations_service_utils.h"
+#import "components/variations/variations_seed_store.h"
 #import "ios/chrome/app/application_delegate/app_state.h"
 #import "ios/chrome/app/launch_screen_view_controller.h"
+#import "ios/chrome/browser/application_context/application_context.h"
 #import "ios/chrome/browser/ui/main/scene_state.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
 #endif
 
+namespace {
+
+// The NSUserDefault key to store the time the last seed is fetched.
+NSString* kLastVariationsSeedFetchTimeKey = @"kLastVariationsSeedFetchTime";
+
+// Returns the time the last seed is fetched.
+base::Time GetLastVariationsSeedFetchTime() {
+  double date = [[NSUserDefaults standardUserDefaults]
+      doubleForKey:kLastVariationsSeedFetchTimeKey];
+  return base::Time::FromDoubleT(date);
+}
+
+// TODO(crbug.com/1380164): Look at Variations.SeedFreshness metric to see the
+// percentages of launches that has no seed/unexpired seed/expired seed.
+void RecordSeedFreshness(base::Time time) {
+  if (time.is_null()) {
+    // TODO(crbug.com/1380164): Seed doesn't exist. Log metric.
+  } else if (variations::HasSeedExpiredSinceTime(time)) {
+    // TODO(crbug.com/1380164): Seed expired. Log metric.
+  } else {
+    // TODO(crbug.com/1380164): Seed unexpired. Log metric.
+  }
+}
+
+// Retrieves the time the last variations seed is fetched from local state, and
+// stores it into NSUserDefaults. It should be executed every time before the
+// app shuts down, so the value could be used for the next startup, before
+// PrefService is instantiated.
+void SaveFetchTimeOfLatestSeedInLocalState() {
+  PrefService* localState = GetApplicationContext()->GetLocalState();
+  const base::Time seedDate =
+      variations::VariationsSeedStore::GetLastFetchTimeFromPrefService(
+          localState);
+  if (!seedDate.is_null()) {
+    [[NSUserDefaults standardUserDefaults]
+        setDouble:seedDate.ToDoubleT()
+           forKey:kLastVariationsSeedFetchTimeKey];
+  }
+}
+
+}  // namespace
+
 // TODO(crbug.com/1372180): Implement
 // IOSChromeVariationsSeedFetcherDelegate.
 @interface VariationsAppStateAgent () {
+  // Caches the previous activation level.
+  SceneActivationLevel _previousActivationLevel;
+  // Whether this is the first run of the app since installation.
+  BOOL _firstRun;
   // Whether the variations seed has been fetched.
   BOOL _seedFetched;
   // Whether the extended launch screen is shown.
@@ -29,8 +79,16 @@
 - (instancetype)init {
   self = [super init];
   if (self) {
+    _previousActivationLevel = SceneActivationLevelUnattached;
     _seedFetched = NO;
+    _firstRun = NO;
     _extendedLaunchScreenShown = NO;
+    base::Time lastFetchTime = GetLastVariationsSeedFetchTime();
+    if (lastFetchTime.is_null()) {
+      // No seed in storage, implying first run of the app since installation.
+      _firstRun = YES;
+    }
+    RecordSeedFreshness(lastFetchTime);
     if ([self shouldFetchVariationsSeed]) {
       // TODO(crbug.com/1372180): start seed fetch and a timeout timer.
     }
@@ -49,26 +107,27 @@
       [self.appState queueTransitionToNextInitStage];
     }
   }
-  // Important: do not add code after this block because its purpose is to
-  // clear `self` when not needed anymore.
-  if (previousInitStage == InitStageVariationsSeed) {
-    // Nothing left to do; clean up.
-    [self.appState removeAgent:self];
-  }
   [super appState:appState didTransitionFromInitStage:previousInitStage];
 }
 
 - (void)sceneState:(SceneState*)sceneState
     transitionedToActivationLevel:(SceneActivationLevel)level {
-  if ([self shouldFetchVariationsSeed]) {
-    DCHECK_GE(self.appState.initStage, InitStageVariationsSeed);
-    if (!_extendedLaunchScreenShown &&
-        self.appState.initStage == InitStageVariationsSeed &&
-        level > SceneActivationLevelBackground) {
-      [self showExtendedLaunchScreen:sceneState];
-      _extendedLaunchScreenShown = YES;
-    }
+  // If the app would be showing UI before Chrome UI is ready, extend the launch
+  // screen.
+  if (self.appState.initStage == InitStageVariationsSeed &&
+      [self shouldFetchVariationsSeed] &&
+      level > SceneActivationLevelBackground && !_extendedLaunchScreenShown) {
+    [self showExtendedLaunchScreen:sceneState];
+    _extendedLaunchScreenShown = YES;
   }
+  // Saves the fetch time to NSUserDefatuls when the app moves from foreground
+  // to background.
+  if (_previousActivationLevel > SceneActivationLevelBackground &&
+      level == SceneActivationLevelBackground &&
+      self.appState.initStage >= InitStageBrowserObjectsForUI) {
+    SaveFetchTimeOfLatestSeedInLocalState();
+  }
+  _previousActivationLevel = level;
   [super sceneState:sceneState transitionedToActivationLevel:level];
 }
 
@@ -86,8 +145,12 @@
 
 // Returns whether the variations seed should be fetched.
 - (BOOL)shouldFetchVariationsSeed {
-  // TODO(crbug.com/1372180): return whether the app is in first run AND enabled
-  // the "dynamic FRE finching" feature.
+  return _firstRun && [self shouldTurnOnFeature];
+}
+
+// TODO(crbug.com/1372180): Replace this method by actual method that sets up a
+// custom client side experiment and return the value.
+- (BOOL)shouldTurnOnFeature {
   return NO;
 }
 
diff --git a/ios/chrome/app/variations_app_state_agent_unittest.mm b/ios/chrome/app/variations_app_state_agent_unittest.mm
new file mode 100644
index 0000000..a103db8
--- /dev/null
+++ b/ios/chrome/app/variations_app_state_agent_unittest.mm
@@ -0,0 +1,167 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/app/variations_app_state_agent.h"
+
+#import "base/test/ios/wait_util.h"
+#import "base/test/task_environment.h"
+#import "base/time/time.h"
+#import "components/variations/pref_names.h"
+#import "ios/chrome/app/application_delegate/app_state.h"
+#import "ios/chrome/browser/application_context/application_context.h"
+#import "ios/chrome/browser/ui/main/scene_state.h"
+#import "ios/chrome/test/ios_chrome_scoped_testing_local_state.h"
+#import "testing/platform_test.h"
+#import "third_party/ocmock/OCMock/OCMock.h"
+#import "third_party/ocmock/gtest_support.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace {
+NSString* kLastVariationsSeedFetchTimeKey = @"kLastVariationsSeedFetchTime";
+
+// Simulate the existance for an unexpired seed from previous run.
+void SimulateUnexpiredSeed() {
+  [[NSUserDefaults standardUserDefaults]
+      setDouble:base::Time::NowFromSystemTime().ToDoubleT()
+         forKey:kLastVariationsSeedFetchTimeKey];
+}
+
+// Simulate the existance for an expired seed from previous run.
+void SimulateExpiredSeed() {
+  // Set the offset past zero so that it's not treated as a null value.
+  base::Time distantPast = base::Time::UnixEpoch() + base::Days(1);
+  [[NSUserDefaults standardUserDefaults]
+      setDouble:distantPast.ToDoubleT()
+         forKey:kLastVariationsSeedFetchTimeKey];
+}
+
+}  // namespace
+
+// TODO(crbug.com/1372180): Expose delegate methods.
+
+// Test class for VariationsAppStateAgent that overrides
+// `shouldFetchVariationsSeed` and exposes methods that implement
+// IOSChromeFirstRunVariationsSeedManagerDelegate.
+@interface VariationsAppStateAgentForTesting : VariationsAppStateAgent
+@end
+
+@implementation VariationsAppStateAgentForTesting
+
+// TODO(crbug.com/1372180): rewrite and/or remove once the original method is
+// re-implemented.
+- (BOOL)shouldTurnOnFeature {
+  return YES;
+}
+
+@end
+
+// Unit tests for VariationsAppStateAgent.
+class VariationsAppStateAgentTest : public PlatformTest {
+ protected:
+  VariationsAppStateAgentTest() {
+    mock_app_state_ = OCMClassMock([AppState class]);
+    scene_state_ = [[SceneState alloc] initWithAppState:mock_app_state_];
+  }
+
+  ~VariationsAppStateAgentTest() override {
+    [[NSUserDefaults standardUserDefaults]
+        removeObjectForKey:kLastVariationsSeedFetchTimeKey];
+    [mock_app_state_ stopMocking];
+    local_state_.Get()->ClearPref(variations::prefs::kVariationsLastFetchTime);
+  }
+
+  InitStage GetPreviousStage(InitStage currentStage) {
+    return static_cast<InitStage>(currentStage - 1);
+  }
+
+  id mock_app_state_;
+  SceneState* scene_state_;
+  base::test::TaskEnvironment task_environment_;
+  IOSChromeScopedTestingLocalState local_state_;
+};
+
+// Tests that on first run, the agent transitions to the next stage from
+// InitStageVariationsSeed after seed is fetched, and that the metric for first
+// run would be logged.
+TEST_F(VariationsAppStateAgentTest, EnableSeedFetchOnFirstRun) {
+  // Set up app init stage to be tested and agent and set expectations.
+  OCMStub([mock_app_state_ initStage]).andReturn(InitStageVariationsSeed);
+  OCMStub([mock_app_state_ queueTransitionToNextInitStage])
+      .andDo(^(NSInvocation* inv) {
+        FAIL() << "Should not transition to next init stage since the seed "
+                  "fetching is not completed";
+      });
+  //  Execute.
+  VariationsAppStateAgent* agent =
+      [[VariationsAppStateAgentForTesting alloc] init];
+  [agent setAppState:mock_app_state_];
+  [agent appState:mock_app_state_
+      didTransitionFromInitStage:GetPreviousStage(InitStageVariationsSeed)];
+  EXPECT_OCMOCK_VERIFY(mock_app_state_);
+  // TODO(crbug.com/1380164): Test that first run metric is logged.
+}
+
+// Tests that the agent immediately transitions to the next stage from
+// InitStageVariationsSeed when the seed should not be fetched, and that the
+// metric for unexpired seed would be logged.
+TEST_F(VariationsAppStateAgentTest,
+       DisableSeedFetchOnNonFirstRunWithUnexpiredSeed) {
+  // Set up app init stage to be tested and agent and set expectations.
+  OCMStub([mock_app_state_ initStage]).andReturn(InitStageVariationsSeed);
+  OCMExpect([mock_app_state_ queueTransitionToNextInitStage]);
+  //  Execute.
+  SimulateUnexpiredSeed();
+  VariationsAppStateAgent* agent =
+      [[VariationsAppStateAgentForTesting alloc] init];
+  [agent setAppState:mock_app_state_];
+  [agent appState:mock_app_state_
+      didTransitionFromInitStage:GetPreviousStage(InitStageVariationsSeed)];
+  EXPECT_OCMOCK_VERIFY(mock_app_state_);
+  // TODO(crbug.com/1380164): Test that unexpired seed metric is logged.
+}
+
+// Tests that the agent immediately transitions to the next stage from
+// InitStageVariationsSeed when the seed should not be fetched, and that the
+// metric for expired seed would be logged.
+TEST_F(VariationsAppStateAgentTest,
+       DisableSeedFetchOnNonFirstRunWithExpiredSeed) {
+  // Set up app init stage to be tested and agent and set expectations.
+  OCMStub([mock_app_state_ initStage]).andReturn(InitStageVariationsSeed);
+  OCMExpect([mock_app_state_ queueTransitionToNextInitStage]);
+  //  Execute.
+  SimulateExpiredSeed();
+  VariationsAppStateAgent* agent =
+      [[VariationsAppStateAgentForTesting alloc] init];
+  [agent setAppState:mock_app_state_];
+  [agent appState:mock_app_state_
+      didTransitionFromInitStage:GetPreviousStage(InitStageVariationsSeed)];
+  EXPECT_OCMOCK_VERIFY(mock_app_state_);
+  // TODO(crbug.com/1380164): Test that expired seed metric is logged.
+}
+
+// Tests that the fetch time from last launch will be saved when the app goes to
+// background.
+TEST_F(VariationsAppStateAgentTest, SavesLastSeedFetchTimeOnBackgrounding) {
+  base::Time lastFetchTime = base::Time::Now();
+  // Set up app init stage to be tested and agent and set expectations.
+  OCMStub([mock_app_state_ initStage]).andReturn(InitStageBrowserObjectsForUI);
+  VariationsAppStateAgent* agent =
+      [[VariationsAppStateAgentForTesting alloc] init];
+  [agent setAppState:mock_app_state_];
+  local_state_.Get()->SetTime(variations::prefs::kVariationsLastFetchTime,
+                              lastFetchTime);
+  //  Simulate backgrounding and launch again.
+  [agent sceneState:scene_state_
+      transitionedToActivationLevel:SceneActivationLevelBackground];
+  [mock_app_state_ stopMocking];
+  OCMStub([mock_app_state_ initStage]).andReturn(InitStageVariationsSeed);
+  agent = [[VariationsAppStateAgentForTesting alloc] init];
+  [agent setAppState:mock_app_state_];
+  [agent appState:mock_app_state_
+      didTransitionFromInitStage:GetPreviousStage(InitStageVariationsSeed)];
+  EXPECT_OCMOCK_VERIFY(mock_app_state_);
+}
diff --git a/ios/chrome/browser/power_bookmarks/power_bookmark_service_factory.mm b/ios/chrome/browser/power_bookmarks/power_bookmark_service_factory.mm
index d714b433..64ee44ec 100644
--- a/ios/chrome/browser/power_bookmarks/power_bookmark_service_factory.mm
+++ b/ios/chrome/browser/power_bookmarks/power_bookmark_service_factory.mm
@@ -4,6 +4,7 @@
 
 #import "ios/chrome/browser/power_bookmarks/power_bookmark_service_factory.h"
 
+#import "base/task/thread_pool.h"
 #import "components/keyed_service/ios/browser_state_dependency_manager.h"
 #import "components/power_bookmarks/core/power_bookmark_service.h"
 #import "ios/chrome/browser/bookmarks/bookmark_model_factory.h"
@@ -42,7 +43,11 @@
       ChromeBrowserState::FromBrowserState(state);
   return std::make_unique<power_bookmarks::PowerBookmarkService>(
       ios::BookmarkModelFactory::GetInstance()->GetForBrowserState(
-          chrome_state));
+          chrome_state),
+      state->GetStatePath().AppendASCII("power_bookmarks"),
+      base::ThreadPool::CreateSequencedTaskRunner(
+          {base::MayBlock(), base::TaskPriority::USER_BLOCKING,
+           base::TaskShutdownBehavior::BLOCK_SHUTDOWN}));
 }
 
 web::BrowserState* PowerBookmarkServiceFactory::GetBrowserStateToUse(
diff --git a/ios/chrome/browser/ui/authentication/BUILD.gn b/ios/chrome/browser/ui/authentication/BUILD.gn
index 3bc470d..c6db3e7e 100644
--- a/ios/chrome/browser/ui/authentication/BUILD.gn
+++ b/ios/chrome/browser/ui/authentication/BUILD.gn
@@ -56,6 +56,7 @@
     "//ios/chrome/browser/ui/authentication/signin:signin_headers",
     "//ios/chrome/browser/ui/commands",
     "//ios/chrome/browser/ui/infobars/resources:infobar_warning",
+    "//ios/chrome/browser/ui/ntp:feature_flags",
     "//ios/chrome/browser/ui/settings:settings_root",
     "//ios/chrome/browser/ui/util",
     "//ios/chrome/browser/unified_consent",
diff --git a/ios/chrome/browser/ui/authentication/signin_promo_view_mediator.mm b/ios/chrome/browser/ui/authentication/signin_promo_view_mediator.mm
index d31fc7d..e7772083 100644
--- a/ios/chrome/browser/ui/authentication/signin_promo_view_mediator.mm
+++ b/ios/chrome/browser/ui/authentication/signin_promo_view_mediator.mm
@@ -26,6 +26,7 @@
 #import "ios/chrome/browser/ui/authentication/signin_presenter.h"
 #import "ios/chrome/browser/ui/commands/application_commands.h"
 #import "ios/chrome/browser/ui/commands/show_signin_command.h"
+#import "ios/chrome/browser/ui/ntp/new_tab_page_feature.h"
 #import "ios/chrome/grit/ios_strings.h"
 #import "ui/base/l10n/l10n_util.h"
 
@@ -38,7 +39,6 @@
 // Number of times the sign-in promo should be displayed until it is
 // automatically dismissed.
 constexpr int kAutomaticSigninPromoViewDismissCount = 20;
-constexpr int kAutomaticSigninPromoViewDismissCountTopOfFeed = 10;
 // User defaults key to get the last logged impression of the top-of-feed promo.
 NSString* const kLastSigninImpressionTopOfFeedKey =
     @"last_signin_impression_top_of_feed";
@@ -487,7 +487,7 @@
   const int maxDisplayedCount =
       accessPoint ==
               signin_metrics::AccessPoint::ACCESS_POINT_NTP_FEED_TOP_PROMO
-          ? kAutomaticSigninPromoViewDismissCountTopOfFeed
+          ? FeedSyncPromoAutodismissCount()
           : kAutomaticSigninPromoViewDismissCount;
   const char* displayedCountPreferenceKey =
       DisplayedCountPreferenceKey(accessPoint);
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm
index 1e514a0b..c38109e 100644
--- a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm
+++ b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm
@@ -429,6 +429,7 @@
   // When the visible feed has been updated, recalculate the minimum NTP height.
   if (feedType == self.selectedFeed) {
     [self.ntpViewController updateFeedInsetsForMinimumHeight];
+    [self.ntpViewController updateStickyElements];
   }
 }
 
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_feature.h b/ios/chrome/browser/ui/ntp/new_tab_page_feature.h
index c288ca78..5b37cf6 100644
--- a/ios/chrome/browser/ui/ntp/new_tab_page_feature.h
+++ b/ios/chrome/browser/ui/ntp/new_tab_page_feature.h
@@ -78,6 +78,9 @@
 // Whether the feed top sync promotion is compact or not.
 bool IsDiscoverFeedTopSyncPromoCompact();
 
+// Returns the number of impressions before autodismissing the feed sync promo.
+int FeedSyncPromoAutodismissCount();
+
 // Whether the Following feed default sort type experiment is enabled.
 bool IsFollowingFeedDefaultSortTypeEnabled();
 
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_feature.mm b/ios/chrome/browser/ui/ntp/new_tab_page_feature.mm
index 835cd99f..fab5c0d 100644
--- a/ios/chrome/browser/ui/ntp/new_tab_page_feature.mm
+++ b/ios/chrome/browser/ui/ntp/new_tab_page_feature.mm
@@ -37,6 +37,11 @@
              "FollowingFeedDefaultSortType",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
+// A parameter value for the number of impressions before autodismissing the
+// promo.
+const char kDiscoverFeedTopSyncPromoAutodismissImpressions[] =
+    "autodismissImpressions";
+
 const char kDiscoverFeedSRSReconstructedTemplatesEnabled[] =
     "DiscoverFeedSRSReconstructedTemplatesEnabled";
 
@@ -88,6 +93,12 @@
       false);
 }
 
+int FeedSyncPromoAutodismissCount() {
+  return base::GetFieldTrialParamByFeatureAsInt(
+      kEnableDiscoverFeedTopSyncPromo,
+      kDiscoverFeedTopSyncPromoAutodismissImpressions, 10);
+}
+
 bool IsFollowingFeedDefaultSortTypeEnabled() {
   return base::FeatureList::IsEnabled(kFollowingFeedDefaultSortType);
 }
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.h b/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.h
index a612ff4..de64b45e 100644
--- a/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.h
+++ b/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.h
@@ -131,6 +131,10 @@
 // Updates the scroll position to account for the feed promo being removed.
 - (void)updateScrollPositionForFeedTopSectionClosed;
 
+// Forces the elements that stick to the top when scrolling (eg. omnibox, feed
+// header) to update for the current scroll position.
+- (void)updateStickyElements;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_NTP_NEW_TAB_PAGE_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm b/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm
index 8c1b5b6..8e26659b 100644
--- a/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm
+++ b/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm
@@ -514,6 +514,10 @@
   }
 }
 
+- (void)updateStickyElements {
+  [self handleStickyElementsForScrollPosition:[self scrollPosition] force:YES];
+}
+
 #pragma mark - UIScrollViewDelegate
 
 - (void)scrollViewDidScroll:(UIScrollView*)scrollView {
diff --git a/ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher_unittest.mm b/ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher_unittest.mm
index 586a9c8..24d5c54 100644
--- a/ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher_unittest.mm
+++ b/ios/chrome/browser/variations/ios_chrome_variations_seed_fetcher_unittest.mm
@@ -152,7 +152,7 @@
       [[TestVariationsSeedFetcher alloc] initWithCommandLineArgsForTesting:@[]];
   fetcher.delegate = delegate;
   [fetcher startSeedFetch];
-  base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(0.05));
+  base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(0.1));
   EXPECT_OCMOCK_VERIFY(delegate);
 }
 
@@ -183,7 +183,7 @@
   TestVariationsSeedFetcher* fetcher = [[TestVariationsSeedFetcher alloc]
       initWithCommandLineArgsForTesting:@[ argument ]];
   [fetcher startSeedFetch];
-  base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(0.05));
+  base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(0.1));
   EXPECT_OCMOCK_VERIFY(mockURLSession);
 }
 
@@ -207,12 +207,12 @@
   fetcher.delegate = delegate;
   fetcher.startTimeOfOngoingSeedRequest = [NSDate now];
   [fetcher onSeedRequestCompletedWithData:nil response:responseOk error:error];
-  base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(0.05));
+  base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(0.1));
   EXPECT_EQ([IOSChromeVariationsSeedStore popSeed], nil);
   EXPECT_EQ(fetcher.startTimeOfOngoingSeedRequest, nil);
   fetcher.startTimeOfOngoingSeedRequest = [NSDate now];
   [fetcher onSeedRequestCompletedWithData:nil response:responseError error:nil];
-  base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(0.05));
+  base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(0.1));
   EXPECT_EQ([IOSChromeVariationsSeedStore popSeed], nil);
   EXPECT_EQ(fetcher.startTimeOfOngoingSeedRequest, nil);
   EXPECT_OCMOCK_VERIFY(delegate);
@@ -245,7 +245,7 @@
   [fetcherWithSeed onSeedRequestCompletedWithData:nil
                                          response:response
                                             error:nil];
-  base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(0.05));
+  base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(0.1));
   EXPECT_EQ([fetcherWithSeed startTimeOfOngoingSeedRequest], nil);
   EXPECT_EQ([IOSChromeVariationsSeedStore popSeed], expectedSeed);
   EXPECT_OCMOCK_VERIFY(delegate);
@@ -272,7 +272,7 @@
   [fetcherWithSeed onSeedRequestCompletedWithData:nil
                                          response:response
                                             error:nil];
-  base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(0.05));
+  base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(0.1));
   EXPECT_EQ([fetcherWithSeed startTimeOfOngoingSeedRequest], nil);
   EXPECT_EQ([IOSChromeVariationsSeedStore popSeed], nil);
   EXPECT_OCMOCK_VERIFY(delegate);
diff --git a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1 b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1
index 54cafa4..f9a72d5c 100644
--- a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1
+++ b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1
@@ -1 +1 @@
-5d5b8b43977e1f2fc89cd80f7310b27962bd46f1
\ No newline at end of file
+f384b6988a69526ca2b99d33a05e87f825860224
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1 b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1
index e21c195e..c495b763 100644
--- a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1
+++ b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1
@@ -1 +1 @@
-1dce5b5cc3fd51314b0377ee5ca94974309acc71
\ No newline at end of file
+e093af8040f694fde23a7139644520c9d3fd82b3
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
index 4741e46..49b3e2a 100644
--- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-1076654c5a2fa77bc4c58d863c5578dafceb1f0f
\ No newline at end of file
+adb53d72e356287df6cba6db1874240c96a879b8
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
index 41006d38..848d1d0 100644
--- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-b9394a25da573b3f49d6afa746dabfe2f5eff216
\ No newline at end of file
+25c5bd206ce4796ff5641baed2d388148ee5b0d2
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
index 383a080c..64d979b 100644
--- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-6685a97aa0d2de2df90b55ea1142a1c7125185e9
\ No newline at end of file
+b5b8bf71d21ab72f6f729d449e07b018032c8af3
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
index 8d80aa3..3af8881 100644
--- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-f3bca0d01b1b1db39b24699b6393907bcb54e41f
\ No newline at end of file
+69eb6d4a8f5fb0a721cd0fda64bb78b44de5d3fc
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1
index 7c2c792d..4134238 100644
--- a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-c7670a94db4021b680f76075a3448c4b7d6e35a2
\ No newline at end of file
+507c4137bc9ab34c8ba4a43ae75630b9ddc8f03b
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1
index 89883f4..8a885e2 100644
--- a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-cb72c7e75b9d35320023c923c52cb3ea28241312
\ No newline at end of file
+6218c10d732b17bbc8a974f67a3f6b55da4c2fa6
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1
index 1b0c7084..c6d0fc5 100644
--- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-55f13ba24a763c494ad5473d6babbefd326eb3c1
\ No newline at end of file
+db3fac89776239a8b26dbc29538acdbb58937dd5
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1
index e396bcb..7c511170 100644
--- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-ff5d6e65552c6a4c5c92b8f4c5c3e63d02dd3d96
\ No newline at end of file
+63f4e8ead51803e827da4c4658c72a7cfe0e079b
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
index fe3e67b..be6906b 100644
--- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-a6eecaea0d164e16ba3f77c9818a4b430615ecbb
\ No newline at end of file
+d8b77e4e2b5b991b2257f2ac49fb85de994f670b
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
index 64713be..5e4ae9b7 100644
--- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-0a650a31b8b9588d12f8bee315a7c79f248e97d2
\ No newline at end of file
+19289cc0597a3ddf931bdfddfc34c8088da0a156
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
index e6a3f827..65a223da 100644
--- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-494d925b354b87cc9e5ef93e5f945a09bf0f3808
\ No newline at end of file
+5fea5abacadbc0a315d282c3336afe7726b66754
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
index 2e4b7c8..c8b1ffa 100644
--- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-1fa233344cacfa564817d834f2b9542fe856cc57
\ No newline at end of file
+20ff1346f6e30749e3a630421128a24acc59d755
\ No newline at end of file
diff --git a/net/cert/trial_comparison_cert_verifier_unittest.cc b/net/cert/trial_comparison_cert_verifier_unittest.cc
index 26ae5f4..ab08e03c 100644
--- a/net/cert/trial_comparison_cert_verifier_unittest.cc
+++ b/net/cert/trial_comparison_cert_verifier_unittest.cc
@@ -1194,44 +1194,40 @@
                                         std::move(intermediates));
   ASSERT_TRUE(different_chain);
 
-  CertVerifyResult different_chain_result;
-  different_chain_result.verified_cert = different_chain;
+  CertVerifyResult different_chain_result_no_known_root;
+  different_chain_result_no_known_root.verified_cert = different_chain;
 
-  CertVerifyResult nonev_chain_result;
-  nonev_chain_result.verified_cert = cert_chain;
+  CertVerifyResult different_chain_result_known_root;
+  different_chain_result_known_root.verified_cert = different_chain;
+  different_chain_result_known_root.is_issued_by_known_root = true;
 
-  CertVerifyResult ev_chain_result;
-  ev_chain_result.verified_cert = cert_chain;
-  ev_chain_result.cert_status =
-      CERT_STATUS_IS_EV | CERT_STATUS_REV_CHECKING_ENABLED;
+  CertVerifyResult chain_result;
+  chain_result.verified_cert = cert_chain;
+  chain_result.is_issued_by_known_root = true;
 
   SHA256HashValue root_fingerprint;
   crypto::SHA256HashString(x509_util::CryptoBufferAsStringPiece(
                                cert_chain->intermediate_buffers().back().get()),
                            root_fingerprint.data,
                            sizeof(root_fingerprint.data));
-  // Both policies in the target are EV policies, but only 1.2.6.7 is valid for
-  // the root in cert_chain.
-  ScopedTestEVPolicy scoped_ev_policy_1(EVRootCAMetadata::GetInstance(),
-                                        root_fingerprint, "1.2.6.7");
-  ScopedTestEVPolicy scoped_ev_policy_2(EVRootCAMetadata::GetInstance(),
-                                        SHA256HashValue(), "1.2.3.4");
 
   scoped_refptr<MockCertVerifyProc> verify_proc1 =
       base::MakeRefCounted<MockCertVerifyProc>();
   // Primary verifier returns ok status and different_chain if verifying leaf
-  // alone.
+  // alone, but not is_known_root.
   EXPECT_CALL(*verify_proc1, VerifyInternal(leaf.get(), _, _, _, _, _, _, _, _))
-      .WillOnce(DoAll(SetArgPointee<7>(different_chain_result), Return(OK)));
-  // Primary verifier returns ok status and nonev_chain_result if verifying
-  // cert_chain.
+      .WillOnce(DoAll(SetArgPointee<7>(different_chain_result_no_known_root),
+                      Return(OK)));
+  // Primary verifier returns ok status and different_chain if verifying
+  // cert_chain and with is_known_root..
   EXPECT_CALL(*verify_proc1,
               VerifyInternal(cert_chain.get(), _, _, _, _, _, _, _, _))
-      .WillOnce(DoAll(SetArgPointee<7>(nonev_chain_result), Return(OK)));
+      .WillOnce(DoAll(SetArgPointee<7>(different_chain_result_known_root),
+                      Return(OK)));
 
-  // Trial verifier returns ok status and ev_chain_result.
+  // Trial verifier returns ok status and chain_result.
   scoped_refptr<FakeCertVerifyProc> verify_proc2 =
-      base::MakeRefCounted<FakeCertVerifyProc>(OK, ev_chain_result);
+      base::MakeRefCounted<FakeCertVerifyProc>(OK, chain_result);
 
   std::vector<TrialReportInfo> reports;
   TrialComparisonCertVerifier verifier(
@@ -1260,7 +1256,8 @@
   EXPECT_TRUE(reports.empty());
 
   // Primary verifier should be used twice, the second time with the chain
-  // from the trial verifier.
+  // from the trial verifier. Even so, it only should be counted once in
+  // metrics.
   testing::Mock::VerifyAndClear(verify_proc1.get());
   EXPECT_EQ(1, verify_proc2->num_verifications());
   histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", 1);
@@ -1772,6 +1769,7 @@
   EXPECT_EQ(1U, reports.size());
 }
 
+#if defined(PLATFORM_USES_CHROMIUM_EV_METADATA)
 TEST_F(TrialComparisonCertVerifierTest, MultipleEVPolicies) {
   base::FilePath certs_dir =
       GetTestNetDataDirectory()
@@ -1977,6 +1975,7 @@
       "Net.CertVerifier_TrialComparisonResult",
       TrialComparisonResult::kBothValidDifferentDetails, 1);
 }
+#endif
 
 TEST_F(TrialComparisonCertVerifierTest, LocallyTrustedLeaf) {
   // Platform verifier verifies the leaf directly.
diff --git a/printing/test_printing_context.cc b/printing/test_printing_context.cc
index ca5781f..529e27a 100644
--- a/printing/test_printing_context.cc
+++ b/printing/test_printing_context.cc
@@ -153,8 +153,12 @@
   abort_printing_ = false;
   in_print_job_ = true;
 
-  if (!skip_system_calls() && new_document_blocked_by_permissions_)
-    return mojom::ResultCode::kAccessDenied;
+  if (!skip_system_calls()) {
+    if (new_document_fails_)
+      return mojom::ResultCode::kFailed;
+    if (new_document_blocked_by_permissions_)
+      return mojom::ResultCode::kAccessDenied;
+  }
 
   // No-op.
   return mojom::ResultCode::kSuccess;
diff --git a/printing/test_printing_context.h b/printing/test_printing_context.h
index c87f243c..faec108 100644
--- a/printing/test_printing_context.h
+++ b/printing/test_printing_context.h
@@ -68,6 +68,7 @@
   }
 
   // Enables tests to fail with a failed error.
+  void SetNewDocumentFails() { new_document_fails_ = true; }
   void SetUseDefaultSettingsFails() { use_default_settings_fails_ = true; }
 
   // Enables tests to fail with a canceled error.
@@ -107,6 +108,7 @@
   base::flat_map<std::string, std::unique_ptr<PrintSettings>> device_settings_;
   bool use_default_settings_fails_ = false;
   bool ask_user_for_settings_cancel_ = false;
+  bool new_document_fails_ = false;
   bool new_document_blocked_by_permissions_ = false;
 #if BUILDFLAG(IS_WIN)
   bool render_page_blocked_by_permissions_ = false;
diff --git a/remoting/android/lint-baseline.xml b/remoting/android/lint-baseline.xml
index 992617ed..f6a316d 100644
--- a/remoting/android/lint-baseline.xml
+++ b/remoting/android/lint-baseline.xml
@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 7.4.0-alpha05" type="baseline" client="" dependencies="true" name="" variant="all" version="7.4.0-alpha05">
+<issues format="6" by="lint 8.0.0-alpha06" type="baseline" client="" dependencies="true" name="" variant="all" version="8.0.0-alpha06">
 
     <issue
         id="LintError"
-        message="../../remoting/android/lint-baseline.xml (relative to /usr/local/google/home/wnwen/z1/src/out/Debug) does not exist"
+        message="../../remoting/android/lint-baseline.xml (relative to /usr/local/google/code/clankium/src/out/Lint-Default) does not exist"
         errorLine1="  &lt;baseline file=&quot;../../remoting/android/lint-baseline.xml&quot;/>"
         errorLine2="  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
@@ -18,7 +18,7 @@
         errorLine1="        if (mDrawerLayout.isDrawerOpen(Gravity.START)) {"
         errorLine2="                                       ~~~~~~~~~~~~~">
         <location
-            file="$SRC/remoting/android/java/src/org/chromium/chromoting/Chromoting.java"
+            file="../../remoting/android/java/src/org/chromium/chromoting/Chromoting.java"
             line="204"
             column="40"/>
     </issue>
@@ -29,7 +29,7 @@
         errorLine1="            mDrawerLayout.closeDrawer(Gravity.START);"
         errorLine2="                                      ~~~~~~~~~~~~~">
         <location
-            file="$SRC/remoting/android/java/src/org/chromium/chromoting/Chromoting.java"
+            file="../../remoting/android/java/src/org/chromium/chromoting/Chromoting.java"
             line="205"
             column="39"/>
     </issue>
@@ -40,7 +40,7 @@
         errorLine1="                        if (mDrawerLayout.isDrawerOpen(Gravity.START)) {"
         errorLine2="                                                       ~~~~~~~~~~~~~">
         <location
-            file="$SRC/remoting/android/java/src/org/chromium/chromoting/Chromoting.java"
+            file="../../remoting/android/java/src/org/chromium/chromoting/Chromoting.java"
             line="292"
             column="56"/>
     </issue>
@@ -51,7 +51,7 @@
         errorLine1="                            mDrawerLayout.closeDrawer(Gravity.START);"
         errorLine2="                                                      ~~~~~~~~~~~~~">
         <location
-            file="$SRC/remoting/android/java/src/org/chromium/chromoting/Chromoting.java"
+            file="../../remoting/android/java/src/org/chromium/chromoting/Chromoting.java"
             line="293"
             column="55"/>
     </issue>
@@ -62,7 +62,7 @@
         errorLine1="                            mDrawerLayout.openDrawer(Gravity.START);"
         errorLine2="                                                     ~~~~~~~~~~~~~">
         <location
-            file="$SRC/remoting/android/java/src/org/chromium/chromoting/Chromoting.java"
+            file="../../remoting/android/java/src/org/chromium/chromoting/Chromoting.java"
             line="295"
             column="54"/>
     </issue>
@@ -73,7 +73,7 @@
         errorLine1="        for (int i = 0; i &lt; InputMode.NUM_ENTRIES; i++) {"
         errorLine2="                                      ~~~~~~~~~~~">
         <location
-            file="$SRC/remoting/android/java/src/org/chromium/chromoting/Desktop.java"
+            file="../../remoting/android/java/src/org/chromium/chromoting/Desktop.java"
             line="351"
             column="39"/>
     </issue>
@@ -84,7 +84,7 @@
         errorLine1="        android:drawableStart=&quot;@drawable/ic_host_online&quot;"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/remoting/android/java/res/layout/host_online.xml"
+            file="../../remoting/android/java/res/layout/host_online.xml"
             line="28"
             column="9"/>
     </issue>
@@ -95,7 +95,7 @@
         errorLine1="        mWebView.getSettings().setJavaScriptEnabled(true);"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/remoting/android/java/src/org/chromium/chromoting/help/HelpActivity.java"
+            file="../../remoting/android/java/src/org/chromium/chromoting/help/HelpActivity.java"
             line="91"
             column="9"/>
     </issue>
@@ -106,7 +106,7 @@
         errorLine1="        webView.getSettings().setJavaScriptEnabled(true);"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/remoting/android/java/src/org/chromium/chromoting/WebViewActivity.java"
+            file="../../remoting/android/java/src/org/chromium/chromoting/WebViewActivity.java"
             line="46"
             column="9"/>
     </issue>
@@ -124,99 +124,132 @@
 
     <issue
         id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is always >= 23"
+        message="Unnecessary; SDK_INT is always >= 24"
         errorLine1="        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/remoting/android/java/src/org/chromium/chromoting/accountswitcher/AccountManagerCompat.java"
+            file="../../remoting/android/java/src/org/chromium/chromoting/accountswitcher/AccountManagerCompat.java"
             line="25"
             column="13"/>
     </issue>
 
     <issue
         id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is always >= 23"
+        message="Unnecessary; SDK_INT is always >= 24"
         errorLine1="        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/remoting/android/java/src/org/chromium/chromoting/Chromoting.java"
+            file="../../remoting/android/java/src/org/chromium/chromoting/Chromoting.java"
             line="628"
             column="13"/>
     </issue>
 
     <issue
         id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is always >= 23"
+        message="Unnecessary; SDK_INT is always >= 24"
         errorLine1="        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/remoting/android/java/src/org/chromium/chromoting/Desktop.java"
+            file="../../remoting/android/java/src/org/chromium/chromoting/Desktop.java"
             line="183"
             column="13"/>
     </issue>
 
     <issue
         id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is always >= 23"
+        message="Unnecessary; SDK_INT is always >= 24"
+        errorLine1="        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="../../remoting/android/java/src/org/chromium/chromoting/Desktop.java"
+            line="215"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="ObsoleteSdkInt"
+        message="Unnecessary; SDK_INT is always >= 24"
         errorLine1="        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {"
         errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/remoting/android/java/src/org/chromium/chromoting/Desktop.java"
+            file="../../remoting/android/java/src/org/chromium/chromoting/Desktop.java"
             line="221"
             column="20"/>
     </issue>
 
     <issue
         id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is always >= 23"
+        message="Unnecessary; SDK_INT is always >= 24"
         errorLine1="        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/remoting/android/java/src/org/chromium/chromoting/Desktop.java"
+            file="../../remoting/android/java/src/org/chromium/chromoting/Desktop.java"
             line="280"
             column="13"/>
     </issue>
 
     <issue
         id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is always >= 23"
+        message="Unnecessary; SDK_INT is always >= 24"
         errorLine1="        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/remoting/android/java/src/org/chromium/chromoting/Desktop.java"
+            file="../../remoting/android/java/src/org/chromium/chromoting/Desktop.java"
             line="512"
             column="13"/>
     </issue>
 
     <issue
         id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is always >= 23"
+        message="Unnecessary; SDK_INT is always >= 24"
         errorLine1="        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/remoting/android/java/src/org/chromium/chromoting/Desktop.java"
+            file="../../remoting/android/java/src/org/chromium/chromoting/Desktop.java"
             line="521"
             column="13"/>
     </issue>
 
     <issue
         id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is always >= 23"
+        message="Unnecessary; SDK_INT is always >= 24"
         errorLine1="        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="$SRC/remoting/android/java/src/org/chromium/chromoting/Desktop.java"
+            file="../../remoting/android/java/src/org/chromium/chromoting/Desktop.java"
             line="605"
             column="13"/>
     </issue>
 
     <issue
+        id="ObsoleteSdkInt"
+        message="Unnecessary; SDK_INT is always >= 24"
+        errorLine1="            @RequiresApi(Build.VERSION_CODES.N)"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="../../remoting/android/java/src/org/chromium/chromoting/help/HelpActivity.java"
+            line="105"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="ObsoleteSdkInt"
+        message="Unnecessary; SDK_INT is always >= 24"
+        errorLine1="            @RequiresApi(Build.VERSION_CODES.N)"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="../../remoting/android/java/src/org/chromium/chromoting/WebViewActivity.java"
+            line="53"
+            column="13"/>
+    </issue>
+
+    <issue
         id="MonochromeLauncherIcon"
         message="The application adaptive icon is missing a monochrome tag"
         errorLine1="&lt;adaptive-icon xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;>"
         errorLine2="^">
         <location
-            file="$SRC/remoting/android/java/res/mipmap-anydpi-v26/ic_launcher.xml"
+            file="../../remoting/android/java/res/mipmap-anydpi-v26/ic_launcher.xml"
             line="2"
             column="1"/>
     </issue>
@@ -227,7 +260,7 @@
         errorLine1="    public final boolean onTouchEvent(MotionEvent event) {"
         errorLine2="                         ~~~~~~~~~~~~">
         <location
-            file="$SRC/remoting/android/java/src/org/chromium/chromoting/DesktopView.java"
+            file="../../remoting/android/java/src/org/chromium/chromoting/DesktopView.java"
             line="85"
             column="26"/>
     </issue>
diff --git a/services/device/generic_sensor/android/junit/src/org/chromium/device/sensors/PlatformSensorAndProviderTest.java b/services/device/generic_sensor/android/junit/src/org/chromium/device/sensors/PlatformSensorAndProviderTest.java
index 1eaba00..91734cb 100644
--- a/services/device/generic_sensor/android/junit/src/org/chromium/device/sensors/PlatformSensorAndProviderTest.java
+++ b/services/device/generic_sensor/android/junit/src/org/chromium/device/sensors/PlatformSensorAndProviderTest.java
@@ -51,7 +51,7 @@
  * Unit tests for PlatformSensor and PlatformSensorProvider.
  */
 @RunWith(BaseRobolectricTestRunner.class)
-@Config(sdk = Build.VERSION_CODES.M, manifest = Config.NONE)
+@Config(sdk = Build.VERSION_CODES.N, manifest = Config.NONE)
 @SuppressWarnings("GuardedBy") // verify(sensor, times(1)).sensorError() cannot resolve |mLock|.
 public class PlatformSensorAndProviderTest {
     @Mock
diff --git a/services/device/geolocation/android/junit/src/org/chromium/device/geolocation/LocationProviderTest.java b/services/device/geolocation/android/junit/src/org/chromium/device/geolocation/LocationProviderTest.java
index b60d694..0bd2cac 100644
--- a/services/device/geolocation/android/junit/src/org/chromium/device/geolocation/LocationProviderTest.java
+++ b/services/device/geolocation/android/junit/src/org/chromium/device/geolocation/LocationProviderTest.java
@@ -37,7 +37,7 @@
  * Test suite for Java Geolocation.
  */
 @RunWith(ParameterizedRobolectricTestRunner.class)
-@Config(sdk = Build.VERSION_CODES.M, manifest = Config.NONE)
+@Config(sdk = Build.VERSION_CODES.N, manifest = Config.NONE)
 public class LocationProviderTest {
     public static enum LocationProviderType { MOCK, ANDROID, GMS_CORE }
 
diff --git a/services/device/nfc/android/junit/src/org/chromium/device/nfc/NFCTest.java b/services/device/nfc/android/junit/src/org/chromium/device/nfc/NFCTest.java
index e5ed558..9b08326b 100644
--- a/services/device/nfc/android/junit/src/org/chromium/device/nfc/NFCTest.java
+++ b/services/device/nfc/android/junit/src/org/chromium/device/nfc/NFCTest.java
@@ -71,7 +71,7 @@
  * Unit tests for NfcImpl and NdefMessageUtils classes.
  */
 @RunWith(BaseRobolectricTestRunner.class)
-@Config(sdk = Build.VERSION_CODES.M, manifest = Config.NONE)
+@Config(sdk = Build.VERSION_CODES.N, manifest = Config.NONE)
 public class NFCTest {
     private TestNfcDelegate mDelegate;
     private int mNextWatchId;
diff --git a/services/device/nfc/android/junit/src/org/chromium/device/nfc/NfcBlocklistTest.java b/services/device/nfc/android/junit/src/org/chromium/device/nfc/NfcBlocklistTest.java
index e91e99ac..24c651a 100644
--- a/services/device/nfc/android/junit/src/org/chromium/device/nfc/NfcBlocklistTest.java
+++ b/services/device/nfc/android/junit/src/org/chromium/device/nfc/NfcBlocklistTest.java
@@ -20,7 +20,7 @@
  * Unit tests for the {@link NfcBlocklist} class.
  */
 @RunWith(BaseRobolectricTestRunner.class)
-@Config(sdk = Build.VERSION_CODES.M, manifest = Config.NONE)
+@Config(sdk = Build.VERSION_CODES.N, manifest = Config.NONE)
 public class NfcBlocklistTest {
     // Static historical bytes
     private static final byte[] YUBIKEY_NEO_HISTORICAL_BYTES = new byte[] {
diff --git a/services/shape_detection/android/junit/src/org/chromium/shape_detection/BitmapUtilsTest.java b/services/shape_detection/android/junit/src/org/chromium/shape_detection/BitmapUtilsTest.java
index 1601441..7215c38c8 100644
--- a/services/shape_detection/android/junit/src/org/chromium/shape_detection/BitmapUtilsTest.java
+++ b/services/shape_detection/android/junit/src/org/chromium/shape_detection/BitmapUtilsTest.java
@@ -25,7 +25,7 @@
  * Test suite for conversion-to-Frame utils.
  */
 @RunWith(BaseRobolectricTestRunner.class)
-@Config(sdk = Build.VERSION_CODES.M, manifest = Config.NONE)
+@Config(sdk = Build.VERSION_CODES.N, manifest = Config.NONE)
 public class BitmapUtilsTest {
     private static final int VALID_WIDTH = 1;
     private static final int VALID_HEIGHT = 1;
diff --git a/styleguide/python/OWNERS b/styleguide/python/OWNERS
index a0e0826..a6d08ea 100644
--- a/styleguide/python/OWNERS
+++ b/styleguide/python/OWNERS
@@ -1,2 +1,3 @@
 agrieve@chromium.org
+dpranke@google.com
 wnwen@chromium.org
diff --git a/testing/buildbot/chrome.json b/testing/buildbot/chrome.json
index 94826093..6cee103 100644
--- a/testing/buildbot/chrome.json
+++ b/testing/buildbot/chrome.json
@@ -1328,14 +1328,13 @@
               "pool": "chrome.tests"
             }
           ],
-          "hard_timeout": 7200,
           "idempotent": false,
           "io_timeout": 3600,
           "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com",
           "shards": 10
         },
-        "test": "chrome_all_tast_tests_with_lacros",
-        "test_id_prefix": "ninja://chromeos:chrome_all_tast_tests_with_lacros/",
+        "test": "chrome_all_tast_tests",
+        "test_id_prefix": "ninja://chromeos:chrome_all_tast_tests/",
         "trigger_script": {
           "script": "//testing/trigger_scripts/chromeos_device_trigger.py"
         }
@@ -1871,6 +1870,70 @@
     "skylab_tests": [
       {
         "args": [],
+        "cros_board": "dedede",
+        "cros_img": "dedede-release/R109-15201.0.0",
+        "name": "lacros_all_tast_tests DEDEDE_RELEASE_LKGM",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {},
+        "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)",
+        "test": "lacros_all_tast_tests",
+        "test_id_prefix": "ninja://chromeos/lacros:lacros_all_tast_tests/",
+        "timeout_sec": 10800,
+        "variant_id": "DEDEDE_RELEASE_LKGM"
+      },
+      {
+        "args": [],
+        "cros_board": "dedede",
+        "cros_img": "dedede-release/R108-15183.14.0",
+        "name": "lacros_all_tast_tests DEDEDE_RELEASE_DEV",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {},
+        "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)",
+        "test": "lacros_all_tast_tests",
+        "test_id_prefix": "ninja://chromeos/lacros:lacros_all_tast_tests/",
+        "timeout_sec": 10800,
+        "variant_id": "DEDEDE_RELEASE_DEV"
+      },
+      {
+        "args": [],
+        "cros_board": "dedede",
+        "cros_img": "dedede-release/R107-15117.66.0",
+        "name": "lacros_all_tast_tests DEDEDE_RELEASE_BETA",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {},
+        "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)",
+        "test": "lacros_all_tast_tests",
+        "test_id_prefix": "ninja://chromeos/lacros:lacros_all_tast_tests/",
+        "timeout_sec": 10800,
+        "variant_id": "DEDEDE_RELEASE_BETA"
+      },
+      {
+        "args": [],
+        "cros_board": "dedede",
+        "cros_img": "dedede-release/R107-15117.86.0",
+        "name": "lacros_all_tast_tests DEDEDE_RELEASE_STABLE",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {},
+        "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)",
+        "test": "lacros_all_tast_tests",
+        "test_id_prefix": "ninja://chromeos/lacros:lacros_all_tast_tests/",
+        "timeout_sec": 10800,
+        "variant_id": "DEDEDE_RELEASE_STABLE"
+      },
+      {
+        "args": [],
         "cros_board": "eve",
         "cros_img": "eve-release/R109-15201.0.0",
         "name": "lacros_all_tast_tests EVE_RELEASE_LKGM",
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json
index 56ecf6c..e996d711 100644
--- a/testing/buildbot/chromium.android.json
+++ b/testing/buildbot/chromium.android.json
@@ -31396,7 +31396,7 @@
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 9
+          "shards": 27
         },
         "test": "webview_instrumentation_test_apk",
         "test_id_prefix": "ninja://android_webview/test:webview_instrumentation_test_apk/"
@@ -36047,7 +36047,8 @@
       {
         "args": [
           "--gs-results-bucket=chromium-result-details",
-          "--recover-devices"
+          "--recover-devices",
+          "--use-persistent-shell"
         ],
         "ci_only": true,
         "merge": {
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json
index 9a3ce1df..b55689f 100644
--- a/testing/buildbot/chromium.chromiumos.json
+++ b/testing/buildbot/chromium.chromiumos.json
@@ -3550,7 +3550,7 @@
           ],
           "quickrun_shards": 40,
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 20
+          "shards": 60
         },
         "test": "browser_tests",
         "test_id_prefix": "ninja://chrome/test:browser_tests/"
diff --git a/testing/buildbot/chromium.clang.json b/testing/buildbot/chromium.clang.json
index 425a96ee..329400e 100644
--- a/testing/buildbot/chromium.clang.json
+++ b/testing/buildbot/chromium.clang.json
@@ -8463,6 +8463,30 @@
         "test_id_prefix": "ninja://ui/compositor:compositor_unittests/"
       },
       {
+        "args": [
+          "--test-arg=--disable-gpu",
+          "--test-arg=--headless",
+          "--test-arg=--ozone-platform=headless"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-18.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 8
+        },
+        "test": "content_browsertests",
+        "test_id_prefix": "ninja://content/test:content_browsertests/"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -10043,6 +10067,31 @@
         "test_id_prefix": "ninja://ui/compositor:compositor_unittests/"
       },
       {
+        "args": [
+          "--test-arg=--disable-gpu",
+          "--test-arg=--headless",
+          "--test-arg=--ozone-platform=headless"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "cpu": "arm64",
+              "inside_docker": "1",
+              "os": "Ubuntu-20.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 8
+        },
+        "test": "content_browsertests",
+        "test_id_prefix": "ninja://content/test:content_browsertests/"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
diff --git a/testing/buildbot/chromium.fuchsia.fyi.json b/testing/buildbot/chromium.fuchsia.fyi.json
index 84de0f9..5618ddff 100644
--- a/testing/buildbot/chromium.fuchsia.fyi.json
+++ b/testing/buildbot/chromium.fuchsia.fyi.json
@@ -32,31 +32,6 @@
       },
       {
         "args": [
-          "--test-arg=--disable-gpu",
-          "--test-arg=--headless",
-          "--test-arg=--ozone-platform=headless"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "cpu": "arm64",
-              "inside_docker": "1",
-              "os": "Ubuntu-20.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 8
-        },
-        "test": "content_browsertests",
-        "test_id_prefix": "ninja://content/test:content_browsertests/"
-      },
-      {
-        "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.unit_tests.filter"
         ],
         "merge": {
@@ -450,6 +425,31 @@
         "test_id_prefix": "ninja://ui/compositor:compositor_unittests/"
       },
       {
+        "args": [
+          "--test-arg=--disable-gpu",
+          "--test-arg=--headless",
+          "--test-arg=--ozone-platform=headless"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "cpu": "arm64",
+              "inside_docker": "1",
+              "os": "Ubuntu-20.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 8
+        },
+        "test": "content_browsertests",
+        "test_id_prefix": "ninja://content/test:content_browsertests/"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -1612,6 +1612,30 @@
       },
       {
         "args": [
+          "--test-arg=--disable-gpu",
+          "--test-arg=--headless",
+          "--test-arg=--ozone-platform=headless"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-18.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 8
+        },
+        "test": "content_browsertests",
+        "test_id_prefix": "ninja://content/test:content_browsertests/"
+      },
+      {
+        "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.lsan.content_unittests.filter"
         ],
         "merge": {
@@ -2910,6 +2934,30 @@
         "test_id_prefix": "ninja://ui/compositor:compositor_unittests/"
       },
       {
+        "args": [
+          "--test-arg=--disable-gpu",
+          "--test-arg=--headless",
+          "--test-arg=--ozone-platform=headless"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-18.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 8
+        },
+        "test": "content_browsertests",
+        "test_id_prefix": "ninja://content/test:content_browsertests/"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -3858,30 +3906,6 @@
       },
       {
         "args": [
-          "--test-arg=--disable-gpu",
-          "--test-arg=--headless",
-          "--test-arg=--ozone-platform=headless"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "kvm": "1",
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 8
-        },
-        "test": "content_browsertests",
-        "test_id_prefix": "ninja://content/test:content_browsertests/"
-      },
-      {
-        "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.unit_tests.filter"
         ],
         "merge": {
@@ -4155,31 +4179,6 @@
       },
       {
         "args": [
-          "--test-arg=--disable-gpu",
-          "--test-arg=--headless",
-          "--test-arg=--ozone-platform=headless",
-          "--custom-image=workstation_eng.qemu-x64-release"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "kvm": "1",
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 8
-        },
-        "test": "content_browsertests",
-        "test_id_prefix": "ninja://content/test:content_browsertests/"
-      },
-      {
-        "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.unit_tests.filter",
           "--custom-image=workstation_eng.qemu-x64-release"
         ],
diff --git a/testing/buildbot/chromium.fuchsia.json b/testing/buildbot/chromium.fuchsia.json
index 24953b6a..59bc911 100644
--- a/testing/buildbot/chromium.fuchsia.json
+++ b/testing/buildbot/chromium.fuchsia.json
@@ -369,6 +369,31 @@
         "test_id_prefix": "ninja://ui/compositor:compositor_unittests/"
       },
       {
+        "args": [
+          "--test-arg=--disable-gpu",
+          "--test-arg=--headless",
+          "--test-arg=--ozone-platform=headless"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "cpu": "arm64",
+              "inside_docker": "1",
+              "os": "Ubuntu-20.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 14
+        },
+        "test": "content_browsertests",
+        "test_id_prefix": "ninja://content/test:content_browsertests/"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -1547,6 +1572,31 @@
         "test_id_prefix": "ninja://ui/compositor:compositor_unittests/"
       },
       {
+        "args": [
+          "--test-arg=--disable-gpu",
+          "--test-arg=--headless",
+          "--test-arg=--ozone-platform=headless"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "cpu": "arm64",
+              "inside_docker": "1",
+              "os": "Ubuntu-20.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 14
+        },
+        "test": "content_browsertests",
+        "test_id_prefix": "ninja://content/test:content_browsertests/"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -2725,6 +2775,31 @@
         "test_id_prefix": "ninja://ui/compositor:compositor_unittests/"
       },
       {
+        "args": [
+          "--test-arg=--disable-gpu",
+          "--test-arg=--headless",
+          "--test-arg=--ozone-platform=headless"
+        ],
+        "ci_only": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-18.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 41
+        },
+        "test": "content_browsertests",
+        "test_id_prefix": "ninja://content/test:content_browsertests/"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -4237,6 +4312,30 @@
         "test_id_prefix": "ninja://ui/compositor:compositor_unittests/"
       },
       {
+        "args": [
+          "--test-arg=--disable-gpu",
+          "--test-arg=--headless",
+          "--test-arg=--ozone-platform=headless"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-18.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 8
+        },
+        "test": "content_browsertests",
+        "test_id_prefix": "ninja://content/test:content_browsertests/"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index e0018cf..c1c2921 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -19383,6 +19383,33 @@
       },
       {
         "args": [
+          "--test-arg=--disable-gpu",
+          "--test-arg=--headless",
+          "--test-arg=--ozone-platform=headless",
+          "--ram-size-mb=16384",
+          "--code-coverage",
+          "--code-coverage-dir=${ISOLATED_OUTDIR}"
+        ],
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-18.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 8
+        },
+        "test": "content_browsertests",
+        "test_id_prefix": "ninja://content/test:content_browsertests/"
+      },
+      {
+        "args": [
           "--ram-size-mb=16384",
           "--code-coverage",
           "--code-coverage-dir=${ISOLATED_OUTDIR}"
@@ -20919,6 +20946,31 @@
         "test_id_prefix": "ninja://ui/compositor:compositor_unittests/"
       },
       {
+        "args": [
+          "--test-arg=--disable-gpu",
+          "--test-arg=--headless",
+          "--test-arg=--ozone-platform=headless"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "cpu": "arm64",
+              "inside_docker": "1",
+              "os": "Ubuntu-20.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 8
+        },
+        "test": "content_browsertests",
+        "test_id_prefix": "ninja://content/test:content_browsertests/"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -22225,6 +22277,30 @@
         "test_id_prefix": "ninja://ui/compositor:compositor_unittests/"
       },
       {
+        "args": [
+          "--test-arg=--disable-gpu",
+          "--test-arg=--headless",
+          "--test-arg=--ozone-platform=headless"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-18.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 8
+        },
+        "test": "content_browsertests",
+        "test_id_prefix": "ninja://content/test:content_browsertests/"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
diff --git a/testing/buildbot/chromium.mac.json b/testing/buildbot/chromium.mac.json
index 7ee3531..2a2fdbe8 100644
--- a/testing/buildbot/chromium.mac.json
+++ b/testing/buildbot/chromium.mac.json
@@ -8892,6 +8892,7 @@
               "os": "Mac-12"
             }
           ],
+          "inverse_quickrun_shards": 24,
           "quickrun_shards": 10,
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
           "shards": 12
@@ -8931,6 +8932,7 @@
               "os": "Mac-12"
             }
           ],
+          "inverse_quickrun_shards": 36,
           "quickrun_shards": 16,
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
           "shards": 18
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json
index 3ff3ee8..b5635148 100644
--- a/testing/buildbot/chromium.memory.json
+++ b/testing/buildbot/chromium.memory.json
@@ -1,1754 +1,6 @@
 {
   "AAAAA1 AUTOGENERATED FILE DO NOT EDIT": {},
   "AAAAA2 See generate_buildbot_json.py to make changes": {},
-  "Linux ASan LSan Low Symbols FYI Tests (1)": {
-    "gtest_tests": [
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "absl_hardening_tests",
-        "test_id_prefix": "ninja://third_party/abseil-cpp:absl_hardening_tests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "accessibility_unittests",
-        "test_id_prefix": "ninja://ui/accessibility:accessibility_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "angle_unittests",
-        "test_id_prefix": "ninja://third_party/angle/src/tests:angle_unittests/",
-        "use_isolated_scripts_api": true
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "app_shell_unittests",
-        "test_id_prefix": "ninja://extensions/shell:app_shell_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "aura_unittests",
-        "test_id_prefix": "ninja://ui/aura:aura_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "base_unittests",
-        "test_id_prefix": "ninja://base:base_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "blink_common_unittests",
-        "test_id_prefix": "ninja://third_party/blink/common:blink_common_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "blink_fuzzer_unittests",
-        "test_id_prefix": "ninja://third_party/blink/renderer/platform:blink_fuzzer_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "blink_heap_unittests",
-        "test_id_prefix": "ninja://third_party/blink/renderer/platform/heap:blink_heap_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "blink_platform_unittests",
-        "test_id_prefix": "ninja://third_party/blink/renderer/platform:blink_platform_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "name": "webkit_unit_tests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 5
-        },
-        "test": "blink_unittests",
-        "test_id_prefix": "ninja://third_party/blink/renderer/controller:blink_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "boringssl_crypto_tests",
-        "test_id_prefix": "ninja://third_party/boringssl:boringssl_crypto_tests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "boringssl_ssl_tests",
-        "test_id_prefix": "ninja://third_party/boringssl:boringssl_ssl_tests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "quickrun_shards": 80,
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 40
-        },
-        "test": "browser_tests",
-        "test_id_prefix": "ninja://chrome/test:browser_tests/"
-      },
-      {
-        "args": [
-          "--gtest_filter=-*UsingRealWebcam*",
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "capture_unittests",
-        "test_id_prefix": "ninja://media/capture:capture_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "cast_unittests",
-        "test_id_prefix": "ninja://media/cast:cast_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "cc_unittests",
-        "test_id_prefix": "ninja://cc:cc_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "chrome_app_unittests",
-        "test_id_prefix": "ninja://chrome/test:chrome_app_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "chromedriver_unittests",
-        "test_id_prefix": "ninja://chrome/test/chromedriver:chromedriver_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "color_unittests",
-        "test_id_prefix": "ninja://ui/color:color_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "components_browsertests",
-        "test_id_prefix": "ninja://components:components_browsertests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 5
-        },
-        "test": "components_unittests",
-        "test_id_prefix": "ninja://components:components_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "compositor_unittests",
-        "test_id_prefix": "ninja://ui/compositor:compositor_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "quickrun_shards": 24,
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 12
-        },
-        "test": "content_browsertests",
-        "test_id_prefix": "ninja://content/test:content_browsertests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 2
-        },
-        "test": "content_unittests",
-        "test_id_prefix": "ninja://content/test:content_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "crashpad_tests",
-        "test_id_prefix": "ninja://third_party/crashpad/crashpad:crashpad_tests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "cronet_tests",
-        "test_id_prefix": "ninja://components/cronet:cronet_tests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "cronet_unittests",
-        "test_id_prefix": "ninja://components/cronet:cronet_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "crypto_unittests",
-        "test_id_prefix": "ninja://crypto:crypto_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "dbus_unittests",
-        "test_id_prefix": "ninja://dbus:dbus_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "device_unittests",
-        "test_id_prefix": "ninja://device:device_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "display_unittests",
-        "test_id_prefix": "ninja://ui/display:display_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "events_unittests",
-        "test_id_prefix": "ninja://ui/events:events_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "extensions_browsertests",
-        "test_id_prefix": "ninja://extensions:extensions_browsertests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "extensions_unittests",
-        "test_id_prefix": "ninja://extensions:extensions_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "filesystem_service_unittests",
-        "test_id_prefix": "ninja://components/services/filesystem:filesystem_service_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "gcm_unit_tests",
-        "test_id_prefix": "ninja://google_apis/gcm:gcm_unit_tests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "gfx_unittests",
-        "test_id_prefix": "ninja://ui/gfx:gfx_unittests/"
-      },
-      {
-        "args": [
-          "--use-cmd-decoder=passthrough",
-          "--test-launcher-print-test-stdio=always",
-          "--use-gpu-in-tests",
-          "--no-xvfb"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "name": "gl_tests_passthrough",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:2184",
-              "os": "Ubuntu",
-              "pool": "chromium.tests.gpu"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 2
-        },
-        "test": "gl_tests",
-        "test_id_prefix": "ninja://gpu:gl_tests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "gl_unittests",
-        "test_id_prefix": "ninja://ui/gl:gl_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "google_apis_unittests",
-        "test_id_prefix": "ninja://google_apis:google_apis_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "gpu_unittests",
-        "test_id_prefix": "ninja://gpu:gpu_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "gwp_asan_unittests",
-        "test_id_prefix": "ninja://components/gwp_asan:gwp_asan_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "headless_browsertests",
-        "test_id_prefix": "ninja://headless:headless_browsertests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "headless_unittests",
-        "test_id_prefix": "ninja://headless:headless_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "quickrun_shards": 12,
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 6
-        },
-        "test": "interactive_ui_tests",
-        "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "ipc_tests",
-        "test_id_prefix": "ninja://ipc:ipc_tests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "latency_unittests",
-        "test_id_prefix": "ninja://ui/latency:latency_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "libjingle_xmpp_unittests",
-        "test_id_prefix": "ninja://third_party/libjingle_xmpp:libjingle_xmpp_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "liburlpattern_unittests",
-        "test_id_prefix": "ninja://third_party/liburlpattern:liburlpattern_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "media_unittests",
-        "test_id_prefix": "ninja://media:media_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "message_center_unittests",
-        "test_id_prefix": "ninja://ui/message_center:message_center_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "midi_unittests",
-        "test_id_prefix": "ninja://media/midi:midi_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "mojo_core_unittests",
-        "test_id_prefix": "ninja://mojo/core:mojo_core_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "mojo_unittests",
-        "test_id_prefix": "ninja://mojo:mojo_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "nacl_loader_unittests",
-        "test_id_prefix": "ninja://components/nacl/loader:nacl_loader_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "native_theme_unittests",
-        "test_id_prefix": "ninja://ui/native_theme:native_theme_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 16
-        },
-        "test": "net_unittests",
-        "test_id_prefix": "ninja://net:net_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "openscreen_unittests",
-        "test_id_prefix": "ninja://chrome/browser/media/router:openscreen_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "ozone_x11_unittests",
-        "test_id_prefix": "ninja://ui/ozone:ozone_x11_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "pdf_unittests",
-        "test_id_prefix": "ninja://pdf:pdf_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "perfetto_unittests",
-        "test_id_prefix": "ninja://third_party/perfetto:perfetto_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "ppapi_unittests",
-        "test_id_prefix": "ninja://ppapi:ppapi_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "printing_unittests",
-        "test_id_prefix": "ninja://printing:printing_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "remoting_unittests",
-        "test_id_prefix": "ninja://remoting:remoting_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "sandbox_linux_unittests",
-        "test_id_prefix": "ninja://sandbox/linux:sandbox_linux_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "service_manager_unittests",
-        "test_id_prefix": "ninja://services/service_manager/tests:service_manager_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "quickrun_shards": 2,
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "services_unittests",
-        "test_id_prefix": "ninja://services:services_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "shell_dialogs_unittests",
-        "test_id_prefix": "ninja://ui/shell_dialogs:shell_dialogs_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "skia_unittests",
-        "test_id_prefix": "ninja://skia:skia_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "snapshot_unittests",
-        "test_id_prefix": "ninja://ui/snapshot:snapshot_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "sql_unittests",
-        "test_id_prefix": "ninja://sql:sql_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "storage_unittests",
-        "test_id_prefix": "ninja://storage:storage_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 4
-        },
-        "test": "sync_integration_tests",
-        "test_id_prefix": "ninja://chrome/test:sync_integration_tests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "ui_base_unittests",
-        "test_id_prefix": "ninja://ui/base:ui_base_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "ui_touch_selection_unittests",
-        "test_id_prefix": "ninja://ui/touch_selection:ui_touch_selection_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 4
-        },
-        "test": "unit_tests",
-        "test_id_prefix": "ninja://chrome/test:unit_tests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "url_unittests",
-        "test_id_prefix": "ninja://url:url_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "views_unittests",
-        "test_id_prefix": "ninja://ui/views:views_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "viz_unittests",
-        "test_id_prefix": "ninja://components/viz:viz_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "vr_common_unittests",
-        "test_id_prefix": "ninja://chrome/browser/vr:vr_common_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "vr_pixeltests",
-        "test_id_prefix": "ninja://chrome/browser/vr:vr_pixeltests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "wm_unittests",
-        "test_id_prefix": "ninja://ui/wm:wm_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "wtf_unittests",
-        "test_id_prefix": "ninja://third_party/blink/renderer/platform/wtf:wtf_unittests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "name": "xr_browser_tests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "xr_browser_tests",
-        "test_id_prefix": "ninja://chrome/test:xr_browser_tests/"
-      },
-      {
-        "args": [
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "os": "Ubuntu-18.04"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "zlib_unittests",
-        "test_id_prefix": "ninja://third_party/zlib:zlib_unittests/"
-      }
-    ]
-  },
   "Linux ASan LSan Tests (1)": {
     "gtest_tests": [
       {
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl
index 69883bf7..42540cc6f 100644
--- a/testing/buildbot/gn_isolate_map.pyl
+++ b/testing/buildbot/gn_isolate_map.pyl
@@ -414,13 +414,6 @@
       "--logs-dir=${ISOLATED_OUTDIR}",
     ],
   },
-  "chrome_all_tast_tests_with_lacros": {
-    "label": "//chromeos:chrome_all_tast_tests_with_lacros",
-    "type": "generated_script",
-    "args": [
-      "--logs-dir=${ISOLATED_OUTDIR}",
-    ],
-  },
   "chrome_app_unittests": {
     "label": "//chrome/test:chrome_app_unittests",
     "type": "console_test_launcher",
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl
index c9f5e248..2d0a5de 100644
--- a/testing/buildbot/test_suite_exceptions.pyl
+++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -276,6 +276,7 @@
           ],
           'shards': 12,
           'quickrun_shards': 10,
+          'inverse_quickrun_shards': 24,
         },
       },
       'Mac12 Tests (dbg)': {
@@ -593,6 +594,7 @@
           ],
           'shards': 18,
           'quickrun_shards': 16,
+          'inverse_quickrun_shards': 36,
         },
       },
       'Mac12 Tests (dbg)': {
@@ -855,14 +857,6 @@
           'shards': 10,
         },
       },
-      'Linux ASan LSan Low Symbols FYI Tests (1)': {
-        # These are very slow on the ASAN trybot for some reason.
-        # crbug.com/1257927
-        'swarming': {
-          'shards': 40,
-          'quickrun_shards': 80
-        },
-      },
       'Linux ASan LSan Tests (1)': {
         'ci_only': True,
         # These are very slow on the ASAN trybot for some reason.
@@ -1050,7 +1044,7 @@
       },
       'linux-chromeos-rel': {
         'swarming': {
-          'shards': 20,
+          'shards': 60,
           'quickrun_shards': 40,
           'dimension_sets': [
             {
@@ -1219,16 +1213,6 @@
       'chromeos-octopus-chrome',
     ],
   },
-  'chrome_all_tast_tests_with_lacros': {
-    'modifications': {
-      'chromeos-eve-chrome': {
-        'swarming': {
-          # Increased timeout to 2 hours due to shard timeout.
-          'hard_timeout': 7200,
-        }
-      },
-    },
-  },
   'chrome_java_test_pagecontroller_tests': {
     'modifications': {
       'android-pie-arm64-rel': {
@@ -1530,13 +1514,6 @@
   },
   'components_unittests': {
     'modifications': {
-      'Linux ASan LSan Low Symbols FYI Tests (1)': {
-        # These are very slow on the ASAN trybot for some reason.
-        # crbug.com/1257927
-        'swarming': {
-          'shards': 5,
-        },
-      },
       'Linux ASan LSan Tests (1)': {
         # These are very slow on the ASAN trybot for some reason.
         # crbug.com/1257927
@@ -1600,12 +1577,6 @@
           '--test-launcher-filter-file=../../testing/buildbot/filters/cast-linux.content_browsertests.filter',
         ],
       },
-      'Linux ASan LSan Low Symbols FYI Tests (1)': {
-        'swarming': {
-          'shards': 12,
-          'quickrun_shards': 24,
-        },
-      },
       'Linux ASan LSan Tests (1)': {
         'swarming': {
           'shards': 12,
@@ -1749,6 +1720,24 @@
           'shards': 30,
         },
       },
+      'fuchsia-arm64-cast-receiver-rel': {
+        'swarming': {
+          'shards': 14,
+        },
+      },
+      'fuchsia-arm64-rel': {
+        'swarming': {
+          'shards': 14,
+        },
+      },
+      'fuchsia-x64-cast-receiver-rel': {
+        # Temporarily only run this on CI due to resource requirements.
+        # TODO(crbug.com/1374125): Remove this once resources are available.
+        'ci_only': True,
+        'swarming': {
+          'shards': 41,
+        },
+      },
       'linux-chromeos-code-coverage': {
         'swarming': {
           'shards': 12,
@@ -1862,13 +1851,6 @@
   },
   'content_unittests': {
     'modifications': {
-      'Linux ASan LSan Low Symbols FYI Tests (1)': {
-        # These are slow on the ASAN trybot for some reason.
-        # crbug.com/1257927
-        'swarming': {
-          'shards': 2,
-        },
-      },
       'Linux ASan LSan Tests (1)': {
         # These are slow on the ASAN trybot for some reason.
         # crbug.com/1257927
@@ -2078,7 +2060,6 @@
   'gin_unittests': {
     'remove_from': [
       'ToTLinuxASan',  # https://crbug.com/831667
-      'Linux ASan LSan Low Symbols FYI Tests (1)',  # https://crbug.com/831667
       'Linux ASan LSan Tests (1)',  # https://crbug.com/831667
       'Linux Chromium OS ASan LSan Tests (1)',  # https://crbug.com/831667
     ],
@@ -2105,21 +2086,6 @@
     'modifications': {
       # TODO(kbr): figure out a better way to specify blocks of
       # arguments like this for tests on multiple machines.
-      'Linux ASan LSan Low Symbols FYI Tests (1)': {
-        'args': [
-          '--use-gpu-in-tests',
-          '--no-xvfb',
-        ],
-        'swarming': {
-          'dimension_sets': [
-            {
-              'gpu': '10de:2184',
-              'os': 'Ubuntu',
-              'pool': 'chromium.tests.gpu',
-            },
-          ],
-        },
-      },
       'Linux ASan LSan Tests (1)': {
         'args': [
           '--use-gpu-in-tests',
@@ -2394,13 +2360,6 @@
           'shards': 3,
         },
       },
-      'Linux ASan LSan Low Symbols FYI Tests (1)': {
-        # These are slow on the ASan trybot for some reason, crbug.com/1257927
-        'swarming': {
-          'shards': 6,
-          'quickrun_shards': 12,
-        },
-      },
       'Linux ASan LSan Tests (1)': {
         # These are slow on the ASan trybot for some reason, crbug.com/1257927
         'swarming': {
@@ -2663,7 +2622,7 @@
     },
   },
   'mediapipe_validating_tests': {
-    'modifications': { 
+    'modifications': {
       # TODO(crbug.com/1372213): Remove once tests are stable.
       'fuchsia-x64-chrome-rel': {
         'experiment_percentage': 100,
@@ -2758,13 +2717,6 @@
           'shards': 16,
         },
       },
-      'Linux ASan LSan Low Symbols FYI Tests (1)': {
-        # These are very slow on the ASAN trybot for some reason.
-        # crbug.com/1257927
-        'swarming': {
-          'shards': 16,
-        },
-      },
       'Linux ASan LSan Tests (1)': {
         # These are very slow on the ASAN trybot for some reason.
         # crbug.com/1257927
@@ -3187,11 +3139,6 @@
       },
     },
     'modifications': {
-      'Linux ASan LSan Low Symbols FYI Tests (1)': {
-        'swarming': {
-          'quickrun_shards': 2,
-        },
-      },
       'Linux ASan LSan Tests (1)': {
         'swarming': {
           'quickrun_shards': 2,
@@ -3236,11 +3183,6 @@
       'CrWinAsan(dll)', # https://crbug.com/935598
     ],
     'modifications': {
-      'Linux ASan LSan Low Symbols FYI Tests (1)': {
-        'swarming': {
-          'shards': 4,
-        },
-      },
       'Linux ASan LSan Tests (1)': {
         'swarming': {
           'shards': 4,
@@ -3461,13 +3403,6 @@
       'android-pie-arm64-rel',  # https://crbug.com/1010211
     ],
     'modifications': {
-      'Linux ASan LSan Low Symbols FYI Tests (1)': {
-        # These are slow on the ASAN trybot for some reason.
-        # crbug.com/1257927
-        'swarming': {
-          'shards': 4,
-        },
-      },
       'Linux ASan LSan Tests (1)': {
         # These are slow on the ASAN trybot for some reason.
         # crbug.com/1257927
@@ -3944,13 +3879,6 @@
       'Win 7 Tests x64 (1)',
     ],
     'modifications': {
-      'Linux ASan LSan Low Symbols FYI Tests (1)': {
-        # These are very slow on the ASAN trybot for some reason.
-        # crbug.com/1257927
-        'swarming': {
-          'shards': 5,
-        },
-      },
       'Linux ASan LSan Tests (1)': {
         # These are very slow on the ASAN trybot for some reason.
         # crbug.com/1257927
@@ -4031,10 +3959,13 @@
       },
       'android-nougat-x86-rel': {
         'swarming': {
-          'shards': 9,
+          'shards': 27,
         },
       },
       'android-pie-arm64-rel': {
+        'args': [
+          '--use-persistent-shell',
+        ],
         'ci_only': True, # crbug/1368281
         'swarming': {
           'shards': 9,
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl
index 0625e8f..e60353f 100644
--- a/testing/buildbot/test_suites.pyl
+++ b/testing/buildbot/test_suites.pyl
@@ -647,22 +647,6 @@
       },
     },
 
-    # TODO(crbug.com/1306345): Merge this back to
-    # 'chromeos_browser_all_tast_tests'.
-    'chromeos_browser_all_tast_tests_with_lacros': {
-      'chrome_all_tast_tests_with_lacros': {
-        'swarming': {
-          'idempotent': False,  # https://crbug.com/923426#c27
-          # Tast test doesn't always output. See crbug.com/1306300
-          'io_timeout': 3600,
-          'shards': 10,
-        },
-        'mixins': [
-          'has_native_resultdb_integration',
-        ],
-      },
-    },
-
     'chromeos_browser_finch_tests': {
       'chrome_variations_tast_tests': {
         'swarming': {
@@ -2164,17 +2148,6 @@
           'shards': 40,
         },
       },
-      # TODO(crbug.com/1371630): Move to one of the fuchsia_common_gtests* sets.
-      'content_browsertests': {
-        'args': [
-          '--test-arg=--disable-gpu',
-          '--test-arg=--headless',
-          '--test-arg=--ozone-platform=headless',
-        ],
-        'swarming': {
-          'shards': 8,
-        },
-      },
       'unit_tests': {
         'args': [
           '--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.unit_tests.filter',
@@ -2220,6 +2193,16 @@
         },
       },
       'compositor_unittests': {},
+      'content_browsertests': {
+        'args': [
+          '--test-arg=--disable-gpu',
+          '--test-arg=--headless',
+          '--test-arg=--ozone-platform=headless',
+        ],
+        'swarming': {
+          'shards': 8,
+        },
+      },
       'content_unittests': {},
       'crypto_unittests': {},
       'events_unittests': {},
@@ -5658,12 +5641,6 @@
       'chromeos_device_only_gtests',
     ],
 
-    'chromeos_device_gtests_with_lacros': [
-      'chromeos_browser_all_tast_tests_with_lacros',
-      'chromeos_browser_integration_tests',
-      'chromeos_device_only_gtests',
-    ],
-
     'chromeos_device_no_gtests': [
       'chromeos_browser_all_tast_tests',
       'chromeos_browser_integration_tests',
@@ -7166,6 +7143,10 @@
     'lacros_skylab_tests_amd64_generic': {
       'lacros_skylab_tests': {
         'variants': [
+          'CROS_DEDEDE_RELEASE_LKGM',
+          'CROS_DEDEDE_RELEASE_DEV',
+          'CROS_DEDEDE_RELEASE_BETA',
+          'CROS_DEDEDE_RELEASE_STABLE',
           'CROS_EVE_RELEASE_LKGM',
           'CROS_EVE_RELEASE_DEV',
           'CROS_EVE_RELEASE_BETA',
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl
index 769f765..29b36b3 100644
--- a/testing/buildbot/variants.pyl
+++ b/testing/buildbot/variants.pyl
@@ -537,6 +537,42 @@
       '--test-apk-as-instant',
     ],
   },
+  'CROS_DEDEDE_RELEASE_LKGM': {
+    'skylab': {
+      'cros_board': 'dedede',
+      'cros_chrome_version': '109.0.5367.0',
+      'cros_img': 'dedede-release/R109-15201.0.0',
+    },
+    'enabled': True,
+    'identifier': 'DEDEDE_RELEASE_LKGM',
+  },
+  'CROS_DEDEDE_RELEASE_DEV': {
+    'skylab': {
+      'cros_board': 'dedede',
+      'cros_chrome_version': '108.0.5359.12',
+      'cros_img': 'dedede-release/R108-15183.14.0',
+    },
+    'enabled': True,
+    'identifier': 'DEDEDE_RELEASE_DEV',
+  },
+  'CROS_DEDEDE_RELEASE_BETA': {
+    'skylab': {
+      'cros_board': 'dedede',
+      'cros_chrome_version': '107.0.5304.51',
+      'cros_img': 'dedede-release/R107-15117.66.0',
+    },
+    'enabled': True,
+    'identifier': 'DEDEDE_RELEASE_BETA',
+  },
+  'CROS_DEDEDE_RELEASE_STABLE': {
+    'skylab': {
+      'cros_board': 'dedede',
+      'cros_chrome_version': '107.0.5304.92',
+      'cros_img': 'dedede-release/R107-15117.86.0',
+    },
+    'enabled': True,
+    'identifier': 'DEDEDE_RELEASE_STABLE',
+  },
   'CROS_EVE_RELEASE_LKGM': {
     'skylab': {
       'cros_board': 'eve',
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl
index b4bc97f..0890cef 100644
--- a/testing/buildbot/waterfalls.pyl
+++ b/testing/buildbot/waterfalls.pyl
@@ -98,7 +98,7 @@
           'chromiumos_preflight',
         ],
         'test_suites': {
-          'gtest_tests': 'chromeos_device_gtests_with_lacros',
+          'gtest_tests': 'chromeos_device_gtests',
         },
         'swarming': {
           'dimension_sets': [
@@ -5060,17 +5060,6 @@
     'name': 'chromium.memory',
     'mixins': ['chromium-tester-service-account'],
     'machines': {
-      'Linux ASan LSan Low Symbols FYI Tests (1)': {
-        'mixins': [
-          'linux-bionic',
-        ],
-        'test_suites': {
-          'gtest_tests': 'chromium_linux_and_gl_gtests',
-        },
-        'args': [
-          '--test-launcher-print-test-stdio=always',
-        ],
-      },
       'Linux ASan LSan Tests (1)': {
         'mixins': [
           'linux-bionic',
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index b30acac9..9d642bb 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -9356,6 +9356,21 @@
             ]
         }
     ],
+    "RemoveIOSPowerEventNotifications": [
+        {
+            "platforms": [
+                "ios"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "RemoveIOSPowerEventNotifications"
+                    ]
+                }
+            ]
+        }
+    ],
     "ReportCertificateErrors": [
         {
             "platforms": [
@@ -10364,21 +10379,6 @@
             ]
         }
     ],
-    "SmartLockBluetoothScreenOffFix": [
-        {
-            "platforms": [
-                "chromeos"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "SmartLockBluetoothScreenOffFix"
-                    ]
-                }
-            ]
-        }
-    ],
     "SnoozeIPH": [
         {
             "platforms": [
diff --git a/third_party/Python-Markdown/OWNERS b/third_party/Python-Markdown/OWNERS
new file mode 100644
index 0000000..68cf5bf
--- /dev/null
+++ b/third_party/Python-Markdown/OWNERS
@@ -0,0 +1 @@
+dpranke@google.com
diff --git a/third_party/blink/public/common/renderer_preferences/renderer_preferences.h b/third_party/blink/public/common/renderer_preferences/renderer_preferences.h
index 7c3017a..381bbed1 100644
--- a/third_party/blink/public/common/renderer_preferences/renderer_preferences.h
+++ b/third_party/blink/public/common/renderer_preferences/renderer_preferences.h
@@ -69,7 +69,7 @@
   int32_t arrow_bitmap_height_vertical_scroll_bar_in_dips{0};
   int32_t arrow_bitmap_width_horizontal_scroll_bar_in_dips{0};
 #endif
-#if defined(USE_OZONE)
+#if BUILDFLAG(IS_OZONE)
   bool selection_clipboard_buffer_available{false};
 #endif
   bool plugin_fullscreen_allowed{true};
diff --git a/third_party/blink/public/devtools_protocol/browser_protocol.pdl b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
index 687db8a..82b79708 100644
--- a/third_party/blink/public/devtools_protocol/browser_protocol.pdl
+++ b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
@@ -10493,6 +10493,20 @@
     returns
       AuthenticatorId authenticatorId
 
+  # Resets parameters isBogusSignature, isBadUV, isBadUP to false if they are not present.
+  command setResponseOverrideBits
+    parameters
+      AuthenticatorId authenticatorId
+      # If isBogusSignature is set, overrides the signature in the authenticator response to be zero.
+      # Defaults to false.
+      optional boolean isBogusSignature
+      # If isBadUV is set, overrides the UV bit in the flags in the authenticator response to
+      # be zero. Defaults to false.
+      optional boolean isBadUV
+      # If isBadUP is set, overrides the UP bit in the flags in the authenticator response to
+      # be zero. Defaults to false.
+      optional boolean isBadUP
+
   # Removes the given authenticator.
   command removeVirtualAuthenticator
     parameters
diff --git a/third_party/blink/public/platform/web_url_error.h b/third_party/blink/public/platform/web_url_error.h
index 6740b012..3087e47 100644
--- a/third_party/blink/public/platform/web_url_error.h
+++ b/third_party/blink/public/platform/web_url_error.h
@@ -39,6 +39,10 @@
 #include "third_party/blink/public/platform/web_common.h"
 #include "third_party/blink/public/platform/web_url.h"
 
+namespace network {
+struct URLLoaderCompletionStatus;
+}  // namespace network
+
 namespace blink {
 
 // TODO(yhirano): Change this to a class.
@@ -57,6 +61,9 @@
     kTrue,
   };
 
+  static WebURLError Create(const network::URLLoaderCompletionStatus&,
+                            const WebURL&);
+
   WebURLError() = delete;
   // |reason| must not be 0.
   WebURLError(int reason, const WebURL&);
diff --git a/third_party/blink/public/platform/web_url_loader.h b/third_party/blink/public/platform/web_url_loader.h
index 6ba4364..8141175 100644
--- a/third_party/blink/public/platform/web_url_loader.h
+++ b/third_party/blink/public/platform/web_url_loader.h
@@ -52,13 +52,12 @@
 namespace base {
 class SingleThreadTaskRunner;
 class WaitableEvent;
-}
+}  // namespace base
 
 namespace network {
 class SharedURLLoaderFactory;
 struct ResourceRequest;
-struct URLLoaderCompletionStatus;
-}
+}  // namespace network
 
 namespace blink {
 
@@ -93,15 +92,6 @@
   // The WebURLLoader may be deleted in a call to its client.
   virtual ~WebURLLoader();
 
-  static void PopulateURLResponse(const WebURL& url,
-                                  const network::mojom::URLResponseHead& head,
-                                  WebURLResponse* response,
-                                  bool report_security_info,
-                                  int request_id);
-  static WebURLError PopulateURLError(
-      const network::URLLoaderCompletionStatus& status,
-      const WebURL& url);
-
   // Load the request synchronously, returning results directly to the
   // caller upon completion.  There is no mechanism to interrupt a
   // synchronous load!!
diff --git a/third_party/blink/public/platform/web_url_response.h b/third_party/blink/public/platform/web_url_response.h
index d6e7657..894058b 100644
--- a/third_party/blink/public/platform/web_url_response.h
+++ b/third_party/blink/public/platform/web_url_response.h
@@ -51,6 +51,7 @@
 enum class FetchResponseSource;
 enum class FetchResponseType : int32_t;
 enum class IPAddressSpace : int32_t;
+class URLResponseHead;
 class LoadTimingInfo;
 }  // namespace mojom
 }  // namespace network
@@ -75,6 +76,11 @@
     kHTTPVersion_2_0
   };
 
+  static WebURLResponse Create(const WebURL& url,
+                               const network::mojom::URLResponseHead& head,
+                               bool report_security_info,
+                               int request_id);
+
   ~WebURLResponse();
 
   WebURLResponse();
diff --git a/third_party/blink/renderer/core/animation/css/css_animations.cc b/third_party/blink/renderer/core/animation/css/css_animations.cc
index 8b9fa73..80aad5d4 100644
--- a/third_party/blink/renderer/core/animation/css/css_animations.cc
+++ b/third_party/blink/renderer/core/animation/css/css_animations.cc
@@ -2257,6 +2257,8 @@
   switch (property.PropertyID()) {
     case CSSPropertyID::kAnimation:
     case CSSPropertyID::kAnimationDelay:
+    case CSSPropertyID::kAnimationDelayEnd:
+    case CSSPropertyID::kAnimationDelayStart:
     case CSSPropertyID::kAnimationDirection:
     case CSSPropertyID::kAnimationDuration:
     case CSSPropertyID::kAnimationFillMode:
diff --git a/third_party/blink/renderer/core/clipboard/system_clipboard.cc b/third_party/blink/renderer/core/clipboard/system_clipboard.cc
index 61075f7..859540c 100644
--- a/third_party/blink/renderer/core/clipboard/system_clipboard.cc
+++ b/third_party/blink/renderer/core/clipboard/system_clipboard.cc
@@ -63,10 +63,10 @@
   frame->GetBrowserInterfaceBroker().GetInterface(
       clipboard_.BindNewPipeAndPassReceiver(
           frame->GetTaskRunner(TaskType::kUserInteraction)));
-#if defined(USE_OZONE)
+#if BUILDFLAG(IS_OZONE)
   is_selection_buffer_available_ =
       frame->GetSettings()->GetSelectionClipboardBufferAvailable();
-#endif  // defined(USE_OZONE)
+#endif  // BUILDFLAG(IS_OZONE)
 }
 
 bool SystemClipboard::IsSelectionMode() const {
diff --git a/third_party/blink/renderer/core/css/css_value_keywords.json5 b/third_party/blink/renderer/core/css/css_value_keywords.json5
index 642e1726..f3f6209 100644
--- a/third_party/blink/renderer/core/css/css_value_keywords.json5
+++ b/third_party/blink/renderer/core/css/css_value_keywords.json5
@@ -1305,7 +1305,6 @@
     "longer",
     "decreasing",
     "increasing",
-    "specified",
 
     // For gradient interpolations in certain color spaces
     "in",
diff --git a/third_party/blink/renderer/core/css/properties/computed_style_utils.cc b/third_party/blink/renderer/core/css/properties/computed_style_utils.cc
index b67fb42e2..cd0387b 100644
--- a/third_party/blink/renderer/core/css/properties/computed_style_utils.cc
+++ b/third_party/blink/renderer/core/css/properties/computed_style_utils.cc
@@ -1745,9 +1745,9 @@
         delay.relative_offset * 100.0,
         CSSPrimitiveValue::UnitType::kPercentage));
   } else {
-    list->Append(
-        *CSSNumericLiteralValue::Create(delay.AsTimeValue().InSecondsF(),
-                                        CSSPrimitiveValue::UnitType::kSeconds));
+    return CSSNumericLiteralValue::Create(
+        delay.AsTimeValue().InSecondsF(),
+        CSSPrimitiveValue::UnitType::kSeconds);
   }
   return list;
 }
@@ -1765,14 +1765,14 @@
 CSSValue* ComputedStyleUtils::ValueForAnimationDelayStart(
     const CSSTimingData* timing_data) {
   if (!timing_data)
-    return ValueForTimingDelay(CSSTimingData::InitialDelayStart());
+    return ValueForTimingDelayList({CSSTimingData::InitialDelayStart()});
   return ValueForTimingDelayList(timing_data->DelayStartList());
 }
 
 CSSValue* ComputedStyleUtils::ValueForAnimationDelayEnd(
     const CSSTimingData* timing_data) {
   if (!timing_data)
-    return ValueForTimingDelay(CSSTimingData::InitialDelayEnd());
+    return ValueForTimingDelayList({CSSTimingData::InitialDelayEnd()});
   return ValueForTimingDelayList(timing_data->DelayEndList());
 }
 
diff --git a/third_party/blink/renderer/core/css/properties/computed_style_utils_test.cc b/third_party/blink/renderer/core/css/properties/computed_style_utils_test.cc
index bac32e1..673078e0 100644
--- a/third_party/blink/renderer/core/css/properties/computed_style_utils_test.cc
+++ b/third_party/blink/renderer/core/css/properties/computed_style_utils_test.cc
@@ -6,7 +6,9 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/renderer/core/css/css_custom_ident_value.h"
 #include "third_party/blink/renderer/core/css/css_identifier_value.h"
+#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h"
 #include "third_party/blink/renderer/core/css/css_string_value.h"
+#include "third_party/blink/renderer/core/css/css_value_list.h"
 #include "third_party/blink/renderer/core/style/style_name.h"
 #include "third_party/blink/renderer/core/style/style_name_or_keyword.h"
 #include "third_party/googletest/src/googletest/include/gtest/gtest.h"
@@ -67,4 +69,24 @@
             *MakeGarbageCollected<CSSIdentifierValue>(CSSValueID::kNone));
 }
 
+TEST(ComputedStyleUtilsTest, ValueForAnimationDelayWithNullptr) {
+  // Verify that ValueForAnimationDelayStart/End produces a CSSValue with
+  // canonical structure.
+  auto* expected = CSSValueList::CreateCommaSeparated();
+  expected->Append(*CSSNumericLiteralValue::Create(
+      0, CSSPrimitiveValue::UnitType::kSeconds));
+
+  auto* start =
+      DynamicTo<CSSValueList>(ComputedStyleUtils::ValueForAnimationDelayStart(
+          /* CSSTimingData */ nullptr));
+  ASSERT_TRUE(start);
+  EXPECT_EQ(*expected, *start);
+
+  auto* end =
+      DynamicTo<CSSValueList>(ComputedStyleUtils::ValueForAnimationDelayEnd(
+          /* CSSTimingData */ nullptr));
+  ASSERT_TRUE(end);
+  EXPECT_EQ(*expected, *end);
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc b/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc
index 82b88ab7..bf61225 100644
--- a/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc
+++ b/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc
@@ -1717,8 +1717,6 @@
         read_hue = Color::HueInterpolationMethod::kDecreasing;
       else if (ConsumeIdent<CSSValueID::kIncreasing>(args))
         read_hue = Color::HueInterpolationMethod::kIncreasing;
-      else if (ConsumeIdent<CSSValueID::kSpecified>(args))
-        read_hue = Color::HueInterpolationMethod::kSpecified;
       if (read_hue) {
         if (!ConsumeIdent<CSSValueID::kHue>(args))
           return false;
@@ -1744,7 +1742,8 @@
   CSSParserTokenRange args = ConsumeFunction(range);
   // First argument is the colorspace
   Color::ColorInterpolationSpace color_space;
-  Color::HueInterpolationMethod hue_interpolation_method;
+  Color::HueInterpolationMethod hue_interpolation_method =
+      Color::HueInterpolationMethod::kShorter;
   if (!ConsumeColorInterpolationSpace(args, color_space,
                                       hue_interpolation_method))
     return nullptr;
@@ -2645,7 +2644,8 @@
   // [ [ circle | ellipse] || <size-keyword> ]] ]
 
   Color::ColorInterpolationSpace color_space;
-  Color::HueInterpolationMethod hue_interpolation_method;
+  Color::HueInterpolationMethod hue_interpolation_method =
+      Color::HueInterpolationMethod::kShorter;
   bool has_color_space = ConsumeColorInterpolationSpace(
       args, color_space, hue_interpolation_method);
 
@@ -2748,7 +2748,8 @@
   // [ in <color-space>? || [ <angle> | to <side-or-corner> ]?]
   bool expect_comma = true;
   Color::ColorInterpolationSpace color_space;
-  Color::HueInterpolationMethod hue_interpolation_method;
+  Color::HueInterpolationMethod hue_interpolation_method =
+      Color::HueInterpolationMethod::kShorter;
   bool has_color_space = ConsumeColorInterpolationSpace(
       args, color_space, hue_interpolation_method);
 
@@ -2805,7 +2806,8 @@
                                       const CSSParserContext& context,
                                       cssvalue::CSSGradientRepeat repeating) {
   Color::ColorInterpolationSpace color_space;
-  Color::HueInterpolationMethod hue_interpolation_method;
+  Color::HueInterpolationMethod hue_interpolation_method =
+      Color::HueInterpolationMethod::kShorter;
   bool has_color_space = ConsumeColorInterpolationSpace(
       args, color_space, hue_interpolation_method);
 
diff --git a/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc b/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc
index f87d093..5096443 100644
--- a/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc
@@ -2012,6 +2012,17 @@
   EXPECT_EQ("15px", cascade.ComputedValue("width"));
 }
 
+TEST_F(StyleCascadeTest, SubstituteAnimationTaintedInAnimationDelay) {
+  TestCascade cascade(GetDocument());
+  cascade.Add(AnimationTaintedSet("--x", "1s"));
+  cascade.Add("animation-delay-start", "var(--x)");
+  cascade.Add("animation-delay-end", "var(--x)");
+  cascade.Apply();
+  EXPECT_EQ("1s", cascade.ComputedValue("--x"));
+  EXPECT_EQ("0s", cascade.ComputedValue("animation-delay-start"));
+  EXPECT_EQ("0s", cascade.ComputedValue("animation-delay-end"));
+}
+
 TEST_F(StyleCascadeTest, SubstituteAnimationTaintedInAnimationProperty) {
   TestCascade cascade(GetDocument());
   cascade.Add("--x", "20s");
diff --git a/third_party/blink/renderer/core/document_transition/document_transition_style_tracker.cc b/third_party/blink/renderer/core/document_transition/document_transition_style_tracker.cc
index d237ddb7..da049d3 100644
--- a/third_party/blink/renderer/core/document_transition/document_transition_style_tracker.cc
+++ b/third_party/blink/renderer/core/document_transition/document_transition_style_tracker.cc
@@ -102,6 +102,7 @@
     // opposed to the intersection between the clip-path and the border box
     // bounds. This seems suboptimal, but that's the rect that we use further
     // down the pipeline to generate the texture.
+    // TODO(khushalsagar): This doesn't account for CSS clip property.
     return PhysicalRect::EnclosingRect(*clip_path_bounds);
   }
 
@@ -117,7 +118,8 @@
   if (auto* layout_box = DynamicTo<LayoutBox>(&box)) {
     // Clip self painting descendant overflow by the overflow clip rect, then
     // add in the visual overflow from the own painting layer.
-    result.Intersect(layout_box->OverflowClipRect(PhysicalOffset()));
+    if (layout_box->ShouldClipOverflowAlongEitherAxis())
+      result.Intersect(layout_box->OverflowClipRect(PhysicalOffset()));
     result.Unite(layout_box->PhysicalVisualOverflowRectIncludingFilters());
   } else {
     // In this case we cannot clip children so just take the visual overflow
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 f891deeead..404f7a6 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -3392,10 +3392,10 @@
   GetSettings()->SetCaretBrowsingEnabled(
       renderer_preferences_.caret_browsing_enabled);
 
-#if defined(USE_OZONE)
+#if BUILDFLAG(IS_OZONE)
   GetSettings()->SetSelectionClipboardBufferAvailable(
       renderer_preferences_.selection_clipboard_buffer_available);
-#endif  // defined(USE_OZONE)
+#endif  // BUILDFLAG(IS_OZONE)
 
   SetExplicitlyAllowedPorts(
       renderer_preferences_.explicitly_allowed_network_ports);
diff --git a/third_party/blink/renderer/core/html/parser/html_construction_site.cc b/third_party/blink/renderer/core/html/parser/html_construction_site.cc
index 4ef035e..41d6f85 100644
--- a/third_party/blink/renderer/core/html/parser/html_construction_site.cc
+++ b/third_party/blink/renderer/core/html/parser/html_construction_site.cc
@@ -27,6 +27,7 @@
 #include "third_party/blink/renderer/core/html/parser/html_construction_site.h"
 
 #include <limits>
+
 #include "third_party/blink/renderer/core/dom/comment.h"
 #include "third_party/blink/renderer/core/dom/document_fragment.h"
 #include "third_party/blink/renderer/core/dom/document_type.h"
@@ -91,17 +92,21 @@
 }
 
 static bool HasImpliedEndTag(const HTMLStackItem* item) {
-  if (item->NamespaceURI() != html_names::xhtmlNamespaceURI)
-    return false;
-
-  auto tag = item->GetHTMLTag();
-  return tag == html_names::HTMLTag::kDd || tag == html_names::HTMLTag::kDt ||
-         tag == html_names::HTMLTag::kLi ||
-         tag == html_names::HTMLTag::kOption ||
-         tag == html_names::HTMLTag::kOptgroup ||
-         tag == html_names::HTMLTag::kP || tag == html_names::HTMLTag::kRb ||
-         tag == html_names::HTMLTag::kRp || tag == html_names::HTMLTag::kRt ||
-         tag == html_names::HTMLTag::kRTC;
+  switch (item->GetHTMLTag()) {
+    case html_names::HTMLTag::kDd:
+    case html_names::HTMLTag::kDt:
+    case html_names::HTMLTag::kLi:
+    case html_names::HTMLTag::kOption:
+    case html_names::HTMLTag::kOptgroup:
+    case html_names::HTMLTag::kP:
+    case html_names::HTMLTag::kRb:
+    case html_names::HTMLTag::kRp:
+    case html_names::HTMLTag::kRt:
+    case html_names::HTMLTag::kRTC:
+      return item->IsHTMLNamespace();
+    default:
+      return false;
+  }
 }
 
 static bool ShouldUseLengthLimit(const ContainerNode& node) {
@@ -274,12 +279,6 @@
   if (pending_text_.IsEmpty())
     return;
 
-  PendingText pending_text;
-  // Hold onto the current pending text on the stack so that queueTask doesn't
-  // recurse infinitely.
-  pending_text_.Swap(pending_text);
-  DCHECK(pending_text_.IsEmpty());
-
   // Splitting text nodes into smaller chunks contradicts HTML5 spec, but is
   // necessary for performance, see:
   // https://bugs.webkit.org/show_bug.cgi?id=55898
@@ -290,10 +289,10 @@
   absl::optional<unsigned> length_limit;
 
   unsigned current_position = 0;
-  const StringBuilder& string = pending_text.string_builder;
+  const StringBuilder& string = pending_text_.string_builder;
   while (current_position < string.length()) {
     unsigned proposed_break_index = NextTextBreakPositionForContainer(
-        *pending_text.parent, current_position, string.length(), length_limit);
+        *pending_text_.parent, current_position, string.length(), length_limit);
     unsigned break_index =
         FindBreakIndexBetween(string, current_position, proposed_break_index);
     DCHECK_LE(break_index, string.length());
@@ -306,8 +305,8 @@
         string.Substring(current_position, break_index - current_position);
     // Strings composed entirely of whitespace are likely to be repeated. Turn
     // them into AtomicString so we share a single string for each.
-    if (pending_text.whitespace_mode == kAllWhitespace ||
-        (pending_text.whitespace_mode == kWhitespaceUnknown &&
+    if (pending_text_.whitespace_mode == kAllWhitespace ||
+        (pending_text_.whitespace_mode == kWhitespaceUnknown &&
          IsAllWhitespace(substring))) {
       substring = AtomicString(substring).GetString();
     }
@@ -315,19 +314,21 @@
     DCHECK_GT(break_index, current_position);
     DCHECK_EQ(break_index - current_position, substring.length());
     HTMLConstructionSiteTask task(HTMLConstructionSiteTask::kInsertText);
-    task.parent = pending_text.parent;
-    task.next_child = pending_text.next_child;
+    task.parent = pending_text_.parent;
+    task.next_child = pending_text_.next_child;
     task.child = Text::Create(task.parent->GetDocument(), std::move(substring));
-    QueueTask(task);
+    QueueTask(task, false);
     DCHECK_EQ(To<Text>(task.child.Get())->length(),
               break_index - current_position);
     current_position = break_index;
   }
+  pending_text_.Discard();
 }
 
-void HTMLConstructionSite::QueueTask(const HTMLConstructionSiteTask& task) {
-  FlushPendingText();
-  DCHECK(pending_text_.IsEmpty());
+void HTMLConstructionSite::QueueTask(const HTMLConstructionSiteTask& task,
+                                     bool flush_pending_text) {
+  if (flush_pending_text)
+    FlushPendingText();
   task_queue_.push_back(task);
 }
 
@@ -357,7 +358,7 @@
     task.parent = task.parent->parentNode();
 
   DCHECK(task.parent);
-  QueueTask(task);
+  QueueTask(task, true);
 }
 
 void HTMLConstructionSite::ExecuteQueuedTasks() {
@@ -903,7 +904,7 @@
   HTMLConstructionSiteTask task(HTMLConstructionSiteTask::kReparent);
   task.parent = new_parent->GetNode();
   task.child = child->GetNode();
-  QueueTask(task);
+  QueueTask(task, true);
 }
 
 void HTMLConstructionSite::Reparent(HTMLElementStack::ElementRecord* new_parent,
@@ -911,7 +912,7 @@
   HTMLConstructionSiteTask task(HTMLConstructionSiteTask::kReparent);
   task.parent = new_parent->GetNode();
   task.child = child->GetNode();
-  QueueTask(task);
+  QueueTask(task, true);
 }
 
 void HTMLConstructionSite::InsertAlreadyParsedChild(
@@ -926,7 +927,7 @@
       HTMLConstructionSiteTask::kInsertAlreadyParsedChild);
   task.parent = new_parent->GetNode();
   task.child = child->GetNode();
-  QueueTask(task);
+  QueueTask(task, true);
 }
 
 void HTMLConstructionSite::TakeAllChildren(
@@ -935,7 +936,7 @@
   HTMLConstructionSiteTask task(HTMLConstructionSiteTask::kTakeAllChildren);
   task.parent = new_parent->GetNode();
   task.child = old_parent->GetNode();
-  QueueTask(task);
+  QueueTask(task, true);
 }
 
 CreateElementFlags HTMLConstructionSite::GetCreateElementFlags() const {
@@ -1242,7 +1243,7 @@
   FindFosterSite(task);
   task.child = node;
   DCHECK(task.parent);
-  QueueTask(task);
+  QueueTask(task, true);
 }
 
 void HTMLConstructionSite::PendingText::Trace(Visitor* visitor) const {
diff --git a/third_party/blink/renderer/core/html/parser/html_construction_site.h b/third_party/blink/renderer/core/html/parser/html_construction_site.h
index 3c8c1f7..aafc76b 100644
--- a/third_party/blink/renderer/core/html/parser/html_construction_site.h
+++ b/third_party/blink/renderer/core/html/parser/html_construction_site.h
@@ -259,7 +259,7 @@
   void MergeAttributesFromTokenIntoElement(AtomicHTMLToken*, Element*);
 
   void ExecuteTask(HTMLConstructionSiteTask&);
-  void QueueTask(const HTMLConstructionSiteTask&);
+  void QueueTask(const HTMLConstructionSiteTask&, bool flush_pending_text);
 
   CustomElementDefinition* LookUpCustomElementDefinition(
       Document&,
@@ -303,19 +303,14 @@
       whitespace_mode = std::min(whitespace_mode, new_whitespace_mode);
     }
 
-    void Swap(PendingText& other) {
-      std::swap(whitespace_mode, other.whitespace_mode);
-      parent.Swap(other.parent);
-      next_child.Swap(other.next_child);
-      string_builder.Swap(other.string_builder);
-    }
-
     void Discard() {
       if (IsEmpty())
         return;
 
-      PendingText discarded_text;
-      Swap(discarded_text);
+      parent.Clear();
+      next_child.Clear();
+      string_builder.Clear();
+      whitespace_mode = kWhitespaceUnknown;
     }
 
     bool IsEmpty() {
diff --git a/third_party/blink/renderer/core/paint/ng/ng_text_combine_painter.cc b/third_party/blink/renderer/core/paint/ng/ng_text_combine_painter.cc
index 14bc17da..a111d7e 100644
--- a/third_party/blink/renderer/core/paint/ng/ng_text_combine_painter.cc
+++ b/third_party/blink/renderer/core/paint/ng/ng_text_combine_painter.cc
@@ -105,10 +105,10 @@
 
   const NGTextDecorationOffset decoration_offset(style_, style_);
 
-  // Paint underline and overline text decorations
-  PaintUnderOrOverLineDecorations(NGTextFragmentPaintInfo{}, decoration_offset,
-                                  decoration_info, ~TextDecorationLine::kNone,
-                                  paint_info, text_style);
+  // Paint text decorations except line through
+  PaintDecorationsExceptLineThrough(
+      NGTextFragmentPaintInfo{}, decoration_offset, decoration_info,
+      ~TextDecorationLine::kNone, paint_info, text_style);
 
   // Paint line through if needed
   PaintDecorationsOnlyLineThrough(decoration_info, paint_info, text_style);
diff --git a/third_party/blink/renderer/core/paint/ng/ng_text_painter.cc b/third_party/blink/renderer/core/paint/ng/ng_text_painter.cc
index 897d917..61a51b5 100644
--- a/third_party/blink/renderer/core/paint/ng/ng_text_painter.cc
+++ b/third_party/blink/renderer/core/paint/ng/ng_text_painter.cc
@@ -285,7 +285,7 @@
                                          decoration_info, lines_to_paint,
                                          paint_info, text_style);
   } else {
-    NGTextPainterBase::PaintUnderOrOverLineDecorations(
+    NGTextPainterBase::PaintDecorationsExceptLineThrough(
         fragment_paint_info, decoration_offset, decoration_info, lines_to_paint,
         paint_info, text_style, nullptr);
   }
@@ -508,7 +508,7 @@
       if (SetupPaintForSvgText(state, graphics_context_, style_to_paint,
                                SvgPaintMode::kTextDecoration, *resource_mode,
                                flags)) {
-        NGTextPainterBase::PaintUnderOrOverLineDecorations(
+        NGTextPainterBase::PaintDecorationsExceptLineThrough(
             fragment_paint_info, decoration_offset, decoration_info,
             lines_to_paint, paint_info, text_style, &flags);
       }
diff --git a/third_party/blink/renderer/core/paint/ng/ng_text_painter_base.cc b/third_party/blink/renderer/core/paint/ng/ng_text_painter_base.cc
index afecde7..2066804d0 100644
--- a/third_party/blink/renderer/core/paint/ng/ng_text_painter_base.cc
+++ b/third_party/blink/renderer/core/paint/ng/ng_text_painter_base.cc
@@ -22,12 +22,12 @@
 
 namespace blink {
 
-// We have two functions to paint text decorations, because we should paint
+// We have two functions to paint text decoations, because we should paint
 // text and decorations in following order:
-//   1. Paint underline or overline text decorations
+//   1. Paint text decorations except line through
 //   2. Paint text
-//   3. Paint line through
-void NGTextPainterBase::PaintUnderOrOverLineDecorations(
+//   3. Paint line throguh
+void NGTextPainterBase::PaintDecorationsExceptLineThrough(
     const NGTextFragmentPaintInfo& fragment_paint_info,
     const TextDecorationOffsetBase& decoration_offset,
     TextDecorationInfo& decoration_info,
@@ -44,72 +44,8 @@
 
   GraphicsContext& context = paint_info.context;
   GraphicsContextStateSaver state_saver(context);
+  UpdateGraphicsContext(context, text_style, state_saver);
 
-  // Updating Graphics Context for text only (kTextProperOnly),
-  // instead of the default text and shadows (kBothShadowsAndTextProper),
-  // because shadows will be painted by
-  // NGTextPainterBase::PaintUnderOrOverLineDecorationShadows.
-  UpdateGraphicsContext(context, text_style, state_saver,
-                        ShadowMode::kTextProperOnly);
-
-  PaintUnderOrOverLineDecorationShadows(fragment_paint_info, decoration_offset,
-                                        decoration_info, lines_to_paint, flags,
-                                        text_style, context);
-
-  PaintUnderOrOverLineDecorations(fragment_paint_info, decoration_offset,
-                                  decoration_info, lines_to_paint, flags,
-                                  context);
-}
-
-void NGTextPainterBase::PaintUnderOrOverLineDecorationShadows(
-    const NGTextFragmentPaintInfo& fragment_paint_info,
-    const TextDecorationOffsetBase& decoration_offset,
-    TextDecorationInfo& decoration_info,
-    TextDecorationLine lines_to_paint,
-    const cc::PaintFlags* flags,
-    const TextPaintStyle& text_style,
-    GraphicsContext& context) {
-  if (text_style.shadow == nullptr)
-    return;
-
-  const ShadowList* shadow_list = text_style.shadow.get();
-  if (shadow_list == nullptr)
-    return;
-
-  for (const auto& shadow : shadow_list->Shadows()) {
-    const Color& color = shadow.GetColor().Resolve(text_style.current_color,
-                                                   text_style.color_scheme);
-    // Detect when there's no effective shadow.
-    if (color.IsTransparent())
-      continue;
-
-    const gfx::Vector2dF& offset = shadow.Location().OffsetFromOrigin();
-
-    float blur = shadow.Blur();
-    DCHECK_GE(blur, 0);
-    const auto sigma = BlurRadiusToStdDev(blur);
-
-    context.BeginLayer(
-        1.0f, SkBlendMode::kSrcOver, nullptr, kColorFilterNone,
-        sk_make_sp<DropShadowPaintFilter>(
-            offset.x(), offset.y(), sigma, sigma, color.toSkColor4f(),
-            DropShadowPaintFilter::ShadowMode::kDrawShadowOnly, nullptr));
-
-    PaintUnderOrOverLineDecorations(fragment_paint_info, decoration_offset,
-                                    decoration_info, lines_to_paint, flags,
-                                    context);
-
-    context.EndLayer();
-  }
-}
-
-void NGTextPainterBase::PaintUnderOrOverLineDecorations(
-    const NGTextFragmentPaintInfo& fragment_paint_info,
-    const TextDecorationOffsetBase& decoration_offset,
-    TextDecorationInfo& decoration_info,
-    TextDecorationLine lines_to_paint,
-    const cc::PaintFlags* flags,
-    GraphicsContext& context) {
   for (wtf_size_t i = 0; i < decoration_info.AppliedDecorationCount(); i++) {
     decoration_info.SetDecorationIndex(i);
     context.SetStrokeThickness(decoration_info.ResolvedThickness());
diff --git a/third_party/blink/renderer/core/paint/ng/ng_text_painter_base.h b/third_party/blink/renderer/core/paint/ng/ng_text_painter_base.h
index 5208b3e..3c13cb10 100644
--- a/third_party/blink/renderer/core/paint/ng/ng_text_painter_base.h
+++ b/third_party/blink/renderer/core/paint/ng/ng_text_painter_base.h
@@ -45,12 +45,12 @@
   ~NGTextPainterBase() = default;
 
  protected:
-  // We have two functions to paint text decorations, because we should paint
+  // We have two functions to paint text decoations, because we should paint
   // text and decorations in following order:
-  //   1. Paint underline or overline text decorations
+  //   1. Paint text decorations except line through
   //   2. Paint text
-  //   3. Paint line through text decoration
-  void PaintUnderOrOverLineDecorations(
+  //   3. Paint line through
+  void PaintDecorationsExceptLineThrough(
       const NGTextFragmentPaintInfo& fragment_paint_info,
       const TextDecorationOffsetBase& decoration_offset,
       TextDecorationInfo& decoration_info,
@@ -59,12 +59,6 @@
       const TextPaintStyle& text_style,
       const cc::PaintFlags* flags = nullptr);
 
-  virtual void ClipDecorationsStripe(const NGTextFragmentPaintInfo&,
-                                     float upper,
-                                     float stripe_width,
-                                     float dilation) = 0;
-
- private:
   void PaintDecorationUnderOrOverLine(
       const NGTextFragmentPaintInfo& fragment_paint_info,
       GraphicsContext& context,
@@ -72,22 +66,10 @@
       TextDecorationLine line,
       const cc::PaintFlags* flags = nullptr);
 
-  void PaintUnderOrOverLineDecorationShadows(
-      const NGTextFragmentPaintInfo& fragment_paint_info,
-      const TextDecorationOffsetBase& decoration_offset,
-      TextDecorationInfo& decoration_info,
-      TextDecorationLine lines_to_paint,
-      const cc::PaintFlags* flags,
-      const TextPaintStyle& text_style,
-      GraphicsContext& context);
-
-  void PaintUnderOrOverLineDecorations(
-      const NGTextFragmentPaintInfo& fragment_paint_info,
-      const TextDecorationOffsetBase& decoration_offset,
-      TextDecorationInfo& decoration_info,
-      TextDecorationLine lines_to_paint,
-      const cc::PaintFlags* flags,
-      GraphicsContext& context);
+  virtual void ClipDecorationsStripe(const NGTextFragmentPaintInfo&,
+                                     float upper,
+                                     float stripe_width,
+                                     float dilation) = 0;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/speculation_rules/document_rule_predicate.cc b/third_party/blink/renderer/core/speculation_rules/document_rule_predicate.cc
index 5a94325..c000c1c 100644
--- a/third_party/blink/renderer/core/speculation_rules/document_rule_predicate.cc
+++ b/third_party/blink/renderer/core/speculation_rules/document_rule_predicate.cc
@@ -5,7 +5,11 @@
 #include "third_party/blink/renderer/core/speculation_rules/document_rule_predicate.h"
 
 #include "base/containers/contains.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_urlpatterninit_usvstring.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_url_pattern_init.h"
+#include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/element.h"
+#include "third_party/blink/renderer/core/url_pattern/url_pattern.h"
 #include "third_party/blink/renderer/platform/heap/collection_support/heap_vector.h"
 #include "third_party/blink/renderer/platform/heap/member.h"
 #include "third_party/blink/renderer/platform/json/json_values.h"
@@ -139,9 +143,122 @@
 
 }  // namespace
 
+// Represents a document rule URL pattern predicate:
+// https://wicg.github.io/nav-speculation/speculation-rules.html#document-rule-url-pattern-predicate
+class URLPatternPredicate : public DocumentRulePredicate {
+ public:
+  explicit URLPatternPredicate(HeapVector<Member<URLPattern>> patterns)
+      : patterns_(std::move(patterns)) {}
+  ~URLPatternPredicate() override = default;
+
+  bool Matches(const Element& el) const override {
+    // Let href be the result of running el’s href getter steps.
+    const KURL href = el.HrefURL();
+    // For each pattern of predicate’s patterns:
+    for (const auto& pattern : patterns_) {
+      // Match given pattern and href. If the result is not null, return true.
+      if (pattern->test(/*script_state=*/nullptr,
+                        MakeGarbageCollected<V8URLPatternInput>(href),
+                        ASSERT_NO_EXCEPTION))
+        return true;
+    }
+    return false;
+  }
+
+  String ToString() const override {
+    StringBuilder builder;
+    builder.Append("Href([");
+    for (wtf_size_t i = 0; i < patterns_.size(); i++) {
+      builder.Append(patterns_[i]->ToString());
+      if (i != patterns_.size() - 1)
+        builder.Append(", ");
+    }
+    builder.Append("])");
+    return builder.ReleaseString();
+  }
+
+  Type GetTypeForTesting() const override { return Type::kURLPatterns; }
+
+  HeapVector<Member<URLPattern>> GetURLPatternsForTesting() const override {
+    return patterns_;
+  }
+
+  void Trace(Visitor* visitor) const override {
+    visitor->Trace(patterns_);
+    DocumentRulePredicate::Trace(visitor);
+  }
+
+ private:
+  HeapVector<Member<URLPattern>> patterns_;
+};
+
+namespace {
+URLPattern* ParseRawPattern(JSONValue* raw_pattern,
+                            const KURL& base_url,
+                            ExceptionState& exception_state) {
+  // If rawPattern is a string, then:
+  if (String raw_string; raw_pattern->AsString(&raw_string)) {
+    // Set pattern to the result of constructing a URLPattern using the
+    // URLPattern(input, baseURL) constructor steps given rawPattern and
+    // serializedBaseURL.
+    V8URLPatternInput* url_pattern_input =
+        MakeGarbageCollected<V8URLPatternInput>(raw_string);
+    return URLPattern::Create(url_pattern_input, base_url, exception_state);
+  }
+  // Otherwise, if rawPattern is a map
+  if (JSONObject* pattern_object = JSONObject::Cast(raw_pattern)) {
+    // Let init be «[ "baseURL" → serializedBaseURL ]», representing a
+    // dictionary of type URLPatternInit.
+    URLPatternInit* init = URLPatternInit::Create();
+    init->setBaseURL(base_url);
+
+    // For each key -> value of rawPattern:
+    for (wtf_size_t i = 0; i < pattern_object->size(); i++) {
+      JSONObject::Entry entry = pattern_object->at(i);
+      String key = entry.first;
+      String value;
+      // If value is not a string
+      if (!entry.second->AsString(&value))
+        return nullptr;
+
+      // Set init[key] to value.
+      if (key == "protocol")
+        init->setProtocol(value);
+      else if (key == "username")
+        init->setUsername(value);
+      else if (key == "password")
+        init->setPassword(value);
+      else if (key == "hostname")
+        init->setHostname(value);
+      else if (key == "port")
+        init->setPort(value);
+      else if (key == "pathname")
+        init->setPathname(value);
+      else if (key == "search")
+        init->setSearch(value);
+      else if (key == "hash")
+        init->setHash(value);
+      else if (key == "baseURL")
+        init->setBaseURL(value);
+      else
+        return nullptr;
+    }
+
+    // Set pattern to the result of constructing a URLPattern using the
+    // URLPattern(input, baseURL) constructor steps given init.
+    V8URLPatternInput* url_pattern_input =
+        MakeGarbageCollected<V8URLPatternInput>(init);
+    return URLPattern::Create(url_pattern_input, exception_state);
+  }
+  return nullptr;
+}
+}  // namespace
+
 // static
-DocumentRulePredicate* DocumentRulePredicate::Parse(JSONObject* input,
-                                                    const KURL& base_url) {
+DocumentRulePredicate* DocumentRulePredicate::Parse(
+    JSONObject* input,
+    const KURL& base_url,
+    ExceptionState& exception_state) {
   // If input is not a map, then return null.
   if (!input)
     return nullptr;
@@ -179,7 +296,8 @@
       JSONObject* raw_clause = JSONObject::Cast(raw_clauses->at(i));
       // Let clause be the result of parsing a document rule predicate given
       // rawClause and baseURL.
-      DocumentRulePredicate* clause = Parse(raw_clause, base_url);
+      DocumentRulePredicate* clause =
+          Parse(raw_clause, base_url, exception_state);
       // If clause is null, then return null.
       if (!clause)
         return nullptr;
@@ -204,7 +322,8 @@
 
     // Let clause be the result of parsing a document rule predicate given
     // rawClause and baseURL.
-    DocumentRulePredicate* clause = Parse(raw_clause, base_url);
+    DocumentRulePredicate* clause =
+        Parse(raw_clause, base_url, exception_state);
 
     // If clause is null, then return null.
     if (!clause)
@@ -216,8 +335,35 @@
 
   // If predicateType is "href_matches"
   if (predicate_type == "href_matches") {
-    // TODO(crbug.com/1371522): Implement this.
-    NOTIMPLEMENTED();
+    // Let rawPatterns be input["href_matches"].
+    Vector<JSONValue*> raw_patterns;
+    JSONArray* href_matches = input->GetArray("href_matches");
+    if (href_matches) {
+      for (wtf_size_t i = 0; i < href_matches->size(); i++) {
+        raw_patterns.push_back(href_matches->at(i));
+      }
+    } else {
+      // If rawPatterns is not a list, then set rawPatterns to « rawPatterns ».
+      raw_patterns.push_back(input->Get("href_matches"));
+    }
+    // Let patterns be an empty list.
+    HeapVector<Member<URLPattern>> patterns;
+    // For each rawPattern of rawPatterns:
+    for (JSONValue* raw_pattern : raw_patterns) {
+      URLPattern* pattern =
+          ParseRawPattern(raw_pattern, base_url, exception_state);
+      // If those steps throw, catch the exception and return null.
+      if (exception_state.HadException()) {
+        exception_state.ClearException();
+        return nullptr;
+      }
+      if (!pattern)
+        return nullptr;
+      // Append pattern to patterns.
+      patterns.push_back(pattern);
+    }
+    // Return a document rule URL pattern predicate whose patterns is patterns.
+    return MakeGarbageCollected<URLPatternPredicate>(std::move(patterns));
   }
 
   // If predicateType is "selector_matches"
@@ -241,6 +387,12 @@
   return {};
 }
 
+HeapVector<Member<URLPattern>> DocumentRulePredicate::GetURLPatternsForTesting()
+    const {
+  NOTREACHED();
+  return {};
+}
+
 void DocumentRulePredicate::Trace(Visitor*) const {}
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/speculation_rules/document_rule_predicate.h b/third_party/blink/renderer/core/speculation_rules/document_rule_predicate.h
index 3320c1d2..f940f37 100644
--- a/third_party/blink/renderer/core/speculation_rules/document_rule_predicate.h
+++ b/third_party/blink/renderer/core/speculation_rules/document_rule_predicate.h
@@ -14,8 +14,10 @@
 namespace blink {
 
 class Element;
+class ExceptionState;
 class JSONObject;
 class KURL;
+class URLPattern;
 
 class CORE_EXPORT DocumentRulePredicate
     : public GarbageCollected<DocumentRulePredicate> {
@@ -23,7 +25,9 @@
   DocumentRulePredicate() = default;
   virtual ~DocumentRulePredicate() = default;
 
-  static DocumentRulePredicate* Parse(JSONObject* input, const KURL& base_url);
+  static DocumentRulePredicate* Parse(JSONObject* input,
+                                      const KURL& base_url,
+                                      ExceptionState& exception_state);
   // Creates a predicate that matches with any link (i.e. Matches() below will
   // always returns true).
   static DocumentRulePredicate* MakeDefaultPredicate();
@@ -31,11 +35,12 @@
   virtual bool Matches(const Element& link) const = 0;
 
   // Methods for testing.
-  enum class Type { kAnd, kOr, kNot };
+  enum class Type { kAnd, kOr, kNot, kURLPatterns };
   virtual String ToString() const = 0;
   virtual Type GetTypeForTesting() const = 0;
   virtual HeapVector<Member<DocumentRulePredicate>> GetSubPredicatesForTesting()
       const;
+  virtual HeapVector<Member<URLPattern>> GetURLPatternsForTesting() const;
 
   virtual void Trace(Visitor*) const;
 };
diff --git a/third_party/blink/renderer/core/speculation_rules/speculation_rule_set.cc b/third_party/blink/renderer/core/speculation_rules/speculation_rule_set.cc
index 4636f966..dffd7a0 100644
--- a/third_party/blink/renderer/core/speculation_rules/speculation_rule_set.cc
+++ b/third_party/blink/renderer/core/speculation_rules/speculation_rule_set.cc
@@ -8,6 +8,7 @@
 #include "third_party/blink/public/mojom/speculation_rules/speculation_rules.mojom-blink.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/core/speculation_rules/document_rule_predicate.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/json/json_parser.h"
 #include "third_party/blink/renderer/platform/json/json_values.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
@@ -116,7 +117,8 @@
     // predicate given input["where"] and baseURL.
     else {
       document_rule_predicate =
-          DocumentRulePredicate::Parse(input->GetJSONObject("where"), base_url);
+          DocumentRulePredicate::Parse(input->GetJSONObject("where"), base_url,
+                                       IGNORE_EXCEPTION_FOR_TESTING);
     }
     if (!document_rule_predicate)
       return nullptr;
diff --git a/third_party/blink/renderer/core/speculation_rules/speculation_rule_set_test.cc b/third_party/blink/renderer/core/speculation_rules/speculation_rule_set_test.cc
index 08ede0d..73501f3 100644
--- a/third_party/blink/renderer/core/speculation_rules/speculation_rule_set_test.cc
+++ b/third_party/blink/renderer/core/speculation_rules/speculation_rule_set_test.cc
@@ -17,6 +17,7 @@
 #include "third_party/blink/public/common/browser_interface_broker_proxy.h"
 #include "third_party/blink/public/mojom/speculation_rules/speculation_rules.mojom-blink.h"
 #include "third_party/blink/public/web/blink.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_urlpatterninit_usvstring.h"
 #include "third_party/blink/renderer/core/execution_context/agent.h"
 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -31,6 +32,7 @@
 #include "third_party/blink/renderer/core/speculation_rules/stub_speculation_host.h"
 #include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
 #include "third_party/blink/renderer/core/testing/null_execution_context.h"
+#include "third_party/blink/renderer/core/url_pattern/url_pattern.h"
 #include "third_party/blink/renderer/platform/scheduler/public/event_loop.h"
 #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
 #include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
@@ -767,6 +769,8 @@
       return "Or";
     case DocumentRulePredicate::Type::kNot:
       return "Not";
+    case DocumentRulePredicate::Type::kURLPatterns:
+      return "Href";
   }
 }
 
@@ -844,6 +848,105 @@
       ConditionMatcher(DocumentRulePredicate::Type::kNot, {matcher}));
 }
 
+class HrefMatcher {
+ public:
+  explicit HrefMatcher(Vector<::testing::Matcher<URLPattern>> pattern_matchers)
+      : pattern_matchers_(std::move(pattern_matchers)) {}
+
+  bool MatchAndExplain(DocumentRulePredicate* predicate,
+                       ::testing::MatchResultListener* listener) const {
+    if (!predicate)
+      return false;
+    return MatchAndExplain(*predicate, listener);
+  }
+
+  bool MatchAndExplain(const DocumentRulePredicate& predicate,
+                       ::testing::MatchResultListener* listener) const {
+    if (predicate.GetTypeForTesting() !=
+            DocumentRulePredicate::Type::kURLPatterns ||
+        predicate.GetURLPatternsForTesting().size() !=
+            pattern_matchers_.size()) {
+      *listener << predicate.ToString();
+      return false;
+    }
+
+    auto patterns = predicate.GetURLPatternsForTesting();
+    ::testing::StringMatchResultListener inner_listener;
+    for (wtf_size_t i = 0; i < pattern_matchers_.size(); i++) {
+      if (!pattern_matchers_[i].MatchAndExplain(*patterns[i],
+                                                &inner_listener)) {
+        *listener << predicate.ToString();
+        return false;
+      }
+    }
+    return true;
+  }
+
+  void DescribeTo(::std::ostream* os) const {
+    *os << GetTypeString(DocumentRulePredicate::Type::kURLPatterns) << "([";
+    for (wtf_size_t i = 0; i < pattern_matchers_.size(); i++) {
+      pattern_matchers_[i].DescribeTo(os);
+      if (i != pattern_matchers_.size() - 1)
+        *os << ", ";
+    }
+    *os << "])";
+  }
+
+  void DescribeNegationTo(::std::ostream* os) const { DescribeTo(os); }
+
+ private:
+  Vector<::testing::Matcher<URLPattern>> pattern_matchers_;
+};
+
+auto Href(Vector<::testing::Matcher<URLPattern>> pattern_matchers = {}) {
+  return testing::MakePolymorphicMatcher(HrefMatcher(pattern_matchers));
+}
+
+class URLPatternMatcher {
+ public:
+  explicit URLPatternMatcher(String pattern, const KURL& base_url) {
+    auto* url_pattern_input = MakeGarbageCollected<V8URLPatternInput>(pattern);
+    url_pattern_ =
+        URLPattern::Create(url_pattern_input, base_url, ASSERT_NO_EXCEPTION);
+  }
+
+  bool MatchAndExplain(URLPattern* pattern,
+                       ::testing::MatchResultListener* listener) const {
+    if (!pattern)
+      return false;
+    return MatchAndExplain(*pattern, listener);
+  }
+
+  bool MatchAndExplain(const URLPattern& pattern,
+                       ::testing::MatchResultListener* listener) const {
+    using Component = V8URLPatternComponent::Enum;
+    Component components[] = {Component::kProtocol, Component::kUsername,
+                              Component::kPassword, Component::kHostname,
+                              Component::kPort,     Component::kPathname,
+                              Component::kSearch,   Component::kHash};
+    for (auto component : components) {
+      if (URLPattern::compareComponent(V8URLPatternComponent(component),
+                                       url_pattern_, &pattern) != 0) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  void DescribeTo(::std::ostream* os) const { *os << url_pattern_->ToString(); }
+
+  void DescribeNegationTo(::std::ostream* os) const { DescribeTo(os); }
+
+ private:
+  Persistent<URLPattern> url_pattern_;
+};
+
+auto URLPattern(String pattern,
+                const KURL& base_url = KURL("https://example.com/")) {
+  return ::testing::MakePolymorphicMatcher(
+      URLPatternMatcher(pattern, base_url));
+}
+
 class DocumentRulesTest : public SpeculationRuleSetTest {
  public:
   ~DocumentRulesTest() override = default;
@@ -919,6 +1022,68 @@
                           MatchesPredicate(Neg(Or({And(), Or()})))));
 }
 
+TEST_F(DocumentRulesTest, ParseHref) {
+  auto* rule_set = SpeculationRuleSet::Parse(
+      R"({
+        "prefetch": [{
+          "source": "document",
+          "where": {"href_matches": "/foo#bar"}
+        }, {
+          "source": "document",
+          "where": {"href_matches": {"pathname": "/foo"}}
+        }, {
+          "source": "document",
+          "where": {"href_matches": [
+            {"pathname": "/buzz"},
+            "/fizz",
+            {"hostname": "bar.com"}
+          ]}
+        }, {
+          "source": "document",
+          "where": {"or": [
+            {"href_matches": {"hostname": "foo.com"}},
+            {"not": {"href_matches": {"protocol": "http", "hostname": "*"}}}
+          ]}
+        }]
+      })",
+      KURL("https://example.com/"), execution_context());
+  EXPECT_THAT(
+      rule_set->prefetch_rules(),
+      ElementsAre(
+          MatchesPredicate(Href({URLPattern("/foo#bar")})),
+          MatchesPredicate(Href({URLPattern("/foo")})),
+          MatchesPredicate(Href({URLPattern("/buzz"), URLPattern("/fizz"),
+                                 URLPattern("https://bar.com")})),
+          MatchesPredicate(Or({Href({URLPattern("https://foo.com")}),
+                               Neg(Href({URLPattern("http://*")}))}))));
+}
+
+TEST_F(DocumentRulesTest, ParseHref_AllUrlPatternKeys) {
+  auto* href_matches = CreatePredicate(R"("href_matches": {
+    "username": "",
+    "password": "",
+    "port": "*",
+    "pathname": "/*",
+    "search": "*",
+    "hash": "",
+    "protocol": "https",
+    "hostname": "abc.xyz",
+    "baseURL": "https://example.com"
+  })");
+  EXPECT_THAT(href_matches, Href({URLPattern("https://abc.xyz:*/*\\?*")}));
+}
+
+TEST_F(DocumentRulesTest, HrefMatchesWithBaseURL) {
+  auto* without_base_specified = CreatePredicate(
+      R"("href_matches": {"pathname": "/hello"})", KURL("http://foo.com"));
+  EXPECT_THAT(without_base_specified,
+              Href({URLPattern("http://foo.com/hello")}));
+  auto* with_base_specified = CreatePredicate(
+      R"("href_matches": {"pathname": "hello", "baseURL": "http://bar.com"})",
+      KURL("http://foo.com"));
+  EXPECT_THAT(with_base_specified, Href({URLPattern("http://bar.com/hello")}));
+}
+
 TEST_F(DocumentRulesTest, DropInvalidRules) {
   auto* rule_set = SpeculationRuleSet::Parse(
       R"({"prefetch": [)"
@@ -963,14 +1128,32 @@
       // "not" key has invalid object value.
       R"({"source": "document", "where": {"not": {"foo": "bar"}}},)"
 
+      // pattern is not a string or map value.
+      R"({"source": "document", "where": {"href_matches": false}},)"
+
+      // pattern string is invalid.
+      R"({"source": "document", "where": {"href_matches": "::"}},)"
+
+      // pattern object has invalid key.
+      R"({"source": "document", "where": {"href_matches": {"foo": "bar"}}},)"
+
+      // pattern object has invalid value.
+      R"({"source": "document",
+          "where": {"href_matches": {"protocol": "::"}}},)"
+
       // valid document rule.
       R"({"source": "document",
-          "where": {"and": [{"or": []}, {"not": {"and": []}}]}
+          "where": {"and": [
+            {"or": [{"href_matches": "/hello.html"}]},
+            {"not": {"and": [{"href_matches": {"hostname": "world.com"}}]}}
+          ]}
          }]})",
       KURL("https://example.com/"), execution_context());
   ASSERT_TRUE(rule_set);
   EXPECT_THAT(rule_set->prefetch_rules(),
-              ElementsAre(MatchesPredicate(And({Or(), Neg(And())}))));
+              ElementsAre(MatchesPredicate(
+                  And({Or({Href({URLPattern("/hello.html")})}),
+                       Neg(And({Href({URLPattern("https://world.com")})}))}))));
 }
 
 TEST_F(DocumentRulesTest, DefaultPredicate) {
@@ -1036,5 +1219,32 @@
   EXPECT_TRUE(not_false->Matches(*link));
 }
 
+TEST_F(DocumentRulesTest, EvaluateHrefMatches) {
+  DummyPageHolder page_holder;
+  Document& document = page_holder.GetDocument();
+  HTMLAnchorElement* link = MakeGarbageCollected<HTMLAnchorElement>(document);
+  link->setHref("https://foo.com/bar.html?fizz=buzz");
+
+  // No patterns specified, will not match any link.
+  auto* empty = CreatePredicate(R"("href_matches": [])");
+  EXPECT_FALSE(empty->Matches(*link));
+
+  // Single pattern (should match).
+  auto* single =
+      CreatePredicate(R"("href_matches": "https://foo.com/bar.html?*")");
+  EXPECT_TRUE(single->Matches(*link));
+
+  // Two patterns which don't match.
+  auto* double_fail = CreatePredicate(
+      R"("href_matches": ["http://foo.com/*", "https://bar.com/*"])");
+  EXPECT_FALSE(double_fail->Matches(*link));
+
+  // One pattern that matches, one that doesn't - should still pass due to
+  // an implicit or between patterns in a href_matches list.
+  auto* pass_fail = CreatePredicate(
+      R"("href_matches": ["https://foo.com/bar.html?*", "https://bar.com/*"])");
+  EXPECT_TRUE(pass_fail->Matches(*link));
+}
+
 }  // namespace
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/url_pattern/url_pattern.cc b/third_party/blink/renderer/core/url_pattern/url_pattern.cc
index a864f4c1..f2dce41 100644
--- a/third_party/blink/renderer/core/url_pattern/url_pattern.cc
+++ b/third_party/blink/renderer/core/url_pattern/url_pattern.cc
@@ -18,6 +18,7 @@
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/weborigin/kurl.h"
 #include "third_party/blink/renderer/platform/weborigin/security_origin.h"
+#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
 #include "third_party/blink/renderer/platform/wtf/text/string_to_number.h"
 #include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -477,6 +478,20 @@
   NOTREACHED();
 }
 
+String URLPattern::ToString() const {
+  StringBuilder builder;
+  builder.Append("(");
+  Vector<String> components = {protocol(), username(), password(), hostname(),
+                               port(),     pathname(), search(),   hash()};
+  for (wtf_size_t i = 0; i < components.size(); i++) {
+    builder.Append(components[i] == g_empty_string ? " " : components[i]);
+    if (i != components.size() - 1)
+      builder.Append(",");
+  }
+  builder.Append(")");
+  return builder.ReleaseString();
+}
+
 void URLPattern::Trace(Visitor* visitor) const {
   visitor->Trace(protocol_);
   visitor->Trace(username_);
diff --git a/third_party/blink/renderer/core/url_pattern/url_pattern.h b/third_party/blink/renderer/core/url_pattern/url_pattern.h
index e7ac7bc..98bb973 100644
--- a/third_party/blink/renderer/core/url_pattern/url_pattern.h
+++ b/third_party/blink/renderer/core/url_pattern/url_pattern.h
@@ -88,6 +88,9 @@
                               const URLPattern* left,
                               const URLPattern* right);
 
+  // Used for testing and debugging.
+  String ToString() const;
+
   void Trace(Visitor* visitor) const override;
 
  private:
diff --git a/third_party/blink/renderer/modules/service_worker/navigation_preload_request.cc b/third_party/blink/renderer/modules/service_worker/navigation_preload_request.cc
index b01e263..23c4e6bb 100644
--- a/third_party/blink/renderer/modules/service_worker/navigation_preload_request.cc
+++ b/third_party/blink/renderer/modules/service_worker/navigation_preload_request.cc
@@ -10,7 +10,6 @@
 #include "services/network/public/mojom/early_hints.mojom.h"
 #include "services/network/public/mojom/url_response_head.mojom.h"
 #include "third_party/blink/public/mojom/service_worker/service_worker_error_type.mojom-blink.h"
-#include "third_party/blink/public/platform/web_url_loader.h"
 #include "third_party/blink/public/web/modules/service_worker/web_service_worker_context_client.h"
 
 namespace blink {
@@ -52,8 +51,8 @@
   response_ = std::make_unique<WebURLResponse>();
   // TODO(horo): Set report_security_info to true when DevTools is attached.
   const bool report_security_info = false;
-  WebURLLoader::PopulateURLResponse(url_, *response_head, response_.get(),
-                                    report_security_info, -1 /* request_id */);
+  *response_ = WebURLResponse::Create(
+      url_, *response_head, report_security_info, -1 /* request_id */);
   body_ = std::move(body);
   MaybeReportResponseToOwner();
 }
@@ -66,9 +65,9 @@
       response_head->headers->response_code()));
 
   response_ = std::make_unique<WebURLResponse>();
-  WebURLLoader::PopulateURLResponse(url_, *response_head, response_.get(),
-                                    false /* report_security_info */,
-                                    -1 /* request_id */);
+  *response_ = WebURLResponse::Create(url_, *response_head,
+                                      false /* report_security_info */,
+                                      -1 /* request_id */);
   owner_->OnNavigationPreloadResponse(fetch_event_id_, std::move(response_),
                                       mojo::ScopedDataPipeConsumerHandle());
   // This will delete |this|.
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_supported_limits.cc b/third_party/blink/renderer/modules/webgpu/gpu_supported_limits.cc
index 66fd678..0a775ea 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_supported_limits.cc
+++ b/third_party/blink/renderer/modules/webgpu/gpu_supported_limits.cc
@@ -15,6 +15,7 @@
   X(maxTextureDimension3D)                     \
   X(maxTextureArrayLayers)                     \
   X(maxBindGroups)                             \
+  X(maxBindingsPerBindGroup)                   \
   X(maxDynamicUniformBuffersPerPipelineLayout) \
   X(maxDynamicStorageBuffersPerPipelineLayout) \
   X(maxSampledTexturesPerShaderStage)          \
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_supported_limits.h b/third_party/blink/renderer/modules/webgpu/gpu_supported_limits.h
index 116419d..d31b862d 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_supported_limits.h
+++ b/third_party/blink/renderer/modules/webgpu/gpu_supported_limits.h
@@ -34,6 +34,7 @@
   unsigned maxTextureDimension3D() const;
   unsigned maxTextureArrayLayers() const;
   unsigned maxBindGroups() const;
+  unsigned maxBindingsPerBindGroup() const;
   unsigned maxDynamicUniformBuffersPerPipelineLayout() const;
   unsigned maxDynamicStorageBuffersPerPipelineLayout() const;
   unsigned maxSampledTexturesPerShaderStage() const;
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_supported_limits.idl b/third_party/blink/renderer/modules/webgpu/gpu_supported_limits.idl
index fb6a1e6..9273415 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_supported_limits.idl
+++ b/third_party/blink/renderer/modules/webgpu/gpu_supported_limits.idl
@@ -13,6 +13,7 @@
     readonly attribute unsigned long maxTextureDimension3D;
     readonly attribute unsigned long maxTextureArrayLayers;
     readonly attribute unsigned long maxBindGroups;
+    readonly attribute unsigned long maxBindingsPerBindGroup;
     readonly attribute unsigned long maxDynamicUniformBuffersPerPipelineLayout;
     readonly attribute unsigned long maxDynamicStorageBuffersPerPipelineLayout;
     readonly attribute unsigned long maxSampledTexturesPerShaderStage;
diff --git a/third_party/blink/renderer/platform/exported/web_url_error.cc b/third_party/blink/renderer/platform/exported/web_url_error.cc
index a7200566..c5a6bf9 100644
--- a/third_party/blink/renderer/platform/exported/web_url_error.cc
+++ b/third_party/blink/renderer/platform/exported/web_url_error.cc
@@ -5,10 +5,48 @@
 #include "third_party/blink/public/platform/web_url_error.h"
 
 #include "net/base/net_errors.h"
+#include "services/network/public/cpp/url_loader_completion_status.h"
 #include "services/network/public/mojom/trust_tokens.mojom-shared.h"
 
 namespace blink {
 
+// static
+WebURLError WebURLError::Create(
+    const network::URLLoaderCompletionStatus& status,
+    const WebURL& url) {
+  DCHECK_NE(net::OK, status.error_code);
+  const WebURLError::HasCopyInCache has_copy_in_cache =
+      status.exists_in_cache ? WebURLError::HasCopyInCache::kTrue
+                             : WebURLError::HasCopyInCache::kFalse;
+  if (status.cors_error_status)
+    return WebURLError(*status.cors_error_status, has_copy_in_cache, url);
+  if (status.blocked_by_response_reason) {
+    DCHECK_EQ(net::ERR_BLOCKED_BY_RESPONSE, status.error_code);
+    return WebURLError(*status.blocked_by_response_reason,
+                       status.resolve_error_info, has_copy_in_cache, url);
+  }
+
+  if (status.trust_token_operation_status !=
+      network::mojom::TrustTokenOperationStatus::kOk) {
+    DCHECK(status.error_code ==
+               net::ERR_TRUST_TOKEN_OPERATION_SUCCESS_WITHOUT_SENDING_REQUEST ||
+           status.error_code == net::ERR_TRUST_TOKEN_OPERATION_FAILED)
+        << "Unexpected error code on Trust Token operation failure (or cache "
+           "hit): "
+        << status.error_code;
+
+    return WebURLError(status.error_code, status.trust_token_operation_status,
+                       url);
+  }
+
+  return WebURLError(status.error_code, status.extended_error_code,
+                     status.resolve_error_info, has_copy_in_cache,
+                     WebURLError::IsWebSecurityViolation::kFalse, url,
+                     status.should_collapse_initiator
+                         ? WebURLError::ShouldCollapseInitiator::kTrue
+                         : WebURLError::ShouldCollapseInitiator::kFalse);
+}
+
 WebURLError::WebURLError(int reason, const WebURL& url)
     : reason_(reason), url_(url) {
   DCHECK_NE(reason_, 0);
diff --git a/third_party/blink/renderer/platform/exported/web_url_response.cc b/third_party/blink/renderer/platform/exported/web_url_response.cc
index 68507d8..91024fc 100644
--- a/third_party/blink/renderer/platform/exported/web_url_response.cc
+++ b/third_party/blink/renderer/platform/exported/web_url_response.cc
@@ -37,8 +37,10 @@
 #include "base/memory/ptr_util.h"
 #include "base/memory/scoped_refptr.h"
 #include "net/ssl/ssl_info.h"
+#include "services/network/public/cpp/is_potentially_trustworthy.h"
 #include "services/network/public/mojom/ip_address_space.mojom-shared.h"
 #include "services/network/public/mojom/load_timing_info.mojom.h"
+#include "services/network/public/mojom/url_response_head.mojom.h"
 #include "third_party/blink/public/platform/web_http_header_visitor.h"
 #include "third_party/blink/public/platform/web_string.h"
 #include "third_party/blink/public/platform/web_url.h"
@@ -48,6 +50,200 @@
 
 namespace blink {
 
+namespace {
+
+// Converts timing data from |load_timing| to the mojo type.
+// TODO:(https://crbug.com/1379780): Consider removing unnecessary type
+// conversions.
+network::mojom::LoadTimingInfo ToMojoLoadTiming(
+    const net::LoadTimingInfo& load_timing) {
+  DCHECK(!load_timing.request_start.is_null());
+
+  return network::mojom::LoadTimingInfo(
+      load_timing.socket_reused, load_timing.socket_log_id,
+      load_timing.request_start_time, load_timing.request_start,
+      load_timing.proxy_resolve_start, load_timing.proxy_resolve_end,
+      load_timing.connect_timing, load_timing.send_start, load_timing.send_end,
+      load_timing.receive_headers_start, load_timing.receive_headers_end,
+      load_timing.receive_non_informational_headers_start,
+      load_timing.first_early_hints_time, load_timing.push_start,
+      load_timing.push_end, load_timing.service_worker_start_time,
+      load_timing.service_worker_ready_time,
+      load_timing.service_worker_fetch_start,
+      load_timing.service_worker_respond_with_settled);
+}
+
+// TODO(https://crbug.com/862940): Use KURL here.
+void SetSecurityStyleAndDetails(const GURL& url,
+                                const network::mojom::URLResponseHead& head,
+                                WebURLResponse* response,
+                                bool report_security_info) {
+  if (!report_security_info) {
+    response->SetSecurityStyle(SecurityStyle::kUnknown);
+    return;
+  }
+  if (!url.SchemeIsCryptographic()) {
+    // Some origins are considered secure even though they're not cryptographic,
+    // so treat them as secure in the UI.
+    if (network::IsUrlPotentiallyTrustworthy(url))
+      response->SetSecurityStyle(SecurityStyle::kSecure);
+    else
+      response->SetSecurityStyle(SecurityStyle::kInsecure);
+    return;
+  }
+
+  // The resource loader does not provide a guarantee that requests always have
+  // security info (such as a certificate) attached. Use SecurityStyleUnknown
+  // in this case where there isn't enough information to be useful.
+  if (!head.ssl_info.has_value()) {
+    response->SetSecurityStyle(SecurityStyle::kUnknown);
+    return;
+  }
+
+  const net::SSLInfo& ssl_info = *head.ssl_info;
+  if (net::IsCertStatusError(head.cert_status)) {
+    response->SetSecurityStyle(SecurityStyle::kInsecure);
+  } else {
+    response->SetSecurityStyle(SecurityStyle::kSecure);
+  }
+
+  if (!ssl_info.cert) {
+    NOTREACHED();
+    response->SetSecurityStyle(SecurityStyle::kUnknown);
+    return;
+  }
+
+  response->SetSSLInfo(ssl_info);
+}
+
+}  // namespace
+
+// static
+WebURLResponse WebURLResponse::Create(
+    const WebURL& url,
+    const network::mojom::URLResponseHead& head,
+    bool report_security_info,
+    int request_id) {
+  WebURLResponse response;
+
+  response.SetCurrentRequestUrl(url);
+  response.SetResponseTime(head.response_time);
+  response.SetMimeType(WebString::FromUTF8(head.mime_type));
+  response.SetTextEncodingName(WebString::FromUTF8(head.charset));
+  response.SetExpectedContentLength(head.content_length);
+  response.SetHasMajorCertificateErrors(
+      net::IsCertStatusError(head.cert_status));
+  response.SetIsLegacyTLSVersion(head.is_legacy_tls_version);
+  response.SetHasRangeRequested(head.has_range_requested);
+  response.SetTimingAllowPassed(head.timing_allow_passed);
+  response.SetWasCached(!head.load_timing.request_start_time.is_null() &&
+                        head.response_time <
+                            head.load_timing.request_start_time);
+  response.SetConnectionID(head.load_timing.socket_log_id);
+  response.SetConnectionReused(head.load_timing.socket_reused);
+  response.SetWasFetchedViaSPDY(head.was_fetched_via_spdy);
+  response.SetWasFetchedViaServiceWorker(head.was_fetched_via_service_worker);
+  response.SetServiceWorkerResponseSource(head.service_worker_response_source);
+  response.SetType(head.response_type);
+  response.SetPadding(head.padding);
+  WebVector<KURL> url_list_via_service_worker(
+      head.url_list_via_service_worker.size());
+  std::transform(head.url_list_via_service_worker.begin(),
+                 head.url_list_via_service_worker.end(),
+                 url_list_via_service_worker.begin(),
+                 [](const GURL& h) { return KURL(h); });
+  response.SetUrlListViaServiceWorker(url_list_via_service_worker);
+  response.SetCacheStorageCacheName(
+      head.service_worker_response_source ==
+              network::mojom::FetchResponseSource::kCacheStorage
+          ? WebString::FromUTF8(head.cache_storage_cache_name)
+          : WebString());
+
+  WebVector<WebString> dns_aliases(head.dns_aliases.size());
+  std::transform(head.dns_aliases.begin(), head.dns_aliases.end(),
+                 dns_aliases.begin(),
+                 [](const std::string& h) { return WebString::FromASCII(h); });
+  response.SetDnsAliases(dns_aliases);
+  response.SetRemoteIPEndpoint(head.remote_endpoint);
+  response.SetAddressSpace(head.response_address_space);
+  response.SetClientAddressSpace(head.client_address_space);
+
+  WebVector<WebString> cors_exposed_header_names(
+      head.cors_exposed_header_names.size());
+  std::transform(head.cors_exposed_header_names.begin(),
+                 head.cors_exposed_header_names.end(),
+                 cors_exposed_header_names.begin(),
+                 [](const std::string& h) { return WebString::FromLatin1(h); });
+  response.SetCorsExposedHeaderNames(cors_exposed_header_names);
+  response.SetDidServiceWorkerNavigationPreload(
+      head.did_service_worker_navigation_preload);
+  response.SetIsValidated(head.is_validated);
+  response.SetEncodedDataLength(head.encoded_data_length);
+  response.SetEncodedBodyLength(head.encoded_body_length);
+  response.SetWasAlpnNegotiated(head.was_alpn_negotiated);
+  response.SetAlpnNegotiatedProtocol(
+      WebString::FromUTF8(head.alpn_negotiated_protocol));
+  response.SetAlternateProtocolUsage(head.alternate_protocol_usage);
+  response.SetHasAuthorizationCoveredByWildcardOnPreflight(
+      head.has_authorization_covered_by_wildcard_on_preflight);
+  response.SetWasAlternateProtocolAvailable(
+      head.was_alternate_protocol_available);
+  response.SetConnectionInfo(head.connection_info);
+  response.SetAsyncRevalidationRequested(head.async_revalidation_requested);
+  response.SetNetworkAccessed(head.network_accessed);
+  response.SetRequestId(request_id);
+  response.SetIsSignedExchangeInnerResponse(
+      head.is_signed_exchange_inner_response);
+  response.SetWasInPrefetchCache(head.was_in_prefetch_cache);
+  response.SetWasCookieInRequest(head.was_cookie_in_request);
+  response.SetRecursivePrefetchToken(head.recursive_prefetch_token);
+  response.SetWebBundleURL(KURL(head.web_bundle_url));
+
+  SetSecurityStyleAndDetails(GURL(KURL(url)), head, &response,
+                             report_security_info);
+
+  // If there's no received headers end time, don't set load timing.  This is
+  // the case for non-HTTP requests, requests that don't go over the wire, and
+  // certain error cases.
+  if (!head.load_timing.receive_headers_end.is_null()) {
+    response.SetLoadTiming(ToMojoLoadTiming(head.load_timing));
+  }
+
+  response.SetEmittedExtraInfo(head.emitted_extra_info);
+
+  response.SetAuthChallengeInfo(head.auth_challenge_info);
+  response.SetRequestIncludeCredentials(head.request_include_credentials);
+
+  const net::HttpResponseHeaders* headers = head.headers.get();
+  if (!headers)
+    return response;
+
+  WebURLResponse::HTTPVersion version = WebURLResponse::kHTTPVersionUnknown;
+  if (headers->GetHttpVersion() == net::HttpVersion(0, 9))
+    version = WebURLResponse::kHTTPVersion_0_9;
+  else if (headers->GetHttpVersion() == net::HttpVersion(1, 0))
+    version = WebURLResponse::kHTTPVersion_1_0;
+  else if (headers->GetHttpVersion() == net::HttpVersion(1, 1))
+    version = WebURLResponse::kHTTPVersion_1_1;
+  else if (headers->GetHttpVersion() == net::HttpVersion(2, 0))
+    version = WebURLResponse::kHTTPVersion_2_0;
+  response.SetHttpVersion(version);
+  response.SetHttpStatusCode(headers->response_code());
+  response.SetHttpStatusText(WebString::FromLatin1(headers->GetStatusText()));
+
+  // Build up the header map.
+  size_t iter = 0;
+  std::string name;
+  std::string value;
+  while (headers->EnumerateHeaderLines(&iter, &name, &value)) {
+    response.AddHttpHeaderField(WebString::FromLatin1(name),
+                                WebString::FromLatin1(value));
+  }
+
+  response.SetHasPartitionedCookie(head.has_partitioned_cookie);
+  return response;
+}
+
 WebURLResponse::~WebURLResponse() = default;
 
 WebURLResponse::WebURLResponse()
diff --git a/third_party/blink/renderer/platform/graphics/color.cc b/third_party/blink/renderer/platform/graphics/color.cc
index f267a93f..6004ba3 100644
--- a/third_party/blink/renderer/platform/graphics/color.cc
+++ b/third_party/blink/renderer/platform/graphics/color.cc
@@ -361,9 +361,6 @@
         value1 += 360.0f;
       DCHECK(-360.0f < value2 - value1 && value2 - value1 <= 0.f);
       break;
-    case Color::HueInterpolationMethod::kSpecified:
-      // No fixup performed.
-      break;
   }
   return AngleToUnitCircleDegrees(blink::Blend(value2, value1, percentage));
 }
@@ -1216,9 +1213,6 @@
       case Color::HueInterpolationMethod::kLonger:
         result.Append(" longer hue");
         break;
-      case Color::HueInterpolationMethod::kSpecified:
-        result.Append(" specified hue");
-        break;
       // Shorter is the default value and does not get serialized
       case Color::HueInterpolationMethod::kShorter:
         break;
diff --git a/third_party/blink/renderer/platform/graphics/color.h b/third_party/blink/renderer/platform/graphics/color.h
index 6bc8bf16..4bee612 100644
--- a/third_party/blink/renderer/platform/graphics/color.h
+++ b/third_party/blink/renderer/platform/graphics/color.h
@@ -206,7 +206,6 @@
     kLonger,
     kIncreasing,
     kDecreasing,
-    kSpecified,
   };
 
   // Creates a color with the Color-Mix method in CSS Color 5. This will produce
@@ -252,12 +251,9 @@
   bool SetFromString(const String&);
   bool SetNamedColor(const String&);
 
-  // Returns true if the color is not opaque.
+  // Return true if the color is not opaque.
   bool HasAlpha() const { return Alpha() < 255; }
 
-  // Returns true if the color is transparent.
-  bool IsTransparent() const { return Alpha() == 0; }
-
   // Access the color as though it were created using rgba syntax. This will
   // clamp all colors to an 8-bit sRGB representation. All callers of these
   // functions should be audited. The function Rgb(), despite the name, does
diff --git a/third_party/blink/renderer/platform/graphics/color_test.cc b/third_party/blink/renderer/platform/graphics/color_test.cc
index 26ae37d..48edc4f3 100644
--- a/third_party/blink/renderer/platform/graphics/color_test.cc
+++ b/third_party/blink/renderer/platform/graphics/color_test.cc
@@ -230,8 +230,6 @@
         return "kIncreasing";
       case Color::HueInterpolationMethod::kDecreasing:
         return "kDecreasing";
-      case Color::HueInterpolationMethod::kSpecified:
-        return "kSpecified";
     }
   };
 
@@ -248,9 +246,6 @@
       {60.0f, 330.0f, 0.0f, Color::HueInterpolationMethod::kDecreasing, 60.0f},
       {60.0f, 330.0f, 1.0f, Color::HueInterpolationMethod::kDecreasing, 330.0f},
       {60.0f, 330.0f, 0.7f, Color::HueInterpolationMethod::kDecreasing, 357.0f},
-      {60.0f, 330.0f, 0.0f, Color::HueInterpolationMethod::kSpecified, 60.0f},
-      {60.0f, 330.0f, 1.0f, Color::HueInterpolationMethod::kSpecified, 330.0f},
-      {60.0f, 330.0f, 0.7f, Color::HueInterpolationMethod::kSpecified, 249.0f},
       {60.0f, 90.0f, 0.0f, Color::HueInterpolationMethod::kShorter, 60.0f},
       {60.0f, 90.0f, 1.0f, Color::HueInterpolationMethod::kShorter, 90.0f},
       {60.0f, 90.0f, 0.7f, Color::HueInterpolationMethod::kShorter, 81.0f},
@@ -263,9 +258,6 @@
       {60.0f, 90.0f, 0.0f, Color::HueInterpolationMethod::kDecreasing, 60.0f},
       {60.0f, 90.0f, 1.0f, Color::HueInterpolationMethod::kDecreasing, 90.0f},
       {60.0f, 90.0f, 0.7f, Color::HueInterpolationMethod::kDecreasing, 189.0f},
-      {60.0f, 90.0f, 0.0f, Color::HueInterpolationMethod::kSpecified, 60.0f},
-      {60.0f, 90.0f, 1.0f, Color::HueInterpolationMethod::kSpecified, 90.0f},
-      {60.0f, 90.0f, 0.7f, Color::HueInterpolationMethod::kSpecified, 81.0f},
   };
 
   for (auto& hue_test : hue_tests) {
diff --git a/third_party/blink/renderer/platform/graphics/gradient.cc b/third_party/blink/renderer/platform/graphics/gradient.cc
index 1911d87..5866d0b0 100644
--- a/third_party/blink/renderer/platform/graphics/gradient.cc
+++ b/third_party/blink/renderer/platform/graphics/gradient.cc
@@ -29,6 +29,7 @@
 
 #include <algorithm>
 #include "third_party/abseil-cpp/absl/types/optional.h"
+#include "third_party/blink/renderer/platform/graphics/color.h"
 #include "third_party/blink/renderer/platform/graphics/dark_mode_settings_builder.h"
 #include "third_party/blink/renderer/platform/graphics/graphics_context.h"
 #include "third_party/blink/renderer/platform/graphics/paint/paint_shader.h"
@@ -86,6 +87,14 @@
   std::stable_sort(stops_.begin(), stops_.end(), CompareStops);
 }
 
+bool Gradient::HasNonLegacyColor() const {
+  for (const auto& stop : stops_) {
+    if (!stop.color.IsLegacyColor())
+      return true;
+  }
+  return false;
+}
+
 // Collect sorted stop position and color information into the pos and colors
 // buffers, ensuring stops at both 0.0 and 1.0.
 // TODO(fmalita): theoretically Skia should provide the same 0.0/1.0 padding
@@ -129,6 +138,71 @@
   }
 }
 
+SkGradientShader::Interpolation Gradient::ResolveSkInterpolation() const {
+  using sk_colorspace = SkGradientShader::Interpolation::ColorSpace;
+  using sk_hue_method = SkGradientShader::Interpolation::HueMethod;
+  SkGradientShader::Interpolation sk_interpolation;
+
+  switch (color_space_interpolation_space_) {
+    case Color::ColorInterpolationSpace::kXYZD65:
+    case Color::ColorInterpolationSpace::kXYZD50:
+    case Color::ColorInterpolationSpace::kSRGBLinear:
+      sk_interpolation.fColorSpace = sk_colorspace::kSRGBLinear;
+      break;
+    case Color::ColorInterpolationSpace::kLab:
+      sk_interpolation.fColorSpace = sk_colorspace::kLab;
+      break;
+    case Color::ColorInterpolationSpace::kOklab:
+      sk_interpolation.fColorSpace = sk_colorspace::kOKLab;
+      break;
+    case Color::ColorInterpolationSpace::kLch:
+      sk_interpolation.fColorSpace = sk_colorspace::kLCH;
+      break;
+    case Color::ColorInterpolationSpace::kOklch:
+      sk_interpolation.fColorSpace = sk_colorspace::kOKLCH;
+      break;
+    case Color::ColorInterpolationSpace::kSRGB:
+      sk_interpolation.fColorSpace = sk_colorspace::kSRGB;
+      break;
+    case Color::ColorInterpolationSpace::kHSL:
+      sk_interpolation.fColorSpace = sk_colorspace::kHSL;
+      break;
+    case Color::ColorInterpolationSpace::kHWB:
+      sk_interpolation.fColorSpace = sk_colorspace::kHWB;
+      break;
+    case Color::ColorInterpolationSpace::kNone:
+      if (HasNonLegacyColor()) {
+        // If no colorspace is provided and the gradient is not entirely
+        // composed of legacy colors, Oklab is the default interpolation space.
+        sk_interpolation.fColorSpace = sk_colorspace::kOKLab;
+      } else {
+        // TODO(crbug.com/1379462): This should be kSRGB.
+        sk_interpolation.fColorSpace = sk_colorspace::kDestination;
+      }
+  }
+
+  switch (hue_interpolation_method_) {
+    case Color::HueInterpolationMethod::kLonger:
+      sk_interpolation.fHueMethod = sk_hue_method::kLonger;
+      break;
+    case Color::HueInterpolationMethod::kIncreasing:
+      sk_interpolation.fHueMethod = sk_hue_method::kIncreasing;
+      break;
+    case Color::HueInterpolationMethod::kDecreasing:
+      sk_interpolation.fHueMethod = sk_hue_method::kDecreasing;
+      break;
+    default:
+      sk_interpolation.fHueMethod = sk_hue_method::kShorter;
+  }
+
+  sk_interpolation.fInPremul =
+      (color_interpolation_ == ColorInterpolation::kPremultiplied)
+          ? SkGradientShader::Interpolation::InPremul::kYes
+          : SkGradientShader::Interpolation::InPremul::kNo;
+
+  return sk_interpolation;
+}
+
 sk_sp<PaintShader> Gradient::CreateShaderInternal(
     const SkMatrix& local_matrix) {
   SortStopsIfNecessary();
@@ -162,12 +236,8 @@
           SkColor(color), DarkModeFilter::ElementRole::kBackground);
     }
   }
-
-  uint32_t flags = color_interpolation_ == ColorInterpolation::kPremultiplied
-                       ? SkGradientShader::kInterpolateColorsInPremul_Flag
-                       : 0;
-  sk_sp<PaintShader> shader =
-      CreateShader(colors, pos, tile, flags, local_matrix, colors.back());
+  sk_sp<PaintShader> shader = CreateShader(
+      colors, pos, tile, ResolveSkInterpolation(), local_matrix, colors.back());
   DCHECK(shader);
 
   return shader;
@@ -221,7 +291,7 @@
   sk_sp<PaintShader> CreateShader(const ColorBuffer& colors,
                                   const OffsetBuffer& pos,
                                   SkTileMode tile_mode,
-                                  uint32_t flags,
+                                  SkGradientShader::Interpolation interpolation,
                                   const SkMatrix& local_matrix,
                                   SkColor fallback_color) const override {
     if (GetDegenerateHandling() == DegenerateHandling::kDisallow &&
@@ -238,7 +308,8 @@
       colors4f.push_back(SkColor4f::FromColor(color));
     return PaintShader::MakeLinearGradient(
         pts, colors4f.data(), pos.data(), static_cast<int>(colors4f.size()),
-        tile_mode, flags, &local_matrix, SkColor4f::FromColor(fallback_color));
+        tile_mode, interpolation, 0 /* flags */, &local_matrix,
+        SkColor4f::FromColor(fallback_color));
   }
 
  private:
@@ -270,7 +341,7 @@
   sk_sp<PaintShader> CreateShader(const ColorBuffer& colors,
                                   const OffsetBuffer& pos,
                                   SkTileMode tile_mode,
-                                  uint32_t flags,
+                                  SkGradientShader::Interpolation interpolation,
                                   const SkMatrix& local_matrix,
                                   SkColor fallback_color) const override {
     const SkMatrix* matrix = &local_matrix;
@@ -303,7 +374,8 @@
     return PaintShader::MakeTwoPointConicalGradient(
         FloatPointToSkPoint(p0_), radius0, FloatPointToSkPoint(p1_), radius1,
         colors4f.data(), pos.data(), static_cast<int>(colors4f.size()),
-        tile_mode, flags, matrix, SkColor4f::FromColor(fallback_color));
+        tile_mode, interpolation, 0 /* flags */, matrix,
+        SkColor4f::FromColor(fallback_color));
   }
 
  private:
@@ -336,7 +408,7 @@
   sk_sp<PaintShader> CreateShader(const ColorBuffer& colors,
                                   const OffsetBuffer& pos,
                                   SkTileMode tile_mode,
-                                  uint32_t flags,
+                                  SkGradientShader::Interpolation interpolation,
                                   const SkMatrix& local_matrix,
                                   SkColor fallback_color) const override {
     if (GetDegenerateHandling() == DegenerateHandling::kDisallow &&
@@ -364,7 +436,8 @@
     return PaintShader::MakeSweepGradient(
         position_.x(), position_.y(), colors4f.data(), pos.data(),
         static_cast<int>(colors4f.size()), tile_mode, start_angle_, end_angle_,
-        flags, matrix, SkColor4f::FromColor(fallback_color));
+        interpolation, 0 /* flags */, matrix,
+        SkColor4f::FromColor(fallback_color));
   }
 
  private:
diff --git a/third_party/blink/renderer/platform/graphics/gradient.h b/third_party/blink/renderer/platform/graphics/gradient.h
index c6180f3..7706f8c6 100644
--- a/third_party/blink/renderer/platform/graphics/gradient.h
+++ b/third_party/blink/renderer/platform/graphics/gradient.h
@@ -39,6 +39,7 @@
 #include "third_party/blink/renderer/platform/wtf/ref_counted.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
 #include "third_party/skia/include/core/SkRefCnt.h"
+#include "third_party/skia/include/effects/SkGradientShader.h"
 
 class SkMatrix;
 
@@ -132,7 +133,7 @@
   virtual sk_sp<PaintShader> CreateShader(const ColorBuffer&,
                                           const OffsetBuffer&,
                                           SkTileMode,
-                                          uint32_t flags,
+                                          SkGradientShader::Interpolation,
                                           const SkMatrix&,
                                           SkColor) const = 0;
 
@@ -142,9 +143,11 @@
 
  private:
   sk_sp<PaintShader> CreateShaderInternal(const SkMatrix& local_matrix);
+  SkGradientShader::Interpolation ResolveSkInterpolation() const;
 
   void SortStopsIfNecessary() const;
   void FillSkiaStops(ColorBuffer&, OffsetBuffer&) const;
+  bool HasNonLegacyColor() const;
 
   const Type type_;
   const GradientSpreadMethod spread_method_;
@@ -159,8 +162,10 @@
   mutable sk_sp<PaintShader> cached_shader_;
   mutable sk_sp<SkColorFilter> color_filter_;
 
-  Color::ColorInterpolationSpace color_space_interpolation_space_;
-  Color::HueInterpolationMethod hue_interpolation_method_;
+  Color::ColorInterpolationSpace color_space_interpolation_space_ =
+      Color::ColorInterpolationSpace::kNone;
+  Color::HueInterpolationMethod hue_interpolation_method_ =
+      Color::HueInterpolationMethod::kShorter;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/navigation_body_loader.cc b/third_party/blink/renderer/platform/loader/fetch/url_loader/navigation_body_loader.cc
index 82f2357..c9ede04 100644
--- a/third_party/blink/renderer/platform/loader/fetch/url_loader/navigation_body_loader.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/navigation_body_loader.cc
@@ -21,7 +21,8 @@
 #include "third_party/blink/public/mojom/navigation/navigation_params.mojom.h"
 #include "third_party/blink/public/platform/resource_load_info_notifier_wrapper.h"
 #include "third_party/blink/public/platform/web_code_cache_loader.h"
-#include "third_party/blink/public/platform/web_url_loader.h"
+#include "third_party/blink/public/platform/web_url_error.h"
+#include "third_party/blink/public/platform/web_url_response.h"
 #include "third_party/blink/public/web/web_navigation_params.h"
 #include "third_party/blink/renderer/platform/loader/fetch/body_text_decoder.h"
 #include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
@@ -488,7 +489,7 @@
 
   absl::optional<WebURLError> error;
   if (status_.error_code != net::OK) {
-    error = WebURLLoader::PopulateURLError(status_, original_url_);
+    error = WebURLError::Create(status_, original_url_);
   }
 
   resource_load_info_notifier_wrapper_->NotifyResourceLoadCompleted(status_);
@@ -583,9 +584,9 @@
         navigation_params->redirects[i];
     auto& redirect_info = commit_params->redirect_infos[i];
     auto& redirect_response = commit_params->redirect_response[i];
-    WebURLLoader::PopulateURLResponse(
-        url, *redirect_response, &redirect.redirect_response,
-        response_head->ssl_info.has_value(), request_id);
+    redirect.redirect_response =
+        WebURLResponse::Create(url, *redirect_response,
+                               response_head->ssl_info.has_value(), request_id);
     resource_load_info_notifier_wrapper->NotifyResourceRedirectReceived(
         redirect_info, std::move(redirect_response));
     if (url.ProtocolIsData())
@@ -601,9 +602,8 @@
     url = KURL(redirect_info.new_url);
   }
 
-  WebURLLoader::PopulateURLResponse(
-      url, *response_head, &navigation_params->response,
-      response_head->ssl_info.has_value(), request_id);
+  navigation_params->response = WebURLResponse::Create(
+      url, *response_head, response_head->ssl_info.has_value(), request_id);
   if (url.ProtocolIsData())
     navigation_params->response.SetHttpStatusCode(200);
 
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/web_url_loader.cc b/third_party/blink/renderer/platform/loader/fetch/url_loader/web_url_loader.cc
index 696116b3..a05e010 100644
--- a/third_party/blink/renderer/platform/loader/fetch/url_loader/web_url_loader.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/web_url_loader.cc
@@ -98,68 +98,6 @@
 
 namespace {
 
-// Converts timing data from |load_timing| to the mojo type.
-network::mojom::LoadTimingInfo ToMojoLoadTiming(
-    const net::LoadTimingInfo& load_timing) {
-  DCHECK(!load_timing.request_start.is_null());
-
-  return network::mojom::LoadTimingInfo(
-      load_timing.socket_reused, load_timing.socket_log_id,
-      load_timing.request_start_time, load_timing.request_start,
-      load_timing.proxy_resolve_start, load_timing.proxy_resolve_end,
-      load_timing.connect_timing, load_timing.send_start, load_timing.send_end,
-      load_timing.receive_headers_start, load_timing.receive_headers_end,
-      load_timing.receive_non_informational_headers_start,
-      load_timing.first_early_hints_time, load_timing.push_start,
-      load_timing.push_end, load_timing.service_worker_start_time,
-      load_timing.service_worker_ready_time,
-      load_timing.service_worker_fetch_start,
-      load_timing.service_worker_respond_with_settled);
-}
-
-// TODO(crbug.com/862940): Use KURL here.
-void SetSecurityStyleAndDetails(const GURL& url,
-                                const network::mojom::URLResponseHead& head,
-                                WebURLResponse* response,
-                                bool report_security_info) {
-  if (!report_security_info) {
-    response->SetSecurityStyle(SecurityStyle::kUnknown);
-    return;
-  }
-  if (!url.SchemeIsCryptographic()) {
-    // Some origins are considered secure even though they're not cryptographic,
-    // so treat them as secure in the UI.
-    if (network::IsUrlPotentiallyTrustworthy(url))
-      response->SetSecurityStyle(SecurityStyle::kSecure);
-    else
-      response->SetSecurityStyle(SecurityStyle::kInsecure);
-    return;
-  }
-
-  // The resource loader does not provide a guarantee that requests always have
-  // security info (such as a certificate) attached. Use SecurityStyleUnknown
-  // in this case where there isn't enough information to be useful.
-  if (!head.ssl_info.has_value()) {
-    response->SetSecurityStyle(SecurityStyle::kUnknown);
-    return;
-  }
-
-  const net::SSLInfo& ssl_info = *head.ssl_info;
-  if (net::IsCertStatusError(head.cert_status)) {
-    response->SetSecurityStyle(SecurityStyle::kInsecure);
-  } else {
-    response->SetSecurityStyle(SecurityStyle::kSecure);
-  }
-
-  if (!ssl_info.cert) {
-    NOTREACHED();
-    response->SetSecurityStyle(SecurityStyle::kUnknown);
-    return;
-  }
-
-  response->SetSSLInfo(ssl_info);
-}
-
 bool IsBannedCrossSiteAuth(
     network::ResourceRequest* resource_request,
     WebURLRequestExtraData* passed_url_request_extra_data) {
@@ -508,9 +446,8 @@
                          this,
                          TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
 
-  WebURLResponse response;
-  PopulateURLResponse(url_, *head, &response, has_devtools_request_id_,
-                      request_id_);
+  WebURLResponse response = WebURLResponse::Create(
+      url_, *head, has_devtools_request_id_, request_id_);
 
   url_ = KURL(redirect_info.new_url);
   return client_->WillFollowRedirect(
@@ -538,9 +475,8 @@
   DCHECK(!head->headers || !head->headers->HasHeader("set-cookie2"));
   DCHECK(!head->headers || !head->headers->HasHeader("clear-site-data"));
 
-  WebURLResponse response;
-  PopulateURLResponse(url_, *head, &response, has_devtools_request_id_,
-                      request_id_);
+  WebURLResponse response = WebURLResponse::Create(
+      url_, *head, has_devtools_request_id_, request_id_);
   response.SetArrivalTimeAtRenderer(response_arrival_at_renderer);
 
   client_->DidReceiveResponse(response);
@@ -587,9 +523,9 @@
                            TRACE_EVENT_FLAG_FLOW_IN);
 
     if (status.error_code != net::OK) {
-      client_->DidFail(PopulateURLError(status, url_), status.completion_time,
-                       total_transfer_size, encoded_body_size,
-                       status.decoded_body_length);
+      client_->DidFail(WebURLError::Create(status, url_),
+                       status.completion_time, total_transfer_size,
+                       encoded_body_size, status.decoded_body_length);
     } else {
       client_->DidFinishLoading(status.completion_time, total_transfer_size,
                                 encoded_body_size, status.decoded_body_length,
@@ -645,166 +581,6 @@
   Cancel();
 }
 
-void WebURLLoader::PopulateURLResponse(
-    const WebURL& url,
-    const network::mojom::URLResponseHead& head,
-    WebURLResponse* response,
-    bool report_security_info,
-    int request_id) {
-  response->SetCurrentRequestUrl(url);
-  response->SetResponseTime(head.response_time);
-  response->SetMimeType(WebString::FromUTF8(head.mime_type));
-  response->SetTextEncodingName(WebString::FromUTF8(head.charset));
-  response->SetExpectedContentLength(head.content_length);
-  response->SetHasMajorCertificateErrors(
-      net::IsCertStatusError(head.cert_status));
-  response->SetIsLegacyTLSVersion(head.is_legacy_tls_version);
-  response->SetHasRangeRequested(head.has_range_requested);
-  response->SetTimingAllowPassed(head.timing_allow_passed);
-  response->SetWasCached(!head.load_timing.request_start_time.is_null() &&
-                         head.response_time <
-                             head.load_timing.request_start_time);
-  response->SetConnectionID(head.load_timing.socket_log_id);
-  response->SetConnectionReused(head.load_timing.socket_reused);
-  response->SetWasFetchedViaSPDY(head.was_fetched_via_spdy);
-  response->SetWasFetchedViaServiceWorker(head.was_fetched_via_service_worker);
-  response->SetServiceWorkerResponseSource(head.service_worker_response_source);
-  response->SetType(head.response_type);
-  response->SetPadding(head.padding);
-  WebVector<KURL> url_list_via_service_worker(
-      head.url_list_via_service_worker.size());
-  std::transform(head.url_list_via_service_worker.begin(),
-                 head.url_list_via_service_worker.end(),
-                 url_list_via_service_worker.begin(),
-                 [](const GURL& h) { return KURL(h); });
-  response->SetUrlListViaServiceWorker(url_list_via_service_worker);
-  response->SetCacheStorageCacheName(
-      head.service_worker_response_source ==
-              network::mojom::FetchResponseSource::kCacheStorage
-          ? WebString::FromUTF8(head.cache_storage_cache_name)
-          : WebString());
-
-  WebVector<WebString> dns_aliases(head.dns_aliases.size());
-  std::transform(head.dns_aliases.begin(), head.dns_aliases.end(),
-                 dns_aliases.begin(),
-                 [](const std::string& h) { return WebString::FromASCII(h); });
-  response->SetDnsAliases(dns_aliases);
-  response->SetRemoteIPEndpoint(head.remote_endpoint);
-  response->SetAddressSpace(head.response_address_space);
-  response->SetClientAddressSpace(head.client_address_space);
-
-  WebVector<WebString> cors_exposed_header_names(
-      head.cors_exposed_header_names.size());
-  std::transform(head.cors_exposed_header_names.begin(),
-                 head.cors_exposed_header_names.end(),
-                 cors_exposed_header_names.begin(),
-                 [](const std::string& h) { return WebString::FromLatin1(h); });
-  response->SetCorsExposedHeaderNames(cors_exposed_header_names);
-  response->SetDidServiceWorkerNavigationPreload(
-      head.did_service_worker_navigation_preload);
-  response->SetIsValidated(head.is_validated);
-  response->SetEncodedDataLength(head.encoded_data_length);
-  response->SetEncodedBodyLength(head.encoded_body_length);
-  response->SetWasAlpnNegotiated(head.was_alpn_negotiated);
-  response->SetAlpnNegotiatedProtocol(
-      WebString::FromUTF8(head.alpn_negotiated_protocol));
-  response->SetAlternateProtocolUsage(head.alternate_protocol_usage);
-  response->SetHasAuthorizationCoveredByWildcardOnPreflight(
-      head.has_authorization_covered_by_wildcard_on_preflight);
-  response->SetWasAlternateProtocolAvailable(
-      head.was_alternate_protocol_available);
-  response->SetConnectionInfo(head.connection_info);
-  response->SetAsyncRevalidationRequested(head.async_revalidation_requested);
-  response->SetNetworkAccessed(head.network_accessed);
-  response->SetRequestId(request_id);
-  response->SetIsSignedExchangeInnerResponse(
-      head.is_signed_exchange_inner_response);
-  response->SetWasInPrefetchCache(head.was_in_prefetch_cache);
-  response->SetWasCookieInRequest(head.was_cookie_in_request);
-  response->SetRecursivePrefetchToken(head.recursive_prefetch_token);
-  response->SetWebBundleURL(KURL(head.web_bundle_url));
-
-  SetSecurityStyleAndDetails(GURL(KURL(url)), head, response,
-                             report_security_info);
-
-  // If there's no received headers end time, don't set load timing.  This is
-  // the case for non-HTTP requests, requests that don't go over the wire, and
-  // certain error cases.
-  if (!head.load_timing.receive_headers_end.is_null()) {
-    response->SetLoadTiming(ToMojoLoadTiming(head.load_timing));
-  }
-
-  response->SetEmittedExtraInfo(head.emitted_extra_info);
-
-  response->SetAuthChallengeInfo(head.auth_challenge_info);
-  response->SetRequestIncludeCredentials(head.request_include_credentials);
-
-  const net::HttpResponseHeaders* headers = head.headers.get();
-  if (!headers)
-    return;
-
-  WebURLResponse::HTTPVersion version = WebURLResponse::kHTTPVersionUnknown;
-  if (headers->GetHttpVersion() == net::HttpVersion(0, 9))
-    version = WebURLResponse::kHTTPVersion_0_9;
-  else if (headers->GetHttpVersion() == net::HttpVersion(1, 0))
-    version = WebURLResponse::kHTTPVersion_1_0;
-  else if (headers->GetHttpVersion() == net::HttpVersion(1, 1))
-    version = WebURLResponse::kHTTPVersion_1_1;
-  else if (headers->GetHttpVersion() == net::HttpVersion(2, 0))
-    version = WebURLResponse::kHTTPVersion_2_0;
-  response->SetHttpVersion(version);
-  response->SetHttpStatusCode(headers->response_code());
-  response->SetHttpStatusText(WebString::FromLatin1(headers->GetStatusText()));
-
-  // Build up the header map.
-  size_t iter = 0;
-  std::string name;
-  std::string value;
-  while (headers->EnumerateHeaderLines(&iter, &name, &value)) {
-    response->AddHttpHeaderField(WebString::FromLatin1(name),
-                                 WebString::FromLatin1(value));
-  }
-
-  response->SetHasPartitionedCookie(head.has_partitioned_cookie);
-}
-
-// static
-WebURLError WebURLLoader::PopulateURLError(
-    const network::URLLoaderCompletionStatus& status,
-    const WebURL& url) {
-  DCHECK_NE(net::OK, status.error_code);
-  const WebURLError::HasCopyInCache has_copy_in_cache =
-      status.exists_in_cache ? WebURLError::HasCopyInCache::kTrue
-                             : WebURLError::HasCopyInCache::kFalse;
-  if (status.cors_error_status)
-    return WebURLError(*status.cors_error_status, has_copy_in_cache, url);
-  if (status.blocked_by_response_reason) {
-    DCHECK_EQ(net::ERR_BLOCKED_BY_RESPONSE, status.error_code);
-    return WebURLError(*status.blocked_by_response_reason,
-                       status.resolve_error_info, has_copy_in_cache, url);
-  }
-
-  if (status.trust_token_operation_status !=
-      network::mojom::TrustTokenOperationStatus::kOk) {
-    DCHECK(status.error_code ==
-               net::ERR_TRUST_TOKEN_OPERATION_SUCCESS_WITHOUT_SENDING_REQUEST ||
-           status.error_code == net::ERR_TRUST_TOKEN_OPERATION_FAILED)
-        << "Unexpected error code on Trust Token operation failure (or cache "
-           "hit): "
-        << status.error_code;
-
-    return WebURLError(status.error_code, status.trust_token_operation_status,
-                       url);
-  }
-
-  return WebURLError(status.error_code, status.extended_error_code,
-                     status.resolve_error_info, has_copy_in_cache,
-                     WebURLError::IsWebSecurityViolation::kFalse, url,
-                     status.should_collapse_initiator
-                         ? WebURLError::ShouldCollapseInitiator::kTrue
-                         : WebURLError::ShouldCollapseInitiator::kFalse);
-}
-
 void WebURLLoader::LoadSynchronously(
     std::unique_ptr<network::ResourceRequest> request,
     scoped_refptr<WebURLRequestExtraData> url_request_extra_data,
@@ -862,8 +638,9 @@
     return;
   }
 
-  PopulateURLResponse(final_url, *sync_load_response.head, &response,
-                      has_devtools_request_id, context_->request_id());
+  response =
+      WebURLResponse::Create(final_url, *sync_load_response.head,
+                             has_devtools_request_id, context_->request_id());
   encoded_data_length = sync_load_response.head->encoded_data_length;
   encoded_body_length = sync_load_response.head->encoded_body_length;
   if (sync_load_response.downloaded_blob) {
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/web_url_loader_unittest.cc b/third_party/blink/renderer/platform/loader/fetch/url_loader/web_url_loader_unittest.cc
index 7e05d8d..ff83429 100644
--- a/third_party/blink/renderer/platform/loader/fetch/url_loader/web_url_loader_unittest.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/web_url_loader_unittest.cc
@@ -502,8 +502,7 @@
     network::mojom::URLResponseHead head;
     head.remote_endpoint = net::IPEndPoint(address, test.port);
 
-    WebURLResponse response;
-    WebURLLoader::PopulateURLResponse(url, head, &response, true, -1);
+    WebURLResponse response = WebURLResponse::Create(url, head, true, -1);
     EXPECT_EQ(head.remote_endpoint, response.RemoteIPEndpoint());
   };
 }
@@ -514,8 +513,7 @@
   network::mojom::URLResponseHead head;
   head.response_address_space = network::mojom::IPAddressSpace::kPrivate;
 
-  WebURLResponse response;
-  WebURLLoader::PopulateURLResponse(url, head, &response, true, -1);
+  WebURLResponse response = WebURLResponse::Create(url, head, true, -1);
 
   EXPECT_EQ(network::mojom::IPAddressSpace::kPrivate, response.AddressSpace());
 }
@@ -526,8 +524,7 @@
   network::mojom::URLResponseHead head;
   head.client_address_space = network::mojom::IPAddressSpace::kPublic;
 
-  WebURLResponse response;
-  WebURLLoader::PopulateURLResponse(url, head, &response, true, -1);
+  WebURLResponse response = WebURLResponse::Create(url, head, true, -1);
 
   EXPECT_EQ(network::mojom::IPAddressSpace::kPublic,
             response.ClientAddressSpace());
@@ -554,8 +551,7 @@
 
   network::mojom::URLResponseHead head;
   head.ssl_info = ssl_info;
-  WebURLResponse web_url_response;
-  WebURLLoader::PopulateURLResponse(url, head, &web_url_response, true, -1);
+  WebURLResponse web_url_response = WebURLResponse::Create(url, head, true, -1);
 
   const absl::optional<net::SSLInfo>& got_ssl_info =
       web_url_response.ToResourceResponse().GetSSLInfo();
@@ -607,7 +603,8 @@
   EXPECT_TRUE(downloaded_blob.Uuid().IsNull());
 }
 
-// Verifies that PopulateURLResponse() copies AuthChallengeInfo to the response.
+// Verifies that WebURLResponse::Create() copies AuthChallengeInfo to the
+// response.
 TEST_F(WebURLLoaderTest, AuthChallengeInfo) {
   network::mojom::URLResponseHead head;
   net::AuthChallengeInfo auth_challenge_info;
@@ -615,8 +612,8 @@
   auth_challenge_info.challenge = "foobar";
   head.auth_challenge_info = auth_challenge_info;
 
-  blink::WebURLResponse response;
-  WebURLLoader::PopulateURLResponse(KURL(), head, &response, true, -1);
+  blink::WebURLResponse response =
+      WebURLResponse::Create(KURL(), head, true, -1);
   ASSERT_TRUE(response.AuthChallengeInfo().has_value());
   EXPECT_TRUE(response.AuthChallengeInfo()->is_proxy);
   EXPECT_EQ("foobar", response.AuthChallengeInfo()->challenge);
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/worker_main_script_loader.cc b/third_party/blink/renderer/platform/loader/fetch/url_loader/worker_main_script_loader.cc
index a9b9a04e..f324247e 100644
--- a/third_party/blink/renderer/platform/loader/fetch/url_loader/worker_main_script_loader.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/worker_main_script_loader.cc
@@ -12,7 +12,6 @@
 #include "third_party/blink/public/platform/resource_load_info_notifier_wrapper.h"
 #include "third_party/blink/public/platform/url_conversion.h"
 #include "third_party/blink/public/platform/web_url.h"
-#include "third_party/blink/public/platform/web_url_loader.h"
 #include "third_party/blink/public/platform/web_url_response.h"
 #include "third_party/blink/renderer/platform/loader/cors/cors.h"
 #include "third_party/blink/renderer/platform/loader/fetch/cached_metadata.h"
@@ -66,11 +65,10 @@
                        worker_main_script_load_params->redirect_responses);
   }
 
-  WebURLResponse response;
   auto response_head = std::move(worker_main_script_load_params->response_head);
-  WebURLLoader::PopulateURLResponse(
-      WebURL(last_request_url_), *response_head, &response,
-      response_head->ssl_info.has_value(), request_id_);
+  WebURLResponse response =
+      WebURLResponse::Create(WebURL(last_request_url_), *response_head,
+                             response_head->ssl_info.has_value(), request_id_);
   resource_response_ = response.ToResourceResponse();
   resource_load_info_notifier_wrapper_->NotifyResourceResponseReceived(
       std::move(response_head));
@@ -310,9 +308,8 @@
             ReferrerUtils::NetToMojoReferrerPolicy(
                 redirect_info.new_referrer_policy),
             /*skip_service_worker=*/false);
-    WebURLResponse response;
-    WebURLLoader::PopulateURLResponse(
-        WebURL(last_request_url_), *redirect_response, &response,
+    WebURLResponse response = WebURLResponse::Create(
+        WebURL(last_request_url_), *redirect_response,
         redirect_response->ssl_info.has_value(), request_id_);
     resource_load_info_notifier_wrapper_->NotifyResourceRedirectReceived(
         redirect_info, std::move(redirect_response));
diff --git a/third_party/blink/renderer/platform/media/web_media_player_impl.cc b/third_party/blink/renderer/platform/media/web_media_player_impl.cc
index 000c6017..83f51e76 100644
--- a/third_party/blink/renderer/platform/media/web_media_player_impl.cc
+++ b/third_party/blink/renderer/platform/media/web_media_player_impl.cc
@@ -212,7 +212,7 @@
     std::unique_ptr<media::MediaLog> media_log,
     std::unique_ptr<media::RendererFactorySelector> renderer_factory_selector,
     std::unique_ptr<WebSurfaceLayerBridge> bridge,
-    bool is_chunk_demuxer) {
+    absl::optional<media::DemuxerType> demuxer_type) {
   // We release `bridge` after pipeline stop to ensure layout tests receive
   // painted video frames before test harness exit.
   main_task_runner->DeleteSoon(FROM_HERE, std::move(bridge));
@@ -224,7 +224,7 @@
 
   // ChunkDemuxer can be deleted on any thread, but other demuxers are bound to
   // the main thread and must be deleted there now that the renderer is gone.
-  if (!is_chunk_demuxer) {
+  if (demuxer_type != media::DemuxerType::kChunkDemuxer) {
     main_task_runner->DeleteSoon(FROM_HERE, std::move(demuxer));
     main_task_runner->DeleteSoon(FROM_HERE, std::move(data_source));
     main_task_runner->DeleteSoon(FROM_HERE, std::move(cdm_context_1));
@@ -650,7 +650,7 @@
                      std::move(cdm_context_ref_),
                      std::move(pending_cdm_context_ref_), std::move(media_log_),
                      std::move(renderer_factory_selector_), std::move(bridge_),
-                     !!chunk_demuxer_));
+                     GetDemuxerType()));
 }
 
 WebMediaPlayer::LoadTiming WebMediaPlayerImpl::Load(
@@ -1075,7 +1075,7 @@
   //      never elided.
   if (paused_ && pipeline_controller_->IsStable() &&
       (paused_time_ == time || (ended_ && time == base::Seconds(Duration()))) &&
-      !chunk_demuxer_) {
+      GetDemuxerType() != media::DemuxerType::kChunkDemuxer) {
     if (old_state == kReadyStateHaveEnoughData) {
       // This will in turn SetReadyState() to signal the demuxer seek, followed
       // by timeChanged() to signal the renderer seek.
@@ -1309,8 +1309,9 @@
   // TimeDelta with potentially reduced precision (limited to Microseconds).
   // ChunkDemuxer returns the full-precision user-specified double. This ensures
   // users can "get" the exact duration they "set".
-  if (chunk_demuxer_)
-    return chunk_demuxer_->GetDuration();
+  if (GetDemuxerType() == media::DemuxerType::kChunkDemuxer) {
+    return static_cast<media::ChunkDemuxer*>(demuxer_.get())->GetDuration();
+  }
 
   base::TimeDelta pipeline_duration = GetPipelineMediaDuration();
   return pipeline_duration == media::kInfiniteDuration
@@ -1622,7 +1623,7 @@
   // For MSE/chunk_demuxer case the media track updates are handled by
   // WebSourceBufferImpl.
   DCHECK(demuxer_.get());
-  DCHECK(!chunk_demuxer_);
+  DCHECK(GetDemuxerType() != media::DemuxerType::kChunkDemuxer);
 
   // Report the media track information to blink. Only the first audio track and
   // the first video track are enabled by default to match blink logic.
@@ -1852,8 +1853,9 @@
 }
 
 void WebMediaPlayerImpl::OnChunkDemuxerOpened() {
+  // Note - this can't be CHECK_EQ because |GetDemuxerType| returns an optional
+  CHECK(GetDemuxerType() == media::DemuxerType::kChunkDemuxer);
   DCHECK(main_task_runner_->BelongsToCurrentThread());
-  CHECK_EQ(demuxer_->GetDemuxerType(), media::DemuxerType::kChunkDemuxer);
   client_->MediaSourceOpened(new WebMediaSourceImpl(
       static_cast<media::ChunkDemuxer*>(demuxer_.get())));
 }
@@ -1864,7 +1866,7 @@
   DCHECK(main_task_runner_->BelongsToCurrentThread());
   DCHECK(
       base::FeatureList::IsEnabled(media::kMemoryPressureBasedSourceBufferGC));
-  DCHECK(chunk_demuxer_);
+  DCHECK(GetDemuxerType() == media::DemuxerType::kChunkDemuxer);
 
   if (memory_pressure_level ==
       base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE) {
@@ -1885,15 +1887,17 @@
        memory_pressure_level ==
            base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
 
-  // base::Unretained is safe, since `chunk_demuxer_` is actually owned by
-  // `this` via this->demuxer_. Note the destruction of `chunk_demuxer_` is done
+  // base::Unretained is safe, since `demuxer_` is actually owned by
+  // `this` via this->demuxer_. Note the destruction of `demuxer_` is done
   // from ~WMPI by first hopping to `media_task_runner_` to prevent race with
   // this task.
   media_task_runner_->PostTask(
-      FROM_HERE, base::BindOnce(&media::ChunkDemuxer::OnMemoryPressure,
-                                base::Unretained(chunk_demuxer_),
-                                base::Seconds(CurrentTime()),
-                                memory_pressure_level, force_instant_gc));
+      FROM_HERE,
+      base::BindOnce(
+          &media::ChunkDemuxer::OnMemoryPressure,
+          base::Unretained(static_cast<media::ChunkDemuxer*>(demuxer_.get())),
+          base::Seconds(CurrentTime()), memory_pressure_level,
+          force_instant_gc));
 }
 
 void WebMediaPlayerImpl::OnFallback(media::PipelineStatus status) {
@@ -2251,7 +2255,7 @@
 bool WebMediaPlayerImpl::CanPlayThrough() {
   if (!base::FeatureList::IsEnabled(media::kSpecCompliantCanPlayThrough))
     return true;
-  if (chunk_demuxer_)
+  if (GetDemuxerType() == media::DemuxerType::kChunkDemuxer)
     return true;
   if (data_source_ && data_source_->AssumeFullyBuffered())
     return true;
@@ -2925,6 +2929,43 @@
 }
 #endif
 
+std::unique_ptr<Demuxer> WebMediaPlayerImpl::CreateChunkDemuxer() {
+  if (base::FeatureList::IsEnabled(media::kMemoryPressureBasedSourceBufferGC)) {
+    // base::Unretained is safe because `this` owns memory_pressure_listener_.
+    // TODO (crbug/1377053): Remove this. It doesn't appear to be used.
+    memory_pressure_listener_ = std::make_unique<base::MemoryPressureListener>(
+        FROM_HERE, base::BindRepeating(&WebMediaPlayerImpl::OnMemoryPressure,
+                                       base::Unretained(this)));
+  }
+
+  return std::make_unique<media::ChunkDemuxer>(
+      media::BindToCurrentLoop(base::BindOnce(
+          &WebMediaPlayerImpl::OnChunkDemuxerOpened, weak_this_)),
+      media::BindToCurrentLoop(
+          base::BindRepeating(&WebMediaPlayerImpl::OnProgress, weak_this_)),
+      media::BindToCurrentLoop(base::BindRepeating(
+          &WebMediaPlayerImpl::OnEncryptedMediaInitData, weak_this_)),
+      media_log_.get());
+}
+
+absl::optional<media::DemuxerType> WebMediaPlayerImpl::GetDemuxerType() const {
+  // Note: this can't be a ternary expression because the compiler throws a fit
+  // over type conversions.
+  if (demuxer_)
+    return demuxer_->GetDemuxerType();
+  return absl::nullopt;
+}
+
+#if BUILDFLAG(IS_ANDROID)
+std::unique_ptr<Demuxer> WebMediaPlayerImpl::CreateMediaUrlDemuxer(
+    bool expect_hls_content) {
+  return std::make_unique<media::MediaUrlDemuxer>(
+      media_task_runner_, loaded_url_, frame_->GetDocument().SiteForCookies(),
+      frame_->GetDocument().TopFrameOrigin(),
+      allow_media_player_renderer_credentials_, expect_hls_content);
+}
+#endif
+
 void WebMediaPlayerImpl::StartPipeline() {
   DCHECK(main_task_runner_->BelongsToCurrentThread());
 
@@ -2947,10 +2988,8 @@
     // reporter.
     video_decode_stats_reporter_.reset();
 
-    SetDemuxer(std::make_unique<media::MediaUrlDemuxer>(
-        media_task_runner_, loaded_url_, frame_->GetDocument().SiteForCookies(),
-        frame_->GetDocument().TopFrameOrigin(),
-        allow_media_player_renderer_credentials_, demuxer_found_hls_));
+    SetDemuxer(CreateMediaUrlDemuxer(demuxer_found_hls_));
+
     pipeline_controller_->Start(media::Pipeline::StartType::kNormal,
                                 demuxer_.get(), this, false, false);
     return;
@@ -2959,13 +2998,13 @@
 
   // Figure out which demuxer to use.
   if (demuxer_override_) {
-    DCHECK(!chunk_demuxer_);
-
+    // can't use absl::optional with DCHECK_NE.
+    DCHECK(GetDemuxerType() != media::DemuxerType::kChunkDemuxer);
     SetDemuxer(std::move(demuxer_override_));
     // TODO(https://crbug.com/1076267): Should everything else after this block
     // run in the demuxer override case?
   } else if (load_type_ != kLoadTypeMediaSource) {
-    DCHECK(!chunk_demuxer_);
+    DCHECK(GetDemuxerType() != media::DemuxerType::kChunkDemuxer);
     DCHECK(data_source_);
 #if BUILDFLAG(ENABLE_FFMPEG)
     SetDemuxer(CreateFFmpegDemuxer());
@@ -2974,35 +3013,16 @@
     return;
 #endif
   } else {
-    DCHECK(!chunk_demuxer_);
+    DCHECK(GetDemuxerType() != media::DemuxerType::kChunkDemuxer);
     DCHECK(!data_source_);
-
-    Demuxer::EncryptedMediaInitDataCB encrypted_media_init_data_cb =
-        media::BindToCurrentLoop(base::BindRepeating(
-            &WebMediaPlayerImpl::OnEncryptedMediaInitData, weak_this_));
-
-    chunk_demuxer_ = new media::ChunkDemuxer(
-        media::BindToCurrentLoop(base::BindOnce(
-            &WebMediaPlayerImpl::OnChunkDemuxerOpened, weak_this_)),
-        media::BindToCurrentLoop(
-            base::BindRepeating(&WebMediaPlayerImpl::OnProgress, weak_this_)),
-        encrypted_media_init_data_cb, media_log_.get());
-    SetDemuxer(std::unique_ptr<Demuxer>(chunk_demuxer_));
-
-    if (base::FeatureList::IsEnabled(
-            media::kMemoryPressureBasedSourceBufferGC)) {
-      // base::Unretained is safe because `this` owns memory_pressure_listener_.
-      memory_pressure_listener_ =
-          std::make_unique<base::MemoryPressureListener>(
-              FROM_HERE,
-              base::BindRepeating(&WebMediaPlayerImpl::OnMemoryPressure,
-                                  base::Unretained(this)));
-    }
+    SetDemuxer(CreateChunkDemuxer());
+    DCHECK(demuxer_);
   }
 
   // If possible attempt to avoid decoder spool up until playback starts.
   auto start_type = media::Pipeline::StartType::kNormal;
-  if (!chunk_demuxer_ && preload_ == media::DataSource::METADATA &&
+  if ((GetDemuxerType() != media::DemuxerType::kChunkDemuxer) &&
+      preload_ == media::DataSource::METADATA &&
       !client_->CouldPlayIfEnoughData() && !IsStreaming()) {
     start_type =
         (has_poster_ ||
@@ -3014,7 +3034,7 @@
 
   // TODO(sandersd): FileSystem objects may also be non-static, but due to our
   // caching layer such situations are broken already. http://crbug.com/593159
-  const bool is_static = !chunk_demuxer_;
+  const bool is_static = media::DemuxerType::kChunkDemuxer != GetDemuxerType();
 
   // ... and we're ready to go!
   // TODO(sandersd): On Android, defer Start() if the tab is not visible.
@@ -3495,7 +3515,8 @@
   watch_time_reporter_ = std::make_unique<WatchTimeReporter>(
       media::mojom::PlaybackProperties::New(
           pipeline_metadata_.has_audio, has_video, false, false,
-          !!chunk_demuxer_, is_encrypted_, embedded_media_experience_enabled_,
+          GetDemuxerType() == media::DemuxerType::kChunkDemuxer, is_encrypted_,
+          embedded_media_experience_enabled_,
           media::mojom::MediaStreamType::kNone),
       pipeline_metadata_.natural_size,
       base::BindRepeating(&WebMediaPlayerImpl::GetCurrentTimeInternal,
@@ -3860,7 +3881,7 @@
 }
 
 void WebMediaPlayerImpl::RecordUnderflowDuration(base::TimeDelta duration) {
-  DCHECK(data_source_ || chunk_demuxer_);
+  DCHECK(data_source_ || GetDemuxerType() == media::DemuxerType::kChunkDemuxer);
 
   if (data_source_)
     UMA_HISTOGRAM_TIMES("Media.UnderflowDuration2.SRC", duration);
@@ -3930,7 +3951,7 @@
 
 void WebMediaPlayerImpl::RecordTimingUMA(const std::string& key,
                                          base::TimeDelta elapsed) {
-  if (chunk_demuxer_)
+  if (GetDemuxerType() == media::DemuxerType::kChunkDemuxer)
     base::UmaHistogramMediumTimes(key + ".MSE", elapsed);
   else
     base::UmaHistogramMediumTimes(key + ".SRC", elapsed);
diff --git a/third_party/blink/renderer/platform/media/web_media_player_impl.h b/third_party/blink/renderer/platform/media/web_media_player_impl.h
index 9f40456a..2bb9156 100644
--- a/third_party/blink/renderer/platform/media/web_media_player_impl.h
+++ b/third_party/blink/renderer/platform/media/web_media_player_impl.h
@@ -26,6 +26,7 @@
 #include "build/build_config.h"
 #include "media/base/cdm_config.h"
 #include "media/base/data_source.h"
+#include "media/base/demuxer.h"
 #include "media/base/encryption_scheme.h"
 #include "media/base/media_observer.h"
 #include "media/base/media_tracks.h"
@@ -620,8 +621,8 @@
   void OnFirstFrame(base::TimeTicks frame_time);
 
   // Records timing metrics for three UMA metrics: #key.SRC, #key.MSE, and
-  // #key.EME. The SRC and MSE ones are mutually exclusive based on the presence
-  // of |chunk_demuxer_|, while the EME one is only recorded if |is_encrypted_|.
+  // #key.EME. The SRC and MSE ones are mutually exclusive based on
+  // the demuxer type, while the EME one is only recorded if |is_encrypted_|.
   void RecordTimingUMA(const std::string& key, base::TimeDelta elapsed);
 
   // Records the encryption scheme used by the stream |stream_name|. This is
@@ -669,11 +670,20 @@
   // Report UMAs when this object instance is destroyed.
   void ReportSessionUMAs() const;
 
-#if BUILDFLAG(ENABLE_FFMPEG)
   // Helper methods for creating demuxers to encapsulate build flags.
+  std::unique_ptr<media::Demuxer> CreateChunkDemuxer();
+
+#if BUILDFLAG(ENABLE_FFMPEG)
   std::unique_ptr<media::Demuxer> CreateFFmpegDemuxer();
 #endif
 
+#if BUILDFLAG(IS_ANDROID)
+  std::unique_ptr<media::Demuxer> CreateMediaUrlDemuxer(
+      bool expect_hls_content);
+#endif
+
+  absl::optional<media::DemuxerType> GetDemuxerType() const;
+
   WebLocalFrame* const frame_;
 
   WebMediaPlayer::NetworkState network_state_ =
@@ -799,16 +809,13 @@
   // Routes audio playback to either AudioRendererSink or WebAudio.
   scoped_refptr<WebAudioSourceProviderImpl> audio_source_provider_;
 
-  // These two are mutually exclusive:
-  //   |data_source_| is used for regular resource loads.
-  //   |chunk_demuxer_| is used for Media Source resource loads.
-  //
-  // |demuxer_| will contain the appropriate demuxer based on which resource
-  // load strategy we're using.
+  // |demuxer_| holds the the appropriate demuxer based on which resource load
+  // strategy we're using.
+  std::unique_ptr<media::Demuxer> demuxer_;
+
+  // |data_source_| will be null if we're using the ChunkDemuxer.
   MultiBufferDataSource* mb_data_source_ = nullptr;
   std::unique_ptr<media::DataSource> data_source_;
-  std::unique_ptr<media::Demuxer> demuxer_;
-  media::ChunkDemuxer* chunk_demuxer_ = nullptr;
 
   std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_;
 
diff --git a/third_party/blink/renderer/platform/transforms/transformation_matrix.cc b/third_party/blink/renderer/platform/transforms/transformation_matrix.cc
index 3570976..609c6d7 100644
--- a/third_party/blink/renderer/platform/transforms/transformation_matrix.cc
+++ b/third_party/blink/renderer/platform/transforms/transformation_matrix.cc
@@ -727,8 +727,13 @@
 
     // Translation.
     if (!check_invertibility_only) {
-      result->MakeIdentity();
-      result->Translate3d(-matrix_[3][0], -matrix_[3][1], -matrix_[3][2]);
+      if (result != this)
+        result->MakeIdentity();
+      // Use `0.0 - component` to avoid -0 for 0 components. Not a big deal,
+      // but just to keep the original behavior.
+      result->matrix_[3][0] = 0.0 - matrix_[3][0];
+      result->matrix_[3][1] = 0.0 - matrix_[3][1];
+      result->matrix_[3][2] = 0.0 - matrix_[3][2];
     }
     return true;
   }
diff --git a/third_party/blink/tools/BUILD.gn b/third_party/blink/tools/BUILD.gn
index 8847c58..41485e0 100644
--- a/third_party/blink/tools/BUILD.gn
+++ b/third_party/blink/tools/BUILD.gn
@@ -26,7 +26,11 @@
 
     # The web_tests/wpt_internal directory contains internal WPTs
     "//third_party/blink/web_tests/wpt_internal/",
+
+    # Configuration files
     "//third_party/blink/web_tests/wptrunner.blink.ini",
+    "//third_party/blink/web_tests/FlagSpecificConfig",
+    "//third_party/blink/web_tests/SmokeTests/",
 
     # Include the root vpython spec.
     "//.vpython3",
diff --git a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
index ff841dfa..bf253ed 100644
--- a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
+++ b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
@@ -2266,6 +2266,8 @@
 crbug.com/1303102 virtual/document-transition/wpt_internal/document-transition/new-content-captures-different-size.html [ Skip ]
 crbug.com/1303102 virtual/document-transition/wpt_internal/document-transition/old-content-captures-different-size.html [ Skip ]
 crbug.com/1377777 virtual/document-transition/wpt_internal/document-transition/content-with-inline-child.html [ Skip ]
+crbug.com/1321217 virtual/document-transition-wide-gamut/wpt_internal/document-transition/element-with-overflow.html [ Skip ]
+crbug.com/1321217 virtual/document-transition/wpt_internal/document-transition/element-with-overflow.html [ Skip ]
 
 crbug.com/1303102 virtual/document-transition-wide-gamut/wpt_internal/document-transition/old-content-captures-different-size.html [ Skip ]
 crbug.com/1303102 virtual/document-transition-wide-gamut/wpt_internal/document-transition/new-content-captures-different-size.html [ Skip ]
diff --git a/third_party/blink/web_tests/FlagExpectations/highdpi b/third_party/blink/web_tests/FlagExpectations/highdpi
index d4a7825..347dd22 100644
--- a/third_party/blink/web_tests/FlagExpectations/highdpi
+++ b/third_party/blink/web_tests/FlagExpectations/highdpi
@@ -72,6 +72,7 @@
 crbug.com/1353771 virtual/document-transition-wide-gamut/wpt_internal/document-transition/old-content-with-overflow-zoomed.html [ Failure ]
 crbug.com/1351422 virtual/document-transition/wpt_internal/document-transition/content-visibility-auto-shared-element.html [ Failure ]
 crbug.com/1351422 virtual/document-transition-wide-gamut/wpt_internal/document-transition/content-visibility-auto-shared-element.html [ Failure ]
+crbug.com/1353771 virtual/document-transition/wpt_internal/document-transition/element-with-overflow.html [ Failure ]
 
 crbug.com/1314903 external/wpt/css/css-sizing/contain-intrinsic-size/animation/contain-intrinsic-size-interpolation.html [ Failure ]
 crbug.com/1314903 external/wpt/css/css-sizing/contain-intrinsic-size/contain-intrinsic-size-009.html [ Failure ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 3d741fe..4b81ede 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -2668,18 +2668,9 @@
 crbug.com/604875 external/wpt/css/css-images/tiled-gradients.html [ Failure ]
 
 # CSS Color 4 interpolations
-crbug.com/1362022 external/wpt/css/css-images/gradient/gradient-eval-002.html [ Failure ]
-crbug.com/1358565 external/wpt/css/css-images/gradient/gradient-eval-003.html [ Failure ]
 crbug.com/1362022 external/wpt/css/css-images/gradient/gradient-eval-004.html [ Failure ]
-crbug.com/1362022 external/wpt/css/css-images/gradient/gradient-eval-005.html [ Failure ]
 crbug.com/1362022 external/wpt/css/css-images/gradient/gradient-eval-006.html [ Failure ]
-crbug.com/1362022 external/wpt/css/css-images/gradient/gradient-eval-007.html [ Failure ]
 crbug.com/1362022 external/wpt/css/css-images/gradient/gradient-eval-008.html [ Failure ]
-crbug.com/1362022 external/wpt/css/css-images/gradient/gradient-eval-009.html [ Failure ]
-crbug.com/1362022 external/wpt/css/css-images/gradient/css-color-4-colors-default-to-oklab-gradient.html [ Failure ]
-crbug.com/1362022 external/wpt/css/css-images/gradient/oklab-gradient.html [ Failure ]
-crbug.com/1362022 external/wpt/css/css-images/gradient/srgb-linear-gradient.html [ Failure ]
-crbug.com/1362022 external/wpt/css/css-images/gradient/xyz-gradient.html [ Failure ]
 
 crbug.com/808834 [ Linux ] external/wpt/css/css-pseudo/first-letter-001.html [ Failure ]
 crbug.com/808834 [ Win ] external/wpt/css/css-pseudo/first-letter-001.html [ Failure ]
@@ -3383,7 +3374,7 @@
 crbug.com/626703 external/wpt/css/css-contain/content-visibility/content-visibility-060.html [ Failure ]
 crbug.com/626703 external/wpt/css/css-contain/content-visibility/content-visibility-061.html [ Failure ]
 crbug.com/626703 external/wpt/css/css-contain/content-visibility/content-visibility-062.html [ Failure ]
-crbug.com/626703 crbug.com/1380449 external/wpt/css/css-contain/content-visibility/content-visibility-063.html [ Failure Crash ]
+crbug.com/626703 crbug.com/1380449 external/wpt/css/css-contain/content-visibility/content-visibility-063.html [ Crash Failure ]
 crbug.com/626703 external/wpt/css/css-contain/content-visibility/content-visibility-065.html [ Failure ]
 crbug.com/626703 external/wpt/css/css-contain/content-visibility/content-visibility-066.html [ Failure ]
 crbug.com/626703 external/wpt/css/css-contain/content-visibility/content-visibility-067.html [ Failure ]
@@ -3392,7 +3383,7 @@
 crbug.com/626703 virtual/offsetparent-old-behavior/external/wpt/css/css-contain/content-visibility/content-visibility-060.html [ Failure ]
 crbug.com/626703 virtual/offsetparent-old-behavior/external/wpt/css/css-contain/content-visibility/content-visibility-061.html [ Failure ]
 crbug.com/626703 virtual/offsetparent-old-behavior/external/wpt/css/css-contain/content-visibility/content-visibility-062.html [ Failure ]
-crbug.com/626703 crbug.com/1380449 virtual/offsetparent-old-behavior/external/wpt/css/css-contain/content-visibility/content-visibility-063.html [ Failure Crash ]
+crbug.com/626703 crbug.com/1380449 virtual/offsetparent-old-behavior/external/wpt/css/css-contain/content-visibility/content-visibility-063.html [ Crash Failure ]
 crbug.com/626703 virtual/offsetparent-old-behavior/external/wpt/css/css-contain/content-visibility/content-visibility-065.html [ Failure ]
 crbug.com/626703 virtual/offsetparent-old-behavior/external/wpt/css/css-contain/content-visibility/content-visibility-066.html [ Failure ]
 crbug.com/626703 virtual/offsetparent-old-behavior/external/wpt/css/css-contain/content-visibility/content-visibility-067.html [ Failure ]
@@ -5186,7 +5177,7 @@
 crbug.com/1079188 external/wpt/fetch/stale-while-revalidate/revalidate-not-blocked-by-csp.html [ Timeout ]
 
 # the inspector-protocol/media tests only work in the virtual test environment.
-crbug.com/1074129 inspector-protocol/media/media-player.js [ Timeout ]
+crbug.com/1074129 inspector-protocol/media/media-player.js [ Skip Timeout ]
 
 # Sheriff 2020-05-04
 crbug.com/952717 [ Debug ] http/tests/xmlhttprequest/redirect-cross-origin-post.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
index 9e45982..b7338d3 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -73533,6 +73533,19 @@
        {}
       ]
      ],
+     "anchor-scroll-fixedpos.tentative.html": [
+      "ee7d22608b65570fe075e02542dbd877cd38cd82",
+      [
+       null,
+       [
+        [
+         "/css/css-anchor-position/reference/anchor-scroll-fixedpos-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
      "anchor-scroll-nested.tentative.html": [
       "964b02a5b04845537c2a98c5df2defe5b820483b",
       [
@@ -269337,6 +269350,10 @@
       []
      ],
      "reference": {
+      "anchor-scroll-fixedpos-ref.html": [
+       "e73354df72dac33f7a94eaef445e80ec61e3976a",
+       []
+      ],
       "anchor-scroll-nested-ref.html": [
        "6190258f3cb50d4048eb843ba7c68ff191317b6f",
        []
@@ -309152,7 +309169,7 @@
      []
     ],
     "idlharness.window_exclude=Node-expected.txt": [
-     "836b44069385d6046702df10689ebd2b76c24c6d",
+     "aedf9a5a825e052b3b42562bc9c69897390155e3",
      []
     ],
     "lists": {
@@ -343238,7 +343255,7 @@
      []
     ],
     "getdisplaymedia.https-expected.txt": [
-     "22a39e4a36601eae5cb351484a1f999c6a0686f4",
+     "018ec4e3b250f00f86d030d273d9845c9d0384d9",
      []
     ]
    },
@@ -353500,7 +353517,7 @@
      []
     ],
     "supported-stats-expected.txt": [
-     "da29e157ffccf735fcdecc43185def5ad340c8eb",
+     "20f579d987325f9459ed590a26893da5c1fc0736",
      []
     ]
    },
@@ -426771,7 +426788,7 @@
      ]
     ],
     "idlharness.window.js": [
-     "c73fbf217568726acd563361c0764cb420bd9218",
+     "2c7bfd727e85bde896e31bbef9ddec20b89bf3b4",
      [
       "dom/idlharness.window.html?exclude=Node",
       {
@@ -514993,6 +515010,43 @@
       null,
       {}
      ]
+    ],
+    "web-font-styled-text-resize-block.html": [
+     "572442f2a2cd4c83b8c21cbf57817f413e791b06",
+     [
+      null,
+      {}
+     ]
+    ],
+    "web-font-styled-text-resize-swap-after-interaction.html": [
+     "3ba02bab5ac331913b0570e5c911e9d5b4570fe9",
+     [
+      null,
+      {
+       "testdriver": true
+      }
+     ]
+    ],
+    "web-font-styled-text-resize-swap-smaller.html": [
+     "253038eb8d1b1c6f6b15c28fc7473f5d22cb1720",
+     [
+      null,
+      {}
+     ]
+    ],
+    "web-font-styled-text-resize-swap-subnode.html": [
+     "eca5f3590f3b1b84c8a1f4bbd22876ebcf8a26d0",
+     [
+      null,
+      {}
+     ]
+    ],
+    "web-font-styled-text-resize-swap.html": [
+     "61c00fad20a375bb22338b24d7814fcc0832edac",
+     [
+      null,
+      {}
+     ]
     ]
    },
    "layout-instability": {
@@ -547712,7 +547766,7 @@
      ]
     ],
     "getdisplaymedia.https.html": [
-     "ad6cf480e536ebf31c0ceebba72815a88eb3659c",
+     "6affada28ee3e4db49e03f7b24eda1b3aaa3b75a",
      [
       null,
       {
@@ -584146,7 +584200,7 @@
      ]
     ],
     "supported-stats.html": [
-     "2da52a1885e3a78b7c08f2468ae1ef0f54736cf5",
+     "7370306c519de59d9574c87796457bad4f28fe0a",
      [
       null,
       {
diff --git a/third_party/blink/web_tests/external/wpt/credential-management/fedcm-network-requests.https.html b/third_party/blink/web_tests/external/wpt/credential-management/fedcm-network-requests.https.html
index 46065eb..2d1d72d 100644
--- a/third_party/blink/web_tests/external/wpt/credential-management/fedcm-network-requests.https.html
+++ b/third_party/blink/web_tests/external/wpt/credential-management/fedcm-network-requests.https.html
@@ -3,6 +3,7 @@
 <link rel="help" href="https://fedidcg.github.io/FedCM">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
+<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
 
 <body>
 
@@ -12,6 +13,15 @@
         select_manifest,
         set_fedcm_cookie} from './support/fedcm-helper.sub.js';
 
+function loadUrlInIframe(url) {
+  let iframe = document.createElement("iframe");
+  return new Promise(resolve => {
+    iframe.src = url;
+    iframe.onload = function() { resolve(iframe); };
+    document.body.appendChild(iframe);
+  });
+}
+
 fedcm_test(async t => {
   const cred = await navigator.credentials.get(default_request_options());
   assert_equals(cred.token, "token");
@@ -152,4 +162,30 @@
 // cached, when the user visits the IDP as a first party, the IDP would be able to determine the
 // last RP the user visited regardless of whether the user granted consent via the FedCM prompt.
 
+fedcm_test(async t => {
+  const service_worker_url = 'support/fedcm/intercept_service_worker.js';
+  const sw_scope_url = '/credential-management/support/fedcm/';
+  // URL for querying number of page loads observed by service worker.
+  const query_sw_intercepts_url = 'support/fedcm/query_service_worker_intercepts.html';
+  const page_in_sw_scope_url = 'support/fedcm/simple.html';
+
+  const sw_registration = await service_worker_unregister_and_register(
+      t, service_worker_url, sw_scope_url);
+  t.add_cleanup(() => service_worker_unregister(t, sw_scope_url));
+  await wait_for_state(t, sw_registration.installing, 'activated');
+
+  // Verify that service worker works.
+  await loadUrlInIframe(page_in_sw_scope_url);
+  let query_sw_iframe = await loadUrlInIframe(query_sw_intercepts_url);
+  assert_equals(query_sw_iframe.contentDocument.body.textContent, "1");
+
+  await set_fedcm_cookie();
+  const cred = await navigator.credentials.get(default_request_options());
+  assert_equals(cred.token, "token");
+
+  // Use cache buster query parameter to avoid cached response.
+  let query_sw_iframe2 = await loadUrlInIframe(query_sw_intercepts_url + "?2");
+  assert_equals(query_sw_iframe2.contentDocument.body.textContent, "1");
+}, 'Test that service worker cannot observe fetches performed by FedCM API');
+
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/intercept_service_worker.js b/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/intercept_service_worker.js
new file mode 100644
index 0000000..773e38f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/intercept_service_worker.js
@@ -0,0 +1,10 @@
+var num_overridden = 0;
+
+self.addEventListener('fetch', event => {
+  const url = event.request.url;
+  if (url.indexOf('query_service_worker_intercepts.html') != -1) {
+    event.respondWith(new Response(num_overridden));
+  } else if (url.indexOf('credential-management/support') != -1) {
+    ++num_overridden;
+  }
+});
diff --git a/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/simple.html b/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/simple.html
new file mode 100644
index 0000000..d62419ce
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/simple.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<html><body>
+Simple
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-color-mix-function-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-color-mix-function-expected.txt
index b261cc4..9f50874 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-color-mix-function-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-color-mix-function-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 474 tests; 0 PASS, 474 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 450 tests; 0 PASS, 450 FAIL, 0 TIMEOUT, 0 NOTRUN.
 FAIL e.style['color'] = "color-mix(in hsl, hsl(120deg 10% 20%), hsl(30deg 30% 40%))" should set the property value assert_equals: serialization should be canonical expected "rgb(84, 92, 61)" but got "color-mix(hsl, rgb(46, 56, 46), rgb(133, 102, 71))"
 FAIL e.style['color'] = "color-mix(in hsl, hsl(120deg 10% 20%) 25%, hsl(30deg 30% 40%))" should set the property value assert_equals: serialization should be canonical expected "rgb(112, 106, 67)" but got "color-mix(hsl, rgb(46, 56, 46) 25%, rgb(133, 102, 71))"
 FAIL e.style['color'] = "color-mix(in hsl, 25% hsl(120deg 10% 20%), hsl(30deg 30% 40%))" should set the property value assert_not_equals: property should be set got disallowed value ""
@@ -48,12 +48,6 @@
 FAIL e.style['color'] = "color-mix(in hsl decreasing hue, hsl(330deg 50% 50%), hsl(50deg 50% 50%))" should set the property value assert_equals: serialization should be canonical expected "rgb(64, 170, 191)" but got "color-mix(hsl decreasing hue, rgb(191, 64, 128), rgb(191, 170, 64))"
 FAIL e.style['color'] = "color-mix(in hsl decreasing hue, hsl(20deg 50% 50%), hsl(320deg 50% 50%))" should set the property value assert_equals: serialization should be canonical expected "rgb(191, 64, 85)" but got "color-mix(hsl decreasing hue, rgb(191, 106, 64), rgb(191, 64, 149))"
 FAIL e.style['color'] = "color-mix(in hsl decreasing hue, hsl(320deg 50% 50%), hsl(20deg 50% 50%))" should set the property value assert_equals: serialization should be canonical expected "rgb(64, 191, 170)" but got "color-mix(hsl decreasing hue, rgb(191, 64, 149), rgb(191, 106, 64))"
-FAIL e.style['color'] = "color-mix(in hsl specified hue, hsl(40deg 50% 50%), hsl(60deg 50% 50%))" should set the property value assert_equals: serialization should be canonical expected "rgb(191, 170, 64)" but got "color-mix(hsl specified hue, rgb(191, 149, 64), rgb(191, 191, 64))"
-FAIL e.style['color'] = "color-mix(in hsl specified hue, hsl(60deg 50% 50%), hsl(40deg 50% 50%))" should set the property value assert_equals: serialization should be canonical expected "rgb(191, 170, 64)" but got "color-mix(hsl specified hue, rgb(191, 191, 64), rgb(191, 149, 64))"
-FAIL e.style['color'] = "color-mix(in hsl specified hue, hsl(50deg 50% 50%), hsl(330deg 50% 50%))" should set the property value assert_equals: serialization should be canonical expected "rgb(64, 170, 191)" but got "color-mix(hsl specified hue, rgb(191, 170, 64), rgb(191, 64, 128))"
-FAIL e.style['color'] = "color-mix(in hsl specified hue, hsl(330deg 50% 50%), hsl(50deg 50% 50%))" should set the property value assert_equals: serialization should be canonical expected "rgb(64, 170, 191)" but got "color-mix(hsl specified hue, rgb(191, 64, 128), rgb(191, 170, 64))"
-FAIL e.style['color'] = "color-mix(in hsl specified hue, hsl(20deg 50% 50%), hsl(320deg 50% 50%))" should set the property value assert_equals: serialization should be canonical expected "rgb(64, 191, 170)" but got "color-mix(hsl specified hue, rgb(191, 106, 64), rgb(191, 64, 149))"
-FAIL e.style['color'] = "color-mix(in hsl specified hue, hsl(320deg 50% 50%), hsl(20deg 50% 50%))" should set the property value assert_equals: serialization should be canonical expected "rgb(64, 191, 170)" but got "color-mix(hsl specified hue, rgb(191, 64, 149), rgb(191, 106, 64))"
 FAIL e.style['color'] = "color-mix(in hsl, hsl(none none none), hsl(none none none))" should set the property value assert_equals: serialization should be canonical expected "rgb(0, 0, 0)" but got "color-mix(hsl, rgb(0, 0, 0), rgb(0, 0, 0))"
 FAIL e.style['color'] = "color-mix(in hsl, hsl(none none none), hsl(30deg 40% 80%))" should set the property value assert_equals: serialization should be canonical expected "rgb(224, 204, 184)" but got "color-mix(hsl, rgb(0, 0, 0), rgb(224, 204, 184))"
 FAIL e.style['color'] = "color-mix(in hsl, hsl(120deg 20% 40%), hsl(none none none))" should set the property value assert_equals: serialization should be canonical expected "rgb(82, 122, 82)" but got "color-mix(hsl, rgb(82, 122, 82), rgb(0, 0, 0))"
@@ -120,12 +114,6 @@
 FAIL e.style['color'] = "color-mix(in hwb decreasing hue, hwb(330deg 30% 40%), hwb(50deg 30% 40%))" should set the property value assert_equals: serialization should be canonical expected "rgb(77, 140, 153)" but got "color-mix(hwb decreasing hue, rgb(153, 77, 115), rgb(153, 140, 77))"
 FAIL e.style['color'] = "color-mix(in hwb decreasing hue, hwb(20deg 30% 40%), hwb(320deg 30% 40%))" should set the property value assert_equals: serialization should be canonical expected "rgb(153, 77, 89)" but got "color-mix(hwb decreasing hue, rgb(153, 102, 77), rgb(153, 77, 127))"
 FAIL e.style['color'] = "color-mix(in hwb decreasing hue, hwb(320deg 30% 40%), hwb(20deg 30% 40%))" should set the property value assert_equals: serialization should be canonical expected "rgb(77, 153, 140)" but got "color-mix(hwb decreasing hue, rgb(153, 77, 127), rgb(153, 102, 77))"
-FAIL e.style['color'] = "color-mix(in hwb specified hue, hwb(40deg 30% 40%), hwb(60deg 30% 40%))" should set the property value assert_equals: serialization should be canonical expected "rgb(153, 140, 77)" but got "color-mix(hwb specified hue, rgb(153, 128, 77), rgb(153, 153, 77))"
-FAIL e.style['color'] = "color-mix(in hwb specified hue, hwb(60deg 30% 40%), hwb(40deg 30% 40%))" should set the property value assert_equals: serialization should be canonical expected "rgb(153, 140, 77)" but got "color-mix(hwb specified hue, rgb(153, 153, 77), rgb(153, 128, 77))"
-FAIL e.style['color'] = "color-mix(in hwb specified hue, hwb(50deg 30% 40%), hwb(330deg 30% 40%))" should set the property value assert_equals: serialization should be canonical expected "rgb(77, 140, 153)" but got "color-mix(hwb specified hue, rgb(153, 140, 77), rgb(153, 77, 115))"
-FAIL e.style['color'] = "color-mix(in hwb specified hue, hwb(330deg 30% 40%), hwb(50deg 30% 40%))" should set the property value assert_equals: serialization should be canonical expected "rgb(77, 140, 153)" but got "color-mix(hwb specified hue, rgb(153, 77, 115), rgb(153, 140, 77))"
-FAIL e.style['color'] = "color-mix(in hwb specified hue, hwb(20deg 30% 40%), hwb(320deg 30% 40%))" should set the property value assert_equals: serialization should be canonical expected "rgb(77, 153, 140)" but got "color-mix(hwb specified hue, rgb(153, 102, 77), rgb(153, 77, 127))"
-FAIL e.style['color'] = "color-mix(in hwb specified hue, hwb(320deg 30% 40%), hwb(20deg 30% 40%))" should set the property value assert_equals: serialization should be canonical expected "rgb(77, 153, 140)" but got "color-mix(hwb specified hue, rgb(153, 77, 127), rgb(153, 102, 77))"
 FAIL e.style['color'] = "color-mix(in hwb, hwb(none none none), hwb(none none none))" should set the property value assert_equals: serialization should be canonical expected "rgb(255, 0, 0)" but got "color-mix(hwb, rgb(255, 0, 0), rgb(255, 0, 0))"
 FAIL e.style['color'] = "color-mix(in hwb, hwb(none none none), hwb(30deg 30% 40%))" should set the property value assert_equals: serialization should be canonical expected "rgb(153, 115, 77)" but got "color-mix(hwb, rgb(255, 0, 0), rgb(153, 115, 77))"
 FAIL e.style['color'] = "color-mix(in hwb, hwb(120deg 10% 20%), hwb(none none none))" should set the property value assert_equals: serialization should be canonical expected "rgb(26, 204, 26)" but got "color-mix(hwb, rgb(26, 204, 26), rgb(255, 0, 0))"
@@ -192,12 +180,6 @@
 FAIL e.style['color'] = "color-mix(in lch decreasing hue, lch(100 0 330deg), lch(100 0 50deg))" should set the property value assert_equals: serialization should be canonical expected "lch(100 0 190)" but got "color-mix(lch decreasing hue, lch(100 0 330), lch(100 0 50))"
 FAIL e.style['color'] = "color-mix(in lch decreasing hue, lch(100 0 20deg), lch(100 0 320deg))" should set the property value assert_equals: serialization should be canonical expected "lch(100 0 350)" but got "color-mix(lch decreasing hue, lch(100 0 20), lch(100 0 320))"
 FAIL e.style['color'] = "color-mix(in lch decreasing hue, lch(100 0 320deg), lch(100 0 20deg))" should set the property value assert_equals: serialization should be canonical expected "lch(100 0 170)" but got "color-mix(lch decreasing hue, lch(100 0 320), lch(100 0 20))"
-FAIL e.style['color'] = "color-mix(in lch specified hue, lch(100 0 40deg), lch(100 0 60deg))" should set the property value assert_equals: serialization should be canonical expected "lch(100 0 50)" but got "color-mix(lch specified hue, lch(100 0 40), lch(100 0 60))"
-FAIL e.style['color'] = "color-mix(in lch specified hue, lch(100 0 60deg), lch(100 0 40deg))" should set the property value assert_equals: serialization should be canonical expected "lch(100 0 50)" but got "color-mix(lch specified hue, lch(100 0 60), lch(100 0 40))"
-FAIL e.style['color'] = "color-mix(in lch specified hue, lch(100 0 50deg), lch(100 0 330deg))" should set the property value assert_equals: serialization should be canonical expected "lch(100 0 190)" but got "color-mix(lch specified hue, lch(100 0 50), lch(100 0 330))"
-FAIL e.style['color'] = "color-mix(in lch specified hue, lch(100 0 330deg), lch(100 0 50deg))" should set the property value assert_equals: serialization should be canonical expected "lch(100 0 190)" but got "color-mix(lch specified hue, lch(100 0 330), lch(100 0 50))"
-FAIL e.style['color'] = "color-mix(in lch specified hue, lch(100 0 20deg), lch(100 0 320deg))" should set the property value assert_equals: serialization should be canonical expected "lch(100 0 170)" but got "color-mix(lch specified hue, lch(100 0 20), lch(100 0 320))"
-FAIL e.style['color'] = "color-mix(in lch specified hue, lch(100 0 320deg), lch(100 0 20deg))" should set the property value assert_equals: serialization should be canonical expected "lch(100 0 170)" but got "color-mix(lch specified hue, lch(100 0 320), lch(100 0 20))"
 FAIL e.style['color'] = "color-mix(in lch, lch(none none none), lch(none none none))" should set the property value assert_equals: serialization should be canonical expected "lch(none none none)" but got "color-mix(lch, lch(none none none), lch(none none none))"
 FAIL e.style['color'] = "color-mix(in lch, lch(none none none), lch(50 60 70deg))" should set the property value assert_equals: serialization should be canonical expected "lch(50 60 70)" but got "color-mix(lch, lch(none none none), lch(50 60 70))"
 FAIL e.style['color'] = "color-mix(in lch, lch(10 20 30deg), lch(none none none))" should set the property value assert_equals: serialization should be canonical expected "lch(10 20 30)" but got "color-mix(lch, lch(10 20 30), lch(none none none))"
@@ -255,12 +237,6 @@
 FAIL e.style['color'] = "color-mix(in oklch decreasing hue, oklch(100 0 330deg), oklch(100 0 50deg))" should set the property value assert_equals: serialization should be canonical expected "oklch(100 0 190)" but got "color-mix(oklch decreasing hue, oklch(100 0 330), oklch(100 0 50))"
 FAIL e.style['color'] = "color-mix(in oklch decreasing hue, oklch(100 0 20deg), oklch(100 0 320deg))" should set the property value assert_equals: serialization should be canonical expected "oklch(100 0 350)" but got "color-mix(oklch decreasing hue, oklch(100 0 20), oklch(100 0 320))"
 FAIL e.style['color'] = "color-mix(in oklch decreasing hue, oklch(100 0 320deg), oklch(100 0 20deg))" should set the property value assert_equals: serialization should be canonical expected "oklch(100 0 170)" but got "color-mix(oklch decreasing hue, oklch(100 0 320), oklch(100 0 20))"
-FAIL e.style['color'] = "color-mix(in oklch specified hue, oklch(100 0 40deg), oklch(100 0 60deg))" should set the property value assert_equals: serialization should be canonical expected "oklch(100 0 50)" but got "color-mix(oklch specified hue, oklch(100 0 40), oklch(100 0 60))"
-FAIL e.style['color'] = "color-mix(in oklch specified hue, oklch(100 0 60deg), oklch(100 0 40deg))" should set the property value assert_equals: serialization should be canonical expected "oklch(100 0 50)" but got "color-mix(oklch specified hue, oklch(100 0 60), oklch(100 0 40))"
-FAIL e.style['color'] = "color-mix(in oklch specified hue, oklch(100 0 50deg), oklch(100 0 330deg))" should set the property value assert_equals: serialization should be canonical expected "oklch(100 0 190)" but got "color-mix(oklch specified hue, oklch(100 0 50), oklch(100 0 330))"
-FAIL e.style['color'] = "color-mix(in oklch specified hue, oklch(100 0 330deg), oklch(100 0 50deg))" should set the property value assert_equals: serialization should be canonical expected "oklch(100 0 190)" but got "color-mix(oklch specified hue, oklch(100 0 330), oklch(100 0 50))"
-FAIL e.style['color'] = "color-mix(in oklch specified hue, oklch(100 0 20deg), oklch(100 0 320deg))" should set the property value assert_equals: serialization should be canonical expected "oklch(100 0 170)" but got "color-mix(oklch specified hue, oklch(100 0 20), oklch(100 0 320))"
-FAIL e.style['color'] = "color-mix(in oklch specified hue, oklch(100 0 320deg), oklch(100 0 20deg))" should set the property value assert_equals: serialization should be canonical expected "oklch(100 0 170)" but got "color-mix(oklch specified hue, oklch(100 0 320), oklch(100 0 20))"
 FAIL e.style['color'] = "color-mix(in oklch, oklch(none none none), oklch(none none none))" should set the property value assert_equals: serialization should be canonical expected "oklch(none none none)" but got "color-mix(oklch, oklch(none none none), oklch(none none none))"
 FAIL e.style['color'] = "color-mix(in oklch, oklch(none none none), oklch(50 60 70deg))" should set the property value assert_equals: serialization should be canonical expected "oklch(50 60 70)" but got "color-mix(oklch, oklch(none none none), oklch(50 60 70))"
 FAIL e.style['color'] = "color-mix(in oklch, oklch(10 20 30deg), oklch(none none none))" should set the property value assert_equals: serialization should be canonical expected "oklch(10 20 30)" but got "color-mix(oklch, oklch(10 20 30), oklch(none none none))"
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-color-mix-function.html b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-color-mix-function.html
index b1027a66..76209b1 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-color-mix-function.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-color-mix-function.html
@@ -81,13 +81,6 @@
     test_valid_value(`color`, `color-mix(in hsl decreasing hue, hsl(20deg 50% 50%), hsl(320deg 50% 50%))`, canonicalize(`hsl(350deg 50% 50%)`));
     test_valid_value(`color`, `color-mix(in hsl decreasing hue, hsl(320deg 50% 50%), hsl(20deg 50% 50%))`, canonicalize(`hsl(170deg 50% 50%)`));
 
-    test_valid_value(`color`, `color-mix(in hsl specified hue, hsl(40deg 50% 50%), hsl(60deg 50% 50%))`, canonicalize(`hsl(50deg 50% 50%)`));
-    test_valid_value(`color`, `color-mix(in hsl specified hue, hsl(60deg 50% 50%), hsl(40deg 50% 50%))`, canonicalize(`hsl(50deg 50% 50%)`));
-    test_valid_value(`color`, `color-mix(in hsl specified hue, hsl(50deg 50% 50%), hsl(330deg 50% 50%))`, canonicalize(`hsl(190deg 50% 50%)`));
-    test_valid_value(`color`, `color-mix(in hsl specified hue, hsl(330deg 50% 50%), hsl(50deg 50% 50%))`, canonicalize(`hsl(190deg 50% 50%)`));
-    test_valid_value(`color`, `color-mix(in hsl specified hue, hsl(20deg 50% 50%), hsl(320deg 50% 50%))`, canonicalize(`hsl(170deg 50% 50%)`));
-    test_valid_value(`color`, `color-mix(in hsl specified hue, hsl(320deg 50% 50%), hsl(20deg 50% 50%))`, canonicalize(`hsl(170deg 50% 50%)`));
-
     test_valid_value(`color`, `color-mix(in hsl, hsl(none none none), hsl(none none none))`, canonicalize(`hsl(none none none)`));
     test_valid_value(`color`, `color-mix(in hsl, hsl(none none none), hsl(30deg 40% 80%))`, canonicalize(`hsl(30deg 40% 80%)`));
     test_valid_value(`color`, `color-mix(in hsl, hsl(120deg 20% 40%), hsl(none none none))`, canonicalize(`hsl(120deg 20% 40%)`));
@@ -165,13 +158,6 @@
     test_valid_value(`color`, `color-mix(in hwb decreasing hue, hwb(20deg 30% 40%), hwb(320deg 30% 40%))`, canonicalize(`hwb(350deg 30% 40%)`));
     test_valid_value(`color`, `color-mix(in hwb decreasing hue, hwb(320deg 30% 40%), hwb(20deg 30% 40%))`, canonicalize(`hwb(170deg 30% 40%)`));
 
-    test_valid_value(`color`, `color-mix(in hwb specified hue, hwb(40deg 30% 40%), hwb(60deg 30% 40%))`, canonicalize(`hwb(50deg 30% 40%)`));
-    test_valid_value(`color`, `color-mix(in hwb specified hue, hwb(60deg 30% 40%), hwb(40deg 30% 40%))`, canonicalize(`hwb(50deg 30% 40%)`));
-    test_valid_value(`color`, `color-mix(in hwb specified hue, hwb(50deg 30% 40%), hwb(330deg 30% 40%))`, canonicalize(`hwb(190deg 30% 40%)`));
-    test_valid_value(`color`, `color-mix(in hwb specified hue, hwb(330deg 30% 40%), hwb(50deg 30% 40%))`, canonicalize(`hwb(190deg 30% 40%)`));
-    test_valid_value(`color`, `color-mix(in hwb specified hue, hwb(20deg 30% 40%), hwb(320deg 30% 40%))`, canonicalize(`hwb(170deg 30% 40%)`));
-    test_valid_value(`color`, `color-mix(in hwb specified hue, hwb(320deg 30% 40%), hwb(20deg 30% 40%))`, canonicalize(`hwb(170deg 30% 40%)`));
-
     test_valid_value(`color`, `color-mix(in hwb, hwb(none none none), hwb(none none none))`, canonicalize(`hwb(none none none)`));
     test_valid_value(`color`, `color-mix(in hwb, hwb(none none none), hwb(30deg 30% 40%))`, canonicalize(`hwb(30deg 30% 40%)`));
     test_valid_value(`color`, `color-mix(in hwb, hwb(120deg 10% 20%), hwb(none none none))`, canonicalize(`hwb(120deg 10% 20%)`));
@@ -248,13 +234,6 @@
         test_valid_value(`color`, `color-mix(in ${colorSpace} decreasing hue, ${colorSpace}(100 0 20deg), ${colorSpace}(100 0 320deg))`, `${colorSpace}(100 0 350)`);
         test_valid_value(`color`, `color-mix(in ${colorSpace} decreasing hue, ${colorSpace}(100 0 320deg), ${colorSpace}(100 0 20deg))`, `${colorSpace}(100 0 170)`);
 
-        test_valid_value(`color`, `color-mix(in ${colorSpace} specified hue, ${colorSpace}(100 0 40deg), ${colorSpace}(100 0 60deg))`, `${colorSpace}(100 0 50)`);
-        test_valid_value(`color`, `color-mix(in ${colorSpace} specified hue, ${colorSpace}(100 0 60deg), ${colorSpace}(100 0 40deg))`, `${colorSpace}(100 0 50)`);
-        test_valid_value(`color`, `color-mix(in ${colorSpace} specified hue, ${colorSpace}(100 0 50deg), ${colorSpace}(100 0 330deg))`, `${colorSpace}(100 0 190)`);
-        test_valid_value(`color`, `color-mix(in ${colorSpace} specified hue, ${colorSpace}(100 0 330deg), ${colorSpace}(100 0 50deg))`, `${colorSpace}(100 0 190)`);
-        test_valid_value(`color`, `color-mix(in ${colorSpace} specified hue, ${colorSpace}(100 0 20deg), ${colorSpace}(100 0 320deg))`, `${colorSpace}(100 0 170)`);
-        test_valid_value(`color`, `color-mix(in ${colorSpace} specified hue, ${colorSpace}(100 0 320deg), ${colorSpace}(100 0 20deg))`, `${colorSpace}(100 0 170)`);
-
         test_valid_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(none none none), ${colorSpace}(none none none))`, `${colorSpace}(none none none)`);
         test_valid_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(none none none), ${colorSpace}(50 60 70deg))`, `${colorSpace}(50 60 70)`);
         test_valid_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(10 20 30deg), ${colorSpace}(none none none))`, `${colorSpace}(10 20 30)`);
diff --git a/third_party/blink/web_tests/external/wpt/css/css-images/gradient/css-color-4-colors-default-to-oklab-gradient.html b/third_party/blink/web_tests/external/wpt/css/css-images/gradient/css-color-4-colors-default-to-oklab-gradient.html
index c34521c..5be18ac 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-images/gradient/css-color-4-colors-default-to-oklab-gradient.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-images/gradient/css-color-4-colors-default-to-oklab-gradient.html
@@ -2,7 +2,7 @@
 <html>
  <head>
   <title>CSS color 4 colors default to OKLab gradient interpolation</title>
-  <meta name="fuzzy" content="maxDifference=1-2;totalPixels=0-24000">
+  <meta name="fuzzy" content="maxDifference=1-8;totalPixels=0-24000">
   <link rel="author" title="Aaron Krajeski" href="mailto:aaronhk@chromium.org">
   <link rel="help" href="https://www.w3.org/TR/css-color-4/#interpolation">
   <meta name="assert" content="Test that new color inputs default to OKLab for gradient interpolation when none is provided. Reference generated here: https://raphlinus.github.io/color/2021/01/18/oklab-critique.html">
@@ -11,7 +11,7 @@
    .test {
        width: 480px;
        height: 50px;
-       background: linear-gradient(to right, rgb(255 0 0), rgb(0 255 0));
+       background: linear-gradient(to right, rgb(255, 0, 0), color(srgb 0 255 0));
    }
  </style>
  </head>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-images/gradient/oklab-gradient.html b/third_party/blink/web_tests/external/wpt/css/css-images/gradient/oklab-gradient.html
index b520cbe..71230ef 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-images/gradient/oklab-gradient.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-images/gradient/oklab-gradient.html
@@ -2,7 +2,7 @@
 <html>
  <head>
   <title>OKLab gradient interpolation</title>
-  <meta name="fuzzy" content="maxDifference=1-2;totalPixels=0-24000">
+  <meta name="fuzzy" content="maxDifference=1-8;totalPixels=0-24000">
   <link rel="author" title="Aaron Krajeski" href="mailto:aaronhk@chromium.org">
   <link rel="help" href="https://www.w3.org/TR/css-color-4/#interpolation">
   <meta name="assert" content="Test OKLab as a gradient interpolation space. Reference generated here: https://raphlinus.github.io/color/2021/01/18/oklab-critique.html">
diff --git a/third_party/blink/web_tests/external/wpt/css/css-images/gradient/resources/srgb-linear-gradient.png b/third_party/blink/web_tests/external/wpt/css/css-images/gradient/resources/red-green-gradient-linear-colorspace.png
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/css/css-images/gradient/resources/srgb-linear-gradient.png
rename to third_party/blink/web_tests/external/wpt/css/css-images/gradient/resources/red-green-gradient-linear-colorspace.png
Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/css/css-images/gradient/srgb-linear-gradient-expected.html b/third_party/blink/web_tests/external/wpt/css/css-images/gradient/srgb-linear-gradient-expected.html
index b3984d7..34f660f6 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-images/gradient/srgb-linear-gradient-expected.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-images/gradient/srgb-linear-gradient-expected.html
@@ -9,7 +9,7 @@
    .test {
        width: 480px;
        height: 50px;
-       background: url("resources/srgb-linear-gradient.png");
+       background: url("resources/red-green-gradient-linear-colorspace.png");
    }
  </style>
  </head>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-images/gradient/srgb-linear-gradient.html b/third_party/blink/web_tests/external/wpt/css/css-images/gradient/srgb-linear-gradient.html
index fa2dd1a..0869f3d 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-images/gradient/srgb-linear-gradient.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-images/gradient/srgb-linear-gradient.html
@@ -2,7 +2,7 @@
 <html>
  <head>
   <title>sRGB-linear gradient interpolation</title>
-  <meta name="fuzzy" content="maxDifference=1-2;totalPixels=0-24000">
+  <meta name="fuzzy" content="maxDifference=1-8;totalPixels=0-24000">
   <link rel="author" title="Aaron Krajeski" href="mailto:aaronhk@chromium.org">
   <link rel="help" href="https://www.w3.org/TR/css-color-4/#interpolation">
   <meta name="assert" content="Test sRGB-linear as a gradient interpolation space. Reference generated here: https://raphlinus.github.io/color/2021/01/18/oklab-critique.html">
diff --git a/third_party/blink/web_tests/external/wpt/css/css-images/gradient/xyz-gradient-expected.html b/third_party/blink/web_tests/external/wpt/css/css-images/gradient/xyz-gradient-expected.html
index 0411ccf..a435bbf 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-images/gradient/xyz-gradient-expected.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-images/gradient/xyz-gradient-expected.html
@@ -9,7 +9,7 @@
    .test {
        width: 480px;
        height: 50px;
-       background: url("resources/xyz-gradient.png");
+       background: url("resources/red-green-gradient-linear-colorspace.png");
    }
  </style>
  </head>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-images/gradient/xyz-gradient.html b/third_party/blink/web_tests/external/wpt/css/css-images/gradient/xyz-gradient.html
index fc7c9c4..f760f14 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-images/gradient/xyz-gradient.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-images/gradient/xyz-gradient.html
@@ -2,7 +2,7 @@
 <html>
  <head>
   <title>XYZ gradient interpolation</title>
-  <meta name="fuzzy" content="maxDifference=1-2;totalPixels=0-24000">
+  <meta name="fuzzy" content="maxDifference=1-8;totalPixels=0-24000">
   <link rel="author" title="Aaron Krajeski" href="mailto:aaronhk@chromium.org">
   <link rel="help" href="https://www.w3.org/TR/css-color-4/#interpolation">
   <meta name="assert" content="Test XYZ as a gradient interpolation space. Reference generated here: https://raphlinus.github.io/color/2021/01/18/oklab-critique.html">
diff --git a/third_party/blink/web_tests/external/wpt/css/css-images/parsing/gradient-interpolation-method-computed.html b/third_party/blink/web_tests/external/wpt/css/css-images/parsing/gradient-interpolation-method-computed.html
index 050fb43e..9593a597 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-images/parsing/gradient-interpolation-method-computed.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-images/parsing/gradient-interpolation-method-computed.html
@@ -90,7 +90,7 @@
     }
 
     for (const colorSpace of [ "hsl", "hwb", "lch", "oklch" ]) {
-        for (const hueInterpolationMethod of [ "", " shorter hue", " longer hue", " increasing hue", " decreasing hue", " specified hue" ]) {
+        for (const hueInterpolationMethod of [ "", " shorter hue", " longer hue", " increasing hue", " decreasing hue" ]) {
             const colorInterpolationMethod = `${colorSpace}${hueInterpolationMethod}`
             const colorInterpolationMethodResult = hueInterpolationMethod == " shorter hue" ? colorSpace : colorInterpolationMethod
 
diff --git a/third_party/blink/web_tests/external/wpt/css/css-images/parsing/gradient-interpolation-method-valid.html b/third_party/blink/web_tests/external/wpt/css/css-images/parsing/gradient-interpolation-method-valid.html
index d71d8da..a5ae5c0 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-images/parsing/gradient-interpolation-method-valid.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-images/parsing/gradient-interpolation-method-valid.html
@@ -75,7 +75,7 @@
     }
 
     for (const colorSpace of [ "hsl", "hwb", "lch", "oklch" ]) {
-        for (const hueInterpolationMethod of [ "", " shorter hue", " longer hue", " increasing hue", " decreasing hue", " specified hue" ]) {
+        for (const hueInterpolationMethod of [ "", " shorter hue", " longer hue", " increasing hue", " decreasing hue" ]) {
             const colorInterpolationMethod = `${colorSpace}${hueInterpolationMethod}`
             const colorInterpolationMethodResult = hueInterpolationMethod == " shorter hue" ? colorSpace : colorInterpolationMethod
 
diff --git a/third_party/blink/web_tests/external/wpt/css/css-typed-om/the-stylepropertymap/properties/animation-delay-end.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-typed-om/the-stylepropertymap/properties/animation-delay-end.tentative.html
new file mode 100644
index 0000000..79b9f946
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-typed-om/the-stylepropertymap/properties/animation-delay-end.tentative.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<title>'animation-delay-end' property</title>
+<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#dom-stylepropertymap-get">
+<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#dom-stylepropertymap-set">
+<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#property-stle-value-normalization">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../../resources/testhelper.js"></script>
+<script src="resources/testsuite.js"></script>
+<body>
+<div id="log"></div>
+<script>
+'use strict';
+
+runListValuedPropertyTests('animation-delay-end', [
+  { syntax: '<time>' }
+]);
+
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-typed-om/the-stylepropertymap/properties/animation-delay-start.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-typed-om/the-stylepropertymap/properties/animation-delay-start.tentative.html
new file mode 100644
index 0000000..2fba4d8e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-typed-om/the-stylepropertymap/properties/animation-delay-start.tentative.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<title>'animation-delay-start' property</title>
+<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#dom-stylepropertymap-get">
+<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#dom-stylepropertymap-set">
+<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#property-stle-value-normalization">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../../resources/testhelper.js"></script>
+<script src="resources/testsuite.js"></script>
+<body>
+<div id="log"></div>
+<script>
+'use strict';
+
+runListValuedPropertyTests('animation-delay-start', [
+  { syntax: '<time>' }
+]);
+
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/geometry/DOMMatrix-invert-invertible.html b/third_party/blink/web_tests/external/wpt/css/geometry/DOMMatrix-invert-invertible.html
new file mode 100644
index 0000000..3e7c73a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/geometry/DOMMatrix-invert-invertible.html
@@ -0,0 +1,76 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.fxtf.org/geometry-1/#DOMMatrix">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/dommatrix-test-util.js"></script>
+<p>Test DOMMatrix.inverse()/invertSelf() for invertible matrices</p>
+<script>
+test(function() {
+  var m = new DOMMatrix();
+  assert_true(m.isIdentity);
+  var m1 = m.inverse();
+  assert_true(m1.isIdentity);
+  // Use checkMatrix() instead of checkDOMMatrix() because checkMatrix() has
+  // a default epsilon = Number.MIN_VALUE which can at least pass
+  // assert_approx_equal(0, -0, epsilon).
+  checkMatrix(m, m1);
+  m.invertSelf();
+  checkMatrix(m, m1);
+}, "identity");
+
+test(function() {
+  var m = new DOMMatrix().translate(10, -20.5);
+  var m1 = m.inverse();
+  checkMatrix(m1, new DOMMatrix().translate(-10, 20.5));
+  // Check with 'new DOMMatrix()' instead of identity() because the latter is
+  // a 3d identity matrix.
+  checkMatrix(m1.multiply(m), new DOMMatrix());
+  m.invertSelf();
+  checkMatrix(m, m1);
+}, "translate");
+
+test(function() {
+  var m = new DOMMatrix().translate(10, -20.5, 30.5);
+  var m1 = m.inverse();
+  checkMatrix(m1, new DOMMatrix().translate(-10, 20.5, -30.5));
+  checkMatrix(m1.multiply(m), identity());
+  m.invertSelf();
+  checkMatrix(m, m1);
+}, "translate3d");
+
+test(function() {
+  var m = new DOMMatrix().scale(10, -0.5);
+  var m1 = m.inverse();
+  checkMatrix(m1, new DOMMatrix().scale(0.1, -2.0));
+  checkMatrix(m1.multiply(m), new DOMMatrix());
+  m.invertSelf();
+  checkMatrix(m, m1);
+}, "scale");
+
+test(function() {
+  var m = new DOMMatrix().scale(10, -0.5, 2.5);
+  var m1 = m.inverse();
+  checkMatrix(m1, new DOMMatrix().scale(0.1, -2.0, 0.4));
+  checkMatrix(m1.multiply(m), identity());
+  m.invertSelf();
+  checkMatrix(m, m1);
+}, "scale3d");
+
+test(function() {
+  var m = new DOMMatrix().rotateAxisAngle(0, 0, 1, -30)
+                         .scale(10, -0.5, 2.5)
+                         .rotateAxisAngle(0, 1, 0, 10)
+                         .translate(10, -20.5, 30.5)
+                         .rotateAxisAngle(1, 0, 0, 20);
+  var expected = new DOMMatrix().rotateAxisAngle(1, 0, 0, -20)
+                                .translate(-10, 20.5, -30.5)
+                                .rotateAxisAngle(0, 1, 0, -10)
+                                .scale(0.1, -2.0, 0.4)
+                                .rotateAxisAngle(0, 0, 1, 30);
+  var m1 = m.inverse();
+  var epsilon = 1e-6;
+  checkMatrix(m1, expected, {epsilon});
+  m.invertSelf();
+  checkMatrix(m, expected, {epsilon});
+}, "complex");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/dom/idlharness.window.js b/third_party/blink/web_tests/external/wpt/dom/idlharness.window.js
index c73fbf21..2c7bfd7 100644
--- a/third_party/blink/web_tests/external/wpt/dom/idlharness.window.js
+++ b/third_party/blink/web_tests/external/wpt/dom/idlharness.window.js
@@ -11,7 +11,7 @@
 'use strict';
 
 idl_test(
-  ['dom'],
+  ['dom', 'fullscreen'],
   ['html'],
   idl_array => {
     self.xmlDoc = document.implementation.createDocument(null, '', null);
diff --git a/third_party/blink/web_tests/external/wpt/dom/idlharness.window_exclude=Node-expected.txt b/third_party/blink/web_tests/external/wpt/dom/idlharness.window_exclude=Node-expected.txt
index 836b440..aedf9a5 100644
--- a/third_party/blink/web_tests/external/wpt/dom/idlharness.window_exclude=Node-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/dom/idlharness.window_exclude=Node-expected.txt
@@ -1,14 +1,22 @@
 This is a testharness.js-based test.
-Found 1292 tests; 1290 PASS, 2 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 1326 tests; 1325 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS idl_test setup
 PASS idl_test validation
 PASS Partial interface Window: original interface defined
 PASS Partial interface Window: member names are unique
+PASS Partial interface Element: original interface defined
+PASS Partial interface Element: member names are unique
+PASS Partial interface Document: original interface defined
 PASS Partial interface Document: member names are unique
+PASS Partial interface mixin DocumentOrShadowRoot: original interface mixin defined
+PASS Partial interface mixin DocumentOrShadowRoot: member names are unique
 PASS Partial interface Document[2]: member names are unique
+PASS Partial interface Document[3]: member names are unique
 PASS Partial interface Window[2]: member names are unique
 PASS Document includes NonElementParentNode: member names are unique
 PASS DocumentFragment includes NonElementParentNode: member names are unique
+PASS Document includes DocumentOrShadowRoot: member names are unique
+PASS ShadowRoot includes DocumentOrShadowRoot: member names are unique
 PASS Document includes ParentNode: member names are unique
 PASS DocumentFragment includes ParentNode: member names are unique
 PASS Element includes ParentNode: member names are unique
@@ -272,7 +280,7 @@
 PASS Document interface object name
 PASS Document interface: existence and properties of interface prototype object
 PASS Document interface: existence and properties of interface prototype object's "constructor" property
-FAIL Document interface: existence and properties of interface prototype object's @@unscopables property assert_not_equals: Document.prototype[Symbol.unscopables] has unexpected property "fullscreen" got disallowed value -1
+PASS Document interface: existence and properties of interface prototype object's @@unscopables property
 PASS Document interface: attribute implementation
 PASS Document interface: attribute URL
 PASS Document interface: attribute documentURI
@@ -301,7 +309,13 @@
 PASS Document interface: operation createRange()
 PASS Document interface: operation createNodeIterator(Node, optional unsigned long, optional NodeFilter?)
 PASS Document interface: operation createTreeWalker(Node, optional unsigned long, optional NodeFilter?)
+PASS Document interface: attribute fullscreenEnabled
+PASS Document interface: attribute fullscreen
+PASS Document interface: operation exitFullscreen()
+PASS Document interface: attribute onfullscreenchange
+PASS Document interface: attribute onfullscreenerror
 PASS Document interface: operation getElementById(DOMString)
+PASS Document interface: attribute fullscreenElement
 PASS Document interface: attribute children
 PASS Document interface: attribute firstElementChild
 PASS Document interface: attribute lastElementChild
@@ -360,8 +374,14 @@
 PASS Document interface: calling createNodeIterator(Node, optional unsigned long, optional NodeFilter?) on new Document() with too few arguments must throw TypeError
 PASS Document interface: new Document() must inherit property "createTreeWalker(Node, optional unsigned long, optional NodeFilter?)" with the proper type
 PASS Document interface: calling createTreeWalker(Node, optional unsigned long, optional NodeFilter?) on new Document() with too few arguments must throw TypeError
+PASS Document interface: new Document() must inherit property "fullscreenEnabled" with the proper type
+PASS Document interface: new Document() must inherit property "fullscreen" with the proper type
+PASS Document interface: new Document() must inherit property "exitFullscreen()" with the proper type
+PASS Document interface: new Document() must inherit property "onfullscreenchange" with the proper type
+PASS Document interface: new Document() must inherit property "onfullscreenerror" with the proper type
 PASS Document interface: new Document() must inherit property "getElementById(DOMString)" with the proper type
 PASS Document interface: calling getElementById(DOMString) on new Document() with too few arguments must throw TypeError
+PASS Document interface: new Document() must inherit property "fullscreenElement" with the proper type
 PASS Document interface: new Document() must inherit property "children" with the proper type
 PASS Document interface: new Document() must inherit property "firstElementChild" with the proper type
 PASS Document interface: new Document() must inherit property "lastElementChild" with the proper type
@@ -440,8 +460,14 @@
 PASS Document interface: calling createNodeIterator(Node, optional unsigned long, optional NodeFilter?) on xmlDoc with too few arguments must throw TypeError
 PASS Document interface: xmlDoc must inherit property "createTreeWalker(Node, optional unsigned long, optional NodeFilter?)" with the proper type
 PASS Document interface: calling createTreeWalker(Node, optional unsigned long, optional NodeFilter?) on xmlDoc with too few arguments must throw TypeError
+PASS Document interface: xmlDoc must inherit property "fullscreenEnabled" with the proper type
+PASS Document interface: xmlDoc must inherit property "fullscreen" with the proper type
+PASS Document interface: xmlDoc must inherit property "exitFullscreen()" with the proper type
+PASS Document interface: xmlDoc must inherit property "onfullscreenchange" with the proper type
+PASS Document interface: xmlDoc must inherit property "onfullscreenerror" with the proper type
 PASS Document interface: xmlDoc must inherit property "getElementById(DOMString)" with the proper type
 PASS Document interface: calling getElementById(DOMString) on xmlDoc with too few arguments must throw TypeError
+PASS Document interface: xmlDoc must inherit property "fullscreenElement" with the proper type
 PASS Document interface: xmlDoc must inherit property "children" with the proper type
 PASS Document interface: xmlDoc must inherit property "firstElementChild" with the proper type
 PASS Document interface: xmlDoc must inherit property "lastElementChild" with the proper type
@@ -569,6 +595,7 @@
 PASS ShadowRoot interface: attribute slotAssignment
 PASS ShadowRoot interface: attribute host
 PASS ShadowRoot interface: attribute onslotchange
+PASS ShadowRoot interface: attribute fullscreenElement
 PASS Element interface: existence and properties of interface object
 PASS Element interface object length
 PASS Element interface object name
@@ -610,6 +637,9 @@
 PASS Element interface: operation getElementsByClassName(DOMString)
 PASS Element interface: operation insertAdjacentElement(DOMString, Element)
 PASS Element interface: operation insertAdjacentText(DOMString, DOMString)
+PASS Element interface: operation requestFullscreen(optional FullscreenOptions)
+PASS Element interface: attribute onfullscreenchange
+PASS Element interface: attribute onfullscreenerror
 PASS Element interface: attribute children
 PASS Element interface: attribute firstElementChild
 PASS Element interface: attribute lastElementChild
@@ -686,6 +716,10 @@
 PASS Element interface: calling insertAdjacentElement(DOMString, Element) on element with too few arguments must throw TypeError
 PASS Element interface: element must inherit property "insertAdjacentText(DOMString, DOMString)" with the proper type
 PASS Element interface: calling insertAdjacentText(DOMString, DOMString) on element with too few arguments must throw TypeError
+PASS Element interface: element must inherit property "requestFullscreen(optional FullscreenOptions)" with the proper type
+PASS Element interface: calling requestFullscreen(optional FullscreenOptions) on element with too few arguments must throw TypeError
+PASS Element interface: element must inherit property "onfullscreenchange" with the proper type
+PASS Element interface: element must inherit property "onfullscreenerror" with the proper type
 PASS Element interface: element must inherit property "children" with the proper type
 PASS Element interface: element must inherit property "firstElementChild" with the proper type
 PASS Element interface: element must inherit property "lastElementChild" with the proper type
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/shadow-multiple-expected.png b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/shadow-multiple-expected.png
deleted file mode 100644
index 98c30647..0000000
--- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/shadow-multiple-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/text-antialias/stroking-decorations-expected.png b/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/text-antialias/stroking-decorations-expected.png
deleted file mode 100644
index 1ce47d45..0000000
--- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/text-antialias/stroking-decorations-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/fast/writing-mode/english-lr-text-expected.png b/third_party/blink/web_tests/flag-specific/highdpi/fast/writing-mode/english-lr-text-expected.png
deleted file mode 100644
index 5a864bc..0000000
--- a/third_party/blink/web_tests/flag-specific/highdpi/fast/writing-mode/english-lr-text-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/skia-vulkan-swiftshader/css3/blending/effect-background-blend-mode-stacking-expected.png b/third_party/blink/web_tests/flag-specific/skia-vulkan-swiftshader/css3/blending/effect-background-blend-mode-stacking-expected.png
index 36d0c14..d59ef84 100644
--- a/third_party/blink/web_tests/flag-specific/skia-vulkan-swiftshader/css3/blending/effect-background-blend-mode-stacking-expected.png
+++ b/third_party/blink/web_tests/flag-specific/skia-vulkan-swiftshader/css3/blending/effect-background-blend-mode-stacking-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/webauthn/resources/webauthn-test.https.html b/third_party/blink/web_tests/http/tests/inspector-protocol/webauthn/resources/webauthn-test.https.html
index c176c18..e6a58e0 100644
--- a/third_party/blink/web_tests/http/tests/inspector-protocol/webauthn/resources/webauthn-test.https.html
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/webauthn/resources/webauthn-test.https.html
@@ -102,6 +102,43 @@
     return {status: error.toString()};
   }
 }
+
+async function getCredentialSignature() {
+  try {
+    const r = await getCredential({
+      type: "public-key",
+      id: new TextEncoder().encode("cred-1"),
+      transports: ["usb", "ble", "nfc"],
+    });
+    const signature = new Uint8Array(r.attestation.response.signature);
+    return {
+      status: "OK",
+      signature
+    }
+  } catch(error) {
+    return {status: error.toString()};
+  }
+}
+
+async function getFlags(bitNumber) {
+  try {
+    const r = await getCredential({
+      type: "public-key",
+      id: new TextEncoder().encode("cred-1"),
+      transports: ["usb", "ble", "nfc"],
+    });
+    const flags = new Uint8Array(r.attestation.response.authenticatorData)[32];
+    // bitNumber is 0 indexed.
+    const bit = (flags & (1 << bitNumber)) != 0 ? 1 : 0;
+    return {
+      status: "OK",
+      bit
+    }
+  } catch(error) {
+    return {status: error.toString()};
+  }
+}
+
   </script>
 </head>
 <body>
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/webauthn/webauthn-set-bad-up-bit-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/webauthn/webauthn-set-bad-up-bit-expected.txt
new file mode 100644
index 0000000..9234383
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/webauthn/webauthn-set-bad-up-bit-expected.txt
@@ -0,0 +1,22 @@
+Check that the WebAuthn command setBadUVBit works
+{
+    id : <number>
+    result : {
+    }
+    sessionId : <string>
+}
+{
+    bit : 1
+    status : OK
+}
+{
+    id : <number>
+    result : {
+    }
+    sessionId : <string>
+}
+{
+    bit : 0
+    status : OK
+}
+
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/webauthn/webauthn-set-bad-up-bit.js b/third_party/blink/web_tests/http/tests/inspector-protocol/webauthn/webauthn-set-bad-up-bit.js
new file mode 100644
index 0000000..2512366
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/webauthn/webauthn-set-bad-up-bit.js
@@ -0,0 +1,40 @@
+(async function(testRunner) {
+  const {page, session, dp} = await testRunner.startURL(
+      'https://devtools.test:8443/inspector-protocol/webauthn/resources/webauthn-test.https.html',
+      'Check that the WebAuthn command setBadUVBit works');
+
+  // Create an authenticator.
+  await dp.WebAuthn.enable();
+  const authenticatorId = (await dp.WebAuthn.addVirtualAuthenticator({
+                            options: {
+                              protocol: 'ctap2',
+                              transport: 'usb',
+                              hasResidentKey: true,
+                              hasUserVerification: false,
+                            },
+                          })).result.authenticatorId;
+
+  // Register a non-resident credential.
+  const nonResidentCredentialId = 'cred-1';
+  testRunner.log(await dp.WebAuthn.addCredential({
+    authenticatorId,
+    credential: {
+      credentialId: btoa(nonResidentCredentialId),
+      rpId: 'devtools.test',
+      privateKey: await session.evaluateAsync('generateBase64Key()'),
+      signCount: 0,
+      isResidentCredential: false,
+    }
+  }));
+
+  // Get UP bit from flags from authenticator data in response.
+  testRunner.log(await session.evaluateAsync(`getFlags(0)`));
+
+  // Set UP bit in authenticator response to always be 0.
+  testRunner.log(await dp.WebAuthn.setResponseOverrideBits(
+      {authenticatorId, isBadUP: true}));
+
+  // Get UP bit from flags from authenticator data in response.
+  testRunner.log(await session.evaluateAsync(`getFlags(0)`));
+  testRunner.completeTest();
+})
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/webauthn/webauthn-set-bad-uv-bit-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/webauthn/webauthn-set-bad-uv-bit-expected.txt
new file mode 100644
index 0000000..9234383
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/webauthn/webauthn-set-bad-uv-bit-expected.txt
@@ -0,0 +1,22 @@
+Check that the WebAuthn command setBadUVBit works
+{
+    id : <number>
+    result : {
+    }
+    sessionId : <string>
+}
+{
+    bit : 1
+    status : OK
+}
+{
+    id : <number>
+    result : {
+    }
+    sessionId : <string>
+}
+{
+    bit : 0
+    status : OK
+}
+
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/webauthn/webauthn-set-bad-uv-bit.js b/third_party/blink/web_tests/http/tests/inspector-protocol/webauthn/webauthn-set-bad-uv-bit.js
new file mode 100644
index 0000000..5b278e85
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/webauthn/webauthn-set-bad-uv-bit.js
@@ -0,0 +1,41 @@
+(async function(testRunner) {
+  const {page, session, dp} = await testRunner.startURL(
+      'https://devtools.test:8443/inspector-protocol/webauthn/resources/webauthn-test.https.html',
+      'Check that the WebAuthn command setBadUVBit works');
+
+  // Create an authenticator.
+  await dp.WebAuthn.enable();
+  const authenticatorId = (await dp.WebAuthn.addVirtualAuthenticator({
+                            options: {
+                              protocol: 'ctap2',
+                              transport: 'usb',
+                              hasResidentKey: true,
+                              hasUserVerification: true,
+                              isUserVerified: true,
+                            },
+                          })).result.authenticatorId;
+
+  // Register a non-resident credential.
+  const nonResidentCredentialId = 'cred-1';
+  testRunner.log(await dp.WebAuthn.addCredential({
+    authenticatorId,
+    credential: {
+      credentialId: btoa(nonResidentCredentialId),
+      rpId: 'devtools.test',
+      privateKey: await session.evaluateAsync('generateBase64Key()'),
+      signCount: 0,
+      isResidentCredential: false,
+    }
+  }));
+
+  // Get UV bit from flags from authenticator data in response.
+  testRunner.log(await session.evaluateAsync(`getFlags(2)`));
+
+  // Set UV bit in authenticator response to always be 0.
+  testRunner.log(await dp.WebAuthn.setResponseOverrideBits(
+      {authenticatorId, isBadUV: true}));
+
+  // Get UV bit from flags from authenticator data in response.
+  testRunner.log(await session.evaluateAsync(`getFlags(2)`));
+  testRunner.completeTest();
+})
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/webauthn/webauthn-set-bogus-signature-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/webauthn/webauthn-set-bogus-signature-expected.txt
new file mode 100644
index 0000000..cc15728
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/webauthn/webauthn-set-bogus-signature-expected.txt
@@ -0,0 +1,20 @@
+Check that the WebAuthn command setBogusSignature works
+{
+    id : <number>
+    result : {
+    }
+    sessionId : <string>
+}
+{
+    id : <number>
+    result : {
+    }
+    sessionId : <string>
+}
+{
+    signature : {
+        0 : 0
+    }
+    status : OK
+}
+
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/webauthn/webauthn-set-bogus-signature.js b/third_party/blink/web_tests/http/tests/inspector-protocol/webauthn/webauthn-set-bogus-signature.js
new file mode 100644
index 0000000..e6d4ebb
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/webauthn/webauthn-set-bogus-signature.js
@@ -0,0 +1,37 @@
+(async function(testRunner) {
+  const {page, session, dp} = await testRunner.startURL(
+      'https://devtools.test:8443/inspector-protocol/webauthn/resources/webauthn-test.https.html',
+      'Check that the WebAuthn command setBogusSignature works');
+
+  // Create an authenticator.
+  await dp.WebAuthn.enable();
+  const authenticatorId = (await dp.WebAuthn.addVirtualAuthenticator({
+                            options: {
+                              protocol: 'ctap2',
+                              transport: 'usb',
+                              hasResidentKey: true,
+                              hasUserVerification: false,
+                            },
+                          })).result.authenticatorId;
+
+  // Register a non-resident credential.
+  const nonResidentCredentialId = 'cred-1';
+  testRunner.log(await dp.WebAuthn.addCredential({
+    authenticatorId,
+    credential: {
+      credentialId: btoa(nonResidentCredentialId),
+      rpId: 'devtools.test',
+      privateKey: await session.evaluateAsync('generateBase64Key()'),
+      signCount: 0,
+      isResidentCredential: false,
+    }
+  }));
+
+  // Set signature in authenticator response to be bogus.
+  testRunner.log(await dp.WebAuthn.setResponseOverrideBits(
+      {authenticatorId, isBogusSignature: true}));
+
+  // Get signature from response.
+  testRunner.log(await session.evaluateAsync(`getCredentialSignature()`));
+  testRunner.completeTest();
+})
diff --git a/third_party/blink/web_tests/platform/linux/compositing/visibility/visibility-simple-video-layer-expected.png b/third_party/blink/web_tests/platform/linux/compositing/visibility/visibility-simple-video-layer-expected.png
index 57a5729a2..6afdc3a 100644
--- a/third_party/blink/web_tests/platform/linux/compositing/visibility/visibility-simple-video-layer-expected.png
+++ b/third_party/blink/web_tests/platform/linux/compositing/visibility/visibility-simple-video-layer-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/fast/writing-mode/english-lr-text-expected.png b/third_party/blink/web_tests/platform/linux/fast/writing-mode/english-lr-text-expected.png
index 963778b..5a864bc 100644
--- a/third_party/blink/web_tests/platform/linux/fast/writing-mode/english-lr-text-expected.png
+++ b/third_party/blink/web_tests/platform/linux/fast/writing-mode/english-lr-text-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/ietestcenter/css3/text/textshadow-002-expected.png b/third_party/blink/web_tests/platform/linux/ietestcenter/css3/text/textshadow-002-expected.png
index ce9e65e..cbbf441 100644
--- a/third_party/blink/web_tests/platform/linux/ietestcenter/css3/text/textshadow-002-expected.png
+++ b/third_party/blink/web_tests/platform/linux/ietestcenter/css3/text/textshadow-002-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/paint/invalidation/shadow-multiple-expected.png b/third_party/blink/web_tests/platform/linux/paint/invalidation/shadow-multiple-expected.png
index cabdfa8f..98c30647 100644
--- a/third_party/blink/web_tests/platform/linux/paint/invalidation/shadow-multiple-expected.png
+++ b/third_party/blink/web_tests/platform/linux/paint/invalidation/shadow-multiple-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/text-antialias/stroking-decorations-expected.png b/third_party/blink/web_tests/platform/linux/virtual/text-antialias/stroking-decorations-expected.png
index ed35105..1ce47d45 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/text-antialias/stroking-decorations-expected.png
+++ b/third_party/blink/web_tests/platform/linux/virtual/text-antialias/stroking-decorations-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/threaded/compositing/visibility/visibility-simple-video-layer-expected.png b/third_party/blink/web_tests/platform/linux/virtual/threaded/compositing/visibility/visibility-simple-video-layer-expected.png
index 57a5729a2..6afdc3a 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/threaded/compositing/visibility/visibility-simple-video-layer-expected.png
+++ b/third_party/blink/web_tests/platform/linux/virtual/threaded/compositing/visibility/visibility-simple-video-layer-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/dark-color-scheme/fast/forms/color-scheme/scrollbar/dynamic-color-scheme-change-expected.png b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/dark-color-scheme/fast/forms/color-scheme/scrollbar/dynamic-color-scheme-change-expected.png
index de23a320c..e4a8103 100644
--- a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/dark-color-scheme/fast/forms/color-scheme/scrollbar/dynamic-color-scheme-change-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/dark-color-scheme/fast/forms/color-scheme/scrollbar/dynamic-color-scheme-change-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
index 210f496..1bf788b 100644
--- a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/text-antialias/stroking-decorations-expected.png b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/text-antialias/stroking-decorations-expected.png
index 8a20ce0..ff1e445e 100644
--- a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/text-antialias/stroking-decorations-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/text-antialias/stroking-decorations-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac11-arm64/paint/invalidation/shadow-multiple-expected.png b/third_party/blink/web_tests/platform/mac-mac11-arm64/paint/invalidation/shadow-multiple-expected.png
deleted file mode 100644
index 575d2b5..0000000
--- a/third_party/blink/web_tests/platform/mac-mac11-arm64/paint/invalidation/shadow-multiple-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
index 50a6b10..c2d500a8 100644
--- a/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac12-arm64/paint/invalidation/shadow-multiple-expected.png b/third_party/blink/web_tests/platform/mac-mac12-arm64/paint/invalidation/shadow-multiple-expected.png
deleted file mode 100644
index 575d2b5..0000000
--- a/third_party/blink/web_tests/platform/mac-mac12-arm64/paint/invalidation/shadow-multiple-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
index 50a6b10..c2d500a8 100644
--- a/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/compositing/visibility/visibility-simple-video-layer-expected.png b/third_party/blink/web_tests/platform/mac/compositing/visibility/visibility-simple-video-layer-expected.png
index f7cc94e..64458de 100644
--- a/third_party/blink/web_tests/platform/mac/compositing/visibility/visibility-simple-video-layer-expected.png
+++ b/third_party/blink/web_tests/platform/mac/compositing/visibility/visibility-simple-video-layer-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fast/writing-mode/english-lr-text-expected.png b/third_party/blink/web_tests/platform/mac/fast/writing-mode/english-lr-text-expected.png
index 2035c2b..2c1a028 100644
--- a/third_party/blink/web_tests/platform/mac/fast/writing-mode/english-lr-text-expected.png
+++ b/third_party/blink/web_tests/platform/mac/fast/writing-mode/english-lr-text-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/ietestcenter/css3/text/textshadow-002-expected.png b/third_party/blink/web_tests/platform/mac/ietestcenter/css3/text/textshadow-002-expected.png
index f5d1059..44ec0ed 100644
--- a/third_party/blink/web_tests/platform/mac/ietestcenter/css3/text/textshadow-002-expected.png
+++ b/third_party/blink/web_tests/platform/mac/ietestcenter/css3/text/textshadow-002-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/paint/invalidation/shadow-multiple-expected.png b/third_party/blink/web_tests/platform/mac/paint/invalidation/shadow-multiple-expected.png
index 4876e755b3..44789bb7 100644
--- a/third_party/blink/web_tests/platform/mac/paint/invalidation/shadow-multiple-expected.png
+++ b/third_party/blink/web_tests/platform/mac/paint/invalidation/shadow-multiple-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/file/file-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/file/file-appearance-basic-expected.png
index 24226fdd6..8d07711 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/file/file-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/file/file-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/media/video-playback-speed-menu-expected.png b/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/media/video-playback-speed-menu-expected.png
index d0cd4ec..24b95f9 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/media/video-playback-speed-menu-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/media/video-playback-speed-menu-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/scrollbar/dynamic-color-scheme-change-expected.png b/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/scrollbar/dynamic-color-scheme-change-expected.png
index 7959162..27ebd10b 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/scrollbar/dynamic-color-scheme-change-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/scrollbar/dynamic-color-scheme-change-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/scrollbar/horizontal-scrollbar-basic-expected.png b/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/scrollbar/horizontal-scrollbar-basic-expected.png
index 7e59633..9ce72bc7 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/scrollbar/horizontal-scrollbar-basic-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/scrollbar/horizontal-scrollbar-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png b/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
index 7c77c9a..347d4f0 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-disabled-multiple-hover-focused-unselected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
index 9f672d9..1014c1eb 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png b/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
index 926edd9..6a5cbeb 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-focused-unselected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png b/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png
index c7315923..4bd35924 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-selected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png b/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png
index a52a0fe6..e6e6284 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/select/select-multiple-hover-unselected-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/scrollbar/scrollbar-middle-expected.png b/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/scrollbar/scrollbar-middle-expected.png
index 769eebb0..ed5cca9b 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/scrollbar/scrollbar-middle-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/scrollbar/scrollbar-middle-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/scrollbar/scrollbar-top-expected.png b/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/scrollbar/scrollbar-top-expected.png
index c7712370..b8a9fe3 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/scrollbar/scrollbar-top-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/scrollbar/scrollbar-top-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/text-antialias/stroking-decorations-expected.png b/third_party/blink/web_tests/platform/mac/virtual/text-antialias/stroking-decorations-expected.png
index d6589be3..70c851f6 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/text-antialias/stroking-decorations-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/text-antialias/stroking-decorations-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/compositing/visibility/visibility-simple-video-layer-expected.png b/third_party/blink/web_tests/platform/win/compositing/visibility/visibility-simple-video-layer-expected.png
index f17218b9..843dbae 100644
--- a/third_party/blink/web_tests/platform/win/compositing/visibility/visibility-simple-video-layer-expected.png
+++ b/third_party/blink/web_tests/platform/win/compositing/visibility/visibility-simple-video-layer-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/writing-mode/english-lr-text-expected.png b/third_party/blink/web_tests/platform/win/fast/writing-mode/english-lr-text-expected.png
index 53ed456..cf160afd 100644
--- a/third_party/blink/web_tests/platform/win/fast/writing-mode/english-lr-text-expected.png
+++ b/third_party/blink/web_tests/platform/win/fast/writing-mode/english-lr-text-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/ietestcenter/css3/text/textshadow-002-expected.png b/third_party/blink/web_tests/platform/win/ietestcenter/css3/text/textshadow-002-expected.png
index 57ddf1d8..f8aa958 100644
--- a/third_party/blink/web_tests/platform/win/ietestcenter/css3/text/textshadow-002-expected.png
+++ b/third_party/blink/web_tests/platform/win/ietestcenter/css3/text/textshadow-002-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/paint/invalidation/shadow-multiple-expected.png b/third_party/blink/web_tests/platform/win/paint/invalidation/shadow-multiple-expected.png
index fa2baf5..16410b0 100644
--- a/third_party/blink/web_tests/platform/win/paint/invalidation/shadow-multiple-expected.png
+++ b/third_party/blink/web_tests/platform/win/paint/invalidation/shadow-multiple-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/text-antialias/stroking-decorations-expected.png b/third_party/blink/web_tests/platform/win/virtual/text-antialias/stroking-decorations-expected.png
index 85afa7d..a60df6b1 100644
--- a/third_party/blink/web_tests/platform/win/virtual/text-antialias/stroking-decorations-expected.png
+++ b/third_party/blink/web_tests/platform/win/virtual/text-antialias/stroking-decorations-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/virtual/stable/external/wpt/css/css-color/parsing/color-valid-color-mix-function-expected.txt b/third_party/blink/web_tests/virtual/stable/external/wpt/css/css-color/parsing/color-valid-color-mix-function-expected.txt
index 7116c476..1388547 100644
--- a/third_party/blink/web_tests/virtual/stable/external/wpt/css/css-color/parsing/color-valid-color-mix-function-expected.txt
+++ b/third_party/blink/web_tests/virtual/stable/external/wpt/css/css-color/parsing/color-valid-color-mix-function-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 474 tests; 0 PASS, 474 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 450 tests; 0 PASS, 450 FAIL, 0 TIMEOUT, 0 NOTRUN.
 FAIL e.style['color'] = "color-mix(in hsl, hsl(120deg 10% 20%), hsl(30deg 30% 40%))" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['color'] = "color-mix(in hsl, hsl(120deg 10% 20%) 25%, hsl(30deg 30% 40%))" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['color'] = "color-mix(in hsl, 25% hsl(120deg 10% 20%), hsl(30deg 30% 40%))" should set the property value assert_not_equals: property should be set got disallowed value ""
@@ -48,12 +48,6 @@
 FAIL e.style['color'] = "color-mix(in hsl decreasing hue, hsl(330deg 50% 50%), hsl(50deg 50% 50%))" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['color'] = "color-mix(in hsl decreasing hue, hsl(20deg 50% 50%), hsl(320deg 50% 50%))" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['color'] = "color-mix(in hsl decreasing hue, hsl(320deg 50% 50%), hsl(20deg 50% 50%))" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['color'] = "color-mix(in hsl specified hue, hsl(40deg 50% 50%), hsl(60deg 50% 50%))" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['color'] = "color-mix(in hsl specified hue, hsl(60deg 50% 50%), hsl(40deg 50% 50%))" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['color'] = "color-mix(in hsl specified hue, hsl(50deg 50% 50%), hsl(330deg 50% 50%))" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['color'] = "color-mix(in hsl specified hue, hsl(330deg 50% 50%), hsl(50deg 50% 50%))" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['color'] = "color-mix(in hsl specified hue, hsl(20deg 50% 50%), hsl(320deg 50% 50%))" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['color'] = "color-mix(in hsl specified hue, hsl(320deg 50% 50%), hsl(20deg 50% 50%))" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['color'] = "color-mix(in hsl, hsl(none none none), hsl(none none none))" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['color'] = "color-mix(in hsl, hsl(none none none), hsl(30deg 40% 80%))" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['color'] = "color-mix(in hsl, hsl(120deg 20% 40%), hsl(none none none))" should set the property value assert_not_equals: property should be set got disallowed value ""
@@ -120,12 +114,6 @@
 FAIL e.style['color'] = "color-mix(in hwb decreasing hue, hwb(330deg 30% 40%), hwb(50deg 30% 40%))" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['color'] = "color-mix(in hwb decreasing hue, hwb(20deg 30% 40%), hwb(320deg 30% 40%))" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['color'] = "color-mix(in hwb decreasing hue, hwb(320deg 30% 40%), hwb(20deg 30% 40%))" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['color'] = "color-mix(in hwb specified hue, hwb(40deg 30% 40%), hwb(60deg 30% 40%))" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['color'] = "color-mix(in hwb specified hue, hwb(60deg 30% 40%), hwb(40deg 30% 40%))" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['color'] = "color-mix(in hwb specified hue, hwb(50deg 30% 40%), hwb(330deg 30% 40%))" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['color'] = "color-mix(in hwb specified hue, hwb(330deg 30% 40%), hwb(50deg 30% 40%))" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['color'] = "color-mix(in hwb specified hue, hwb(20deg 30% 40%), hwb(320deg 30% 40%))" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['color'] = "color-mix(in hwb specified hue, hwb(320deg 30% 40%), hwb(20deg 30% 40%))" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['color'] = "color-mix(in hwb, hwb(none none none), hwb(none none none))" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['color'] = "color-mix(in hwb, hwb(none none none), hwb(30deg 30% 40%))" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['color'] = "color-mix(in hwb, hwb(120deg 10% 20%), hwb(none none none))" should set the property value assert_not_equals: property should be set got disallowed value ""
@@ -192,12 +180,6 @@
 FAIL e.style['color'] = "color-mix(in lch decreasing hue, lch(100 0 330deg), lch(100 0 50deg))" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['color'] = "color-mix(in lch decreasing hue, lch(100 0 20deg), lch(100 0 320deg))" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['color'] = "color-mix(in lch decreasing hue, lch(100 0 320deg), lch(100 0 20deg))" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['color'] = "color-mix(in lch specified hue, lch(100 0 40deg), lch(100 0 60deg))" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['color'] = "color-mix(in lch specified hue, lch(100 0 60deg), lch(100 0 40deg))" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['color'] = "color-mix(in lch specified hue, lch(100 0 50deg), lch(100 0 330deg))" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['color'] = "color-mix(in lch specified hue, lch(100 0 330deg), lch(100 0 50deg))" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['color'] = "color-mix(in lch specified hue, lch(100 0 20deg), lch(100 0 320deg))" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['color'] = "color-mix(in lch specified hue, lch(100 0 320deg), lch(100 0 20deg))" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['color'] = "color-mix(in lch, lch(none none none), lch(none none none))" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['color'] = "color-mix(in lch, lch(none none none), lch(50 60 70deg))" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['color'] = "color-mix(in lch, lch(10 20 30deg), lch(none none none))" should set the property value assert_not_equals: property should be set got disallowed value ""
@@ -255,12 +237,6 @@
 FAIL e.style['color'] = "color-mix(in oklch decreasing hue, oklch(100 0 330deg), oklch(100 0 50deg))" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['color'] = "color-mix(in oklch decreasing hue, oklch(100 0 20deg), oklch(100 0 320deg))" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['color'] = "color-mix(in oklch decreasing hue, oklch(100 0 320deg), oklch(100 0 20deg))" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['color'] = "color-mix(in oklch specified hue, oklch(100 0 40deg), oklch(100 0 60deg))" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['color'] = "color-mix(in oklch specified hue, oklch(100 0 60deg), oklch(100 0 40deg))" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['color'] = "color-mix(in oklch specified hue, oklch(100 0 50deg), oklch(100 0 330deg))" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['color'] = "color-mix(in oklch specified hue, oklch(100 0 330deg), oklch(100 0 50deg))" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['color'] = "color-mix(in oklch specified hue, oklch(100 0 20deg), oklch(100 0 320deg))" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['color'] = "color-mix(in oklch specified hue, oklch(100 0 320deg), oklch(100 0 20deg))" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['color'] = "color-mix(in oklch, oklch(none none none), oklch(none none none))" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['color'] = "color-mix(in oklch, oklch(none none none), oklch(50 60 70deg))" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['color'] = "color-mix(in oklch, oklch(10 20 30deg), oklch(none none none))" should set the property value assert_not_equals: property should be set got disallowed value ""
diff --git a/third_party/blink/web_tests/virtual/stable/external/wpt/css/css-images/parsing/gradient-interpolation-method-computed-expected.txt b/third_party/blink/web_tests/virtual/stable/external/wpt/css/css-images/parsing/gradient-interpolation-method-computed-expected.txt
index d6c629f0..bbd2cb6f 100644
--- a/third_party/blink/web_tests/virtual/stable/external/wpt/css/css-images/parsing/gradient-interpolation-method-computed-expected.txt
+++ b/third_party/blink/web_tests/virtual/stable/external/wpt/css/css-images/parsing/gradient-interpolation-method-computed-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 1068 tests; 7 PASS, 1061 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 932 tests; 7 PASS, 925 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Property background-image value 'linear-gradient(30deg, red, blue)'
 PASS Property background-image value 'linear-gradient(to right bottom, red, blue)'
 FAIL Property background-image value 'linear-gradient(30deg, color(srgb 1 0 0), blue)' assert_true: 'linear-gradient(30deg, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
@@ -124,16 +124,6 @@
 FAIL Property background-image value 'linear-gradient(in hsl decreasing hue 30deg, color(srgb 1 0 0), blue)' assert_true: 'linear-gradient(in hsl decreasing hue 30deg, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'linear-gradient(to right bottom in hsl decreasing hue, color(srgb 1 0 0), blue)' assert_true: 'linear-gradient(to right bottom in hsl decreasing hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'linear-gradient(in hsl decreasing hue to right bottom, color(srgb 1 0 0), blue)' assert_true: 'linear-gradient(in hsl decreasing hue to right bottom, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(in hsl specified hue, red, blue)' assert_true: 'linear-gradient(in hsl specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(30deg in hsl specified hue, red, blue)' assert_true: 'linear-gradient(30deg in hsl specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(in hsl specified hue 30deg, red, blue)' assert_true: 'linear-gradient(in hsl specified hue 30deg, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(to right bottom in hsl specified hue, red, blue)' assert_true: 'linear-gradient(to right bottom in hsl specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(in hsl specified hue to right bottom, red, blue)' assert_true: 'linear-gradient(in hsl specified hue to right bottom, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(in hsl specified hue, color(srgb 1 0 0), blue)' assert_true: 'linear-gradient(in hsl specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(30deg in hsl specified hue, color(srgb 1 0 0), blue)' assert_true: 'linear-gradient(30deg in hsl specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(in hsl specified hue 30deg, color(srgb 1 0 0), blue)' assert_true: 'linear-gradient(in hsl specified hue 30deg, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(to right bottom in hsl specified hue, color(srgb 1 0 0), blue)' assert_true: 'linear-gradient(to right bottom in hsl specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(in hsl specified hue to right bottom, color(srgb 1 0 0), blue)' assert_true: 'linear-gradient(in hsl specified hue to right bottom, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'linear-gradient(in hwb, red, blue)' assert_true: 'linear-gradient(in hwb, red, blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'linear-gradient(30deg in hwb, red, blue)' assert_true: 'linear-gradient(30deg in hwb, red, blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'linear-gradient(in hwb 30deg, red, blue)' assert_true: 'linear-gradient(in hwb 30deg, red, blue)' is a supported value for background-image. expected true got false
@@ -184,16 +174,6 @@
 FAIL Property background-image value 'linear-gradient(in hwb decreasing hue 30deg, color(srgb 1 0 0), blue)' assert_true: 'linear-gradient(in hwb decreasing hue 30deg, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'linear-gradient(to right bottom in hwb decreasing hue, color(srgb 1 0 0), blue)' assert_true: 'linear-gradient(to right bottom in hwb decreasing hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'linear-gradient(in hwb decreasing hue to right bottom, color(srgb 1 0 0), blue)' assert_true: 'linear-gradient(in hwb decreasing hue to right bottom, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(in hwb specified hue, red, blue)' assert_true: 'linear-gradient(in hwb specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(30deg in hwb specified hue, red, blue)' assert_true: 'linear-gradient(30deg in hwb specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(in hwb specified hue 30deg, red, blue)' assert_true: 'linear-gradient(in hwb specified hue 30deg, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(to right bottom in hwb specified hue, red, blue)' assert_true: 'linear-gradient(to right bottom in hwb specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(in hwb specified hue to right bottom, red, blue)' assert_true: 'linear-gradient(in hwb specified hue to right bottom, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(in hwb specified hue, color(srgb 1 0 0), blue)' assert_true: 'linear-gradient(in hwb specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(30deg in hwb specified hue, color(srgb 1 0 0), blue)' assert_true: 'linear-gradient(30deg in hwb specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(in hwb specified hue 30deg, color(srgb 1 0 0), blue)' assert_true: 'linear-gradient(in hwb specified hue 30deg, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(to right bottom in hwb specified hue, color(srgb 1 0 0), blue)' assert_true: 'linear-gradient(to right bottom in hwb specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(in hwb specified hue to right bottom, color(srgb 1 0 0), blue)' assert_true: 'linear-gradient(in hwb specified hue to right bottom, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'linear-gradient(in lch, red, blue)' assert_true: 'linear-gradient(in lch, red, blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'linear-gradient(30deg in lch, red, blue)' assert_true: 'linear-gradient(30deg in lch, red, blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'linear-gradient(in lch 30deg, red, blue)' assert_true: 'linear-gradient(in lch 30deg, red, blue)' is a supported value for background-image. expected true got false
@@ -244,16 +224,6 @@
 FAIL Property background-image value 'linear-gradient(in lch decreasing hue 30deg, color(srgb 1 0 0), blue)' assert_true: 'linear-gradient(in lch decreasing hue 30deg, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'linear-gradient(to right bottom in lch decreasing hue, color(srgb 1 0 0), blue)' assert_true: 'linear-gradient(to right bottom in lch decreasing hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'linear-gradient(in lch decreasing hue to right bottom, color(srgb 1 0 0), blue)' assert_true: 'linear-gradient(in lch decreasing hue to right bottom, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(in lch specified hue, red, blue)' assert_true: 'linear-gradient(in lch specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(30deg in lch specified hue, red, blue)' assert_true: 'linear-gradient(30deg in lch specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(in lch specified hue 30deg, red, blue)' assert_true: 'linear-gradient(in lch specified hue 30deg, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(to right bottom in lch specified hue, red, blue)' assert_true: 'linear-gradient(to right bottom in lch specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(in lch specified hue to right bottom, red, blue)' assert_true: 'linear-gradient(in lch specified hue to right bottom, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(in lch specified hue, color(srgb 1 0 0), blue)' assert_true: 'linear-gradient(in lch specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(30deg in lch specified hue, color(srgb 1 0 0), blue)' assert_true: 'linear-gradient(30deg in lch specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(in lch specified hue 30deg, color(srgb 1 0 0), blue)' assert_true: 'linear-gradient(in lch specified hue 30deg, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(to right bottom in lch specified hue, color(srgb 1 0 0), blue)' assert_true: 'linear-gradient(to right bottom in lch specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(in lch specified hue to right bottom, color(srgb 1 0 0), blue)' assert_true: 'linear-gradient(in lch specified hue to right bottom, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'linear-gradient(in oklch, red, blue)' assert_true: 'linear-gradient(in oklch, red, blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'linear-gradient(30deg in oklch, red, blue)' assert_true: 'linear-gradient(30deg in oklch, red, blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'linear-gradient(in oklch 30deg, red, blue)' assert_true: 'linear-gradient(in oklch 30deg, red, blue)' is a supported value for background-image. expected true got false
@@ -304,16 +274,6 @@
 FAIL Property background-image value 'linear-gradient(in oklch decreasing hue 30deg, color(srgb 1 0 0), blue)' assert_true: 'linear-gradient(in oklch decreasing hue 30deg, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'linear-gradient(to right bottom in oklch decreasing hue, color(srgb 1 0 0), blue)' assert_true: 'linear-gradient(to right bottom in oklch decreasing hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'linear-gradient(in oklch decreasing hue to right bottom, color(srgb 1 0 0), blue)' assert_true: 'linear-gradient(in oklch decreasing hue to right bottom, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(in oklch specified hue, red, blue)' assert_true: 'linear-gradient(in oklch specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(30deg in oklch specified hue, red, blue)' assert_true: 'linear-gradient(30deg in oklch specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(in oklch specified hue 30deg, red, blue)' assert_true: 'linear-gradient(in oklch specified hue 30deg, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(to right bottom in oklch specified hue, red, blue)' assert_true: 'linear-gradient(to right bottom in oklch specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(in oklch specified hue to right bottom, red, blue)' assert_true: 'linear-gradient(in oklch specified hue to right bottom, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(in oklch specified hue, color(srgb 1 0 0), blue)' assert_true: 'linear-gradient(in oklch specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(30deg in oklch specified hue, color(srgb 1 0 0), blue)' assert_true: 'linear-gradient(30deg in oklch specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(in oklch specified hue 30deg, color(srgb 1 0 0), blue)' assert_true: 'linear-gradient(in oklch specified hue 30deg, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(to right bottom in oklch specified hue, color(srgb 1 0 0), blue)' assert_true: 'linear-gradient(to right bottom in oklch specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'linear-gradient(in oklch specified hue to right bottom, color(srgb 1 0 0), blue)' assert_true: 'linear-gradient(in oklch specified hue to right bottom, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
 PASS Property background-image value 'radial-gradient(50px, red, blue)'
 PASS Property background-image value 'radial-gradient(ellipse 50% 40em, red, blue)'
 PASS Property background-image value 'radial-gradient(at right center, red, blue)'
@@ -488,20 +448,6 @@
 FAIL Property background-image value 'radial-gradient(in hsl decreasing hue ellipse 50% 40em, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(in hsl decreasing hue ellipse 50% 40em, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'radial-gradient(at right center in hsl decreasing hue, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(at right center in hsl decreasing hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'radial-gradient(in hsl decreasing hue at right center, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(in hsl decreasing hue at right center, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(in hsl specified hue, red, blue)' assert_true: 'radial-gradient(in hsl specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(50px in hsl specified hue, red, blue)' assert_true: 'radial-gradient(50px in hsl specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(in hsl specified hue 50px, red, blue)' assert_true: 'radial-gradient(in hsl specified hue 50px, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(ellipse 50% 40em in hsl specified hue, red, blue)' assert_true: 'radial-gradient(ellipse 50% 40em in hsl specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(in hsl specified hue ellipse 50% 40em, red, blue)' assert_true: 'radial-gradient(in hsl specified hue ellipse 50% 40em, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(at right center in hsl specified hue, red, blue)' assert_true: 'radial-gradient(at right center in hsl specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(in hsl specified hue at right center, red, blue)' assert_true: 'radial-gradient(in hsl specified hue at right center, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(in hsl specified hue, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(in hsl specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(50px in hsl specified hue, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(50px in hsl specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(in hsl specified hue 50px, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(in hsl specified hue 50px, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(ellipse 50% 40em in hsl specified hue, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(ellipse 50% 40em in hsl specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(in hsl specified hue ellipse 50% 40em, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(in hsl specified hue ellipse 50% 40em, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(at right center in hsl specified hue, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(at right center in hsl specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(in hsl specified hue at right center, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(in hsl specified hue at right center, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'radial-gradient(in hwb, red, blue)' assert_true: 'radial-gradient(in hwb, red, blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'radial-gradient(50px in hwb, red, blue)' assert_true: 'radial-gradient(50px in hwb, red, blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'radial-gradient(in hwb 50px, red, blue)' assert_true: 'radial-gradient(in hwb 50px, red, blue)' is a supported value for background-image. expected true got false
@@ -572,20 +518,6 @@
 FAIL Property background-image value 'radial-gradient(in hwb decreasing hue ellipse 50% 40em, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(in hwb decreasing hue ellipse 50% 40em, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'radial-gradient(at right center in hwb decreasing hue, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(at right center in hwb decreasing hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'radial-gradient(in hwb decreasing hue at right center, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(in hwb decreasing hue at right center, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(in hwb specified hue, red, blue)' assert_true: 'radial-gradient(in hwb specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(50px in hwb specified hue, red, blue)' assert_true: 'radial-gradient(50px in hwb specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(in hwb specified hue 50px, red, blue)' assert_true: 'radial-gradient(in hwb specified hue 50px, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(ellipse 50% 40em in hwb specified hue, red, blue)' assert_true: 'radial-gradient(ellipse 50% 40em in hwb specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(in hwb specified hue ellipse 50% 40em, red, blue)' assert_true: 'radial-gradient(in hwb specified hue ellipse 50% 40em, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(at right center in hwb specified hue, red, blue)' assert_true: 'radial-gradient(at right center in hwb specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(in hwb specified hue at right center, red, blue)' assert_true: 'radial-gradient(in hwb specified hue at right center, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(in hwb specified hue, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(in hwb specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(50px in hwb specified hue, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(50px in hwb specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(in hwb specified hue 50px, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(in hwb specified hue 50px, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(ellipse 50% 40em in hwb specified hue, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(ellipse 50% 40em in hwb specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(in hwb specified hue ellipse 50% 40em, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(in hwb specified hue ellipse 50% 40em, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(at right center in hwb specified hue, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(at right center in hwb specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(in hwb specified hue at right center, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(in hwb specified hue at right center, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'radial-gradient(in lch, red, blue)' assert_true: 'radial-gradient(in lch, red, blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'radial-gradient(50px in lch, red, blue)' assert_true: 'radial-gradient(50px in lch, red, blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'radial-gradient(in lch 50px, red, blue)' assert_true: 'radial-gradient(in lch 50px, red, blue)' is a supported value for background-image. expected true got false
@@ -656,20 +588,6 @@
 FAIL Property background-image value 'radial-gradient(in lch decreasing hue ellipse 50% 40em, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(in lch decreasing hue ellipse 50% 40em, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'radial-gradient(at right center in lch decreasing hue, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(at right center in lch decreasing hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'radial-gradient(in lch decreasing hue at right center, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(in lch decreasing hue at right center, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(in lch specified hue, red, blue)' assert_true: 'radial-gradient(in lch specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(50px in lch specified hue, red, blue)' assert_true: 'radial-gradient(50px in lch specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(in lch specified hue 50px, red, blue)' assert_true: 'radial-gradient(in lch specified hue 50px, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(ellipse 50% 40em in lch specified hue, red, blue)' assert_true: 'radial-gradient(ellipse 50% 40em in lch specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(in lch specified hue ellipse 50% 40em, red, blue)' assert_true: 'radial-gradient(in lch specified hue ellipse 50% 40em, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(at right center in lch specified hue, red, blue)' assert_true: 'radial-gradient(at right center in lch specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(in lch specified hue at right center, red, blue)' assert_true: 'radial-gradient(in lch specified hue at right center, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(in lch specified hue, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(in lch specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(50px in lch specified hue, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(50px in lch specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(in lch specified hue 50px, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(in lch specified hue 50px, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(ellipse 50% 40em in lch specified hue, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(ellipse 50% 40em in lch specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(in lch specified hue ellipse 50% 40em, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(in lch specified hue ellipse 50% 40em, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(at right center in lch specified hue, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(at right center in lch specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(in lch specified hue at right center, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(in lch specified hue at right center, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'radial-gradient(in oklch, red, blue)' assert_true: 'radial-gradient(in oklch, red, blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'radial-gradient(50px in oklch, red, blue)' assert_true: 'radial-gradient(50px in oklch, red, blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'radial-gradient(in oklch 50px, red, blue)' assert_true: 'radial-gradient(in oklch 50px, red, blue)' is a supported value for background-image. expected true got false
@@ -740,20 +658,6 @@
 FAIL Property background-image value 'radial-gradient(in oklch decreasing hue ellipse 50% 40em, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(in oklch decreasing hue ellipse 50% 40em, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'radial-gradient(at right center in oklch decreasing hue, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(at right center in oklch decreasing hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'radial-gradient(in oklch decreasing hue at right center, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(in oklch decreasing hue at right center, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(in oklch specified hue, red, blue)' assert_true: 'radial-gradient(in oklch specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(50px in oklch specified hue, red, blue)' assert_true: 'radial-gradient(50px in oklch specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(in oklch specified hue 50px, red, blue)' assert_true: 'radial-gradient(in oklch specified hue 50px, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(ellipse 50% 40em in oklch specified hue, red, blue)' assert_true: 'radial-gradient(ellipse 50% 40em in oklch specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(in oklch specified hue ellipse 50% 40em, red, blue)' assert_true: 'radial-gradient(in oklch specified hue ellipse 50% 40em, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(at right center in oklch specified hue, red, blue)' assert_true: 'radial-gradient(at right center in oklch specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(in oklch specified hue at right center, red, blue)' assert_true: 'radial-gradient(in oklch specified hue at right center, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(in oklch specified hue, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(in oklch specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(50px in oklch specified hue, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(50px in oklch specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(in oklch specified hue 50px, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(in oklch specified hue 50px, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(ellipse 50% 40em in oklch specified hue, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(ellipse 50% 40em in oklch specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(in oklch specified hue ellipse 50% 40em, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(in oklch specified hue ellipse 50% 40em, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(at right center in oklch specified hue, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(at right center in oklch specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'radial-gradient(in oklch specified hue at right center, color(srgb 1 0 0), blue)' assert_true: 'radial-gradient(in oklch specified hue at right center, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
 PASS Property background-image value 'conic-gradient(from 30deg, red, blue)'
 PASS Property background-image value 'conic-gradient(at left 10px top 50em, red, blue)'
 FAIL Property background-image value 'conic-gradient(from 30deg, color(srgb 1 0 0), blue)' assert_true: 'conic-gradient(from 30deg, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
@@ -878,16 +782,6 @@
 FAIL Property background-image value 'conic-gradient(in hsl decreasing hue from 30deg, color(srgb 1 0 0), blue)' assert_true: 'conic-gradient(in hsl decreasing hue from 30deg, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'conic-gradient(at left 10px top 50em in hsl decreasing hue, color(srgb 1 0 0), blue)' assert_true: 'conic-gradient(at left 10px top 50em in hsl decreasing hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'conic-gradient(in hsl decreasing hue at left 10px top 50em, color(srgb 1 0 0), blue)' assert_true: 'conic-gradient(in hsl decreasing hue at left 10px top 50em, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(in hsl specified hue, red, blue)' assert_true: 'conic-gradient(in hsl specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(from 30deg in hsl specified hue, red, blue)' assert_true: 'conic-gradient(from 30deg in hsl specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(in hsl specified hue from 30deg, red, blue)' assert_true: 'conic-gradient(in hsl specified hue from 30deg, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(at left 10px top 50em in hsl specified hue, red, blue)' assert_true: 'conic-gradient(at left 10px top 50em in hsl specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(in hsl specified hue at left 10px top 50em, red, blue)' assert_true: 'conic-gradient(in hsl specified hue at left 10px top 50em, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(in hsl specified hue, color(srgb 1 0 0), blue)' assert_true: 'conic-gradient(in hsl specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(from 30deg in hsl specified hue, color(srgb 1 0 0), blue)' assert_true: 'conic-gradient(from 30deg in hsl specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(in hsl specified hue from 30deg, color(srgb 1 0 0), blue)' assert_true: 'conic-gradient(in hsl specified hue from 30deg, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(at left 10px top 50em in hsl specified hue, color(srgb 1 0 0), blue)' assert_true: 'conic-gradient(at left 10px top 50em in hsl specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(in hsl specified hue at left 10px top 50em, color(srgb 1 0 0), blue)' assert_true: 'conic-gradient(in hsl specified hue at left 10px top 50em, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'conic-gradient(in hwb, red, blue)' assert_true: 'conic-gradient(in hwb, red, blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'conic-gradient(from 30deg in hwb, red, blue)' assert_true: 'conic-gradient(from 30deg in hwb, red, blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'conic-gradient(in hwb from 30deg, red, blue)' assert_true: 'conic-gradient(in hwb from 30deg, red, blue)' is a supported value for background-image. expected true got false
@@ -938,16 +832,6 @@
 FAIL Property background-image value 'conic-gradient(in hwb decreasing hue from 30deg, color(srgb 1 0 0), blue)' assert_true: 'conic-gradient(in hwb decreasing hue from 30deg, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'conic-gradient(at left 10px top 50em in hwb decreasing hue, color(srgb 1 0 0), blue)' assert_true: 'conic-gradient(at left 10px top 50em in hwb decreasing hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'conic-gradient(in hwb decreasing hue at left 10px top 50em, color(srgb 1 0 0), blue)' assert_true: 'conic-gradient(in hwb decreasing hue at left 10px top 50em, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(in hwb specified hue, red, blue)' assert_true: 'conic-gradient(in hwb specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(from 30deg in hwb specified hue, red, blue)' assert_true: 'conic-gradient(from 30deg in hwb specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(in hwb specified hue from 30deg, red, blue)' assert_true: 'conic-gradient(in hwb specified hue from 30deg, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(at left 10px top 50em in hwb specified hue, red, blue)' assert_true: 'conic-gradient(at left 10px top 50em in hwb specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(in hwb specified hue at left 10px top 50em, red, blue)' assert_true: 'conic-gradient(in hwb specified hue at left 10px top 50em, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(in hwb specified hue, color(srgb 1 0 0), blue)' assert_true: 'conic-gradient(in hwb specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(from 30deg in hwb specified hue, color(srgb 1 0 0), blue)' assert_true: 'conic-gradient(from 30deg in hwb specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(in hwb specified hue from 30deg, color(srgb 1 0 0), blue)' assert_true: 'conic-gradient(in hwb specified hue from 30deg, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(at left 10px top 50em in hwb specified hue, color(srgb 1 0 0), blue)' assert_true: 'conic-gradient(at left 10px top 50em in hwb specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(in hwb specified hue at left 10px top 50em, color(srgb 1 0 0), blue)' assert_true: 'conic-gradient(in hwb specified hue at left 10px top 50em, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'conic-gradient(in lch, red, blue)' assert_true: 'conic-gradient(in lch, red, blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'conic-gradient(from 30deg in lch, red, blue)' assert_true: 'conic-gradient(from 30deg in lch, red, blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'conic-gradient(in lch from 30deg, red, blue)' assert_true: 'conic-gradient(in lch from 30deg, red, blue)' is a supported value for background-image. expected true got false
@@ -998,16 +882,6 @@
 FAIL Property background-image value 'conic-gradient(in lch decreasing hue from 30deg, color(srgb 1 0 0), blue)' assert_true: 'conic-gradient(in lch decreasing hue from 30deg, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'conic-gradient(at left 10px top 50em in lch decreasing hue, color(srgb 1 0 0), blue)' assert_true: 'conic-gradient(at left 10px top 50em in lch decreasing hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'conic-gradient(in lch decreasing hue at left 10px top 50em, color(srgb 1 0 0), blue)' assert_true: 'conic-gradient(in lch decreasing hue at left 10px top 50em, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(in lch specified hue, red, blue)' assert_true: 'conic-gradient(in lch specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(from 30deg in lch specified hue, red, blue)' assert_true: 'conic-gradient(from 30deg in lch specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(in lch specified hue from 30deg, red, blue)' assert_true: 'conic-gradient(in lch specified hue from 30deg, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(at left 10px top 50em in lch specified hue, red, blue)' assert_true: 'conic-gradient(at left 10px top 50em in lch specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(in lch specified hue at left 10px top 50em, red, blue)' assert_true: 'conic-gradient(in lch specified hue at left 10px top 50em, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(in lch specified hue, color(srgb 1 0 0), blue)' assert_true: 'conic-gradient(in lch specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(from 30deg in lch specified hue, color(srgb 1 0 0), blue)' assert_true: 'conic-gradient(from 30deg in lch specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(in lch specified hue from 30deg, color(srgb 1 0 0), blue)' assert_true: 'conic-gradient(in lch specified hue from 30deg, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(at left 10px top 50em in lch specified hue, color(srgb 1 0 0), blue)' assert_true: 'conic-gradient(at left 10px top 50em in lch specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(in lch specified hue at left 10px top 50em, color(srgb 1 0 0), blue)' assert_true: 'conic-gradient(in lch specified hue at left 10px top 50em, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'conic-gradient(in oklch, red, blue)' assert_true: 'conic-gradient(in oklch, red, blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'conic-gradient(from 30deg in oklch, red, blue)' assert_true: 'conic-gradient(from 30deg in oklch, red, blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'conic-gradient(in oklch from 30deg, red, blue)' assert_true: 'conic-gradient(in oklch from 30deg, red, blue)' is a supported value for background-image. expected true got false
@@ -1058,15 +932,5 @@
 FAIL Property background-image value 'conic-gradient(in oklch decreasing hue from 30deg, color(srgb 1 0 0), blue)' assert_true: 'conic-gradient(in oklch decreasing hue from 30deg, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'conic-gradient(at left 10px top 50em in oklch decreasing hue, color(srgb 1 0 0), blue)' assert_true: 'conic-gradient(at left 10px top 50em in oklch decreasing hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
 FAIL Property background-image value 'conic-gradient(in oklch decreasing hue at left 10px top 50em, color(srgb 1 0 0), blue)' assert_true: 'conic-gradient(in oklch decreasing hue at left 10px top 50em, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(in oklch specified hue, red, blue)' assert_true: 'conic-gradient(in oklch specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(from 30deg in oklch specified hue, red, blue)' assert_true: 'conic-gradient(from 30deg in oklch specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(in oklch specified hue from 30deg, red, blue)' assert_true: 'conic-gradient(in oklch specified hue from 30deg, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(at left 10px top 50em in oklch specified hue, red, blue)' assert_true: 'conic-gradient(at left 10px top 50em in oklch specified hue, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(in oklch specified hue at left 10px top 50em, red, blue)' assert_true: 'conic-gradient(in oklch specified hue at left 10px top 50em, red, blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(in oklch specified hue, color(srgb 1 0 0), blue)' assert_true: 'conic-gradient(in oklch specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(from 30deg in oklch specified hue, color(srgb 1 0 0), blue)' assert_true: 'conic-gradient(from 30deg in oklch specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(in oklch specified hue from 30deg, color(srgb 1 0 0), blue)' assert_true: 'conic-gradient(in oklch specified hue from 30deg, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(at left 10px top 50em in oklch specified hue, color(srgb 1 0 0), blue)' assert_true: 'conic-gradient(at left 10px top 50em in oklch specified hue, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
-FAIL Property background-image value 'conic-gradient(in oklch specified hue at left 10px top 50em, color(srgb 1 0 0), blue)' assert_true: 'conic-gradient(in oklch specified hue at left 10px top 50em, color(srgb 1 0 0), blue)' is a supported value for background-image. expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/virtual/stable/external/wpt/css/css-images/parsing/gradient-interpolation-method-valid-expected.txt b/third_party/blink/web_tests/virtual/stable/external/wpt/css/css-images/parsing/gradient-interpolation-method-valid-expected.txt
index 301cb98c..5fb5170 100644
--- a/third_party/blink/web_tests/virtual/stable/external/wpt/css/css-images/parsing/gradient-interpolation-method-valid-expected.txt
+++ b/third_party/blink/web_tests/virtual/stable/external/wpt/css/css-images/parsing/gradient-interpolation-method-valid-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 1068 tests; 7 PASS, 1061 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 932 tests; 7 PASS, 925 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS e.style['background-image'] = "linear-gradient(30deg, red, blue)" should set the property value
 PASS e.style['background-image'] = "linear-gradient(to right bottom, red, blue)" should set the property value
 FAIL e.style['background-image'] = "linear-gradient(30deg, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
@@ -124,16 +124,6 @@
 FAIL e.style['background-image'] = "linear-gradient(in hsl decreasing hue 30deg, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "linear-gradient(to right bottom in hsl decreasing hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "linear-gradient(in hsl decreasing hue to right bottom, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(in hsl specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(30deg in hsl specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(in hsl specified hue 30deg, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(to right bottom in hsl specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(in hsl specified hue to right bottom, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(in hsl specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(30deg in hsl specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(in hsl specified hue 30deg, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(to right bottom in hsl specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(in hsl specified hue to right bottom, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "linear-gradient(in hwb, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "linear-gradient(30deg in hwb, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "linear-gradient(in hwb 30deg, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
@@ -184,16 +174,6 @@
 FAIL e.style['background-image'] = "linear-gradient(in hwb decreasing hue 30deg, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "linear-gradient(to right bottom in hwb decreasing hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "linear-gradient(in hwb decreasing hue to right bottom, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(in hwb specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(30deg in hwb specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(in hwb specified hue 30deg, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(to right bottom in hwb specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(in hwb specified hue to right bottom, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(in hwb specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(30deg in hwb specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(in hwb specified hue 30deg, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(to right bottom in hwb specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(in hwb specified hue to right bottom, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "linear-gradient(in lch, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "linear-gradient(30deg in lch, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "linear-gradient(in lch 30deg, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
@@ -244,16 +224,6 @@
 FAIL e.style['background-image'] = "linear-gradient(in lch decreasing hue 30deg, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "linear-gradient(to right bottom in lch decreasing hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "linear-gradient(in lch decreasing hue to right bottom, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(in lch specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(30deg in lch specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(in lch specified hue 30deg, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(to right bottom in lch specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(in lch specified hue to right bottom, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(in lch specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(30deg in lch specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(in lch specified hue 30deg, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(to right bottom in lch specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(in lch specified hue to right bottom, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "linear-gradient(in oklch, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "linear-gradient(30deg in oklch, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "linear-gradient(in oklch 30deg, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
@@ -304,16 +274,6 @@
 FAIL e.style['background-image'] = "linear-gradient(in oklch decreasing hue 30deg, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "linear-gradient(to right bottom in oklch decreasing hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "linear-gradient(in oklch decreasing hue to right bottom, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(in oklch specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(30deg in oklch specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(in oklch specified hue 30deg, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(to right bottom in oklch specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(in oklch specified hue to right bottom, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(in oklch specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(30deg in oklch specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(in oklch specified hue 30deg, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(to right bottom in oklch specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "linear-gradient(in oklch specified hue to right bottom, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 PASS e.style['background-image'] = "radial-gradient(50px, red, blue)" should set the property value
 PASS e.style['background-image'] = "radial-gradient(ellipse 50% 40em, red, blue)" should set the property value
 PASS e.style['background-image'] = "radial-gradient(at right center, red, blue)" should set the property value
@@ -488,20 +448,6 @@
 FAIL e.style['background-image'] = "radial-gradient(in hsl decreasing hue ellipse 50% 40em, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "radial-gradient(at right center in hsl decreasing hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "radial-gradient(in hsl decreasing hue at right center, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(in hsl specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(50px in hsl specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(in hsl specified hue 50px, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(ellipse 50% 40em in hsl specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(in hsl specified hue ellipse 50% 40em, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(at right center in hsl specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(in hsl specified hue at right center, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(in hsl specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(50px in hsl specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(in hsl specified hue 50px, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(ellipse 50% 40em in hsl specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(in hsl specified hue ellipse 50% 40em, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(at right center in hsl specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(in hsl specified hue at right center, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "radial-gradient(in hwb, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "radial-gradient(50px in hwb, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "radial-gradient(in hwb 50px, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
@@ -572,20 +518,6 @@
 FAIL e.style['background-image'] = "radial-gradient(in hwb decreasing hue ellipse 50% 40em, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "radial-gradient(at right center in hwb decreasing hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "radial-gradient(in hwb decreasing hue at right center, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(in hwb specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(50px in hwb specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(in hwb specified hue 50px, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(ellipse 50% 40em in hwb specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(in hwb specified hue ellipse 50% 40em, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(at right center in hwb specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(in hwb specified hue at right center, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(in hwb specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(50px in hwb specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(in hwb specified hue 50px, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(ellipse 50% 40em in hwb specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(in hwb specified hue ellipse 50% 40em, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(at right center in hwb specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(in hwb specified hue at right center, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "radial-gradient(in lch, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "radial-gradient(50px in lch, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "radial-gradient(in lch 50px, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
@@ -656,20 +588,6 @@
 FAIL e.style['background-image'] = "radial-gradient(in lch decreasing hue ellipse 50% 40em, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "radial-gradient(at right center in lch decreasing hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "radial-gradient(in lch decreasing hue at right center, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(in lch specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(50px in lch specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(in lch specified hue 50px, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(ellipse 50% 40em in lch specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(in lch specified hue ellipse 50% 40em, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(at right center in lch specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(in lch specified hue at right center, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(in lch specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(50px in lch specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(in lch specified hue 50px, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(ellipse 50% 40em in lch specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(in lch specified hue ellipse 50% 40em, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(at right center in lch specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(in lch specified hue at right center, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "radial-gradient(in oklch, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "radial-gradient(50px in oklch, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "radial-gradient(in oklch 50px, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
@@ -740,20 +658,6 @@
 FAIL e.style['background-image'] = "radial-gradient(in oklch decreasing hue ellipse 50% 40em, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "radial-gradient(at right center in oklch decreasing hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "radial-gradient(in oklch decreasing hue at right center, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(in oklch specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(50px in oklch specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(in oklch specified hue 50px, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(ellipse 50% 40em in oklch specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(in oklch specified hue ellipse 50% 40em, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(at right center in oklch specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(in oklch specified hue at right center, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(in oklch specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(50px in oklch specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(in oklch specified hue 50px, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(ellipse 50% 40em in oklch specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(in oklch specified hue ellipse 50% 40em, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(at right center in oklch specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "radial-gradient(in oklch specified hue at right center, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 PASS e.style['background-image'] = "conic-gradient(from 30deg, red, blue)" should set the property value
 PASS e.style['background-image'] = "conic-gradient(at left 10px top 50em, red, blue)" should set the property value
 FAIL e.style['background-image'] = "conic-gradient(from 30deg, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
@@ -878,16 +782,6 @@
 FAIL e.style['background-image'] = "conic-gradient(in hsl decreasing hue from 30deg, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "conic-gradient(at left 10px top 50em in hsl decreasing hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "conic-gradient(in hsl decreasing hue at left 10px top 50em, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(in hsl specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(from 30deg in hsl specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(in hsl specified hue from 30deg, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(at left 10px top 50em in hsl specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(in hsl specified hue at left 10px top 50em, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(in hsl specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(from 30deg in hsl specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(in hsl specified hue from 30deg, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(at left 10px top 50em in hsl specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(in hsl specified hue at left 10px top 50em, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "conic-gradient(in hwb, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "conic-gradient(from 30deg in hwb, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "conic-gradient(in hwb from 30deg, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
@@ -938,16 +832,6 @@
 FAIL e.style['background-image'] = "conic-gradient(in hwb decreasing hue from 30deg, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "conic-gradient(at left 10px top 50em in hwb decreasing hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "conic-gradient(in hwb decreasing hue at left 10px top 50em, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(in hwb specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(from 30deg in hwb specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(in hwb specified hue from 30deg, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(at left 10px top 50em in hwb specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(in hwb specified hue at left 10px top 50em, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(in hwb specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(from 30deg in hwb specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(in hwb specified hue from 30deg, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(at left 10px top 50em in hwb specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(in hwb specified hue at left 10px top 50em, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "conic-gradient(in lch, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "conic-gradient(from 30deg in lch, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "conic-gradient(in lch from 30deg, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
@@ -998,16 +882,6 @@
 FAIL e.style['background-image'] = "conic-gradient(in lch decreasing hue from 30deg, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "conic-gradient(at left 10px top 50em in lch decreasing hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "conic-gradient(in lch decreasing hue at left 10px top 50em, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(in lch specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(from 30deg in lch specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(in lch specified hue from 30deg, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(at left 10px top 50em in lch specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(in lch specified hue at left 10px top 50em, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(in lch specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(from 30deg in lch specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(in lch specified hue from 30deg, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(at left 10px top 50em in lch specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(in lch specified hue at left 10px top 50em, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "conic-gradient(in oklch, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "conic-gradient(from 30deg in oklch, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "conic-gradient(in oklch from 30deg, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
@@ -1058,15 +932,5 @@
 FAIL e.style['background-image'] = "conic-gradient(in oklch decreasing hue from 30deg, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "conic-gradient(at left 10px top 50em in oklch decreasing hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['background-image'] = "conic-gradient(in oklch decreasing hue at left 10px top 50em, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(in oklch specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(from 30deg in oklch specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(in oklch specified hue from 30deg, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(at left 10px top 50em in oklch specified hue, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(in oklch specified hue at left 10px top 50em, red, blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(in oklch specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(from 30deg in oklch specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(in oklch specified hue from 30deg, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(at left 10px top 50em in oklch specified hue, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['background-image'] = "conic-gradient(in oklch specified hue at left 10px top 50em, color(srgb 1 0 0), blue)" should set the property value assert_not_equals: property should be set got disallowed value ""
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/element-with-overflow-ref.html b/third_party/blink/web_tests/wpt_internal/document-transition/element-with-overflow-ref.html
new file mode 100644
index 0000000..523c8616
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/document-transition/element-with-overflow-ref.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+<title>View transitions: element with overflow ref</title>
+<link rel="help" href="https://github.com/WICG/view-transitions">
+<link rel="author" href="mailto:khushalsagar@chromium.org">
+<style>
+  .old_target {
+    position: fixed;
+    top: 0px;
+    left: 0px;
+    width: 100px;
+    height: 100px;
+    background: lightblue;
+    transform: translate(8px, 8px);
+  }
+
+  .new_target {
+    position: fixed;
+    top: 200px;
+    left: 0;
+    width: 100px;
+    height: 100px;
+    background: lightgreen;
+    transform: translate(8px, 8px);
+  }
+
+  .inner {
+    width: 100px;
+    height: 100px;
+    position: relative;
+    top: 50px;
+    left: 50px;
+    border: 5px solid black;
+  }
+</style>
+<div class="old_target">
+  <div class="inner"></div>
+</div>
+<div class="new_target">
+  <div class="inner" style="border:5px solid blue"></div>
+</div>
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/element-with-overflow.html b/third_party/blink/web_tests/wpt_internal/document-transition/element-with-overflow.html
new file mode 100644
index 0000000..78a58b79
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/document-transition/element-with-overflow.html
@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<title>View transitions: element with overflow</title>
+<link rel="help" href="https://github.com/WICG/view-transitions">
+<link rel="author" href="mailto:khushalsagar@chromium.org">
+<link rel="match" href="element-with-overflow-ref.html">
+
+<script src="/common/reftest-wait.js"></script>
+<style>
+  .hidden {
+    width: 10px;
+    height: 10px;
+    page-transition-tag: hidden;
+    background: green;
+    contain: layout;
+  }
+
+  .target {
+    width: 100px;
+    height: 100px;
+    background: lightblue;
+    contain: layout;
+    page-transition-tag: target;
+  }
+  .inner {
+    width: 100px;
+    height: 100px;
+    position: relative;
+    top: 50px;
+    left: 50px;
+    border: 5px solid black;
+  }
+
+  html::page-transition-container(hidden) { animation-duration: 300s; }
+  html::page-transition-image-wrapper(hidden) { animation: unset; opacity: 0; }
+
+  html::page-transition-incoming-image(*), html::page-transition-outgoing-image(*) {
+    opacity: 1;
+    animation: unset;
+  }
+
+  html::page-transition-outgoing-image(target) {
+    top: 0px;
+    left: 0px;
+  }
+
+  html::page-transition-incoming-image(target) {
+    top: 200px;
+    left: 0px;
+  }
+</style>
+
+<div class="target">
+  <div class="inner"></div>
+</div>
+<div class="hidden"></div>
+
+<script>
+async function runTest() {
+  document.startViewTransition(() => {
+    document.getElementsByClassName("target")[0].style.background="lightgreen";
+    document.getElementsByClassName("inner")[0].style.border="5px solid blue";
+    requestAnimationFrame(() => requestAnimationFrame(() =>
+      requestAnimationFrame(() => requestAnimationFrame(takeScreenshot))
+    ));
+  });
+}
+onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest));
+</script>
+
diff --git a/third_party/crashpad/README.chromium b/third_party/crashpad/README.chromium
index dc0b20b..bd38c6f6 100644
--- a/third_party/crashpad/README.chromium
+++ b/third_party/crashpad/README.chromium
@@ -50,3 +50,4 @@
  - MultiprocessExec.MultiprocessExec is disabled entirely on the Mac.
    https://crbug.com/1341377
  - SystemSnapshotLinux.Basic is disabled on Android: https://crbug.com/1362091
+ - Updated ANDROID_API from 24 to 26: https://crbug.com/1379422
diff --git a/third_party/crashpad/crashpad/test/scoped_set_thread_name_posix.cc b/third_party/crashpad/crashpad/test/scoped_set_thread_name_posix.cc
index 9314b5f3..6b090f0a 100644
--- a/third_party/crashpad/crashpad/test/scoped_set_thread_name_posix.cc
+++ b/third_party/crashpad/crashpad/test/scoped_set_thread_name_posix.cc
@@ -61,7 +61,7 @@
 
 std::string GetCurrentThreadName() {
   std::string result(kPthreadNameMaxLen, '\0');
-#if BUILDFLAG(IS_ANDROID) && __ANDROID_API__ < 24
+#if BUILDFLAG(IS_ANDROID) && __ANDROID_API__ < 26
   static constexpr char kGetThreadNameFunctionName[] = "prctl";
   PCHECK(prctl(PR_GET_NAME, result.data()) == 0) << "prctl(PR_GET_NAME)";
 #else
diff --git a/third_party/pyjson5/OWNERS b/third_party/pyjson5/OWNERS
new file mode 100644
index 0000000..68cf5bf
--- /dev/null
+++ b/third_party/pyjson5/OWNERS
@@ -0,0 +1 @@
+dpranke@google.com
diff --git a/tools/OWNERS b/tools/OWNERS
index 9f7685ae..d615f35 100644
--- a/tools/OWNERS
+++ b/tools/OWNERS
@@ -7,6 +7,7 @@
 
 set noparent
 brucedawson@chromium.org
+dpranke@google.com
 thakis@chromium.org
 
 per-file add_header*.py=dcheng@chromium.org
diff --git a/tools/android/avd/avd.py b/tools/android/avd/avd.py
index b4252dd85..cedec269 100755
--- a/tools/android/avd/avd.py
+++ b/tools/android/avd/avd.py
@@ -171,7 +171,7 @@
 
     debug_tags = args.debug_tags
     if not debug_tags and args.verbose:
-      debug_tags = 'init'
+      debug_tags = 'time,init'
 
     inst = avd_config.CreateInstance()
     inst.Start(read_only=args.read_only,
diff --git a/tools/clang/plugins/BlinkDataMemberTypeChecker.cpp b/tools/clang/plugins/BlinkDataMemberTypeChecker.cpp
index f85b782c..e563619 100644
--- a/tools/clang/plugins/BlinkDataMemberTypeChecker.cpp
+++ b/tools/clang/plugins/BlinkDataMemberTypeChecker.cpp
@@ -51,7 +51,7 @@
 
 void BlinkDataMemberTypeChecker::CheckClass(SourceLocation location,
                                             const CXXRecordDecl* record) {
-  std::string filename = GetFilename(instance_, location);
+  std::string filename = GetFilename(instance_.getSourceManager(), location);
   if (!included_filenames_regex_.match(filename))
     return;
   if (excluded_filenames_regex_.match(filename))
@@ -147,7 +147,8 @@
     // Similarly, stop finding the root underlying type if the intermediate
     // type is defined in a file that should not be checked, e.g. in a file
     // under third_party/blink/public/common.
-    std::string filename = GetFilename(instance_, decl->getLocation());
+    std::string filename =
+        GetFilename(instance_.getSourceManager(), decl->getLocation());
     if (!included_filenames_regex_.match(filename))
       return;
   }
diff --git a/tools/clang/plugins/CMakeLists.txt b/tools/clang/plugins/CMakeLists.txt
index 0c0c4aa..d07457f8 100644
--- a/tools/clang/plugins/CMakeLists.txt
+++ b/tools/clang/plugins/CMakeLists.txt
@@ -3,6 +3,7 @@
   ChromeClassTester.cpp
   FindBadConstructsAction.cpp
   FindBadConstructsConsumer.cpp
+  FindBadRawPtrPatterns.cpp
   CheckIPCVisitor.cpp
   CheckLayoutObjectMethodsVisitor.cpp
   Util.cpp
diff --git a/tools/clang/plugins/ChromeClassTester.cpp b/tools/clang/plugins/ChromeClassTester.cpp
index a76d59ff..603e2c8b 100644
--- a/tools/clang/plugins/ChromeClassTester.cpp
+++ b/tools/clang/plugins/ChromeClassTester.cpp
@@ -71,7 +71,7 @@
   if (instance().getSourceManager().isInSystemHeader(loc))
     return LocationType::kThirdParty;
 
-  std::string filename = GetFilename(instance(), loc);
+  std::string filename = GetFilename(instance().getSourceManager(), loc);
   if (filename.empty()) {
     // If the filename cannot be determined, simply treat this as a banned
     // location, instead of going through the full lookup process.
@@ -139,7 +139,7 @@
   // If |record_location| is a macro, check the whole chain of expansions.
   const SourceManager& source_manager = instance_.getSourceManager();
   while (true) {
-    filename = GetFilename(instance(), record_location);
+    filename = GetFilename(instance().getSourceManager(), record_location);
     if (ends_with(filename, ".cc") || ends_with(filename, ".cpp") ||
         ends_with(filename, ".mm")) {
       return true;
diff --git a/tools/clang/plugins/FindBadConstructsAction.cpp b/tools/clang/plugins/FindBadConstructsAction.cpp
index 698b4a8..c6ea3bc 100644
--- a/tools/clang/plugins/FindBadConstructsAction.cpp
+++ b/tools/clang/plugins/FindBadConstructsAction.cpp
@@ -55,6 +55,8 @@
       options_.check_layout_object_methods = true;
     } else if (args[i] == "raw-ref-template-as-trivial-member") {
       options_.raw_ref_template_as_trivial_member = true;
+    } else if (args[i] == "check-bad-raw-ptr-cast") {
+      options_.check_bad_raw_ptr_cast = true;
     } else {
       parsed = false;
       llvm::errs() << "Unknown clang plugin argument: " << args[i] << "\n";
diff --git a/tools/clang/plugins/FindBadConstructsConsumer.cpp b/tools/clang/plugins/FindBadConstructsConsumer.cpp
index ac25fd7..3386c131 100644
--- a/tools/clang/plugins/FindBadConstructsConsumer.cpp
+++ b/tools/clang/plugins/FindBadConstructsConsumer.cpp
@@ -4,6 +4,7 @@
 
 #include "FindBadConstructsConsumer.h"
 
+#include "FindBadRawPtrPatterns.h"
 #include "Util.h"
 #include "clang/AST/Attr.h"
 #include "clang/Frontend/CompilerInstance.h"
@@ -230,6 +231,7 @@
   RecursiveASTVisitor::TraverseDecl(context.getTranslationUnitDecl());
   if (ipc_visitor_)
     ipc_visitor_->set_context(nullptr);
+  FindBadRawPtrPatterns(options_, context, instance());
 }
 
 bool FindBadConstructsConsumer::TraverseDecl(Decl* decl) {
diff --git a/tools/clang/plugins/FindBadRawPtrPatterns.cpp b/tools/clang/plugins/FindBadRawPtrPatterns.cpp
new file mode 100644
index 0000000..7cbf997
--- /dev/null
+++ b/tools/clang/plugins/FindBadRawPtrPatterns.cpp
@@ -0,0 +1,105 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "FindBadRawPtrPatterns.h"
+
+#include "Util.h"
+#include "clang/AST/AST.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/Attr.h"
+#include "clang/AST/CXXInheritance.h"
+#include "clang/AST/TypeLoc.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/ASTMatchers/ASTMatchersMacros.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/Support/LineIterator.h"
+
+using namespace clang;
+using namespace clang::ast_matchers;
+
+namespace chrome_checker {
+
+const char kBadCastSignature[] =
+    "[chromium-raw-ptr-cast] Casting raw_ptr<T>* to another type is not "
+    "allowed as it may cause BRP ref count mismatch and bypass security "
+    "checks.";
+
+class BadCastMatcher : public MatchFinder::MatchCallback {
+ public:
+  explicit BadCastMatcher(clang::CompilerInstance& compiler)
+      : compiler_(compiler) {
+    error_bad_raw_ptr_cast_signature_ =
+        compiler_.getDiagnostics().getCustomDiagID(
+            clang::DiagnosticsEngine::Error, kBadCastSignature);
+  }
+
+  void Register(MatchFinder& match_finder) {
+    // TODO(keishi): Also find casts to and from classes that contain raw_ptr.
+    auto cast_matcher =
+        castExpr(
+            allOf(hasSourceExpression(hasType(pointerType(pointee(
+                      hasUnqualifiedDesugaredType(recordType(hasDeclaration(
+                          cxxRecordDecl(classTemplateSpecializationDecl(
+                              hasName("base::raw_ptr")))))))))),
+                  hasCastKind(CK_BitCast)))
+            .bind("castExpr");
+    match_finder.addMatcher(cast_matcher, this);
+  }
+
+  void run(const MatchFinder::MatchResult& result) override {
+    const clang::CastExpr* cast_expr =
+        result.Nodes.getNodeAs<clang::CastExpr>("castExpr");
+    assert(cast_expr && "matcher should bind 'castExpr'");
+
+    const clang::SourceManager& source_manager = *result.SourceManager;
+    clang::SourceLocation loc = cast_expr->getSourceRange().getBegin();
+    std::string file_path = GetFilename(source_manager, loc);
+
+    // Using raw_ptr<T> in a stdlib collection will cause a cast.
+    // e.g.
+    // https://source.chromium.org/chromium/chromium/src/+/main:components/feed/core/v2/xsurface_datastore.h;drc=a0ff03edcace35ec020edd235f4d9e9735fc9690;l=107
+    if (file_path.find("buildtools/third_party/libc++") != std::string::npos)
+      return;
+    // CHECK(raw_ptr<T>) will cause a cast.
+    // e.g.
+    // https://source.chromium.org/chromium/chromium/src/+/main:base/task/sequence_manager/thread_controller_with_message_pump_impl.cc;drc=c49b7434a9d4a61c49fc0123e904a6c5e7162731;l=121
+    if (file_path.find("base/check_op.h") != std::string::npos)
+      return;
+    // raw_ptr<T>* is cast to ui::metadata::PropertyKey
+    // https://source.chromium.org/chromium/chromium/src/+/main:ui/views/view.cc;drc=a0ff03edcace35ec020edd235f4d9e9735fc9690;l=2417
+    if (file_path.find("ui/views/controls/table/table_view.cc") !=
+        std::string::npos)
+      return;
+    // XdgActivation::activation_queue_ is a base::queue<raw_ptr> which causes a
+    // cast in VectorBuffer and circular_deque.
+    if (file_path.find("base/containers/vector_buffer.h") != std::string::npos)
+      return;
+    if (file_path.find("base/containers/circular_deque.h") != std::string::npos)
+      return;
+
+    compiler_.getDiagnostics().Report(cast_expr->getEndLoc(),
+                                      error_bad_raw_ptr_cast_signature_);
+  }
+
+ private:
+  clang::CompilerInstance& compiler_;
+  unsigned error_bad_raw_ptr_cast_signature_;
+};
+
+void FindBadRawPtrPatterns(Options options,
+                           clang::ASTContext& ast_context,
+                           clang::CompilerInstance& compiler) {
+  if (!options.check_bad_raw_ptr_cast)
+    return;
+  MatchFinder match_finder;
+
+  BadCastMatcher bad_cast_matcher(compiler);
+  bad_cast_matcher.Register(match_finder);
+
+  match_finder.matchAST(ast_context);
+}
+
+}  // namespace chrome_checker
diff --git a/tools/clang/plugins/FindBadRawPtrPatterns.h b/tools/clang/plugins/FindBadRawPtrPatterns.h
new file mode 100644
index 0000000..6d10e8e
--- /dev/null
+++ b/tools/clang/plugins/FindBadRawPtrPatterns.h
@@ -0,0 +1,20 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef TOOLS_CLANG_PLUGINS_FINDBADRAWPTRPATTERNS_H_
+#define TOOLS_CLANG_PLUGINS_FINDBADRAWPTRPATTERNS_H_
+
+#include "Options.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/Frontend/CompilerInstance.h"
+
+namespace chrome_checker {
+
+void FindBadRawPtrPatterns(Options options,
+                           clang::ASTContext& ast_context,
+                           clang::CompilerInstance& compiler);
+
+}  // namespace chrome_checker
+
+#endif  // TOOLS_CLANG_PLUGINS_FINDBADRAWPTRPATTERNS_H_
diff --git a/tools/clang/plugins/Options.h b/tools/clang/plugins/Options.h
index e06a971..e016193 100644
--- a/tools/clang/plugins/Options.h
+++ b/tools/clang/plugins/Options.h
@@ -13,6 +13,7 @@
   bool check_ipc = false;
   bool check_layout_object_methods = false;
   bool raw_ref_template_as_trivial_member = false;
+  bool check_bad_raw_ptr_cast = false;
 };
 
 }  // namespace chrome_checker
diff --git a/tools/clang/plugins/Util.cpp b/tools/clang/plugins/Util.cpp
index 73641113..5b6ebb41 100644
--- a/tools/clang/plugins/Util.cpp
+++ b/tools/clang/plugins/Util.cpp
@@ -37,9 +37,8 @@
   return GetNamespaceImpl(record->getDeclContext(), std::string());
 }
 
-std::string GetFilename(clang::CompilerInstance& instance,
+std::string GetFilename(const clang::SourceManager& source_manager,
                         clang::SourceLocation location) {
-  const clang::SourceManager& source_manager = instance.getSourceManager();
   clang::SourceLocation spelling_location =
       source_manager.getSpellingLoc(location);
   clang::PresumedLoc ploc = source_manager.getPresumedLoc(spelling_location);
diff --git a/tools/clang/plugins/Util.h b/tools/clang/plugins/Util.h
index 02f7edd..01f05b6 100644
--- a/tools/clang/plugins/Util.h
+++ b/tools/clang/plugins/Util.h
@@ -9,7 +9,7 @@
 
 #include "clang/AST/DeclBase.h"
 #include "clang/Basic/SourceLocation.h"
-#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Basic/SourceManager.h"
 
 // Utility method for subclasses to determine the namespace of the
 // specified record, if any. Unnamed namespaces will be identified as
@@ -18,7 +18,7 @@
 
 // Attempts to determine the filename for the given SourceLocation.
 // Returns an empty string if the filename could not be determined.
-std::string GetFilename(clang::CompilerInstance& instance,
+std::string GetFilename(const clang::SourceManager& instance,
                         clang::SourceLocation location);
 
 #endif  // TOOLS_CLANG_PLUGINS_UTIL_H_
diff --git a/tools/clang/plugins/tests/bad_raw_ptr_cast.cpp b/tools/clang/plugins/tests/bad_raw_ptr_cast.cpp
new file mode 100644
index 0000000..1ebfa3d
--- /dev/null
+++ b/tools/clang/plugins/tests/bad_raw_ptr_cast.cpp
@@ -0,0 +1,17 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "bad_raw_ptr_cast.h"
+
+#include <cstring>
+
+void BadRawPtr::Check() {
+  // Explicit cast from raw_ptr<T>* is not allowed.
+  void* bar = reinterpret_cast<void*>(&foo_);
+  bar = static_cast<void*>(&foo_);
+  bar = (void*)&foo_;
+  // Implicit cast from raw_ptr<T>* is not allowed.
+  bar = &foo_;
+  memcpy(&foo_, &foo_, 1);
+}
diff --git a/tools/clang/plugins/tests/bad_raw_ptr_cast.flags b/tools/clang/plugins/tests/bad_raw_ptr_cast.flags
new file mode 100644
index 0000000..f56a9561
--- /dev/null
+++ b/tools/clang/plugins/tests/bad_raw_ptr_cast.flags
@@ -0,0 +1 @@
+-Xclang -plugin-arg-find-bad-constructs -Xclang check-bad-raw-ptr-cast
diff --git a/tools/clang/plugins/tests/bad_raw_ptr_cast.h b/tools/clang/plugins/tests/bad_raw_ptr_cast.h
new file mode 100644
index 0000000..a6b8931
--- /dev/null
+++ b/tools/clang/plugins/tests/bad_raw_ptr_cast.h
@@ -0,0 +1,18 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef TOOLS_CLANG_PLUGINS_TESTS_BAD_RAW_PTR_CAST_H_
+#define TOOLS_CLANG_PLUGINS_TESTS_BAD_RAW_PTR_CAST_H_
+
+#include "base/memory/raw_ptr.h"
+
+class BadRawPtr {
+ public:
+  void Check();
+
+ private:
+  raw_ptr<int> foo_;
+};
+
+#endif  // TOOLS_CLANG_PLUGINS_TESTS_BAD_RAW_PTR_CAST_H_
\ No newline at end of file
diff --git a/tools/clang/plugins/tests/bad_raw_ptr_cast.txt b/tools/clang/plugins/tests/bad_raw_ptr_cast.txt
new file mode 100644
index 0000000..a1a11ba
--- /dev/null
+++ b/tools/clang/plugins/tests/bad_raw_ptr_cast.txt
@@ -0,0 +1,19 @@
+bad_raw_ptr_cast.cpp:11:44: error: [chromium-raw-ptr-cast] Casting raw_ptr<T>* to another type is not allowed as it may cause BRP ref count mismatch and bypass security checks.
+  void* bar = reinterpret_cast<void*>(&foo_);
+                                           ^
+bad_raw_ptr_cast.cpp:12:29: error: [chromium-raw-ptr-cast] Casting raw_ptr<T>* to another type is not allowed as it may cause BRP ref count mismatch and bypass security checks.
+  bar = static_cast<void*>(&foo_);
+                            ^
+bad_raw_ptr_cast.cpp:13:17: error: [chromium-raw-ptr-cast] Casting raw_ptr<T>* to another type is not allowed as it may cause BRP ref count mismatch and bypass security checks.
+  bar = (void*)&foo_;
+                ^
+bad_raw_ptr_cast.cpp:15:10: error: [chromium-raw-ptr-cast] Casting raw_ptr<T>* to another type is not allowed as it may cause BRP ref count mismatch and bypass security checks.
+  bar = &foo_;
+         ^
+bad_raw_ptr_cast.cpp:16:11: error: [chromium-raw-ptr-cast] Casting raw_ptr<T>* to another type is not allowed as it may cause BRP ref count mismatch and bypass security checks.
+  memcpy(&foo_, &foo_, 1);
+          ^
+bad_raw_ptr_cast.cpp:16:18: error: [chromium-raw-ptr-cast] Casting raw_ptr<T>* to another type is not allowed as it may cause BRP ref count mismatch and bypass security checks.
+  memcpy(&foo_, &foo_, 1);
+                 ^
+6 errors generated.
diff --git a/tools/gdb/gdb_chrome.py b/tools/gdb/gdb_chrome.py
index 154c30eb..8385554b 100644
--- a/tools/gdb/gdb_chrome.py
+++ b/tools/gdb/gdb_chrome.py
@@ -465,7 +465,7 @@
     return self.val['__a_']['__a_value']
 
 
-pp_set.add_printer('std::Cr::__atomic', '^std::Cr::__atomic<.*>$',
+pp_set.add_printer('std::Cr::__atomic', '^std::Cr::(__)?atomic<.*>$',
                    AtomicPrinter)
 
 gdb.printing.register_pretty_printer(gdb, pp_set, replace=_DEBUGGING)
diff --git a/tools/licenses.py b/tools/licenses.py
index 8acf3c3..677c633 100755
--- a/tools/licenses.py
+++ b/tools/licenses.py
@@ -89,6 +89,9 @@
     # Proprietary barcode detection library.
     os.path.join('third_party', 'barhopper'),
 
+    # Internal Chrome Build only for proprietary webref library.
+    os.path.join('components', 'optimization_guide', 'internal', 'third_party'),
+
     # Proprietary DevTools code.
     os.path.join('third_party', 'devtools-frontend-internal'),
 
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 828b87d..90008586 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -623,8 +623,7 @@
     },
 
     'chromium.memory': {
-      'Linux ASan LSan Builder': 'asan_lsan_release_trybot_minimum_symbols_reclient',
-      'Linux ASan LSan Low Symbols FYI Builder': 'asan_lsan_release_trybot_reclient',
+      'Linux ASan LSan Builder': 'asan_lsan_release_trybot_reclient',
       'Linux CFI': 'cfi_full_cfi_icall_cfi_diag_thin_lto_release_static_dcheck_always_on_reclient',
       'Linux Chromium OS ASan LSan Builder': 'asan_lsan_chromeos_release_bot_dcheck_always_on_reclient',
       'Linux ChromiumOS MSan Builder': 'chromeos_msan_release_bot_reclient',
@@ -817,7 +816,6 @@
     },
 
     'internal.chrome.fyi': {
-      'chromeos-amd64-generic-lacros-internal-rel': 'chromeos_amd64-generic_lacros_rel',
       'chromeos-arm-generic-cfi-thin-lto-chrome-reclient': 'chromeos_arm-generic_cfi_thin_lto_official_reclient',
       'lacros-arm-generic-chrome-fyi-reclient': 'chromeos_arm-generic_lacros_official_skylab_reclient',
       'linux-autofill-captured-sites-rel': 'release_bot_reclient',
@@ -1182,7 +1180,7 @@
       'linux-x64-castos-audio': 'cast_audio_release_trybot',
       'linux-x64-castos-dbg': 'cast_debug_bot',
       'linux_chromium_archive_rel_ng': 'release_bot_reclient',
-      'linux_chromium_asan_rel_ng': 'asan_lsan_release_trybot_minimum_symbols_reclient',
+      'linux_chromium_asan_rel_ng': 'asan_lsan_release_trybot_reclient',
       'linux_chromium_cfi_rel_ng': 'cfi_full_cfi_icall_cfi_diag_thin_lto_release_static_dcheck_always_on_reclient',
       'linux_chromium_chromeos_asan_rel_ng': 'asan_lsan_chromeos_release_bot_dcheck_always_on',
       'linux_chromium_chromeos_msan_focal': 'chromeos_msan_release_bot',
@@ -1924,12 +1922,8 @@
       'asan', 'lsan', 'release_bot_blink_reclient',
     ],
 
-    'asan_lsan_release_trybot_minimum_symbols_reclient': [
-      'asan', 'lsan', 'release_trybot_minimal_symbols_reclient',
-    ],
-
     'asan_lsan_release_trybot_reclient': [
-      'asan', 'lsan', 'release_trybot_reclient',
+      'asan', 'lsan', 'release_trybot_minimal_symbols_reclient',
     ],
 
     'asan_minimal_symbols_disable_nacl_release_bot_dcheck_always_on_reclient': [
@@ -2044,10 +2038,6 @@
       'chromeos_amd64-generic-crostoolchain', 'lacros', 'official', 'minimal_symbols', 'cfi', 'thin_lto', 'is_skylab',
     ],
 
-    'chromeos_amd64-generic_lacros_rel': [
-      'chromeos_amd64-generic-crostoolchain', 'lacros', 'release',
-    ],
-
     'chromeos_amd64-generic_lacros_rel_dchecks': [
       'chromeos_amd64-generic-crostoolchain', 'lacros', 'release', 'dcheck_always_on',
     ],
@@ -3268,7 +3258,7 @@
     ],
 
     'official_goma_fuchsia_x64_perf': [
-      'official', 'goma', 'minimal_symbols', 'fuchsia', 'fuchsia_include_chromebook_image', 'x64', 'ffmpeg_branding_chrome', 'proprietary_codecs', 'test_isolate_no_emulator', 'fuchsia_cfv2_script'
+      'official', 'goma', 'minimal_symbols', 'fuchsia', 'x64', 'ffmpeg_branding_chrome', 'proprietary_codecs', 'test_isolate_no_emulator', 'fuchsia_cfv2_script'
     ],
 
     'official_goma_linux_perf': [
@@ -3487,8 +3477,7 @@
     ],
 
     'release_bot_fuchsia_workstation_reclient': [
-      'release_bot_reclient', 'fuchsia', 'fuchsia_include_workstation_image',
-      'fuchsia_chrome'
+      'release_bot_reclient', 'fuchsia', 'fuchsia_chrome'
     ],
 
     'release_bot_mac_strip_minimal_symbols': [
@@ -3632,8 +3621,7 @@
     ],
 
     'release_trybot_fuchsia_workstation': [
-      'release_trybot', 'fuchsia', 'fuchsia_include_workstation_image',
-      'fuchsia_chrome'
+      'release_trybot', 'fuchsia', 'fuchsia_chrome'
     ],
 
     'release_trybot_minimal_symbols_reclient': [
@@ -4228,18 +4216,10 @@
       'gn_args': 'fuchsia_code_coverage=true',
     },
 
-    'fuchsia_include_chromebook_image': {
-      'gn_args': 'fuchsia_additional_boot_images=["//third_party/fuchsia-sdk/images/chromebook-x64-release/"]',
-    },
-
     'fuchsia_include_sd_images': {
       'gn_args': 'fuchsia_additional_boot_images=["//third_party/fuchsia-sdk/images-internal/astro-release/","//third_party/fuchsia-sdk/images-internal/sherlock-release/"]',
     },
 
-    'fuchsia_include_workstation_image': {
-      'gn_args': 'fuchsia_additional_boot_images=["//third_party/fuchsia-sdk/images/qemu-x64-release/"]',
-    },
-
     'full_symbols': {
       'gn_args': 'symbol_level=2',
     },
diff --git a/tools/mb/mb_config_expectations/chromium.fuchsia.fyi.json b/tools/mb/mb_config_expectations/chromium.fuchsia.fyi.json
index a72fe98..555f801 100644
--- a/tools/mb/mb_config_expectations/chromium.fuchsia.fyi.json
+++ b/tools/mb/mb_config_expectations/chromium.fuchsia.fyi.json
@@ -55,9 +55,6 @@
   "fuchsia-x64-workstation": {
     "gn_args": {
       "dcheck_always_on": false,
-      "fuchsia_additional_boot_images": [
-        "//third_party/fuchsia-sdk/images/qemu-x64-release/"
-      ],
       "fuchsia_browser_type": "chrome",
       "is_component_build": false,
       "is_debug": false,
diff --git a/tools/mb/mb_config_expectations/chromium.memory.json b/tools/mb/mb_config_expectations/chromium.memory.json
index e3b21db7..bfe35970 100644
--- a/tools/mb/mb_config_expectations/chromium.memory.json
+++ b/tools/mb/mb_config_expectations/chromium.memory.json
@@ -10,17 +10,6 @@
       "use_remoteexec": true
     }
   },
-  "Linux ASan LSan Low Symbols FYI Builder": {
-    "gn_args": {
-      "dcheck_always_on": true,
-      "is_asan": true,
-      "is_component_build": false,
-      "is_debug": false,
-      "is_lsan": true,
-      "symbol_level": 0,
-      "use_remoteexec": true
-    }
-  },
   "Linux CFI": {
     "gn_args": {
       "dcheck_always_on": true,
diff --git a/tools/mb/mb_config_expectations/chromium.perf.fyi.json b/tools/mb/mb_config_expectations/chromium.perf.fyi.json
index a24b02b..e4681fa 100644
--- a/tools/mb/mb_config_expectations/chromium.perf.fyi.json
+++ b/tools/mb/mb_config_expectations/chromium.perf.fyi.json
@@ -64,9 +64,6 @@
   "fuchsia-builder-perf-x64": {
     "gn_args": {
       "ffmpeg_branding": "Chrome",
-      "fuchsia_additional_boot_images": [
-        "//third_party/fuchsia-sdk/images/chromebook-x64-release/"
-      ],
       "is_chrome_branded": true,
       "is_official_build": true,
       "proprietary_codecs": true,
diff --git a/tools/mb/mb_config_expectations/client.v8.fyi.json b/tools/mb/mb_config_expectations/client.v8.fyi.json
index 78994a79..e9d534a2a 100644
--- a/tools/mb/mb_config_expectations/client.v8.fyi.json
+++ b/tools/mb/mb_config_expectations/client.v8.fyi.json
@@ -21,7 +21,7 @@
       "is_component_build": false,
       "is_debug": false,
       "is_lsan": true,
-      "symbol_level": 0,
+      "symbol_level": 1,
       "use_remoteexec": true
     }
   },
diff --git a/tools/mb/mb_config_expectations/internal.chrome.fyi.json b/tools/mb/mb_config_expectations/internal.chrome.fyi.json
index 600c7949..7112e01 100644
--- a/tools/mb/mb_config_expectations/internal.chrome.fyi.json
+++ b/tools/mb/mb_config_expectations/internal.chrome.fyi.json
@@ -1,16 +1,4 @@
 {
-  "chromeos-amd64-generic-lacros-internal-rel": {
-    "args_file": "//build/args/chromeos/amd64-generic-crostoolchain.gni",
-    "gn_args": {
-      "chromeos_is_browser_only": true,
-      "dcheck_always_on": false,
-      "is_chromeos_device": true,
-      "is_debug": false,
-      "ozone_platform_headless": true,
-      "target_os": "chromeos",
-      "use_goma": true
-    }
-  },
   "chromeos-arm-generic-cfi-thin-lto-chrome-reclient": {
     "args_file": "//build/args/chromeos/arm-generic.gni",
     "gn_args": {
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.fuchsia.json b/tools/mb/mb_config_expectations/tryserver.chromium.fuchsia.json
index f0489dc..5f281fe 100644
--- a/tools/mb/mb_config_expectations/tryserver.chromium.fuchsia.json
+++ b/tools/mb/mb_config_expectations/tryserver.chromium.fuchsia.json
@@ -121,9 +121,6 @@
   "fuchsia-x64-workstation": {
     "gn_args": {
       "dcheck_always_on": true,
-      "fuchsia_additional_boot_images": [
-        "//third_party/fuchsia-sdk/images/qemu-x64-release/"
-      ],
       "fuchsia_browser_type": "chrome",
       "is_component_build": false,
       "is_debug": false,
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.perf.json b/tools/mb/mb_config_expectations/tryserver.chromium.perf.json
index 3073566..090bb51 100644
--- a/tools/mb/mb_config_expectations/tryserver.chromium.perf.json
+++ b/tools/mb/mb_config_expectations/tryserver.chromium.perf.json
@@ -93,9 +93,6 @@
   "Fuchsia Builder Perf x64": {
     "gn_args": {
       "ffmpeg_branding": "Chrome",
-      "fuchsia_additional_boot_images": [
-        "//third_party/fuchsia-sdk/images/chromebook-x64-release/"
-      ],
       "is_chrome_branded": true,
       "is_official_build": true,
       "proprietary_codecs": true,
diff --git a/tools/md_browser/OWNERS b/tools/md_browser/OWNERS
new file mode 100644
index 0000000..68cf5bf
--- /dev/null
+++ b/tools/md_browser/OWNERS
@@ -0,0 +1 @@
+dpranke@google.com
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 689180e..0169994 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -19399,6 +19399,7 @@
   <int value="3" label="Excessive unique destination sites"/>
   <int value="4" label="Excessive reporting orgins"/>
   <int value="5" label="Prohibited by browser policy"/>
+  <int value="6" label="Success but noise applied"/>
 </enum>
 
 <enum name="ConversionStorageSqlInitStatus">
@@ -57457,6 +57458,7 @@
   <int value="-2075807193" label="enable-webusb-on-any-origin"/>
   <int value="-2075725205" label="disable-new-zip-unpacker"/>
   <int value="-2075607807" label="CSSOverflowForReplacedElements:disabled"/>
+  <int value="-2074936999" label="AutoDisableAccessibilityV2:disabled"/>
   <int value="-2074080173" label="NightLight:disabled"/>
   <int value="-2073402331"
       label="BrokerFileOperationsOnDiskCacheInNetworkService:disabled"/>
@@ -58865,6 +58867,7 @@
   <int value="-1276579737" label="PictureInPictureAPI:disabled"/>
   <int value="-1275552094" label="SpectreVariant2Mitigation:disabled"/>
   <int value="-1274502866" label="AllowDisableMouseAcceleration:enabled"/>
+  <int value="-1274154806" label="LacrosWaylandLogging:disabled"/>
   <int value="-1273786900" label="SyncAndroidPromosWithTitle:disabled"/>
   <int value="-1272990935"
       label="SyncAndroidLimitNTPPromoImpressions:disabled"/>
@@ -61791,6 +61794,7 @@
   <int value="474743272" label="material-design-ink-drop"/>
   <int value="475858648"
       label="OverlayScrollbarFlashAfterAnyScrollUpdate:disabled"/>
+  <int value="476814335" label="AutoDisableAccessibilityV2:enabled"/>
   <int value="477796416" label="ReleaseNotes:enabled"/>
   <int value="477967119" label="enable-unified-media-pipeline"/>
   <int value="478380451" label="BlockMigratedDefaultChromeAppSync:disabled"/>
@@ -62853,6 +62857,7 @@
   <int value="1114629582" label="enable-floating-virtual-keyboard"/>
   <int value="1114794286" label="AutofillTypeSpecificPopupWidth:disabled"/>
   <int value="1115532551" label="EnableFrameSinkDesktopCapturerInCrd:enabled"/>
+  <int value="1115564918" label="LacrosWaylandLogging:enabled"/>
   <int value="1115635149" label="EnableUnifiedMultiDeviceSetup:enabled"/>
   <int value="1116084116" label="BindingManagerConnectionLimit:enabled"/>
   <int value="1116593018" label="CaptureThumbnailOnLoadFinished:disabled"/>
diff --git a/tools/metrics/histograms/metadata/cookie/histograms.xml b/tools/metrics/histograms/metadata/cookie/histograms.xml
index 2f3eb92..c09b7b5 100644
--- a/tools/metrics/histograms/metadata/cookie/histograms.xml
+++ b/tools/metrics/histograms/metadata/cookie/histograms.xml
@@ -492,7 +492,7 @@
 </histogram>
 
 <histogram name="Cookie.IncludedResponseEffectiveSameSite"
-    enum="CookieEffectiveSameSite" expires_after="2022-11-20">
+    enum="CookieEffectiveSameSite" expires_after="2023-11-20">
   <owner>bingler@chromium.org</owner>
   <owner>miketaylr@chromium.org</owner>
   <summary>
@@ -655,7 +655,7 @@
 </histogram>
 
 <histogram name="Cookie.Port.Read.{HostType}" enum="InterestingCookiePorts"
-    expires_after="2022-11-18">
+    expires_after="2023-11-18">
   <owner>bingler@chromium.org</owner>
   <owner>miketaylr@chromium.org</owner>
   <summary>
@@ -677,7 +677,7 @@
 </histogram>
 
 <histogram name="Cookie.Port.ReadDiffersFromSet.{HostType}"
-    enum="CookieSentToSamePort" expires_after="2022-11-18">
+    enum="CookieSentToSamePort" expires_after="2023-11-18">
   <owner>bingler@chromium.org</owner>
   <owner>miketaylr@chromium.org</owner>
   <summary>
@@ -708,7 +708,7 @@
 </histogram>
 
 <histogram name="Cookie.Port.Set.{HostType}" enum="InterestingCookiePorts"
-    expires_after="2022-11-18">
+    expires_after="2023-11-18">
   <owner>bingler@chromium.org</owner>
   <owner>miketaylr@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/extensions/histograms.xml b/tools/metrics/histograms/metadata/extensions/histograms.xml
index 4fa3730..0cea4bd9 100644
--- a/tools/metrics/histograms/metadata/extensions/histograms.xml
+++ b/tools/metrics/histograms/metadata/extensions/histograms.xml
@@ -3014,7 +3014,7 @@
 </histogram>
 
 <histogram name="Extensions.SandboxedPageLoad.IsWebAccessibleResource"
-    enum="BooleanVisible" expires_after="2022-11-01">
+    enum="BooleanVisible" expires_after="2023-11-01">
   <owner>solomonkinard@google.com</owner>
   <owner>extensions-core@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/others/histograms.xml b/tools/metrics/histograms/metadata/others/histograms.xml
index 38b2f8e..6e0a003 100644
--- a/tools/metrics/histograms/metadata/others/histograms.xml
+++ b/tools/metrics/histograms/metadata/others/histograms.xml
@@ -4316,6 +4316,22 @@
 
 <histogram name="Conversions.SourceStoredStatus"
     enum="ConversionStorageSourceStatus" expires_after="M117">
+  <obsolete>
+    Replaced with Conversions.SourceStoredStatus2 due to enum value change,
+    November 2022.
+  </obsolete>
+  <owner>anthonygarant@chromium.org</owner>
+  <owner>linnan@chromium.org</owner>
+  <owner>measurement-api-dev+metrics@google.com</owner>
+  <summary>
+    Measures how often sources are stored successfully or rejected and why.
+    Recorded once for each source event processed by the attribution storage
+    layer.
+  </summary>
+</histogram>
+
+<histogram name="Conversions.SourceStoredStatus2"
+    enum="ConversionStorageSourceStatus" expires_after="M117">
   <owner>anthonygarant@chromium.org</owner>
   <owner>linnan@chromium.org</owner>
   <owner>measurement-api-dev+metrics@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/service/histograms.xml b/tools/metrics/histograms/metadata/service/histograms.xml
index 5f23537..221fe31 100644
--- a/tools/metrics/histograms/metadata/service/histograms.xml
+++ b/tools/metrics/histograms/metadata/service/histograms.xml
@@ -302,7 +302,7 @@
 </histogram>
 
 <histogram name="ServiceWorker.ExtendableMessageEvent.Time" units="ms"
-    expires_after="2022-12-15">
+    expires_after="2023-06-15">
   <owner>nhiroki@chromium.org</owner>
   <owner>chrome-worker@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/windows/histograms.xml b/tools/metrics/histograms/metadata/windows/histograms.xml
index 0fdf7b1..e2e6cc3 100644
--- a/tools/metrics/histograms/metadata/windows/histograms.xml
+++ b/tools/metrics/histograms/metadata/windows/histograms.xml
@@ -159,7 +159,7 @@
 </histogram>
 
 <histogram name="Windows.MakeChromeDefaultDirectly.Result"
-    enum="DefaultDirectAttemptResult" expires_after="M109">
+    enum="DefaultDirectAttemptResult" expires_after="M112">
   <owner>robliao@chromium.org</owner>
   <owner>davidbienvenu@chromium.org</owner>
   <summary>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index 1f3903d9d..8a85915 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -5,16 +5,16 @@
             "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux_arm64/49b4b5dcbc312d8d2c3751cf29238b8efeb4e494/trace_processor_shell"
         },
         "win": {
-            "hash": "c7f76776267357f2f63745f7906a50af25c537d1",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/cb8281edbb0e244234ce27dbf69b71c1334bc836/trace_processor_shell.exe"
+            "hash": "18d0103c2a2b08215dcfb6b4f4b695803acccea7",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/0cbb37ad93ee2bfcf4c1b0bc3e136eadbe4fb467/trace_processor_shell.exe"
         },
         "linux_arm": {
             "hash": "58893933be305d3bfe0a72ebebcacde2ac3ca893",
             "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux_arm/49b4b5dcbc312d8d2c3751cf29238b8efeb4e494/trace_processor_shell"
         },
         "mac": {
-            "hash": "99c915b3766b8c3edf3deeae545b533f7414fcbb",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/cb8281edbb0e244234ce27dbf69b71c1334bc836/trace_processor_shell"
+            "hash": "6f2840b72c0f8cab5e2f26ad39fe4a9aaebf955b",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/0cbb37ad93ee2bfcf4c1b0bc3e136eadbe4fb467/trace_processor_shell"
         },
         "mac_arm64": {
             "hash": "92318bea34f5c9beec69d2d826a9a92ec9d3cdcd",
diff --git a/tools/typescript/definitions/passwords_private.d.ts b/tools/typescript/definitions/passwords_private.d.ts
index 8cd59444..f1f8a9f 100644
--- a/tools/typescript/definitions/passwords_private.d.ts
+++ b/tools/typescript/definitions/passwords_private.d.ts
@@ -154,10 +154,8 @@
           id: number, reason: PlaintextReason): Promise<string>;
       export function requestCredentialDetails(id: number):
           Promise<PasswordUiEntry>;
-      export function getSavedPasswordList(
-          callback: (entries: PasswordUiEntry[]) => void): void;
-      export function getPasswordExceptionList(
-          callback: (entries: ExceptionEntry[]) => void): void;
+      export function getSavedPasswordList(): Promise<PasswordUiEntry[]>;
+      export function getPasswordExceptionList(): Promise<ExceptionEntry[]>;
       export function movePasswordsToAccount(ids: number[]): void;
       export function importPasswords(toStore: PasswordStoreSet):
           Promise<ImportResults>;
diff --git a/ui/android/delegated_frame_host_android.cc b/ui/android/delegated_frame_host_android.cc
index 4565e50..db1bee3 100644
--- a/ui/android/delegated_frame_host_android.cc
+++ b/ui/android/delegated_frame_host_android.cc
@@ -282,6 +282,7 @@
     return;
   registered_parent_compositor_->RemoveChildFrameSink(frame_sink_id_);
   registered_parent_compositor_ = nullptr;
+  content_to_visible_time_request_ = nullptr;
 }
 
 bool DelegatedFrameHostAndroid::IsPrimarySurfaceEvicted() const {
diff --git a/ui/file_manager/file_manager/background/js/BUILD.gn b/ui/file_manager/file_manager/background/js/BUILD.gn
index 5321a0b..27226ee0 100644
--- a/ui/file_manager/file_manager/background/js/BUILD.gn
+++ b/ui/file_manager/file_manager/background/js/BUILD.gn
@@ -141,10 +141,8 @@
     ":crostini",
     "//ui/file_manager/file_manager/externs/background:crostini",
   ]
-  visibility += [
-    "//ui/file_manager/file_manager/foreground/js:file_tasks_unittest",
-    "//ui/file_manager/file_manager/foreground/js:task_controller_unittest",
-  ]
+  visibility +=
+      [ "//ui/file_manager/file_manager/foreground/js:file_tasks_unittest" ]
 }
 
 js_unittest("crostini_unittest") {
diff --git a/ui/file_manager/file_manager/foreground/js/BUILD.gn b/ui/file_manager/file_manager/foreground/js/BUILD.gn
index 217f22c..e5214dff 100644
--- a/ui/file_manager/file_manager/foreground/js/BUILD.gn
+++ b/ui/file_manager/file_manager/foreground/js/BUILD.gn
@@ -1188,31 +1188,6 @@
   ]
 }
 
-js_unittest("task_controller_unittest") {
-  deps = [
-    ":directory_model",
-    ":fake_file_selection_handler",
-    ":file_selection",
-    ":metadata_update_controller",
-    "metadata:mock_metadata",
-    "ui:command",
-    "ui:file_manager_ui",
-    "//chrome/test/data/webui:chai_assert",
-    "//ui/file_manager/file_manager/background/js:mock_crostini",
-    "//ui/file_manager/file_manager/common/js:dialog_type",
-    "//ui/file_manager/file_manager/common/js:metrics",
-    "//ui/file_manager/file_manager/common/js:mock_chrome",
-    "//ui/file_manager/file_manager/common/js:mock_entry",
-    "//ui/file_manager/file_manager/common/js:test_error_reporting",
-    "//ui/file_manager/file_manager/common/js:util",
-    "//ui/file_manager/file_manager/common/js:volume_manager_types",
-    "//ui/file_manager/file_manager/externs:volume_manager",
-    "//ui/file_manager/file_manager/externs/background:progress_center",
-    "//ui/webui/resources/js:assert",
-    "//ui/webui/resources/js/cr:ui",
-  ]
-}
-
 js_library("task_history") {
   deps = [
     "//ui/webui/resources/js:cr_deprecated",
@@ -1285,7 +1260,6 @@
     ":path_component_unittest",
     ":providers_model_unittest",
     ":spinner_controller_unittest",
-    ":task_controller_unittest",
     ":thumbnail_loader_unittest",
   ]
 
diff --git a/ui/file_manager/file_manager/foreground/js/task_controller_unittest.js b/ui/file_manager/file_manager/foreground/js/task_controller_unittest.ts
similarity index 77%
rename from ui/file_manager/file_manager/foreground/js/task_controller_unittest.js
rename to ui/file_manager/file_manager/foreground/js/task_controller_unittest.ts
index 6cb8874..a3c0689d 100644
--- a/ui/file_manager/file_manager/foreground/js/task_controller_unittest.js
+++ b/ui/file_manager/file_manager/foreground/js/task_controller_unittest.ts
@@ -4,6 +4,7 @@
 
 import {assert} from 'chrome://resources/js/assert.js';
 import {decorate} from 'chrome://resources/js/cr/ui.js';
+import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
 import {assertNotReached} from 'chrome://webui-test/chai_assert.js';
 
 import {createCrostiniForTest} from '../../background/js/mock_crostini.js';
@@ -20,36 +21,32 @@
 import {DirectoryModel} from './directory_model.js';
 import {FakeFileSelectionHandler} from './fake_file_selection_handler.js';
 import {FileSelectionHandler} from './file_selection.js';
+import {FileTasks} from './file_tasks.js';
+import {MetadataModel} from './metadata/metadata_model.js';
 import {MockMetadataModel} from './metadata/mock_metadata.js';
 import {MetadataUpdateController} from './metadata_update_controller.js';
 import {TaskController} from './task_controller.js';
 import {Command} from './ui/command.js';
 import {FileManagerUI} from './ui/file_manager_ui.js';
 
-/**
- * Mock metrics.
- * @param {string} name
- * @param {*} value
- * @param {Array<*>|number=} valid
- */
-metrics.recordEnum = function(name, value, valid) {};
 
-/**
- * Mock chrome APIs.
- * @type {!Object}
- */
-let mockChrome;
+/** Mock metrics. */
+metrics.recordEnum = function(
+    _name: string, _value: any, _valid?: any[]|number) {};
+
+/** Mock chrome APIs.  */
+let mockChrome: any;
 
 // Set up test components.
 export function setUp() {
   // Mock LoadTimeData strings.
-  window.loadTimeData.getBoolean = key => false;
-  window.loadTimeData.getString = id => id;
+  loadTimeData.getBoolean = (_key: string) => false;
+  loadTimeData.getString = (id: string) => id;
 
   // Mock chrome APIs.
   mockChrome = {
     commandLinePrivate: {
-      hasSwitch: function(name, callback) {
+      hasSwitch: function(_name: string, callback: (v: boolean) => void) {
         callback(false);
       },
     },
@@ -59,13 +56,13 @@
     },
     storage: {
       onChanged: {
-        addListener: function(callback) {},
+        addListener: function(_callback: EventListener) {},
       },
       local: {
-        get: function(key, callback) {
+        get: function(_key: string, callback: (v: any) => void) {
           callback({});
         },
-        set: function(value) {},
+        set: function(_value: any) {},
       },
     },
   };
@@ -83,16 +80,11 @@
   decorate('command', Command);
 }
 
-/**
- * Returns a task controller.
- * @param {!FileSelectionHandler} fileSelectionHandler
- * @return {!TaskController}
- */
-function createTaskController(fileSelectionHandler) {
+function createTaskController(fileSelectionHandler: FileSelectionHandler):
+    TaskController {
   const taskController = new TaskController(
-      DialogType.FULL_PAGE,
-      /** @type {!VolumeManager} */ ({
-        getLocationInfo: function(entry) {
+      DialogType.FULL_PAGE, {
+        getLocationInfo: function(_entry: Entry) {
           return VolumeManagerCommon.RootType.DRIVE;
         },
         getDriveConnectionState: function() {
@@ -103,21 +95,19 @@
             volumeType: VolumeManagerCommon.VolumeType.DRIVE,
           };
         },
-      }),
-      /** @type {!FileManagerUI} */ ({
+      } as unknown as VolumeManager,
+      {
         taskMenuButton: document.createElement('button'),
         fileContextMenu: {
           defaultActionMenuItem: document.createElement('div'),
         },
-        speakA11yMessage: text => {},
-      }),
-      new MockMetadataModel({}),
-      /** @type {!DirectoryModel} */ ({
+        speakA11yMessage: (_text: string) => {},
+      } as unknown as FileManagerUI,
+      new MockMetadataModel({}) as unknown as MetadataModel, {
         getCurrentRootType: () => null,
-      }),
-      fileSelectionHandler,
-      /** @type {!MetadataUpdateController} */ ({}), createCrostiniForTest(),
-      /** @type {!ProgressCenter} */ ({}));
+      } as unknown as DirectoryModel,
+      fileSelectionHandler, {} as unknown as MetadataUpdateController,
+      createCrostiniForTest(), {} as unknown as ProgressCenter);
 
   return taskController;
 }
@@ -139,9 +129,9 @@
     },
     getFileTaskCalledCount_: 0,
     onIOTaskProgressStatus: {
-      addListener: function(callback) {},
+      addListener: function(_callback: EventListener) {},
     },
-    getFileTasks: function(entries, callback) {
+    getFileTasks: function(_entries: Entry[], callback: (tasks: any) => void) {
       mockChrome.fileManagerPrivate.getFileTaskCalledCount_++;
       const fileTasks = ([
         /** @type {!chrome.fileManagerPrivate.FileTask} */ ({
@@ -172,8 +162,9 @@
 /**
  * Tests that executeEntryTask() runs the expected task.
  */
-export function testExecuteEntryTask(callback) {
-  const selectionHandler = new FakeFileSelectionHandler();
+export function testExecuteEntryTask(callback: () => void) {
+  const selectionHandler =
+      new FakeFileSelectionHandler() as unknown as FileSelectionHandler;
 
   const fileSystem = new MockFileSystem('volumeId');
   fileSystem.entries['/test.png'] =
@@ -184,9 +175,9 @@
   taskController.executeEntryTask(testEntry);
 
   reportPromise(
-      new Promise(resolve => {
+      new Promise<chrome.fileManagerPrivate.FileTaskDescriptor>((resolve) => {
         mockChrome.fileManagerPrivate.executeTask = resolve;
-      }).then(descriptor => {
+      }).then((descriptor: chrome.fileManagerPrivate.FileTaskDescriptor) => {
         assert(util.descriptorEqual(
             {appId: 'handler-extension-id', taskType: 'file', actionId: 'play'},
             descriptor));
@@ -198,13 +189,15 @@
  * Tests that getFileTasks() does not call .fileManagerPrivate.getFileTasks()
  * multiple times when the selected entries are not changed.
  */
-export function testGetFileTasksShouldNotBeCalledMultipleTimes(callback) {
+export function testGetFileTasksShouldNotBeCalledMultipleTimes(
+    callback: () => void) {
   const selectionHandler = new FakeFileSelectionHandler();
 
   const fileSystem = new MockFileSystem('volumeId');
   selectionHandler.updateSelection(
       [MockFileEntry.create(fileSystem, '/test.png')], ['image/png']);
-  const taskController = createTaskController(selectionHandler);
+  const taskController =
+      createTaskController(selectionHandler as unknown as FileSelectionHandler);
 
   assert(mockChrome.fileManagerPrivate.getFileTaskCalledCount_ === 0);
 
@@ -235,13 +228,15 @@
  * correspond to FileSelectionHandler.selection at the time getFileTasks() is
  * called.
  */
-export function testGetFileTasksShouldNotReturnObsoletePromise(callback) {
+export function testGetFileTasksShouldNotReturnObsoletePromise(
+    callback: () => void) {
   const selectionHandler = new FakeFileSelectionHandler();
 
   const fileSystem = new MockFileSystem('volumeId');
   selectionHandler.updateSelection(
       [MockFileEntry.create(fileSystem, '/test.png')], ['image/png']);
-  const taskController = createTaskController(selectionHandler);
+  const taskController =
+      createTaskController(selectionHandler as unknown as FileSelectionHandler);
 
   taskController.getFileTasks()
       .then(tasks => {
@@ -267,13 +262,15 @@
  * Tests that changing the file selection during a getFileTasks() call causes
  * the getFileTasks() promise to reject.
  */
-export function testGetFileTasksShouldNotCacheRejectedPromise(callback) {
+export function testGetFileTasksShouldNotCacheRejectedPromise(
+    callback: () => void) {
   const selectionHandler = new FakeFileSelectionHandler();
 
   const fileSystem = new MockFileSystem('volumeId');
   selectionHandler.updateSelection(
       [MockFileEntry.create(fileSystem, '/test.png')], ['image/png']);
-  const taskController = createTaskController(selectionHandler);
+  const taskController =
+      createTaskController(selectionHandler as unknown as FileSelectionHandler);
 
   // Setup the selection handler computeAdditionalCallback to change the file
   // selection during the getFileTasks() call.
@@ -283,7 +280,7 @@
   };
 
   taskController.getFileTasks().then(
-      tasks => {
+      (_tasks: FileTasks) => {
         assertNotReached('Fail: getFileTasks promise should be rejected');
         callback();
       },
diff --git a/ui/file_manager/file_names.gni b/ui/file_manager/file_names.gni
index 9398ae1..f36a1fcae 100644
--- a/ui/file_manager/file_names.gni
+++ b/ui/file_manager/file_names.gni
@@ -298,6 +298,9 @@
   "file_manager/widgets/xf_dlp_restriction_details_dialog_unittest.ts",
   "file_manager/widgets/xf_nudge_unittest.ts",
   "file_manager/widgets/xf_select_unittest.ts",
+
+  # Foreground:
+  "file_manager/foreground/js/task_controller_unittest.ts",
 ]
 
 ts_generated_templates = []
@@ -400,7 +403,6 @@
   "file_manager/foreground/js/metadata/metadata_cache_set_unittest.js",
   "file_manager/foreground/js/metadata/multi_metadata_provider_unittest.js",
   "file_manager/foreground/js/file_manager_commands_unittest.js",
-  "file_manager/foreground/js/task_controller_unittest.js",
   "file_manager/foreground/js/thumbnail_loader_unittest.js",
   "file_manager/foreground/js/directory_contents_unittest.js",
   "file_manager/foreground/js/file_list_model_unittest.js",
diff --git a/ui/gfx/geometry/quad_f_unittest.cc b/ui/gfx/geometry/quad_f_unittest.cc
index 8b844ce..985aeb27 100644
--- a/ui/gfx/geometry/quad_f_unittest.cc
+++ b/ui/gfx/geometry/quad_f_unittest.cc
@@ -9,6 +9,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gfx/geometry/quad_f.h"
 #include "ui/gfx/geometry/rect_f.h"
+#include "ui/gfx/geometry/transform.h"
 
 namespace gfx {
 
@@ -154,6 +155,46 @@
   }
 }
 
+TEST(QuadFTest, IsRectilinearForMappedQuad) {
+  const int kNumRectilinear = 8;
+  Transform rectilinear_trans[kNumRectilinear];
+  rectilinear_trans[1].Rotate(90.f);
+  rectilinear_trans[2].Rotate(180.f);
+  rectilinear_trans[3].Rotate(270.f);
+  rectilinear_trans[4].Skew(0.00000000001f, 0.0f);
+  rectilinear_trans[5].Skew(0.0f, 0.00000000001f);
+  rectilinear_trans[6].Scale(0.00001f, 0.00001f);
+  rectilinear_trans[6].Rotate(180.f);
+  rectilinear_trans[7].Scale(100000.f, 100000.f);
+  rectilinear_trans[7].Rotate(180.f);
+
+  gfx::QuadF original(
+      gfx::RectF(0.01010101f, 0.01010101f, 100.01010101f, 100.01010101f));
+
+  for (int i = 0; i < kNumRectilinear; ++i) {
+    gfx::QuadF quad = rectilinear_trans[i].MapQuad(original);
+    EXPECT_TRUE(quad.IsRectilinear()) << "case " << i;
+  }
+
+  const int kNumNonRectilinear = 10;
+  gfx::Transform non_rectilinear_trans[kNumNonRectilinear];
+  non_rectilinear_trans[0].Rotate(359.9999f);
+  non_rectilinear_trans[1].Rotate(0.0000001f);
+  non_rectilinear_trans[2].Rotate(89.9999f);
+  non_rectilinear_trans[3].Rotate(90.00001f);
+  non_rectilinear_trans[4].Rotate(179.9999f);
+  non_rectilinear_trans[5].Rotate(180.00001f);
+  non_rectilinear_trans[6].Rotate(269.9999f);
+  non_rectilinear_trans[7].Rotate(270.0001f);
+  non_rectilinear_trans[8].Skew(0.00001f, 0.0f);
+  non_rectilinear_trans[9].Skew(0.0f, 0.00001f);
+
+  for (int i = 0; i < kNumNonRectilinear; ++i) {
+    gfx::QuadF quad = non_rectilinear_trans[i].MapQuad(original);
+    EXPECT_FALSE(quad.IsRectilinear()) << "case " << i;
+  }
+}
+
 TEST(QuadFTest, IsCounterClockwise) {
   PointF a1(1, 1);
   PointF b1(2, 1);
diff --git a/ui/gfx/geometry/transform.cc b/ui/gfx/geometry/transform.cc
index d8e8f37..05745e229 100644
--- a/ui/gfx/geometry/transform.cc
+++ b/ui/gfx/geometry/transform.cc
@@ -16,10 +16,10 @@
 #include "ui/gfx/geometry/double4.h"
 #include "ui/gfx/geometry/point3_f.h"
 #include "ui/gfx/geometry/point_conversions.h"
+#include "ui/gfx/geometry/quad_f.h"
 #include "ui/gfx/geometry/quaternion.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/rect_conversions.h"
-#include "ui/gfx/geometry/skia_conversions.h"
 #include "ui/gfx/geometry/transform_util.h"
 #include "ui/gfx/geometry/vector3d_f.h"
 
@@ -720,12 +720,7 @@
     return axis_2d_.MapRect(rect);
   }
 
-  // TODO(crbug.com/1359528): Use local implementation.
-  SkRect src = RectFToSkRect(rect);
-  TransformToFlattenedSkMatrix(*this).mapRect(&src);
-  return RectF(ClampFloatGeometry(src.x()), ClampFloatGeometry(src.y()),
-               ClampFloatGeometry(src.width()),
-               ClampFloatGeometry(src.height()));
+  return MapQuad(QuadF(rect)).BoundingBox();
 }
 
 Rect Transform::MapRect(const Rect& rect) const {
@@ -750,12 +745,7 @@
   if (!GetInverse(&inverse))
     return absl::nullopt;
 
-  // TODO(crbug.com/1359528): Use local implementation and clamp the results.
-  SkRect src = RectFToSkRect(rect);
-  TransformToFlattenedSkMatrix(inverse).mapRect(&src);
-  return RectF(ClampFloatGeometry(src.x()), ClampFloatGeometry(src.y()),
-               ClampFloatGeometry(src.width()),
-               ClampFloatGeometry(src.height()));
+  return inverse.MapQuad(QuadF(rect)).BoundingBox();
 }
 
 absl::optional<Rect> Transform::InverseMapRect(const Rect& rect) const {
@@ -786,6 +776,89 @@
   return bounds;
 }
 
+QuadF Transform::MapQuad(const QuadF& quad) const {
+  return QuadF(MapPoint(quad.p1()), MapPoint(quad.p2()), MapPoint(quad.p3()),
+               MapPoint(quad.p4()));
+}
+
+PointF Transform::ProjectPoint(const PointF& point, bool* clamped) const {
+  // This is basically ray-tracing. We have a point in the destination plane
+  // with z=0, and we cast a ray parallel to the z-axis from that point to find
+  // the z-position at which it intersects the z=0 plane with the transform
+  // applied. Once we have that point we apply the inverse transform to find
+  // the corresponding point in the source space.
+  //
+  // Given a plane with normal Pn, and a ray starting at point R0 and with
+  // direction defined by the vector Rd, we can find the intersection point as
+  // a distance d from R0 in units of Rd by:
+  //
+  // d = -dot (Pn', R0) / dot (Pn', Rd)
+
+  if (clamped)
+    *clamped = false;
+
+  if (LIKELY(!matrix_))
+    return axis_2d_.MapPoint(point);
+
+  if (!std::isnormal(matrix_->rc(2, 2))) {
+    // In this case, the projection plane is parallel to the ray we are trying
+    // to trace, and there is no well-defined value for the projection.
+    if (clamped)
+      *clamped = true;
+    return gfx::PointF();
+  }
+
+  double x = point.x();
+  double y = point.y();
+  double z =
+      -(matrix_->rc(2, 0) * x + matrix_->rc(2, 1) * y + matrix_->rc(2, 3)) /
+      matrix_->rc(2, 2);
+  if (!std::isfinite(z)) {
+    // Same as the previous condition.
+    if (clamped)
+      *clamped = true;
+    return gfx::PointF();
+  }
+
+  double v[4] = {x, y, z, 1};
+  matrix_->MapScalars(v);
+
+  if (v[3] <= 0) {
+    // To represent infinity and ensure the bounding box of ProjectQuad() is
+    // accurate in both float, int and blink::LayoutUnit, we use a large but
+    // not-too-large number here when clamping.
+    constexpr double kBigNumber = 1 << (std::numeric_limits<float>::digits - 1);
+    if (clamped)
+      *clamped = true;
+    return PointF(std::copysign(kBigNumber, v[0]),
+                  std::copysign(kBigNumber, v[1]));
+  }
+
+  if (v[3] != 1) {
+    v[0] /= v[3];
+    v[1] /= v[3];
+  }
+  return PointF(ClampFloatGeometry(v[0]), ClampFloatGeometry(v[1]));
+}
+
+QuadF Transform::ProjectQuad(const QuadF& quad) const {
+  bool clamped1 = false;
+  bool clamped2 = false;
+  bool clamped3 = false;
+  bool clamped4 = false;
+
+  QuadF projected_quad(
+      ProjectPoint(quad.p1(), &clamped1), ProjectPoint(quad.p2(), &clamped2),
+      ProjectPoint(quad.p3(), &clamped3), ProjectPoint(quad.p4(), &clamped4));
+
+  // If all points on the quad had w < 0, then the entire quad would not be
+  // visible to the projected surface.
+  if (clamped1 && clamped2 && clamped3 && clamped4)
+    return QuadF();
+
+  return projected_quad;
+}
+
 absl::optional<DecomposedTransform> Transform::Decompose() const {
   if (LIKELY(!matrix_)) {
     // Consider letting 2d decomposition always succeed.
@@ -858,13 +931,13 @@
   }
 }
 
-Point3F Transform::MapPointInternal(const Matrix44& xform,
+Point3F Transform::MapPointInternal(const Matrix44& matrix,
                                     const Point3F& point) const {
   DCHECK(matrix_);
 
   double p[4] = {point.x(), point.y(), point.z(), 1};
 
-  xform.MapScalars(p);
+  matrix.MapScalars(p);
 
   if (p[3] != 1.0 && std::isnormal(p[3])) {
     float w_inverse = 1.0 / p[3];
diff --git a/ui/gfx/geometry/transform.h b/ui/gfx/geometry/transform.h
index 7ffb8f8..76d8fdc 100644
--- a/ui/gfx/geometry/transform.h
+++ b/ui/gfx/geometry/transform.h
@@ -23,6 +23,7 @@
 class Point;
 class PointF;
 class Point3F;
+class QuadF;
 class Quaternion;
 class Vector2dF;
 class Vector3dF;
@@ -391,6 +392,7 @@
   // Returns the point with the transformation applied to |point|, clamped
   // with ClampFloatGeometry().
   [[nodiscard]] Point3F MapPoint(const Point3F& point) const;
+  // Maps [point.x(), point.y(), 0] to [result.x(), result.y(), discarded_z].
   [[nodiscard]] PointF MapPoint(const PointF& point) const;
   [[nodiscard]] Point MapPoint(const Point& point) const;
 
@@ -433,6 +435,36 @@
   // transformed box, clamped with ClampFloatGeometry().
   [[nodiscard]] BoxF MapBox(const BoxF& box) const;
 
+  // Applies transformation on the given quad by applying the transformation
+  // on each point of the quad.
+  [[nodiscard]] QuadF MapQuad(const QuadF& quad) const;
+
+  // Maps a point on the z=0 plane into a point on the plane with which the
+  // transform applied, by extending a ray perpendicular to the source plane and
+  // computing the local x,y position of the point where that ray intersects
+  // with the destination plane. If such a point exists, sets |*clamped| (if
+  // provided) to false and returns the point. Otherwise sets |*clamped| (if
+  // provided) to true and:
+  // - If the ray is parallel with the destination plane, returns PointF().
+  // - If the opposite ray intersects with the destination plane, returns
+  //   a point containing signed big values (simulating infinities).
+  //
+  // See https://bit.ly/perspective-projection-clamping for an illustration of
+  // clamping with perspective.
+  //
+  // When |this| is invertible and the result |*clamped| is false, this
+  // function is equivalent to:
+  //   inverse(flatten(inverse(this))).MapPoint(point)
+  // and
+  //   MapPoint(Point3F(point.x(), point.y(), unknown_z)) to
+  //   Point3F(result.x(), result.y(), 0).
+  [[nodiscard]] PointF ProjectPoint(const PointF& point,
+                                    bool* clamped = nullptr) const;
+
+  // Projects the four corners of the quad with ProjectPoint(). Returns an
+  // empty quad if all of the vertices are clamped.
+  [[nodiscard]] QuadF ProjectQuad(const QuadF& quad) const;
+
   // Decomposes |this| into |decomp|. Returns nullopt if |this| can't be
   // decomposed. |decomp| must be identity on input.
   //
@@ -518,7 +550,7 @@
             double r3c3);
   Transform(float scale_x, float scale_y, float trans_x, float trans_y);
 
-  Point3F MapPointInternal(const Matrix44& xform, const Point3F& point) const;
+  Point3F MapPointInternal(const Matrix44& matrix, const Point3F& point) const;
 
   Matrix44 GetFullMatrix() const;
   Matrix44& EnsureFullMatrix();
diff --git a/ui/gfx/geometry/transform_unittest.cc b/ui/gfx/geometry/transform_unittest.cc
index 8de9ac5..38d0d4f0 100644
--- a/ui/gfx/geometry/transform_unittest.cc
+++ b/ui/gfx/geometry/transform_unittest.cc
@@ -2964,6 +2964,12 @@
 
   auto singular = Transform::MakeScale(0.f);
   EXPECT_EQ(RectF(0, 0, 0, 0), singular.MapRect(rect));
+
+  auto negative_scale = Transform::MakeScale(-1, -2);
+  EXPECT_EQ(RectF(-5.f, -13.f, 3.75f, 8.f), negative_scale.MapRect(rect));
+
+  auto rotate = Transform::Make90degRotation();
+  EXPECT_EQ(RectF(-6.5f, 1.25f, 4.f, 3.75f), rotate.MapRect(rect));
 }
 
 TEST(XFormTest, MapIntRect) {
@@ -2986,6 +2992,13 @@
 
   auto singular = Transform::MakeScale(0.f);
   EXPECT_FALSE(singular.InverseMapRect(rect));
+
+  auto negative_scale = Transform::MakeScale(-1, -2);
+  EXPECT_EQ(RectF(-5.f, -3.25f, 3.75f, 2.f),
+            negative_scale.InverseMapRect(rect));
+
+  auto rotate = Transform::Make90degRotation();
+  EXPECT_EQ(RectF(2.5f, -5.f, 4.f, 3.75f), rotate.InverseMapRect(rect));
 }
 
 TEST(XFormTest, InverseMapIntRect) {
@@ -2998,6 +3011,30 @@
   EXPECT_FALSE(singular.InverseMapRect(Rect(1, 2, 3, 4)));
 }
 
+TEST(XFormTest, MapQuad) {
+  auto translation = Transform::MakeTranslation(3.25f, 7.75f);
+  QuadF q(PointF(1.25f, 2.5f), PointF(3.75f, 4.f), PointF(23.f, 45.f),
+          PointF(12.f, 67.f));
+  EXPECT_EQ(QuadF(PointF(4.5f, 10.25f), PointF(7.f, 11.75f),
+                  PointF(26.25f, 52.75f), PointF(15.25f, 74.75f)),
+            translation.MapQuad(q));
+
+  EXPECT_EQ(q, Transform().MapQuad(q));
+
+  auto singular = Transform::MakeScale(0.f);
+  EXPECT_EQ(QuadF(), singular.MapQuad(q));
+
+  auto negative_scale = Transform::MakeScale(-1, -2);
+  EXPECT_EQ(QuadF(PointF(-1.25f, -5.f), PointF(-3.75f, -8.f),
+                  PointF(-23.f, -90.f), PointF(-12.f, -134.f)),
+            negative_scale.MapQuad(q));
+
+  auto rotate = Transform::Make90degRotation();
+  EXPECT_EQ(QuadF(PointF(-2.5f, 1.25f), PointF(-4.f, 3.75f),
+                  PointF(-45.f, 23.f), PointF(-67.f, 12.f)),
+            rotate.MapQuad(q));
+}
+
 TEST(XFormTest, MapBox) {
   Transform translation;
   translation.Translate3d(3.f, 7.f, 6.f);
@@ -3366,6 +3403,126 @@
   }
 }
 
+constexpr float kProjectionClampedBigNumber =
+    1 << (std::numeric_limits<float>::digits - 1);
+
+// This test also demonstrates the relationship between ProjectPoint() and
+// MapPoint().
+TEST(XFormTest, ProjectPoint) {
+  Transform transform;
+  PointF p(1.25f, -3.5f);
+  bool clamped = true;
+  EXPECT_EQ(p, transform.ProjectPoint(p));
+  EXPECT_EQ(p, transform.ProjectPoint(p, &clamped));
+  EXPECT_FALSE(clamped);
+  // MapPoint() and ProjectPoint() are the same with a flat transform.
+  EXPECT_EQ(p, transform.MapPoint(p));
+
+  // ProjectPoint with simple 2d transform.
+  transform = Transform::MakeTranslation(10, 20) * Transform::MakeScale(3, 4);
+  clamped = true;
+  gfx::PointF projected = transform.ProjectPoint(p, &clamped);
+  EXPECT_EQ(PointF(13.75f, 6.f), projected);
+  EXPECT_FALSE(clamped);
+  // MapPoint() and ProjectPoint() are the same with a flat transform.
+  EXPECT_EQ(projected, transform.MapPoint(p));
+
+  clamped = true;
+  transform.EnsureFullMatrixForTesting();
+  EXPECT_EQ(projected, transform.ProjectPoint(p, &clamped));
+  EXPECT_FALSE(clamped);
+  EXPECT_EQ(projected, transform.MapPoint(p));
+
+  // Set scale z to 0.
+  transform.set_rc(2, 2, 0);
+  clamped = true;
+  projected = transform.ProjectPoint(p, &clamped);
+  EXPECT_EQ(PointF(), projected);
+  EXPECT_TRUE(clamped);
+  // MapPoint() still produces the original result.
+  EXPECT_EQ(PointF(13.75f, 6.f), transform.MapPoint(p));
+
+  // Normally (except the last case below), t.ProjectPoint() is equivalent to
+  // inverse(flatten(inverse(t))).MapPoint().
+  auto projection_transform = [](const Transform& t) {
+    auto flat = t.GetCheckedInverse();
+    flat.FlattenTo2d();
+    return flat.GetCheckedInverse();
+  };
+
+  transform.MakeIdentity();
+  transform.RotateAboutYAxis(60);
+  clamped = true;
+  projected = transform.ProjectPoint(p, &clamped);
+  EXPECT_EQ(PointF(2.5f, -3.5f), projected);
+  EXPECT_FALSE(clamped);
+  EXPECT_EQ(PointF(0.625f, -3.5f), transform.MapPoint(p));
+
+  EXPECT_EQ(projected, projection_transform(transform).MapPoint(p));
+  EXPECT_EQ(projected, projection_transform(transform).ProjectPoint(p));
+
+  transform.ApplyPerspectiveDepth(10);
+  clamped = true;
+  projected = transform.ProjectPoint(p, &clamped);
+  EXPECT_POINTF_NEAR(PointF(3.19f, -4.47f), projected, 0.01f);
+  EXPECT_FALSE(clamped);
+  EXPECT_EQ(PointF(0.625f, -3.5f), transform.MapPoint(p));
+
+  EXPECT_POINTF_NEAR(projected, projection_transform(transform).MapPoint(p),
+                     1e-5f);
+  EXPECT_POINTF_NEAR(projected, projection_transform(transform).ProjectPoint(p),
+                     1e-5f);
+
+  // With a small perspective, the ray doesn't intersect the destination plane.
+  transform.ApplyPerspectiveDepth(2);
+  clamped = false;
+  projected = transform.ProjectPoint(p, &clamped);
+  EXPECT_TRUE(clamped);
+  EXPECT_EQ(projected.x(), kProjectionClampedBigNumber);
+  EXPECT_EQ(projected.y(), -kProjectionClampedBigNumber);
+  EXPECT_EQ(PointF(0.625f, -3.5f), transform.MapPoint(p));
+  // In this case, MapPoint() returns a point behind the eye.
+  EXPECT_POINTF_NEAR(PointF(-8.36014f, 11.7042f),
+                     projection_transform(transform).MapPoint(p), 1e-5f);
+  EXPECT_POINTF_NEAR(projected, projection_transform(transform).ProjectPoint(p),
+                     1e-5f);
+}
+
+TEST(XFormTest, ProjectQuad) {
+  auto transform = Transform::MakeTranslation(3.25f, 7.75f);
+  QuadF q(PointF(1.25f, 2.5f), PointF(3.75f, 4.f), PointF(23.f, 45.f),
+          PointF(12.f, 67.f));
+  EXPECT_EQ(QuadF(PointF(4.5f, 10.25f), PointF(7.f, 11.75f),
+                  PointF(26.25f, 52.75f), PointF(15.25f, 74.75f)),
+            transform.ProjectQuad(q));
+
+  transform.set_rc(2, 2, 0);
+  EXPECT_EQ(QuadF(), transform.ProjectQuad(q));
+
+  transform.MakeIdentity();
+  transform.RotateAboutYAxis(60);
+  EXPECT_EQ(QuadF(PointF(2.5f, 2.5f), PointF(7.5f, 4.f), PointF(46.f, 45.f),
+                  PointF(24.f, 67.f)),
+            transform.ProjectQuad(q));
+
+  // With a small perspective, all points of |q| are clamped, and the
+  // projected result is an empty quad.
+  transform.ApplyPerspectiveDepth(2);
+  EXPECT_EQ(QuadF(), transform.ProjectQuad(q));
+
+  // Change the quad so that 2 points are clamped.
+  q.set_p1(PointF(-1.25f, -2.5f));
+  q.set_p2(PointF(-3.75f, 4.f));
+  q.set_p3(PointF(23.f, -45.f));
+  QuadF q1 = transform.ProjectQuad(q);
+  EXPECT_POINTF_NEAR(PointF(-1.2f, -1.2f), q1.p1(), 0.01f);
+  EXPECT_POINTF_NEAR(PointF(-1.77f, 0.94f), q1.p2(), 0.01f);
+  EXPECT_EQ(q1.p3().x(), kProjectionClampedBigNumber);
+  EXPECT_EQ(q1.p3().y(), -kProjectionClampedBigNumber);
+  EXPECT_EQ(q1.p4().x(), kProjectionClampedBigNumber);
+  EXPECT_EQ(q1.p4().y(), kProjectionClampedBigNumber);
+}
+
 TEST(XFormTest, ToString) {
   auto zeros =
       Transform::ColMajor(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
diff --git a/ui/gl/gl_display.cc b/ui/gl/gl_display.cc
index 8faf33a..e6fdcbd5 100644
--- a/ui/gl/gl_display.cc
+++ b/ui/gl/gl_display.cc
@@ -520,6 +520,17 @@
                         bool supports_angle_metal,
                         const base::CommandLine* command_line,
                         std::vector<DisplayType>* init_displays) {
+  // Check which experiment groups we're in. Check these early in the function
+  // so that finch assigns a group before the final decision to use the API is
+  // made. If we check too late, it will appear that some users are missing from
+  // the group if they are falling back to another path due to crashes or
+  // missing support.
+  bool default_angle_opengl =
+      base::FeatureList::IsEnabled(features::kDefaultANGLEOpenGL);
+  bool default_angle_metal =
+      base::FeatureList::IsEnabled(features::kDefaultANGLEMetal);
+  bool default_angle_vulkan = features::IsDefaultANGLEVulkan();
+
   // If we're already requesting software GL, make sure we don't fallback to the
   // GPU
   bool forceSoftwareGL = IsSoftwareGLImplementation(GetGLImplementationParts());
@@ -543,19 +554,16 @@
   // experiment is enabled, try creating OpenGL displays first.
   // TODO(oetuaho@nvidia.com): Only enable this path on specific GPUs with a
   // blocklist entry. http://crbug.com/693090
-  if (supports_angle_opengl && use_angle_default &&
-      base::FeatureList::IsEnabled(features::kDefaultANGLEOpenGL)) {
+  if (supports_angle_opengl && use_angle_default && default_angle_opengl) {
     AddInitDisplay(init_displays, ANGLE_OPENGL);
     AddInitDisplay(init_displays, ANGLE_OPENGLES);
   }
 
-  if (supports_angle_metal && use_angle_default &&
-      base::FeatureList::IsEnabled(features::kDefaultANGLEMetal)) {
+  if (supports_angle_metal && use_angle_default && default_angle_metal) {
     AddInitDisplay(init_displays, ANGLE_METAL);
   }
 
-  if (supports_angle_vulkan && use_angle_default &&
-      features::IsDefaultANGLEVulkan()) {
+  if (supports_angle_vulkan && use_angle_default && default_angle_vulkan) {
     AddInitDisplay(init_displays, ANGLE_VULKAN);
   }
 
diff --git a/ui/ozone/platform/flatland/flatland_surface.cc b/ui/ozone/platform/flatland/flatland_surface.cc
index 9dae411..0fc8076 100644
--- a/ui/ozone/platform/flatland/flatland_surface.cc
+++ b/ui/ozone/platform/flatland/flatland_surface.cc
@@ -72,6 +72,20 @@
                               static_cast<uint32_t>(size.height())};
 }
 
+fuchsia::ui::composition::ContentId CreateImage(
+    FlatlandConnection* flatland,
+    fuchsia::ui::composition::BufferCollectionImportToken import_token,
+    const gfx::Size& size,
+    uint32_t vmo_index) {
+  fuchsia::ui::composition::ImageProperties image_properties;
+  image_properties.set_size(GfxSizeToFuchsiaSize(size));
+  const fuchsia::ui::composition::ContentId image_id =
+      flatland->NextContentId();
+  flatland->flatland()->CreateImage(image_id, std::move(import_token),
+                                    vmo_index, std::move(image_properties));
+  return image_id;
+}
+
 }  // namespace
 
 FlatlandSurface::FlatlandSurface(
@@ -303,19 +317,28 @@
 
   const auto ids_itr = pixmap_ids_to_flatland_ids_.find(ids);
   if (ids_itr != pixmap_ids_to_flatland_ids_.end()) {
+    // There is a size change in pixmap, we should recreate the image with the
+    // updated size.
+    if (ids_itr->second.image_size != pixmap->GetBufferSize()) {
+      flatland_.flatland()->ReleaseImage(ids_itr->second.image_id);
+      ids_itr->second.image_id =
+          CreateImage(&flatland_, collection->GetFlatlandImportToken(),
+                      pixmap->GetBufferSize(), ids.buffer_index);
+      ids_itr->second.image_size = pixmap->GetBufferSize();
+      if (!is_primary_plane) {
+        flatland_.flatland()->SetContent(ids_itr->second.transform_id,
+                                         ids_itr->second.image_id);
+      }
+    }
     return ids_itr->second;
   }
 
-  // Create Flatland Image.
-  fuchsia::ui::composition::ImageProperties image_properties;
-  image_properties.set_size(GfxSizeToFuchsiaSize(pixmap->GetBufferSize()));
   const fuchsia::ui::composition::ContentId image_id =
-      flatland_.NextContentId();
-  flatland_.flatland()->CreateImage(
-      image_id, collection->GetFlatlandImportToken(), ids.buffer_index,
-      std::move(image_properties));
+      CreateImage(&flatland_, collection->GetFlatlandImportToken(),
+                  pixmap->GetBufferSize(), ids.buffer_index);
 
-  // Create flatland transform for overlays.
+  // Skip creating a transform for the primary plane because
+  // |primary_plane_transform_id_| is used.
   fuchsia::ui::composition::TransformId transform_id = {0};
   if (!is_primary_plane) {
     transform_id = flatland_.NextTransformId();
@@ -323,9 +346,10 @@
     flatland_.flatland()->SetContent(transform_id, image_id);
   }
 
-  // Add Flatland ids to |buffer_collection_to_image_id_|.
-  FlatlandSurface::FlatlandIds flatland_ids = {.image_id = image_id,
-                                               .transform_id = transform_id};
+  FlatlandSurface::FlatlandIds flatland_ids = {
+      .image_id = image_id,
+      .transform_id = transform_id,
+      .image_size = (pixmap->GetBufferSize())};
   pixmap_ids_to_flatland_ids_[ids] = flatland_ids;
   collection->AddOnReleasedCallback(
       base::BindOnce(&FlatlandSurface::RemovePixmapResources,
diff --git a/ui/ozone/platform/flatland/flatland_surface.h b/ui/ozone/platform/flatland/flatland_surface.h
index 686a2b13..31aa2a9 100644
--- a/ui/ozone/platform/flatland/flatland_surface.h
+++ b/ui/ozone/platform/flatland/flatland_surface.h
@@ -101,6 +101,7 @@
   struct FlatlandIds {
     fuchsia::ui::composition::ContentId image_id;
     fuchsia::ui::composition::TransformId transform_id;
+    gfx::Size image_size;
   };
 
   void OnGetLayout(fuchsia::ui::composition::LayoutInfo info);
diff --git a/ui/views/examples/table_example.cc b/ui/views/examples/table_example.cc
index c1aced2..c6225120 100644
--- a/ui/views/examples/table_example.cc
+++ b/ui/views/examples/table_example.cc
@@ -65,21 +65,20 @@
                                      MaximumFlexSizeRule::kUnbounded)
                        .WithWeight(1);
 
-  const auto make_checkbox = [](const std::u16string& label, int id,
-                                raw_ptr<TableView>* table,
-                                raw_ptr<Checkbox>* checkbox,
-                                FlexSpecification full_flex) {
-    return Builder<Checkbox>()
-        .CopyAddressTo(checkbox)
-        .SetText(label)
-        .SetCallback(base::BindRepeating(
-            [](int id, raw_ptr<TableView>* table, raw_ptr<Checkbox>* checkbox) {
-              (*table)->SetColumnVisibility(id, (*checkbox)->GetChecked());
-            },
-            id, table, checkbox))
-        .SetChecked(true)
-        .SetProperty(kFlexBehaviorKey, full_flex);
-  };
+  const auto make_checkbox =
+      [](const std::u16string& label, int id, raw_ptr<TableView>* table,
+         raw_ptr<Checkbox>* checkbox, FlexSpecification full_flex) {
+        return Builder<Checkbox>()
+            .CopyAddressTo(checkbox)
+            .SetText(label)
+            .SetCallback(base::BindRepeating(
+                [](int id, TableView* table, Checkbox* checkbox) {
+                  table->SetColumnVisibility(id, checkbox->GetChecked());
+                },
+                id, *table, *checkbox))
+            .SetChecked(true)
+            .SetProperty(kFlexBehaviorKey, full_flex);
+      };
 
   // Make table
   Builder<View>(container)
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
index a3c39629..8981b39 100644
--- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
+++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
@@ -417,6 +417,11 @@
   event_client_.reset();
 }
 
+base::WeakPtr<internal::NativeWidgetPrivate>
+DesktopNativeWidgetAura::GetWeakPtr() {
+  return weak_ptr_factory_.GetWeakPtr();
+}
+
 void DesktopNativeWidgetAura::NotifyAccessibilityEvent(
     ax::mojom::Event event_type) {
   if (!GetWidget() || !GetWidget()->GetRootView())
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.h b/ui/views/widget/desktop_aura/desktop_native_widget_aura.h
index edc92062..be2544c8 100644
--- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.h
+++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.h
@@ -117,6 +117,8 @@
     native_widget_delegate_ = delegate;
   }
 
+  base::WeakPtr<internal::NativeWidgetPrivate> GetWeakPtr() override;
+
  protected:
   // internal::NativeWidgetPrivate:
   void InitNativeWidget(Widget::InitParams params) override;
@@ -353,7 +355,9 @@
   // See DesktopWindowTreeHost::ShouldUseDesktopNativeCursorManager().
   bool use_desktop_native_cursor_manager_ = false;
 
-  // The following factory is used for calls to close to run drop callback.
+  // The following factory is used to provide references to the
+  // DesktopNativeWidgetAura instance and used for calls to close to run drop
+  // callback.
   base::WeakPtrFactory<DesktopNativeWidgetAura> weak_ptr_factory_{this};
 };
 
diff --git a/ui/views/widget/native_widget_aura.cc b/ui/views/widget/native_widget_aura.cc
index 9ee7b6c7..632e022 100644
--- a/ui/views/widget/native_widget_aura.cc
+++ b/ui/views/widget/native_widget_aura.cc
@@ -947,6 +947,10 @@
   return window_ ? window_->GetName() : std::string();
 }
 
+base::WeakPtr<internal::NativeWidgetPrivate> NativeWidgetAura::GetWeakPtr() {
+  return weak_factory.GetWeakPtr();
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // NativeWidgetAura, aura::WindowDelegate implementation:
 
diff --git a/ui/views/widget/native_widget_aura.h b/ui/views/widget/native_widget_aura.h
index ad08964b..a4639d5 100644
--- a/ui/views/widget/native_widget_aura.h
+++ b/ui/views/widget/native_widget_aura.h
@@ -169,6 +169,7 @@
   void OnNativeViewHierarchyWillChange() override;
   void OnNativeViewHierarchyChanged() override;
   std::string GetName() const override;
+  base::WeakPtr<internal::NativeWidgetPrivate> GetWeakPtr() override;
 
   // aura::WindowDelegate:
   gfx::Size GetMinimumSize() const override;
@@ -272,6 +273,19 @@
   // The following factory is used for calls to close the NativeWidgetAura
   // instance.
   base::WeakPtrFactory<NativeWidgetAura> close_widget_factory_{this};
+
+  // The following factory is used to provide references to the NativeWidgetAura
+  // instance. We need a separate factory from the |close_widget_factory_|
+  // because the close widget factory is currently used to ensure that the
+  // CloseNow task is only posted once. We check whether there are any weak
+  // pointers from close_widget_factory_| before posting
+  // the CloseNow task, so we can't have any other weak pointers for this to
+  // work properly. CloseNow can destroy the aura::Window
+  // which will not destroy the NativeWidget if WIDGET_OWNS_NATIVE_WIDGET, and
+  // we need to make sure we do not attempt to destroy the aura::Window twice.
+  // TODO(1346381): The two factories can be combined if the
+  // WIDGET_OWNS_NATIVE_WIDGET is removed.
+  base::WeakPtrFactory<NativeWidgetAura> weak_factory{this};
 };
 
 }  // namespace views
diff --git a/ui/views/widget/native_widget_mac.h b/ui/views/widget/native_widget_mac.h
index 09c336a..d7aa7db6 100644
--- a/ui/views/widget/native_widget_mac.h
+++ b/ui/views/widget/native_widget_mac.h
@@ -206,6 +206,7 @@
   void OnNativeViewHierarchyWillChange() override;
   void OnNativeViewHierarchyChanged() override;
   std::string GetName() const override;
+  base::WeakPtr<internal::NativeWidgetPrivate> GetWeakPtr() override;
 
   // Calls |callback| with the newly created NativeWidget whenever a
   // NativeWidget is created.
@@ -291,6 +292,9 @@
   std::unique_ptr<ZoomFocusMonitor> zoom_focus_monitor_;
   // Held while this widget is active if it's a child.
   std::unique_ptr<Widget::PaintAsActiveLock> parent_key_lock_;
+  // The following factory is used to provide references to the NativeWidgetMac
+  // instance.
+  base::WeakPtrFactory<NativeWidgetMac> weak_factory{this};
 };
 
 }  // namespace views
diff --git a/ui/views/widget/native_widget_mac.mm b/ui/views/widget/native_widget_mac.mm
index 2f406ced..9a0490a3 100644
--- a/ui/views/widget/native_widget_mac.mm
+++ b/ui/views/widget/native_widget_mac.mm
@@ -894,6 +894,10 @@
   return name_;
 }
 
+base::WeakPtr<internal::NativeWidgetPrivate> NativeWidgetMac::GetWeakPtr() {
+  return weak_factory.GetWeakPtr();
+}
+
 // static
 void NativeWidgetMac::SetInitNativeWidgetCallback(
     base::RepeatingCallback<void(NativeWidgetMac*)> callback) {
diff --git a/ui/views/widget/native_widget_private.h b/ui/views/widget/native_widget_private.h
index 321d466..c3a5bd06 100644
--- a/ui/views/widget/native_widget_private.h
+++ b/ui/views/widget/native_widget_private.h
@@ -241,6 +241,8 @@
   // Returns an internal name that matches the name of the associated Widget.
   virtual std::string GetName() const = 0;
 
+  virtual base::WeakPtr<NativeWidgetPrivate> GetWeakPtr() = 0;
+
   // Overridden from NativeWidget:
   internal::NativeWidgetPrivate* AsNativeWidgetPrivate() override;
 };
diff --git a/ui/views/widget/widget.cc b/ui/views/widget/widget.cc
index e37d2d3..2ff624b 100644
--- a/ui/views/widget/widget.cc
+++ b/ui/views/widget/widget.cc
@@ -191,7 +191,7 @@
   if (widget_delegate_)
     widget_delegate_->WidgetDestroying();
   if (ownership_ == InitParams::WIDGET_OWNS_NATIVE_WIDGET) {
-    delete native_widget_;
+    owned_native_widget_.reset();
     DCHECK(native_widget_destroyed_);
   } else if (ownership_ == InitParams::NATIVE_WIDGET_OWNS_WIDGET) {
     // TODO(crbug.com/937381): Revert to DCHECK once we figure out the reason.
@@ -422,7 +422,12 @@
         std::make_unique<SublevelManager>(this, params.sublevel);
   }
 
-  native_widget_ = CreateNativeWidget(params, this)->AsNativeWidgetPrivate();
+  internal::NativeWidgetPrivate* native_widget_raw_ptr =
+      CreateNativeWidget(params, this)->AsNativeWidgetPrivate();
+  native_widget_ = native_widget_raw_ptr->GetWeakPtr();
+  if (params.ownership == InitParams::WIDGET_OWNS_NATIVE_WIDGET) {
+    owned_native_widget_ = base::WrapUnique(native_widget_raw_ptr);
+  }
   root_view_.reset(CreateRootView());
 
   // Copy the elements of params that will be used after it is moved.
@@ -1197,11 +1202,11 @@
 }
 
 const NativeWidget* Widget::native_widget() const {
-  return native_widget_;
+  return native_widget_.get();
 }
 
 NativeWidget* Widget::native_widget() {
-  return native_widget_;
+  return native_widget_.get();
 }
 
 void Widget::SetCapture(View* view) {
diff --git a/ui/views/widget/widget.h b/ui/views/widget/widget.h
index 67bbeedf..c7495ec 100644
--- a/ui/views/widget/widget.h
+++ b/ui/views/widget/widget.h
@@ -969,16 +969,11 @@
   NativeWidget* native_widget();
 
   internal::NativeWidgetPrivate* native_widget_private() {
-    return native_widget_;
-  }
-  const internal::NativeWidgetPrivate* native_widget_private() const {
-    return native_widget_;
+    return native_widget_.get();
   }
 
-  // Sets the NativeWidget. The original NativeWidget may need to be cleaned up
-  // by the caller of this method.
-  void SetNativeWidgetForTesting(internal::NativeWidgetPrivate* native_widget) {
-    native_widget_ = native_widget;
+  const internal::NativeWidgetPrivate* native_widget_private() const {
+    return native_widget_.get();
   }
 
   // Sets capture to the specified view. This makes it so that all mouse, touch
@@ -1242,8 +1237,13 @@
   static DisableActivationChangeHandlingType
       g_disable_activation_change_handling_;
 
-  raw_ptr<internal::NativeWidgetPrivate, DanglingUntriaged> native_widget_ =
-      nullptr;
+  base::WeakPtr<internal::NativeWidgetPrivate> native_widget_ = nullptr;
+
+  // This unique pointer is only set when WIDGET_OWNS_NATIVE_WIDGET so that we
+  // can destroy the NativeWidget. Except for managing lifetime for
+  // WIDGET_OWNS_NATIVE_WIDGET, the NativeWidget should always be referenced
+  // through the |native_widget_| weak ptr.
+  std::unique_ptr<internal::NativeWidgetPrivate> owned_native_widget_;
 
   base::ObserverList<WidgetObserver> observers_;
 
diff --git a/ui/views/widget/widget_unittest.cc b/ui/views/widget/widget_unittest.cc
index bf32302..ed305e3 100644
--- a/ui/views/widget/widget_unittest.cc
+++ b/ui/views/widget/widget_unittest.cc
@@ -1037,23 +1037,14 @@
     ViewsTestBase::SetUp();
     widget_ = CreateTestWidget();
     widget_->Show();
-    native_widget_ = widget_->native_widget_private();
-    widget_->SetNativeWidgetForTesting(nullptr);
-  }
-
-  void TearDown() override {
-    ViewsTestBase::TearDown();
-    // Add the NativeWidget back to be destroyed. We should be able to directly
-    // tell the NativeWidget to be destroyed if we decouple the lifetime of
-    // Widget and NativeWidget.
-    widget_->SetNativeWidgetForTesting(native_widget_);
+    widget_->Close();
+    RunPendingMessages();
   }
 
   Widget* widget() { return widget_.get(); }
 
  private:
   std::unique_ptr<Widget> widget_;
-  internal::NativeWidgetPrivate* native_widget_;
 };
 
 TEST_F(WidgetWithDestroyedNativeWidgetTest, Activate) {
diff --git a/ui/webui/resources/cr_components/history_clusters/cluster.html b/ui/webui/resources/cr_components/history_clusters/cluster.html
index a999f8d..cdd057a 100644
--- a/ui/webui/resources/cr_components/history_clusters/cluster.html
+++ b/ui/webui/resources/cr_components/history_clusters/cluster.html
@@ -55,13 +55,13 @@
     padding-inline-start: 16px;
   }
 
-  .label {
+  #label {
     color: var(--cr-primary-text-color);
     font-size: 1rem;  /* 16px */
     font-weight: 500;
   }
 
-  :host([in-side-panel_]) .label {
+  :host([in-side-panel_]) #label {
     font-size: .875rem;  /* 14px */
     line-height: calc(10/7); /* 20px */
   }
@@ -140,7 +140,8 @@
        left, while outside the side panel the timestamp and the menu should
        be side by side on the right. -->
   <div class="label-row">
-    <div id="label" class="label"></div>
+    <span id="label" class="label"></span>
+    <img is="cr-auto-img" auto-src="[[imageUrl_]]">
     <div class="debug-info">[[cluster.debugInfo]]</div>
     <div class="timestamp-and-menu">
       <div class="timestamp">[[cluster.visits.0.relativeDate]]</div>
diff --git a/ui/webui/resources/cr_components/history_clusters/cluster.ts b/ui/webui/resources/cr_components/history_clusters/cluster.ts
index 0693c6c0..bd7c5183 100644
--- a/ui/webui/resources/cr_components/history_clusters/cluster.ts
+++ b/ui/webui/resources/cr_components/history_clusters/cluster.ts
@@ -9,6 +9,7 @@
 import './url_visit.js';
 import '../../cr_elements/cr_icons.css.js';
 import 'chrome://resources/polymer/v3_0/iron-collapse/iron-collapse.js';
+import 'chrome://resources/cr_elements/cr_auto_img/cr_auto_img.js';
 
 import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js';
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
@@ -121,6 +122,15 @@
         type: Object,
         computed: `computeVisibleVisits_(cluster.visits.*)`,
       },
+
+      /**
+       * The cluster's image URL in a form easily passed to cr-auto-img.
+       * Also notifies the outer iron-list of a resize.
+       */
+      imageUrl_: {
+        type: String,
+        computed: `computeImageUrl_(cluster.imageUrl)`,
+      },
     };
   }
 
@@ -336,6 +346,24 @@
     });
   }
 
+  private computeImageUrl_(): string {
+    if (!this.cluster.imageUrl) {
+      return '';
+    }
+
+    // iron-list can't handle our size changing because of loading an image
+    // without an explicit event. But we also can't send this until we have
+    // updated the image property, so send it on the next idle.
+    window.requestIdleCallback(() => {
+      this.dispatchEvent(new CustomEvent('iron-resize', {
+        bubbles: true,
+        composed: true,
+      }));
+    });
+
+    return this.cluster.imageUrl.url;
+  }
+
   /**
    * Returns the label of the toggle button based on whether the default-hidden
    * visits are visible.
diff --git a/ui/webui/resources/cr_components/history_clusters/clusters.ts b/ui/webui/resources/cr_components/history_clusters/clusters.ts
index 0690eee..3340e06 100644
--- a/ui/webui/resources/cr_components/history_clusters/clusters.ts
+++ b/ui/webui/resources/cr_components/history_clusters/clusters.ts
@@ -13,6 +13,7 @@
 
 import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js';
 import {Time} from 'chrome://resources/mojo/mojo/public/mojom/base/time.mojom-webui.js';
+import {Url} from 'chrome://resources/mojo/url/mojom/url.mojom-webui.js';
 import {IronListElement} from 'chrome://resources/polymer/v3_0/iron-list/iron-list.js';
 import {IronScrollThresholdElement} from 'chrome://resources/polymer/v3_0/iron-scroll-threshold/iron-scroll-threshold.js';
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
@@ -127,6 +128,7 @@
   private headerText_: string;
   private inSidePanel_: boolean;
   private onClustersQueryResultListenerId_: number|null = null;
+  private onClusterImageUpdatedListenerId_: number|null = null;
   private onVisitsRemovedListenerId_: number|null = null;
   private onHistoryDeletedListenerId_: number|null = null;
   private onQueryChangedByUserListenerId_: number|null = null;
@@ -160,6 +162,9 @@
     this.onClustersQueryResultListenerId_ =
         this.callbackRouter_.onClustersQueryResult.addListener(
             this.onClustersQueryResult_.bind(this));
+    this.onClusterImageUpdatedListenerId_ =
+        this.callbackRouter_.onClusterImageUpdated.addListener(
+            this.onClusterImageUpdated_.bind(this));
     this.onVisitsRemovedListenerId_ =
         this.callbackRouter_.onVisitsRemoved.addListener(
             this.onVisitsRemoved_.bind(this));
@@ -351,6 +356,14 @@
   }
 
   /**
+   * Called when an image has become available for `clusterIndex`.
+   */
+  private onClusterImageUpdated_(clusterIndex: number, imageUrl: Url) {
+    // TODO(tommycli): Make deletions handle `clusterIndex` properly.
+    this.set(`result_.clusters.${clusterIndex}.imageUrl`, imageUrl);
+  }
+
+  /**
    * Called when the user entered search query changes. Also used to fetch the
    * initial set of clusters when the page loads.
    */
diff --git a/ui/webui/resources/cr_components/history_clusters/history_clusters.mojom b/ui/webui/resources/cr_components/history_clusters/history_clusters.mojom
index f1e4eb3..629b0df 100644
--- a/ui/webui/resources/cr_components/history_clusters/history_clusters.mojom
+++ b/ui/webui/resources/cr_components/history_clusters/history_clusters.mojom
@@ -141,6 +141,9 @@
   // Search queries related to this cluster's visits.
   array<SearchQuery> related_searches;
 
+  // The image URL associated with this cluster.
+  url.mojom.Url? image_url;
+
   // Additional debug string to show. This is not visible in production, and
   // used for development only. Disabled by default, but can be enabled by the
   // 'JourneysUserVisibleDebug' flag.
@@ -225,6 +228,9 @@
   // older Clusters.
   OnClustersQueryResult(QueryResult result);
 
+  // Called when the browser has found a suitable image for `cluster_index`.
+  OnClusterImageUpdated(int32 cluster_index, url.mojom.Url image_url);
+
   // Called with the set of removed visits when the last accepted call to
   // `RemoveVisits()` succeeds. `removed_visits` will be used to update the UI.
   OnVisitsRemoved(array<URLVisit> removed_visits);