diff --git a/.gn b/.gn
index ac2a30b5..22070a9a 100644
--- a/.gn
+++ b/.gn
@@ -78,8 +78,6 @@
   "//headless:headless_shared_sources",  # 4 errors
   "//headless:headless_shell_browser_lib",  # 10 errors
   "//headless:headless_shell_lib",  # 10 errors
-  "//headless:headless_unittests",  # 6 errors
-  "//headless:headless_unittests__exec",
 
   "//third_party/libwebp:*",  # 7 errors, https://crbug.com/800762
 
diff --git a/AUTHORS b/AUTHORS
index c038d097..b5483b6a 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1270,6 +1270,7 @@
 Yuta Kasai <kasai.yuta0810@gmail.com>
 Yuvanesh Natarajan <yuvanesh.n1@samsung.com>
 Zach Bjornson <zbbjornson@gmail.com>
+Zachary Capalbo <zach.geek@gmail.com>
 Zeno Albisser <zeno.albisser@digia.com>
 Zeqin Chen <talonchen@tencent.com>
 Zhang Hao <15686357310a@gmail.com>
diff --git a/DEPS b/DEPS
index 99ce721..0f0a3da 100644
--- a/DEPS
+++ b/DEPS
@@ -245,7 +245,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': '466df1e697fde6471ec7c6e3d233410089b6fe8b',
+  'skia_revision': '458653d9fce73db0f48d628353e50e828ad6c389',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
@@ -257,7 +257,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
-  'swiftshader_revision': '9b1a72a8d2266960a0f036a39c644314c52877d3',
+  'swiftshader_revision': '2e74d5dc03dfbfab0821f9aac5d2b3ad317eab28',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
@@ -292,7 +292,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling freetype
   # and whatever else without interference from each other.
-  'freetype_revision': 'd118bf8e35e69454ed046b57ac54dd67d49b87d9',
+  'freetype_revision': '773e31c78397a5471efb7c37d7cd1eca40b46351',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling freetype
   # and whatever else without interference from each other.
@@ -320,7 +320,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling devtools-frontend
   # and whatever else without interference from each other.
-  'devtools_frontend_revision': '0177fa779100b8680f43719785dc1ef7c3958ac7',
+  'devtools_frontend_revision': '68613ab02f6d556a2c5ac68ea08f466a534c6bd9',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libprotobuf-mutator
   # and whatever else without interference from each other.
@@ -360,7 +360,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'dawn_revision': '605354395ec6430dd7fd067c41f047aaee6dcc69',
+  'dawn_revision': 'd0530a6e035d6bbba42313b9e075672c08a89c32',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -384,7 +384,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libavif
   # and whatever else without interference from each other.
-  'libavif_revision': '6198acd0a1fd658a6abd835dd4e2cd3d4521405e',
+  'libavif_revision': '411221a16d2cee76e14dad10963c1ffafe2cfa6b',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling nearby
   # and whatever else without interference from each other.
@@ -641,7 +641,7 @@
   },
 
   'src/ios/third_party/material_components_ios/src': {
-      'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '10e82d096e2c7558b525c76c42d63a708bca03ba',
+      'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + 'ec85dac78dbf6cba59971f6d6db6b6e606a43fdb',
       'condition': 'checkout_ios',
   },
 
@@ -1044,7 +1044,7 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'fd7427ccf691cd784330a825ce2433e58da7f318',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'cb340f5b7bbdcaba0fad346b08db91538619a531',
 
   'src/third_party/devtools-frontend/src':
     Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'),
@@ -1053,7 +1053,7 @@
     Var('chromium_git') + '/chromium/dom-distiller/dist.git' + '@' + 'f339eb9463714c3d31657c8ee1bd53d1c7e5c555',
 
   'src/third_party/eigen3/src':
-    Var('chromium_git') + '/external/gitlab.com/libeigen/eigen.git' + '@' + '163f11e24a1011ac8ba1cecfaf53e9b11ace5f5c',
+    Var('chromium_git') + '/external/gitlab.com/libeigen/eigen.git' + '@' + 'e939c06b0e54fd7c4bfa173d01b47d2554bf7a85',
 
   'src/third_party/emoji-metadata/src': {
     'url': Var('chromium_git') + '/external/github.com/googlefonts/emoji-metadata' + '@' + '84fcb4151d2d110abfb4451369469048f28b73ff',
@@ -1427,7 +1427,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + '80ed61adcb0af00e74c890e359eef2d3536289fb',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + '56f2ccce0511ebd51e2f7d2fa659719a712a6044',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
@@ -1588,7 +1588,7 @@
   },
 
   'src/third_party/tflite/src':
-    Var('chromium_git') + '/external/github.com/tensorflow/tensorflow.git' + '@' + 'ceedf1794a703715d88605b5ac493517e8fa2499',
+    Var('chromium_git') + '/external/github.com/tensorflow/tensorflow.git' + '@' + '7d380ffcce7a13884ca76d703ca0d983c870582c',
 
   'src/third_party/turbine': {
       'packages': [
@@ -1645,10 +1645,10 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'b1f3776e4913637221733a4da09f3339e783b771',
 
   'src/third_party/webgpu-cts/src':
-    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '72561785742eab5afee480368659cde144bca33c',
+    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'fc207904abbb29864991c71c7156336455a3d892',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '094e042edb47fdd82baba85e4b8ff8a0c6b6619e',
+    Var('webrtc_git') + '/src.git' + '@' + 'ac506bddcfa3af906128281db6a0127f26e3ed59',
 
   'src/third_party/libgifcodec':
      Var('skia_git') + '/libgifcodec' + '@'+  Var('libgifcodec_revision'),
@@ -1718,7 +1718,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@2d0c33981edd03fadf8adcf3bd69578501853d46',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@69463595064cb645ef53552c575462495998f389',
     'condition': 'checkout_src_internal',
   },
 
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index 6bb157f..e35f5db 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -4250,6 +4250,113 @@
 
   return [output_api.PresubmitNotifyResult(message)]
 
+
+_ACCESSIBILITY_EVENTS_TEST_PATH = (
+    r"^content[\\/]test[\\/]data[\\/]accessibility[\\/]event[\\/].*\.html",
+)
+
+_ACCESSIBILITY_TREE_TEST_PATH = (
+    r"^content[\\/]test[\\/]data[\\/]accessibility[\\/]accname[\\/].*\.html",
+    r"^content[\\/]test[\\/]data[\\/]accessibility[\\/]aria[\\/].*\.html",
+    r"^content[\\/]test[\\/]data[\\/]accessibility[\\/]css[\\/].*\.html",
+    r"^content[\\/]test[\\/]data[\\/]accessibility[\\/]html[\\/].*\.html",
+)
+
+_ACCESSIBILITY_ANDROID_EVENTS_TEST_PATH = (
+    r"^.*[\\/]WebContentsAccessibilityEventsTest\.java",
+)
+
+_ACCESSIBILITY_ANDROID_TREE_TEST_PATH = (
+    r"^.*[\\/]WebContentsAccessibilityEventsTest\.java",
+)
+
+def CheckAccessibilityEventsTestsAreIncludedForAndroid(input_api, output_api):
+  """Checks that commits that include a newly added, renamed/moved, or deleted
+  test in the DumpAccessibilityEventsTest suite also includes a corresponding
+  change to the Android test."""
+  def FilePathFilter(affected_file):
+    paths = _ACCESSIBILITY_EVENTS_TEST_PATH
+    return input_api.FilterSourceFile(affected_file, files_to_check=paths)
+
+  def AndroidFilePathFilter(affected_file):
+    paths = _ACCESSIBILITY_ANDROID_EVENTS_TEST_PATH
+    return input_api.FilterSourceFile(affected_file, files_to_check=paths)
+
+  # Only consider changes in the events test data path with html type.
+  if not any(input_api.AffectedFiles(include_deletes=True,
+                                     file_filter=FilePathFilter)):
+    return []
+
+  # If the commit contains any change to the Android test file, ignore.
+  if any(input_api.AffectedFiles(include_deletes=True,
+                                 file_filter=AndroidFilePathFilter)):
+    return []
+
+  # Only consider changes that are adding/renaming or deleting a file
+  message = []
+  for f in input_api.AffectedFiles(include_deletes=True,
+                                   file_filter=FilePathFilter):
+    if f.Action()=='A' or f.Action()=='D':
+      message = ("It appears that you are adding, renaming or deleting"
+                 "\na dump_accessibility_events* test, but have not included"
+                 "\na corresponding change for Android."
+                 "\nPlease include (or remove) the test from:"
+                 "\n    content/public/android/javatests/src/org/chromium/"
+                 "content/browser/accessibility/"
+                 "WebContentsAccessibilityEventsTest.java"
+                 "\nIf this message is confusing or annoying, please contact"
+                 "\nmembers of ui/accessibility/OWNERS.")
+
+  # If no message was set, return empty.
+  if not len(message):
+    return []
+
+  return [output_api.PresubmitPromptWarning(message)]
+
+def CheckAccessibilityTreeTestsAreIncludedForAndroid(input_api, output_api):
+  """Checks that commits that include a newly added, renamed/moved, or deleted
+  test in the DumpAccessibilityTreeTest suite also includes a corresponding
+  change to the Android test."""
+  def FilePathFilter(affected_file):
+    paths = _ACCESSIBILITY_TREE_TEST_PATH
+    return input_api.FilterSourceFile(affected_file, files_to_check=paths)
+
+  def AndroidFilePathFilter(affected_file):
+    paths = _ACCESSIBILITY_ANDROID_TREE_TEST_PATH
+    return input_api.FilterSourceFile(affected_file, files_to_check=paths)
+
+  # Only consider changes in the various tree test data paths with html type.
+  if not any(input_api.AffectedFiles(include_deletes=True,
+                                     file_filter=FilePathFilter)):
+    return []
+
+  # If the commit contains any change to the Android test file, ignore.
+  if any(input_api.AffectedFiles(include_deletes=True,
+                                 file_filter=AndroidFilePathFilter)):
+    return []
+
+  # Only consider changes that are adding/renaming or deleting a file
+  message = []
+  for f in input_api.AffectedFiles(include_deletes=True,
+                                   file_filter=FilePathFilter):
+    if f.Action()=='A' or f.Action()=='D':
+      message = ("It appears that you are adding, renaming or deleting"
+                 "\na dump_accessibility_tree* test, but have not included"
+                 "\na corresponding change for Android."
+                 "\nPlease include (or remove) the test from:"
+                 "\n    content/public/android/javatests/src/org/chromium/"
+                 "content/browser/accessibility/"
+                 "WebContentsAccessibilityTreeTest.java"
+                 "\nIf this message is confusing or annoying, please contact"
+                 "\nmembers of ui/accessibility/OWNERS.")
+
+  # If no message was set, return empty.
+  if not len(message):
+    return []
+
+  return [output_api.PresubmitPromptWarning(message)]
+
+
 # string pattern, sequence of strings to show when pattern matches,
 # error flag. True if match is a presubmit error, otherwise it's a warning.
 _NON_INCLUSIVE_TERMS = (
diff --git a/PRESUBMIT_test.py b/PRESUBMIT_test.py
index ce3aacd6..3f54eb9 100755
--- a/PRESUBMIT_test.py
+++ b/PRESUBMIT_test.py
@@ -1028,6 +1028,234 @@
                      'Expected %d messages, found %d: %s'
                      % (0, len(msgs), msgs))
 
+class AccessibilityEventsTestsAreIncludedForAndroidTest(unittest.TestCase):
+  # Test that no warning is raised when the Android file is also modified.
+  def testAndroidChangeIncluded(self):
+    mock_input_api = MockInputApi()
+
+    mock_input_api.files = [
+        MockAffectedFile('content/test/data/accessibility/event/foo.html',
+          [''], action='A'),
+        MockAffectedFile(
+          'accessibility/WebContentsAccessibilityEventsTest.java',
+          [''], action='M')
+    ]
+
+    msgs = PRESUBMIT.CheckAccessibilityEventsTestsAreIncludedForAndroid(
+        mock_input_api, MockOutputApi())
+    self.assertEqual(0, len(msgs),
+                     'Expected %d messages, found %d: %s'
+                     % (0, len(msgs), msgs))
+
+  # Test that a warning is raised when the Android file is not modified.
+  def testAndroidChangeMissing(self):
+    mock_input_api = MockInputApi()
+
+    mock_input_api.files = [
+        MockAffectedFile('content/test/data/accessibility/event/foo.html',
+          [''], action='A'),
+    ]
+
+    msgs = PRESUBMIT.CheckAccessibilityEventsTestsAreIncludedForAndroid(
+        mock_input_api, MockOutputApi())
+    self.assertEqual(1, len(msgs),
+                     'Expected %d messages, found %d: %s'
+                     % (1, len(msgs), msgs))
+
+  # Test that Android change is not required when no html file is added/removed.
+  def testIgnoreNonHtmlFiles(self):
+    mock_input_api = MockInputApi()
+
+    mock_input_api.files = [
+        MockAffectedFile('content/test/data/accessibility/event/foo.txt',
+          [''], action='A'),
+        MockAffectedFile('content/test/data/accessibility/event/foo.cc',
+          [''], action='A'),
+        MockAffectedFile('content/test/data/accessibility/event/foo.h',
+          [''], action='A'),
+        MockAffectedFile('content/test/data/accessibility/event/foo.py',
+          [''], action='A')
+    ]
+
+    msgs = PRESUBMIT.CheckAccessibilityEventsTestsAreIncludedForAndroid(
+        mock_input_api, MockOutputApi())
+    self.assertEqual(0, len(msgs),
+                     'Expected %d messages, found %d: %s'
+                     % (0, len(msgs), msgs))
+
+  # Test that Android change is not required for unrelated html files.
+  def testIgnoreNonRelatedHtmlFiles(self):
+    mock_input_api = MockInputApi()
+
+    mock_input_api.files = [
+        MockAffectedFile('content/test/data/accessibility/aria/foo.html',
+          [''], action='A'),
+        MockAffectedFile('content/test/data/accessibility/html/foo.html',
+          [''], action='A'),
+        MockAffectedFile('chrome/tests/data/accessibility/foo.html',
+          [''], action='A')
+    ]
+
+    msgs = PRESUBMIT.CheckAccessibilityEventsTestsAreIncludedForAndroid(
+        mock_input_api, MockOutputApi())
+    self.assertEqual(0, len(msgs),
+                     'Expected %d messages, found %d: %s'
+                     % (0, len(msgs), msgs))
+
+  # Test that only modifying an html file will not trigger the warning.
+  def testIgnoreModifiedFiles(self):
+    mock_input_api = MockInputApi()
+
+    mock_input_api.files = [
+        MockAffectedFile('content/test/data/accessibility/event/foo.html',
+          [''], action='M')
+    ]
+
+    msgs = PRESUBMIT.CheckAccessibilityEventsTestsAreIncludedForAndroid(
+        mock_input_api, MockOutputApi())
+    self.assertEqual(0, len(msgs),
+                     'Expected %d messages, found %d: %s'
+                     % (0, len(msgs), msgs))
+
+  # Test that deleting an html file will trigger the warning.
+  def testAndroidChangeMissingOnDeletedFile(self):
+    mock_input_api = MockInputApi()
+
+    mock_input_api.files = [
+        MockAffectedFile('content/test/data/accessibility/event/foo.html',
+          [], action='D')
+    ]
+
+    msgs = PRESUBMIT.CheckAccessibilityEventsTestsAreIncludedForAndroid(
+        mock_input_api, MockOutputApi())
+    self.assertEqual(1, len(msgs),
+                     'Expected %d messages, found %d: %s'
+                     % (1, len(msgs), msgs))
+
+class AccessibilityTreeTestsAreIncludedForAndroidTest(unittest.TestCase):
+  # Test that no warning is raised when the Android file is also modified.
+  def testAndroidChangeIncluded(self):
+    mock_input_api = MockInputApi()
+
+    mock_input_api.files = [
+        MockAffectedFile('content/test/data/accessibility/aria/foo.html',
+          [''], action='A'),
+        MockAffectedFile(
+          'accessibility/WebContentsAccessibilityEventsTest.java',
+          [''], action='M')
+    ]
+
+    msgs = PRESUBMIT.CheckAccessibilityTreeTestsAreIncludedForAndroid(
+        mock_input_api, MockOutputApi())
+    self.assertEqual(0, len(msgs),
+                     'Expected %d messages, found %d: %s'
+                     % (0, len(msgs), msgs))
+
+  # Test that no warning is raised when the Android file is also modified.
+  def testAndroidChangeIncludedManyFiles(self):
+    mock_input_api = MockInputApi()
+
+    mock_input_api.files = [
+        MockAffectedFile('content/test/data/accessibility/accname/foo.html',
+          [''], action='A'),
+        MockAffectedFile('content/test/data/accessibility/aria/foo.html',
+          [''], action='A'),
+        MockAffectedFile('content/test/data/accessibility/css/foo.html',
+          [''], action='A'),
+        MockAffectedFile('content/test/data/accessibility/html/foo.html',
+          [''], action='A'),
+        MockAffectedFile(
+          'accessibility/WebContentsAccessibilityEventsTest.java',
+          [''], action='M')
+    ]
+
+    msgs = PRESUBMIT.CheckAccessibilityTreeTestsAreIncludedForAndroid(
+        mock_input_api, MockOutputApi())
+    self.assertEqual(0, len(msgs),
+                     'Expected %d messages, found %d: %s'
+                     % (0, len(msgs), msgs))
+
+  # Test that a warning is raised when the Android file is not modified.
+  def testAndroidChangeMissing(self):
+    mock_input_api = MockInputApi()
+
+    mock_input_api.files = [
+        MockAffectedFile('content/test/data/accessibility/aria/foo.html',
+          [''], action='A'),
+    ]
+
+    msgs = PRESUBMIT.CheckAccessibilityTreeTestsAreIncludedForAndroid(
+        mock_input_api, MockOutputApi())
+    self.assertEqual(1, len(msgs),
+                     'Expected %d messages, found %d: %s'
+                     % (1, len(msgs), msgs))
+
+  # Test that Android change is not required when no html file is added/removed.
+  def testIgnoreNonHtmlFiles(self):
+    mock_input_api = MockInputApi()
+
+    mock_input_api.files = [
+        MockAffectedFile('content/test/data/accessibility/accname/foo.txt',
+          [''], action='A'),
+        MockAffectedFile('content/test/data/accessibility/aria/foo.cc',
+          [''], action='A'),
+        MockAffectedFile('content/test/data/accessibility/css/foo.h',
+          [''], action='A'),
+        MockAffectedFile('content/test/data/accessibility/tree/foo.py',
+          [''], action='A')
+    ]
+
+    msgs = PRESUBMIT.CheckAccessibilityTreeTestsAreIncludedForAndroid(
+        mock_input_api, MockOutputApi())
+    self.assertEqual(0, len(msgs),
+                     'Expected %d messages, found %d: %s'
+                     % (0, len(msgs), msgs))
+
+  # Test that Android change is not required for unrelated html files.
+  def testIgnoreNonRelatedHtmlFiles(self):
+    mock_input_api = MockInputApi()
+
+    mock_input_api.files = [
+        MockAffectedFile('content/test/data/accessibility/event/foo.html',
+          [''], action='A'),
+    ]
+
+    msgs = PRESUBMIT.CheckAccessibilityTreeTestsAreIncludedForAndroid(
+        mock_input_api, MockOutputApi())
+    self.assertEqual(0, len(msgs),
+                     'Expected %d messages, found %d: %s'
+                     % (0, len(msgs), msgs))
+
+  # Test that only modifying an html file will not trigger the warning.
+  def testIgnoreModifiedFiles(self):
+    mock_input_api = MockInputApi()
+
+    mock_input_api.files = [
+        MockAffectedFile('content/test/data/accessibility/aria/foo.html',
+          [''], action='M')
+    ]
+
+    msgs = PRESUBMIT.CheckAccessibilityTreeTestsAreIncludedForAndroid(
+        mock_input_api, MockOutputApi())
+    self.assertEqual(0, len(msgs),
+                     'Expected %d messages, found %d: %s'
+                     % (0, len(msgs), msgs))
+
+  # Test that deleting an html file will trigger the warning.
+  def testAndroidChangeMissingOnDeletedFile(self):
+    mock_input_api = MockInputApi()
+
+    mock_input_api.files = [
+        MockAffectedFile('content/test/data/accessibility/accname/foo.html',
+          [], action='D')
+    ]
+
+    msgs = PRESUBMIT.CheckAccessibilityTreeTestsAreIncludedForAndroid(
+        mock_input_api, MockOutputApi())
+    self.assertEqual(1, len(msgs),
+                     'Expected %d messages, found %d: %s'
+                     % (1, len(msgs), msgs))
+
 class AndroidDeprecatedTestAnnotationTest(unittest.TestCase):
   def testCheckAndroidTestAnnotationUsage(self):
     mock_input_api = MockInputApi()
diff --git a/WATCHLISTS b/WATCHLISTS
index c59260eb..f382fc46 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -6,7 +6,7 @@
 # Refer: https://chromium.googlesource.com/chromium/src/+/main/docs/infra/watchlists.md
 
 # IMPORTANT: The regular expression filepath is tested against each path using
-# re.search, so it is not usually necessary to add .*.
+# re.search, so it is not usually necessary to add .* at the end of the pattern.
 
 {
   'WATCHLIST_DEFINITIONS': {
@@ -39,12 +39,12 @@
       'filepath': 'chrome/android/java/src/org/chromium/chrome/browser/webapps/|'\
                   'chrome/android/javatests/src/org/chromium/chrome/browser/webapps/|'\
                   'chrome/android/junit/src/org/chromium/chrome/browser/webapps/|'\
-                  'chrome/browser/android/shortcut_.*|'\
+                  'chrome/browser/android/shortcut_|'\
                   'chrome/browser/android/webapps/|'\
                   'components/webapps/browser/android/',
     },
     'agent_scheduling_group': {
-      'filepath': '.*agent_scheduling_group.*|.*agent_group_scheduler.*',
+      'filepath': '.*agent_scheduling_group|.*agent_group_scheduler',
     },
     'android_crash_reporting': {
       'filepath': 'chrome/android/java/src/org/chromium/chrome/browser/crash/' \
@@ -178,7 +178,7 @@
                   '|chrome/browser/ui/ash/.*wallpaper.*/'\
                   '|chrome/browser/ui/ash/ambient/'\
                   '|chrome/browser/ui/ash/assistant/'\
-                  '|chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.*'\
+                  '|chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler'\
     },
     'audio_service': {
       'filepath': 'services/audio/'
@@ -224,7 +224,7 @@
       'filepath': 'chrome/android/java/src/org/chromium/chrome/browser/banners/|'\
                   'chrome/android/javatests/src/org/chromium/chrome/browser/banners/|'\
                   'chrome/browser/banners/|'\
-                  'chrome/browser/ui/android/infobars/app_banner_.*|'\
+                  'chrome/browser/ui/android/infobars/app_banner_|'\
                   'components/webapps/browser/banners/|'\
                   'third_party/blink/public/platform/modules/app_banner/|'\
                   'third_party/blink/renderer/modules/app_banner/',
@@ -253,10 +253,10 @@
                   'device/battery/',
     },
     'bfcache': {
-      'filepath': 'content/browser/renderer_host/back_forward_cache.*|'\
+      'filepath': 'content/browser/renderer_host/back_forward_cache|'\
                   'content/browser/back_forward_cache_browsertest.cc|'\
                   'content/test/data/back_forward_cache/|'\
-                  'content/public/browser/back_forward_cache.*|'\
+                  'content/public/browser/back_forward_cache|'\
                   'testing/buildbot/filters.bfcache.*.filter',
     },
     'binary_size': {
@@ -510,25 +510,25 @@
       'filepath': 'third_party/blink/renderer/modules/scheduler'
     },
     'blink_script': {
-      'filepath': 'third_party/blink/renderer/bindings/core/v8/.*module.*' \
-                  '|third_party/blink/renderer/bindings/core/v8/script_controller.*' \
-                  '|third_party/blink/renderer/bindings/core/v8/script_source_code.*' \
-                  '|third_party/blink/renderer/bindings/core/v8/v8_script_runner.*'
-                  '|third_party/blink/renderer/core/dom/.*modul.*' \
-                  '|third_party/blink/renderer/core/dom/.*script.*' \
-                  '|third_party/blink/renderer/core/html/html_script_element.*' \
-                  '|third_party/blink/renderer/core/html/parser/html_parser_script_runner.*' \
+      'filepath': 'third_party/blink/renderer/bindings/core/v8/.*module' \
+                  '|third_party/blink/renderer/bindings/core/v8/script_controller' \
+                  '|third_party/blink/renderer/bindings/core/v8/script_source_code' \
+                  '|third_party/blink/renderer/bindings/core/v8/v8_script_runner'
+                  '|third_party/blink/renderer/core/dom/.*modul' \
+                  '|third_party/blink/renderer/core/dom/.*script' \
+                  '|third_party/blink/renderer/core/html/html_script_element' \
+                  '|third_party/blink/renderer/core/html/parser/html_parser_script_runner' \
                   '|third_party/blink/renderer/core/loader/modulescript/' \
-                  '|third_party/blink/renderer/core/loader/resource/script_resource.*' \
-                  '|third_party/blink/renderer/core/svg/svg_script_element.*' \
-                  '|third_party/blink/renderer/core/xml/parser/xml_document_parser.*'
+                  '|third_party/blink/renderer/core/loader/resource/script_resource' \
+                  '|third_party/blink/renderer/core/svg/svg_script_element' \
+                  '|third_party/blink/renderer/core/xml/parser/xml_document_parser'
     },
     'blink_scroll': {
-      'filepath': 'third_party/blink/renderer/core/frame/.*view.*' \
-                  '|third_party/blink/renderer/core/input/.*scroll.*' \
-                  '|third_party/blink/renderer/core/input/event_handler.*' \
+      'filepath': 'third_party/blink/renderer/core/frame/.*view' \
+                  '|third_party/blink/renderer/core/input/.*scroll' \
+                  '|third_party/blink/renderer/core/input/event_handler' \
                   '|third_party/blink/renderer/core/page/scrolling/' \
-                  '|third_party/blink/renderer/core/paint/.*scrollable_area.*' \
+                  '|third_party/blink/renderer/core/paint/.*scrollable_area' \
                   '|third_party/blink/renderer/platform/scroll/'
     },
     'blink_service_worker' : {
@@ -563,8 +563,8 @@
     'blink_viewport_interaction': {
       'filepath': 'third_party/blink/renderer/core/css/.*viewport' \
                   '|third_party/blink/renderer/core/dom/viewport_arguments' \
-                  '|third_party/blink/renderer/core/frame/frame_view.*' \
-                  '|third_party/blink/renderer/core/frame/.*viewport.*' \
+                  '|third_party/blink/renderer/core/frame/frame_view' \
+                  '|third_party/blink/renderer/core/frame/.*viewport' \
                   '|third_party/blink/renderer/core/html/html_meta_element'
     },
     'blink_w3ctests': {
@@ -685,8 +685,8 @@
                   '|chrome/browser/ash/web_applications/camera_app'\
                   '|components/arc/intent_helper/control_camera_app_delegate.h'\
                   '|components/arc/mojom/camera_intent.mojom'\
-                  '|media/capture/video/chromeos/camera_app.*'\
-                  '|media/capture/video/chromeos/mojom/camera_app.*',
+                  '|media/capture/video/chromeos/camera_app'\
+                  '|media/capture/video/chromeos/mojom/camera_app',
     },
     'chrome_cleaner': {
       'filepath': 'chrome/browser/component_updater/sw_reporter_'\
@@ -892,7 +892,7 @@
                   '|ui/wm/core/.*cursor',
     },
     'custom_proxy': {
-      'filepath': 'services/network/network_service_proxy_delegate.*',
+      'filepath': 'services/network/network_service_proxy_delegate',
     },
     'custom_tabs': {
       'filepath': 'chrome/android/java/src/org/chromium/chrome/browser/customtabs/|'\
@@ -916,7 +916,7 @@
     'demo_mode': {
       'filepath': 'docs/login/demo_mode.md|'\
                   'chrome/browser/ash/login/demo_mode/|'\
-                  'ash/metrics/demo_session_metrics_recorder.*',
+                  'ash/metrics/demo_session_metrics_recorder',
     },
     'desktop_in_product_help': {
       'filepath': 'chrome/browser/ui/in_product_help|'\
@@ -927,16 +927,16 @@
     },
     'device_chooser': {
       'filepath': 'chrome/browser/chooser_controller/|'\
-                  'chrome/browser/ui/android/bluetooth_chooser_.*|'\
-                  'chrome/browser/ui/android/usb_chooser_.*|'\
+                  'chrome/browser/ui/android/bluetooth_chooser_|'\
+                  'chrome/browser/ui/android/usb_chooser_|'\
                   'chrome/browser/ui/bluetooth/|'\
-                  'chrome/browser/ui/cocoa/device_chooser_.*|'\
-                  'chrome/browser/ui/cocoa/extensions/chooser_dialog_.*|'\
-                  'chrome/browser/ui/cocoa/permission_bubble/chooser_bubble_.*|'\
-                  'chrome/browser/ui/views/device_chooser_.*|'\
-                  'chrome/browser/ui/views/extensions/chooser_dialog_.*|'\
-                  'chrome/browser/ui/views/permission_bubble/chooser_bubble_.*|'\
-                  'chrome/browser/usb/usb_chooser_.*',
+                  'chrome/browser/ui/cocoa/device_chooser_|'\
+                  'chrome/browser/ui/cocoa/extensions/chooser_dialog_|'\
+                  'chrome/browser/ui/cocoa/permission_bubble/chooser_bubble_|'\
+                  'chrome/browser/ui/views/device_chooser_|'\
+                  'chrome/browser/ui/views/extensions/chooser_dialog_|'\
+                  'chrome/browser/ui/views/permission_bubble/chooser_bubble_|'\
+                  'chrome/browser/usb/usb_chooser_',
     },
     'devtools': {
       'filepath': 'devtools',
@@ -1070,9 +1070,9 @@
     'geolocation': {
       'filepath': 'chrome/browser/geolocation/|'\
                   'content/browser/geolocation|'\
-                  'content/public/common/geoposition.*|'\
-                  'content/public/browser/geolocation.*|'\
-                  'content/renderer/geolocation.*|'\
+                  'content/public/common/geoposition|'\
+                  'content/public/browser/geolocation|'\
+                  'content/renderer/geolocation|'\
                   'content/shell/geolocation/',
     },
     'gfx_geometry': {
@@ -1121,15 +1121,15 @@
       'filepath': 'headless/'
     },
     'heap_mojo': {
-      'filepath': 'third_party/blink/renderer/platform/mojo/heap_mojo_.*'
+      'filepath': 'third_party/blink/renderer/platform/mojo/heap_mojo_'
     },
     'holding_space': {
       'filepath': 'ash/public/cpp/holding_space|'\
                   'ash/system/holding_space|'\
-                  'chrome/browser/lacros/.*holding_space.*|'\
+                  'chrome/browser/lacros/.*holding_space|'\
                   'chrome/browser/ui/ash/holding_space|'\
-                  'chrome/browser/ui/ash/thumbnail_loader.*|'\
-                  'chromeos/crosapi/mojom/.*holding_space.*|'\
+                  'chrome/browser/ui/ash/thumbnail_loader|'\
+                  'chromeos/crosapi/mojom/.*holding_space|'\
                   'tools/metrics/histograms/metadata/holding_space'
     },
     'i18n': {
@@ -1239,10 +1239,10 @@
       'filepath': 'content/common/sandbox.*linux.cc',
     },
     'lookalikes': {
-      'filepath': 'chrome/browser/component_updater/safety_tips_.*'\
+      'filepath': 'chrome/browser/component_updater/safety_tips_'\
                   '|chrome/browser/lookalikes/'\
                   '|chrome/browser/reputation/'\
-                  '|chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view.*'\
+                  '|chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view'\
                   '|components/lookalikes/'\
                   '|components/site_engagement/'\
                   '|components/url_formatter/',
@@ -1281,7 +1281,7 @@
                   '|media/gpu/vaapi'\
                   '|media/gpu/v4l2'\
                   '|media/gpu/.*\.(cc|h)$'\
-                  '|media/mojo/(clients|mojom|test|services)/.*accelerator.*'
+                  '|media/mojo/(clients|mojom|test|services)/.*accelerator'
     },
     'media_gpu_vaapi': {
       'filepath': 'media/gpu/vaapi',
@@ -1382,11 +1382,11 @@
     },
     'navigation': {
       'filepath': 'content/browser/renderer_host|'\
-                  'content/browser/renderer_host/render_process_host.*|'\
-                  'content/browser/renderer_host/render_view_host.*|'\
-                  'content/browser/web_contents/web_contents_impl.*|'\
-                  'content/renderer/render_frame.*|'\
-                  'content/renderer/render_view.*'
+                  'content/browser/renderer_host/render_process_host|'\
+                  'content/browser/renderer_host/render_view_host|'\
+                  'content/browser/web_contents/web_contents_impl|'\
+                  'content/renderer/render_frame|'\
+                  'content/renderer/render_view'
     },
     'nearby': {
       'filepath': 'chrome/browser/nearby_sharing/|'\
@@ -1502,8 +1502,8 @@
       'filepath': 'ui/ozone/|'\
         'ui/events/ozone/|'\
         'ui/gfx/linux/|'\
-        'ui/gl/gl_.*egl.*|'\
-        'ui/gl/gl_.*ozone.*'
+        'ui/gl/gl_.*egl|'\
+        'ui/gl/gl_.*ozone'
     },
     'ozone_fuchsia': {
       'filepath': 'ui/ozone/platform/flatland/|'\
@@ -1631,7 +1631,7 @@
     },
     'quick_answers': {
       'filepath': 'ash/quick_answers/'\
-                  '|chrome/browser/renderer_context_menu/quick_answers.*'\
+                  '|chrome/browser/renderer_context_menu/quick_answers'\
                   '|chromeos/components/quick_answers/'
     },
     'relaunch_notification': {
@@ -1715,7 +1715,7 @@
     },
     'share_sheet': {
       'filepath': 'chrome/android/java/src/org/chromium/chrome/browser/share/'\
-                  '|chrome/android/java/res/layout/share_sheet_.*'\
+                  '|chrome/android/java/res/layout/share_sheet_'\
                   '|chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/',
     },
     'sharing': {
@@ -1900,7 +1900,7 @@
                   '|content/public/android/java/src/org/chromium/content/browser/selection/'
     },
     'tracing': {
-      'filepath': 'base/debug/trace_event.*'\
+      'filepath': 'base/debug/trace_event'\
                   '|base/trace_event/'\
                   '|content/browser/tracing/'\
                   '|components/tracing/'\
@@ -1972,7 +1972,7 @@
                   'media/capture/video/|'\
                   'media/filters/|'\
                   'media/gpu/|'\
-                  '.*video.*',
+                  '.*video',
     },
     'video_capture': {
       'filepath': 'chrome/browser/media/.*(capture|media|webrtc)'\
@@ -2025,7 +2025,7 @@
     },
     'web_share': {
       'filepath': 'chrome/android/java/src/org/chromium/chrome/browser/webshare/'\
-                  '|chrome/android/javatests/src/org/chromium/chrome/browser/WebShare.*'\
+                  '|chrome/android/javatests/src/org/chromium/chrome/browser/WebShare'\
                   '|third_party/blink/web_tests/webshare/'\
                   '|third_party/blink/web_tests/external/wpt/web-share/'\
                   '|third_party/blink/public/mojom/webshare/'\
diff --git a/apps/app_restore_service_browsertest.cc b/apps/app_restore_service_browsertest.cc
index 18e7a75..df9fc68c 100644
--- a/apps/app_restore_service_browsertest.cc
+++ b/apps/app_restore_service_browsertest.cc
@@ -6,6 +6,7 @@
 
 #include "apps/app_restore_service_factory.h"
 #include "apps/saved_files_service.h"
+#include "base/files/file_util.h"
 #include "base/threading/thread_restrictions.h"
 #include "build/build_config.h"
 #include "chrome/browser/apps/platform_apps/app_browsertest_util.h"
diff --git a/ash/accelerators/accelerator_controller_impl.cc b/ash/accelerators/accelerator_controller_impl.cc
index ce0bae5..29d2241 100644
--- a/ash/accelerators/accelerator_controller_impl.cc
+++ b/ash/accelerators/accelerator_controller_impl.cc
@@ -43,7 +43,8 @@
 #include "ash/public/cpp/accelerators.h"
 #include "ash/public/cpp/assistant/controller/assistant_ui_controller.h"
 #include "ash/public/cpp/new_window_delegate.h"
-#include "ash/public/cpp/toast_data.h"
+#include "ash/public/cpp/system/toast_catalog.h"
+#include "ash/public/cpp/system/toast_data.h"
 #include "ash/root_window_controller.h"
 #include "ash/rotator/window_rotation.h"
 #include "ash/shelf/home_button.h"
@@ -218,8 +219,10 @@
   IncrementStartupNotificationCount(pref_service);
 }
 
-void ShowToast(std::string id, const std::u16string& text) {
-  ToastData toast(id, text, ToastData::kDefaultToastDurationMs,
+void ShowToast(std::string id,
+               ToastCatalogName catalog_name,
+               const std::u16string& text) {
+  ToastData toast(id, catalog_name, text, ToastData::kDefaultToastDurationMs,
                   /*visible_on_lock_screen=*/true);
   Shell::Get()->toast_manager()->Show(toast);
 }
@@ -328,7 +331,7 @@
 void HandleNewDesk() {
   auto* desks_controller = DesksController::Get();
   if (!desks_controller->CanCreateDesks()) {
-    ShowToast(kVirtualDesksToastId,
+    ShowToast(kVirtualDesksToastId, ToastCatalogName::kVirtualDesksLimitMax,
               l10n_util::GetStringUTF16(IDS_ASH_DESKS_MAX_NUM_REACHED));
     return;
   }
@@ -350,7 +353,7 @@
 
   auto* desks_controller = DesksController::Get();
   if (!desks_controller->CanRemoveDesks()) {
-    ShowToast(kVirtualDesksToastId,
+    ShowToast(kVirtualDesksToastId, ToastCatalogName::kVirtualDesksLimitMin,
               l10n_util::GetStringUTF16(IDS_ASH_DESKS_MIN_NUM_REACHED));
     return;
   }
@@ -1003,44 +1006,44 @@
       AssistantAllowedState::ALLOWED)) {
     case AssistantAllowedState::DISALLOWED_BY_NONPRIMARY_USER:
       // Show a toast if the active user is not primary.
-      ShowToast(kAssistantErrorToastId,
+      ShowToast(kAssistantErrorToastId, ToastCatalogName::kAssistantError,
                 l10n_util::GetStringUTF16(
                     IDS_ASH_ASSISTANT_SECONDARY_USER_TOAST_MESSAGE));
       return;
     case AssistantAllowedState::DISALLOWED_BY_LOCALE:
       // Show a toast if the Assistant is disabled due to unsupported
       // locales.
-      ShowToast(kAssistantErrorToastId,
+      ShowToast(kAssistantErrorToastId, ToastCatalogName::kAssistantError,
                 l10n_util::GetStringUTF16(
                     IDS_ASH_ASSISTANT_LOCALE_UNSUPPORTED_TOAST_MESSAGE));
       return;
     case AssistantAllowedState::DISALLOWED_BY_POLICY:
       // Show a toast if the Assistant is disabled due to enterprise policy.
-      ShowToast(kAssistantErrorToastId,
+      ShowToast(kAssistantErrorToastId, ToastCatalogName::kAssistantError,
                 l10n_util::GetStringUTF16(
                     IDS_ASH_ASSISTANT_DISABLED_BY_POLICY_MESSAGE));
       return;
     case AssistantAllowedState::DISALLOWED_BY_DEMO_MODE:
       // Show a toast if the Assistant is disabled due to being in Demo
       // Mode.
-      ShowToast(kAssistantErrorToastId,
+      ShowToast(kAssistantErrorToastId, ToastCatalogName::kAssistantError,
                 l10n_util::GetStringUTF16(
                     IDS_ASH_ASSISTANT_DISABLED_IN_DEMO_MODE_MESSAGE));
       return;
     case AssistantAllowedState::DISALLOWED_BY_PUBLIC_SESSION:
       // Show a toast if the Assistant is disabled due to being in public
       // session.
-      ShowToast(kAssistantErrorToastId,
+      ShowToast(kAssistantErrorToastId, ToastCatalogName::kAssistantError,
                 l10n_util::GetStringUTF16(
                     IDS_ASH_ASSISTANT_DISABLED_IN_PUBLIC_SESSION_MESSAGE));
       return;
     case AssistantAllowedState::DISALLOWED_BY_INCOGNITO:
-      ShowToast(kAssistantErrorToastId,
+      ShowToast(kAssistantErrorToastId, ToastCatalogName::kAssistantError,
                 l10n_util::GetStringUTF16(
                     IDS_ASH_ASSISTANT_DISABLED_IN_GUEST_MESSAGE));
       return;
     case AssistantAllowedState::DISALLOWED_BY_ACCOUNT_TYPE:
-      ShowToast(kAssistantErrorToastId,
+      ShowToast(kAssistantErrorToastId, ToastCatalogName::kAssistantError,
                 l10n_util::GetStringUTF16(
                     IDS_ASH_ASSISTANT_DISABLED_BY_ACCOUNT_MESSAGE));
       return;
diff --git a/ash/accelerators/debug_commands.cc b/ash/accelerators/debug_commands.cc
index ecf9e687..56d3c505 100644
--- a/ash/accelerators/debug_commands.cc
+++ b/ash/accelerators/debug_commands.cc
@@ -13,7 +13,8 @@
 #include "ash/hud_display/hud_display.h"
 #include "ash/public/cpp/accelerators.h"
 #include "ash/public/cpp/debug_utils.h"
-#include "ash/public/cpp/toast_data.h"
+#include "ash/public/cpp/system/toast_catalog.h"
+#include "ash/public/cpp/system/toast_data.h"
 #include "ash/shell.h"
 #include "ash/system/toast/toast_manager_impl.h"
 #include "ash/touch/touch_devices_controller.h"
@@ -182,7 +183,8 @@
       break;
     case DEBUG_SHOW_TOAST:
       Shell::Get()->toast_manager()->Show(ToastData(
-          /*id=*/"id", /*text=*/u"Toast", ToastData::kDefaultToastDurationMs,
+          /*id=*/"id", ToastCatalogName::kDebugCommand, /*text=*/u"Toast",
+          ToastData::kDefaultToastDurationMs,
           /*visible_on_lock_screen=*/false, /*dismiss_text=*/u"Dismiss"));
       break;
     case DEBUG_TOGGLE_TOUCH_PAD:
diff --git a/ash/accessibility/accessibility_controller_impl.cc b/ash/accessibility/accessibility_controller_impl.cc
index 643e918..1ad3b91 100644
--- a/ash/accessibility/accessibility_controller_impl.cc
+++ b/ash/accessibility/accessibility_controller_impl.cc
@@ -2404,11 +2404,12 @@
 
 void AccessibilityControllerImpl::UpdateDictationBubble(
     bool visible,
+    DictationBubbleIconType icon,
     const absl::optional<std::u16string>& text) {
   DCHECK(dictation().enabled());
   DCHECK(dictation_bubble_controller_);
 
-  dictation_bubble_controller_->UpdateBubble(visible, text);
+  dictation_bubble_controller_->UpdateBubble(visible, icon, text);
 }
 
 }  // namespace ash
diff --git a/ash/accessibility/accessibility_controller_impl.h b/ash/accessibility/accessibility_controller_impl.h
index 5d6f99d..10f77f2 100644
--- a/ash/accessibility/accessibility_controller_impl.h
+++ b/ash/accessibility/accessibility_controller_impl.h
@@ -451,6 +451,7 @@
       const std::u16string& display_language) override;
   void UpdateDictationBubble(
       bool visible,
+      DictationBubbleIconType icon,
       const absl::optional<std::u16string>& text) override;
 
   // SessionObserver:
diff --git a/ash/app_list/BUILD.gn b/ash/app_list/BUILD.gn
index 2642950f..f7dbaab 100644
--- a/ash/app_list/BUILD.gn
+++ b/ash/app_list/BUILD.gn
@@ -60,6 +60,8 @@
     "views/app_list_page.h",
     "views/app_list_reorder_undo_container_view.cc",
     "views/app_list_reorder_undo_container_view.h",
+    "views/app_list_toast_view.cc",
+    "views/app_list_toast_view.h",
     "views/app_list_view.cc",
     "views/app_list_view.h",
     "views/app_list_view_util.cc",
diff --git a/ash/app_list/views/app_list_reorder_undo_container_view.cc b/ash/app_list/views/app_list_reorder_undo_container_view.cc
index ee8bf78..7d002011 100644
--- a/ash/app_list/views/app_list_reorder_undo_container_view.cc
+++ b/ash/app_list/views/app_list_reorder_undo_container_view.cc
@@ -8,8 +8,8 @@
 
 #include "ash/app_list/app_list_model_provider.h"
 #include "ash/app_list/app_list_view_delegate.h"
+#include "ash/app_list/views/app_list_toast_view.h"
 #include "ash/public/cpp/app_list/app_list_model_delegate.h"
-#include "ash/style/system_toast_style.h"
 #include "base/strings/strcat.h"
 #include "ui/views/layout/flex_layout.h"
 #include "ui/views/layout/flex_layout_types.h"
@@ -62,21 +62,24 @@
 
   const std::u16string toast_text = CalculateToastTextFromOrder(*new_order);
   if (toast_view_) {
-    toast_view_->SetText(toast_text);
+    toast_view_->SetTitle(toast_text);
     return;
   }
 
-  toast_view_ = AddChildView(std::make_unique<SystemToastStyle>(
-      base::BindRepeating(
-          &AppListReorderUndoContainerView::OnReorderUndoButtonClicked,
-          base::Unretained(this)),
-      toast_text, kToastDismissText,
-      /*is_managed=*/false));
+  // TODO(crbug.com/1277001): Add icon to the toast.
+  toast_view_ = AddChildView(
+      AppListToastView::Builder(toast_text)
+          .SetButton(
+              kToastDismissText,
+              base::BindRepeating(
+                  &AppListReorderUndoContainerView::OnReorderUndoButtonClicked,
+                  base::Unretained(this)))
+          .Build());
 }
 
 views::LabelButton*
 AppListReorderUndoContainerView::GetToastDismissButtonForTest() {
-  return toast_view_->button();
+  return toast_view_->toast_button();
 }
 
 void AppListReorderUndoContainerView::OnReorderUndoButtonClicked() {
diff --git a/ash/app_list/views/app_list_reorder_undo_container_view.h b/ash/app_list/views/app_list_reorder_undo_container_view.h
index 41c3b5c..b756366 100644
--- a/ash/app_list/views/app_list_reorder_undo_container_view.h
+++ b/ash/app_list/views/app_list_reorder_undo_container_view.h
@@ -13,7 +13,7 @@
 
 namespace ash {
 
-class SystemToastStyle;
+class AppListToastView;
 enum class AppListSortOrder;
 
 // A view accommodating a toast view that reverts the app list temporary
@@ -45,7 +45,7 @@
   [[nodiscard]] std::u16string CalculateToastTextFromOrder(
       AppListSortOrder order) const;
 
-  SystemToastStyle* toast_view_ = nullptr;
+  AppListToastView* toast_view_ = nullptr;
 };
 
 }  // namespace ash
diff --git a/ash/app_list/views/app_list_toast_view.cc b/ash/app_list/views/app_list_toast_view.cc
new file mode 100644
index 0000000..8a54dcd
--- /dev/null
+++ b/ash/app_list/views/app_list_toast_view.cc
@@ -0,0 +1,204 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/app_list/views/app_list_toast_view.h"
+
+#include <memory>
+
+#include "ash/app_list/app_list_controller_impl.h"
+#include "ash/bubble/bubble_utils.h"
+#include "ash/shell.h"
+#include "ash/style/ash_color_provider.h"
+#include "ash/style/pill_button.h"
+#include "ui/gfx/color_palette.h"
+#include "ui/views/background.h"
+#include "ui/views/controls/button/label_button.h"
+#include "ui/views/controls/image_view.h"
+#include "ui/views/controls/label.h"
+#include "ui/views/layout/box_layout.h"
+
+namespace ash {
+
+constexpr int kCornerRadius = 16;
+constexpr gfx::Insets kInteriorMargin(7, 8, 7, 16);
+
+constexpr int kToastHeight = 32;
+constexpr int kToastMaximumWidth = 512;
+constexpr int kToastMinimumWidth = 288;
+
+AppListToastView::Builder::Builder(const std::u16string title)
+    : title_(title) {}
+
+AppListToastView::Builder::~Builder() = default;
+
+std::unique_ptr<AppListToastView> AppListToastView::Builder::Build() {
+  std::unique_ptr<AppListToastView> toast =
+      std::make_unique<AppListToastView>(title_);
+
+  if (dark_icon_ && light_icon_)
+    toast->SetThemingIcons(dark_icon_, light_icon_);
+  else if (icon_)
+    toast->SetIcon(icon_);
+
+  if (has_button_)
+    toast->SetButton(*button_text_, button_callback_);
+
+  if (subtitle_)
+    toast->SetSubtitle(*subtitle_);
+
+  return toast;
+}
+
+AppListToastView::Builder& AppListToastView::Builder::SetIcon(
+    const gfx::VectorIcon& icon) {
+  DCHECK(!dark_icon_);
+  DCHECK(!light_icon_);
+
+  icon_ = &icon;
+  return *this;
+}
+
+AppListToastView::Builder& AppListToastView::Builder::SetThemingIcons(
+    const gfx::VectorIcon& dark_icon,
+    const gfx::VectorIcon& light_icon) {
+  DCHECK(!icon_);
+
+  dark_icon_ = &dark_icon;
+  light_icon_ = &light_icon;
+  return *this;
+}
+
+AppListToastView::Builder& AppListToastView::Builder::SetSubtitle(
+    const std::u16string subtitle) {
+  subtitle_ = subtitle;
+  return *this;
+}
+
+AppListToastView::Builder& AppListToastView::Builder::SetButton(
+    const std::u16string button_text,
+    views::Button::PressedCallback button_callback) {
+  DCHECK(button_callback);
+
+  has_button_ = true;
+  button_text_ = button_text;
+  button_callback_ = button_callback;
+  return *this;
+}
+
+AppListToastView::AppListToastView(const std::u16string title) {
+  views::BoxLayout* layout_manager =
+      SetLayoutManager(std::make_unique<views::BoxLayout>(
+          views::BoxLayout::Orientation::kHorizontal, kInteriorMargin));
+  layout_manager->set_cross_axis_alignment(
+      views::BoxLayout::CrossAxisAlignment::kCenter);
+
+  label_container_ = AddChildView(std::make_unique<views::View>());
+  label_container_->SetLayoutManager(std::make_unique<views::BoxLayout>(
+      views::BoxLayout::Orientation::kVertical));
+
+  title_label_ =
+      label_container_->AddChildView(std::make_unique<views::Label>(title));
+  title_label_->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT);
+
+  layout_manager->SetFlexForView(label_container_, 1);
+}
+
+AppListToastView::~AppListToastView() = default;
+
+void AppListToastView::OnThemeChanged() {
+  views::View::OnThemeChanged();
+  if (title_label_)
+    bubble_utils::ApplyStyle(title_label_, bubble_utils::LabelStyle::kBody);
+  if (subtitle_label_)
+    bubble_utils::ApplyStyle(subtitle_label_,
+                             bubble_utils::LabelStyle::kSubtitle);
+
+  SetBackground(views::CreateRoundedRectBackground(
+      AshColorProvider::Get()->GetControlsLayerColor(
+          AshColorProvider::ControlsLayerType::kControlBackgroundColorInactive),
+      kCornerRadius));
+
+  UpdateIconImage();
+}
+
+void AppListToastView::SetButton(
+    std::u16string button_text,
+    views::Button::PressedCallback button_callback) {
+  DCHECK(button_callback);
+
+  toast_button_ = AddChildView(std::make_unique<PillButton>(
+      button_callback, button_text, PillButton::Type::kIconless,
+      /*icon=*/nullptr));
+}
+
+void AppListToastView::SetTitle(const std::u16string title) {
+  title_label_->SetText(title);
+}
+
+void AppListToastView::SetSubtitle(const std::u16string subtitle) {
+  if (subtitle_label_) {
+    subtitle_label_->SetText(subtitle);
+    return;
+  }
+
+  subtitle_label_ =
+      label_container_->AddChildView(std::make_unique<views::Label>(subtitle));
+  subtitle_label_->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT);
+}
+
+void AppListToastView::SetIcon(const gfx::VectorIcon* icon) {
+  DCHECK(!dark_icon_);
+  DCHECK(!light_icon_);
+
+  CreateIconView();
+
+  default_icon_ = icon;
+  UpdateIconImage();
+}
+
+void AppListToastView::SetThemingIcons(const gfx::VectorIcon* dark_icon,
+                                       const gfx::VectorIcon* light_icon) {
+  DCHECK(!default_icon_);
+
+  CreateIconView();
+
+  dark_icon_ = dark_icon;
+  light_icon_ = light_icon;
+  UpdateIconImage();
+}
+
+gfx::Size AppListToastView::GetMaximumSize() const {
+  return gfx::Size(kToastMaximumWidth, GetPreferredSize().height());
+}
+
+gfx::Size AppListToastView::GetMinimumSize() const {
+  return gfx::Size(kToastMinimumWidth, kToastHeight);
+}
+
+void AppListToastView::UpdateIconImage() {
+  if (!icon_)
+    return;
+
+  if (default_icon_) {
+    icon_->SetImage(ui::ImageModel::FromVectorIcon(*default_icon_));
+    return;
+  }
+
+  // Default to dark_icon_ if dark/light mode feature is not enabled.
+  icon_->SetImage(ui::ImageModel::FromVectorIcon(
+      !features::IsDarkLightModeEnabled() ||
+              AshColorProvider::Get()->IsDarkModeEnabled()
+          ? *dark_icon_
+          : *light_icon_));
+}
+
+void AppListToastView::CreateIconView() {
+  DCHECK(!icon_);
+
+  icon_ = AddChildViewAt(std::make_unique<views::ImageView>(), 0);
+  icon_->SetVerticalAlignment(views::ImageView::Alignment::kCenter);
+  icon_->SetHorizontalAlignment(views::ImageView::Alignment::kCenter);
+}
+
+}  // namespace ash
diff --git a/ash/app_list/views/app_list_toast_view.h b/ash/app_list/views/app_list_toast_view.h
new file mode 100644
index 0000000..25cc89f
--- /dev/null
+++ b/ash/app_list/views/app_list_toast_view.h
@@ -0,0 +1,113 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_APP_LIST_VIEWS_APP_LIST_TOAST_VIEW_H_
+#define ASH_APP_LIST_VIEWS_APP_LIST_TOAST_VIEW_H_
+
+#include <memory>
+
+#include "ash/ash_export.h"
+#include "ui/views/controls/button/button.h"
+#include "ui/views/view.h"
+
+namespace views {
+class Label;
+class LabelButton;
+class ImageView;
+}  // namespace views
+
+namespace gfx {
+struct VectorIcon;
+}  // namespace gfx
+
+namespace ash {
+
+// A view specific to AppList that displays an icon, two labels and a button.
+// The view can be built with all or some of the elements mentioned before, but
+// always will have to include at least a title. The view has a grid-like layout
+// with 3 columns where the icon will be on the first column, the button on the
+// last column and the title and subtitle will share the middle column, with the
+// title over the subtitle.
+class ASH_EXPORT AppListToastView : public views::View {
+ public:
+  class Builder {
+   public:
+    explicit Builder(const std::u16string title);
+    virtual ~Builder();
+
+    std::unique_ptr<AppListToastView> Build();
+
+    // Methods for setting vector icons for the toast.
+    // Vector icons would change appearance with theming by default.
+    // Nevertheless there might be a case when different icons need to be used
+    // with dark/light mode (i.e. non-monochromatic icons) and a single icon is
+    // not enough. For this case, use SetThemingIcons().
+    Builder& SetIcon(const gfx::VectorIcon& icon);
+    Builder& SetThemingIcons(const gfx::VectorIcon& dark_icon,
+                             const gfx::VectorIcon& light_icon);
+
+    Builder& SetSubtitle(const std::u16string subtitle);
+    Builder& SetButton(std::u16string button_text,
+                       views::Button::PressedCallback button_callback);
+
+   private:
+    std::u16string title_;
+    absl::optional<std::u16string> subtitle_;
+    absl::optional<std::u16string> button_text_;
+    const gfx::VectorIcon* icon_ = nullptr;
+    const gfx::VectorIcon* dark_icon_ = nullptr;
+    const gfx::VectorIcon* light_icon_ = nullptr;
+    views::Button::PressedCallback button_callback_;
+    bool has_button_ = false;
+  };
+
+  explicit AppListToastView(const std::u16string title);
+  AppListToastView(const AppListToastView&) = delete;
+  AppListToastView& operator=(const AppListToastView&) = delete;
+  ~AppListToastView() override;
+
+  // views::View:
+  gfx::Size GetMaximumSize() const override;
+  gfx::Size GetMinimumSize() const override;
+  void OnThemeChanged() override;
+
+  void SetButton(std::u16string button_text,
+                 views::Button::PressedCallback button_callback);
+
+  void SetIcon(const gfx::VectorIcon* icon);
+  void SetThemingIcons(const gfx::VectorIcon* dark_icon,
+                       const gfx::VectorIcon* light_icon);
+  void SetTitle(const std::u16string title);
+  void SetSubtitle(const std::u16string subtitle);
+
+  views::LabelButton* toast_button() const { return toast_button_; }
+
+ private:
+  // Attach the icon to the toast based on theming and available icons.
+  void UpdateIconImage();
+  // Creates an ImageView for the icon and inserts it in the toast view.
+  void CreateIconView();
+
+  // Vector icons to use with dark/light mode.
+  const gfx::VectorIcon* dark_icon_ = nullptr;
+  const gfx::VectorIcon* light_icon_ = nullptr;
+
+  // Vector icon to use if there are not dark or light mode specific icons.
+  const gfx::VectorIcon* default_icon_ = nullptr;
+
+  // Toast icon view.
+  views::ImageView* icon_ = nullptr;
+  // Label with the main text for the toast.
+  views::Label* title_label_ = nullptr;
+  // Label with the subtext for the toast.
+  views::Label* subtitle_label_ = nullptr;
+  // The button for the toast.
+  views::LabelButton* toast_button_ = nullptr;
+  // Helper view to layout labels.
+  views::View* label_container_ = nullptr;
+};
+
+}  // namespace ash
+
+#endif  // ASH_APP_LIST_VIEWS_APP_LIST_TOAST_VIEW_H_
diff --git a/ash/app_list/views/privacy_container_view.cc b/ash/app_list/views/privacy_container_view.cc
index a6765658..80fd46f0 100644
--- a/ash/app_list/views/privacy_container_view.cc
+++ b/ash/app_list/views/privacy_container_view.cc
@@ -49,11 +49,6 @@
   return nullptr;
 }
 
-int PrivacyContainerView::ScheduleResultAnimations(int preceeding_results) {
-  NOTREACHED();
-  return -1;
-}
-
 int PrivacyContainerView::DoUpdate() {
   const bool should_show_suggested_content =
       view_delegate()->ShouldShowSuggestedContentInfo();
diff --git a/ash/app_list/views/privacy_container_view.h b/ash/app_list/views/privacy_container_view.h
index edc3f5e3..ae02103 100644
--- a/ash/app_list/views/privacy_container_view.h
+++ b/ash/app_list/views/privacy_container_view.h
@@ -26,7 +26,6 @@
 
   // SearchResultContainerView:
   SearchResultBaseView* GetResultViewAt(size_t index) override;
-  int ScheduleResultAnimations(int preceeding_results) override;
 
  private:
   friend class test::PrivacyContainerViewTest;
diff --git a/ash/app_list/views/productivity_launcher_search_view.cc b/ash/app_list/views/productivity_launcher_search_view.cc
index c8486cc..26a52e34 100644
--- a/ash/app_list/views/productivity_launcher_search_view.cc
+++ b/ash/app_list/views/productivity_launcher_search_view.cc
@@ -88,7 +88,8 @@
   auto* answer_card_container =
       scroll_contents->AddChildView(std::make_unique<SearchResultListView>(
           /*main_view=*/nullptr, view_delegate, dialog_controller_,
-          SearchResultView::SearchResultViewType::kAnswerCard, absl::nullopt));
+          SearchResultView::SearchResultViewType::kAnswerCard,
+          /*animates_result_updates=*/true, absl::nullopt));
   answer_card_container->SetListType(
       SearchResultListView::SearchResultListType::kAnswerCard);
   add_result_container(answer_card_container);
@@ -97,7 +98,8 @@
   auto* best_match_container =
       scroll_contents->AddChildView(std::make_unique<SearchResultListView>(
           /*main_view=*/nullptr, view_delegate, dialog_controller_,
-          SearchResultView::SearchResultViewType::kDefault, absl::nullopt));
+          SearchResultView::SearchResultViewType::kDefault,
+          /*animated_result_updates=*/true, absl::nullopt));
   best_match_container->SetListType(
       SearchResultListView::SearchResultListType::kBestMatch);
   add_result_container(best_match_container);
@@ -114,7 +116,8 @@
     auto* result_container =
         scroll_contents->AddChildView(std::make_unique<SearchResultListView>(
             /*main_view=*/nullptr, view_delegate, dialog_controller_,
-            SearchResultView::SearchResultViewType::kDefault, i));
+            SearchResultView::SearchResultViewType::kDefault,
+            /*animates_result_updates=*/true, i));
     add_result_container(result_container);
   }
 
@@ -148,10 +151,16 @@
   }
 
   if (features::IsProductivityLauncherAnimationEnabled()) {
-    int scheduled_result_animations = 0;
+    using AnimationInfo = SearchResultContainerView::ResultsAnimationInfo;
+    AnimationInfo aggregate_animation_info;
     for (SearchResultContainerView* view : result_container_views_) {
-      scheduled_result_animations +=
-          view->ScheduleResultAnimations(scheduled_result_animations);
+      absl::optional<AnimationInfo> container_animation_info =
+          view->ScheduleResultAnimations(aggregate_animation_info);
+      DCHECK(container_animation_info);
+      aggregate_animation_info.total_views +=
+          container_animation_info->total_views;
+      aggregate_animation_info.animating_views +=
+          container_animation_info->animating_views;
     }
   }
 
diff --git a/ash/app_list/views/result_selection_controller_unittest.cc b/ash/app_list/views/result_selection_controller_unittest.cc
index 8138038..9c9ea2f4 100644
--- a/ash/app_list/views/result_selection_controller_unittest.cc
+++ b/ash/app_list/views/result_selection_controller_unittest.cc
@@ -136,10 +136,6 @@
     DCHECK_LT(index, search_result_views_.size());
     return search_result_views_[index].get();
   }
-  int ScheduleResultAnimations(int preceeding_results) override {
-    NOTREACHED();
-    return -1;
-  }
 
  private:
   int DoUpdate() override { return search_result_views_.size(); }
diff --git a/ash/app_list/views/search_result_container_view.cc b/ash/app_list/views/search_result_container_view.cc
index 4a94949..0b1a5a2 100644
--- a/ash/app_list/views/search_result_container_view.cc
+++ b/ash/app_list/views/search_result_container_view.cc
@@ -34,6 +34,13 @@
   Update();
 }
 
+absl::optional<SearchResultContainerView::ResultsAnimationInfo>
+SearchResultContainerView::ScheduleResultAnimations(
+    const ResultsAnimationInfo& aggregate_animation_info) {
+  NOTREACHED();
+  return absl::nullopt;
+}
+
 void SearchResultContainerView::Update() {
   update_factory_.InvalidateWeakPtrs();
   num_results_ = DoUpdate();
diff --git a/ash/app_list/views/search_result_container_view.h b/ash/app_list/views/search_result_container_view.h
index 75d0351..cbd97c5 100644
--- a/ash/app_list/views/search_result_container_view.h
+++ b/ash/app_list/views/search_result_container_view.h
@@ -55,7 +55,25 @@
   int num_results() const { return num_results_; }
 
   virtual SearchResultBaseView* GetResultViewAt(size_t index) = 0;
-  virtual int ScheduleResultAnimations(int preceeding_results) = 0;
+
+  // Information needed to configure search result visibility animations when
+  // result updates are animated.
+  struct ResultsAnimationInfo {
+    // Total number of visible views (either title or result views).
+    int total_views = 0;
+
+    // The number of views that are animating (either title or result views).
+    int animating_views = 0;
+  };
+
+  // Schedules animations for result list updates. Expected to be implemented
+  // for search result containers that animate result updates.
+  // `aggregate_animation_info` The aggregated animation information for all
+  // search result containers that appear in the search results UI before this
+  // container.
+  // Returns the animation info for this container.
+  virtual absl::optional<ResultsAnimationInfo> ScheduleResultAnimations(
+      const ResultsAnimationInfo& aggregate_animation_info);
 
   bool horizontally_traversable() const { return horizontally_traversable_; }
 
diff --git a/ash/app_list/views/search_result_list_view.cc b/ash/app_list/views/search_result_list_view.cc
index 7a31d0f..9b627ad6 100644
--- a/ash/app_list/views/search_result_list_view.cc
+++ b/ash/app_list/views/search_result_list_view.cc
@@ -120,10 +120,12 @@
     AppListViewDelegate* view_delegate,
     SearchResultPageDialogController* dialog_controller,
     SearchResultView::SearchResultViewType search_result_view_type,
+    bool animates_result_updates,
     absl::optional<size_t> productivity_launcher_index)
     : SearchResultContainerView(view_delegate),
       main_view_(main_view),
       view_delegate_(view_delegate),
+      animates_result_updates_(animates_result_updates),
       results_container_(new views::View),
       productivity_launcher_index_(productivity_launcher_index),
       search_result_view_type_(search_result_view_type) {
@@ -140,7 +142,6 @@
   title_label_->SetVisible(false);
   title_label_->SetPaintToLayer();
   title_label_->layer()->SetFillsBoundsOpaquely(false);
-  title_label_->layer()->SetOpacity(0.0f);
 
   results_container_->AddChildView(title_label_);
 
@@ -154,7 +155,6 @@
     search_result_views_.back()->set_index_in_container(i);
     search_result_views_.back()->SetPaintToLayer();
     search_result_views_.back()->layer()->SetFillsBoundsOpaquely(false);
-    search_result_views_.back()->layer()->SetOpacity(0.0f);
     results_container_->AddChildView(search_result_views_.back());
     AddObservedResultView(search_result_views_.back());
   }
@@ -278,38 +278,66 @@
   return categorical_search_types;
 }
 
-int SearchResultListView::ScheduleResultAnimations(
-    int preceeding_result_count) {
+absl::optional<SearchResultContainerView::ResultsAnimationInfo>
+SearchResultListView::ScheduleResultAnimations(
+    const ResultsAnimationInfo& aggregate_animation_info) {
   DCHECK(features::IsProductivityLauncherAnimationEnabled());
+  DCHECK(animates_result_updates_);
+
+  // Collect current container animation info.
+  ResultsAnimationInfo current_animation_info;
 
   if (num_results_ < 1 || !enabled_) {
     SetVisible(false);
-    for (auto* result_view : search_result_views_) {
-      result_view->SetResult(nullptr);
+    last_container_start_index_ = -1;
+    for (auto* result_view : search_result_views_)
       result_view->SetVisible(false);
-    }
-    return 0;
+    return current_animation_info;
   }
 
-  // Tracks the number of animations scheduled so far.
-  int animated_view_count = 0;
+  // All views should be animated if
+  // *   the container is being shown, or
+  // *   any of the result views that precede the container in the search UI are
+  //     animating, or
+  // *   the number of result views before this container changed (e.g. if some
+  //     results get removed).
+  bool force_animation =
+      !GetVisible() || aggregate_animation_info.animating_views > 0 ||
+      last_container_start_index_ != aggregate_animation_info.total_views;
 
   SetVisible(true);
+  last_container_start_index_ = aggregate_animation_info.total_views;
+
+  auto schedule_animation = [this, &current_animation_info,
+                             &aggregate_animation_info](views::View* view) {
+    ShowViewWithAnimation(view, current_animation_info.total_views +
+                                    aggregate_animation_info.total_views);
+    ++current_animation_info.animating_views;
+  };
+
   if (title_label_->GetVisible()) {
-    ShowViewWithAnimation(title_label_,
-                          preceeding_result_count + animated_view_count);
-    animated_view_count += 1;
+    if (force_animation)
+      schedule_animation(title_label_);
+    ++current_animation_info.total_views;
   }
 
-  for (size_t i = 0; i < num_results_; ++i) {
+  for (size_t i = 0; i < search_result_views_.size(); ++i) {
     SearchResultView* result_view = GetResultViewAt(i);
-    result_view->SizeToPreferredSize();
-    ShowViewWithAnimation(result_view,
-                          preceeding_result_count + animated_view_count);
-    animated_view_count += 1;
+    result_view->SetVisible(i < num_results_);
+
+    const bool needs_animation = result_view->GetAndResetResultChanged();
+    if (i < num_results_) {
+      if (force_animation || needs_animation) {
+        // If one of the result views have to be animated, animate all result
+        // views that follow.
+        force_animation = true;
+        schedule_animation(result_view);
+      }
+      ++current_animation_info.total_views;
+    }
   }
 
-  return animated_view_count;
+  return current_animation_info;
 }
 
 void SearchResultListView::ShowViewWithAnimation(views::View* view,
@@ -329,35 +357,19 @@
   // Duration: 100 ms
   // Ease: Linear
 
-  // Reset starting opacity of the view to 0%. Needed when aborting in-progress
-  // layer animations.
-  views::AnimationBuilder()
-      .SetPreemptionStrategy(
-          ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET)
-      .Once()
-      .SetOpacity(view, 0.0f, gfx::Tween::LINEAR)
-      .SetDuration(base::Milliseconds(0));
-
-  views::AnimationBuilder()
-      .SetPreemptionStrategy(
-          ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET)
-      .Once()
-      .SetOpacity(view, 1.0f, gfx::Tween::LINEAR)
-      .SetDuration(kFadeInDuration);
-
-  // Set the initial offset via a layer transform.
   gfx::Transform translate_down;
   translate_down.Translate(0, position * kAnimatedOffsetMultiplier);
-  views::AnimationBuilder()
-      .Once()
-      .SetDuration(base::Milliseconds(0))
-      .SetTransform(view, translate_down, gfx::Tween::LINEAR);
 
-  // Animate the transform back to the identity transform.
   views::AnimationBuilder()
       .SetPreemptionStrategy(
           ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET)
       .Once()
+      .SetOpacity(view, 0.0f)
+      .SetTransform(view, translate_down)
+      .Then()
+      .SetOpacity(view, 1.0f, gfx::Tween::LINEAR)
+      .SetDuration(kFadeInDuration)
+      .At(base::TimeDelta())
       .SetDuration(kIdentityTranslationDuration)
       .SetTransform(view, gfx::Transform(), gfx::Tween::LINEAR_OUT_SLOW_IN);
 }
@@ -602,31 +614,27 @@
 }
 
 std::vector<SearchResult*> SearchResultListView::UpdateResultViews() {
-  // Opacity will be animated to 1 by ShowViewWithAnimation() if Productivity
-  // launcher animations are enabled.
-  title_label_->layer()->SetOpacity(
-      features::IsProductivityLauncherAnimationEnabled() ? 0.0f : 1.0f);
   std::vector<SearchResult*> display_results = GetCategorizedSearchResults();
   size_t num_results = display_results.size();
   num_results_ = num_results;
   for (size_t i = 0; i < search_result_views_.size(); ++i) {
     SearchResultView* result_view = GetResultViewAt(i);
-    result_view->layer()->SetOpacity(
-        features::IsProductivityLauncherAnimationEnabled() ? 0.0f : 1.0f);
     if (i < num_results) {
       result_view->SetResult(display_results[i]);
       result_view->SizeToPreferredSize();
-      // Opacity will be animated to 1 by ShowViewWithAnimation() if
-      // Productivity launcher animations are enabled.
-      result_view->SetVisible(true);
     } else {
       result_view->SetResult(nullptr);
-      result_view->SetVisible(false);
     }
+    // If result updates are animated, the result visibility will be updated in
+    // `ScheduleResultAnimations()`
+    if (!animates_result_updates_)
+      result_view->SetVisible(i < num_results);
   }
 
-  // the search_result_list_view should be hidden if there are no results.
-  SetVisible(num_results > 0);
+  // If result updates are animated, the container visibility will be updated in
+  // `ScheduleResultAnimations()`
+  if (!animates_result_updates_)
+    SetVisible(num_results > 0);
   return display_results;
 }
 
diff --git a/ash/app_list/views/search_result_list_view.h b/ash/app_list/views/search_result_list_view.h
index ec2d9e6..b175d204 100644
--- a/ash/app_list/views/search_result_list_view.h
+++ b/ash/app_list/views/search_result_list_view.h
@@ -77,6 +77,7 @@
       AppListViewDelegate* view_delegate,
       SearchResultPageDialogController* dialog_controller,
       SearchResultView::SearchResultViewType search_result_view_type,
+      bool animates_result_updates,
       absl::optional<size_t> productivity_launcher_index);
 
   SearchResultListView(const SearchResultListView&) = delete;
@@ -99,7 +100,8 @@
 
   // Overridden from SearchResultContainerView:
   SearchResultView* GetResultViewAt(size_t index) override;
-  int ScheduleResultAnimations(int preceeding_result_count) override;
+  absl::optional<ResultsAnimationInfo> ScheduleResultAnimations(
+      const ResultsAnimationInfo& aggregate_animation_info) override;
 
   // Fades the view in and animates a vertical transform based on the view's
   // position in the overall search container view.
@@ -167,6 +169,11 @@
   AppListMainView* main_view_;          // Owned by views hierarchy.
   AppListViewDelegate* view_delegate_;  // Not owned.
 
+  // Whether the result updates will be animated. If set,
+  // `ScheduleResultAnimations()` is expected to be called whenever list of
+  // results shown in the list changes.
+  const bool animates_result_updates_;
+
   views::View* results_container_;
 
   std::vector<SearchResultView*> search_result_views_;  // Not owned.
@@ -199,6 +206,11 @@
 
   // The number of results shown by the list view.
   size_t num_results_ = 0;
+
+  // The most recent container's index within the search UI - the index
+  // indicates the number of result and title views that appear before this
+  // container.
+  int last_container_start_index_ = -1;
 };
 
 }  // namespace ash
diff --git a/ash/app_list/views/search_result_list_view_unittest.cc b/ash/app_list/views/search_result_list_view_unittest.cc
index 0c3a243..01def38 100644
--- a/ash/app_list/views/search_result_list_view_unittest.cc
+++ b/ash/app_list/views/search_result_list_view_unittest.cc
@@ -66,19 +66,20 @@
 
     unified_view_ = std::make_unique<SearchResultListView>(
         nullptr, &view_delegate_, nullptr,
-        SearchResultView::SearchResultViewType::kClassic, absl::nullopt);
+        SearchResultView::SearchResultViewType::kClassic, false, absl::nullopt);
     unified_view_->SetListType(
         SearchResultListView::SearchResultListType::kUnified);
 
     default_view_ = std::make_unique<SearchResultListView>(
         nullptr, &view_delegate_, nullptr,
-        SearchResultView::SearchResultViewType::kDefault, absl::nullopt);
+        SearchResultView::SearchResultViewType::kDefault, true, absl::nullopt);
     default_view_->SetListType(
         SearchResultListView::SearchResultListType::kBestMatch);
 
     answer_card_view_ = std::make_unique<SearchResultListView>(
         nullptr, &view_delegate_, nullptr,
-        SearchResultView::SearchResultViewType::kAnswerCard, absl::nullopt);
+        SearchResultView::SearchResultViewType::kAnswerCard, true,
+        absl::nullopt);
     answer_card_view_->SetListType(
         SearchResultListView::SearchResultListType::kAnswerCard);
 
diff --git a/ash/app_list/views/search_result_page_view.cc b/ash/app_list/views/search_result_page_view.cc
index d7dd14e..d7654e3 100644
--- a/ash/app_list/views/search_result_page_view.cc
+++ b/ash/app_list/views/search_result_page_view.cc
@@ -255,7 +255,8 @@
     search_result_list_view_ =
         AddSearchResultContainerView(std::make_unique<SearchResultListView>(
             app_list_main_view, view_delegate, dialog_controller_.get(),
-            SearchResultView::SearchResultViewType::kClassic, absl::nullopt));
+            SearchResultView::SearchResultViewType::kClassic,
+            /*animates_result_updates=*/false, absl::nullopt));
 
     search_box_view->SetResultSelectionController(
         result_selection_controller());
diff --git a/ash/app_list/views/search_result_tile_item_list_view.cc b/ash/app_list/views/search_result_tile_item_list_view.cc
index 47dd960..f369559 100644
--- a/ash/app_list/views/search_result_tile_item_list_view.cc
+++ b/ash/app_list/views/search_result_tile_item_list_view.cc
@@ -116,12 +116,6 @@
   return tile_views_[index];
 }
 
-int SearchResultTileItemListView::ScheduleResultAnimations(
-    int preceeding_results) {
-  NOTREACHED();
-  return -1;
-}
-
 int SearchResultTileItemListView::DoUpdate() {
   if (!GetWidget() || !GetWidget()->IsVisible() || !GetWidget()->IsActive()) {
     for (size_t i = 0; i < max_search_result_tiles_; ++i) {
diff --git a/ash/app_list/views/search_result_tile_item_list_view.h b/ash/app_list/views/search_result_tile_item_list_view.h
index fb85deb..ec25600 100644
--- a/ash/app_list/views/search_result_tile_item_list_view.h
+++ b/ash/app_list/views/search_result_tile_item_list_view.h
@@ -34,7 +34,6 @@
 
   // Overridden from SearchResultContainerView:
   SearchResultTileItemView* GetResultViewAt(size_t index) override;
-  int ScheduleResultAnimations(int preceeding_results) override;
 
   // Overridden from views::View:
   const char* GetClassName() const override;
diff --git a/ash/app_list/views/search_result_view.cc b/ash/app_list/views/search_result_view.cc
index f759b7b..960f303 100644
--- a/ash/app_list/views/search_result_view.cc
+++ b/ash/app_list/views/search_result_view.cc
@@ -239,6 +239,16 @@
 
 SearchResultView::~SearchResultView() = default;
 
+void SearchResultView::OnResultChanging(SearchResult* new_result) {
+  if (result_changed_)
+    return;
+  if (!new_result || !result()) {
+    result_changed_ = new_result;
+    return;
+  }
+  result_changed_ = new_result->id() != result()->id();
+}
+
 void SearchResultView::OnResultChanged() {
   OnMetadataChanged();
   // Update tile, separator, and details text visibility.
@@ -313,6 +323,12 @@
   }
 }
 
+bool SearchResultView::GetAndResetResultChanged() {
+  bool result_changed = result_changed_;
+  result_changed_ = false;
+  return result_changed;
+}
+
 void SearchResultView::UpdateDetailsText() {
   if (!result() || result()->details().empty()) {
     details_label_->SetText(std::u16string());
diff --git a/ash/app_list/views/search_result_view.h b/ash/app_list/views/search_result_view.h
index 73ccec3..0fd417bde 100644
--- a/ash/app_list/views/search_result_view.h
+++ b/ash/app_list/views/search_result_view.h
@@ -59,6 +59,7 @@
   ~SearchResultView() override;
 
   // Sets/gets SearchResult displayed by this view.
+  void OnResultChanging(SearchResult* new_result) override;
   void OnResultChanged() override;
 
   void SetSearchResultViewType(SearchResultViewType type);
@@ -66,6 +67,11 @@
 
   views::LayoutOrientation GetLayoutOrientationForTest();
 
+  // Returns whether the result has changed since this method was last called.
+  // Used to determine whether the result should be animated when the result
+  // list changes.
+  bool GetAndResetResultChanged();
+
  private:
   friend class test::SearchResultListViewTest;
   friend class SearchResultListView;
@@ -132,6 +138,11 @@
   views::Label* rating_ = nullptr;           // Owned by views hierarchy.
   views::ImageView* rating_star_ = nullptr;  // Owned by views hierarchy.
 
+  // Whether a result change was detected. This will be set only if the ID of
+  // the result shown by the view changes. Result will be considered unchanged
+  // if its metadata (e.g. icon, or text style tags) changes.
+  bool result_changed_ = false;
+
   // Whether the removal confirmation dialog is invoked by long press touch.
   bool confirm_remove_by_long_press_ = false;
 
diff --git a/ash/app_list/views/suggestion_chip_container_view.cc b/ash/app_list/views/suggestion_chip_container_view.cc
index c5274c3f..f039dea 100644
--- a/ash/app_list/views/suggestion_chip_container_view.cc
+++ b/ash/app_list/views/suggestion_chip_container_view.cc
@@ -178,12 +178,6 @@
   return "SuggestionChipContainerView";
 }
 
-int SuggestionChipContainerView::ScheduleResultAnimations(
-    int preceeding_results) {
-  NOTREACHED();
-  return -1;
-}
-
 void SuggestionChipContainerView::Layout() {
   // Only show the chips that fit in this view's contents bounds.
   int total_width = 0;
diff --git a/ash/app_list/views/suggestion_chip_container_view.h b/ash/app_list/views/suggestion_chip_container_view.h
index f2208ac..ca72ea6 100644
--- a/ash/app_list/views/suggestion_chip_container_view.h
+++ b/ash/app_list/views/suggestion_chip_container_view.h
@@ -29,7 +29,6 @@
   SearchResultSuggestionChipView* GetResultViewAt(size_t index) override;
   int DoUpdate() override;
   const char* GetClassName() const override;
-  int ScheduleResultAnimations(int preceeding_results) override;
 
   // views::View:
   void Layout() override;
diff --git a/ash/assistant/assistant_ui_controller_impl.cc b/ash/assistant/assistant_ui_controller_impl.cc
index 058817d..dd52807 100644
--- a/ash/assistant/assistant_ui_controller_impl.cc
+++ b/ash/assistant/assistant_ui_controller_impl.cc
@@ -14,7 +14,8 @@
 #include "ash/public/cpp/assistant/assistant_setup.h"
 #include "ash/public/cpp/assistant/assistant_state.h"
 #include "ash/public/cpp/assistant/controller/assistant_interaction_controller.h"
-#include "ash/public/cpp/toast_data.h"
+#include "ash/public/cpp/system/toast_catalog.h"
+#include "ash/public/cpp/system/toast_data.h"
 #include "ash/session/session_controller_impl.h"
 #include "ash/shell.h"
 #include "ash/strings/grit/ash_strings.h"
@@ -48,8 +49,10 @@
 constexpr char kUnboundServiceToastId[] =
     "assistant_controller_unbound_service";
 
-void ShowToast(const std::string& id, int message_id) {
-  ToastData toast(id, l10n_util::GetStringUTF16(message_id));
+void ShowToast(const std::string& id,
+               ToastCatalogName catalog_name,
+               int message_id) {
+  ToastData toast(id, catalog_name, l10n_util::GetStringUTF16(message_id));
   Shell::Get()->toast_manager()->Show(toast);
 }
 
@@ -112,12 +115,16 @@
   // TODO(dmblack): Show a more helpful message to the user.
   if (assistant_state->assistant_status() ==
       chromeos::assistant::AssistantStatus::NOT_READY) {
-    ShowToast(kUnboundServiceToastId, IDS_ASH_ASSISTANT_ERROR_GENERIC);
+    ShowToast(kUnboundServiceToastId,
+              ToastCatalogName::kAssistantUnboundService,
+              IDS_ASH_ASSISTANT_ERROR_GENERIC);
     return;
   }
 
   if (!assistant_) {
-    ShowToast(kUnboundServiceToastId, IDS_ASH_ASSISTANT_ERROR_GENERIC);
+    ShowToast(kUnboundServiceToastId,
+              ToastCatalogName::kAssistantUnboundService,
+              IDS_ASH_ASSISTANT_ERROR_GENERIC);
     return;
   }
 
@@ -255,7 +262,8 @@
   if (state != HighlighterEnabledState::kEnabled)
     return;
 
-  ShowToast(kStylusPromptToastId, IDS_ASH_ASSISTANT_PROMPT_STYLUS);
+  ShowToast(kStylusPromptToastId, ToastCatalogName::kStylusPrompt,
+            IDS_ASH_ASSISTANT_PROMPT_STYLUS);
   CloseUi(AssistantExitPoint::kStylus);
 }
 
diff --git a/ash/assistant/ui/base/assistant_button.cc b/ash/assistant/ui/base/assistant_button.cc
index 8d91740..f6ffbeb 100644
--- a/ash/assistant/ui/base/assistant_button.cc
+++ b/ash/assistant/ui/base/assistant_button.cc
@@ -26,7 +26,6 @@
 namespace {
 
 // Appearance.
-constexpr float kInkDropHighlightOpacity = 0.08f;
 constexpr int kInkDropInset = 2;
 
 }  // namespace
@@ -45,9 +44,6 @@
                                              base::Unretained(this))),
       listener_(listener),
       id_(button_id) {
-  constexpr SkColor kInkDropBaseColor = SK_ColorBLACK;
-  constexpr float kInkDropVisibleOpacity = 0.06f;
-
   // Avoid drawing default focus rings since Assistant buttons use
   // a custom highlight on focus.
   SetInstallFocusRingOnFocus(false);
@@ -60,8 +56,7 @@
   // Ink drop.
   views::InkDrop::Get(this)->SetMode(views::InkDropHost::InkDropMode::ON);
   SetHasInkDropActionOnClick(true);
-  views::InkDrop::Get(this)->SetBaseColor(kInkDropBaseColor);
-  views::InkDrop::Get(this)->SetVisibleOpacity(kInkDropVisibleOpacity);
+  UpdateInkDropColors();
   views::InstallCircleHighlightPathGenerator(this, gfx::Insets(kInkDropInset));
   views::InkDrop::UseInkDropForFloodFillRipple(views::InkDrop::Get(this));
   views::InkDrop::Get(this)->SetCreateHighlightCallback(base::BindRepeating(
@@ -69,7 +64,8 @@
         auto highlight = std::make_unique<views::InkDropHighlight>(
             gfx::SizeF(host->size()),
             views::InkDrop::Get(host)->GetBaseColor());
-        highlight->set_visible_opacity(kInkDropHighlightOpacity);
+        highlight->set_visible_opacity(
+            views::InkDrop::Get(host)->GetVisibleOpacity());
         return highlight;
       },
       this));
@@ -130,15 +126,15 @@
 void AssistantButton::OnBoundsChanged(const gfx::Rect& previous_bounds) {
   // Note that the current assumption is that button bounds are square.
   DCHECK_EQ(width(), height());
-  SetFocusPainter(views::Painter::CreateSolidRoundRectPainter(
-      SkColorSetA(views::InkDrop::Get(this)->GetBaseColor(),
-                  0xff * kInkDropHighlightOpacity),
-      width() / 2 - kInkDropInset, gfx::Insets(kInkDropInset)));
+  UpdateFocusPainter();
 }
 
 void AssistantButton::OnThemeChanged() {
   views::View::OnThemeChanged();
 
+  UpdateFocusPainter();
+  UpdateInkDropColors();
+
   if (!icon_color_type_.has_value() || !icon_description_.has_value())
     return;
 
@@ -154,6 +150,25 @@
   listener_->OnButtonPressed(id_);
 }
 
+void AssistantButton::UpdateFocusPainter() {
+  ScopedAssistantLightModeAsDefault scoped_assistant_light_mode_as_default;
+  std::pair<SkColor, float> base_color_and_opacity =
+      ColorProvider::Get()->GetInkDropBaseColorAndOpacity();
+  SetFocusPainter(views::Painter::CreateSolidRoundRectPainter(
+      SkColorSetA(base_color_and_opacity.first,
+                  0xff * base_color_and_opacity.second),
+      width() / 2 - kInkDropInset, gfx::Insets(kInkDropInset)));
+}
+
+void AssistantButton::UpdateInkDropColors() {
+  ScopedAssistantLightModeAsDefault scoped_assistant_light_mode_as_default;
+
+  std::pair<SkColor, float> base_color_and_opacity =
+      ColorProvider::Get()->GetInkDropBaseColorAndOpacity();
+  views::InkDrop::Get(this)->SetBaseColor(base_color_and_opacity.first);
+  views::InkDrop::Get(this)->SetVisibleOpacity(base_color_and_opacity.second);
+}
+
 BEGIN_METADATA(AssistantButton, views::ImageButton)
 END_METADATA
 
diff --git a/ash/assistant/ui/base/assistant_button.h b/ash/assistant/ui/base/assistant_button.h
index 3d6aaf6..c97cbdf 100644
--- a/ash/assistant/ui/base/assistant_button.h
+++ b/ash/assistant/ui/base/assistant_button.h
@@ -83,6 +83,8 @@
 
  private:
   void OnButtonPressed();
+  void UpdateFocusPainter();
+  void UpdateInkDropColors();
 
   AssistantButtonListener* listener_;
   const AssistantButtonId id_;
diff --git a/ash/assistant/ui/base/assistant_button_unittest.cc b/ash/assistant/ui/base/assistant_button_unittest.cc
index efb7914c..f46764a 100644
--- a/ash/assistant/ui/base/assistant_button_unittest.cc
+++ b/ash/assistant/ui/base/assistant_button_unittest.cc
@@ -21,18 +21,37 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "third_party/skia/include/core/SkColor.h"
+#include "ui/gfx/canvas.h"
 #include "ui/gfx/color_palette.h"
+#include "ui/gfx/geometry/insets.h"
 #include "ui/gfx/image/image_unittest_util.h"
 #include "ui/gfx/paint_vector_icon.h"
 #include "ui/gfx/vector_icon_types.h"
+#include "ui/views/animation/ink_drop.h"
 #include "ui/views/controls/button/button.h"
+#include "ui/views/painter.h"
+#include "ui/views/widget/widget.h"
 
 namespace ash {
 
 namespace {
 
 constexpr int kSizeInDip = 32;
-constexpr int kIconSizeInDip = 32;
+constexpr int kIconSizeInDip = 24;
+constexpr int kIconOffset = 4;
+constexpr int kInkDropInset = 2;
+
+SkBitmap CreateExpectedImageWithFocus(SkColor icon_color, SkColor focus_color) {
+  gfx::Canvas expected(gfx::Size(kSizeInDip, kSizeInDip), /*image_scale=*/1.0f,
+                       /*is_opaque=*/true);
+  expected.DrawImageInt(
+      gfx::CreateVectorIcon(kKeyboardIcon, kIconSizeInDip, icon_color),
+      kIconOffset, kIconOffset);
+  views::Painter::CreateSolidRoundRectPainter(
+      focus_color, kSizeInDip / 2 - kInkDropInset, gfx::Insets(kInkDropInset))
+      ->Paint(&expected, gfx::Size(kSizeInDip, kSizeInDip));
+  return expected.GetBitmap();
+}
 
 }  // namespace
 
@@ -112,4 +131,86 @@
            .bitmap(),
       *button->GetImage(views::Button::STATE_NORMAL).bitmap()));
 }
+
+TEST_F(AssistantButtonTest, FocusAndHoverColor) {
+  ASSERT_FALSE(features::IsDarkLightModeEnabled());
+
+  AssistantButton::InitParams params;
+  params.size_in_dip = kSizeInDip;
+  params.icon_size_in_dip = kIconSizeInDip;
+  params.accessible_name_id = IDS_ASH_ASSISTANT_DIALOG_PLATE_KEYBOARD_ACCNAME;
+  params.icon_color_type = ColorProvider::ContentLayerType::kIconColorPrimary;
+
+  std::unique_ptr<views::Widget> widget = CreateTestWidget();
+  AssistantButton* button =
+      widget->GetContentsView()->AddChildView(AssistantButton::Create(
+          nullptr, kKeyboardIcon, AssistantButtonId::kKeyboardInputToggle,
+          std::move(params)));
+  button->SizeToPreferredSize();
+
+  button->RequestFocus();
+  ASSERT_TRUE(button->HasFocus());
+
+  gfx::Canvas canvas(gfx::Size(kSizeInDip, kSizeInDip), /*image_scale=*/1.0f,
+                     /*is_opaque=*/true);
+  button->OnPaint(&canvas);
+  EXPECT_TRUE(gfx::test::AreBitmapsEqual(
+      CreateExpectedImageWithFocus(
+          /*icon_color=*/gfx::kGoogleGrey900,
+          /*focus_color=*/SkColorSetA(SK_ColorBLACK, 0xff * 0.06f)),
+      canvas.GetBitmap()));
+  EXPECT_EQ(views::InkDrop::Get(button)->GetBaseColor(), SK_ColorBLACK);
+  EXPECT_EQ(views::InkDrop::Get(button)->GetVisibleOpacity(), 0.06f);
+}
+
+TEST_F(AssistantButtonTest, FocusAndHoverColorDarkLightMode) {
+  base::test::ScopedFeatureList scoped_feature_list_enable_dark_light_mode(
+      chromeos::features::kDarkLightMode);
+  AshColorProvider::Get()->OnActiveUserPrefServiceChanged(
+      Shell::Get()->session_controller()->GetActivePrefService());
+  ASSERT_FALSE(ColorProvider::Get()->IsDarkModeEnabled());
+
+  AssistantButton::InitParams params;
+  params.size_in_dip = kSizeInDip;
+  params.icon_size_in_dip = kIconSizeInDip;
+  params.accessible_name_id = IDS_ASH_ASSISTANT_DIALOG_PLATE_KEYBOARD_ACCNAME;
+  params.icon_color_type = ColorProvider::ContentLayerType::kIconColorPrimary;
+
+  std::unique_ptr<views::Widget> widget = CreateTestWidget();
+  AssistantButton* button =
+      widget->GetContentsView()->AddChildView(AssistantButton::Create(
+          nullptr, kKeyboardIcon, AssistantButtonId::kKeyboardInputToggle,
+          std::move(params)));
+  button->SizeToPreferredSize();
+
+  button->RequestFocus();
+  ASSERT_TRUE(button->HasFocus());
+
+  gfx::Canvas canvas(gfx::Size(kSizeInDip, kSizeInDip), /*image_scale=*/1.0f,
+                     /*is_opaque=*/true);
+  button->OnPaint(&canvas);
+  EXPECT_TRUE(gfx::test::AreBitmapsEqual(
+      CreateExpectedImageWithFocus(
+          /*icon_color=*/gfx::kGoogleGrey900,
+          /*focus_color=*/SkColorSetA(SK_ColorBLACK, 0xff * 0.06f)),
+      canvas.GetBitmap()));
+  EXPECT_EQ(views::InkDrop::Get(button)->GetBaseColor(), SK_ColorBLACK);
+  EXPECT_EQ(views::InkDrop::Get(button)->GetVisibleOpacity(), 0.06f);
+
+  // Switch to dark mode
+  Shell::Get()->session_controller()->GetActivePrefService()->SetBoolean(
+      prefs::kDarkModeEnabled, true);
+  ASSERT_TRUE(ColorProvider::Get()->IsDarkModeEnabled());
+
+  canvas.RecreateBackingCanvas(gfx::Size(kSizeInDip, kSizeInDip),
+                               /*image_scale=*/1.0f, /*is_opaque=*/true);
+  button->OnPaint(&canvas);
+  EXPECT_TRUE(gfx::test::AreBitmapsEqual(
+      CreateExpectedImageWithFocus(
+          /*icon_color=*/gfx::kGoogleGrey200,
+          /*focus_color=*/SkColorSetA(SK_ColorWHITE, 0xff * 0.08f)),
+      canvas.GetBitmap()));
+  EXPECT_EQ(views::InkDrop::Get(button)->GetBaseColor(), SK_ColorWHITE);
+  EXPECT_EQ(views::InkDrop::Get(button)->GetVisibleOpacity(), 0.08f);
+}
 }  // namespace ash
diff --git a/ash/components/arc/compat_mode/resize_util.cc b/ash/components/arc/compat_mode/resize_util.cc
index ba6c140..d2b27ab 100644
--- a/ash/components/arc/compat_mode/resize_util.cc
+++ b/ash/components/arc/compat_mode/resize_util.cc
@@ -11,8 +11,9 @@
 #include "ash/components/arc/compat_mode/metrics.h"
 #include "ash/components/arc/compat_mode/resize_confirmation_dialog_view.h"
 #include "ash/public/cpp/arc_resize_lock_type.h"
-#include "ash/public/cpp/toast_data.h"
-#include "ash/public/cpp/toast_manager.h"
+#include "ash/public/cpp/system/toast_catalog.h"
+#include "ash/public/cpp/system/toast_data.h"
+#include "ash/public/cpp/system/toast_manager.h"
 #include "ash/public/cpp/window_properties.h"
 #include "base/callback_forward.h"
 #include "base/callback_helpers.h"
@@ -118,7 +119,7 @@
       "arc.compat_mode.turn_off_resize_lock";
   toast_manager->Cancel(kTurnOffResizeLockToastId);
   ash::ToastData toast(
-      kTurnOffResizeLockToastId,
+      kTurnOffResizeLockToastId, ash::ToastCatalogName::kAppResizable,
       l10n_util::GetStringUTF16(IDS_ARC_COMPAT_MODE_DISABLE_RESIZE_LOCK_TOAST));
   toast_manager->Show(toast);
 }
diff --git a/ash/components/arc/compat_mode/resize_util_unittest.cc b/ash/components/arc/compat_mode/resize_util_unittest.cc
index f83bd302b2..7304be8 100644
--- a/ash/components/arc/compat_mode/resize_util_unittest.cc
+++ b/ash/components/arc/compat_mode/resize_util_unittest.cc
@@ -7,7 +7,7 @@
 #include <memory>
 
 #include "ash/components/arc/compat_mode/test/compat_mode_test_base.h"
-#include "ash/public/cpp/toast_manager.h"
+#include "ash/public/cpp/system/toast_manager.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/views/widget/widget.h"
 #include "ui/views/widget/widget_delegate.h"
diff --git a/ash/components/arc/mojom/metrics.mojom b/ash/components/arc/mojom/metrics.mojom
index 794bdb1..cf6dd4cd 100644
--- a/ash/components/arc/mojom/metrics.mojom
+++ b/ash/components/arc/mojom/metrics.mojom
@@ -1,7 +1,7 @@
 // Copyright 2016 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
-// Next MinVersion: 22
+// Next MinVersion: 23
 
 module arc.mojom;
 
@@ -155,6 +155,9 @@
   [MinVersion=17] kWifiManagerEnableTdls = 33,
   [MinVersion=17] kWifiManagerStartLocalHotspot = 34,
   [MinVersion=17] kWifiManagerAddPasspointConfiguration = 35,
+  [MinVersion=19] kAndroidIpsecIke2VpnConnection = 36,
+  [MinVersion=22] kAndroidVpnIpv6Provisioned = 37,
+  [MinVersion=22] kAndroidVpnIpv4Provisioned = 38,
 };
 
 // These enum values are persisted to metrics thus must be treated as
diff --git a/ash/components/arc/mojom/video.mojom b/ash/components/arc/mojom/video.mojom
index d45c414..8bb5eca 100644
--- a/ash/components/arc/mojom/video.mojom
+++ b/ash/components/arc/mojom/video.mojom
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// Next MinVersion: 9
+// Next MinVersion: 10
 
 module arc.mojom;
 
@@ -60,7 +60,7 @@
            protected_buffer_manager);
 
   // Create a new |video_decoder| instance.
-  [MinVersion=8]
+  [MinVersion=9]
   CreateVideoDecoder@4(
       pending_receiver<VideoDecoder> video_decoder);
 
diff --git a/ash/components/login/auth/cryptohome_authenticator.cc b/ash/components/login/auth/cryptohome_authenticator.cc
index e690353..fd4d818 100644
--- a/ash/components/login/auth/cryptohome_authenticator.cc
+++ b/ash/components/login/auth/cryptohome_authenticator.cc
@@ -31,6 +31,7 @@
 #include "chromeos/metrics/login_event_recorder.h"
 #include "components/account_id/account_id.h"
 #include "components/device_event_log/device_event_log.h"
+#include "components/prefs/pref_service.h"
 #include "components/user_manager/known_user.h"
 #include "components/user_manager/user_names.h"
 #include "components/user_manager/user_type.h"
@@ -461,19 +462,13 @@
 
 CryptohomeAuthenticator::CryptohomeAuthenticator(
     scoped_refptr<base::SequencedTaskRunner> task_runner,
+    PrefService* local_state,
     std::unique_ptr<SafeModeDelegate> safe_mode_delegate,
     AuthStatusConsumer* consumer)
     : Authenticator(consumer),
       task_runner_(std::move(task_runner)),
+      local_state_(local_state),
       safe_mode_delegate_(std::move(safe_mode_delegate)),
-      migrate_attempted_(false),
-      remove_attempted_(false),
-      resync_attempted_(false),
-      ephemeral_mount_attempted_(false),
-      already_reported_success_(false),
-      owner_is_verified_(false),
-      user_can_login_(false),
-      remove_user_data_on_failure_(false),
       delayed_login_failure_(AuthFailure::NONE) {}
 
 void CryptohomeAuthenticator::AuthenticateToLogin(
@@ -503,11 +498,12 @@
 
   // Reset the verified flag.
   owner_is_verified_ = false;
-  if (!user_manager::known_user::FindPrefs(
-          current_state_->user_context->GetAccountId(), nullptr)) {
-    // Save logged in user into local state as early as possible.
-    user_manager::known_user::SaveKnownUser(
-        current_state_->user_context->GetAccountId());
+  if (local_state_.get()) {
+    user_manager::KnownUser known_user(local_state_);
+    if (!known_user.UserExists(current_state_->user_context->GetAccountId())) {
+      // Save logged in user into local state as early as possible.
+      known_user.SaveKnownUser(current_state_->user_context->GetAccountId());
+    }
   }
 
   StartMount(current_state_->AsWeakPtr(),
diff --git a/ash/components/login/auth/cryptohome_authenticator.h b/ash/components/login/auth/cryptohome_authenticator.h
index fb9a1f0..22213eb 100644
--- a/ash/components/login/auth/cryptohome_authenticator.h
+++ b/ash/components/login/auth/cryptohome_authenticator.h
@@ -15,6 +15,7 @@
 #include "base/compiler_specific.h"
 #include "base/component_export.h"
 #include "base/gtest_prod_util.h"
+#include "base/memory/raw_ptr.h"
 #include "base/synchronization/lock.h"
 #include "base/task/sequenced_task_runner.h"
 #include "chromeos/dbus/cryptohome/UserDataAuth.pb.h"
@@ -22,6 +23,7 @@
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 class AuthFailure;
+class PrefService;
 
 namespace ash {
 
@@ -98,6 +100,7 @@
   };
 
   CryptohomeAuthenticator(scoped_refptr<base::SequencedTaskRunner> task_runner,
+                          PrefService* local_state,
                           std::unique_ptr<SafeModeDelegate> safe_mode_delegate,
                           AuthStatusConsumer* consumer);
 
@@ -232,28 +235,30 @@
 
   scoped_refptr<base::SequencedTaskRunner> task_runner_;
 
+  const base::raw_ptr<PrefService> local_state_;
+
   std::unique_ptr<SafeModeDelegate> safe_mode_delegate_;
 
   std::unique_ptr<AuthAttemptState> current_state_;
-  bool migrate_attempted_;
-  bool remove_attempted_;
-  bool resync_attempted_;
-  bool ephemeral_mount_attempted_;
+  bool migrate_attempted_ = false;
+  bool remove_attempted_ = false;
+  bool resync_attempted_ = false;
+  bool ephemeral_mount_attempted_ = false;
 
   // When the user has changed their password, but gives us the old one, we will
   // be able to mount their cryptohome, but online authentication will fail.
   // This allows us to present the same behavior to the caller, regardless
   // of the order in which we receive these results.
-  bool already_reported_success_;
+  bool already_reported_success_ = false;
   base::Lock success_lock_;  // A lock around |already_reported_success_|.
 
   // Flags signaling whether the owner verification has been done and the result
   // of it.
-  bool owner_is_verified_;
-  bool user_can_login_;
+  bool owner_is_verified_ = false;
+  bool user_can_login_ = false;
 
   // Flag indicating to delete the user's cryptohome the login fails.
-  bool remove_user_data_on_failure_;
+  bool remove_user_data_on_failure_ = false;
 
   // When |remove_user_data_on_failure_| is set, we delay calling
   // consumer_->OnAuthFailure() until we removed the user cryptohome.
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc
index 78b362c..6c05a8e 100644
--- a/ash/constants/ash_features.cc
+++ b/ash/constants/ash_features.cc
@@ -1041,16 +1041,12 @@
 const base::Feature kProjectorManagedUser{"ProjectorManagedUser",
                                           base::FEATURE_DISABLED_BY_DEFAULT};
 
-// Controls whether to enable Projector in status tray.
-const base::Feature kProjectorFeaturePod{"ProjectorFeaturePod",
-                                         base::FEATURE_DISABLED_BY_DEFAULT};
-
 // Controls whether to enable Projector annotator or marker tools.
 // The annotator tools are newer and based on the ink library.
 // The marker tools are older and based on fast ink.
 // We are deprecating the old marker tools in favor of the annotator tools.
 const base::Feature kProjectorAnnotator{"ProjectorAnnotator",
-                                        base::FEATURE_ENABLED_BY_DEFAULT};
+                                        base::FEATURE_DISABLED_BY_DEFAULT};
 
 // Controls whether the quick dim prototype is enabled.
 const base::Feature kQuickDim{"QuickDim", base::FEATURE_DISABLED_BY_DEFAULT};
@@ -1797,11 +1793,6 @@
   return base::FeatureList::IsEnabled(kProjectorManagedUser);
 }
 
-bool IsProjectorFeaturePodEnabled() {
-  return IsProjectorEnabled() &&
-         base::FeatureList::IsEnabled(kProjectorFeaturePod);
-}
-
 bool IsProjectorAnnotatorEnabled() {
   return IsProjectorEnabled() &&
          base::FeatureList::IsEnabled(kProjectorAnnotator);
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h
index a84c789..eae593c 100644
--- a/ash/constants/ash_features.h
+++ b/ash/constants/ash_features.h
@@ -396,7 +396,6 @@
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kProjector;
 COMPONENT_EXPORT(ASH_CONSTANTS)
 extern const base::Feature kProjectorManagedUser;
-COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kProjectorFeaturePod;
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kProjectorAnnotator;
 COMPONENT_EXPORT(ASH_CONSTANTS)
 extern const base::Feature kQuickDim;
diff --git a/ash/login/login_screen_controller.cc b/ash/login/login_screen_controller.cc
index 06f3ade..d8daa31c 100644
--- a/ash/login/login_screen_controller.cc
+++ b/ash/login/login_screen_controller.cc
@@ -13,7 +13,8 @@
 #include "ash/login/ui/login_data_dispatcher.h"
 #include "ash/public/cpp/child_accounts/parent_access_controller.h"
 #include "ash/public/cpp/login_screen_client.h"
-#include "ash/public/cpp/toast_data.h"
+#include "ash/public/cpp/system/toast_catalog.h"
+#include "ash/public/cpp/system/toast_data.h"
 #include "ash/root_window_controller.h"
 #include "ash/session/session_controller_impl.h"
 #include "ash/shelf/login_shelf_view.h"
@@ -291,8 +292,8 @@
 }
 
 void LoginScreenController::ShowKioskAppError(const std::string& message) {
-  ToastData toast_data("KioskAppError", base::UTF8ToUTF16(message),
-                       ToastData::kInfiniteDuration,
+  ToastData toast_data("KioskAppError", ToastCatalogName::kKioskAppError,
+                       base::UTF8ToUTF16(message), ToastData::kInfiniteDuration,
                        /*visible_on_lock_screen=*/true);
   Shell::Get()->toast_manager()->Show(toast_data);
 }
diff --git a/ash/projector/projector_controller_unittest.cc b/ash/projector/projector_controller_unittest.cc
index 73703b5..52939f5 100644
--- a/ash/projector/projector_controller_unittest.cc
+++ b/ash/projector/projector_controller_unittest.cc
@@ -12,6 +12,7 @@
 #include "ash/components/audio/cras_audio_handler.h"
 #include "ash/constants/ash_features.h"
 #include "ash/projector/model/projector_session_impl.h"
+#include "ash/projector/projector_metadata_controller.h"
 #include "ash/projector/projector_metrics.h"
 #include "ash/projector/test/mock_projector_client.h"
 #include "ash/projector/test/mock_projector_metadata_controller.h"
@@ -19,6 +20,8 @@
 #include "ash/public/cpp/projector/projector_new_screencast_precondition.h"
 #include "ash/public/cpp/projector/projector_session.h"
 #include "ash/test/ash_test_base.h"
+#include "base/bind.h"
+#include "base/callback_forward.h"
 #include "base/files/file_path.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/json/json_writer.h"
@@ -29,6 +32,7 @@
 #include "base/values.h"
 #include "chromeos/dbus/audio/audio_node.h"
 #include "chromeos/dbus/audio/fake_cras_audio_client.h"
+#include "media/mojo/mojom/speech_recognition_result.h"
 #include "media/mojo/mojom/speech_recognition_service.mojom.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/core/SkColor.h"
@@ -49,6 +53,11 @@
 constexpr char kProjectorCreationFlowHistogramName[] =
     "Ash.Projector.CreationFlow.ClamshellMode";
 
+constexpr char kProjectorTranscriptsCountHistogramName[] =
+    "Ash.Projector.TranscriptsCount.ClamshellMode";
+
+constexpr char kFilePath[] = "random/file/path";
+
 void NotifyControllerForFinalSpeechResult(ProjectorControllerImpl* controller) {
   media::SpeechRecognitionResult result;
   result.transcription = "transcript text 1";
@@ -76,12 +85,40 @@
       media::SpeechRecognitionResult("transcript partial text 1", false));
 }
 
+class ProjectorMetadataControllerForTest : public ProjectorMetadataController {
+ public:
+  ProjectorMetadataControllerForTest() = default;
+  ProjectorMetadataControllerForTest(
+      const ProjectorMetadataControllerForTest&) = delete;
+  ProjectorMetadataControllerForTest& operator=(
+      const ProjectorMetadataControllerForTest&) = delete;
+  ~ProjectorMetadataControllerForTest() override = default;
+
+  void SetRunLoopQuitClosure(base::RepeatingClosure closure) {
+    quit_closure_ = base::BindOnce(closure);
+  }
+
+ protected:
+  // ProjectorMetadataController:
+  void OnSaveFileResult(const base::FilePath& path,
+                        size_t transcripts_count,
+                        bool success) override {
+    ProjectorMetadataController::OnSaveFileResult(path, transcripts_count,
+                                                  success);
+    std::move(quit_closure_).Run();
+  }
+
+ private:
+  base::OnceClosure quit_closure_;
+};
+
 }  // namespace
 
 class ProjectorControllerTest : public AshTestBase {
  public:
   ProjectorControllerTest()
-      : AshTestBase(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {
+      : AshTestBase(base::test::TaskEnvironment::TimeSource::MOCK_TIME),
+        file_path_(kFilePath) {
     scoped_feature_list_.InitWithFeatures(
         {features::kProjector, features::kProjectorAnnotator}, {});
   }
@@ -112,12 +149,23 @@
         SpeechRecognitionAvailability::kAvailable);
   }
 
+  void InitializeRealMetadataController() {
+    std::unique_ptr<ProjectorMetadataController> metadata_controller =
+        std::make_unique<ProjectorMetadataControllerForTest>();
+    metadata_controller_ = static_cast<ProjectorMetadataControllerForTest*>(
+        metadata_controller.get());
+    controller_->SetProjectorMetadataControllerForTest(
+        std::move(metadata_controller));
+  }
+
  protected:
   MockProjectorUiController* mock_ui_controller_ = nullptr;
   MockProjectorMetadataController* mock_metadata_controller_ = nullptr;
+  ProjectorMetadataControllerForTest* metadata_controller_;
   ProjectorControllerImpl* controller_;
   MockProjectorClient mock_client_;
   base::HistogramTester histogram_tester_;
+  base::FilePath file_path_;
 
  private:
   base::test::ScopedFeatureList scoped_feature_list_;
@@ -249,13 +297,15 @@
         // with the expected path.
         const std::string expected_screencast_name =
             "Screencast 2021-01-02 20.02.10";
-        EXPECT_CALL(*mock_metadata_controller_,
-                    SaveMetadata(screencast_container_path.Append("root")
-                                     .Append("projector_data")
-                                     // Screencast container folder.
-                                     .Append(expected_screencast_name)
-                                     // Screencast file name without extension.
-                                     .Append(expected_screencast_name)));
+        const base::FilePath expected_path =
+            screencast_container_path.Append("root")
+                .Append("projector_data")
+                // Screencast container folder.
+                .Append(expected_screencast_name)
+                // Screencast file name without extension.
+                .Append(expected_screencast_name);
+        EXPECT_EQ(screencast_file_path_no_extension, expected_path);
+        EXPECT_CALL(*mock_metadata_controller_, SaveMetadata(expected_path));
 
         controller_->OnRecordingEnded(/*is_in_projector_mode=*/true);
         runLoop.Quit();
@@ -272,4 +322,39 @@
   histogram_tester_.ExpectTotalCount(kProjectorCreationFlowHistogramName,
                                      /*count=*/4);
 }
+
+TEST_F(ProjectorControllerTest, NoTranscriptsTest) {
+  InitializeRealMetadataController();
+  metadata_controller_->OnRecordingStarted();
+
+  base::RunLoop run_loop;
+  metadata_controller_->SetRunLoopQuitClosure(run_loop.QuitClosure());
+
+  // Simulate ending the recording and saving the metadata file.
+  metadata_controller_->SaveMetadata(file_path_);
+  run_loop.Run();
+
+  histogram_tester_.ExpectUniqueSample(kProjectorTranscriptsCountHistogramName,
+                                       /*sample=*/0, /*count=*/1);
+}
+
+TEST_F(ProjectorControllerTest, TranscriptsTest) {
+  InitializeRealMetadataController();
+  metadata_controller_->OnRecordingStarted();
+
+  base::RunLoop run_loop;
+  metadata_controller_->SetRunLoopQuitClosure(run_loop.QuitClosure());
+
+  // Simulate adding some transcripts.
+  NotifyControllerForFinalSpeechResult(controller_);
+  NotifyControllerForFinalSpeechResult(controller_);
+
+  // Simulate ending the recording and saving the metadata file.
+  metadata_controller_->SaveMetadata(file_path_);
+  run_loop.Run();
+
+  histogram_tester_.ExpectUniqueSample(kProjectorTranscriptsCountHistogramName,
+                                       /*sample=*/2, /*count=*/1);
+}
+
 }  // namespace ash
diff --git a/ash/projector/projector_metadata_controller.cc b/ash/projector/projector_metadata_controller.cc
index efa54d3..3b3e673 100644
--- a/ash/projector/projector_metadata_controller.cc
+++ b/ash/projector/projector_metadata_controller.cc
@@ -4,11 +4,11 @@
 
 #include "ash/projector/projector_metadata_controller.h"
 
+#include "ash/projector/projector_metrics.h"
 #include "ash/projector/projector_ui_controller.h"
 #include "ash/public/cpp/projector/projector_controller.h"
 #include "ash/strings/grit/ash_strings.h"
 #include "base/bind.h"
-#include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
 #include "base/strings/utf_string_conversions.h"
@@ -81,16 +81,21 @@
   base::ThreadPool::PostTaskAndReplyWithResult(
       FROM_HERE, {base::MayBlock()},
       base::BindOnce(&SaveFile, metadata_str, path),
-      base::BindOnce(
-          [](const base::FilePath& path, bool success) {
-            if (!success) {
-              LOG(ERROR) << "Failed to save the metadata file: " << path;
-              ProjectorUiController::ShowFailureNotification(
-                  IDS_ASH_PROJECTOR_FAILURE_MESSAGE_SAVE_SCREENCAST);
-              return;
-            }
-          },
-          path));
+      base::BindOnce(&ProjectorMetadataController::OnSaveFileResult,
+                     weak_factory_.GetWeakPtr(), path,
+                     metadata_->GetTranscriptsCount()));
+}
+
+void ProjectorMetadataController::OnSaveFileResult(const base::FilePath& path,
+                                                   size_t transcripts_count,
+                                                   bool success) {
+  if (!success) {
+    LOG(ERROR) << "Failed to save the metadata file: " << path;
+    ProjectorUiController::ShowFailureNotification(
+        IDS_ASH_PROJECTOR_FAILURE_MESSAGE_SAVE_SCREENCAST);
+    return;
+  }
+  RecordTranscriptsCount(transcripts_count);
 }
 
 void ProjectorMetadataController::SetProjectorMetadataModelForTest(
diff --git a/ash/projector/projector_metadata_controller.h b/ash/projector/projector_metadata_controller.h
index 35406e6..ae398d1 100644
--- a/ash/projector/projector_metadata_controller.h
+++ b/ash/projector/projector_metadata_controller.h
@@ -10,6 +10,7 @@
 
 #include "ash/ash_export.h"
 #include "ash/projector/projector_metadata_model.h"
+#include "base/files/file_path.h"
 #include "base/memory/weak_ptr.h"
 #include "media/mojo/mojom/speech_recognition_service.mojom.h"
 
@@ -43,6 +44,12 @@
   void SetProjectorMetadataModelForTest(
       std::unique_ptr<ProjectorMetadata> metadata);
 
+ protected:
+  // Triggered after finish saving the metadata file.
+  virtual void OnSaveFileResult(const base::FilePath& path,
+                                size_t transcripts_count,
+                                bool success);
+
  private:
   std::unique_ptr<ProjectorMetadata> metadata_;
 
diff --git a/ash/projector/projector_metadata_model.h b/ash/projector/projector_metadata_model.h
index 51be41da..d3eaba7 100644
--- a/ash/projector/projector_metadata_model.h
+++ b/ash/projector/projector_metadata_model.h
@@ -96,6 +96,8 @@
   void MarkKeyIdea();
   // Serializes the metadata for storage.
   std::string Serialize();
+  // Returns the number of transcripts.
+  size_t GetTranscriptsCount() const { return transcripts_.size(); }
 
  private:
   base::Value ToJson();
diff --git a/ash/projector/projector_metrics.cc b/ash/projector/projector_metrics.cc
index c17fd4f..be50b81 100644
--- a/ash/projector/projector_metrics.cc
+++ b/ash/projector/projector_metrics.cc
@@ -19,6 +19,9 @@
 constexpr char kProjectorCreationFlowHistogramName[] =
     "Ash.Projector.CreationFlow";
 
+constexpr char kProjectorTranscriptsCountHistogramName[] =
+    "Ash.Projector.TranscriptsCount";
+
 // Appends the proper suffix to |prefix| based on whether the user is in tablet
 // mode or not.
 std::string GetHistogramName(const std::string& prefix) {
@@ -44,4 +47,11 @@
       GetHistogramName(kProjectorCreationFlowHistogramName), step);
 }
 
+void RecordTranscriptsCount(size_t count) {
+  // We don't expect most screencasts to exceed 10,000 transcripts. If this
+  // limit is exceeded, then the metric would fall into an overflow bucket.
+  base::UmaHistogramCounts10000(
+      GetHistogramName(kProjectorTranscriptsCountHistogramName), count);
+}
+
 }  // namespace ash
diff --git a/ash/projector/projector_metrics.h b/ash/projector/projector_metrics.h
index 324b078e..d4e6364 100644
--- a/ash/projector/projector_metrics.h
+++ b/ash/projector/projector_metrics.h
@@ -5,6 +5,8 @@
 #ifndef ASH_PROJECTOR_PROJECTOR_METRICS_H_
 #define ASH_PROJECTOR_PROJECTOR_METRICS_H_
 
+#include <cstddef>
+
 namespace ash {
 
 // These enum values represent buttons on the Projector toolbar and log to UMA.
@@ -79,6 +81,9 @@
 // Records the user's progress in the Projector creation flow.
 void RecordCreationFlowMetrics(ProjectorCreationFlow step);
 
+// Records the number of transcripts generated during a screencast recording.
+void RecordTranscriptsCount(size_t count);
+
 }  // namespace ash
 
 #endif  // ASH_PROJECTOR_PROJECTOR_METRICS_H_
diff --git a/ash/projector/projector_ui_controller.cc b/ash/projector/projector_ui_controller.cc
index dc2d366..00fa657a 100644
--- a/ash/projector/projector_ui_controller.cc
+++ b/ash/projector/projector_ui_controller.cc
@@ -13,7 +13,7 @@
 #include "ash/projector/projector_metrics.h"
 #include "ash/public/cpp/notification_utils.h"
 #include "ash/public/cpp/projector/projector_annotator_controller.h"
-#include "ash/public/cpp/toast_data.h"
+#include "ash/public/cpp/system/toast_data.h"
 #include "ash/public/cpp/window_properties.h"
 #include "ash/resources/vector_icons/vector_icons.h"
 #include "ash/root_window_controller.h"
diff --git a/ash/public/cpp/BUILD.gn b/ash/public/cpp/BUILD.gn
index b5b5bd5..7e1107f 100644
--- a/ash/public/cpp/BUILD.gn
+++ b/ash/public/cpp/BUILD.gn
@@ -292,6 +292,11 @@
     "style/color_provider.h",
     "stylus_utils.cc",
     "stylus_utils.h",
+    "system/toast_catalog.h",
+    "system/toast_data.cc",
+    "system/toast_data.h",
+    "system/toast_manager.cc",
+    "system/toast_manager.h",
     "system_tray.cc",
     "system_tray.h",
     "system_tray_client.h",
@@ -309,10 +314,6 @@
     "tablet_mode.cc",
     "tablet_mode.h",
     "tablet_mode_observer.h",
-    "toast_data.cc",
-    "toast_data.h",
-    "toast_manager.cc",
-    "toast_manager.h",
     "update_types.h",
     "view_shadow.cc",
     "view_shadow.h",
diff --git a/ash/public/cpp/accessibility_controller.h b/ash/public/cpp/accessibility_controller.h
index b746e1a1..f45a829 100644
--- a/ash/public/cpp/accessibility_controller.h
+++ b/ash/public/cpp/accessibility_controller.h
@@ -23,6 +23,7 @@
 class AccessibilityControllerClient;
 enum class AccessibilityPanelState;
 enum class DictationToggleSource;
+enum class DictationBubbleIconType;
 class SelectToSpeakEventHandlerDelegate;
 enum class SelectToSpeakState;
 
@@ -188,6 +189,7 @@
   // clear the bubble's text.
   virtual void UpdateDictationBubble(
       bool visible,
+      DictationBubbleIconType icon,
       const absl::optional<std::u16string>& text) = 0;
 
  protected:
diff --git a/ash/public/cpp/accessibility_controller_enums.h b/ash/public/cpp/accessibility_controller_enums.h
index 3d0c51d..f2b2c8b 100644
--- a/ash/public/cpp/accessibility_controller_enums.h
+++ b/ash/public/cpp/accessibility_controller_enums.h
@@ -198,6 +198,15 @@
   kMaxValue = kEdge
 };
 
+// The icon shown in the Dictation bubble UI. This enum should be kept in sync
+// with chrome.accessibilityPrivate.DictationBubbleIconType.
+enum class DictationBubbleIconType {
+  kHidden,
+  kStandby,
+  kMacroSuccess,
+  kMacroFail,
+};
+
 }  // namespace ash
 
 #endif  // ASH_PUBLIC_CPP_ACCESSIBILITY_CONTROLLER_ENUMS_H_
diff --git a/ash/public/cpp/app_list/app_list_types.cc b/ash/public/cpp/app_list/app_list_types.cc
index 3d5041d..05dda941 100644
--- a/ash/public/cpp/app_list/app_list_types.cc
+++ b/ash/public/cpp/app_list/app_list_types.cc
@@ -219,22 +219,22 @@
 
 SearchResultTextItem::~SearchResultTextItem() = default;
 
-SearchResultTextItemType SearchResultTextItem::GetType() {
+SearchResultTextItemType SearchResultTextItem::GetType() const {
   return item_type;
 }
 
-const std::string& SearchResultTextItem::GetText() {
+const std::u16string& SearchResultTextItem::GetText() const {
   DCHECK_EQ(item_type, SearchResultTextItemType::kString);
   return raw_text.value();
 }
 
-SearchResultTextItem& SearchResultTextItem::SetText(std::string text) {
+SearchResultTextItem& SearchResultTextItem::SetText(std::u16string text) {
   DCHECK_EQ(item_type, SearchResultTextItemType::kString);
   raw_text = text;
   return *this;
 }
 
-const SearchResultTags& SearchResultTextItem::GetTextTags() {
+const SearchResultTags& SearchResultTextItem::GetTextTags() const {
   DCHECK_EQ(item_type, SearchResultTextItemType::kString);
   return text_tags.value();
 }
@@ -245,7 +245,7 @@
   return *this;
 }
 
-gfx::ImageSkia SearchResultTextItem::GetIconFromCode() {
+gfx::ImageSkia SearchResultTextItem::GetIconFromCode() const {
   DCHECK_EQ(item_type, SearchResultTextItemType::kIconCode);
   return gfx::ImageSkia();
 }
@@ -256,7 +256,7 @@
   return *this;
 }
 
-gfx::ImageSkia SearchResultTextItem::GetIcon() {
+gfx::ImageSkia SearchResultTextItem::GetIcon() const {
   DCHECK_EQ(item_type, SearchResultTextItemType::kCustomIcon);
   return raw_icon.value();
 }
diff --git a/ash/public/cpp/app_list/app_list_types.h b/ash/public/cpp/app_list/app_list_types.h
index 96cd4134..3c57ba284 100644
--- a/ash/public/cpp/app_list/app_list_types.h
+++ b/ash/public/cpp/app_list/app_list_types.h
@@ -393,6 +393,8 @@
     URL = 1 << 0,
     MATCH = 1 << 1,
     DIM = 1 << 2,
+    GREEN = 1 << 3,
+    RED = 1 << 4,
   };
 
   SearchResultTag();
@@ -432,24 +434,24 @@
   SearchResultTextItem& operator=(const SearchResultTextItem&);
   ~SearchResultTextItem();
 
-  SearchResultTextItemType GetType();
+  SearchResultTextItemType GetType() const;
 
-  const std::string& GetText();
-  SearchResultTextItem& SetText(std::string text);
+  const std::u16string& GetText() const;
+  SearchResultTextItem& SetText(std::u16string text);
 
-  const SearchResultTags& GetTextTags();
+  const SearchResultTags& GetTextTags() const;
   SearchResultTextItem& SetTextTags(SearchResultTags tags);
 
-  gfx::ImageSkia GetIconFromCode();
+  gfx::ImageSkia GetIconFromCode() const;
   SearchResultTextItem& SetIconCode(int icon_code);
 
-  gfx::ImageSkia GetIcon();
+  gfx::ImageSkia GetIcon() const;
   SearchResultTextItem& SetIcon(gfx::ImageSkia icon);
 
  private:
   SearchResultTextItemType item_type;
   // used for type SearchResultTextItemType::kString.
-  absl::optional<std::string> raw_text;
+  absl::optional<std::u16string> raw_text;
   absl::optional<SearchResultTags> text_tags;
   // used for type SearchResultTextItemType::kIconCode.
   absl::optional<int> icon_code;
diff --git a/ash/public/cpp/system/OWNERS b/ash/public/cpp/system/OWNERS
new file mode 100644
index 0000000..451ae4a
--- /dev/null
+++ b/ash/public/cpp/system/OWNERS
@@ -0,0 +1,6 @@
+file://ash/system/OWNERS
+
+kradtke@chromium.org
+
+per-file *catalog.h=set noparent
+per-file *catalog.h=file://chromeos/SECURITY_OWNERS
\ No newline at end of file
diff --git a/ash/public/cpp/system/toast_catalog.h b/ash/public/cpp/system/toast_catalog.h
new file mode 100644
index 0000000..33c92c2
--- /dev/null
+++ b/ash/public/cpp/system/toast_catalog.h
@@ -0,0 +1,54 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_PUBLIC_CPP_SYSTEM_TOAST_CATALOG_H_
+#define ASH_PUBLIC_CPP_SYSTEM_TOAST_CATALOG_H_
+
+namespace ash {
+
+// A living catalog that registers Toast notifiers.
+// CatalogNames can be shared between semantically similar notifiers, but opt
+// for unique names when possible for more specific identification and metrics.
+// TODO(crbug/1287561): Implement metrics for toasts using their CatalogNames.
+// New enumerators can be added to the end, but existing items must not be
+// removed or reordered.
+enum class ToastCatalogName {
+  kVirtualDesksLimitMax = 0,
+  kVirtualDesksLimitMin,
+  kAssistantError,
+  kDebugCommand,
+  kAssistantUnboundService,
+  kStylusPrompt,
+  kAppResizable,
+  kKioskAppError,
+  kBluetoothDevicePaired,
+  kBluetoothDeviceDisconnected,
+  kBluetoothDeviceConnected,
+  kBluetoothAdapterDiscoverable,
+  kEncourageUnlock,
+  kNetworkAutoConnect,
+  kAssistantLoading,
+  kToastManagerUnittest,
+  kMaximumDeskLaunchTemplate,
+  kEnterOverviewGesture,
+  kExitOverviewGesture,
+  kNextDeskGesture,
+  kPreviousDeskGesture,
+  kMoveVisibleOnAllDesksWindow,
+  kAppCannotSnap,
+  kCrostiniUnsupportedVirtualKeyboard,
+  kCrostiniUnsupportedIME,
+  kCopyToClipboardShareAction,
+  kClipboardBlockedAction,
+  kClipboardWarnOnPaste,
+  kAppNotAvailable,
+  kCameraPrivacySwitchOff,
+  kCameraPrivacySwitchOn,
+  kExtensionInstallSuccess,
+  kAccountRemoved,
+};
+
+}  // namespace ash
+
+#endif  // ASH_PUBLIC_CPP_SYSTEM_TOAST_CATALOG_H_
diff --git a/ash/public/cpp/toast_data.cc b/ash/public/cpp/system/toast_data.cc
similarity index 84%
rename from ash/public/cpp/toast_data.cc
rename to ash/public/cpp/system/toast_data.cc
index 498b108..8be07ad 100644
--- a/ash/public/cpp/toast_data.cc
+++ b/ash/public/cpp/system/toast_data.cc
@@ -2,18 +2,20 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ash/public/cpp/toast_data.h"
+#include "ash/public/cpp/system/toast_data.h"
 
 #include <utility>
 
 namespace ash {
 
 ToastData::ToastData(std::string id,
+                     ToastCatalogName catalog_name,
                      const std::u16string& text,
                      int32_t duration_ms,
                      bool visible_on_lock_screen,
                      const absl::optional<std::u16string>& dismiss_text)
     : id(std::move(id)),
+      catalog_name(catalog_name),
       text(text),
       duration_ms(duration_ms),
       visible_on_lock_screen(visible_on_lock_screen),
diff --git a/ash/public/cpp/toast_data.h b/ash/public/cpp/system/toast_data.h
similarity index 81%
rename from ash/public/cpp/toast_data.h
rename to ash/public/cpp/system/toast_data.h
index 2b47a4a..10ca862b 100644
--- a/ash/public/cpp/toast_data.h
+++ b/ash/public/cpp/system/toast_data.h
@@ -2,12 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ASH_PUBLIC_CPP_TOAST_DATA_H_
-#define ASH_PUBLIC_CPP_TOAST_DATA_H_
+#ifndef ASH_PUBLIC_CPP_SYSTEM_TOAST_DATA_H_
+#define ASH_PUBLIC_CPP_SYSTEM_TOAST_DATA_H_
 
 #include <string>
 
 #include "ash/public/cpp/ash_public_export.h"
+#include "ash/public/cpp/system/toast_catalog.h"
 #include "base/callback.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
@@ -20,6 +21,7 @@
   static const int32_t kDefaultToastDurationMs = 6 * 1000;
 
   ToastData(std::string id,
+            ToastCatalogName catalog_name,
             const std::u16string& text,
             int32_t duration_ms = kDefaultToastDurationMs,
             bool visible_on_lock_screen = false,
@@ -28,6 +30,7 @@
   ~ToastData();
 
   std::string id;
+  ToastCatalogName catalog_name;
   std::u16string text;
   int32_t duration_ms;
   bool visible_on_lock_screen;
@@ -38,4 +41,4 @@
 
 }  // namespace ash
 
-#endif  // ASH_PUBLIC_CPP_TOAST_DATA_H_
+#endif  // ASH_PUBLIC_CPP_SYSTEM_TOAST_DATA_H_
diff --git a/ash/public/cpp/toast_manager.cc b/ash/public/cpp/system/toast_manager.cc
similarity index 91%
rename from ash/public/cpp/toast_manager.cc
rename to ash/public/cpp/system/toast_manager.cc
index 6a46ac5..478386a0 100644
--- a/ash/public/cpp/toast_manager.cc
+++ b/ash/public/cpp/system/toast_manager.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ash/public/cpp/toast_manager.h"
+#include "ash/public/cpp/system/toast_manager.h"
 
 #include "base/check_op.h"
 
diff --git a/ash/public/cpp/toast_manager.h b/ash/public/cpp/system/toast_manager.h
similarity index 83%
rename from ash/public/cpp/toast_manager.h
rename to ash/public/cpp/system/toast_manager.h
index 6f543119..9227f56d 100644
--- a/ash/public/cpp/toast_manager.h
+++ b/ash/public/cpp/system/toast_manager.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ASH_PUBLIC_CPP_TOAST_MANAGER_H_
-#define ASH_PUBLIC_CPP_TOAST_MANAGER_H_
+#ifndef ASH_PUBLIC_CPP_SYSTEM_TOAST_MANAGER_H_
+#define ASH_PUBLIC_CPP_SYSTEM_TOAST_MANAGER_H_
 
 #include <string>
 
@@ -32,4 +32,4 @@
 
 }  // namespace ash
 
-#endif  // ASH_PUBLIC_CPP_TOAST_MANAGER_H_
+#endif  // ASH_PUBLIC_CPP_SYSTEM_TOAST_MANAGER_H_
diff --git a/ash/quick_pair/common/BUILD.gn b/ash/quick_pair/common/BUILD.gn
index b426126..4fcf37b 100644
--- a/ash/quick_pair/common/BUILD.gn
+++ b/ash/quick_pair/common/BUILD.gn
@@ -23,6 +23,8 @@
     "fast_pair/fast_pair_decoder.h",
     "fast_pair/fast_pair_feature_usage_metrics_logger.cc",
     "fast_pair/fast_pair_feature_usage_metrics_logger.h",
+    "fast_pair/fast_pair_http_result.cc",
+    "fast_pair/fast_pair_http_result.h",
     "fast_pair/fast_pair_metrics.cc",
     "fast_pair/fast_pair_metrics.h",
     "fast_pair/fast_pair_service_data_creator.cc",
@@ -47,6 +49,9 @@
     "//components/prefs",
     "//device/bluetooth",
     "//device/bluetooth/public/cpp",
+    "//net",
+    "//services/network/public/cpp",
+    "//services/network/public/mojom",
   ]
 }
 
diff --git a/ash/quick_pair/common/fast_pair/fast_pair_http_result.cc b/ash/quick_pair/common/fast_pair/fast_pair_http_result.cc
new file mode 100644
index 0000000..3ac4cb3
--- /dev/null
+++ b/ash/quick_pair/common/fast_pair/fast_pair_http_result.cc
@@ -0,0 +1,72 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/quick_pair/common/fast_pair/fast_pair_http_result.h"
+
+#include "net/base/net_errors.h"
+#include "net/http/http_status_code.h"
+#include "services/network/public/cpp/cors/cors.h"
+#include "services/network/public/mojom/url_response_head.mojom.h"
+
+namespace ash {
+namespace quick_pair {
+
+FastPairHttpResult::FastPairHttpResult(
+    const int net_error,
+    const network::mojom::URLResponseHead* head) {
+  absl::optional<int> http_response_code;
+  if (head && head->headers)
+    http_response_code = head->headers->response_code();
+  bool net_success = (net_error == net::OK ||
+                      net_error == net::ERR_HTTP_RESPONSE_CODE_FAILURE) &&
+                     http_response_code;
+  bool http_success =
+      net_success && network::cors::IsOkStatus(*http_response_code);
+  if (http_success) {
+    type_ = Type::kSuccess;
+  } else if (net_success) {
+    type_ = Type::kHttpFailure;
+    http_response_error_ = *http_response_code;
+  } else {
+    type_ = Type::kNetworkFailure;
+    net_error_ = net_error;
+  }
+}
+
+FastPairHttpResult::~FastPairHttpResult() = default;
+
+bool FastPairHttpResult::IsSuccess() const {
+  return type_ == Type::kSuccess;
+}
+
+std::string FastPairHttpResult::ToString() const {
+  std::string status;
+  switch (type_) {
+    case Type::kSuccess:
+      status = "kSuccess";
+      break;
+    case Type::kNetworkFailure:
+      status = "kNetworkFailure";
+      break;
+    case Type::kHttpFailure:
+      status = "kHttpFailure";
+      break;
+  }
+
+  std::string net_error = net_error_.has_value()
+                              ? net::ErrorToString(net_error_.value())
+                              : "[null]";
+
+  std::string response_error =
+      http_response_error_.has_value()
+          ? net::GetHttpReasonPhrase(
+                static_cast<net::HttpStatusCode>(*http_response_error_))
+          : "[null]";
+
+  return "status=" + status + ", net_error=" + net_error +
+         ", http_response_error=" + response_error;
+}
+
+}  // namespace quick_pair
+}  // namespace ash
diff --git a/ash/quick_pair/common/fast_pair/fast_pair_http_result.h b/ash/quick_pair/common/fast_pair/fast_pair_http_result.h
new file mode 100644
index 0000000..7f9deb9
--- /dev/null
+++ b/ash/quick_pair/common/fast_pair/fast_pair_http_result.h
@@ -0,0 +1,45 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_QUICK_PAIR_COMMON_FAST_PAIR_FAST_PAIR_HTTP_RESULT_H_
+#define ASH_QUICK_PAIR_COMMON_FAST_PAIR_FAST_PAIR_HTTP_RESULT_H_
+
+#include "base/component_export.h"
+#include "services/network/public/mojom/url_response_head.mojom-forward.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace ash {
+namespace quick_pair {
+
+// This class is used to represent server errors (both network and HTTP errors)
+// we encounter in the repository component.
+class COMPONENT_EXPORT(QUICK_PAIR_COMMON) FastPairHttpResult {
+ public:
+  FastPairHttpResult(const int net_error,
+                     const network::mojom::URLResponseHead* head);
+  FastPairHttpResult(const FastPairHttpResult&) = delete;
+  FastPairHttpResult& operator=(const FastPairHttpResult&) = delete;
+  FastPairHttpResult& operator=(FastPairHttpResult&&) = delete;
+  ~FastPairHttpResult();
+
+  absl::optional<int> net_error() const { return net_error_; }
+  absl::optional<int> http_response_error() const {
+    return http_response_error_;
+  }
+
+  bool IsSuccess() const;
+  std::string ToString() const;
+
+ private:
+  enum class Type { kSuccess, kNetworkFailure, kHttpFailure } type_;
+
+  // Only set if the code is an error, i.e., not set on success.
+  absl::optional<int> net_error_;
+  absl::optional<int> http_response_error_;
+};
+
+}  // namespace quick_pair
+}  // namespace ash
+
+#endif  // ASH_QUICK_PAIR_COMMON_FAST_PAIR_FAST_PAIR_HTTP_RESULT_H_
diff --git a/ash/quick_pair/common/fast_pair/fast_pair_metrics.cc b/ash/quick_pair/common/fast_pair/fast_pair_metrics.cc
index 3619a19..7e3b799 100644
--- a/ash/quick_pair/common/fast_pair/fast_pair_metrics.cc
+++ b/ash/quick_pair/common/fast_pair/fast_pair_metrics.cc
@@ -140,12 +140,28 @@
     "TotalConnectTime";
 const char kDeviceMetadataFetchResult[] =
     "Bluetooth.ChromeOS.FastPair.DeviceMetadataFetcher.Result";
+const char kDeviceMetadataFetchNetError[] =
+    "Bluetooth.ChromeOS.FastPair.DeviceMetadataFetcher.Get.NetError";
+const char kDeviceMetadataFetchHttpResponseError[] =
+    "Bluetooth.ChromeOS.FastPair.DeviceMetadataFetcher.Get.HttpResponseError";
 const char kFootprintsFetcherDeleteResult[] =
     "Bluetooth.ChromeOS.FastPair.FootprintsFetcher.Delete.Result";
+const char kFootprintsFetcherDeleteNetError[] =
+    "Bluetooth.ChromeOS.FastPair.FootprintsFetcher.Delete.NetError";
+const char kFootprintsFetcherDeleteHttpResponseError[] =
+    "Bluetooth.ChromeOS.FastPair.FootprintsFetcher.Delete.HttpResponseError";
 const char kFootprintsFetcherPostResult[] =
     "Bluetooth.ChromeOS.FastPair.FootprintsFetcher.Post.Result";
+const char kFootprintsFetcherPostNetError[] =
+    "Bluetooth.ChromeOS.FastPair.FootprintsFetcher.Post.NetError";
+const char kFootprintsFetcherPostHttpResponseError[] =
+    "Bluetooth.ChromeOS.FastPair.FootprintsFetcher.Post.HttpResponseError";
 const char kFootprintsFetcherGetResult[] =
     "Bluetooth.ChromeOS.FastPair.FootprintsFetcher.Get.Result";
+const char kFootprintsFetcherGetNetError[] =
+    "Bluetooth.ChromeOS.FastPair.FootprintsFetcher.Get.NetError";
+const char kFootprintsFetcherGetHttpResponseError[] =
+    "Bluetooth.ChromeOS.FastPair.FootprintsFetcher.Get.HttpResponseError";
 const char kFastPairRepositoryCacheResult[] =
     "Bluetooth.ChromeOS.FastPair.FastPairRepository.Cache.Result";
 const char kHandshakeResult[] = "Bluetooth.ChromeOS.FastPair.Handshake.Result";
@@ -410,20 +426,60 @@
                           total_connect_time);
 }
 
-void RecordDeviceMetadataFetchResult(bool success) {
-  base::UmaHistogramBoolean(kDeviceMetadataFetchResult, success);
+void RecordDeviceMetadataFetchResult(const FastPairHttpResult& result) {
+  base::UmaHistogramBoolean(kDeviceMetadataFetchResult, result.IsSuccess());
+
+  if (result.net_error()) {
+    base::UmaHistogramSparse(kDeviceMetadataFetchNetError,
+                             -*result.net_error());
+  }
+
+  if (result.http_response_error()) {
+    base::UmaHistogramSparse(kDeviceMetadataFetchHttpResponseError,
+                             *result.http_response_error());
+  }
 }
 
-void RecordFootprintsFetcherDeleteResult(bool success) {
-  base::UmaHistogramBoolean(kFootprintsFetcherDeleteResult, success);
+void RecordFootprintsFetcherDeleteResult(const FastPairHttpResult& result) {
+  base::UmaHistogramBoolean(kFootprintsFetcherDeleteResult, result.IsSuccess());
+
+  if (result.net_error()) {
+    base::UmaHistogramSparse(kFootprintsFetcherDeleteNetError,
+                             -*result.net_error());
+  }
+
+  if (result.http_response_error()) {
+    base::UmaHistogramSparse(kFootprintsFetcherDeleteHttpResponseError,
+                             *result.http_response_error());
+  }
 }
 
-void RecordFootprintsFetcherPostResult(bool success) {
-  base::UmaHistogramBoolean(kFootprintsFetcherPostResult, success);
+void RecordFootprintsFetcherPostResult(const FastPairHttpResult& result) {
+  base::UmaHistogramBoolean(kFootprintsFetcherPostResult, result.IsSuccess());
+
+  if (result.net_error()) {
+    base::UmaHistogramSparse(kFootprintsFetcherPostNetError,
+                             -*result.net_error());
+  }
+
+  if (result.http_response_error()) {
+    base::UmaHistogramSparse(kFootprintsFetcherPostHttpResponseError,
+                             *result.http_response_error());
+  }
 }
 
-void RecordFootprintsFetcherGetResult(bool success) {
-  base::UmaHistogramBoolean(kFootprintsFetcherGetResult, success);
+void RecordFootprintsFetcherGetResult(const FastPairHttpResult& result) {
+  base::UmaHistogramBoolean(kFootprintsFetcherGetResult, result.IsSuccess());
+
+  if (result.net_error()) {
+    base::UmaHistogramSparse(kFootprintsFetcherGetNetError,
+                             -*result.net_error());
+  }
+
+  if (result.http_response_error()) {
+    base::UmaHistogramSparse(kFootprintsFetcherGetHttpResponseError,
+                             *result.http_response_error());
+  }
 }
 
 void RecordFastPairRepositoryCacheResult(bool success) {
diff --git a/ash/quick_pair/common/fast_pair/fast_pair_metrics.h b/ash/quick_pair/common/fast_pair/fast_pair_metrics.h
index f46eaa1..7fdb04a 100644
--- a/ash/quick_pair/common/fast_pair/fast_pair_metrics.h
+++ b/ash/quick_pair/common/fast_pair/fast_pair_metrics.h
@@ -6,6 +6,7 @@
 #define ASH_QUICK_PAIR_COMMON_FAST_PAIR_FAST_PAIR_METRICS_H_
 
 #include "ash/quick_pair/common/account_key_failure.h"
+#include "ash/quick_pair/common/fast_pair/fast_pair_http_result.h"
 #include "ash/quick_pair/common/pair_failure.h"
 #include "base/component_export.h"
 #include "base/time/time.h"
@@ -204,16 +205,16 @@
     base::TimeDelta total_connect_time);
 
 COMPONENT_EXPORT(QUICK_PAIR_COMMON)
-void RecordDeviceMetadataFetchResult(bool success);
+void RecordDeviceMetadataFetchResult(const FastPairHttpResult& result);
 
 COMPONENT_EXPORT(QUICK_PAIR_COMMON)
-void RecordFootprintsFetcherDeleteResult(bool success);
+void RecordFootprintsFetcherDeleteResult(const FastPairHttpResult& result);
 
 COMPONENT_EXPORT(QUICK_PAIR_COMMON)
-void RecordFootprintsFetcherPostResult(bool success);
+void RecordFootprintsFetcherPostResult(const FastPairHttpResult& result);
 
 COMPONENT_EXPORT(QUICK_PAIR_COMMON)
-void RecordFootprintsFetcherGetResult(bool success);
+void RecordFootprintsFetcherGetResult(const FastPairHttpResult& result);
 
 COMPONENT_EXPORT(QUICK_PAIR_COMMON)
 void RecordFastPairRepositoryCacheResult(bool success);
diff --git a/ash/quick_pair/fast_pair_handshake/fake_fast_pair_handshake.h b/ash/quick_pair/fast_pair_handshake/fake_fast_pair_handshake.h
index 8ddc887..86db31f 100644
--- a/ash/quick_pair/fast_pair_handshake/fake_fast_pair_handshake.h
+++ b/ash/quick_pair/fast_pair_handshake/fake_fast_pair_handshake.h
@@ -24,7 +24,7 @@
       std::unique_ptr<FastPairGattServiceClient> gatt_service_client = nullptr);
   FakeFastPairHandshake(const FakeFastPairHandshake&) = delete;
   FakeFastPairHandshake& operator=(const FakeFastPairHandshake&) = delete;
-  ~FakeFastPairHandshake();
+  ~FakeFastPairHandshake() override;
 
   void InvokeCallback(absl::optional<PairFailure> failure = absl::nullopt);
 };
diff --git a/ash/quick_pair/fast_pair_handshake/fast_pair_handshake.h b/ash/quick_pair/fast_pair_handshake/fast_pair_handshake.h
index e609e3d6..07a9231 100644
--- a/ash/quick_pair/fast_pair_handshake/fast_pair_handshake.h
+++ b/ash/quick_pair/fast_pair_handshake/fast_pair_handshake.h
@@ -51,7 +51,7 @@
       std::unique_ptr<FastPairGattServiceClient> gatt_service_client);
   FastPairHandshake(const FastPairHandshake&) = delete;
   FastPairHandshake& operator=(const FastPairHandshake&) = delete;
-  ~FastPairHandshake();
+  virtual ~FastPairHandshake();
 
   bool completed_successfully() { return completed_successfully_; }
 
diff --git a/ash/quick_pair/fast_pair_handshake/fast_pair_handshake_impl.h b/ash/quick_pair/fast_pair_handshake/fast_pair_handshake_impl.h
index f32f9c3..fbf9ac57 100644
--- a/ash/quick_pair/fast_pair_handshake/fast_pair_handshake_impl.h
+++ b/ash/quick_pair/fast_pair_handshake/fast_pair_handshake_impl.h
@@ -22,7 +22,7 @@
                         OnCompleteCallback on_complete);
   FastPairHandshakeImpl(const FastPairHandshakeImpl&) = delete;
   FastPairHandshakeImpl& operator=(const FastPairHandshakeImpl&) = delete;
-  ~FastPairHandshakeImpl();
+  ~FastPairHandshakeImpl() override;
 
  private:
   void OnGattClientInitializedCallback(absl::optional<PairFailure> failure);
diff --git a/ash/quick_pair/pairing/retroactive_pairing_detector_impl.cc b/ash/quick_pair/pairing/retroactive_pairing_detector_impl.cc
index 2e9ba7c..e3bab77 100644
--- a/ash/quick_pair/pairing/retroactive_pairing_detector_impl.cc
+++ b/ash/quick_pair/pairing/retroactive_pairing_detector_impl.cc
@@ -4,11 +4,14 @@
 
 #include "ash/quick_pair/pairing/retroactive_pairing_detector_impl.h"
 
+#include "ash/public/cpp/session/session_controller.h"
 #include "ash/quick_pair/common/constants.h"
 #include "ash/quick_pair/common/device.h"
 #include "ash/quick_pair/common/logging.h"
 #include "ash/quick_pair/common/protocol.h"
 #include "ash/quick_pair/message_stream/message_stream.h"
+#include "ash/session/session_controller_impl.h"
+#include "ash/shell.h"
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/callback_helpers.h"
@@ -20,6 +23,25 @@
 #include "device/bluetooth/bluetooth_adapter_factory.h"
 #include "device/bluetooth/bluetooth_device.h"
 
+namespace {
+
+bool ShouldBeEnabledForLoginStatus(ash::LoginStatus status) {
+  switch (status) {
+    case ash::LoginStatus::NOT_LOGGED_IN:
+    case ash::LoginStatus::LOCKED:
+    case ash::LoginStatus::KIOSK_APP:
+    case ash::LoginStatus::GUEST:
+    case ash::LoginStatus::PUBLIC:
+      return false;
+    case ash::LoginStatus::USER:
+    case ash::LoginStatus::CHILD:
+    default:
+      return true;
+  }
+}
+
+}  // namespace
+
 namespace ash {
 namespace quick_pair {
 
@@ -27,6 +49,16 @@
     PairerBroker* pairer_broker,
     MessageStreamLookup* message_stream_lookup)
     : message_stream_lookup_(message_stream_lookup) {
+  // If there is no signed in user, don't enabled the retroactive pairing
+  // scenario, so don't initiate any objects or observations.
+  if (!ShouldBeEnabledForLoginStatus(
+          Shell::Get()->session_controller()->login_status())) {
+    QP_LOG(VERBOSE)
+        << __func__
+        << ": No logged in user to enable retroactive pairing scenario";
+    return;
+  }
+
   device::BluetoothAdapterFactory::Get()->GetAdapter(
       base::BindOnce(&RetroactivePairingDetectorImpl::OnGetAdapter,
                      weak_ptr_factory_.GetWeakPtr()));
diff --git a/ash/quick_pair/pairing/retroactive_pairing_detector_unittest.cc b/ash/quick_pair/pairing/retroactive_pairing_detector_unittest.cc
index a7c171e0..7defb3d 100644
--- a/ash/quick_pair/pairing/retroactive_pairing_detector_unittest.cc
+++ b/ash/quick_pair/pairing/retroactive_pairing_detector_unittest.cc
@@ -22,6 +22,8 @@
 #include "ash/services/quick_pair/quick_pair_process.h"
 #include "ash/services/quick_pair/quick_pair_process_manager.h"
 #include "ash/services/quick_pair/quick_pair_process_manager_impl.h"
+#include "ash/shell.h"
+#include "ash/test/ash_test_base.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/run_loop.h"
 #include "base/test/task_environment.h"
@@ -37,6 +39,7 @@
 constexpr char kTestDeviceAddress[] = "11:12:13:14:15:16";
 constexpr char kTestBleDeviceName[] = "Test Device Name";
 constexpr char kValidModelId[] = "718c17";
+const std::string kUserEmail = "test@test.test";
 
 const std::vector<uint8_t> kModelIdBytes = {
     /*message_group=*/0x03,
@@ -112,10 +115,11 @@
 };
 
 class RetroactivePairingDetectorTest
-    : public testing::Test,
+    : public AshTestBase,
       public RetroactivePairingDetector::Observer {
  public:
   void SetUp() override {
+    AshTestBase::SetUp();
     adapter_ =
         base::MakeRefCounted<RetroactivePairingDetectorFakeBluetoothAdapter>();
     device::BluetoothAdapterFactory::SetAdapterForTesting(adapter_);
@@ -134,14 +138,22 @@
     data_parser_ = std::make_unique<FastPairDataParser>(
         fast_pair_data_parser_.InitWithNewPipeAndPassReceiver());
     data_parser_remote_.Bind(std::move(fast_pair_data_parser_),
-                             task_environment_.GetMainThreadTaskRunner());
+                             task_environment()->GetMainThreadTaskRunner());
     EXPECT_CALL(*mock_process_manager(), GetProcessReference)
         .WillRepeatedly([&](QuickPairProcessManager::ProcessStoppedCallback) {
           return std::make_unique<
               QuickPairProcessManagerImpl::ProcessReferenceImpl>(
               data_parser_remote_, base::DoNothing());
         });
+  }
 
+  void TearDown() override {
+    retroactive_pairing_detector_.reset();
+    ClearLogin();
+    AshTestBase::TearDown();
+  }
+
+  void CreateRetroactivePairingDetector() {
     retroactive_pairing_detector_ =
         std::make_unique<RetroactivePairingDetectorImpl>(
             pairer_broker_.get(), message_stream_lookup_.get());
@@ -192,10 +204,11 @@
         device_address, message_stream_.get());
   }
 
- protected:
-  base::test::TaskEnvironment task_environment_{
-      base::test::TaskEnvironment::TimeSource::MOCK_TIME};
+  void Login(user_manager::UserType user_type) {
+    SimulateUserLogin(kUserEmail, user_type);
+  }
 
+ protected:
   bool retroactive_pair_found_ = false;
   scoped_refptr<Device> retroactive_device_;
 
@@ -222,21 +235,36 @@
 };
 
 TEST_F(RetroactivePairingDetectorTest, DevicedPaired_FastPair) {
+  Login(user_manager::UserType::USER_TYPE_REGULAR);
+  base::RunLoop().RunUntilIdle();
+  CreateRetroactivePairingDetector();
+
   EXPECT_FALSE(retroactive_pair_found_);
+
   PairFastPairDeviceWithFastPair(kTestDeviceAddress);
   PairFastPairDeviceWithClassicBluetooth(
       /*new_paired_status=*/true, kTestDeviceAddress);
+
   EXPECT_FALSE(retroactive_pair_found_);
 }
 
 TEST_F(RetroactivePairingDetectorTest, DeviceUnpaired) {
+  Login(user_manager::UserType::USER_TYPE_REGULAR);
+  base::RunLoop().RunUntilIdle();
+  CreateRetroactivePairingDetector();
+
   EXPECT_FALSE(retroactive_pair_found_);
+
   PairFastPairDeviceWithClassicBluetooth(
       /*new_paired_status=*/false, kTestDeviceAddress);
   EXPECT_FALSE(retroactive_pair_found_);
 }
 
 TEST_F(RetroactivePairingDetectorTest, NoMessageStream) {
+  Login(user_manager::UserType::USER_TYPE_REGULAR);
+  base::RunLoop().RunUntilIdle();
+  CreateRetroactivePairingDetector();
+
   EXPECT_FALSE(retroactive_pair_found_);
 
   PairFastPairDeviceWithClassicBluetooth(
@@ -248,6 +276,10 @@
 }
 
 TEST_F(RetroactivePairingDetectorTest, MessageStream_NoBle) {
+  Login(user_manager::UserType::USER_TYPE_REGULAR);
+  base::RunLoop().RunUntilIdle();
+  CreateRetroactivePairingDetector();
+
   EXPECT_FALSE(retroactive_pair_found_);
 
   SetMessageStream(kModelIdBytes);
@@ -263,6 +295,10 @@
 }
 
 TEST_F(RetroactivePairingDetectorTest, MessageStream_NoModelId) {
+  Login(user_manager::UserType::USER_TYPE_REGULAR);
+  base::RunLoop().RunUntilIdle();
+  CreateRetroactivePairingDetector();
+
   EXPECT_FALSE(retroactive_pair_found_);
 
   SetMessageStream(kBleAddressBytes);
@@ -279,6 +315,10 @@
 }
 
 TEST_F(RetroactivePairingDetectorTest, MessageStream_SocketError) {
+  Login(user_manager::UserType::USER_TYPE_REGULAR);
+  base::RunLoop().RunUntilIdle();
+  CreateRetroactivePairingDetector();
+
   EXPECT_FALSE(retroactive_pair_found_);
 
   std::vector<uint8_t> data;
@@ -295,6 +335,10 @@
 }
 
 TEST_F(RetroactivePairingDetectorTest, MessageStream_NoBytes) {
+  Login(user_manager::UserType::USER_TYPE_REGULAR);
+  base::RunLoop().RunUntilIdle();
+  CreateRetroactivePairingDetector();
+
   EXPECT_FALSE(retroactive_pair_found_);
 
   std::vector<uint8_t> data;
@@ -312,6 +356,10 @@
 }
 
 TEST_F(RetroactivePairingDetectorTest, MessageStream_Ble_ModelId_Lost) {
+  Login(user_manager::UserType::USER_TYPE_REGULAR);
+  base::RunLoop().RunUntilIdle();
+  CreateRetroactivePairingDetector();
+
   EXPECT_FALSE(retroactive_pair_found_);
 
   SetMessageStream(kModelIdBleAddressBytes);
@@ -329,6 +377,10 @@
 }
 
 TEST_F(RetroactivePairingDetectorTest, MessageStream_Ble_ModelId) {
+  Login(user_manager::UserType::USER_TYPE_REGULAR);
+  base::RunLoop().RunUntilIdle();
+  CreateRetroactivePairingDetector();
+
   EXPECT_FALSE(retroactive_pair_found_);
 
   SetMessageStream(kModelIdBleAddressBytes);
@@ -346,7 +398,31 @@
 }
 
 TEST_F(RetroactivePairingDetectorTest,
+       MessageStream_Ble_ModelId_GuestUserLoggedIn) {
+  Login(user_manager::UserType::USER_TYPE_GUEST);
+  base::RunLoop().RunUntilIdle();
+  CreateRetroactivePairingDetector();
+
+  EXPECT_FALSE(retroactive_pair_found_);
+
+  SetMessageStream(kModelIdBleAddressBytes);
+  PairFastPairDeviceWithClassicBluetooth(
+      /*new_paired_status=*/true, kTestDeviceAddress);
+
+  fake_socket_->TriggerReceiveCallback();
+  base::RunLoop().RunUntilIdle();
+  NotifyMessageStreamConnected(kTestDeviceAddress);
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_FALSE(retroactive_pair_found_);
+}
+
+TEST_F(RetroactivePairingDetectorTest,
        MessageStream_GetMessageStream_Ble_ModelId) {
+  Login(user_manager::UserType::USER_TYPE_REGULAR);
+  base::RunLoop().RunUntilIdle();
+  CreateRetroactivePairingDetector();
+
   EXPECT_FALSE(retroactive_pair_found_);
 
   AddMessageStream(kModelIdBleAddressBytes);
@@ -360,7 +436,28 @@
   EXPECT_EQ(retroactive_device_->metadata_id, kModelId);
 }
 
+TEST_F(RetroactivePairingDetectorTest,
+       MessageStream_GetMessageStream_Ble_ModelId_GuestUser) {
+  Login(user_manager::UserType::USER_TYPE_GUEST);
+  base::RunLoop().RunUntilIdle();
+  CreateRetroactivePairingDetector();
+
+  EXPECT_FALSE(retroactive_pair_found_);
+
+  AddMessageStream(kModelIdBleAddressBytes);
+  PairFastPairDeviceWithClassicBluetooth(
+      /*new_paired_status=*/true, kTestDeviceAddress);
+  fake_socket_->TriggerReceiveCallback();
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_FALSE(retroactive_pair_found_);
+}
+
 TEST_F(RetroactivePairingDetectorTest, MessageStream_GetMessageStream_ModelId) {
+  Login(user_manager::UserType::USER_TYPE_REGULAR);
+  base::RunLoop().RunUntilIdle();
+  CreateRetroactivePairingDetector();
+
   EXPECT_FALSE(retroactive_pair_found_);
 
   AddMessageStream(kModelIdBytes);
@@ -373,6 +470,10 @@
 }
 
 TEST_F(RetroactivePairingDetectorTest, MessageStream_Observer_Ble_ModelId) {
+  Login(user_manager::UserType::USER_TYPE_REGULAR);
+  base::RunLoop().RunUntilIdle();
+  CreateRetroactivePairingDetector();
+
   EXPECT_FALSE(retroactive_pair_found_);
 
   fake_socket_->SetIOBufferFromBytes(kModelIdBleAddressBytes);
@@ -391,7 +492,33 @@
   EXPECT_EQ(retroactive_device_->metadata_id, kModelId);
 }
 
+TEST_F(RetroactivePairingDetectorTest,
+       MessageStream_Observer_Ble_ModelId_GuestAccount) {
+  Login(user_manager::UserType::USER_TYPE_GUEST);
+  base::RunLoop().RunUntilIdle();
+  CreateRetroactivePairingDetector();
+
+  EXPECT_FALSE(retroactive_pair_found_);
+
+  fake_socket_->SetIOBufferFromBytes(kModelIdBleAddressBytes);
+  PairFastPairDeviceWithClassicBluetooth(
+      /*new_paired_status=*/true, kTestDeviceAddress);
+  base::RunLoop().RunUntilIdle();
+
+  NotifyMessageStreamConnected(kTestDeviceAddress);
+  base::RunLoop().RunUntilIdle();
+
+  fake_socket_->TriggerReceiveCallback();
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_FALSE(retroactive_pair_found_);
+}
+
 TEST_F(RetroactivePairingDetectorTest, MessageStream_Observer_ModelId) {
+  Login(user_manager::UserType::USER_TYPE_REGULAR);
+  base::RunLoop().RunUntilIdle();
+  CreateRetroactivePairingDetector();
+
   EXPECT_FALSE(retroactive_pair_found_);
 
   fake_socket_->SetIOBufferFromBytes(kModelIdBytes);
@@ -409,6 +536,10 @@
 }
 
 TEST_F(RetroactivePairingDetectorTest, MessageStreamRemovedOnDestroyed) {
+  Login(user_manager::UserType::USER_TYPE_REGULAR);
+  base::RunLoop().RunUntilIdle();
+  CreateRetroactivePairingDetector();
+
   EXPECT_FALSE(retroactive_pair_found_);
 
   SetMessageStream(kModelIdBleAddressBytes);
@@ -426,6 +557,10 @@
 }
 
 TEST_F(RetroactivePairingDetectorTest, MessageStreamRemovedOnDisconnect) {
+  Login(user_manager::UserType::USER_TYPE_REGULAR);
+  base::RunLoop().RunUntilIdle();
+  CreateRetroactivePairingDetector();
+
   EXPECT_FALSE(retroactive_pair_found_);
 
   fake_socket_->SetErrorReason(
diff --git a/ash/quick_pair/repository/BUILD.gn b/ash/quick_pair/repository/BUILD.gn
index 1661ab5b..3f3de4c 100644
--- a/ash/quick_pair/repository/BUILD.gn
+++ b/ash/quick_pair/repository/BUILD.gn
@@ -110,7 +110,11 @@
     "//chromeos/services/bluetooth_config/public/cpp",
     "//components/prefs:test_support",
     "//device/bluetooth:mocks",
+    "//net",
     "//services/data_decoder/public/cpp:test_support",
+    "//services/network:test_support",
+    "//services/network/public/cpp",
+    "//services/network/public/mojom",
     "//testing/gtest",
     "//ui/gfx:test_support",
   ]
diff --git a/ash/quick_pair/repository/fast_pair/device_metadata_fetcher.cc b/ash/quick_pair/repository/fast_pair/device_metadata_fetcher.cc
index 42e4803..1e2ef14 100644
--- a/ash/quick_pair/repository/fast_pair/device_metadata_fetcher.cc
+++ b/ash/quick_pair/repository/fast_pair/device_metadata_fetcher.cc
@@ -4,6 +4,7 @@
 
 #include "ash/quick_pair/repository/fast_pair/device_metadata_fetcher.h"
 
+#include "ash/quick_pair/common/fast_pair/fast_pair_metrics.h"
 #include "ash/quick_pair/common/logging.h"
 #include "ash/quick_pair/proto/fastpair.pb.h"
 #include "ash/quick_pair/repository/unauthenticated_http_fetcher.h"
@@ -71,8 +72,13 @@
 
 void DeviceMetadataFetcher::OnFetchComplete(
     GetObservedDeviceCallback callback,
-    std::unique_ptr<std::string> response_body) {
-  QP_LOG(VERBOSE) << __func__;
+    std::unique_ptr<std::string> response_body,
+    std::unique_ptr<FastPairHttpResult> http_result) {
+  QP_LOG(VERBOSE) << "DeviceMetadataFetcher::" << __func__ << ": HTTP result: "
+                  << (http_result ? http_result->ToString() : "[null]");
+
+  if (http_result)
+    RecordDeviceMetadataFetchResult(*http_result);
 
   if (!response_body) {
     QP_LOG(WARNING) << "No response.";
diff --git a/ash/quick_pair/repository/fast_pair/device_metadata_fetcher.h b/ash/quick_pair/repository/fast_pair/device_metadata_fetcher.h
index 2a109c0..598676d 100644
--- a/ash/quick_pair/repository/fast_pair/device_metadata_fetcher.h
+++ b/ash/quick_pair/repository/fast_pair/device_metadata_fetcher.h
@@ -5,6 +5,7 @@
 #ifndef ASH_QUICK_PAIR_REPOSITORY_FAST_PAIR_DEVICE_METADATA_FETCHER_H_
 #define ASH_QUICK_PAIR_REPOSITORY_FAST_PAIR_DEVICE_METADATA_FETCHER_H_
 
+#include "ash/quick_pair/common/fast_pair/fast_pair_http_result.h"
 #include "ash/quick_pair/proto/fastpair.pb.h"
 #include "base/callback.h"
 #include "base/memory/weak_ptr.h"
@@ -42,7 +43,8 @@
 
  private:
   void OnFetchComplete(GetObservedDeviceCallback callback,
-                       std::unique_ptr<std::string> response_body);
+                       std::unique_ptr<std::string> response_body,
+                       std::unique_ptr<FastPairHttpResult> http_result);
   void OnJsonParsed(GetObservedDeviceCallback callback,
                     data_decoder::DataDecoder::ValueOrError result);
 
diff --git a/ash/quick_pair/repository/fast_pair/device_metadata_fetcher_unittest.cc b/ash/quick_pair/repository/fast_pair/device_metadata_fetcher_unittest.cc
index 6fd5ca25..6feae5a 100644
--- a/ash/quick_pair/repository/fast_pair/device_metadata_fetcher_unittest.cc
+++ b/ash/quick_pair/repository/fast_pair/device_metadata_fetcher_unittest.cc
@@ -8,6 +8,7 @@
 
 #include "ash/quick_pair/common/account_key_failure.h"
 #include "ash/quick_pair/common/device.h"
+#include "ash/quick_pair/common/fast_pair/fast_pair_http_result.h"
 #include "ash/quick_pair/common/pair_failure.h"
 #include "ash/quick_pair/common/protocol.h"
 #include "ash/quick_pair/proto/fastpair.pb.h"
@@ -16,9 +17,14 @@
 #include "base/callback_helpers.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/scoped_refptr.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/mock_callback.h"
 #include "base/test/task_environment.h"
+#include "net/base/net_errors.h"
+#include "net/http/http_status_code.h"
 #include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h"
+#include "services/network/public/mojom/url_response_head.mojom.h"
+#include "services/network/test/test_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
@@ -63,6 +69,12 @@
 constexpr char kInvalidResponse[] = "<html>404 error</html>";
 constexpr char kHexDeviceId[] = "07B";
 const int kDeviceId = 123;
+const char kDeviceMetadataFetchResult[] =
+    "Bluetooth.ChromeOS.FastPair.DeviceMetadataFetcher.Result";
+const char kDeviceMetadataFetchNetError[] =
+    "Bluetooth.ChromeOS.FastPair.DeviceMetadataFetcher.Get.NetError";
+const char kDeviceMetadataFetchHttpResponseError[] =
+    "Bluetooth.ChromeOS.FastPair.DeviceMetadataFetcher.Get.HttpResponseError";
 
 }  // namespace
 
@@ -80,6 +92,7 @@
 
  protected:
   base::test::TaskEnvironment task_environment;
+  base::HistogramTester histogram_tester_;
   std::unique_ptr<DeviceMetadataFetcher> device_metadata_fetcher_;
   MockHttpFetcher* mock_http_fetcher_;
   data_decoder::test::InProcessDataDecoder in_process_data_decoder_;
@@ -93,7 +106,8 @@
                       "https://nearbydevices-pa.googleapis.com/v1/device/123"));
         std::string decoded;
         base::Base64Decode(kValidResponseEncoded, &decoded);
-        std::move(callback).Run(std::make_unique<std::string>(decoded));
+        std::move(callback).Run(std::make_unique<std::string>(decoded),
+                                nullptr);
       });
 
   base::MockCallback<GetObservedDeviceCallback> callback;
@@ -127,8 +141,8 @@
         ASSERT_EQ(0u,
                   url.spec().find(
                       "https://nearbydevices-pa.googleapis.com/v1/device/123"));
-        std::move(callback).Run(
-            std::make_unique<std::string>(kInvalidResponse));
+        std::move(callback).Run(std::make_unique<std::string>(kInvalidResponse),
+                                nullptr);
       });
 
   base::MockCallback<GetObservedDeviceCallback> callback;
@@ -146,7 +160,8 @@
         ASSERT_EQ(0u,
                   url.spec().find(
                       "https://nearbydevices-pa.googleapis.com/v1/device/123"));
-        std::move(callback).Run(std::make_unique<std::string>(kEmptyResponse));
+        std::move(callback).Run(std::make_unique<std::string>(kEmptyResponse),
+                                nullptr);
       });
 
   base::MockCallback<GetObservedDeviceCallback> callback;
@@ -164,7 +179,7 @@
         ASSERT_EQ(0u,
                   url.spec().find(
                       "https://nearbydevices-pa.googleapis.com/v1/device/123"));
-        std::move(callback).Run(nullptr);
+        std::move(callback).Run(nullptr, nullptr);
       });
 
   base::MockCallback<GetObservedDeviceCallback> callback;
@@ -176,5 +191,71 @@
   task_environment.RunUntilIdle();
 }
 
+TEST_F(DeviceMetadataFetcherTest, RecordNetError) {
+  histogram_tester_.ExpectTotalCount(kDeviceMetadataFetchResult, 0);
+  histogram_tester_.ExpectTotalCount(kDeviceMetadataFetchNetError, 0);
+  histogram_tester_.ExpectTotalCount(kDeviceMetadataFetchHttpResponseError, 0);
+
+  EXPECT_CALL(*mock_http_fetcher_, ExecuteGetRequest)
+      .WillOnce([](const GURL& url, FetchCompleteCallback callback) {
+        ASSERT_EQ(0u,
+                  url.spec().find(
+                      "https://nearbydevices-pa.googleapis.com/v1/device/123"));
+        std::unique_ptr<FastPairHttpResult> http_result =
+            std::make_unique<FastPairHttpResult>(
+                /*net_error=*/net::ERR_CERT_COMMON_NAME_INVALID,
+                /*head=*/network::CreateURLResponseHead(
+                    net::HttpStatusCode::HTTP_NOT_FOUND)
+                    .get());
+        std::move(callback).Run(std::make_unique<std::string>(kInvalidResponse),
+                                std::move(http_result));
+      });
+
+  base::MockCallback<GetObservedDeviceCallback> callback;
+  EXPECT_CALL(callback, Run)
+      .WillOnce([](absl::optional<nearby::fastpair::GetObservedDeviceResponse>
+                       response) { ASSERT_EQ(absl::nullopt, response); });
+
+  device_metadata_fetcher_->LookupDeviceId(kDeviceId, callback.Get());
+  task_environment.RunUntilIdle();
+
+  histogram_tester_.ExpectTotalCount(kDeviceMetadataFetchResult, 1);
+  histogram_tester_.ExpectTotalCount(kDeviceMetadataFetchNetError, 1);
+  histogram_tester_.ExpectTotalCount(kDeviceMetadataFetchHttpResponseError, 0);
+}
+
+TEST_F(DeviceMetadataFetcherTest, RecordHttpError) {
+  histogram_tester_.ExpectTotalCount(kDeviceMetadataFetchResult, 0);
+  histogram_tester_.ExpectTotalCount(kDeviceMetadataFetchNetError, 0);
+  histogram_tester_.ExpectTotalCount(kDeviceMetadataFetchHttpResponseError, 0);
+
+  EXPECT_CALL(*mock_http_fetcher_, ExecuteGetRequest)
+      .WillOnce([](const GURL& url, FetchCompleteCallback callback) {
+        ASSERT_EQ(0u,
+                  url.spec().find(
+                      "https://nearbydevices-pa.googleapis.com/v1/device/123"));
+        std::unique_ptr<FastPairHttpResult> http_result =
+            std::make_unique<FastPairHttpResult>(
+                /*net_error=*/net::OK,
+                /*head=*/network::CreateURLResponseHead(
+                    net::HttpStatusCode::HTTP_NOT_FOUND)
+                    .get());
+        std::move(callback).Run(std::make_unique<std::string>(kInvalidResponse),
+                                std::move(http_result));
+      });
+
+  base::MockCallback<GetObservedDeviceCallback> callback;
+  EXPECT_CALL(callback, Run)
+      .WillOnce([](absl::optional<nearby::fastpair::GetObservedDeviceResponse>
+                       response) { ASSERT_EQ(absl::nullopt, response); });
+
+  device_metadata_fetcher_->LookupDeviceId(kDeviceId, callback.Get());
+  task_environment.RunUntilIdle();
+
+  histogram_tester_.ExpectTotalCount(kDeviceMetadataFetchResult, 1);
+  histogram_tester_.ExpectTotalCount(kDeviceMetadataFetchNetError, 0);
+  histogram_tester_.ExpectTotalCount(kDeviceMetadataFetchHttpResponseError, 1);
+}
+
 }  // namespace quick_pair
 }  // namespace ash
diff --git a/ash/quick_pair/repository/fast_pair/footprints_fetcher.cc b/ash/quick_pair/repository/fast_pair/footprints_fetcher.cc
index e92216d..9465e98 100644
--- a/ash/quick_pair/repository/fast_pair/footprints_fetcher.cc
+++ b/ash/quick_pair/repository/fast_pair/footprints_fetcher.cc
@@ -4,6 +4,7 @@
 
 #include "ash/quick_pair/repository/fast_pair/footprints_fetcher.h"
 
+#include "ash/quick_pair/common/fast_pair/fast_pair_http_result.h"
 #include "ash/quick_pair/common/fast_pair/fast_pair_metrics.h"
 #include "ash/quick_pair/common/logging.h"
 #include "ash/quick_pair/proto/fastpair.pb.h"
@@ -85,12 +86,16 @@
 void FootprintsFetcher::OnGetComplete(
     UserReadDevicesCallback callback,
     std::unique_ptr<HttpFetcher> http_fetcher,
-    std::unique_ptr<std::string> response_body) {
-  QP_LOG(VERBOSE) << __func__;
+    std::unique_ptr<std::string> response_body,
+    std::unique_ptr<FastPairHttpResult> http_result) {
+  QP_LOG(VERBOSE) << "FootprintsFetcher::" << __func__ << ": HTTP result: "
+                  << (http_result ? http_result->ToString() : "[null]");
+
+  if (http_result)
+    RecordFootprintsFetcherGetResult(*http_result);
 
   if (!response_body) {
     QP_LOG(WARNING) << __func__ << ": No response.";
-    RecordFootprintsFetcherGetResult(/*success=*/false);
     std::move(callback).Run(absl::nullopt);
     return;
   }
@@ -98,12 +103,10 @@
   nearby::fastpair::UserReadDevicesResponse devices;
   if (!devices.ParseFromString(*response_body)) {
     QP_LOG(WARNING) << __func__ << ": Failed to parse.";
-    RecordFootprintsFetcherGetResult(/*success=*/false);
     std::move(callback).Run(absl::nullopt);
     return;
   }
 
-  RecordFootprintsFetcherGetResult(/*success=*/true);
   QP_LOG(VERBOSE)
       << __func__
       << ": Successfully retrived footprints data.  Paired devices:";
@@ -133,9 +136,13 @@
 void FootprintsFetcher::OnPostComplete(
     AddDeviceCallback callback,
     std::unique_ptr<HttpFetcher> http_fetcher,
-    std::unique_ptr<std::string> response_body) {
-  QP_LOG(VERBOSE) << __func__;
-  RecordFootprintsFetcherPostResult(/*success=*/response_body ? true : false);
+    std::unique_ptr<std::string> response_body,
+    std::unique_ptr<FastPairHttpResult> http_result) {
+  QP_LOG(VERBOSE) << "FootprintsFetcher::" << __func__ << ": HTTP result: "
+                  << (http_result ? http_result->ToString() : "[null]");
+
+  if (http_result)
+    RecordFootprintsFetcherPostResult(*http_result);
 
   if (!response_body) {
     QP_LOG(WARNING) << __func__ << ": No response.";
@@ -161,9 +168,13 @@
 void FootprintsFetcher::OnDeleteComplete(
     DeleteDeviceCallback callback,
     std::unique_ptr<HttpFetcher> http_fetcher,
-    std::unique_ptr<std::string> response_body) {
-  QP_LOG(VERBOSE) << __func__;
-  RecordFootprintsFetcherDeleteResult(/*success=*/response_body ? true : false);
+    std::unique_ptr<std::string> response_body,
+    std::unique_ptr<FastPairHttpResult> http_result) {
+  QP_LOG(VERBOSE) << "FootprintsFetcher::" << __func__ << ": HTTP result: "
+                  << (http_result ? http_result->ToString() : "[null]");
+
+  if (http_result)
+    RecordFootprintsFetcherDeleteResult(*http_result);
 
   if (!response_body) {
     QP_LOG(WARNING) << __func__ << ": No response.";
diff --git a/ash/quick_pair/repository/fast_pair/footprints_fetcher.h b/ash/quick_pair/repository/fast_pair/footprints_fetcher.h
index ddfdc2a8..624d63e 100644
--- a/ash/quick_pair/repository/fast_pair/footprints_fetcher.h
+++ b/ash/quick_pair/repository/fast_pair/footprints_fetcher.h
@@ -21,6 +21,7 @@
 namespace quick_pair {
 
 class HttpFetcher;
+class FastPairHttpResult;
 
 using UserReadDevicesCallback = base::OnceCallback<void(
     absl::optional<nearby::fastpair::UserReadDevicesResponse>)>;
@@ -44,15 +45,18 @@
  private:
   void OnGetComplete(UserReadDevicesCallback callback,
                      std::unique_ptr<HttpFetcher> http_fetcher,
-                     std::unique_ptr<std::string> response_body);
+                     std::unique_ptr<std::string> response_body,
+                     std::unique_ptr<FastPairHttpResult> http_result);
 
   void OnPostComplete(AddDeviceCallback callback,
                       std::unique_ptr<HttpFetcher> http_fetcher,
-                      std::unique_ptr<std::string> response_body);
+                      std::unique_ptr<std::string> response_body,
+                      std::unique_ptr<FastPairHttpResult> http_result);
 
   void OnDeleteComplete(DeleteDeviceCallback callback,
                         std::unique_ptr<HttpFetcher> http_fetcher,
-                        std::unique_ptr<std::string> response_body);
+                        std::unique_ptr<std::string> response_body,
+                        std::unique_ptr<FastPairHttpResult> http_result);
 
   base::WeakPtrFactory<FootprintsFetcher> weak_ptr_factory_{this};
 };
diff --git a/ash/quick_pair/repository/fast_pair_repository_impl.cc b/ash/quick_pair/repository/fast_pair_repository_impl.cc
index ca90331..7e6da0f 100644
--- a/ash/quick_pair/repository/fast_pair_repository_impl.cc
+++ b/ash/quick_pair/repository/fast_pair_repository_impl.cc
@@ -62,8 +62,6 @@
     const std::string& normalized_model_id,
     DeviceMetadataCallback callback,
     absl::optional<nearby::fastpair::GetObservedDeviceResponse> response) {
-  RecordDeviceMetadataFetchResult(/*success=*/response.has_value());
-
   if (!response) {
     std::move(callback).Run(nullptr);
     return;
diff --git a/ash/quick_pair/repository/http_fetcher.h b/ash/quick_pair/repository/http_fetcher.h
index 8e10a3d5..b2b1adc 100644
--- a/ash/quick_pair/repository/http_fetcher.h
+++ b/ash/quick_pair/repository/http_fetcher.h
@@ -5,6 +5,7 @@
 #ifndef ASH_QUICK_PAIR_REPOSITORY_HTTP_FETCHER_H_
 #define ASH_QUICK_PAIR_REPOSITORY_HTTP_FETCHER_H_
 
+#include "ash/quick_pair/common/fast_pair/fast_pair_http_result.h"
 #include "base/callback.h"
 #include "base/memory/weak_ptr.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
@@ -14,7 +15,8 @@
 namespace quick_pair {
 
 using FetchCompleteCallback =
-    base::OnceCallback<void(std::unique_ptr<std::string>)>;
+    base::OnceCallback<void(std::unique_ptr<std::string>,
+                            std::unique_ptr<FastPairHttpResult>)>;
 
 // Makes HTTP GET requests and returns the response.
 class HttpFetcher {
diff --git a/ash/quick_pair/repository/oauth_http_fetcher.cc b/ash/quick_pair/repository/oauth_http_fetcher.cc
index 9aec2dff..ff771d2 100644
--- a/ash/quick_pair/repository/oauth_http_fetcher.cc
+++ b/ash/quick_pair/repository/oauth_http_fetcher.cc
@@ -4,6 +4,7 @@
 
 #include "ash/quick_pair/repository/oauth_http_fetcher.h"
 
+#include "ash/quick_pair/common/fast_pair/fast_pair_http_result.h"
 #include "ash/quick_pair/common/logging.h"
 #include "ash/quick_pair/common/quick_pair_browser_delegate.h"
 #include "components/signin/public/base/consent_level.h"
@@ -11,6 +12,7 @@
 #include "components/signin/public/identity_manager/identity_manager.h"
 #include "components/signin/public/identity_manager/primary_account_access_token_fetcher.h"
 #include "google_apis/gaia/gaia_constants.h"
+#include "net/base/net_errors.h"
 #include "services/network/public/cpp/resource_request.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "services/network/public/cpp/simple_url_loader.h"
@@ -87,7 +89,7 @@
   if (error.state() != GoogleServiceAuthError::NONE) {
     QP_LOG(WARNING) << __func__ << ": Failed to retrieve access token. "
                     << error.ToString();
-    std::move(callback_).Run(nullptr);
+    std::move(callback_).Run(nullptr, nullptr);
     return;
   }
 
@@ -95,7 +97,7 @@
       QuickPairBrowserDelegate::Get()->GetURLLoaderFactory();
   if (!url_loader_factory) {
     QP_LOG(WARNING) << __func__ << ": No SharedURLLoaderFactory is available.";
-    std::move(callback_).Run(nullptr);
+    std::move(callback_).Run(nullptr, nullptr);
     return;
   }
 
@@ -148,7 +150,11 @@
     const network::mojom::URLResponseHead* head,
     std::unique_ptr<std::string> body) {
   QP_LOG(INFO) << __func__;
-  std::move(callback_).Run(std::move(body));
+
+  std::move(callback_).Run(
+      std::move(body),
+      std::make_unique<FastPairHttpResult>(/*net_error=*/net::OK,
+                                           /*head=*/head));
 }
 
 void OAuthHttpFetcher::ProcessApiCallFailure(
@@ -156,7 +162,10 @@
     const network::mojom::URLResponseHead* head,
     std::unique_ptr<std::string> body) {
   QP_LOG(WARNING) << __func__ << ": net_err=" << net_error;
-  std::move(callback_).Run(nullptr);
+
+  std::move(callback_).Run(
+      nullptr, std::make_unique<FastPairHttpResult>(/*net_error=*/net_error,
+                                                    /*head=*/head));
 }
 
 net::PartialNetworkTrafficAnnotationTag
diff --git a/ash/quick_pair/repository/unauthenticated_http_fetcher.cc b/ash/quick_pair/repository/unauthenticated_http_fetcher.cc
index 6574923..85a94e9 100644
--- a/ash/quick_pair/repository/unauthenticated_http_fetcher.cc
+++ b/ash/quick_pair/repository/unauthenticated_http_fetcher.cc
@@ -4,6 +4,7 @@
 
 #include "ash/quick_pair/repository/unauthenticated_http_fetcher.h"
 
+#include "ash/quick_pair/common/fast_pair/fast_pair_http_result.h"
 #include "ash/quick_pair/common/logging.h"
 #include "ash/quick_pair/common/quick_pair_browser_delegate.h"
 #include "services/network/public/cpp/resource_request.h"
@@ -17,15 +18,6 @@
 // expected responses, however it can be increased if needed in the future.
 constexpr int kMaxDownloadBytes = 2 * 1024 * 1024;
 
-// Helper function to extract response code from |SimpleURLLoader|.
-int GetResponseCode(network::SimpleURLLoader* simple_loader) {
-  if (simple_loader->ResponseInfo() && simple_loader->ResponseInfo()->headers) {
-    return simple_loader->ResponseInfo()->headers->response_code();
-  }
-
-  return -1;
-}
-
 }  // namespace
 
 namespace ash {
@@ -60,7 +52,7 @@
       QuickPairBrowserDelegate::Get()->GetURLLoaderFactory();
   if (!url_loader_factory) {
     QP_LOG(WARNING) << __func__ << ": No SharedURLLoaderFactory is available.";
-    std::move(callback).Run(nullptr);
+    std::move(callback).Run(nullptr, nullptr);
     return;
   }
 
@@ -77,21 +69,25 @@
     std::unique_ptr<network::SimpleURLLoader> simple_loader,
     FetchCompleteCallback callback,
     std::unique_ptr<std::string> response_body) {
-  if (simple_loader->NetError() == net::OK && response_body) {
+  std::unique_ptr<FastPairHttpResult> http_result =
+      std::make_unique<FastPairHttpResult>(
+          /*net_error=*/simple_loader->NetError(),
+          /*head=*/simple_loader->ResponseInfo());
+
+  if (http_result->IsSuccess()) {
     QP_LOG(VERBOSE) << "Successfully fetched "
                     << simple_loader->GetContentSize() << " bytes from "
                     << simple_loader->GetFinalURL();
-    std::move(callback).Run(std::move(response_body));
+    std::move(callback).Run(std::move(response_body), std::move(http_result));
     return;
   }
 
   QP_LOG(WARNING) << "Downloading to string from "
-                  << simple_loader->GetFinalURL() << " failed with error code: "
-                  << GetResponseCode(simple_loader.get())
-                  << " with network error: " << simple_loader->NetError();
+                  << simple_loader->GetFinalURL()
+                  << " failed: " << http_result->ToString();
 
   // TODO(jonmann): Implement retries with back-off.
-  std::move(callback).Run(nullptr);
+  std::move(callback).Run(nullptr, std::move(http_result));
 }
 
 }  // namespace quick_pair
diff --git a/ash/resources/vector_icons/BUILD.gn b/ash/resources/vector_icons/BUILD.gn
index af20d54..285beb8 100644
--- a/ash/resources/vector_icons/BUILD.gn
+++ b/ash/resources/vector_icons/BUILD.gn
@@ -66,6 +66,8 @@
     "desks_new_desk_button.icon",
     "desks_templates.icon",
     "dictation_bubble.icon",
+    "dictation_bubble_macro_failed.icon",
+    "dictation_bubble_macro_succeeded.icon",
     "dictation_menu.icon",
     "dictation_off.icon",
     "dictation_off_newui.icon",
diff --git a/ash/resources/vector_icons/dictation_bubble_macro_failed.icon b/ash/resources/vector_icons/dictation_bubble_macro_failed.icon
new file mode 100644
index 0000000..e504bf4
--- /dev/null
+++ b/ash/resources/vector_icons/dictation_bubble_macro_failed.icon
@@ -0,0 +1,29 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+CANVAS_DIMENSIONS, 33,
+MOVE_TO, 14.82f, 16,
+H_LINE_TO, 18.02f,
+V_LINE_TO, 9.6f,
+H_LINE_TO, 14.82f,
+V_LINE_TO, 16,
+CLOSE,
+MOVE_TO, 16.42f, 3.2f,
+CUBIC_TO, 9.35f, 3.2f, 3.62f, 8.93f, 3.62f, 16,
+CUBIC_TO, 3.62f, 23.07f, 9.35f, 28.8f, 16.42f, 28.8f,
+CUBIC_TO, 23.48f, 28.8f, 29.22f, 23.07f, 29.22f, 16,
+CUBIC_TO, 29.22f, 8.93f, 23.48f, 3.2f, 16.42f, 3.2f,
+CLOSE,
+MOVE_TO, 16.42f, 25.6f,
+CUBIC_TO, 11.13f, 25.6f, 6.82f, 21.29f, 6.82f, 16,
+CUBIC_TO, 6.82f, 10.71f, 11.13f, 6.4f, 16.42f, 6.4f,
+CUBIC_TO, 21.71f, 6.4f, 26.02f, 10.71f, 26.02f, 16,
+CUBIC_TO, 26.02f, 21.29f, 21.71f, 25.6f, 16.42f, 25.6f,
+CLOSE,
+MOVE_TO, 14.82f, 22.4f,
+H_LINE_TO, 18.02f,
+V_LINE_TO, 19.2f,
+H_LINE_TO, 14.82f,
+V_LINE_TO, 22.4f,
+CLOSE
diff --git a/ash/resources/vector_icons/dictation_bubble_macro_succeeded.icon b/ash/resources/vector_icons/dictation_bubble_macro_succeeded.icon
new file mode 100644
index 0000000..a4bd6eb
--- /dev/null
+++ b/ash/resources/vector_icons/dictation_bubble_macro_succeeded.icon
@@ -0,0 +1,29 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+CANVAS_DIMENSIONS, 20,
+MOVE_TO, 13.71f, 7.29f,
+CUBIC_TO, 13.32f, 6.9f, 12.68f, 6.9f, 12.29f, 7.29f,
+LINE_TO, 9, 10.59f,
+LINE_TO, 7.71f, 9.29f,
+CUBIC_TO, 7.32f, 8.9f, 6.68f, 8.9f, 6.29f, 9.29f,
+CUBIC_TO, 5.9f, 9.68f, 5.9f, 10.32f, 6.29f, 10.71f,
+LINE_TO, 8.29f, 12.71f,
+CUBIC_TO, 8.68f, 13.1f, 9.32f, 13.1f, 9.71f, 12.71f,
+LINE_TO, 13.71f, 8.71f,
+CUBIC_TO, 14.1f, 8.32f, 14.1f, 7.68f, 13.71f, 7.29f,
+CLOSE,
+NEW_PATH,
+MOVE_TO, 10, 18,
+CUBIC_TO, 14.42f, 18, 18, 14.42f, 18, 10,
+CUBIC_TO, 18, 5.58f, 14.42f, 2, 10, 2,
+CUBIC_TO, 5.58f, 2, 2, 5.58f, 2, 10,
+CUBIC_TO, 2, 14.42f, 5.58f, 18, 10, 18,
+CLOSE,
+MOVE_TO, 10, 16,
+CUBIC_TO, 13.31f, 16, 16, 13.31f, 16, 10,
+CUBIC_TO, 16, 6.69f, 13.31f, 4, 10, 4,
+CUBIC_TO, 6.69f, 4, 4, 6.69f, 4, 10,
+CUBIC_TO, 4, 13.31f, 6.69f, 16, 10, 16,
+CLOSE
diff --git a/ash/services/nearby/public/cpp/BUILD.gn b/ash/services/nearby/public/cpp/BUILD.gn
index de3e6b1b..e9dade9ff 100644
--- a/ash/services/nearby/public/cpp/BUILD.gn
+++ b/ash/services/nearby/public/cpp/BUILD.gn
@@ -36,8 +36,17 @@
   testonly = true
 
   sources = [
+    "fake_firewall_hole.h",
+    "fake_firewall_hole_factory.cc",
+    "fake_firewall_hole_factory.h",
     "fake_nearby_process_manager.cc",
     "fake_nearby_process_manager.h",
+    "fake_tcp_connected_socket.cc",
+    "fake_tcp_connected_socket.h",
+    "fake_tcp_server_socket.cc",
+    "fake_tcp_server_socket.h",
+    "fake_tcp_socket_factory.cc",
+    "fake_tcp_socket_factory.h",
     "mock_nearby_connections.cc",
     "mock_nearby_connections.h",
     "mock_nearby_process_manager.cc",
@@ -48,9 +57,12 @@
 
   deps = [
     ":cpp",
+    ":tcp_server_socket_port",
     "//ash/services/nearby/public/mojom",
     "//base",
+    "//base/test:test_support",
     "//mojo/public/cpp/bindings/",
+    "//services/network/public/mojom",
     "//testing/gmock",
   ]
 }
diff --git a/ash/services/nearby/public/cpp/fake_firewall_hole.h b/ash/services/nearby/public/cpp/fake_firewall_hole.h
new file mode 100644
index 0000000..ea90920
--- /dev/null
+++ b/ash/services/nearby/public/cpp/fake_firewall_hole.h
@@ -0,0 +1,23 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_SERVICES_NEARBY_PUBLIC_CPP_FAKE_FIREWALL_HOLE_H_
+#define ASH_SERVICES_NEARBY_PUBLIC_CPP_FAKE_FIREWALL_HOLE_H_
+
+#include "ash/services/nearby/public/mojom/firewall_hole.mojom.h"
+
+namespace ash {
+namespace nearby {
+
+// A trivial implementation of sharing::mojom::FirewallHole used for testing.
+class FakeFirewallHole : public sharing::mojom::FirewallHole {
+ public:
+  FakeFirewallHole() = default;
+  ~FakeFirewallHole() override = default;
+};
+
+}  // namespace nearby
+}  // namespace ash
+
+#endif  // ASH_SERVICES_NEARBY_PUBLIC_CPP_FAKE_FIREWALL_HOLE_H_
diff --git a/ash/services/nearby/public/cpp/fake_firewall_hole_factory.cc b/ash/services/nearby/public/cpp/fake_firewall_hole_factory.cc
new file mode 100644
index 0000000..5ff1ad8
--- /dev/null
+++ b/ash/services/nearby/public/cpp/fake_firewall_hole_factory.cc
@@ -0,0 +1,33 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/services/nearby/public/cpp/fake_firewall_hole_factory.h"
+#include "ash/services/nearby/public/cpp/fake_firewall_hole.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/self_owned_receiver.h"
+
+namespace ash {
+namespace nearby {
+
+FakeFirewallHoleFactory::FakeFirewallHoleFactory() = default;
+
+FakeFirewallHoleFactory::~FakeFirewallHoleFactory() = default;
+
+// Immediately invokes |callback| with a fake firewall hole if
+// |should_succeed_| is true and NullRemote if false.
+void FakeFirewallHoleFactory::OpenFirewallHole(
+    const ash::nearby::TcpServerSocketPort& port,
+    OpenFirewallHoleCallback callback) {
+  if (should_succeed_) {
+    mojo::PendingRemote<sharing::mojom::FirewallHole> firewall_hole;
+    mojo::MakeSelfOwnedReceiver(std::make_unique<FakeFirewallHole>(),
+                                firewall_hole.InitWithNewPipeAndPassReceiver());
+    std::move(callback).Run(std::move(firewall_hole));
+  } else {
+    std::move(callback).Run(/*firewall_hole=*/mojo::NullRemote());
+  }
+}
+
+}  // namespace nearby
+}  // namespace ash
diff --git a/ash/services/nearby/public/cpp/fake_firewall_hole_factory.h b/ash/services/nearby/public/cpp/fake_firewall_hole_factory.h
new file mode 100644
index 0000000..49e9935
--- /dev/null
+++ b/ash/services/nearby/public/cpp/fake_firewall_hole_factory.h
@@ -0,0 +1,31 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_SERVICES_NEARBY_PUBLIC_CPP_FAKE_FIREWALL_HOLE_FACTORY_H_
+#define ASH_SERVICES_NEARBY_PUBLIC_CPP_FAKE_FIREWALL_HOLE_FACTORY_H_
+
+#include "ash/services/nearby/public/mojom/firewall_hole.mojom.h"
+
+namespace ash {
+namespace nearby {
+
+// A simple implementation of sharing::mojom::FirewallHoleFactory used for
+// testing.
+class FakeFirewallHoleFactory : public sharing::mojom::FirewallHoleFactory {
+ public:
+  FakeFirewallHoleFactory();
+  ~FakeFirewallHoleFactory() override;
+
+  // Immediately invokes |callback| with a fake firewall hole if
+  // |should_succeed_| is true and NullRemote if false.
+  void OpenFirewallHole(const ash::nearby::TcpServerSocketPort& port,
+                        OpenFirewallHoleCallback callback) override;
+
+  bool should_succeed_ = true;
+};
+
+}  // namespace nearby
+}  // namespace ash
+
+#endif  // ASH_SERVICES_NEARBY_PUBLIC_CPP_FAKE_FIREWALL_HOLE_FACTORY_H_
diff --git a/chrome/services/sharing/nearby/platform/fake_tcp_connected_socket.cc b/ash/services/nearby/public/cpp/fake_tcp_connected_socket.cc
similarity index 91%
rename from chrome/services/sharing/nearby/platform/fake_tcp_connected_socket.cc
rename to ash/services/nearby/public/cpp/fake_tcp_connected_socket.cc
index 8b8be50..3897cc6 100644
--- a/chrome/services/sharing/nearby/platform/fake_tcp_connected_socket.cc
+++ b/ash/services/nearby/public/cpp/fake_tcp_connected_socket.cc
@@ -2,13 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/services/sharing/nearby/platform/fake_tcp_connected_socket.h"
+#include "ash/services/nearby/public/cpp/fake_tcp_connected_socket.h"
 
 #include "base/notreached.h"
 
-namespace location {
+namespace ash {
 namespace nearby {
-namespace chrome {
 
 FakeTcpConnectedSocket::FakeTcpConnectedSocket(
     mojo::ScopedDataPipeProducerHandle producer_handle,
@@ -59,6 +58,5 @@
   NOTIMPLEMENTED();
 }
 
-}  // namespace chrome
 }  // namespace nearby
-}  // namespace location
+}  // namespace ash
diff --git a/chrome/services/sharing/nearby/platform/fake_tcp_connected_socket.h b/ash/services/nearby/public/cpp/fake_tcp_connected_socket.h
similarity index 85%
rename from chrome/services/sharing/nearby/platform/fake_tcp_connected_socket.h
rename to ash/services/nearby/public/cpp/fake_tcp_connected_socket.h
index ce95e5c6..d4afdf9 100644
--- a/chrome/services/sharing/nearby/platform/fake_tcp_connected_socket.h
+++ b/ash/services/nearby/public/cpp/fake_tcp_connected_socket.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_SERVICES_SHARING_NEARBY_PLATFORM_FAKE_TCP_CONNECTED_SOCKET_H_
-#define CHROME_SERVICES_SHARING_NEARBY_PLATFORM_FAKE_TCP_CONNECTED_SOCKET_H_
+#ifndef ASH_SERVICES_NEARBY_PUBLIC_CPP_FAKE_TCP_CONNECTED_SOCKET_H_
+#define ASH_SERVICES_NEARBY_PUBLIC_CPP_FAKE_TCP_CONNECTED_SOCKET_H_
 
 #include "base/callback.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
@@ -11,9 +11,8 @@
 #include "services/network/public/mojom/tcp_socket.mojom.h"
 #include "services/network/public/mojom/tls_socket.mojom.h"
 
-namespace location {
+namespace ash {
 namespace nearby {
-namespace chrome {
 
 // A trivial implementation of TCPConnectedSocket that can invoke a callback
 // upon destruction. Used for unit tests.
@@ -49,8 +48,7 @@
   base::OnceClosure on_destroy_callback_;
 };
 
-}  // namespace chrome
 }  // namespace nearby
-}  // namespace location
+}  // namespace ash
 
-#endif  // CHROME_SERVICES_SHARING_NEARBY_PLATFORM_FAKE_TCP_CONNECTED_SOCKET_H_
+#endif  // ASH_SERVICES_NEARBY_PUBLIC_CPP_FAKE_TCP_CONNECTED_SOCKET_H_
diff --git a/chrome/services/sharing/nearby/platform/fake_tcp_server_socket.cc b/ash/services/nearby/public/cpp/fake_tcp_server_socket.cc
similarity index 92%
rename from chrome/services/sharing/nearby/platform/fake_tcp_server_socket.cc
rename to ash/services/nearby/public/cpp/fake_tcp_server_socket.cc
index 85631c3..eb4b677 100644
--- a/chrome/services/sharing/nearby/platform/fake_tcp_server_socket.cc
+++ b/ash/services/nearby/public/cpp/fake_tcp_server_socket.cc
@@ -2,17 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/services/sharing/nearby/platform/fake_tcp_server_socket.h"
+#include "ash/services/nearby/public/cpp/fake_tcp_server_socket.h"
 
 #include <memory>
 
-#include "chrome/services/sharing/nearby/platform/fake_tcp_connected_socket.h"
+#include "ash/services/nearby/public/cpp/fake_tcp_connected_socket.h"
 #include "mojo/public/cpp/bindings/self_owned_receiver.h"
 #include "net/base/net_errors.h"
 
-namespace location {
+namespace ash {
 namespace nearby {
-namespace chrome {
 
 FakeTcpServerSocket::FakeTcpServerSocket() = default;
 
@@ -83,6 +82,5 @@
   }
 }
 
-}  // namespace chrome
 }  // namespace nearby
-}  // namespace location
+}  // namespace ash
diff --git a/chrome/services/sharing/nearby/platform/fake_tcp_server_socket.h b/ash/services/nearby/public/cpp/fake_tcp_server_socket.h
similarity index 87%
rename from chrome/services/sharing/nearby/platform/fake_tcp_server_socket.h
rename to ash/services/nearby/public/cpp/fake_tcp_server_socket.h
index b944ef4..e841f4d 100644
--- a/chrome/services/sharing/nearby/platform/fake_tcp_server_socket.h
+++ b/ash/services/nearby/public/cpp/fake_tcp_server_socket.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_SERVICES_SHARING_NEARBY_PLATFORM_FAKE_TCP_SERVER_SOCKET_H_
-#define CHROME_SERVICES_SHARING_NEARBY_PLATFORM_FAKE_TCP_SERVER_SOCKET_H_
+#ifndef ASH_SERVICES_NEARBY_PUBLIC_CPP_FAKE_TCP_SERVER_SOCKET_H_
+#define ASH_SERVICES_NEARBY_PUBLIC_CPP_FAKE_TCP_SERVER_SOCKET_H_
 
 #include "base/callback.h"
 #include "base/containers/circular_deque.h"
@@ -11,9 +11,8 @@
 #include "net/base/ip_endpoint.h"
 #include "services/network/public/mojom/tcp_socket.mojom.h"
 
-namespace location {
+namespace ash {
 namespace nearby {
-namespace chrome {
 
 // An implementation of TCPServerSocket used for unit tests. The user sets
 // expectations--via SetAcceptCallExpectations()--for the number of Accept()
@@ -55,8 +54,7 @@
   base::circular_deque<AcceptCallback> pending_accept_callbacks_;
 };
 
-}  // namespace chrome
 }  // namespace nearby
-}  // namespace location
+}  // namespace ash
 
-#endif  // CHROME_SERVICES_SHARING_NEARBY_PLATFORM_FAKE_TCP_SERVER_SOCKET_H_
+#endif  // ASH_SERVICES_NEARBY_PUBLIC_CPP_FAKE_TCP_SERVER_SOCKET_H_
diff --git a/chrome/services/sharing/nearby/platform/fake_tcp_socket_factory.cc b/ash/services/nearby/public/cpp/fake_tcp_socket_factory.cc
similarity index 94%
rename from chrome/services/sharing/nearby/platform/fake_tcp_socket_factory.cc
rename to ash/services/nearby/public/cpp/fake_tcp_socket_factory.cc
index 8ef567e..0a7b73f 100644
--- a/chrome/services/sharing/nearby/platform/fake_tcp_socket_factory.cc
+++ b/ash/services/nearby/public/cpp/fake_tcp_socket_factory.cc
@@ -2,18 +2,17 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/services/sharing/nearby/platform/fake_tcp_socket_factory.h"
+#include "ash/services/nearby/public/cpp/fake_tcp_socket_factory.h"
 
+#include "ash/services/nearby/public/cpp/fake_tcp_connected_socket.h"
+#include "ash/services/nearby/public/cpp/fake_tcp_server_socket.h"
 #include "base/test/bind.h"
-#include "chrome/services/sharing/nearby/platform/fake_tcp_connected_socket.h"
-#include "chrome/services/sharing/nearby/platform/fake_tcp_server_socket.h"
 #include "mojo/public/cpp/bindings/self_owned_receiver.h"
 #include "mojo/public/cpp/system/data_pipe.h"
 #include "net/base/net_errors.h"
 
-namespace location {
+namespace ash {
 namespace nearby {
-namespace chrome {
 
 FakeTcpSocketFactory::FakeTcpSocketFactory(
     const net::IPEndPoint& default_local_addr)
@@ -151,6 +150,5 @@
   }
 }
 
-}  // namespace chrome
 }  // namespace nearby
-}  // namespace location
+}  // namespace ash
diff --git a/chrome/services/sharing/nearby/platform/fake_tcp_socket_factory.h b/ash/services/nearby/public/cpp/fake_tcp_socket_factory.h
similarity index 90%
rename from chrome/services/sharing/nearby/platform/fake_tcp_socket_factory.h
rename to ash/services/nearby/public/cpp/fake_tcp_socket_factory.h
index 56ce1f1..7f62afe9 100644
--- a/chrome/services/sharing/nearby/platform/fake_tcp_socket_factory.h
+++ b/ash/services/nearby/public/cpp/fake_tcp_socket_factory.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_SERVICES_SHARING_NEARBY_PLATFORM_FAKE_TCP_SOCKET_FACTORY_H_
-#define CHROME_SERVICES_SHARING_NEARBY_PLATFORM_FAKE_TCP_SOCKET_FACTORY_H_
+#ifndef ASH_SERVICES_NEARBY_PUBLIC_CPP_FAKE_TCP_SOCKET_FACTORY_H_
+#define ASH_SERVICES_NEARBY_PUBLIC_CPP_FAKE_TCP_SOCKET_FACTORY_H_
 
 #include "ash/services/nearby/public/cpp/tcp_server_socket_port.h"
 #include "ash/services/nearby/public/mojom/tcp_socket_factory.mojom.h"
@@ -12,9 +12,8 @@
 #include "net/base/ip_address.h"
 #include "net/base/ip_endpoint.h"
 
-namespace location {
+namespace ash {
 namespace nearby {
-namespace chrome {
 
 // An implementation of TcpSocketFactory used for unit tests. The user sets
 // expectations--via SetCreate{Server,Connected}SocketCallExpectations()--for
@@ -70,8 +69,7 @@
       pending_create_connected_socket_callbacks_;
 };
 
-}  // namespace chrome
 }  // namespace nearby
-}  // namespace location
+}  // namespace ash
 
-#endif  // CHROME_SERVICES_SHARING_NEARBY_PLATFORM_FAKE_TCP_SOCKET_FACTORY_H_
+#endif  // ASH_SERVICES_NEARBY_PUBLIC_CPP_FAKE_TCP_SOCKET_FACTORY_H_
diff --git a/ash/system/accessibility/dictation_bubble_controller.cc b/ash/system/accessibility/dictation_bubble_controller.cc
index 281f1b8d..e29eceb 100644
--- a/ash/system/accessibility/dictation_bubble_controller.cc
+++ b/ash/system/accessibility/dictation_bubble_controller.cc
@@ -5,6 +5,7 @@
 #include "ash/system/accessibility/dictation_bubble_controller.h"
 
 #include "ash/display/window_tree_host_manager.h"
+#include "ash/public/cpp/accessibility_controller_enums.h"
 #include "ash/shell.h"
 #include "ash/system/accessibility/dictation_bubble_view.h"
 #include "ash/wm/collision_detection/collision_detection_utils.h"
@@ -27,12 +28,14 @@
 
 void DictationBubbleController::UpdateBubble(
     bool visible,
+    DictationBubbleIconType icon,
     const absl::optional<std::u16string>& text) {
   if (visible) {
     MaybeInitialize();
-    Update(text);
+    Update(icon, text);
     widget_->Show();
   } else {
+    Update(icon, text);
     if (widget_) {
       widget_->Hide();
     }
@@ -71,12 +74,13 @@
 // TODO(crbug.com/1252037): Fix issue where bubble is shown behind current
 // Chrome tab.
 void DictationBubbleController::Update(
+    DictationBubbleIconType icon,
     const absl::optional<std::u16string>& text) {
   DCHECK(dictation_bubble_view_);
   DCHECK(widget_);
 
   // Update `dictation_bubble_view_`.
-  dictation_bubble_view_->Update(text);
+  dictation_bubble_view_->Update(icon, text);
 
   // Update the bounds to fit entirely within the screen.
   gfx::Rect new_bounds = widget_->GetWindowBoundsInScreen();
diff --git a/ash/system/accessibility/dictation_bubble_controller.h b/ash/system/accessibility/dictation_bubble_controller.h
index 55a412a5..f2662eae 100644
--- a/ash/system/accessibility/dictation_bubble_controller.h
+++ b/ash/system/accessibility/dictation_bubble_controller.h
@@ -24,6 +24,7 @@
 
 namespace ash {
 
+enum class DictationBubbleIconType;
 class DictationBubbleView;
 
 // Manages the Dictation bubble view.
@@ -36,7 +37,9 @@
   ~DictationBubbleController() override;
 
   // Updates the bubble's visibility and text content.
-  void UpdateBubble(bool visible, const absl::optional<std::u16string>& text);
+  void UpdateBubble(bool visible,
+                    DictationBubbleIconType icon,
+                    const absl::optional<std::u16string>& text);
 
   // ui::InputMethodObserver:
   void OnFocus() override {}
@@ -53,7 +56,8 @@
   void MaybeInitialize();
 
   // Updates the view and widget.
-  void Update(const absl::optional<std::u16string>& text);
+  void Update(DictationBubbleIconType icon,
+              const absl::optional<std::u16string>& text);
 
   // Owned by views hierarchy.
   DictationBubbleView* dictation_bubble_view_ = nullptr;
diff --git a/ash/system/accessibility/dictation_bubble_controller_unittest.cc b/ash/system/accessibility/dictation_bubble_controller_unittest.cc
index c235013..770ad285 100644
--- a/ash/system/accessibility/dictation_bubble_controller_unittest.cc
+++ b/ash/system/accessibility/dictation_bubble_controller_unittest.cc
@@ -36,10 +36,15 @@
   }
 
   void Show(const std::u16string& text) {
-    GetController()->UpdateBubble(/*visible=*/true, text);
+    GetController()->UpdateBubble(
+        /*visible=*/true, /*icon=*/DictationBubbleIconType::kHidden, text);
   }
 
-  void Hide() { GetController()->UpdateBubble(/*visible=*/false, u""); }
+  void Hide() {
+    GetController()->UpdateBubble(/*visible=*/false,
+                                  /*icon=*/DictationBubbleIconType::kHidden,
+                                  /*text=*/std::u16string());
+  }
 
   DictationBubbleView* GetView() {
     return GetController()->dictation_bubble_view_;
diff --git a/ash/system/accessibility/dictation_bubble_view.cc b/ash/system/accessibility/dictation_bubble_view.cc
index 3198831..138882b 100644
--- a/ash/system/accessibility/dictation_bubble_view.cc
+++ b/ash/system/accessibility/dictation_bubble_view.cc
@@ -4,6 +4,7 @@
 
 #include "ash/system/accessibility/dictation_bubble_view.h"
 
+#include "ash/public/cpp/accessibility_controller_enums.h"
 #include "ash/resources/vector_icons/vector_icons.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "ui/accessibility/ax_enums.mojom.h"
@@ -30,13 +31,17 @@
 
 DictationBubbleView::~DictationBubbleView() = default;
 
-void DictationBubbleView::Update(const absl::optional<std::u16string>& text) {
-  bool has_text = text.has_value();
-  // Show either the image view, which is a placeholder when there is no text
-  // to be displayed, or the label view. Never show both at the same time.
-  image_view_->SetVisible(!has_text);
-  label_->SetVisible(has_text);
-  label_->SetText(has_text ? text.value() : std::u16string());
+void DictationBubbleView::Update(DictationBubbleIconType icon,
+                                 const absl::optional<std::u16string>& text) {
+  // Update icon visibility.
+  standby_image_->SetVisible(icon == DictationBubbleIconType::kStandby);
+  macro_succeeded_image_->SetVisible(icon ==
+                                     DictationBubbleIconType::kMacroSuccess);
+  macro_failed_image_->SetVisible(icon == DictationBubbleIconType::kMacroFail);
+
+  // Update label.
+  label_->SetVisible(text.has_value());
+  label_->SetText(text.has_value() ? text.value() : std::u16string());
   SizeToContents();
 }
 
@@ -49,7 +54,19 @@
   UseCompactMargins();
   SetBackground(views::CreateSolidBackground(kBackgroundColor));
 
-  AddChildView(CreateIcon());
+  auto create_image_view = [](views::ImageView** destination_view,
+                              const gfx::VectorIcon& icon) {
+    return views::Builder<views::ImageView>()
+        .CopyAddressTo(destination_view)
+        .SetImage(gfx::CreateVectorIcon(icon, kIconSizeDip, kIconAndLabelColor))
+        .Build();
+  };
+
+  AddChildView(create_image_view(&standby_image_, kDictationBubbleIcon));
+  AddChildView(create_image_view(&macro_succeeded_image_,
+                                 kDictationBubbleMacroSucceededIcon));
+  AddChildView(
+      create_image_view(&macro_failed_image_, kDictationBubbleMacroFailedIcon));
   AddChildView(CreateLabel(std::u16string()));
 }
 
@@ -71,12 +88,16 @@
   return label_->GetText();
 }
 
-std::unique_ptr<views::ImageView> DictationBubbleView::CreateIcon() {
-  return views::Builder<views::ImageView>()
-      .CopyAddressTo(&image_view_)
-      .SetImage(gfx::CreateVectorIcon(kDictationBubbleIcon, kIconSizeDip,
-                                      kIconAndLabelColor))
-      .Build();
+bool DictationBubbleView::IsStandbyImageVisibleForTesting() {
+  return standby_image_->GetVisible();
+}
+
+bool DictationBubbleView::IsMacroSucceededImageVisibleForTesting() {
+  return macro_succeeded_image_->GetVisible();
+}
+
+bool DictationBubbleView::IsMacroFailedImageVisibleForTesting() {
+  return macro_failed_image_->GetVisible();
 }
 
 std::unique_ptr<views::Label> DictationBubbleView::CreateLabel(
diff --git a/ash/system/accessibility/dictation_bubble_view.h b/ash/system/accessibility/dictation_bubble_view.h
index 4be5238..3b911be 100644
--- a/ash/system/accessibility/dictation_bubble_view.h
+++ b/ash/system/accessibility/dictation_bubble_view.h
@@ -25,6 +25,8 @@
 
 namespace ash {
 
+enum class DictationBubbleIconType;
+
 // View for the Dictation bubble.
 class ASH_EXPORT DictationBubbleView : public views::BubbleDialogDelegateView {
  public:
@@ -34,9 +36,10 @@
   DictationBubbleView& operator=(const DictationBubbleView&) = delete;
   ~DictationBubbleView() override;
 
-  // Updates the visibility and text content of `label_`. Also updates the size
-  // of this view.
-  void Update(const absl::optional<std::u16string>& text);
+  // Updates the visibility of all child views. Also updates the text content
+  // of `label_` and updates the size of this view.
+  void Update(DictationBubbleIconType icon,
+              const absl::optional<std::u16string>& text);
 
   // views::BubbleDialogDelegateView:
   void Init() override;
@@ -47,13 +50,21 @@
   void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
 
   std::u16string GetTextForTesting();
+  bool IsStandbyImageVisibleForTesting();
+  bool IsMacroSucceededImageVisibleForTesting();
+  bool IsMacroFailedImageVisibleForTesting();
 
  private:
-  std::unique_ptr<views::ImageView> CreateIcon();
   std::unique_ptr<views::Label> CreateLabel(const std::u16string& text);
 
   // Owned by the views hierarchy.
-  views::ImageView* image_view_ = nullptr;
+  // An image that is shown when Dictation is standing by.
+  views::ImageView* standby_image_ = nullptr;
+  // An image that is shown when a macro is successfully run.
+  views::ImageView* macro_succeeded_image_ = nullptr;
+  // An image that is shown when a macro fails to run.
+  views::ImageView* macro_failed_image_ = nullptr;
+  // A label that displays non-final speech results.
   views::Label* label_ = nullptr;
 };
 
diff --git a/ash/system/accessibility/dictation_button_tray.cc b/ash/system/accessibility/dictation_button_tray.cc
index da45fd76..f616a44 100644
--- a/ash/system/accessibility/dictation_button_tray.cc
+++ b/ash/system/accessibility/dictation_button_tray.cc
@@ -21,11 +21,23 @@
 #include "ui/accessibility/accessibility_features.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/compositor/layer.h"
+#include "ui/gfx/geometry/transform_util.h"
 #include "ui/gfx/paint_vector_icon.h"
+#include "ui/views/animation/animation_builder.h"
 #include "ui/views/border.h"
 #include "ui/views/controls/image_view.h"
 
 namespace ash {
+namespace {
+
+// Animation.
+constexpr base::TimeDelta kInProgressAnimationOpacityDuration =
+    base::Milliseconds(100);
+constexpr base::TimeDelta kInProgressAnimationScaleDelay =
+    base::Milliseconds(50);
+constexpr base::TimeDelta kInProgressAnimationScaleDuration =
+    base::Milliseconds(166);
+constexpr float kInProgressAnimationScaleFactor = 0.875f;
 
 // Helper function that creates an image for the dictation icon.
 gfx::ImageSkia GetIconImage(bool enabled) {
@@ -35,6 +47,8 @@
                  : gfx::CreateVectorIcon(kDictationOffNewuiIcon, color);
 }
 
+}  // namespace
+
 DictationProgressIndicator::DictationProgressIndicator(
     const DictationButtonTray* tray)
     : HoldingSpaceProgressIndicator(/*animation_key=*/tray), tray_(tray) {}
@@ -129,12 +143,13 @@
   TrayBackgroundView::OnThemeChanged();
   icon_->SetImage(GetIconImage(
       Shell::Get()->accessibility_controller()->dictation_active()));
+  if (progress_indicator_)
+    progress_indicator_->InvalidateLayer();
 }
 
 void DictationButtonTray::Layout() {
   TrayBackgroundView::Layout();
-  if (progress_indicator_)
-    progress_indicator_->layer()->SetBounds(GetBackgroundBounds());
+  UpdateProgressIndicatorBounds();
 }
 
 const char* DictationButtonTray::GetClassName() const {
@@ -151,6 +166,79 @@
   SetIsActive(dictation_active);
 }
 
+void DictationButtonTray::UpdateIconOpacityAndTransform() {
+  // Updating the tray `icon_` opacity and transform is done to prevent overlap
+  // with the inner icon of the `progress_indicator_` which is only present when
+  // in-progress animation v2 is enabled.
+  if (!features::IsHoldingSpaceInProgressAnimationV2Enabled() ||
+      !progress_indicator_) {
+    return;
+  }
+
+  // When `progress` is not `complete`, the `progress_indicator_` will paint an
+  // inner icon in the same position as the tray `icon_`. To prevent overlap,
+  // the tray `icon_` should be hidden when downloading is in `progress`.
+  const absl::optional<float>& progress = progress_indicator_->progress();
+  bool complete = progress == HoldingSpaceProgressIndicator::kProgressComplete;
+  float target_opacity = complete ? 1.f : 0.f;
+
+  // Lazily create a `layer` for `icon_`.
+  ui::Layer* layer = icon_->layer();
+  if (!layer) {
+    icon_->SetPaintToLayer();
+    layer = icon_->layer();
+    layer->SetFillsBoundsOpaquely(false);
+  }
+
+  // No-op if the tray `icon_` is already animating towards the desired state.
+  if (layer->GetTargetOpacity() == target_opacity)
+    return;
+
+  // When the tray `icon_` should be hidden, it should be hidden immediately
+  // without animation to prevent overlapping with the `progress_indicator_`'s
+  // inner icon.
+  if (target_opacity == 0.f) {
+    layer->SetOpacity(0.f);
+    return;
+  }
+
+  // When the tray `icon_` has not yet been laid out, it is not necessary to
+  // animate it in. We can do so immediately.
+  const gfx::Rect& bounds = icon_->bounds();
+  if (bounds.IsEmpty()) {
+    layer->SetOpacity(1.f);
+    layer->SetTransform(gfx::Transform());
+    return;
+  }
+
+  const auto preemption_strategy =
+      ui::LayerAnimator::PreemptionStrategy::IMMEDIATELY_ANIMATE_TO_NEW_TARGET;
+  const auto transform = gfx::GetScaleTransform(
+      bounds.CenterPoint(), kInProgressAnimationScaleFactor);
+  const auto tween_type = gfx::Tween::Type::FAST_OUT_SLOW_IN_3;
+
+  // Animate the tray `icon_` from:
+  // * Opacity: 0% -> 100%
+  // * Scale: 87.5% -> 100%
+  views::AnimationBuilder()
+      .SetPreemptionStrategy(preemption_strategy)
+      .Once()
+      .SetDuration(base::TimeDelta())
+      .SetOpacity(layer, 0.f)
+      .SetTransform(layer, transform)
+      .Then()
+      .SetDuration(kInProgressAnimationOpacityDuration)
+      .SetOpacity(layer, 1.f)
+      .Offset(kInProgressAnimationScaleDelay)
+      .SetDuration(kInProgressAnimationScaleDuration)
+      .SetTransform(layer, gfx::Transform(), tween_type);
+}
+
+void DictationButtonTray::UpdateProgressIndicatorBounds() {
+  if (progress_indicator_)
+    progress_indicator_->layer()->SetBounds(GetBackgroundBounds());
+}
+
 void DictationButtonTray::UpdateVisibility() {
   bool is_visible =
       Shell::Get()->accessibility_controller()->dictation().enabled();
@@ -178,9 +266,15 @@
   download_progress_ = download_progress;
   if (!progress_indicator_) {
     // A progress indicator that is only visible when a SODA download is
-    // in-progress.
+    // in-progress and a subscription to receive notification of progress
+    // changed events.
     progress_indicator_ = std::make_unique<DictationProgressIndicator>(this);
+    progress_changed_subscription_ =
+        progress_indicator_->AddProgressChangedCallback(base::BindRepeating(
+            &DictationButtonTray::UpdateIconOpacityAndTransform,
+            base::Unretained(this)));
     layer()->Add(progress_indicator_->CreateLayer());
+    UpdateProgressIndicatorBounds();
   }
   progress_indicator_->InvalidateLayer();
 }
diff --git a/ash/system/accessibility/dictation_button_tray.h b/ash/system/accessibility/dictation_button_tray.h
index fec551c..7bb89d62 100644
--- a/ash/system/accessibility/dictation_button_tray.h
+++ b/ash/system/accessibility/dictation_button_tray.h
@@ -16,7 +16,7 @@
 
 namespace views {
 class ImageView;
-}
+}  // namespace views
 
 namespace ash {
 
@@ -86,13 +86,20 @@
   friend class DictationButtonTrayTest;
   friend class DictationButtonTraySodaTest;
 
-  // Updates the visibility of the button.
-  void UpdateVisibility();
-
-  // Sets the icon when Dictation is activated / deactiviated.
+  // Sets the icon when Dictation is activated / deactivated.
   // Also updates visibility when Dictation is enabled / disabled.
   void UpdateIcon(bool dictation_active);
 
+  // Updates opacity and transform for `icon_` to prevent overlap with the
+  // `progress_indicator_` when downloading is in progress.
+  void UpdateIconOpacityAndTransform();
+
+  // Updates bounds for `progress_indicator_`.
+  void UpdateProgressIndicatorBounds();
+
+  // Updates the visibility of the button.
+  void UpdateVisibility();
+
   // Actively looks up dictation status and calls UpdateIcon.
   void CheckDictationStatusAndUpdateIcon();
 
@@ -103,8 +110,10 @@
   // in-progress.
   int download_progress_;
 
-  // A progress indicator to indicate SODA download progress.
+  // A progress indicator to indicate SODA download progress and a subscription
+  // to be notified of progress changed events.
   std::unique_ptr<DictationProgressIndicator> progress_indicator_;
+  base::CallbackListSubscription progress_changed_subscription_;
 };
 
 }  // namespace ash
diff --git a/ash/system/accessibility/dictation_button_tray_unittest.cc b/ash/system/accessibility/dictation_button_tray_unittest.cc
index 8ad6d4d..3d533c9 100644
--- a/ash/system/accessibility/dictation_button_tray_unittest.cc
+++ b/ash/system/accessibility/dictation_button_tray_unittest.cc
@@ -25,6 +25,7 @@
 #include "ash/wm/window_util.h"
 #include "base/command_line.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/test/bind.h"
 #include "base/test/metrics/user_action_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/time/time.h"
@@ -60,8 +61,37 @@
                           ui::GestureEventDetails(ui::ET_GESTURE_TAP));
 }
 
+// ProgressIndicatorWaiter -----------------------------------------------------
+
+// A class which supports waiting for a progress indicator to reach a desired
+// state of progress.
+class ProgressIndicatorWaiter {
+ public:
+  ProgressIndicatorWaiter() = default;
+  ProgressIndicatorWaiter(const ProgressIndicatorWaiter&) = delete;
+  ProgressIndicatorWaiter& operator=(const ProgressIndicatorWaiter&) = delete;
+  ~ProgressIndicatorWaiter() = default;
+
+  // Waits for `progress_indicator` to reach the specified `progress`. If the
+  // `progress_indicator` is already at `progress`, this method no-ops.
+  void WaitForProgress(HoldingSpaceProgressIndicator* progress_indicator,
+                       const absl::optional<float>& progress) {
+    if (progress_indicator->progress() == progress)
+      return;
+    base::RunLoop run_loop;
+    auto subscription = progress_indicator->AddProgressChangedCallback(
+        base::BindLambdaForTesting([&]() {
+          if (progress_indicator->progress() == progress)
+            run_loop.Quit();
+        }));
+    run_loop.Run();
+  }
+};
+
 }  // namespace
 
+// DictationButtonTrayTest -----------------------------------------------------
+
 class DictationButtonTrayTest : public AshTestBase {
  public:
   DictationButtonTrayTest() = default;
@@ -69,6 +99,7 @@
   DictationButtonTrayTest(const DictationButtonTrayTest&) = delete;
   DictationButtonTrayTest& operator=(const DictationButtonTrayTest&) = delete;
 
+  // AshTestBase:
   void SetUp() override { AshTestBase::SetUp(); }
 
  protected:
@@ -139,7 +170,12 @@
   EXPECT_FALSE(GetTray()->is_active());
 }
 
-class DictationButtonTraySodaTest : public DictationButtonTrayTest {
+// Base class for SODA tests of the dictation button tray, parameterized by
+// whether in-progress animation v2 is enabled.
+class DictationButtonTraySodaTest
+    : public DictationButtonTrayTest,
+      public testing::WithParamInterface<
+          /*in_progress_animation_v2_enabled=*/bool> {
  public:
   DictationButtonTraySodaTest() = default;
   ~DictationButtonTraySodaTest() override = default;
@@ -147,12 +183,24 @@
   DictationButtonTraySodaTest& operator=(const DictationButtonTraySodaTest&) =
       delete;
 
+  // Returns whether in-progress animation v2 is enabled given test
+  // parameterization.
+  bool IsInProgressAnimationV2Enabled() const { return GetParam(); }
+
+  // DictationButtonTrayTest:
   void SetUp() override {
     DictationButtonTrayTest::SetUp();
-    scoped_feature_list_.InitWithFeatures(
-        {::features::kExperimentalAccessibilityDictationOffline,
-         features::kOnDeviceSpeechRecognition},
-        {});
+
+    std::vector<base::Feature> enabled_features = {
+        ::features::kExperimentalAccessibilityDictationOffline,
+        features::kOnDeviceSpeechRecognition};
+    std::vector<base::Feature> disabled_features;
+
+    // Enable/disable in-progress animation v2 based on test parameterization.
+    (IsInProgressAnimationV2Enabled() ? enabled_features : disabled_features)
+        .push_back(features::kHoldingSpaceInProgressAnimationV2);
+
+    scoped_feature_list_.InitWithFeatures(enabled_features, disabled_features);
 
     // Since this test suite is part of ash unit tests, the
     // SodaInstallerImplChromeOS is never created (it's normally created when
@@ -167,6 +215,10 @@
     AshTestBase::TearDown();
   }
 
+  HoldingSpaceProgressIndicator* GetProgressIndicator() {
+    return GetTray()->progress_indicator_.get();
+  }
+
   float GetProgressIndicatorProgress() {
     DCHECK(GetTray()->progress_indicator_);
     absl::optional<float> progress =
@@ -175,6 +227,17 @@
     return progress.value();
   }
 
+  bool IsImageVisible() {
+    DCHECK(GetTray()->icon_);
+
+    ui::Layer* const layer = GetTray()->icon_->layer();
+    if (!layer)
+      return true;
+
+    return layer->GetTargetOpacity() == 1.f &&
+           layer->GetTargetTransform() == gfx::Transform();
+  }
+
   bool IsProgressIndicatorVisible() {
     DCHECK(GetTray()->progress_indicator_);
     return GetTray()->progress_indicator_->IsVisible();
@@ -185,13 +248,18 @@
   std::unique_ptr<speech::SodaInstallerImplChromeOS> soda_installer_impl_;
 };
 
+INSTANTIATE_TEST_SUITE_P(All,
+                         DictationButtonTraySodaTest,
+                         /*in_progress_animation_v2_enabled=*/testing::Bool());
+
 // Tests the behavior of the UpdateOnSpeechRecognitionDownloadChanged() method.
-TEST_F(DictationButtonTraySodaTest, UpdateOnSpeechRecognitionDownloadChanged) {
+TEST_P(DictationButtonTraySodaTest, UpdateOnSpeechRecognitionDownloadChanged) {
   AccessibilityControllerImpl* controller =
       Shell::Get()->accessibility_controller();
   controller->dictation().SetEnabled(true);
   DictationButtonTray* tray = GetTray();
   views::ImageView* image = GetImageView(tray);
+  EXPECT_TRUE(IsImageVisible());
 
   // Download progress of 0 indicates that download is not in-progress.
   tray->UpdateOnSpeechRecognitionDownloadChanged(/*download_progress=*/0);
@@ -200,6 +268,12 @@
   EXPECT_EQ(base::UTF8ToUTF16(kEnabledTooltip), image->GetTooltipText());
   EXPECT_FALSE(IsProgressIndicatorVisible());
 
+  // The tray icon should be visible when the download is not in-progress.
+  HoldingSpaceProgressIndicator* progress_indicator = GetProgressIndicator();
+  ProgressIndicatorWaiter().WaitForProgress(
+      progress_indicator, HoldingSpaceProgressIndicator::kProgressComplete);
+  EXPECT_TRUE(IsImageVisible());
+
   // Any number 0 < number < 100 means that download is in-progress.
   tray->UpdateOnSpeechRecognitionDownloadChanged(/*download_progress=*/50);
   EXPECT_EQ(50, tray->download_progress());
@@ -208,6 +282,11 @@
   EXPECT_TRUE(IsProgressIndicatorVisible());
   EXPECT_EQ(0.5f, GetProgressIndicatorProgress());
 
+  // If in-progress animation v2 is enabled, the tray icon should *not* be
+  // visible when the download is in progress.
+  ProgressIndicatorWaiter().WaitForProgress(progress_indicator, 0.5f);
+  EXPECT_NE(IsImageVisible(), IsInProgressAnimationV2Enabled());
+
   tray->UpdateOnSpeechRecognitionDownloadChanged(/*download_progress=*/70);
   EXPECT_EQ(70, tray->download_progress());
   EXPECT_FALSE(tray->GetEnabled());
@@ -215,12 +294,22 @@
   EXPECT_TRUE(IsProgressIndicatorVisible());
   EXPECT_EQ(0.7f, GetProgressIndicatorProgress());
 
+  // If in-progress animation v2 is enabled, the tray icon should *not* be
+  // visible when the download is in progress.
+  ProgressIndicatorWaiter().WaitForProgress(progress_indicator, 0.7f);
+  EXPECT_NE(IsImageVisible(), IsInProgressAnimationV2Enabled());
+
   // Similar to 0, a value of 100 means that download is not in-progress.
   tray->UpdateOnSpeechRecognitionDownloadChanged(/*download_progress=*/100);
   EXPECT_EQ(100, tray->download_progress());
   EXPECT_TRUE(tray->GetEnabled());
   EXPECT_EQ(base::UTF8ToUTF16(kEnabledTooltip), image->GetTooltipText());
   EXPECT_FALSE(IsProgressIndicatorVisible());
+
+  // The tray icon should be visible when the download is not in-progress.
+  ProgressIndicatorWaiter().WaitForProgress(
+      progress_indicator, HoldingSpaceProgressIndicator::kProgressComplete);
+  EXPECT_TRUE(IsImageVisible());
 }
 
 }  // namespace ash
diff --git a/ash/system/bluetooth/bluetooth_device_status_ui_handler.cc b/ash/system/bluetooth/bluetooth_device_status_ui_handler.cc
index 75ba701..bfda089 100644
--- a/ash/system/bluetooth/bluetooth_device_status_ui_handler.cc
+++ b/ash/system/bluetooth/bluetooth_device_status_ui_handler.cc
@@ -6,8 +6,9 @@
 
 #include "ash/constants/ash_features.h"
 #include "ash/public/cpp/bluetooth_config_service.h"
-#include "ash/public/cpp/toast_data.h"
-#include "ash/public/cpp/toast_manager.h"
+#include "ash/public/cpp/system/toast_catalog.h"
+#include "ash/public/cpp/system/toast_data.h"
+#include "ash/public/cpp/system/toast_manager.h"
 #include "ash/strings/grit/ash_strings.h"
 #include "base/check.h"
 #include "chromeos/services/bluetooth_config/public/cpp/cros_bluetooth_config_util.h"
@@ -39,6 +40,7 @@
     PairedBluetoothDevicePropertiesPtr device) {
   ash::ToastData toast_data(
       /*id=*/GetToastId(device.get()),
+      ash::ToastCatalogName::kBluetoothDevicePaired,
       /*text=*/
       l10n_util::GetStringFUTF16(
           IDS_ASH_STATUS_TRAY_BLUETOOTH_PAIRED_OR_CONNECTED_TOAST,
@@ -52,6 +54,7 @@
     PairedBluetoothDevicePropertiesPtr device) {
   ash::ToastData toast_data(
       /*id=*/GetToastId(device.get()),
+      ash::ToastCatalogName::kBluetoothDeviceDisconnected,
       /*text=*/
       l10n_util::GetStringFUTF16(
           IDS_ASH_STATUS_TRAY_BLUETOOTH_DISCONNECTED_TOAST,
@@ -65,6 +68,7 @@
     PairedBluetoothDevicePropertiesPtr device) {
   ash::ToastData toast_data(
       /*id=*/GetToastId(device.get()),
+      ash::ToastCatalogName::kBluetoothDeviceConnected,
       /*text=*/
       l10n_util::GetStringFUTF16(
           IDS_ASH_STATUS_TRAY_BLUETOOTH_PAIRED_OR_CONNECTED_TOAST,
diff --git a/ash/system/bluetooth/bluetooth_device_status_ui_handler.h b/ash/system/bluetooth/bluetooth_device_status_ui_handler.h
index d4152c88..1079d19 100644
--- a/ash/system/bluetooth/bluetooth_device_status_ui_handler.h
+++ b/ash/system/bluetooth/bluetooth_device_status_ui_handler.h
@@ -6,7 +6,7 @@
 #define ASH_SYSTEM_BLUETOOTH_BLUETOOTH_DEVICE_STATUS_UI_HANDLER_H_
 
 #include "ash/ash_export.h"
-#include "ash/public/cpp/toast_manager.h"
+#include "ash/public/cpp/system/toast_manager.h"
 #include "chromeos/services/bluetooth_config/public/mojom/cros_bluetooth_config.mojom.h"
 #include "mojo/public/cpp/bindings/receiver.h"
 #include "mojo/public/cpp/bindings/remote.h"
diff --git a/ash/system/bluetooth/bluetooth_device_status_ui_handler_unittest.cc b/ash/system/bluetooth/bluetooth_device_status_ui_handler_unittest.cc
index afa2557..2b3e898 100644
--- a/ash/system/bluetooth/bluetooth_device_status_ui_handler_unittest.cc
+++ b/ash/system/bluetooth/bluetooth_device_status_ui_handler_unittest.cc
@@ -5,7 +5,7 @@
 #include "ash/system/bluetooth/bluetooth_device_status_ui_handler.h"
 
 #include "ash/constants/ash_features.h"
-#include "ash/public/cpp/toast_manager.h"
+#include "ash/public/cpp/system/toast_manager.h"
 #include "ash/strings/grit/ash_strings.h"
 #include "ash/test/ash_test_base.h"
 #include "base/test/scoped_feature_list.h"
diff --git a/ash/system/bluetooth/bluetooth_notification_controller.cc b/ash/system/bluetooth/bluetooth_notification_controller.cc
index 5d16fcd..e6a5974e 100644
--- a/ash/system/bluetooth/bluetooth_notification_controller.cc
+++ b/ash/system/bluetooth/bluetooth_notification_controller.cc
@@ -9,8 +9,9 @@
 
 #include "ash/public/cpp/nearby_share_delegate.h"
 #include "ash/public/cpp/notification_utils.h"
+#include "ash/public/cpp/system/toast_catalog.h"
+#include "ash/public/cpp/system/toast_data.h"
 #include "ash/public/cpp/system_tray_client.h"
-#include "ash/public/cpp/toast_data.h"
 #include "ash/resources/vector_icons/vector_icons.h"
 #include "ash/services/nearby/public/cpp/nearby_client_uuids.h"
 #include "ash/shell.h"
@@ -129,8 +130,10 @@
                                            false /* by_user */);
 }
 
-void ShowToast(const std::string& id, const std::u16string& text) {
-  ash::ToastManager::Get()->Show(ash::ToastData(id, text));
+void ShowToast(const std::string& id,
+               ToastCatalogName catalog_name,
+               const std::u16string& text) {
+  ash::ToastManager::Get()->Show(ash::ToastData(id, catalog_name, text));
 }
 
 }  // namespace
@@ -318,6 +321,7 @@
 
   ShowToast(
       kBluetoothDeviceDiscoverableToastId,
+      ToastCatalogName::kBluetoothAdapterDiscoverable,
       l10n_util::GetStringFUTF16(IDS_ASH_STATUS_TRAY_BLUETOOTH_DISCOVERABLE,
                                  base::UTF8ToUTF16(adapter_->GetName())));
 }
diff --git a/ash/system/holding_space/holding_space_animation_registry.cc b/ash/system/holding_space/holding_space_animation_registry.cc
index 428e498..d905f48 100644
--- a/ash/system/holding_space/holding_space_animation_registry.cc
+++ b/ash/system/holding_space/holding_space_animation_registry.cc
@@ -122,6 +122,39 @@
                                                : nullptr;
   }
 
+  // Sets and returns the registered icon animation for the specified `key`.
+  // NOTE: This method accepts `nullptr` to support un-registration.
+  HoldingSpaceProgressIconAnimation* SetIconAnimationForKey(
+      const void* key,
+      std::unique_ptr<HoldingSpaceProgressIconAnimation> animation) {
+    HoldingSpaceProgressIconAnimation* animation_ptr = animation.get();
+    if (animation) {
+      icon_animations_by_key_[key] = std::move(animation);
+      NotifyIconAnimationChangedForKey(key);
+    } else {
+      EraseIconAnimationForKey(key);
+    }
+    return animation_ptr;
+  }
+
+  // Sets and returns the registered ring animation for the specified `key`.
+  // NOTE: This method accepts `nullptr` to support un-registration.
+  HoldingSpaceProgressRingAnimation* SetRingAnimationForKey(
+      const void* key,
+      std::unique_ptr<HoldingSpaceProgressRingAnimation> animation) {
+    HoldingSpaceProgressRingAnimation* animation_ptr = animation.get();
+    if (animation) {
+      ring_animations_by_key_[key] = SubscribedProgressRingAnimation{
+          .animation = std::move(animation),
+          .subscription = base::CallbackListSubscription(),
+      };
+      NotifyRingAnimationChangedForKey(key);
+    } else {
+      EraseRingAnimationForKey(key);
+    }
+    return animation_ptr;
+  }
+
  private:
   // HoldingSpaceControllerObserver:
   void OnHoldingSpaceModelAttached(HoldingSpaceModel* model) override {
@@ -565,6 +598,22 @@
   return progress_indicator_animation_delegate_->GetRingAnimationForKey(key);
 }
 
+HoldingSpaceProgressIconAnimation*
+HoldingSpaceAnimationRegistry::SetProgressIconAnimationForKey(
+    const void* key,
+    std::unique_ptr<HoldingSpaceProgressIconAnimation> animation) {
+  return progress_indicator_animation_delegate_->SetIconAnimationForKey(
+      key, std::move(animation));
+}
+
+HoldingSpaceProgressRingAnimation*
+HoldingSpaceAnimationRegistry::SetProgressRingAnimationForKey(
+    const void* key,
+    std::unique_ptr<HoldingSpaceProgressRingAnimation> animation) {
+  return progress_indicator_animation_delegate_->SetRingAnimationForKey(
+      key, std::move(animation));
+}
+
 void HoldingSpaceAnimationRegistry::OnShellDestroying() {
   auto& instance_owner = GetInstanceOwner();
   DCHECK_EQ(instance_owner.get(), this);
diff --git a/ash/system/holding_space/holding_space_animation_registry.h b/ash/system/holding_space/holding_space_animation_registry.h
index cf7979e..8088b84 100644
--- a/ash/system/holding_space/holding_space_animation_registry.h
+++ b/ash/system/holding_space/holding_space_animation_registry.h
@@ -5,6 +5,8 @@
 #ifndef ASH_SYSTEM_HOLDING_SPACE_HOLDING_SPACE_ANIMATION_REGISTRY_H_
 #define ASH_SYSTEM_HOLDING_SPACE_HOLDING_SPACE_ANIMATION_REGISTRY_H_
 
+#include <memory>
+
 #include "ash/ash_export.h"
 #include "ash/shell.h"
 #include "ash/shell_observer.h"
@@ -17,11 +19,23 @@
 class HoldingSpaceProgressIconAnimation;
 class HoldingSpaceProgressRingAnimation;
 
-// A lazily initialized singleton registry for holding space animations. Since
-// registered animations are owned by the singleton, they can be shared across
-// different UI components as well have a lifetime which is decoupled from UI
-// component lifetime. Note that the singleton may only exist while `Shell` is
-// alive and will automatically delete itself when `Shell` is being destroyed.
+// A lazily initialized singleton registry for holding space animations.
+//
+// Since registered animations are owned by the singleton, they can be shared
+// across different UI components as well have a lifetime which is decoupled
+// from UI component lifetime. Note that the singleton may only exist while
+// `Shell` is alive and will automatically delete itself when `Shell` is being
+// destroyed.
+//
+// Supported animation types:
+//   * Progress icon animation - independently drive the animation of properties
+//     for a progress indicator's inner icon, as opposed to progress ring
+//     animations which independently drive the animation of properties for a
+//     progress indicator's outer ring.
+//   * Progress ring animation - independently drive the animation of properties
+//     for a progress indicator's outer ring, as opposed to progress icon
+//     animations which independently drive the animation of properties for a
+//     progress indicator's inner icon.
 class ASH_EXPORT HoldingSpaceAnimationRegistry : public ShellObserver {
  public:
   HoldingSpaceAnimationRegistry(const HoldingSpaceAnimationRegistry&) = delete;
@@ -38,12 +52,9 @@
       base::RepeatingCallbackList<void(HoldingSpaceProgressIconAnimation*)>;
 
   // Adds the specified `callback` to be notified of changes to the progress
-  // icon animation associated with the specified `key`. Progress icon
-  // animations independently drive the animation of properties for a progress
-  // indicator's inner icon, as opposed to progress ring animations which
-  // independently drive the animation of properties for a progress indicator's
-  // outer ring. The `callback` will continue to receive events so long as both
-  // `this` and the returned subscription exist.
+  // icon animation associated with the specified `key`. The `callback` will
+  // continue to receive events so long as both `this` and the returned
+  // subscription exist.
   base::CallbackListSubscription AddProgressIconAnimationChangedCallbackForKey(
       const void* key,
       ProgressIconAnimationChangedCallbackList::CallbackType callback);
@@ -52,38 +63,41 @@
       base::RepeatingCallbackList<void(HoldingSpaceProgressRingAnimation*)>;
 
   // Adds the specified `callback` to be notified of changes to the progress
-  // ring animation associated with the specified `key`. Progress ring
-  // animations independently drive the animation of properties for a progress
-  // indicator's outer ring, as opposed to progress icon animations which
-  // independently drive the animation of properties for a progress indicator's
-  // inner icon. The `callback` will continue to receive events so long as both
-  // `this` and the returned subscription exist.
+  // ring animation associated with the specified `key`. The `callback` will
+  // continue to receive events so long as both `this` and the returned
+  // subscription exist.
   base::CallbackListSubscription AddProgressRingAnimationChangedCallbackForKey(
       const void* key,
       ProgressRingAnimationChangedCallbackList::CallbackType callback);
 
-  // Returns the progress icon animation registered for the specified `key`.
-  // Progress icon animations independently drive the animation of properties
-  // for a progress indicator's inner icon, as opposed to progress ring
-  // animations which independently drive the animation of properties for a
-  // progress indicator's outer ring. For cumulative progress, the animation is
-  // keyed on a pointer to the holding space controller. For individual item
-  // progress, the animation is keyed on a pointer to the holding space item
-  // itself. NOTE: This may return `nullptr` if no such animation is registered.
+  // Returns the progress icon animation registered for the specified `key`. For
+  // cumulative progress, the animation is keyed on a pointer to the holding
+  // space controller. For individual item progress, the animation is keyed on a
+  // pointer to the holding space item itself. NOTE: This may return `nullptr`
+  // if no such animation is registered.
   HoldingSpaceProgressIconAnimation* GetProgressIconAnimationForKey(
       const void* key);
 
-  // Returns the progress ring animation registered for the specified `key`.
-  // Progress ring animations independently drive the animation of properties
-  // for a progress indicator's outer ring, as opposed to progress icon
-  // animations which independently drive the animation of properties for a
-  // progress indicator's inner icon. For cumulative progress, the animation is
-  // keyed on a pointer to the holding space controller. For individual item
-  // progress, the animation is keyed on a pointer to the holding space item
-  // itself. NOTE: This may return `nullptr` if no such animation is registered.
+  // Returns the progress ring animation registered for the specified `key`. For
+  // cumulative progress, the animation is keyed on a pointer to the holding
+  // space controller. For individual item progress, the animation is keyed on a
+  // pointer to the holding space item itself. NOTE: This may return `nullptr`
+  // if no such animation is registered.
   HoldingSpaceProgressRingAnimation* GetProgressRingAnimationForKey(
       const void* key);
 
+  // Sets and returns the progress icon animation registered for the specified
+  // `key`. NOTE: This method accepts `nullptr` to support un-registration.
+  HoldingSpaceProgressIconAnimation* SetProgressIconAnimationForKey(
+      const void* key,
+      std::unique_ptr<HoldingSpaceProgressIconAnimation> animation);
+
+  // Sets and returns the progress ring animation registered for the specified
+  // `key`. NOTE: This method accepts `nullptr` to support un-registration.
+  HoldingSpaceProgressRingAnimation* SetProgressRingAnimationForKey(
+      const void* key,
+      std::unique_ptr<HoldingSpaceProgressRingAnimation> animation);
+
  private:
   HoldingSpaceAnimationRegistry();
 
diff --git a/ash/system/holding_space/holding_space_animation_registry_unittest.cc b/ash/system/holding_space/holding_space_animation_registry_unittest.cc
index 74377bd..61645c5 100644
--- a/ash/system/holding_space/holding_space_animation_registry_unittest.cc
+++ b/ash/system/holding_space/holding_space_animation_registry_unittest.cc
@@ -233,4 +233,77 @@
   }
 }
 
+TEST_P(HoldingSpaceAnimationRegistryTest, SetProgressIconAnimationForKey) {
+  StartSession();
+
+  // Create `key` and verify no progress icon animation is registered.
+  size_t key = 0u;
+  EXPECT_FALSE(registry()->GetProgressIconAnimationForKey(&key));
+
+  // Count progress icon animation changed events.
+  size_t callback_call_count = 0u;
+  auto subscription = registry()->AddProgressIconAnimationChangedCallbackForKey(
+      &key, base::BindLambdaForTesting([&](HoldingSpaceProgressIconAnimation*) {
+        ++callback_call_count;
+      }));
+
+  // Unregister progress icon animation for `key`.
+  EXPECT_FALSE(registry()->SetProgressIconAnimationForKey(&key, nullptr));
+  EXPECT_FALSE(registry()->GetProgressIconAnimationForKey(&key));
+  EXPECT_EQ(callback_call_count, 0u);
+
+  // Create a progress icon `animation`.
+  auto animation = std::make_unique<HoldingSpaceProgressIconAnimation>();
+  auto* animation_ptr = animation.get();
+
+  // Register progress icon `animation` for `key`.
+  EXPECT_EQ(
+      registry()->SetProgressIconAnimationForKey(&key, std::move(animation)),
+      animation_ptr);
+  EXPECT_EQ(registry()->GetProgressIconAnimationForKey(&key), animation_ptr);
+  EXPECT_EQ(callback_call_count, 1u);
+
+  // Unregister progress icon animation for `key`.
+  EXPECT_FALSE(registry()->SetProgressIconAnimationForKey(&key, nullptr));
+  EXPECT_FALSE(registry()->GetProgressIconAnimationForKey(&key));
+  EXPECT_EQ(callback_call_count, 2u);
+}
+
+TEST_P(HoldingSpaceAnimationRegistryTest, SetProgressRingAnimationForKey) {
+  StartSession();
+
+  // Create `key` and verify no progress ring animation is registered.
+  size_t key = 0u;
+  EXPECT_FALSE(registry()->GetProgressRingAnimationForKey(&key));
+
+  // Count progress ring animation changed events.
+  size_t callback_call_count = 0u;
+  auto subscription = registry()->AddProgressRingAnimationChangedCallbackForKey(
+      &key, base::BindLambdaForTesting([&](HoldingSpaceProgressRingAnimation*) {
+        ++callback_call_count;
+      }));
+
+  // Unregister progress ring animation for `key`.
+  EXPECT_FALSE(registry()->SetProgressRingAnimationForKey(&key, nullptr));
+  EXPECT_FALSE(registry()->GetProgressRingAnimationForKey(&key));
+  EXPECT_EQ(callback_call_count, 0u);
+
+  // Create a progress ring `animation`.
+  auto animation = HoldingSpaceProgressRingAnimation::CreateOfType(
+      HoldingSpaceProgressRingAnimation::Type::kPulse);
+  auto* animation_ptr = animation.get();
+
+  // Register progress ring `animation` for `key`.
+  EXPECT_EQ(
+      registry()->SetProgressRingAnimationForKey(&key, std::move(animation)),
+      animation_ptr);
+  EXPECT_EQ(registry()->GetProgressRingAnimationForKey(&key), animation_ptr);
+  EXPECT_EQ(callback_call_count, 1u);
+
+  // Unregister progress ring animation for `key`.
+  EXPECT_FALSE(registry()->SetProgressRingAnimationForKey(&key, nullptr));
+  EXPECT_FALSE(registry()->GetProgressRingAnimationForKey(&key));
+  EXPECT_EQ(callback_call_count, 2u);
+}
+
 }  // namespace ash
diff --git a/ash/system/holding_space/holding_space_progress_icon_animation.h b/ash/system/holding_space/holding_space_progress_icon_animation.h
index 689cb67..20dd4a9 100644
--- a/ash/system/holding_space/holding_space_progress_icon_animation.h
+++ b/ash/system/holding_space/holding_space_progress_icon_animation.h
@@ -5,12 +5,13 @@
 #ifndef ASH_SYSTEM_HOLDING_SPACE_HOLDING_SPACE_PROGRESS_ICON_ANIMATION_H_
 #define ASH_SYSTEM_HOLDING_SPACE_HOLDING_SPACE_PROGRESS_ICON_ANIMATION_H_
 
+#include "ash/ash_export.h"
 #include "ash/system/holding_space/holding_space_progress_indicator_animation.h"
 
 namespace ash {
 
 // An animation for a `HoldingSpaceProgressIndicator`'s icon.
-class HoldingSpaceProgressIconAnimation
+class ASH_EXPORT HoldingSpaceProgressIconAnimation
     : public HoldingSpaceProgressIndicatorAnimation {
  public:
   HoldingSpaceProgressIconAnimation();
diff --git a/ash/system/holding_space/holding_space_progress_ring_animation.h b/ash/system/holding_space/holding_space_progress_ring_animation.h
index 5a331bb..3e38e90 100644
--- a/ash/system/holding_space/holding_space_progress_ring_animation.h
+++ b/ash/system/holding_space/holding_space_progress_ring_animation.h
@@ -7,13 +7,14 @@
 
 #include <memory>
 
+#include "ash/ash_export.h"
 #include "ash/system/holding_space/holding_space_progress_indicator_animation.h"
 
 namespace ash {
 
 // An animation for a `HoldingSpaceProgressIndicator` to be painted in lieu of
 // the determinate progress ring that would otherwise be painted.
-class HoldingSpaceProgressRingAnimation
+class ASH_EXPORT HoldingSpaceProgressRingAnimation
     : public HoldingSpaceProgressIndicatorAnimation {
  public:
   enum class Type {
diff --git a/ash/system/message_center/ash_message_center_lock_screen_controller.cc b/ash/system/message_center/ash_message_center_lock_screen_controller.cc
index 93523ba8b..f799ced 100644
--- a/ash/system/message_center/ash_message_center_lock_screen_controller.cc
+++ b/ash/system/message_center/ash_message_center_lock_screen_controller.cc
@@ -7,7 +7,8 @@
 #include "ash/constants/ash_features.h"
 #include "ash/constants/ash_pref_names.h"
 #include "ash/login/ui/lock_screen.h"
-#include "ash/public/cpp/toast_data.h"
+#include "ash/public/cpp/system/toast_catalog.h"
+#include "ash/public/cpp/system/toast_data.h"
 #include "ash/session/session_controller_impl.h"
 #include "ash/shelf/shelf.h"
 #include "ash/shell.h"
@@ -142,7 +143,8 @@
 
   // TODO(yoshiki): Update UI after the UX finalizes.
   Shell::Get()->toast_manager()->Show(
-      ToastData(kToastId, message, ToastData::kInfiniteDuration,
+      ToastData(kToastId, ToastCatalogName::kEncourageUnlock, message,
+                ToastData::kInfiniteDuration,
                 /*visible_on_lock_screen=*/true));
 }
 
diff --git a/ash/system/network/auto_connect_notifier.cc b/ash/system/network/auto_connect_notifier.cc
index 4e11ba4..6a4016e 100644
--- a/ash/system/network/auto_connect_notifier.cc
+++ b/ash/system/network/auto_connect_notifier.cc
@@ -6,8 +6,9 @@
 
 #include <string>
 
-#include "ash/public/cpp/toast_data.h"
-#include "ash/public/cpp/toast_manager.h"
+#include "ash/public/cpp/system/toast_catalog.h"
+#include "ash/public/cpp/system/toast_data.h"
+#include "ash/public/cpp/system/toast_manager.h"
 #include "ash/strings/grit/ash_strings.h"
 #include "base/callback_helpers.h"
 #include "base/logging.h"
@@ -32,8 +33,10 @@
 // a notification.
 constexpr const base::TimeDelta kNetworkConnectionTimeout = base::Seconds(3);
 
-void ShowToast(std::string id, const std::u16string& text) {
-  ash::ToastManager::Get()->Show(ToastData(id, text));
+void ShowToast(std::string id,
+               ToastCatalogName catalog_name,
+               const std::u16string& text) {
+  ash::ToastManager::Get()->Show(ToastData(id, catalog_name, text));
 }
 
 }  // namespace
@@ -141,7 +144,7 @@
   NET_LOG(EVENT) << "Show AutoConnect Toast for: " << NetworkId(network);
   // Remove previous toast if one was already being shown.
   ash::ToastManager::Get()->Cancel(kAutoConnectToastId);
-  ShowToast(kAutoConnectToastId,
+  ShowToast(kAutoConnectToastId, ToastCatalogName::kNetworkAutoConnect,
             l10n_util::GetStringUTF16(IDS_ASH_NETWORK_AUTOCONNECT));
 }
 
diff --git a/ash/system/palette/tools/metalayer_mode.cc b/ash/system/palette/tools/metalayer_mode.cc
index e87d5a8..88d874b 100644
--- a/ash/system/palette/tools/metalayer_mode.cc
+++ b/ash/system/palette/tools/metalayer_mode.cc
@@ -5,7 +5,8 @@
 #include "ash/system/palette/tools/metalayer_mode.h"
 
 #include "ash/assistant/assistant_controller_impl.h"
-#include "ash/public/cpp/toast_data.h"
+#include "ash/public/cpp/system/toast_catalog.h"
+#include "ash/public/cpp/system/toast_data.h"
 #include "ash/resources/vector_icons/vector_icons.h"
 #include "ash/shell.h"
 #include "ash/strings/grit/ash_strings.h"
@@ -137,8 +138,9 @@
     // Repetitive presses will create toasts with the same id which will be
     // ignored.
     Shell::Get()->toast_manager()->Show(
-        ToastData(kToastId, l10n_util::GetStringUTF16(
-                                IDS_ASH_STYLUS_TOOLS_METALAYER_TOAST_LOADING)));
+        ToastData(kToastId, ToastCatalogName::kAssistantLoading,
+                  l10n_util::GetStringUTF16(
+                      IDS_ASH_STYLUS_TOOLS_METALAYER_TOAST_LOADING)));
   } else {
     delegate()->RecordPaletteOptionsUsage(
         PaletteToolIdToPaletteTrayOptions(GetToolId()),
diff --git a/ash/system/time/calendar_event_list_item_view.cc b/ash/system/time/calendar_event_list_item_view.cc
index b646c0b0..47d56be 100644
--- a/ash/system/time/calendar_event_list_item_view.cc
+++ b/ash/system/time/calendar_event_list_item_view.cc
@@ -107,7 +107,7 @@
   GetViewAccessibility().OverrideRole(ax::mojom::Role::kButton);
   SetAccessibleName(l10n_util::GetStringFUTF16(
       IDS_ASH_CALENDAR_EVENT_ENTRY_ACCESSIBLE_DESCRIPTION, start_time_string,
-      end_time_string, base::TimeFormatWithPattern(start_time, "z"),
+      end_time_string, base::TimeFormatWithPattern(start_time, "zzzz"),
       base::UTF8ToUTF16(event.summary())));
   SetFocusBehavior(FocusBehavior::ALWAYS);
 
diff --git a/ash/system/time/calendar_event_list_view_unittest.cc b/ash/system/time/calendar_event_list_view_unittest.cc
index 41f5287..52e401b 100644
--- a/ash/system/time/calendar_event_list_view_unittest.cc
+++ b/ash/system/time/calendar_event_list_view_unittest.cc
@@ -64,7 +64,7 @@
         std::make_unique<CalendarEventListView>(controller_.get());
   }
 
-  void SetSelectedDate(base::Time::Exploded date) {
+  void SetSelectedDate(base::Time date) {
     controller_->selected_date_ = date;
     controller_->ShowEventListView(date, /*row_index=*/0);
   }
@@ -93,9 +93,7 @@
 
   EXPECT_EQ(0u, content_view()->children().size());
 
-  base::Time::Exploded selected_date;
-  date.LocalExplode(&selected_date);
-  SetSelectedDate(selected_date);
+  SetSelectedDate(date);
 
   // 3 events on 18 Nov 2021. And they should be sorted by the start time.
   EXPECT_EQ(3u, content_view()->children().size());
@@ -103,21 +101,18 @@
   EXPECT_EQ(u"summary_0", GetSummary(1)->GetText());
   EXPECT_EQ(u"summary_2", GetSummary(2)->GetText());
 
-  (date + base::Days(1)).LocalExplode(&selected_date);
-  SetSelectedDate(selected_date);
+  SetSelectedDate(date + base::Days(1));
 
   // 1 event on 19 Nov 2021.
   EXPECT_EQ(1u, content_view()->children().size());
   EXPECT_EQ(u"summary_3", GetSummary(0)->GetText());
 
-  (date + base::Days(2)).LocalExplode(&selected_date);
-  SetSelectedDate(selected_date);
+  SetSelectedDate(date + base::Days(2));
 
   // 0 event on 20 Nov 2021.
   EXPECT_EQ(0u, content_view()->children().size());
 
-  (date + base::Days(3)).LocalExplode(&selected_date);
-  SetSelectedDate(selected_date);
+  SetSelectedDate(date + base::Days(3));
 
   // 2 events on 21 Nov 2021.
   EXPECT_EQ(2u, content_view()->children().size());
diff --git a/ash/system/time/calendar_month_view.cc b/ash/system/time/calendar_month_view.cc
index 2c5a3bc..fe917b3 100644
--- a/ash/system/time/calendar_month_view.cc
+++ b/ash/system/time/calendar_month_view.cc
@@ -4,6 +4,8 @@
 
 #include "ash/system/time/calendar_month_view.h"
 
+#include <codecvt>
+
 #include "ash/public/cpp/ash_typography.h"
 #include "ash/strings/grit/ash_strings.h"
 #include "ash/style/ash_color_provider.h"
@@ -45,23 +47,32 @@
 // next one.
 void MoveToNextDay(int& column,
                    base::Time& current_date,
+                   base::Time& local_current_date,
                    base::Time::Exploded& current_date_exploded) {
   // Using 30 hours to make sure the date is moved to the next day, since there
   // are daylight saving days which have more than 24 hours in a day.
   // `base::Days(1)` cannot be used, because it is 24 hours.
-  current_date = current_date.LocalMidnight() + base::Hours(30);
-  current_date.LocalExplode(&current_date_exploded);
+  //
+  // Also using the local time format to calculate the local midnight, since the
+  // LocalExplode doesn't use the manually set timezone.
+  std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> converter;
+  int hours;
+  bool result = base::StringToInt(
+      converter.to_bytes(base::TimeFormatWithPattern(current_date, "H")),
+      &hours);
+  DCHECK(result);
+  current_date += base::Hours(30 - hours);
+  local_current_date += base::Hours(30 - hours);
+  local_current_date.UTCExplode(&current_date_exploded);
   column = (column + 1) % calendar_utils::kDateInOneWeek;
   DCHECK_EQ(column, current_date_exploded.day_of_week);
 }
 
 }  // namespace
 
-// TODO(https://crbug.com/1236276): Fix the ChromeVox window position on this
-// view.
 CalendarDateCellView::CalendarDateCellView(
     CalendarViewController* calendar_view_controller,
-    base::Time::Exploded& date,
+    base::Time date,
     bool is_grayed_out_date,
     int row_index)
     : views::LabelButton(
@@ -73,7 +84,7 @@
                         base::Unretained(calendar_view_controller),
                         date,
                         row_index)),
-          base::UTF8ToUTF16(base::NumberToString(date.day_of_month)),
+          base::TimeFormatWithPattern(date, "d"),
           CONTEXT_CALENDAR_DATE),
       date_(date),
       grayed_out_(is_grayed_out_date),
@@ -130,15 +141,15 @@
   // Sets accessible label. E.g. Calendar, week of July 16th 2021, [selected
   // date] is currently selected.
   if (is_selected_) {
-    base::Time unexploded;
-    bool result = base::Time::FromLocalExploded(date_, &unexploded);
-    DCHECK(result);
-    unexploded -= base::Days(date_.day_of_week);
+    base::Time::Exploded date_exploded =
+        calendar_utils::GetExplodedLocal(date_);
+    base::Time first_day_of_week =
+        date_ - base::Days(date_exploded.day_of_week);
 
     SetAccessibleName(l10n_util::GetStringFUTF16(
         IDS_ASH_CALENDAR_SELECTED_DATE_CELL_ACCESSIBLE_DESCRIPTION,
-        base::TimeFormatWithPattern(unexploded, "MMMMdyyyy"),
-        base::UTF8ToUTF16(base::NumberToString(date_.day_of_month))));
+        base::TimeFormatWithPattern(first_day_of_week, "MMMMdyyyy"),
+        base::TimeFormatWithPattern(date_, "d")));
   }
 
   if (views::View::HasFocus() || is_selected_) {
@@ -226,22 +237,18 @@
   if (grayed_out_)
     return;
 
-  base::Time unexploded;
-  bool result = base::Time::FromLocalExploded(date_, &unexploded);
-  DCHECK(result);
-
   const int event_number =
-      calendar_view_controller_->EventsNumberOfDay(unexploded,
+      calendar_view_controller_->EventsNumberOfDay(date_,
                                                    /*events =*/nullptr);
   const int tooltip_id = (event_number <= 1)
                              ? IDS_ASH_CALENDAR_DATE_CELL_TOOLTIP
                              : IDS_ASH_CALENDAR_DATE_CELL_PLURAL_EVENTS_TOOLTIP;
 
   SetTooltipText(l10n_util::GetStringFUTF16(
-      tooltip_id, base::TimeFormatWithPattern(unexploded, "MMMMdyyyy"),
+      tooltip_id, base::TimeFormatWithPattern(date_, "MMMMdyyyy"),
       base::UTF8ToUTF16(base::NumberToString(event_number))));
   SetAccessibleName(l10n_util::GetStringFUTF16(
-      tooltip_id, base::TimeFormatWithPattern(unexploded, "MMMMdyyyy"),
+      tooltip_id, base::TimeFormatWithPattern(date_, "MMMMdyyyy"),
       base::UTF8ToUTF16(base::NumberToString(event_number))));
 
   if (event_number == 0)
@@ -271,14 +278,31 @@
   layer()->SetFillsBoundsOpaquely(false);
   calendar_utils::SetUpWeekColumns(layout);
 
+  std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> converter;
+
+  // Using the local time format to get the local `base::Time`, which is used to
+  // generate the exploded, since the LocalExplode doesn't use the manually set
+  // timezone.
+  base::Time first_day_of_month_local;
+  bool result = base::Time::FromString(
+      converter
+          .to_bytes(base::TimeFormatWithPattern(first_day_of_month,
+                                                "MMMMdyyyy HH:mm") +
+                    u" UTC")
+          .c_str(),
+      &first_day_of_month_local);
+  DCHECK(result);
   base::Time::Exploded first_day_of_month_exploded =
-      calendar_utils::GetExplodedLocal(first_day_of_month);
+      calendar_utils::GetExplodedUTC(first_day_of_month_local);
 
   // Calculates the start date.
   base::Time current_date =
       first_day_of_month - base::Days(first_day_of_month_exploded.day_of_week);
+  base::Time current_date_local =
+      first_day_of_month_local -
+      base::Days(first_day_of_month_exploded.day_of_week);
   base::Time::Exploded current_date_exploded =
-      calendar_utils::GetExplodedLocal(current_date);
+      calendar_utils::GetExplodedUTC(current_date_local);
 
   // TODO(https://crbug.com/1236276): Extract the following 3 parts (while
   // loops) into a method.
@@ -286,9 +310,10 @@
   // Gray-out dates in the first row, which are from the previous month.
   while (current_date_exploded.month % 12 ==
          (first_day_of_month_exploded.month - 1) % 12) {
-    AddDateCellToLayout(current_date_exploded, column,
+    AddDateCellToLayout(current_date, column,
                         /*is_in_current_month=*/false, /*row_index=*/0);
-    MoveToNextDay(column, current_date, current_date_exploded);
+    MoveToNextDay(column, current_date, current_date_local,
+                  current_date_exploded);
   }
 
   int row_number = 0;
@@ -298,7 +323,7 @@
     if (column == 0 || current_date_exploded.day_of_month == 1) {
       ++row_number;
     }
-    auto* cell = AddDateCellToLayout(current_date_exploded, column,
+    auto* cell = AddDateCellToLayout(current_date, column,
                                      /*is_in_current_month=*/true,
                                      /*row_index=*/row_number - 1);
     // Add the first non-grayed-out cell of the row to the `focused_cells_`.
@@ -307,14 +332,15 @@
     }
     // If this row has today, updates today's row number and replaces today to
     // the last element in the `focused_cells_`.
-    if (calendar_utils::IsToday(current_date_exploded)) {
+    if (calendar_utils::IsToday(current_date)) {
       calendar_view_controller_->set_row_height(
           cell->GetPreferredSize().height());
       calendar_view_controller_->set_today_row(row_number);
       focused_cells_.back() = cell;
       has_today_ = true;
     }
-    MoveToNextDay(column, current_date, current_date_exploded);
+    MoveToNextDay(column, current_date, current_date_local,
+                  current_date_exploded);
   }
 
   last_row_index_ = row_number - 1;
@@ -327,25 +353,26 @@
   // Adds the first several days from the next month if the last day is not the
   // end day of this week.
   const base::Time end_of_the_last_row =
-      current_date + base::Days(6 - current_date_exploded.day_of_week);
+      current_date_local + base::Days(6 - current_date_exploded.day_of_week);
   base::Time::Exploded end_of_row_exploded =
-      calendar_utils::GetExplodedLocal(end_of_the_last_row);
+      calendar_utils::GetExplodedUTC(end_of_the_last_row);
 
   // Gray-out dates in the last row, which are from the next month.
   while (current_date_exploded.day_of_month <=
          end_of_row_exploded.day_of_month) {
     // Next column is generated.
-    AddDateCellToLayout(current_date_exploded, column,
+    AddDateCellToLayout(current_date, column,
                         /*is_in_current_month=*/false,
                         /*row_index=*/row_number);
-    MoveToNextDay(column, current_date, current_date_exploded);
+    MoveToNextDay(column, current_date, current_date_local,
+                  current_date_exploded);
   }
 }
 
 CalendarMonthView::~CalendarMonthView() = default;
 
 CalendarDateCellView* CalendarMonthView::AddDateCellToLayout(
-    base::Time::Exploded current_date_exploded,
+    base::Time current_date,
     int column,
     bool is_in_current_month,
     int row_index) {
@@ -353,7 +380,7 @@
   if (column == 0)
     layout_manager->AddRows(1, views::TableLayout::kFixedSize);
   return AddChildView(std::make_unique<CalendarDateCellView>(
-      calendar_view_controller_, current_date_exploded,
+      calendar_view_controller_, current_date,
       /*is_grayed_out_date=*/!is_in_current_month, /*row_index=*/row_index));
 }
 
diff --git a/ash/system/time/calendar_month_view.h b/ash/system/time/calendar_month_view.h
index 2ca628e..4b08d59 100644
--- a/ash/system/time/calendar_month_view.h
+++ b/ash/system/time/calendar_month_view.h
@@ -21,7 +21,7 @@
   METADATA_HEADER(CalendarDateCellView);
 
   CalendarDateCellView(CalendarViewController* calendar_view_controller,
-                       base::Time::Exploded& date,
+                       base::Time date,
                        bool is_grayed_out_date,
                        int row_index);
   CalendarDateCellView(const CalendarDateCellView& other) = delete;
@@ -66,7 +66,7 @@
   void MaybeDrawEventsIndicator(gfx::Canvas* canvas);
 
   // The date used to render this cell view.
-  const base::Time::Exploded date_;
+  const base::Time date_;
 
   const bool grayed_out_;
 
@@ -114,11 +114,10 @@
  private:
   // Adds the `current_date`'s `CalendarDateCellView` to the table layout and
   // returns it.
-  CalendarDateCellView* AddDateCellToLayout(
-      base::Time::Exploded current_date_exploded,
-      int column,
-      bool is_in_current_month,
-      int row_index);
+  CalendarDateCellView* AddDateCellToLayout(base::Time current_date,
+                                            int column,
+                                            bool is_in_current_month,
+                                            int row_index);
 
   // Owned by `CalendarView`.
   CalendarViewController* const calendar_view_controller_;
diff --git a/ash/system/time/calendar_utils.cc b/ash/system/time/calendar_utils.cc
index 62cf0cd..fe509a36 100644
--- a/ash/system/time/calendar_utils.cc
+++ b/ash/system/time/calendar_utils.cc
@@ -4,8 +4,13 @@
 
 #include "ash/system/time/calendar_utils.h"
 
+#include <codecvt>
+#include <string>
+
 #include "ash/style/ash_color_provider.h"
+#include "base/i18n/time_formatting.h"
 #include "base/i18n/unicodestring.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/time/time.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/icu/source/i18n/unicode/datefmt.h"
@@ -17,16 +22,15 @@
 
 namespace calendar_utils {
 
-bool IsToday(const base::Time::Exploded& selected_date) {
-  base::Time::Exploded today_exploded = GetExplodedLocal(base::Time::Now());
-  return IsTheSameDay(selected_date, today_exploded);
+bool IsToday(const base::Time selected_date) {
+  return IsTheSameDay(selected_date, base::Time::Now());
 }
-bool IsTheSameDay(absl::optional<base::Time::Exploded> date_a,
-                  absl::optional<base::Time::Exploded> date_b) {
+bool IsTheSameDay(absl::optional<base::Time> date_a,
+                  absl::optional<base::Time> date_b) {
   if (!date_a.has_value() || !date_b.has_value())
     return false;
-  return date_a->year == date_b->year && date_a->month == date_b->month &&
-         date_a->day_of_month == date_b->day_of_month;
+  return base::TimeFormatWithPattern(date_a.value(), "dd MMM YYYY") ==
+         base::TimeFormatWithPattern(date_b.value(), "dd MMM YYYY");
 }
 
 base::Time::Exploded GetExplodedLocal(const base::Time& date) {
@@ -42,25 +46,7 @@
 }
 
 std::u16string GetMonthName(const base::Time date) {
-  // Inits status with no error, no warning.
-  UErrorCode status = U_ZERO_ERROR;
-
-  // Generates the "MMMM" pattern.
-  std::unique_ptr<icu::DateTimePatternGenerator> generator(
-      icu::DateTimePatternGenerator::createInstance(status));
-  DCHECK(U_SUCCESS(status));
-  icu::UnicodeString generated_pattern =
-      generator->getBestPattern(icu::UnicodeString(UDAT_MONTH), status);
-  DCHECK(U_SUCCESS(status));
-
-  // Then, creates the formatter and formats `date` to string with the pattern.
-  auto dfmt =
-      std::make_unique<icu::SimpleDateFormat>(generated_pattern, status);
-  UDate unicode_date = static_cast<UDate>(date.ToDoubleT() * 1000);
-  icu::UnicodeString unicode_string;
-  unicode_string = dfmt->format(unicode_date, unicode_string);
-
-  return base::i18n::UnicodeStringToString16(unicode_string);
+  return base::TimeFormatWithPattern(date, "MMMM");
 }
 
 void SetUpWeekColumns(views::TableLayout* layout) {
@@ -87,9 +73,15 @@
 }
 
 base::Time GetStartOfMonthLocal(const base::Time& date) {
-  return (date -
-          base::Days(calendar_utils::GetExplodedLocal(date).day_of_month - 1))
-      .LocalMidnight();
+  // Using the local time format to calculate the start of a month, since the
+  // LocalExplode doesn't use the manually set timezone.
+  std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> converter;
+  int local_day_of_month;
+  bool result = base::StringToInt(
+      converter.to_bytes(base::TimeFormatWithPattern(date, "dd")),
+      &local_day_of_month);
+  DCHECK(result);
+  return date - base::Days(local_day_of_month - 1);
 }
 
 base::Time GetStartOfPreviousMonthLocal(base::Time date) {
diff --git a/ash/system/time/calendar_utils.h b/ash/system/time/calendar_utils.h
index 5e15363..570011d 100644
--- a/ash/system/time/calendar_utils.h
+++ b/ash/system/time/calendar_utils.h
@@ -40,11 +40,11 @@
 constexpr base::TimeDelta kAnimationDurationForMoving = base::Milliseconds(300);
 
 // Checks if the `selected_date` is local time today.
-bool IsToday(const base::Time::Exploded& selected_date);
+bool IsToday(const base::Time selected_date);
 
 // Checks if the two exploded are in the same day.
-bool IsTheSameDay(absl::optional<base::Time::Exploded> date_a,
-                  absl::optional<base::Time::Exploded> date_b);
+bool IsTheSameDay(absl::optional<base::Time> date_a,
+                  absl::optional<base::Time> date_b);
 
 // Gets the given `date`'s `Exploded` instance, in local time.
 base::Time::Exploded GetExplodedLocal(const base::Time& date);
diff --git a/ash/system/time/calendar_view.cc b/ash/system/time/calendar_view.cc
index 5b63e547e..6daa6cc 100644
--- a/ash/system/time/calendar_view.cc
+++ b/ash/system/time/calendar_view.cc
@@ -51,7 +51,7 @@
 // The percentage of a normal row height, which (percentage * row_height) will
 // be used as the `CalendarView` height when the `CalendarEventListView` is
 // expanded.
-constexpr float kExpandedCalendarViewHeightScale = 1.3;
+constexpr float kExpandedCalendarViewHeightScale = 1.2;
 
 // After the user is finished navigating to a different month, this is how long
 // we wait before fetchiung more events.
@@ -118,10 +118,10 @@
 }  // namespace
 
 // The label for each month.
-class CalendarView::MonthYearHeaderView : public views::View {
+class CalendarView::MonthHeaderLabelView : public views::View {
  public:
-  MonthYearHeaderView(LabelType type,
-                      CalendarViewController* calendar_view_controller)
+  MonthHeaderLabelView(LabelType type,
+                       CalendarViewController* calendar_view_controller)
       : month_label_(AddChildView(std::make_unique<views::Label>())) {
     // The layer is required in animation.
     SetPaintToLayer();
@@ -148,28 +148,16 @@
     month_label_->SetBorder(views::CreateEmptyBorder(
         kLabelVerticalPadding, calendar_utils::kDateHorizontalPadding,
         kLabelVerticalPadding, 0));
-
-    if (calendar_utils::GetExplodedLocal(date_).year !=
-        calendar_utils::GetExplodedLocal(base::Time::Now()).year) {
-      year_label_ = AddChildView(std::make_unique<views::Label>());
-      year_label_->SetText(base::UTF8ToUTF16(
-          base::NumberToString(calendar_utils::GetExplodedLocal(date_).year)));
-      SetupLabel(year_label_);
-      year_label_->SetBorder(views::CreateEmptyBorder(
-          gfx::Insets(kLabelVerticalPadding, kLabelTextInBetweenPadding)));
-    }
   }
-  MonthYearHeaderView(const MonthYearHeaderView&) = delete;
-  MonthYearHeaderView& operator=(const MonthYearHeaderView&) = delete;
-  ~MonthYearHeaderView() override = default;
+  MonthHeaderLabelView(const MonthHeaderLabelView&) = delete;
+  MonthHeaderLabelView& operator=(const MonthHeaderLabelView&) = delete;
+  ~MonthHeaderLabelView() override = default;
 
   // views::View:
   void OnThemeChanged() override {
     views::View::OnThemeChanged();
 
     month_label_->SetEnabledColor(calendar_utils::GetPrimaryTextColor());
-    if (year_label_)
-      year_label_->SetEnabledColor(calendar_utils::GetSecondaryTextColor());
   }
 
   void SetupLabel(views::Label* label) {
@@ -187,9 +175,6 @@
 
   // The month label in the view.
   views::Label* const month_label_ = nullptr;
-
-  // The year label in the view.
-  views::Label* year_label_ = nullptr;
 };
 
 CalendarHeaderView::CalendarHeaderView(const std::u16string& month,
@@ -265,10 +250,8 @@
   // Add the header.
   header_ = new CalendarHeaderView(
       calendar_view_controller_->GetOnScreenMonthName(),
-      base::UTF8ToUTF16(base::NumberToString(
-          calendar_utils::GetExplodedLocal(
-              calendar_view_controller_->GetOnScreenMonthFirstDayLocal())
-              .year)));
+      base::TimeFormatWithPattern(calendar_view_controller_->current_date(),
+                                  "YYYY"));
 
   TriView* tri_view = TrayPopupUtils::CreateDefaultRowView();
   tri_view->SetBorder(views::CreateEmptyBorder(kLabelVerticalPadding,
@@ -411,7 +394,8 @@
 int CalendarView::PositionOfSelectedDate() const {
   DCHECK(calendar_view_controller_->selected_date().has_value());
   const int row_height = calendar_view_controller_->selected_date_row_index() *
-                         calendar_view_controller_->row_height();
+                             calendar_view_controller_->row_height() +
+                         calendar_utils::kDateVerticalPadding;
   // The selected date should be either in the current month or the next month.
   if (calendar_view_controller_->IsSelectedDateInCurrentMonth())
     return PositionOfCurrentMonth() + row_height;
@@ -450,11 +434,10 @@
 }
 
 void CalendarView::UpdateHeaders() {
-  header_->UpdateHeaders(calendar_view_controller_->GetOnScreenMonthName(),
-                         base::UTF8ToUTF16(base::NumberToString(
-                             calendar_utils::GetExplodedLocal(
-                                 calendar_view_controller_->current_date())
-                                 .year)));
+  header_->UpdateHeaders(
+      calendar_view_controller_->GetOnScreenMonthName(),
+      base::TimeFormatWithPattern(calendar_view_controller_->current_date(),
+                                  "YYYY"));
 }
 
 void CalendarView::RestoreHeadersStatus() {
@@ -605,7 +588,7 @@
 }
 
 views::View* CalendarView::AddLabelWithId(LabelType type, bool add_at_front) {
-  auto label = std::make_unique<MonthYearHeaderView>(
+  auto label = std::make_unique<MonthHeaderLabelView>(
       type, calendar_view_controller_.get());
   if (add_at_front)
     return content_view_->AddChildViewAt(std::move(label), 0);
@@ -690,18 +673,13 @@
     return;
 
   // Updates `scroll_view_`'s accessible name with the selected date.
-  absl::optional<base::Time::Exploded> selected_date =
+  absl::optional<base::Time> selected_date =
       calendar_view_controller_->selected_date();
-  DCHECK(selected_date.has_value());
-  base::Time unexploded_selected_date;
-  bool result = base::Time::FromLocalExploded(selected_date.value(),
-                                              &unexploded_selected_date);
-  DCHECK(result);
   scroll_view_->GetViewAccessibility().OverrideName(l10n_util::GetStringFUTF16(
       IDS_ASH_CALENDAR_CONTENT_ACCESSIBLE_DESCRIPTION,
       base::TimeFormatWithPattern(calendar_view_controller_->current_date(),
                                   "MMMM yyyy"),
-      base::TimeFormatWithPattern(unexploded_selected_date, "MMMMdyyyy")));
+      base::TimeFormatWithPattern(selected_date.value(), "MMMMdyyyy")));
   scroll_view_->NotifyAccessibilityEvent(ax::mojom::Event::kTextChanged,
                                          /*send_native_event=*/true);
 
@@ -955,7 +933,8 @@
     const int row_height = calendar_view_controller_->GetExpandedRowIndex() *
                            calendar_view_controller_->row_height();
     scroll_view_->ScrollToPosition(scroll_view_->vertical_scroll_bar(),
-                                   PositionOfCurrentMonth() + row_height);
+                                   PositionOfCurrentMonth() + row_height +
+                                       calendar_utils::kDateVerticalPadding);
     scroll_view_->SetVerticalScrollBarMode(
         views::ScrollView::ScrollBarMode::kDisabled);
     return;
@@ -967,8 +946,9 @@
                               current_month_->last_row_index()) {
     ScrollDownOneMonth();
     calendar_view_controller_->set_expanded_row_index(0);
-    scroll_view_->ScrollToPosition(scroll_view_->vertical_scroll_bar(),
-                                   PositionOfCurrentMonth());
+    scroll_view_->ScrollToPosition(
+        scroll_view_->vertical_scroll_bar(),
+        PositionOfCurrentMonth() + calendar_utils::kDateVerticalPadding);
     scroll_view_->SetVerticalScrollBarMode(
         views::ScrollView::ScrollBarMode::kDisabled);
     return;
@@ -980,7 +960,8 @@
   const int row_height = calendar_view_controller_->GetExpandedRowIndex() *
                          calendar_view_controller_->row_height();
   scroll_view_->ScrollToPosition(scroll_view_->vertical_scroll_bar(),
-                                 PositionOfCurrentMonth() + row_height);
+                                 PositionOfCurrentMonth() + row_height +
+                                     calendar_utils::kDateVerticalPadding);
   scroll_view_->SetVerticalScrollBarMode(
       views::ScrollView::ScrollBarMode::kDisabled);
   return;
diff --git a/ash/system/time/calendar_view.h b/ash/system/time/calendar_view.h
index 42342e5..98a0f2b 100644
--- a/ash/system/time/calendar_view.h
+++ b/ash/system/time/calendar_view.h
@@ -97,10 +97,10 @@
   // The header of each month view which shows the month's name. If the year of
   // this month is not the same as the current month, the year is also shown in
   // this view.
-  class MonthYearHeaderView;
+  class MonthHeaderLabelView;
 
-  // The types to create the `MonthYearHeaderView` which are in corresponding to
-  // the 3 months: `previous_month_`, `current_month_` and `next_month_`.
+  // The types to create the `MonthHeaderLabelView` which are in corresponding
+  // to the 3 months: `previous_month_`, `current_month_` and `next_month_`.
   enum LabelType { PREVIOUS, CURRENT, NEXT };
 
   friend class CalendarViewTest;
diff --git a/ash/system/time/calendar_view_controller.cc b/ash/system/time/calendar_view_controller.cc
index 5521772..ce90f65 100644
--- a/ash/system/time/calendar_view_controller.cc
+++ b/ash/system/time/calendar_view_controller.cc
@@ -75,10 +75,8 @@
 
 void CalendarViewController::UpdateMonth(
     const base::Time current_month_first_date) {
-  if (calendar_utils::GetExplodedLocal(current_date_).month ==
-          calendar_utils::GetExplodedLocal(current_month_first_date).month &&
-      calendar_utils::GetExplodedLocal(current_date_).year ==
-          calendar_utils::GetExplodedLocal(current_month_first_date).year) {
+  if (base::TimeFormatWithPattern(current_date_, "MMM YYYY") ==
+      base::TimeFormatWithPattern(current_month_first_date, "MMM YYYY")) {
     return;
   }
 
@@ -255,11 +253,7 @@
   if (!selected_date_.has_value())
     return std::list<google_apis::calendar::CalendarEvent>();
 
-  base::Time date;
-  const bool result =
-      base::Time::FromLocalExploded(selected_date_.value(), &date);
-  DCHECK(result);
-  return FindEvents(date);
+  return FindEvents(selected_date_.value());
 }
 
 int CalendarViewController::EventsNumberOfDayInternal(
@@ -288,9 +282,8 @@
   return event_number;
 }
 
-void CalendarViewController::ShowEventListView(
-    base::Time::Exploded selected_date,
-    int row_index) {
+void CalendarViewController::ShowEventListView(base::Time selected_date,
+                                               int row_index) {
   // Do nothing if selecting on the same date.
   if (is_event_list_showing_ &&
       calendar_utils::IsTheSameDay(selected_date, selected_date_)) {
@@ -328,9 +321,11 @@
   if (!selected_date_.has_value())
     return false;
 
-  auto current = calendar_utils::GetExplodedLocal(current_date_);
-  return current.month == selected_date_->month &&
-         current.year == selected_date_->year;
+  auto current_exploded = calendar_utils::GetExplodedLocal(current_date_);
+  auto selected_exploded =
+      calendar_utils::GetExplodedLocal(selected_date_.value());
+  return current_exploded.month == selected_exploded.month &&
+         current_exploded.year == selected_exploded.year;
 }
 
 void CalendarViewController::OnCalendarEventsFetched(
diff --git a/ash/system/time/calendar_view_controller.h b/ash/system/time/calendar_view_controller.h
index ee377fc1..f53c6f2b 100644
--- a/ash/system/time/calendar_view_controller.h
+++ b/ash/system/time/calendar_view_controller.h
@@ -113,9 +113,7 @@
   bool was_on_later_month() { return was_on_later_month_; }
 
   // The currently selected date to show the event list.
-  absl::optional<base::Time::Exploded> selected_date() {
-    return selected_date_;
-  }
+  absl::optional<base::Time> selected_date() { return selected_date_; }
 
   // The row index of the currently selected date. This is used for auto
   // scrolling to this row when the event list is expanded.
@@ -155,7 +153,7 @@
 
   // A callback passed into the`CalendarDateCellView`, which is called when the
   // cell is clicked to show the event list view.
-  void ShowEventListView(base::Time::Exploded selected_date, int row_index);
+  void ShowEventListView(base::Time selected_date, int row_index);
 
   // A callback passed into the`CalendarEventListView`, which is called when the
   // close button is clicked to close the event list view.
@@ -265,7 +263,7 @@
   bool is_event_list_showing_ = false;
 
   // The currently selected date.
-  absl::optional<base::Time::Exploded> selected_date_;
+  absl::optional<base::Time> selected_date_;
 
   // The row index of the currently selected date.
   int selected_date_row_index_;
diff --git a/ash/system/time/calendar_view_unittest.cc b/ash/system/time/calendar_view_unittest.cc
index 4cf8ca9..97d5b53 100644
--- a/ash/system/time/calendar_view_unittest.cc
+++ b/ash/system/time/calendar_view_unittest.cc
@@ -221,7 +221,7 @@
 
   EXPECT_EQ(u"November", GetPreviousLabelText());
   EXPECT_EQ(u"December", GetCurrentLabelText());
-  EXPECT_EQ(u"January2022", GetNextLabelText());
+  EXPECT_EQ(u"January", GetNextLabelText());
   EXPECT_EQ(u"December", month_header()->GetText());
   EXPECT_EQ(u"2021", header_year()->GetText());
 
@@ -269,7 +269,7 @@
 
   EXPECT_EQ(u"November", GetPreviousLabelText());
   EXPECT_EQ(u"December", GetCurrentLabelText());
-  EXPECT_EQ(u"January2022", GetNextLabelText());
+  EXPECT_EQ(u"January", GetNextLabelText());
   EXPECT_EQ(u"December", month_header()->GetText());
   EXPECT_EQ(u"2021", header_year()->GetText());
 
@@ -277,8 +277,8 @@
                                   NextMonthPosition());
 
   EXPECT_EQ(u"December", GetPreviousLabelText());
-  EXPECT_EQ(u"January2022", GetCurrentLabelText());
-  EXPECT_EQ(u"February2022", GetNextLabelText());
+  EXPECT_EQ(u"January", GetCurrentLabelText());
+  EXPECT_EQ(u"February", GetNextLabelText());
   EXPECT_EQ(u"January", month_header()->GetText());
   EXPECT_EQ(u"2022", header_year()->GetText());
 }
@@ -314,15 +314,15 @@
 
   EXPECT_EQ(u"November", GetPreviousLabelText());
   EXPECT_EQ(u"December", GetCurrentLabelText());
-  EXPECT_EQ(u"January2022", GetNextLabelText());
+  EXPECT_EQ(u"January", GetNextLabelText());
   EXPECT_EQ(u"December", month_header()->GetText());
   EXPECT_EQ(u"2021", header_year()->GetText());
 
   ScrollDownOneMonth();
 
   EXPECT_EQ(u"December", GetPreviousLabelText());
-  EXPECT_EQ(u"January2022", GetCurrentLabelText());
-  EXPECT_EQ(u"February2022", GetNextLabelText());
+  EXPECT_EQ(u"January", GetCurrentLabelText());
+  EXPECT_EQ(u"February", GetNextLabelText());
   EXPECT_EQ(u"January", month_header()->GetText());
   EXPECT_EQ(u"2022", header_year()->GetText());
 
@@ -330,15 +330,15 @@
 
   EXPECT_EQ(u"November", GetPreviousLabelText());
   EXPECT_EQ(u"December", GetCurrentLabelText());
-  EXPECT_EQ(u"January2022", GetNextLabelText());
+  EXPECT_EQ(u"January", GetNextLabelText());
   EXPECT_EQ(u"December", month_header()->GetText());
   EXPECT_EQ(u"2021", header_year()->GetText());
 
   ScrollDownOneMonth();
 
   EXPECT_EQ(u"December", GetPreviousLabelText());
-  EXPECT_EQ(u"January2022", GetCurrentLabelText());
-  EXPECT_EQ(u"February2022", GetNextLabelText());
+  EXPECT_EQ(u"January", GetCurrentLabelText());
+  EXPECT_EQ(u"February", GetNextLabelText());
   EXPECT_EQ(u"January", month_header()->GetText());
   EXPECT_EQ(u"2022", header_year()->GetText());
 
@@ -710,7 +710,6 @@
   std::unique_ptr<DetailedViewDelegate> delegate_;
   scoped_refptr<UnifiedSystemTrayModel> tray_model_;
   std::unique_ptr<UnifiedSystemTrayController> tray_controller_;
-  static base::Time fake_time_;
 };
 
 // The header should show the new header with animation when there's an update.
diff --git a/ash/system/toast/toast_manager_impl.h b/ash/system/toast/toast_manager_impl.h
index 573494d..3533cef 100644
--- a/ash/system/toast/toast_manager_impl.h
+++ b/ash/system/toast/toast_manager_impl.h
@@ -10,8 +10,8 @@
 
 #include "ash/ash_export.h"
 #include "ash/public/cpp/session/session_observer.h"
-#include "ash/public/cpp/toast_data.h"
-#include "ash/public/cpp/toast_manager.h"
+#include "ash/public/cpp/system/toast_data.h"
+#include "ash/public/cpp/system/toast_manager.h"
 #include "ash/system/toast/toast_overlay.h"
 #include "base/containers/circular_deque.h"
 #include "base/memory/weak_ptr.h"
diff --git a/ash/system/toast/toast_manager_unittest.cc b/ash/system/toast/toast_manager_unittest.cc
index bc000e4..5b49e668 100644
--- a/ash/system/toast/toast_manager_unittest.cc
+++ b/ash/system/toast/toast_manager_unittest.cc
@@ -7,7 +7,8 @@
 #include <string>
 
 #include "ash/public/cpp/shelf_config.h"
-#include "ash/public/cpp/toast_data.h"
+#include "ash/public/cpp/system/toast_catalog.h"
+#include "ash/public/cpp/system/toast_data.h"
 #include "ash/root_window_controller.h"
 #include "ash/screen_util.h"
 #include "ash/session/session_controller_impl.h"
@@ -100,7 +101,8 @@
                         int32_t duration,
                         bool visible_on_lock_screen = false) {
     std::string id = "TOAST_ID_" + base::NumberToString(serial_++);
-    manager()->Show(ToastData(id, base::ASCIIToUTF16(text), duration,
+    manager()->Show(ToastData(id, ToastCatalogName::kToastManagerUnittest,
+                              base::ASCIIToUTF16(text), duration,
                               visible_on_lock_screen));
     return id;
   }
@@ -114,7 +116,8 @@
       localized_dismiss = base::ASCIIToUTF16(dismiss_text.value());
 
     std::string id = "TOAST_ID_" + base::NumberToString(serial_++);
-    manager()->Show(ToastData(id, base::ASCIIToUTF16(text), duration,
+    manager()->Show(ToastData(id, ToastCatalogName::kToastManagerUnittest,
+                              base::ASCIIToUTF16(text), duration,
                               /*visible_on_lock_screen=*/false,
                               localized_dismiss));
     return id;
@@ -126,7 +129,8 @@
                     const std::string& text,
                     int32_t duration,
                     bool visible_on_lock_screen = false) {
-    manager()->Show(ToastData(id, base::ASCIIToUTF16(text), duration,
+    manager()->Show(ToastData(id, ToastCatalogName::kToastManagerUnittest,
+                              base::ASCIIToUTF16(text), duration,
                               visible_on_lock_screen));
   }
 
diff --git a/ash/webui/personalization_app/resources/trusted/personalization_store.ts b/ash/webui/personalization_app/resources/trusted/personalization_store.ts
index e90db1c..44d97fc1 100644
--- a/ash/webui/personalization_app/resources/trusted/personalization_store.ts
+++ b/ash/webui/personalization_app/resources/trusted/personalization_store.ts
@@ -4,7 +4,7 @@
 
 import {Action, Store} from 'chrome://resources/js/cr/ui/store.js';
 import {StoreClient, StoreClientInterface} from 'chrome://resources/js/cr/ui/store_client.js';
-import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js';
+import {I18nMixin, I18nMixinInterface} from 'chrome://resources/js/i18n_mixin.js';
 import {IronResizableBehavior} from 'chrome://resources/polymer/v3_0/iron-resizable-behavior/iron-resizable-behavior.js';
 import {mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
@@ -106,14 +106,13 @@
     };
 
 export const WithPersonalizationStore: {
-  new (): PolymerElement&I18nBehavior&IronResizableBehavior&
+  new (): PolymerElement&I18nMixinInterface&IronResizableBehavior&
   PersonalizationStoreClient&StoreClientInterface
 } =
     mixinBehaviors(
         [
           StoreClient,
           PersonalizationStoreClientImpl,
-          I18nBehavior,
           IronResizableBehavior,
         ],
-        PolymerElement);
+        I18nMixin(PolymerElement));
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_error_element.ts b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_error_element.ts
index b8c5533..1074a96 100644
--- a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_error_element.ts
+++ b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_error_element.ts
@@ -9,13 +9,12 @@
  * that may have multiple sizes, not large rectangular svgs.
  */
 
-import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js';
-import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {I18nMixin} from 'chrome://resources/js/i18n_mixin.js';
+import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-const WithI18n: {new (): PolymerElement&I18nBehavior} =
-    mixinBehaviors([I18nBehavior], PolymerElement);
+const WallpaperErrorBase = I18nMixin(PolymerElement);
 
-export class WallpaperError extends WithI18n {
+export class WallpaperError extends WallpaperErrorBase {
   static get is() {
     return 'wallpaper-error';
   }
diff --git a/ash/webui/shimless_rma/backend/shimless_rma_service.cc b/ash/webui/shimless_rma/backend/shimless_rma_service.cc
index cce4f55..19f619b5 100644
--- a/ash/webui/shimless_rma/backend/shimless_rma_service.cc
+++ b/ash/webui/shimless_rma/backend/shimless_rma_service.cc
@@ -744,6 +744,8 @@
                             rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID);
     return;
   }
+  state_proto_.mutable_provision_device()->set_choice(
+      rmad::ProvisionDeviceState::RMAD_PROVISION_CHOICE_CONTINUE);
   TransitionNextStateGeneric(std::move(callback));
 }
 
diff --git a/ash/webui/shimless_rma/backend/shimless_rma_service_unittest.cc b/ash/webui/shimless_rma/backend/shimless_rma_service_unittest.cc
index d255e5a..84415ce9 100644
--- a/ash/webui/shimless_rma/backend/shimless_rma_service_unittest.cc
+++ b/ash/webui/shimless_rma/backend/shimless_rma_service_unittest.cc
@@ -2324,6 +2324,12 @@
       CreateStateReply(rmad::RmadState::kDeviceDestination,
                        rmad::RMAD_ERROR_OK)};
   fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states));
+  fake_rmad_client_()->check_state_callback =
+      base::BindRepeating([](const rmad::RmadState& state) {
+        EXPECT_EQ(state.state_case(), rmad::RmadState::kProvisionDevice);
+        EXPECT_EQ(state.provision_device().choice(),
+                  rmad::ProvisionDeviceState::RMAD_PROVISION_CHOICE_CONTINUE);
+      });
   base::RunLoop run_loop;
   shimless_rma_provider_->GetCurrentState(base::BindLambdaForTesting(
       [&](mojom::State state, bool can_cancel, bool can_go_back,
diff --git a/ash/webui/shimless_rma/resources/onboarding_update_page.html b/ash/webui/shimless_rma/resources/onboarding_update_page.html
index 2461445..75f48f4 100644
--- a/ash/webui/shimless_rma/resources/onboarding_update_page.html
+++ b/ash/webui/shimless_rma/resources/onboarding_update_page.html
@@ -13,10 +13,13 @@
 <base-page orientation="column">
   <div slot="header">
     <h1>[[i18n('osUpdateTitleText')]]</h1>
-    <div>[[updateNoticeMessage_]]</div>
+    <div hidden$="[[isCompliant_]]">
+      [[i18n('osUpdateInvalidComponentsDescriptionText')]]
+    </div>
+    <div hidden$="[[!isCompliant_]]">[[updateNoticeMessage_]]</div>
     <div id="versionInfo">
-      <iron-icon id="updateIcon" icon="[[getUpdateNoticeIcon_(updateAvailable_)]]"
-        class="small-icon">
+      <iron-icon id="updateIcon" class="small-icon"
+          icon="[[getUpdateNoticeIcon_(updateAvailable_)]]">
       </iron-icon>
       [[currentVersionText_]]
     </div>
diff --git a/ash/webui/shimless_rma/resources/onboarding_update_page.js b/ash/webui/shimless_rma/resources/onboarding_update_page.js
index 94a4401..21f67a8 100644
--- a/ash/webui/shimless_rma/resources/onboarding_update_page.js
+++ b/ash/webui/shimless_rma/resources/onboarding_update_page.js
@@ -71,7 +71,7 @@
       /** @protected */
       updateNoticeMessage_: {
         type: String,
-        value: '',
+        computed: 'computeUpdateNoticeMessage_(updateAvailable_)',
       },
 
       /** @protected */
@@ -124,7 +124,8 @@
     this.shimlessRmaService_.observeOsUpdateProgress(
         this.osUpdateObserverReceiver_.$.bindNewPipeAndPassRemote());
 
-    this.isCompliant_ = false;
+    // We assume it's compliant until updated in onHardwareVerificationResult().
+    this.isCompliant_ = true;
     /** @protected {?HardwareVerificationStatusObserverReceiver} */
     this.hwVerificationObserverReceiver_ =
         new HardwareVerificationStatusObserverReceiver(
@@ -173,7 +174,6 @@
           this.updateAvailable_ ? 'currentVersionOutOfDateText' :
                                   'currentVersionUpToDateText',
           this.currentVersion_);
-      this.setUpdateNoticeMessage_();
       this.setNextButtonLabel_();
     });
   }
@@ -210,26 +210,6 @@
     return !this.networkAvailable || this.updateAvailable_;
   }
 
-  /** @private */
-  setUpdateNoticeMessage_() {
-    if (!this.isCompliant_) {
-      this.updateNoticeMessage_ =
-          this.i18n('osUpdateInvalidComponentsDescriptionText');
-    } else if (this.updateAvailable_) {
-      // TODO(gavindodd): Do we need a check that the current major version is
-      // within n of the installed version to switch between this message and
-      // 'Chrome OS needs an additional update to get fully up to date.'?
-      this.updateNoticeMessage_ =
-          this.i18n('osUpdateVeryOutOfDateDescriptionText');
-    } else {
-      // Note: In current implementation this should not be reached, but it is
-      // still a perfectly valid state.
-      // If there was ever an update that did not require a reboot this would
-      // be reached.
-      this.updateNoticeMessage_ = '';
-    }
-  }
-
   /** @return {!Promise<StateResult>} */
   onNextButtonClick() {
     return this.shimlessRmaService_.updateOsSkipped();
@@ -268,7 +248,6 @@
    */
   onHardwareVerificationResult(isCompliant, errorMessage) {
     this.isCompliant_ = isCompliant;
-    this.setUpdateNoticeMessage_();
   }
 
   /** @protected */
@@ -282,6 +261,15 @@
         },
         ));
   }
+
+  /** @protected */
+  computeUpdateNoticeMessage_() {
+    // |updateAvailable_| is not expected to be false in this state but if there
+    // was ever an update that did not require a reboot this would be reached.
+    return this.updateAvailable_ ?
+        this.i18n('osUpdateOutOfDateDescriptionText') :
+        '';
+  }
 }
 
 customElements.define(
diff --git a/ash/wm/desks/templates/desks_templates_presenter.cc b/ash/wm/desks/templates/desks_templates_presenter.cc
index 7cbc36dd..a6d878f 100644
--- a/ash/wm/desks/templates/desks_templates_presenter.cc
+++ b/ash/wm/desks/templates/desks_templates_presenter.cc
@@ -6,8 +6,9 @@
 
 #include "ash/public/cpp/desk_template.h"
 #include "ash/public/cpp/desks_templates_delegate.h"
-#include "ash/public/cpp/toast_data.h"
-#include "ash/public/cpp/toast_manager.h"
+#include "ash/public/cpp/system/toast_catalog.h"
+#include "ash/public/cpp/system/toast_data.h"
+#include "ash/public/cpp/system/toast_manager.h"
 #include "ash/shell.h"
 #include "ash/strings/grit/ash_strings.h"
 #include "ash/wm/desks/desks_bar_view.h"
@@ -137,6 +138,7 @@
   if (!DesksController::Get()->CanCreateDesks()) {
     ToastData toast_data = {
         /*id=*/kMaximumDeskLaunchTemplateToastName,
+        ToastCatalogName::kMaximumDeskLaunchTemplate,
         /*text=*/
         l10n_util::GetStringFUTF16(
             IDS_ASH_DESKS_TEMPLATES_REACH_MAXIMUM_DESK_TOAST,
diff --git a/ash/wm/desks/templates/desks_templates_test_util.cc b/ash/wm/desks/templates/desks_templates_test_util.cc
index bb46796..7eae5e9 100644
--- a/ash/wm/desks/templates/desks_templates_test_util.cc
+++ b/ash/wm/desks/templates/desks_templates_test_util.cc
@@ -5,13 +5,17 @@
 #include "ash/wm/desks/templates/desks_templates_test_util.h"
 
 #include "ash/shell.h"
+#include "ash/style/close_button.h"
 #include "ash/wm/desks/desks_bar_view.h"
 #include "ash/wm/desks/expanded_desks_bar_button.h"
+#include "ash/wm/desks/templates/desks_templates_dialog_controller.h"
 #include "ash/wm/desks/templates/desks_templates_item_view.h"
 #include "ash/wm/desks/templates/desks_templates_presenter.h"
 #include "ash/wm/desks/zero_state_button.h"
 #include "ash/wm/overview/overview_grid.h"
 #include "ash/wm/overview/overview_test_util.h"
+#include "ui/views/widget/widget_delegate.h"
+#include "ui/views/window/dialog_delegate.h"
 
 namespace ash {
 
@@ -141,6 +145,21 @@
   return item ? static_cast<views::Button*>(item) : nullptr;
 }
 
+views::Button* GetTemplateItemDeleteButton(int index) {
+  auto* item = GetItemViewFromTemplatesGrid(index);
+  return item ? static_cast<views::Button*>(const_cast<CloseButton*>(
+                    DesksTemplatesItemViewTestApi(item).delete_button()))
+              : nullptr;
+}
+
+views::Button* GetDesksTemplatesDialogAcceptButton() {
+  const views::Widget* dialog_widget =
+      DesksTemplatesDialogController::Get()->dialog_widget();
+  if (!dialog_widget)
+    return nullptr;
+  return dialog_widget->widget_delegate()->AsDialogDelegate()->GetOkButton();
+}
+
 void WaitForDesksTemplatesUI() {
   auto* overview_session = GetOverviewSession();
   DCHECK(overview_session);
diff --git a/ash/wm/desks/templates/desks_templates_test_util.h b/ash/wm/desks/templates/desks_templates_test_util.h
index 8e95b8c..bbb4fc3 100644
--- a/ash/wm/desks/templates/desks_templates_test_util.h
+++ b/ash/wm/desks/templates/desks_templates_test_util.h
@@ -152,6 +152,8 @@
 views::Button* GetExpandedStateDesksTemplatesButton();
 views::Button* GetSaveDeskAsTemplateButton();
 views::Button* GetTemplateItemButton(int index);
+views::Button* GetTemplateItemDeleteButton(int index);
+views::Button* GetDesksTemplatesDialogAcceptButton();
 
 // A lot of the UI relies on calling into the local desk data manager to
 // update, which sends callbacks via posting tasks. Call
diff --git a/ash/wm/gestures/wm_gesture_handler.cc b/ash/wm/gestures/wm_gesture_handler.cc
index e726520..930d00908 100644
--- a/ash/wm/gestures/wm_gesture_handler.cc
+++ b/ash/wm/gestures/wm_gesture_handler.cc
@@ -6,7 +6,8 @@
 
 #include "ash/constants/ash_features.h"
 #include "ash/constants/ash_pref_names.h"
-#include "ash/public/cpp/toast_data.h"
+#include "ash/public/cpp/system/toast_catalog.h"
+#include "ash/public/cpp/system/toast_data.h"
 #include "ash/session/session_controller_impl.h"
 #include "ash/shell.h"
 #include "ash/strings/grit/ash_strings.h"
@@ -61,9 +62,11 @@
   return IsNaturalScrollOn() ? -offset : offset;
 }
 
-void ShowReverseGestureToast(const char* toast_id, int message_id) {
+void ShowReverseGestureToast(const char* toast_id,
+                             ToastCatalogName catalog_name,
+                             int message_id) {
   Shell::Get()->toast_manager()->Show(
-      ToastData(toast_id, l10n_util::GetStringUTF16(message_id)));
+      ToastData(toast_id, catalog_name, l10n_util::GetStringUTF16(message_id)));
 }
 
 // When reverse scrolling for touchpad is Off, if the user performs wrong
@@ -89,8 +92,11 @@
 
   if (*did_wrong_ptr) {
     ShowReverseGestureToast(
-        toast_id, in_overview ? IDS_CHANGE_EXIT_OVERVIEW_REVERSE_GESTURE
-                              : IDS_CHANGE_ENTER_OVERVIEW_REVERSE_GESTURE);
+        toast_id,
+        in_overview ? ToastCatalogName::kExitOverviewGesture
+                    : ToastCatalogName::kEnterOverviewGesture,
+        in_overview ? IDS_CHANGE_EXIT_OVERVIEW_REVERSE_GESTURE
+                    : IDS_CHANGE_ENTER_OVERVIEW_REVERSE_GESTURE);
   } else {
     *did_wrong_ptr = true;
   }
@@ -146,6 +152,7 @@
       g_did_wrong_next_desk_gesture = true;
     } else {
       ShowReverseGestureToast(kSwitchNextDeskToastId,
+                              ToastCatalogName::kNextDeskGesture,
                               IDS_CHANGE_NEXT_DESK_REVERSE_GESTURE);
     }
     return;
@@ -157,6 +164,7 @@
       g_did_wrong_last_desk_gesture = true;
     } else {
       ShowReverseGestureToast(kSwitchLastDeskToastId,
+                              ToastCatalogName::kPreviousDeskGesture,
                               IDS_CHANGE_LAST_DESK_REVERSE_GESTURE);
     }
     return;
diff --git a/ash/wm/overview/overview_grid.cc b/ash/wm/overview/overview_grid.cc
index ddaf6175..f8c580e2 100644
--- a/ash/wm/overview/overview_grid.cc
+++ b/ash/wm/overview/overview_grid.cc
@@ -17,6 +17,7 @@
 #include "ash/public/cpp/presentation_time_recorder.h"
 #include "ash/public/cpp/shelf_config.h"
 #include "ash/public/cpp/shelf_types.h"
+#include "ash/public/cpp/system/toast_catalog.h"
 #include "ash/public/cpp/window_properties.h"
 #include "ash/resources/vector_icons/vector_icons.h"
 #include "ash/root_window_controller.h"
@@ -1429,6 +1430,7 @@
     // to be unassigned during overview.
     Shell::Get()->toast_manager()->Show(
         ToastData(kMoveVisibleOnAllDesksWindowToastId,
+                  ToastCatalogName::kMoveVisibleOnAllDesksWindow,
                   l10n_util::GetStringUTF16(
                       IDS_ASH_OVERVIEW_VISIBLE_ON_ALL_DESKS_TOAST)));
     return false;
diff --git a/ash/wm/splitview/split_view_utils.cc b/ash/wm/splitview/split_view_utils.cc
index 6ac0677..a030085 100644
--- a/ash/wm/splitview/split_view_utils.cc
+++ b/ash/wm/splitview/split_view_utils.cc
@@ -6,7 +6,8 @@
 
 #include "ash/accessibility/accessibility_controller_impl.h"
 #include "ash/constants/ash_features.h"
-#include "ash/public/cpp/toast_data.h"
+#include "ash/public/cpp/system/toast_catalog.h"
+#include "ash/public/cpp/system/toast_data.h"
 #include "ash/screen_util.h"
 #include "ash/shell.h"
 #include "ash/strings/grit/ash_strings.h"
@@ -399,7 +400,7 @@
 
 void ShowAppCannotSnapToast() {
   Shell::Get()->toast_manager()->Show(
-      ToastData(kAppCannotSnapToastId,
+      ToastData(kAppCannotSnapToastId, ToastCatalogName::kAppCannotSnap,
                 l10n_util::GetStringUTF16(IDS_ASH_SPLIT_VIEW_CANNOT_SNAP)));
 }
 
diff --git a/ash/wm/window_restore/window_restore_controller.cc b/ash/wm/window_restore/window_restore_controller.cc
index cc2c58e..288bd56 100644
--- a/ash/wm/window_restore/window_restore_controller.cc
+++ b/ash/wm/window_restore/window_restore_controller.cc
@@ -326,7 +326,7 @@
   MaybeRestoreOutOfBoundsWindows(window);
 }
 
-void WindowRestoreController::OnARCTaskReadyForUnparentedWindow(
+void WindowRestoreController::OnParentWindowToValidContainer(
     aura::Window* window) {
   DCHECK(window);
   DCHECK(window->GetProperty(app_restore::kParentToHiddenContainerKey));
diff --git a/ash/wm/window_restore/window_restore_controller.h b/ash/wm/window_restore/window_restore_controller.h
index a3cc5a20..107a655 100644
--- a/ash/wm/window_restore/window_restore_controller.h
+++ b/ash/wm/window_restore/window_restore_controller.h
@@ -95,7 +95,7 @@
                             bool could_restore) override;
   void OnAppLaunched(aura::Window* window) override;
   void OnWidgetInitialized(views::Widget* widget) override;
-  void OnARCTaskReadyForUnparentedWindow(aura::Window* window) override;
+  void OnParentWindowToValidContainer(aura::Window* window) override;
 
   // aura::WindowObserver:
   void OnWindowPropertyChanged(aura::Window* window,
diff --git a/ash/wm/window_restore/window_restore_controller_unittest.cc b/ash/wm/window_restore/window_restore_controller_unittest.cc
index 66d8405a..fd4edcf 100644
--- a/ash/wm/window_restore/window_restore_controller_unittest.cc
+++ b/ash/wm/window_restore/window_restore_controller_unittest.cc
@@ -1058,7 +1058,7 @@
 
   // Simulate having the task ready. Our `restored_window` should now be
   // parented to the desk associated with desk 3, which is desk D.
-  WindowRestoreController::Get()->OnARCTaskReadyForUnparentedWindow(
+  WindowRestoreController::Get()->OnParentWindowToValidContainer(
       restored_window);
   EXPECT_EQ(Shell::GetContainer(root_window, kShellWindowId_DeskContainerD),
             restored_window->parent());
@@ -1103,7 +1103,7 @@
   EXPECT_EQ(Shell::GetContainer(secondary_root_window,
                                 kShellWindowId_UnparentedContainer),
             restored_window1->parent());
-  WindowRestoreController::Get()->OnARCTaskReadyForUnparentedWindow(
+  WindowRestoreController::Get()->OnParentWindowToValidContainer(
       restored_window1);
   EXPECT_EQ(
       Shell::GetContainer(secondary_root_window, kShellWindowId_DeskContainerD),
@@ -1125,7 +1125,7 @@
   display_info_list.push_back(primary_info);
   display_manager()->OnNativeDisplaysChanged(display_info_list);
 
-  WindowRestoreController::Get()->OnARCTaskReadyForUnparentedWindow(
+  WindowRestoreController::Get()->OnParentWindowToValidContainer(
       restored_window2);
   EXPECT_EQ(
       Shell::GetContainer(primary_root_window, kShellWindowId_DeskContainerD),
diff --git a/base/allocator/partition_allocator/dot/super-page.dot b/base/allocator/partition_allocator/dot/super-page.dot
index 44673e9e..36187fbc 100644
--- a/base/allocator/partition_allocator/dot/super-page.dot
+++ b/base/allocator/partition_allocator/dot/super-page.dot
@@ -26,8 +26,8 @@
         <TD PORT="green" BGCOLOR="palegreen" WIDTH="39">1</TD>
         <TD PORT="blue" BGCOLOR="cornflowerblue" WIDTH="79">2</TD>
         <TD PORT="gold" BGCOLOR="gold" WIDTH="239">6</TD>
-        <TD PORT="red2" BGCOLOR="crimson" WIDTH="79">2</TD>
-        <TD PORT="pink" BGCOLOR="deeppink" WIDTH="119">3</TD>
+        <TD PORT="red2" BGCOLOR="crimson" WIDTH="119">3</TD>
+        <TD PORT="pink" BGCOLOR="deeppink" WIDTH="39">1</TD>
         <TD WIDTH="79">...</TD>
         <!-- Tail Partition Page -->
         <TD BGCOLOR="darkgrey" WIDTH="39"></TD>
@@ -48,6 +48,8 @@
   metadata_page[xlabel="Metadata",label=<
     <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
       <TR>
+        <!-- Guard Page Metadata -->
+        <TD BGCOLOR="darkgrey"> </TD>
         <!-- Red Slot Span Metadata -->
         <TD BGCOLOR="crimson">v</TD>
         <TD BGCOLOR="crimson">+</TD>
@@ -67,12 +69,13 @@
         <!-- Red Slot Span Metadata -->
         <TD BGCOLOR="crimson">v</TD>
         <TD BGCOLOR="crimson">+</TD>
+        <TD BGCOLOR="crimson">+</TD>
         <!-- Pink Slot Span Metadata -->
         <TD BGCOLOR="deeppink">v</TD>
-        <TD BGCOLOR="deeppink">+</TD>
-        <TD BGCOLOR="deeppink">+</TD>
         <!-- etc. -->
         <TD WIDTH="64">...</TD>
+        <!-- Guard Page Metadata -->
+        <TD BGCOLOR="darkgrey"> </TD>
       </TR>
     </TABLE>
   >]
diff --git a/base/allocator/partition_allocator/dot/super-page.png b/base/allocator/partition_allocator/dot/super-page.png
index 8d64101..0d51bae 100644
--- a/base/allocator/partition_allocator/dot/super-page.png
+++ b/base/allocator/partition_allocator/dot/super-page.png
Binary files differ
diff --git a/base/android/java/src/org/chromium/base/process_launcher/ChildProcessConnection.java b/base/android/java/src/org/chromium/base/process_launcher/ChildProcessConnection.java
index f024ef4..0040835 100644
--- a/base/android/java/src/org/chromium/base/process_launcher/ChildProcessConnection.java
+++ b/base/android/java/src/org/chromium/base/process_launcher/ChildProcessConnection.java
@@ -767,14 +767,15 @@
 
     public void updateGroupImportance(int group, int importanceInGroup) {
         assert isRunningOnLauncherThread();
-        if (!isConnected()) return;
         assert !mUnbound;
         assert mWaivedBinding.isBound();
         assert group != 0 || importanceInGroup == 0;
         if (mGroup != group || mImportanceInGroup != importanceInGroup) {
             mGroup = group;
             mImportanceInGroup = importanceInGroup;
-            mWaivedBinding.updateGroupImportance(group, importanceInGroup);
+            if (isConnected()) {
+                mWaivedBinding.updateGroupImportance(group, importanceInGroup);
+            }
         }
     }
 
diff --git a/base/observer_list_internal.h b/base/observer_list_internal.h
index 5f58c69..651e5d8 100644
--- a/base/observer_list_internal.h
+++ b/base/observer_list_internal.h
@@ -13,7 +13,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list_types.h"
 
-#if DCHECK_IS_ON()
+#if EXPENSIVE_DCHECKS_ARE_ON()
 #include "base/debug/stack_trace.h"
 #endif
 
@@ -104,13 +104,13 @@
     return static_cast<ObserverType*>(adapter.weak_ptr_.get());
   }
 
-#if DCHECK_IS_ON()
+#if EXPENSIVE_DCHECKS_ARE_ON()
   std::string GetCreationStackString() const { return stack_.ToString(); }
 #endif
 
  private:
   WeakPtr<CheckedObserver> weak_ptr_;
-#if DCHECK_IS_ON()
+#if EXPENSIVE_DCHECKS_ARE_ON()
   base::debug::StackTrace stack_;
 #endif
 };
diff --git a/base/task/delayed_task_handle.cc b/base/task/delayed_task_handle.cc
index bd0c370..0c32eb4 100644
--- a/base/task/delayed_task_handle.cc
+++ b/base/task/delayed_task_handle.cc
@@ -41,6 +41,7 @@
   if (delegate_) {
     delegate_->CancelTask();
     DCHECK(!delegate_->IsValid());
+    delegate_.reset();
   }
 }
 
diff --git a/base/task/delayed_task_handle_unittest.cc b/base/task/delayed_task_handle_unittest.cc
index 05dbd1c..7ea2715 100644
--- a/base/task/delayed_task_handle_unittest.cc
+++ b/base/task/delayed_task_handle_unittest.cc
@@ -14,15 +14,26 @@
 // A non-working delegate that allows the testing of DelayedTaskHandle.
 class TestDelegate : public DelayedTaskHandle::Delegate {
  public:
-  TestDelegate() = default;
+  explicit TestDelegate(bool* was_cancel_task_called = nullptr)
+      : was_cancel_task_called_(was_cancel_task_called) {
+    DCHECK(!was_cancel_task_called_ || !*was_cancel_task_called_);
+  }
   ~TestDelegate() override = default;
 
   bool IsValid() const override { return is_valid_; }
-  void CancelTask() override { is_valid_ = false; }
+  void CancelTask() override {
+    is_valid_ = false;
+
+    if (was_cancel_task_called_)
+      *was_cancel_task_called_ = true;
+  }
 
  private:
   // Indicates if this delegate is currently valid.
   bool is_valid_ = true;
+
+  // Indicates if CancelTask() was invoked, if not null. Must outlives |this|.
+  bool* was_cancel_task_called_;
 };
 
 }  // namespace
@@ -49,17 +60,20 @@
 // Tests that calling CancelTask() on the handle will call CancelTask() on the
 // delegate and invalidate it.
 TEST(DelayedTaskHandleTest, CancelTask) {
-  auto delegate = std::make_unique<TestDelegate>();
+  bool was_cancel_task_called = false;
+  auto delegate = std::make_unique<TestDelegate>(&was_cancel_task_called);
+  EXPECT_FALSE(was_cancel_task_called);
   EXPECT_TRUE(delegate->IsValid());
 
   auto* delegate_ptr = delegate.get();
   DelayedTaskHandle delayed_task_handle(std::move(delegate));
+  EXPECT_FALSE(was_cancel_task_called);
   EXPECT_TRUE(delegate_ptr->IsValid());
   EXPECT_TRUE(delayed_task_handle.IsValid());
 
   delayed_task_handle.CancelTask();
 
-  EXPECT_FALSE(delegate_ptr->IsValid());
+  EXPECT_TRUE(was_cancel_task_called);
   EXPECT_FALSE(delayed_task_handle.IsValid());
 }
 
@@ -72,25 +86,33 @@
   EXPECT_FALSE(delayed_task_handle.IsValid());
 }
 
-// Tests that calling CancelTask() on a handle with an invalid delegate will
-// no-op.
+// Tests that calling CancelTask() on a handle with an invalid delegate doesn't
+// crash and keeps the handle invalid.
 TEST(DelayedTaskHandleTest, CancelTaskInvalidDelegate) {
-  auto delegate = std::make_unique<TestDelegate>();
+  bool was_cancel_task_called = false;
+  auto delegate = std::make_unique<TestDelegate>(&was_cancel_task_called);
+  EXPECT_FALSE(was_cancel_task_called);
   EXPECT_TRUE(delegate->IsValid());
 
   auto* delegate_ptr = delegate.get();
   DelayedTaskHandle delayed_task_handle(std::move(delegate));
+  EXPECT_FALSE(was_cancel_task_called);
   EXPECT_TRUE(delegate_ptr->IsValid());
   EXPECT_TRUE(delayed_task_handle.IsValid());
 
   delegate_ptr->CancelTask();
 
+  EXPECT_TRUE(was_cancel_task_called);
   EXPECT_FALSE(delegate_ptr->IsValid());
   EXPECT_FALSE(delayed_task_handle.IsValid());
 
+  // Reset |was_cancel_task_called| to ensure Delegate::CancelTask() is still
+  // invoked on an invalid delegate.
+  was_cancel_task_called = false;
+
   delayed_task_handle.CancelTask();
 
-  EXPECT_FALSE(delegate_ptr->IsValid());
+  EXPECT_TRUE(was_cancel_task_called);
   EXPECT_FALSE(delayed_task_handle.IsValid());
 }
 
diff --git a/base/task/sequence_manager/delayed_task_handle_delegate.cc b/base/task/sequence_manager/delayed_task_handle_delegate.cc
index 41bfdd1..06388c1 100644
--- a/base/task/sequence_manager/delayed_task_handle_delegate.cc
+++ b/base/task/sequence_manager/delayed_task_handle_delegate.cc
@@ -60,7 +60,7 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(IsValid());
   // The task must be removed from the heap before running it.
-  DCHECK(heap_handle_.IsValid());
+  DCHECK(!heap_handle_.IsValid());
   weak_ptr_factory_.InvalidateWeakPtrs();
 }
 
diff --git a/base/task/thread_pool/thread_group.cc b/base/task/thread_pool/thread_group.cc
index 96e3309..11dd18a 100644
--- a/base/task/thread_pool/thread_group.cc
+++ b/base/task/thread_pool/thread_group.cc
@@ -315,15 +315,6 @@
       }
       break;
     }
-    case WorkerEnvironment::COM_STA: {
-      // When defined(COM_INIT_CHECK_HOOK_ENABLED), ignore
-      // WorkerEnvironment::COM_STA to find incorrect uses of
-      // COM that should be running in a COM STA Task Runner.
-#if !defined(COM_INIT_CHECK_HOOK_ENABLED)
-      scoped_environment = std::make_unique<win::ScopedCOMInitializer>();
-#endif
-      break;
-    }
     default:
       break;
   }
diff --git a/base/task/thread_pool/thread_group.h b/base/task/thread_pool/thread_group.h
index b4811e0a5..223a879 100644
--- a/base/task/thread_pool/thread_group.h
+++ b/base/task/thread_pool/thread_group.h
@@ -50,8 +50,6 @@
 #if BUILDFLAG(IS_WIN)
     // Initialize a COM MTA on the worker.
     COM_MTA,
-    // Initialize a COM STA on the worker.
-    COM_STA,
 #endif  // BUILDFLAG(IS_WIN)
   };
 
diff --git a/base/task/thread_pool/thread_group_unittest.cc b/base/task/thread_pool/thread_group_unittest.cc
index cf7aeaf..c22fad80 100644
--- a/base/task/thread_pool/thread_group_unittest.cc
+++ b/base/task/thread_pool/thread_group_unittest.cc
@@ -531,28 +531,6 @@
   task_ran.Wait();
 }
 
-TEST_P(ThreadGroupTestAllExecutionModes, COMSTAWorkerEnvironment) {
-  StartThreadGroup(ThreadGroup::WorkerEnvironment::COM_STA);
-  auto task_runner = test::CreatePooledTaskRunnerWithExecutionMode(
-      execution_mode(), &mock_pooled_task_runner_delegate_);
-
-  TestWaitableEvent task_ran;
-  task_runner->PostTask(
-      FROM_HERE, BindOnce(
-                     [](TestWaitableEvent* task_ran) {
-  // COM STA is ignored when defined(COM_INIT_CHECK_HOOK_ENABLED). See comment
-  // in ThreadGroup::GetScopedWindowsThreadEnvironment().
-#if defined(COM_INIT_CHECK_HOOK_ENABLED)
-                       win::AssertComApartmentType(win::ComApartmentType::NONE);
-#else
-                       win::AssertComApartmentType(win::ComApartmentType::STA);
-#endif
-                       task_ran->Signal();
-                     },
-                     Unretained(&task_ran)));
-  task_ran.Wait();
-}
-
 TEST_P(ThreadGroupTestAllExecutionModes, NoWorkerEnvironment) {
   StartThreadGroup(ThreadGroup::WorkerEnvironment::NONE);
   auto task_runner = test::CreatePooledTaskRunnerWithExecutionMode(
diff --git a/base/task/thread_pool/thread_pool_impl.cc b/base/task/thread_pool/thread_pool_impl.cc
index aefdc9e..13fde29 100644
--- a/base/task/thread_pool/thread_pool_impl.cc
+++ b/base/task/thread_pool/thread_pool_impl.cc
@@ -203,10 +203,6 @@
     case InitParams::CommonThreadPoolEnvironment::COM_MTA:
       worker_environment = ThreadGroup::WorkerEnvironment::COM_MTA;
       break;
-    case InitParams::CommonThreadPoolEnvironment::
-        DEPRECATED_COM_STA_IN_FOREGROUND_GROUP:
-      worker_environment = ThreadGroup::WorkerEnvironment::COM_STA;
-      break;
 #endif
   }
 
@@ -245,15 +241,7 @@
       static_cast<ThreadGroupImpl*>(background_thread_group_.get())
           ->Start(max_best_effort_tasks, max_best_effort_tasks,
                   suggested_reclaim_time, service_thread_task_runner,
-                  worker_thread_observer,
-#if BUILDFLAG(IS_WIN)
-                  // COM STA is a backward-compatibility feature for the
-                  // foreground thread group only.
-                  worker_environment == ThreadGroup::WorkerEnvironment::COM_STA
-                      ? ThreadGroup::WorkerEnvironment::NONE
-                      :
-#endif
-                      worker_environment,
+                  worker_thread_observer, worker_environment,
                   g_synchronous_thread_start_for_testing);
     }
   }
diff --git a/base/task/thread_pool/thread_pool_instance.h b/base/task/thread_pool/thread_pool_instance.h
index 2f05a75..c96f99b3 100644
--- a/base/task/thread_pool/thread_pool_instance.h
+++ b/base/task/thread_pool/thread_pool_instance.h
@@ -55,12 +55,6 @@
 #if BUILDFLAG(IS_WIN)
       // Place the pool's workers in a COM MTA.
       COM_MTA,
-      // Place the pool's *foreground* workers in a COM STA. This exists to
-      // mimic the behavior of SequencedWorkerPool and BrowserThreadImpl that
-      // ThreadPool has replaced. Tasks that need a COM STA should use
-      // CreateCOMSTATaskRunner() instead of Create(Sequenced)TaskRunner() +
-      // this init param.
-      DEPRECATED_COM_STA_IN_FOREGROUND_GROUP,
 #endif  // BUILDFLAG(IS_WIN)
     };
 
diff --git a/base/time/time.h b/base/time/time.h
index a1213842..9536dad 100644
--- a/base/time/time.h
+++ b/base/time/time.h
@@ -174,16 +174,7 @@
   constexpr int64_t ToInternalValue() const { return delta_; }
 
   // Returns the magnitude (absolute value) of this TimeDelta.
-  constexpr TimeDelta magnitude() const {
-    // The code below will not work correctly in this corner case.
-    if (is_min())
-      return Max();
-
-    // std::abs() is not currently constexpr.  The following is a simple
-    // branchless implementation:
-    const int64_t mask = delta_ >> (sizeof(delta_) * 8 - 1);
-    return TimeDelta((delta_ + mask) ^ mask);
-  }
+  constexpr TimeDelta magnitude() const { return TimeDelta(delta_.Abs()); }
 
   // Returns true if the time delta is a zero, positive or negative time delta.
   constexpr bool is_zero() const { return delta_ == 0; }
@@ -251,19 +242,11 @@
   // Computations with numeric types.
   template <typename T>
   constexpr TimeDelta operator*(T a) const {
-    CheckedNumeric<int64_t> rv(delta_);
-    rv *= a;
-    if (rv.IsValid())
-      return TimeDelta(rv.ValueOrDie());
-    return ((delta_ < 0) == (a < 0)) ? Max() : Min();
+    return TimeDelta(int64_t{delta_ * a});
   }
   template <typename T>
   constexpr TimeDelta operator/(T a) const {
-    CheckedNumeric<int64_t> rv(delta_);
-    rv /= a;
-    if (rv.IsValid())
-      return TimeDelta(rv.ValueOrDie());
-    return ((delta_ < 0) == (a < 0)) ? Max() : Min();
+    return TimeDelta(int64_t{delta_ / a});
   }
   template <typename T>
   constexpr TimeDelta& operator*=(T a) {
@@ -290,7 +273,7 @@
   }
   constexpr int64_t IntDiv(TimeDelta a) const {
     if (!is_inf() && !a.is_zero())
-      return delta_ / a.delta_;
+      return int64_t{delta_ / a.delta_};
 
     // For consistency, use the same edge case CHECKs and behavior as the code
     // above.
@@ -340,6 +323,8 @@
   // to avoid confusion by callers with an integer constructor. Use
   // base::Seconds, base::Milliseconds, etc. instead.
   constexpr explicit TimeDelta(int64_t delta_us) : delta_(delta_us) {}
+  constexpr explicit TimeDelta(ClampedNumeric<int64_t> delta_us)
+      : delta_(delta_us) {}
 
   // Returns a double representation of this TimeDelta's tick count.  In
   // particular, Max()/Min() are converted to +/-infinity.
@@ -351,12 +336,12 @@
   }
 
   // Delta in microseconds.
-  int64_t delta_ = 0;
+  ClampedNumeric<int64_t> delta_ = 0;
 };
 
 constexpr TimeDelta TimeDelta::operator+(TimeDelta other) const {
   if (!other.is_inf())
-    return TimeDelta(int64_t{base::ClampAdd(delta_, other.delta_)});
+    return TimeDelta(delta_ + other.delta_);
 
   // Additions involving two infinities are only valid if signs match.
   CHECK(!is_inf() || (delta_ == other.delta_));
@@ -365,10 +350,10 @@
 
 constexpr TimeDelta TimeDelta::operator-(TimeDelta other) const {
   if (!other.is_inf())
-    return TimeDelta(int64_t{base::ClampSub(delta_, other.delta_)});
+    return TimeDelta(delta_ - other.delta_);
 
   // Subtractions involving two infinities are only valid if signs differ.
-  CHECK_NE(delta_, other.delta_);
+  CHECK_NE(int64_t{delta_}, int64_t{other.delta_});
   return (other.delta_ < 0) ? Max() : Min();
 }
 
@@ -487,13 +472,6 @@
   int64_t us_;
 };
 
-template <typename T>
-using EnableIfIntegral = typename std::
-    enable_if<std::is_integral<T>::value || std::is_enum<T>::value, int>::type;
-template <typename T>
-using EnableIfFloat =
-    typename std::enable_if<std::is_floating_point<T>::value, int>::type;
-
 }  // namespace time_internal
 
 template <class TimeClass>
@@ -841,87 +819,47 @@
 // precisely equal |t|. Hence, floating point values should not be used for
 // storage.
 
-template <typename T, time_internal::EnableIfIntegral<T> = 0>
+template <typename T>
 constexpr TimeDelta Days(T n) {
-  return TimeDelta::FromInternalValue(
-      ClampMul(static_cast<int64_t>(n), Time::kMicrosecondsPerDay));
+  return TimeDelta::FromInternalValue(MakeClampedNum(n) *
+                                      Time::kMicrosecondsPerDay);
 }
-template <typename T, time_internal::EnableIfIntegral<T> = 0>
+template <typename T>
 constexpr TimeDelta Hours(T n) {
-  return TimeDelta::FromInternalValue(
-      ClampMul(static_cast<int64_t>(n), Time::kMicrosecondsPerHour));
+  return TimeDelta::FromInternalValue(MakeClampedNum(n) *
+                                      Time::kMicrosecondsPerHour);
 }
-template <typename T, time_internal::EnableIfIntegral<T> = 0>
+template <typename T>
 constexpr TimeDelta Minutes(T n) {
-  return TimeDelta::FromInternalValue(
-      ClampMul(static_cast<int64_t>(n), Time::kMicrosecondsPerMinute));
+  return TimeDelta::FromInternalValue(MakeClampedNum(n) *
+                                      Time::kMicrosecondsPerMinute);
 }
-template <typename T, time_internal::EnableIfIntegral<T> = 0>
+template <typename T>
 constexpr TimeDelta Seconds(T n) {
-  return TimeDelta::FromInternalValue(
-      ClampMul(static_cast<int64_t>(n), Time::kMicrosecondsPerSecond));
+  return TimeDelta::FromInternalValue(MakeClampedNum(n) *
+                                      Time::kMicrosecondsPerSecond);
 }
-template <typename T, time_internal::EnableIfIntegral<T> = 0>
+template <typename T>
 constexpr TimeDelta Milliseconds(T n) {
-  return TimeDelta::FromInternalValue(
-      ClampMul(static_cast<int64_t>(n), Time::kMicrosecondsPerMillisecond));
+  return TimeDelta::FromInternalValue(MakeClampedNum(n) *
+                                      Time::kMicrosecondsPerMillisecond);
 }
-template <typename T, time_internal::EnableIfIntegral<T> = 0>
+template <typename T>
 constexpr TimeDelta Microseconds(T n) {
-  return TimeDelta::FromInternalValue(static_cast<int64_t>(n));
+  return TimeDelta::FromInternalValue(MakeClampedNum(n));
 }
-template <typename T, time_internal::EnableIfIntegral<T> = 0>
+template <typename T>
 constexpr TimeDelta Nanoseconds(T n) {
-  return TimeDelta::FromInternalValue(static_cast<int64_t>(n) /
+  return TimeDelta::FromInternalValue(MakeClampedNum(n) /
                                       Time::kNanosecondsPerMicrosecond);
 }
-template <typename T, time_internal::EnableIfIntegral<T> = 0>
+template <typename T>
 constexpr TimeDelta Hertz(T n) {
   return n ? TimeDelta::FromInternalValue(Time::kMicrosecondsPerSecond /
-                                          static_cast<int64_t>(n))
+                                          MakeClampedNum(n))
            : TimeDelta::Max();
 }
 
-template <typename T, time_internal::EnableIfFloat<T> = 0>
-constexpr TimeDelta Days(T n) {
-  return TimeDelta::FromInternalValue(
-      saturated_cast<int64_t>(n * Time::kMicrosecondsPerDay));
-}
-template <typename T, time_internal::EnableIfFloat<T> = 0>
-constexpr TimeDelta Hours(T n) {
-  return TimeDelta::FromInternalValue(
-      saturated_cast<int64_t>(n * Time::kMicrosecondsPerHour));
-}
-template <typename T, time_internal::EnableIfFloat<T> = 0>
-constexpr TimeDelta Minutes(T n) {
-  return TimeDelta::FromInternalValue(
-      saturated_cast<int64_t>(n * Time::kMicrosecondsPerMinute));
-}
-template <typename T, time_internal::EnableIfFloat<T> = 0>
-constexpr TimeDelta Seconds(T n) {
-  return TimeDelta::FromInternalValue(
-      saturated_cast<int64_t>(n * Time::kMicrosecondsPerSecond));
-}
-template <typename T, time_internal::EnableIfFloat<T> = 0>
-constexpr TimeDelta Milliseconds(T n) {
-  return TimeDelta::FromInternalValue(
-      saturated_cast<int64_t>(n * Time::kMicrosecondsPerMillisecond));
-}
-template <typename T, time_internal::EnableIfFloat<T> = 0>
-constexpr TimeDelta Microseconds(T n) {
-  return TimeDelta::FromInternalValue(saturated_cast<int64_t>(n));
-}
-template <typename T, time_internal::EnableIfFloat<T> = 0>
-constexpr TimeDelta Nanoseconds(T n) {
-  return TimeDelta::FromInternalValue(
-      saturated_cast<int64_t>(n / Time::kNanosecondsPerMicrosecond));
-}
-template <typename T, time_internal::EnableIfFloat<T> = 0>
-constexpr TimeDelta Hertz(T n) {
-  return TimeDelta::FromInternalValue(
-      saturated_cast<int64_t>(Time::kMicrosecondsPerSecond / n));
-}
-
 // TimeDelta functions that must appear below the declarations of Time/TimeDelta
 
 constexpr double TimeDelta::ToHz() const {
diff --git a/base/win/shortcut_unittest.cc b/base/win/shortcut_unittest.cc
index 2112788..02a7298 100644
--- a/base/win/shortcut_unittest.cc
+++ b/base/win/shortcut_unittest.cc
@@ -147,6 +147,10 @@
 }
 
 TEST_F(ShortcutTest, CreateAndResolveShortcut) {
+  // TODO(crbug.com/1264563): Disabled on Win7 bots for being flaky.
+  if (base::win::OSInfo::GetInstance()->version() <= base::win::Version::WIN7)
+    GTEST_SKIP() << "Skipping test for win7";
+
   ShortcutProperties only_target_properties;
   only_target_properties.set_target(link_properties_.target);
 
@@ -162,6 +166,10 @@
 }
 
 TEST_F(ShortcutTest, ResolveShortcutWithArgs) {
+  // TODO(crbug.com/1264563): Disabled on Win7 bots for being flaky.
+  if (base::win::OSInfo::GetInstance()->version() <= base::win::Version::WIN7)
+    GTEST_SKIP() << "Skipping test for win7";
+
   ASSERT_TRUE(CreateOrUpdateShortcutLink(link_file_, link_properties_,
                                          SHORTCUT_CREATE_ALWAYS));
 
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1
index 025bcdc..4d0938f 100644
--- a/build/fuchsia/linux.sdk.sha1
+++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@
-7.20220118.1.1
+7.20220112.2.4
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1
index 025bcdc..4d0938f 100644
--- a/build/fuchsia/mac.sdk.sha1
+++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@
-7.20220118.1.1
+7.20220112.2.4
diff --git a/build/rust/rust_target.gni b/build/rust/rust_target.gni
index f397af05..21dedd70 100644
--- a/build/rust/rust_target.gni
+++ b/build/rust/rust_target.gni
@@ -226,5 +226,16 @@
 
 set_defaults("rust_target") {
   executable_configs = default_executable_configs
+
+  # lld currently eats a section which Rust executables need to
+  # determine their command line arguments. These lines work around this
+  # by retaining all sections.
+  # TODO(crbug/1281664) - remove these lines when this is fixed.
+  executable_configs -= [ "//build/config/compiler:default_optimization" ]
+  executable_configs += [
+    "//build/config/compiler:no_optimize",
+    "//build/rust:keep_sections",
+  ]
+
   library_configs = default_compiler_configs
 }
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index 9bec4cc..f2b89b1 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -414,6 +414,7 @@
     "//chrome/browser/ui/android/layouts:java",
     "//chrome/browser/ui/android/layouts/glue:java",
     "//chrome/browser/ui/android/layouts/third_party/float_property:java",
+    "//chrome/browser/ui/android/logo:java",
     "//chrome/browser/ui/android/management:java",
     "//chrome/browser/ui/android/multiwindow:java",
     "//chrome/browser/ui/android/native_page:java",
@@ -810,6 +811,7 @@
     "//chrome/browser/tab:jni_headers",
     "//chrome/browser/touch_to_fill/android:jni_headers",
     "//chrome/browser/ui/android/favicon:jni_headers",
+    "//chrome/browser/ui/android/logo:jni_headers",
     "//chrome/browser/ui/android/omnibox:jni_headers",
     "//chrome/browser/ui/android/toolbar:jni_headers",
     "//chrome/browser/ui/android/webid:jni_headers",
@@ -1016,6 +1018,7 @@
     "//chrome/browser/ui/android/favicon:java",
     "//chrome/browser/ui/android/layouts:java",
     "//chrome/browser/ui/android/layouts:junit",
+    "//chrome/browser/ui/android/logo:java",
     "//chrome/browser/ui/android/multiwindow:java",
     "//chrome/browser/ui/android/multiwindow:junit",
     "//chrome/browser/ui/android/native_page:java",
@@ -1404,6 +1407,7 @@
     "//chrome/browser/ui/android/layouts:java",
     "//chrome/browser/ui/android/layouts/test:java",
     "//chrome/browser/ui/android/layouts/third_party/float_property:java",
+    "//chrome/browser/ui/android/logo:javatests",
     "//chrome/browser/ui/android/multiwindow:javatests",
     "//chrome/browser/ui/android/native_page:java",
     "//chrome/browser/ui/android/night_mode:java",
@@ -3937,7 +3941,6 @@
     "java/src/org/chromium/chrome/browser/notifications/scheduler/DisplayAgent.java",
     "java/src/org/chromium/chrome/browser/notifications/scheduler/NotificationSchedulerTask.java",
     "java/src/org/chromium/chrome/browser/ntp/ForeignSessionHelper.java",
-    "java/src/org/chromium/chrome/browser/ntp/LogoBridge.java",
     "java/src/org/chromium/chrome/browser/ntp/RecentTabsPagePrefs.java",
     "java/src/org/chromium/chrome/browser/ntp/RecentlyClosedBridge.java",
     "java/src/org/chromium/chrome/browser/offlinepages/AutoFetchNotifier.java",
diff --git a/chrome/android/chrome_java_resources.gni b/chrome/android/chrome_java_resources.gni
index 3cf8e16..367579a 100644
--- a/chrome/android/chrome_java_resources.gni
+++ b/chrome/android/chrome_java_resources.gni
@@ -40,7 +40,6 @@
   "java/res/drawable-hdpi/data_reduction_breakdown_sort_arrow.png",
   "java/res/drawable-hdpi/diners_card.png",
   "java/res/drawable-hdpi/down_arrow.png",
-  "java/res/drawable-hdpi/google_logo.png",
   "java/res/drawable-hdpi/help_outline.png",
   "java/res/drawable-hdpi/ic_devices_16dp.png",
   "java/res/drawable-hdpi/ic_devices_48dp.png",
@@ -135,7 +134,6 @@
   "java/res/drawable-mdpi/data_reduction_breakdown_sort_arrow.png",
   "java/res/drawable-mdpi/diners_card.png",
   "java/res/drawable-mdpi/down_arrow.png",
-  "java/res/drawable-mdpi/google_logo.png",
   "java/res/drawable-mdpi/help_outline.png",
   "java/res/drawable-mdpi/ic_devices_16dp.png",
   "java/res/drawable-mdpi/ic_devices_48dp.png",
@@ -196,11 +194,6 @@
   "java/res/drawable-mdpi/verify_checkmark.png",
   "java/res/drawable-nodpi/bookmark_widget_preview.png",
   "java/res/drawable-nodpi/widget_preview.png",
-  "java/res/drawable-sw600dp-hdpi/google_logo.png",
-  "java/res/drawable-sw600dp-mdpi/google_logo.png",
-  "java/res/drawable-sw600dp-xhdpi/google_logo.png",
-  "java/res/drawable-sw600dp-xxhdpi/google_logo.png",
-  "java/res/drawable-sw600dp-xxxhdpi/google_logo.png",
   "java/res/drawable-sw600dp/toolbar_shadow.xml",
   "java/res/drawable-sw600dp/window_background.xml",
   "java/res/drawable-v21/button_borderless_compat.xml",
@@ -231,7 +224,6 @@
   "java/res/drawable-xhdpi/data_reduction_breakdown_sort_arrow.png",
   "java/res/drawable-xhdpi/diners_card.png",
   "java/res/drawable-xhdpi/down_arrow.png",
-  "java/res/drawable-xhdpi/google_logo.png",
   "java/res/drawable-xhdpi/help_outline.png",
   "java/res/drawable-xhdpi/ic_devices_16dp.png",
   "java/res/drawable-xhdpi/ic_devices_48dp.png",
@@ -310,7 +302,6 @@
   "java/res/drawable-xxhdpi/data_reduction_breakdown_sort_arrow.png",
   "java/res/drawable-xxhdpi/diners_card.png",
   "java/res/drawable-xxhdpi/down_arrow.png",
-  "java/res/drawable-xxhdpi/google_logo.png",
   "java/res/drawable-xxhdpi/help_outline.png",
   "java/res/drawable-xxhdpi/ic_devices_16dp.png",
   "java/res/drawable-xxhdpi/ic_devices_48dp.png",
@@ -389,7 +380,6 @@
   "java/res/drawable-xxxhdpi/data_reduction_breakdown_sort_arrow.png",
   "java/res/drawable-xxxhdpi/diners_card.png",
   "java/res/drawable-xxxhdpi/down_arrow.png",
-  "java/res/drawable-xxxhdpi/google_logo.png",
   "java/res/drawable-xxxhdpi/help_outline.png",
   "java/res/drawable-xxxhdpi/ic_devices_16dp.png",
   "java/res/drawable-xxxhdpi/ic_devices_48dp.png",
@@ -475,7 +465,6 @@
   "java/res/drawable/explore_sites_dense_tile_background.xml",
   "java/res/drawable/google_pay_plex.xml",
   "java/res/drawable/google_pay_with_divider.xml",
-  "java/res/drawable/gpp_maybe_grey.xml",
   "java/res/drawable/ic_add_box_rounded_corner.xml",
   "java/res/drawable/ic_add_to_home_screen.xml",
   "java/res/drawable/ic_arrow_forward_blue_24dp.xml",
@@ -541,6 +530,7 @@
   "java/res/drawable/sharing_more.xml",
   "java/res/drawable/sharing_print.xml",
   "java/res/drawable/sharing_print_baseline.xml",
+  "java/res/drawable/shield.xml",
   "java/res/drawable/signin_header_animation.xml",
   "java/res/drawable/store_locally_tooltip_background.xml",
   "java/res/drawable/tab_indicator.xml",
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni
index 9b3d688..5e53c76 100644
--- a/chrome/android/chrome_java_sources.gni
+++ b/chrome/android/chrome_java_sources.gni
@@ -806,9 +806,6 @@
   "java/src/org/chromium/chrome/browser/ntp/IncognitoNewTabPage.java",
   "java/src/org/chromium/chrome/browser/ntp/IncognitoNewTabPageView.java",
   "java/src/org/chromium/chrome/browser/ntp/LegacyIncognitoDescriptionView.java",
-  "java/src/org/chromium/chrome/browser/ntp/LogoBridge.java",
-  "java/src/org/chromium/chrome/browser/ntp/LogoDelegateImpl.java",
-  "java/src/org/chromium/chrome/browser/ntp/LogoView.java",
   "java/src/org/chromium/chrome/browser/ntp/NativePageRootFrameLayout.java",
   "java/src/org/chromium/chrome/browser/ntp/NewTabPage.java",
   "java/src/org/chromium/chrome/browser/ntp/NewTabPageLaunchOrigin.java",
diff --git a/chrome/android/chrome_test_java_sources.gni b/chrome/android/chrome_test_java_sources.gni
index 1eeec99..e157b9d 100644
--- a/chrome/android/chrome_test_java_sources.gni
+++ b/chrome/android/chrome_test_java_sources.gni
@@ -302,7 +302,6 @@
   "javatests/src/org/chromium/chrome/browser/notifications/channels/SiteChannelsManagerTest.java",
   "javatests/src/org/chromium/chrome/browser/ntp/IncognitoDescriptionViewRenderTest.java",
   "javatests/src/org/chromium/chrome/browser/ntp/IncognitoNewTabPageTest.java",
-  "javatests/src/org/chromium/chrome/browser/ntp/LogoViewTest.java",
   "javatests/src/org/chromium/chrome/browser/ntp/NewTabPageLoadTest.java",
   "javatests/src/org/chromium/chrome/browser/ntp/NewTabPageNavigationTest.java",
   "javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java",
diff --git a/chrome/android/java/res/drawable/gpp_maybe_grey.xml b/chrome/android/java/res/drawable/gpp_maybe_grey.xml
deleted file mode 100644
index 85320ae..0000000
--- a/chrome/android/java/res/drawable/gpp_maybe_grey.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--Copyright 2021 The Chromium Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.-->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="24"
-        android:viewportHeight="24">
-    <path android:fillColor="@android:color/darker_gray"
-          android:pathData="M12,2L4,5v6.09c0,5.05,3.41,9.76,8,10.91c4.59-1.15,8-5.86,8-10.91V5L12,2z M13,16h-2v-2h2V16z M13,12h-2V7h2V12z"/>
-</vector>
diff --git a/chrome/android/java/res/drawable/shield.xml b/chrome/android/java/res/drawable/shield.xml
new file mode 100644
index 0000000..f8a79c2
--- /dev/null
+++ b/chrome/android/java/res/drawable/shield.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Copyright 2021 The Chromium Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24">
+<path android:fillColor="@color/baseline_neutral_variant_700"
+          android:pathData="M12.0 22.0Q8.525 21.125 6.2625 18.0125Q4.0 14.9 4.0 11.1V5.0L12.0 2.0L20.0 5.0V11.1Q20.0 14.9 17.7375 18.0125Q15.475 21.125 12.0 22.0ZM12.0 12.0Q12.0 12.0 12.0 12.0Q12.0 12.0 12.0 12.0Q12.0 12.0 12.0 12.0Q12.0 12.0 12.0 12.0Z"/>
+</vector>
diff --git a/chrome/android/java/res/layout/new_tab_page_layout.xml b/chrome/android/java/res/layout/new_tab_page_layout.xml
index 7a66aaf..d5d7f39 100644
--- a/chrome/android/java/res/layout/new_tab_page_layout.xml
+++ b/chrome/android/java/res/layout/new_tab_page_layout.xml
@@ -28,7 +28,7 @@
             android:layout_height="@dimen/cryptid_height_in_logo_wrapper"
             android:layout_gravity="bottom|start" />
 
-        <org.chromium.chrome.browser.ntp.LogoView
+        <org.chromium.chrome.browser.logo.LogoView
             android:id="@+id/search_provider_logo"
             android:layout_width="match_parent"
             android:layout_height="@dimen/ntp_logo_height"
diff --git a/chrome/android/java/res/values-night/colors.xml b/chrome/android/java/res/values-night/colors.xml
index d0187ff..ba6f650 100644
--- a/chrome/android/java/res/values-night/colors.xml
+++ b/chrome/android/java/res/values-night/colors.xml
@@ -4,8 +4,6 @@
      found in the LICENSE file. -->
 
 <resources>
-    <color name="google_logo_tint">@android:color/white</color>
-
     <!-- Account Signin Colors -->
     <color name="signin_header_animation_background">@color/header_background_dark</color>
     <color name="signin_header_animation_line_light">@color/modern_grey_700</color>
diff --git a/chrome/android/java/res/values/colors.xml b/chrome/android/java/res/values/colors.xml
index d7a6da06..1e203b4 100644
--- a/chrome/android/java/res/values/colors.xml
+++ b/chrome/android/java/res/values/colors.xml
@@ -42,7 +42,6 @@
 
     <!-- NTP and Home sheet colors. Also used on the bookmarks and recent tabs pages. -->
     <color name="ntp_bg_incognito">@color/default_bg_color_dark</color>
-    <color name="google_logo_tint">@android:color/transparent</color>
 
     <!-- Incognito NTP Colors. -->
     <color name="incognito_emphasis">@android:color/white</color>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
index dd267b9d..28d0107 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -2208,7 +2208,7 @@
                 return true;
             }
         } else if (shouldCloseTab) {
-            currentTab.getWebContents().dispatchBeforeUnload(false);
+            if (webContents != null) webContents.dispatchBeforeUnload(false);
             return true;
         }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageLayout.java
index 1550427..a9d8a7b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageLayout.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageLayout.java
@@ -26,6 +26,7 @@
 import androidx.annotation.StringRes;
 import androidx.annotation.VisibleForTesting;
 
+import org.chromium.base.Callback;
 import org.chromium.base.CallbackController;
 import org.chromium.base.MathUtils;
 import org.chromium.base.TraceEvent;
@@ -40,9 +41,11 @@
 import org.chromium.chrome.browser.lens.LensEntryPoint;
 import org.chromium.chrome.browser.lens.LensMetrics;
 import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher;
+import org.chromium.chrome.browser.logo.LogoBridge.Logo;
+import org.chromium.chrome.browser.logo.LogoBridge.LogoObserver;
+import org.chromium.chrome.browser.logo.LogoDelegateImpl;
+import org.chromium.chrome.browser.logo.LogoView;
 import org.chromium.chrome.browser.native_page.ContextMenuManager;
-import org.chromium.chrome.browser.ntp.LogoBridge.Logo;
-import org.chromium.chrome.browser.ntp.LogoBridge.LogoObserver;
 import org.chromium.chrome.browser.ntp.NewTabPage.OnSearchBoxScrollListener;
 import org.chromium.chrome.browser.ntp.search.SearchBoxCoordinator;
 import org.chromium.chrome.browser.offlinepages.OfflinePageBridge;
@@ -70,6 +73,7 @@
 import org.chromium.components.browser_ui.widget.highlight.ViewHighlighter.HighlightParams;
 import org.chromium.components.browser_ui.widget.highlight.ViewHighlighter.HighlightShape;
 import org.chromium.components.feature_engagement.FeatureConstants;
+import org.chromium.content_public.browser.LoadUrlParams;
 import org.chromium.ui.base.DeviceFormFactor;
 import org.chromium.ui.base.WindowAndroid;
 import org.chromium.ui.vr.VrModeObserver;
@@ -241,8 +245,10 @@
         }
 
         mSearchProviderLogoView = findViewById(R.id.search_provider_logo);
-        mLogoDelegate = new LogoDelegateImpl(
-                mManager.getNavigationDelegate(), mSearchProviderLogoView, profile);
+        Callback<LoadUrlParams> logoClickedCallback = mCallbackController.makeCancelable(
+                (urlParams)
+                        -> mManager.getNativePageHost().loadUrl(urlParams, /*isIncognito=*/false));
+        mLogoDelegate = new LogoDelegateImpl(logoClickedCallback, mSearchProviderLogoView, profile);
 
         mSearchBoxCoordinator = new SearchBoxCoordinator(getContext(), this);
         mSearchBoxCoordinator.initialize(lifecycleDispatcher, mIsIncognito, mWindowAndroid);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsUiDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsUiDelegate.java
index a0bb2f4b..367b479 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsUiDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsUiDelegate.java
@@ -5,6 +5,7 @@
 package org.chromium.chrome.browser.suggestions;
 
 import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager;
+import org.chromium.chrome.browser.ui.native_page.NativePageHost;
 
 /**
  * Interface between the suggestion surface and the rest of the browser.
@@ -17,6 +18,9 @@
     /** Convenience method to access the {@link SuggestionsNavigationDelegate}. */
     SuggestionsNavigationDelegate getNavigationDelegate();
 
+    /** Convenience method to access the {@link NativePageHost}. */
+    NativePageHost getNativePageHost();
+
     /** Convenience method to access the {@link ImageFetcher}. */
     ImageFetcher getImageFetcher();
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsUiDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsUiDelegateImpl.java
index f02e859..13011e6 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsUiDelegateImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsUiDelegateImpl.java
@@ -41,6 +41,11 @@
     }
 
     @Override
+    public NativePageHost getNativePageHost() {
+        return mHost;
+    }
+
+    @Override
     public SnackbarManager getSnackbarManager() {
         return mSnackbarManager;
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/DEPS b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/DEPS
index 8b726652..154cad8 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/DEPS
+++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/DEPS
@@ -36,5 +36,6 @@
   'LogoLoadHelper': [
     "+chrome/android/features/start_surface/public",
     "+chrome/android/java/src/org/chromium/chrome/browser",
+    "+content/public/android/java/src/org/chromium/content_public/browser/LoadUrlParams.java",
   ],
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/LogoLoadHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/LogoLoadHelper.java
index 94afcc2..160b316 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/LogoLoadHelper.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/LogoLoadHelper.java
@@ -9,18 +9,22 @@
 
 import androidx.annotation.VisibleForTesting;
 
+import org.chromium.base.Callback;
 import org.chromium.base.CallbackController;
 import org.chromium.base.supplier.ObservableSupplier;
 import org.chromium.base.supplier.OneShotCallback;
-import org.chromium.chrome.browser.ntp.LogoBridge.Logo;
-import org.chromium.chrome.browser.ntp.LogoBridge.LogoObserver;
-import org.chromium.chrome.browser.ntp.LogoDelegateImpl;
-import org.chromium.chrome.browser.ntp.LogoView;
+import org.chromium.base.supplier.Supplier;
+import org.chromium.chrome.browser.logo.LogoBridge.Logo;
+import org.chromium.chrome.browser.logo.LogoBridge.LogoObserver;
+import org.chromium.chrome.browser.logo.LogoDelegateImpl;
+import org.chromium.chrome.browser.logo.LogoView;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.search_engines.TemplateUrlServiceFactory;
+import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tasks.ReturnToChromeExperimentsUtil;
 import org.chromium.chrome.browser.toolbar.top.TopToolbarCoordinator;
 import org.chromium.chrome.features.start_surface.StartSurfaceState;
+import org.chromium.content_public.browser.LoadUrlParams;
 
 /**
  * Helper used to fetch and load logo image for Start surface.
@@ -29,6 +33,8 @@
     private final ObservableSupplier<Profile> mProfileSupplier;
     private final TopToolbarCoordinator mToolbar;
     private final Context mContext;
+    private final Supplier<Tab> mParentTabSupplier;
+    private final Callback<LoadUrlParams> mLogoClickedCallback;
 
     private CallbackController mCallbackController = new CallbackController();
     private LogoDelegateImpl mLogoDelegate;
@@ -37,15 +43,21 @@
     /**
      * Creates a LogoLoadHelper object.
      *
-     * @param profileSupplier Supplier of the currently applicable profile.
      * @param toolbar The {@link TopToolbarCoordinator}.
      * @param context The activity context.
+     * @param parentTabSupplier Supplies the StartSurface's parent tab.
      */
     public LogoLoadHelper(ObservableSupplier<Profile> profileSupplier,
-            TopToolbarCoordinator toolbar, Context context) {
+            TopToolbarCoordinator toolbar, Context context, Supplier<Tab> parentTabSupplier) {
         mProfileSupplier = profileSupplier;
         mToolbar = toolbar;
         mContext = context;
+        mParentTabSupplier = parentTabSupplier;
+        mLogoClickedCallback = mCallbackController.makeCancelable(
+                (urlParams)
+                        -> ReturnToChromeExperimentsUtil.handleLoadUrlFromStartSurface(urlParams,
+                                /*isBackground=*/false,
+                                /*incognito=*/false, mParentTabSupplier.get()));
     }
 
     /**
@@ -111,7 +123,7 @@
 
         if (mLogoDelegate == null) {
             mLogoDelegate = new LogoDelegateImpl(
-                    /* navigationDelegate = */ null, /* logoView = */ null, mProfileSupplier.get());
+                    mLogoClickedCallback, /* logoView = */ null, mProfileSupplier.get());
         }
 
         // If default search engine doesn't have logo, pass in null.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
index 706c01b..13d195a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
@@ -939,7 +939,8 @@
                 mToolbar.updateStartSurfaceToolbarState(newState, shouldShowToolbar, toolbarHeight);
 
                 if (mLogoLoadHelper == null) {
-                    mLogoLoadHelper = new LogoLoadHelper(profileSupplier, mToolbar, mActivity);
+                    mLogoLoadHelper = new LogoLoadHelper(
+                            profileSupplier, mToolbar, mActivity, startSurfaceParentTabSupplier);
                 }
                 mLogoLoadHelper.maybeLoadSearchProviderLogoOnHomepage(mStartSurfaceState);
             };
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/toolbar/LogoLoadHelperUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/toolbar/LogoLoadHelperUnitTest.java
index d1ae488..0dd16d2 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/toolbar/LogoLoadHelperUnitTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/toolbar/LogoLoadHelperUnitTest.java
@@ -31,10 +31,10 @@
 import org.chromium.chrome.browser.flags.CachedFeatureFlags;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.homepage.HomepageManager;
-import org.chromium.chrome.browser.ntp.LogoBridge;
-import org.chromium.chrome.browser.ntp.LogoBridgeJni;
-import org.chromium.chrome.browser.ntp.LogoDelegateImpl;
-import org.chromium.chrome.browser.ntp.LogoView;
+import org.chromium.chrome.browser.logo.LogoBridge;
+import org.chromium.chrome.browser.logo.LogoBridgeJni;
+import org.chromium.chrome.browser.logo.LogoDelegateImpl;
+import org.chromium.chrome.browser.logo.LogoView;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.search_engines.TemplateUrlServiceFactory;
 import org.chromium.chrome.browser.search_engines.TemplateUrlServiceFactoryJni;
@@ -83,7 +83,7 @@
 
         mProfileSupplier = new ObservableSupplierImpl<>();
         mContext = ApplicationProvider.getApplicationContext();
-        mLogoLoadHelper = new LogoLoadHelper(mProfileSupplier, mToolbar, mContext);
+        mLogoLoadHelper = new LogoLoadHelper(mProfileSupplier, mToolbar, mContext, null);
         mLogoLoadHelper.setLogoDelegateForTesting(mLogoDelegate);
 
         doReturn(false).when(mMockProfile1).isOffTheRecord();
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt
index df16a82..aed84aa 100644
--- a/chrome/android/profiles/newest.txt
+++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-99.0.4835.0_rc-r1-merged.afdo.bz2
+chromeos-chrome-amd64-99.0.4837.0_rc-r1-merged.afdo.bz2
diff --git a/chrome/app/chrome_main.cc b/chrome/app/chrome_main.cc
index 33ba038..545f714b 100644
--- a/chrome/app/chrome_main.cc
+++ b/chrome/app/chrome_main.cc
@@ -7,7 +7,6 @@
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/command_line.h"
-#include "base/compiler_specific.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
 #include "chrome/app/chrome_main_delegate.h"
@@ -121,8 +120,8 @@
   base::CommandLine::Init(params.argc, params.argv);
 #endif  // BUILDFLAG(IS_WIN)
   base::CommandLine::Init(0, nullptr);
-  base::CommandLine* command_line(base::CommandLine::ForCurrentProcess());
-  ALLOW_UNUSED_LOCAL(command_line);
+  [[maybe_unused]] base::CommandLine* command_line(
+      base::CommandLine::ForCurrentProcess());
 
 #if BUILDFLAG(IS_WIN)
   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
diff --git a/chrome/app/chrome_main_delegate.cc b/chrome/app/chrome_main_delegate.cc
index 0a25150..3b1e41a 100644
--- a/chrome/app/chrome_main_delegate.cc
+++ b/chrome/app/chrome_main_delegate.cc
@@ -666,8 +666,9 @@
 #endif
 
   version_info::Channel channel = chrome::GetChannel();
-  bool is_canary_dev = (channel == version_info::Channel::CANARY ||
-                        channel == version_info::Channel::DEV);
+  [[maybe_unused]] bool is_canary_dev =
+      (channel == version_info::Channel::CANARY ||
+       channel == version_info::Channel::DEV);
   // GWP-ASAN requires crashpad to gather alloc/dealloc stack traces, which is
   // not always enabled on Linux/ChromeOS.
 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
@@ -687,8 +688,6 @@
 #endif
   }
 
-  ALLOW_UNUSED_LOCAL(is_canary_dev);
-
   // Start heap profiling as early as possible so it can start recording
   // memory allocations.
   if (is_browser_process) {
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 3f5331e2..767ec2c 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -2839,8 +2839,6 @@
       "android/locale/locale_manager.h",
       "android/locale/locale_template_url_loader.cc",
       "android/locale/locale_template_url_loader.h",
-      "android/logo_bridge.cc",
-      "android/logo_bridge.h",
       "android/media/media_capture_devices_dispatcher_android.cc",
       "android/messages_resource_mapper_initializer.cc",
       "android/metrics/android_session_durations_service.cc",
@@ -3865,8 +3863,6 @@
       "first_run/first_run.h",
       "first_run/first_run_dialog.h",
       "first_run/first_run_internal.h",
-      "font_access/chrome_font_access_delegate.cc",
-      "font_access/chrome_font_access_delegate.h",
       "font_family_cache.cc",
       "font_family_cache.h",
       "hid/chrome_hid_delegate.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index a7c8128..496a2080 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -5880,10 +5880,6 @@
      flag_descriptions::kFontAccessAPIDescription, kOsAll,
      FEATURE_VALUE_TYPE(blink::features::kFontAccess)},
 
-    {"font-access-persistent", flag_descriptions::kFontAccessPersistentName,
-     flag_descriptions::kFontAccessPersistentDescription, kOsAll,
-     FEATURE_VALUE_TYPE(blink::features::kFontAccessPersistent)},
-
     {"mouse-subframe-no-implicit-capture",
      flag_descriptions::kMouseSubframeNoImplicitCaptureName,
      flag_descriptions::kMouseSubframeNoImplicitCaptureDescription, kOsAll,
@@ -7199,6 +7195,12 @@
      flag_descriptions::kUpdateHistoryEntryPointsInIncognitoDescription, kOsAll,
      FEATURE_VALUE_TYPE(features::kUpdateHistoryEntryPointsInIncognito)},
 
+    {"throttle-foreground-timers",
+     flag_descriptions::kThrottleForegroundTimersName,
+     flag_descriptions::kThrottleForegroundTimersDescription,
+     kOsDesktop | kOsAndroid,
+     FEATURE_VALUE_TYPE(blink::features::kThrottleForegroundTimers)},
+
     {"enable-throttle-display-none-and-visibility-hidden-cross-origin-iframes",
      flag_descriptions::
          kThrottleDisplayNoneAndVisibilityHiddenCrossOriginIframesName,
diff --git a/chrome/browser/accessibility/accessibility_extension_api_chromeos.cc b/chrome/browser/accessibility/accessibility_extension_api_chromeos.cc
index 4d9edd2..1c15c8d 100644
--- a/chrome/browser/accessibility/accessibility_extension_api_chromeos.cc
+++ b/chrome/browser/accessibility/accessibility_extension_api_chromeos.cc
@@ -774,11 +774,40 @@
   std::unique_ptr<accessibility_private::UpdateDictationBubble::Params> params(
       accessibility_private::UpdateDictationBubble::Params::Create(args()));
   EXTENSION_FUNCTION_VALIDATE(params);
+  accessibility_private::DictationBubbleProperties& properties =
+      params->properties;
 
+  // Extract the icon type.
+  ash::DictationBubbleIconType icon = ash::DictationBubbleIconType::kHidden;
+  switch (properties.icon) {
+    case accessibility_private::DictationBubbleIconType::
+        DICTATION_BUBBLE_ICON_TYPE_HIDDEN:
+      icon = ash::DictationBubbleIconType::kHidden;
+      break;
+    case accessibility_private::DictationBubbleIconType::
+        DICTATION_BUBBLE_ICON_TYPE_STANDBY:
+      icon = ash::DictationBubbleIconType::kStandby;
+      break;
+    case accessibility_private::DictationBubbleIconType::
+        DICTATION_BUBBLE_ICON_TYPE_MACROSUCCESS:
+      icon = ash::DictationBubbleIconType::kMacroSuccess;
+      break;
+    case accessibility_private::DictationBubbleIconType::
+        DICTATION_BUBBLE_ICON_TYPE_MACROFAIL:
+      icon = ash::DictationBubbleIconType::kMacroFail;
+      break;
+    case accessibility_private::DictationBubbleIconType::
+        DICTATION_BUBBLE_ICON_TYPE_NONE:
+      NOTREACHED();
+      break;
+  }
+
+  // Extract text.
   absl::optional<std::u16string> text;
-  if (params->text)
-    text = base::UTF8ToUTF16(*params->text);
-  ash::AccessibilityController::Get()->UpdateDictationBubble(params->visible,
-                                                             text);
+  if (properties.text)
+    text = base::UTF8ToUTF16(*properties.text);
+
+  ash::AccessibilityController::Get()->UpdateDictationBubble(properties.visible,
+                                                             icon, text);
   return RespondNow(NoArguments());
 }
diff --git a/chrome/browser/android/resource_id.h b/chrome/browser/android/resource_id.h
index 4c1ead3..3bc8635 100644
--- a/chrome/browser/android/resource_id.h
+++ b/chrome/browser/android/resource_id.h
@@ -55,8 +55,7 @@
                     R.drawable.ic_photo_camera_black)
 DECLARE_RESOURCE_ID(IDR_ANDROID_MESSAGE_SETTINGS, R.drawable.settings_cog)
 DECLARE_RESOURCE_ID(IDR_ANDROID_MESSAGE_SAFETY_CHECK, R.drawable.safety_check)
-DECLARE_RESOURCE_ID(IDR_ANDROID_MESSAGE_GPP_MAYBE_GREY,
-                    R.drawable.gpp_maybe_grey)
+DECLARE_RESOURCE_ID(IDR_ANDROID_MESSAGE_SHIELD, R.drawable.shield)
 
 // Autofill popup and keyboard accessory images.
 // We use Android's |VectorDrawableCompat| for the following images that are
diff --git a/chrome/browser/apps/app_service/browser_app_launcher.cc b/chrome/browser/apps/app_service/browser_app_launcher.cc
index 39b8633..6a324ba 100644
--- a/chrome/browser/apps/app_service/browser_app_launcher.cc
+++ b/chrome/browser/apps/app_service/browser_app_launcher.cc
@@ -10,8 +10,10 @@
 #include "base/feature_list.h"
 #include "base/files/file_path.h"
 #include "build/chromeos_buildflags.h"
+#include "chrome/browser/extensions/extension_util.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/extensions/app_launch_params.h"
 #include "chrome/browser/ui/extensions/application_launch.h"
 #include "extensions/browser/extension_registry.h"
 #include "extensions/common/extension.h"
@@ -20,6 +22,7 @@
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/apps/app_service/launch_utils.h"
 #include "chrome/browser/apps/app_service/metrics/app_platform_metrics.h"
+#include "chrome/browser/ui/app_list/arc/arc_app_utils.h"
 #include "components/app_restore/app_launch_info.h"
 #include "components/app_restore/full_restore_save_handler.h"
 #include "components/app_restore/full_restore_utils.h"
@@ -27,24 +30,20 @@
 #include "components/sessions/core/session_id.h"
 #endif
 
-namespace apps {
-
-BrowserAppLauncher::BrowserAppLauncher(Profile* profile)
-    : profile_(profile), web_app_launch_manager_(profile) {}
-
-BrowserAppLauncher::~BrowserAppLauncher() = default;
-
-content::WebContents* BrowserAppLauncher::LaunchAppWithParams(
-    AppLaunchParams&& params) {
+namespace {
+content::WebContents* LaunchAppWithParamsImpl(
+    apps::AppLaunchParams&& params,
+    Profile* profile,
+    web_app::WebAppLaunchManager* web_app_launch_manager) {
   const extensions::Extension* extension =
-      extensions::ExtensionRegistry::Get(profile_)->GetInstalledExtension(
+      extensions::ExtensionRegistry::Get(profile)->GetInstalledExtension(
           params.app_id);
   if (!extension) {
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-    AppLaunchParams params_for_restore(params.app_id, params.container,
-                                       params.disposition, params.launch_source,
-                                       params.display_id, params.launch_files,
-                                       params.intent);
+    apps::AppLaunchParams params_for_restore(
+        params.app_id, params.container, params.disposition,
+        params.launch_source, params.display_id, params.launch_files,
+        params.intent);
     std::string app_id = params.app_id;
     apps::mojom::LaunchSource launch_source = params.launch_source;
     apps::mojom::LaunchContainer container = params.container;
@@ -55,19 +54,19 @@
     full_restore::FullRestoreSaveHandler::GetInstance();
 
     auto* web_contents =
-        web_app_launch_manager_.OpenApplication(std::move(params));
+        web_app_launch_manager->OpenApplication(std::move(params));
 
     if (!SessionID::IsValidValue(restore_id)) {
-      RecordAppLaunchMetrics(profile_, apps::AppType::kWeb, app_id,
+      RecordAppLaunchMetrics(profile, apps::AppType::kWeb, app_id,
                              launch_source, container);
       return web_contents;
     }
 
-    RecordAppLaunchMetrics(profile_, apps::AppType::kWeb, app_id,
+    RecordAppLaunchMetrics(profile, apps::AppType::kWeb, app_id,
                            apps::mojom::LaunchSource::kFromFullRestore,
                            container);
 
-    int session_id = GetSessionIdForRestoreFromWebContents(web_contents);
+    int session_id = apps::GetSessionIdForRestoreFromWebContents(web_contents);
     if (!SessionID::IsValidValue(session_id)) {
       return web_contents;
     }
@@ -79,12 +78,11 @@
         params_for_restore.disposition, params_for_restore.display_id,
         std::move(params_for_restore.launch_files),
         std::move(params_for_restore.intent));
-    full_restore::SaveAppLaunchInfo(profile_->GetPath(),
-                                    std::move(launch_info));
+    full_restore::SaveAppLaunchInfo(profile->GetPath(), std::move(launch_info));
 
     return web_contents;
 #else
-    return web_app_launch_manager_.OpenApplication(std::move(params));
+    return web_app_launch_manager->OpenApplication(std::move(params));
 #endif
   }
 
@@ -92,30 +90,60 @@
   // If the restore id is available, save the launch parameters to the full
   // restore file.
   if (SessionID::IsValidValue(params.restore_id)) {
-    RecordAppLaunchMetrics(profile_, apps::AppType::kChromeApp, params.app_id,
+    RecordAppLaunchMetrics(profile, apps::AppType::kChromeApp, params.app_id,
                            apps::mojom::LaunchSource::kFromFullRestore,
                            params.container);
 
-    AppLaunchParams params_for_restore(params.app_id, params.container,
-                                       params.disposition, params.launch_source,
-                                       params.display_id, params.launch_files,
-                                       params.intent);
+    apps::AppLaunchParams params_for_restore(
+        params.app_id, params.container, params.disposition,
+        params.launch_source, params.display_id, params.launch_files,
+        params.intent);
 
     auto launch_info = std::make_unique<app_restore::AppLaunchInfo>(
         params_for_restore.app_id, params_for_restore.container,
         params_for_restore.disposition, params_for_restore.display_id,
         std::move(params_for_restore.launch_files),
         std::move(params_for_restore.intent));
-    full_restore::SaveAppLaunchInfo(profile_->GetPath(),
-                                    std::move(launch_info));
+    full_restore::SaveAppLaunchInfo(profile->GetPath(), std::move(launch_info));
   } else {
-    RecordAppLaunchMetrics(profile_, apps::AppType::kChromeApp, params.app_id,
+    RecordAppLaunchMetrics(profile, apps::AppType::kChromeApp, params.app_id,
                            params.launch_source, params.container);
   }
 #endif
 
-  return ::OpenApplication(profile_, std::move(params));
+  return ::OpenApplication(profile, std::move(params));
 }
+}  // namespace
+
+namespace apps {
+
+BrowserAppLauncher::BrowserAppLauncher(Profile* profile)
+    : profile_(profile), web_app_launch_manager_(profile) {}
+
+BrowserAppLauncher::~BrowserAppLauncher() = default;
+
+// TODO(crbug.com/1244506): Make this interface only work for non-ChromeOS
+// platform after the clean up.
+content::WebContents* BrowserAppLauncher::LaunchAppWithParams(
+    AppLaunchParams&& params) {
+  return LaunchAppWithParamsImpl(std::move(params), profile_,
+                                 &web_app_launch_manager_);
+}
+
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+void BrowserAppLauncher::LaunchPlayStoreWithExtensions() {
+  const extensions::Extension* extension =
+      extensions::ExtensionRegistry::Get(profile_)->GetInstalledExtension(
+          arc::kPlayStoreAppId);
+  DCHECK(extension);
+  DCHECK(extensions::util::IsAppLaunchable(arc::kPlayStoreAppId, profile_));
+  LaunchAppWithParamsImpl(
+      CreateAppLaunchParamsUserContainer(
+          profile_, extension, WindowOpenDisposition::NEW_WINDOW,
+          apps::mojom::LaunchSource::kFromChromeInternal),
+      profile_, &web_app_launch_manager_);
+}
+#endif
 
 void BrowserAppLauncher::LaunchAppWithCallback(
     const std::string& app_id,
diff --git a/chrome/browser/apps/app_service/browser_app_launcher.h b/chrome/browser/apps/app_service/browser_app_launcher.h
index cb6ca3c9..8a88b43 100644
--- a/chrome/browser/apps/app_service/browser_app_launcher.h
+++ b/chrome/browser/apps/app_service/browser_app_launcher.h
@@ -51,6 +51,16 @@
   // Launches an app for the given `app_id` in a way specified by `params`.
   content::WebContents* LaunchAppWithParams(AppLaunchParams&& params);
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+  // Launches Play Store with Extensions. ARC and Extensions share the same app
+  // id for Play Store, and App Service only registered the play store ARC app
+  // (see blocklist in
+  // chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc
+  // for more details). Therefore we need this interface to launch Play Store
+  // with Extensions when ARC is not enabled.
+  void LaunchPlayStoreWithExtensions();
+#endif
+
   // Attempts to open `app_id` in a new window or tab. Open an empty browser
   // window if unsuccessful. The user's preferred launch container for the app
   // (standalone window or browser tab) is used. `callback` will be called with
diff --git a/chrome/browser/ash/accessibility/accessibility_extension_api_browsertest.cc b/chrome/browser/ash/accessibility/accessibility_extension_api_browsertest.cc
index fc55b46..1aef21e 100644
--- a/chrome/browser/ash/accessibility/accessibility_extension_api_browsertest.cc
+++ b/chrome/browser/ash/accessibility/accessibility_extension_api_browsertest.cc
@@ -67,6 +67,50 @@
     return controller->dictation_bubble_view_->GetTextForTesting();
   }
 
+  bool IsDictationBubbleStandbyImageVisible() {
+    DictationBubbleController* controller =
+        Shell::Get()
+            ->accessibility_controller()
+            ->GetDictationBubbleControllerForTest();
+    DCHECK(controller != nullptr);
+    return controller->dictation_bubble_view_
+        ->IsStandbyImageVisibleForTesting();
+  }
+
+  bool IsDictationBubbleMacroSucceededImageVisible() {
+    DictationBubbleController* controller =
+        Shell::Get()
+            ->accessibility_controller()
+            ->GetDictationBubbleControllerForTest();
+    DCHECK(controller != nullptr);
+    return controller->dictation_bubble_view_
+        ->IsMacroSucceededImageVisibleForTesting();
+  }
+
+  bool IsDictationBubbleMacroFailedImageVisible() {
+    DictationBubbleController* controller =
+        Shell::Get()
+            ->accessibility_controller()
+            ->GetDictationBubbleControllerForTest();
+    DCHECK(controller != nullptr);
+    return controller->dictation_bubble_view_
+        ->IsMacroFailedImageVisibleForTesting();
+  }
+
+  DictationBubbleIconType GetDictationBubbleVisibleIcon() {
+    DCHECK_GE(1, IsDictationBubbleStandbyImageVisible() +
+                     IsDictationBubbleMacroSucceededImageVisible() +
+                     IsDictationBubbleMacroFailedImageVisible())
+        << "No more than one icon should be visible!";
+    if (IsDictationBubbleStandbyImageVisible())
+      return DictationBubbleIconType::kStandby;
+    if (IsDictationBubbleMacroSucceededImageVisible())
+      return DictationBubbleIconType::kMacroSuccess;
+    if (IsDictationBubbleMacroFailedImageVisible())
+      return DictationBubbleIconType::kMacroFail;
+    return DictationBubbleIconType::kHidden;
+  }
+
  private:
   base::test::ScopedFeatureList scoped_feature_list_;
 };
@@ -226,27 +270,47 @@
 
   // This test requires some back and forth communication between C++ and JS.
   // Use message listeners to force the synchronicity of this test.
-  ExtensionTestMessageListener show_listener("Show", /*will_reply=*/true);
-  ExtensionTestMessageListener update_listener("Update", /*will_reply=*/true);
+  ExtensionTestMessageListener standby_listener("Standby", /*will_reply=*/true);
+  ExtensionTestMessageListener show_text_listener("Show text",
+                                                  /*will_reply=*/true);
+  ExtensionTestMessageListener macro_success_listener("Show macro success",
+                                                      /*will_reply=*/true);
+  ExtensionTestMessageListener reset_listener("Reset", /*will_reply=*/true);
   ExtensionTestMessageListener hide_listener("Hide", /*will_reply=*/false);
 
   extensions::ResultCatcher result_catcher;
   ASSERT_TRUE(RunSubtest("testUpdateDictationBubble")) << message_;
 
-  ASSERT_TRUE(show_listener.WaitUntilSatisfied());
+  ASSERT_TRUE(standby_listener.WaitUntilSatisfied());
+  EXPECT_TRUE(IsDictationBubbleVisible());
+  EXPECT_EQ(std::u16string(), GetDictationBubbleText());
+  EXPECT_EQ(DictationBubbleIconType::kStandby, GetDictationBubbleVisibleIcon());
+  standby_listener.Reply("Continue");
+
+  ASSERT_TRUE(show_text_listener.WaitUntilSatisfied());
   EXPECT_TRUE(IsDictationBubbleVisible());
   EXPECT_EQ(u"Hello", GetDictationBubbleText());
-  show_listener.Reply("Continue");
+  EXPECT_EQ(DictationBubbleIconType::kHidden, GetDictationBubbleVisibleIcon());
+  show_text_listener.Reply("Continue");
 
-  ASSERT_TRUE(update_listener.WaitUntilSatisfied());
+  ASSERT_TRUE(macro_success_listener.WaitUntilSatisfied());
   EXPECT_TRUE(IsDictationBubbleVisible());
-  EXPECT_EQ(u"Hello world", GetDictationBubbleText());
-  update_listener.Reply("Continue");
+  EXPECT_EQ(u"Hello", GetDictationBubbleText());
+  EXPECT_EQ(DictationBubbleIconType::kMacroSuccess,
+            GetDictationBubbleVisibleIcon());
+  macro_success_listener.Reply("Continue");
+
+  ASSERT_TRUE(reset_listener.WaitUntilSatisfied());
+  EXPECT_TRUE(IsDictationBubbleVisible());
+  EXPECT_EQ(std::u16string(), GetDictationBubbleText());
+  EXPECT_EQ(DictationBubbleIconType::kStandby, GetDictationBubbleVisibleIcon());
+  reset_listener.Reply("Continue");
 
   ASSERT_TRUE(hide_listener.WaitUntilSatisfied());
   EXPECT_FALSE(IsDictationBubbleVisible());
-  // Text remains unchanged.
-  EXPECT_EQ(u"Hello world", GetDictationBubbleText());
+  EXPECT_EQ(std::u16string(), GetDictationBubbleText());
+  EXPECT_EQ(DictationBubbleIconType::kHidden, GetDictationBubbleVisibleIcon());
+
   ASSERT_TRUE(result_catcher.GetNextResult()) << result_catcher.message();
 }
 
diff --git a/chrome/browser/ash/arc/arc_support_host.cc b/chrome/browser/ash/arc/arc_support_host.cc
index 42742b0..ef2899b3 100644
--- a/chrome/browser/ash/arc/arc_support_host.cc
+++ b/chrome/browser/ash/arc/arc_support_host.cc
@@ -22,13 +22,11 @@
 #include "chrome/browser/ash/profiles/profile_helper.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/consent_auditor/consent_auditor_factory.h"
-#include "chrome/browser/extensions/extension_util.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/ui/app_list/arc/arc_app_utils.h"
 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
 #include "chrome/browser/ui/chrome_pages.h"
-#include "chrome/browser/ui/extensions/app_launch_params.h"
 #include "chrome/browser/ui/webui/chromeos/diagnostics_dialog.h"
 #include "chrome/common/webui_url_constants.h"
 #include "chrome/grit/generated_resources.h"
@@ -134,16 +132,9 @@
     "onOpenPrivacySettingsPageClicked";
 
 void RequestOpenApp(Profile* profile) {
-  const extensions::Extension* extension =
-      extensions::ExtensionRegistry::Get(profile)->GetInstalledExtension(
-          arc::kPlayStoreAppId);
-  DCHECK(extension);
-  DCHECK(extensions::util::IsAppLaunchable(arc::kPlayStoreAppId, profile));
   apps::AppServiceProxyFactory::GetForProfile(profile)
       ->BrowserAppLauncher()
-      ->LaunchAppWithParams(CreateAppLaunchParamsUserContainer(
-          profile, extension, WindowOpenDisposition::NEW_WINDOW,
-          apps::mojom::LaunchSource::kFromChromeInternal));
+      ->LaunchPlayStoreWithExtensions();
 }
 
 std::ostream& operator<<(std::ostream& os, ArcSupportHost::UIPage ui_page) {
diff --git a/chrome/browser/ash/arc/session/arc_session_manager_browsertest.cc b/chrome/browser/ash/arc/session/arc_session_manager_browsertest.cc
index 8c23785b..fda5ab6a 100644
--- a/chrome/browser/ash/arc/session/arc_session_manager_browsertest.cc
+++ b/chrome/browser/ash/arc/session/arc_session_manager_browsertest.cc
@@ -28,7 +28,7 @@
 #include "chrome/browser/ash/arc/test/test_arc_session_manager.h"
 #include "chrome/browser/ash/certificate_provider/certificate_provider_service.h"
 #include "chrome/browser/ash/certificate_provider/certificate_provider_service_factory.h"
-#include "chrome/browser/ash/login/test/local_policy_test_server_mixin.h"
+#include "chrome/browser/ash/login/test/embedded_policy_test_server_mixin.h"
 #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
 #include "chrome/browser/ash/profiles/profile_helper.h"
 #include "chrome/browser/browser_process.h"
@@ -45,6 +45,7 @@
 #include "components/policy/core/common/cloud/mock_cloud_policy_client.h"
 #include "components/policy/core/common/cloud/user_cloud_policy_manager.h"
 #include "components/policy/core/common/policy_switches.h"
+#include "components/policy/test_support/request_handler_for_check_android_management.h"
 #include "components/prefs/pref_member.h"
 #include "components/prefs/pref_service.h"
 #include "components/signin/public/base/consent_level.h"
@@ -60,10 +61,6 @@
 
 namespace {
 
-// Set managed auth token for Android managed accounts.
-constexpr char kManagedAuthToken[] = "managed-auth-token";
-// Set unmanaged auth token for other Android unmanaged accounts.
-constexpr char kUnmanagedAuthToken[] = "unmanaged-auth-token";
 constexpr char kWellKnownConsumerName[] = "test@gmail.com";
 constexpr char kFakeUserName[] = "test@example.com";
 constexpr char kFakeGaiaId[] = "1234567890";
@@ -230,7 +227,7 @@
   }
 
  private:
-  ash::LocalPolicyTestServerMixin local_policy_mixin_{&mixin_host_};
+  ash::EmbeddedPolicyTestServerMixin policy_test_server_mixin_{&mixin_host_};
   std::unique_ptr<user_manager::ScopedUserManager> user_manager_enabler_;
   std::unique_ptr<IdentityTestEnvironmentProfileAdaptor>
       identity_test_environment_adaptor_;
@@ -242,7 +239,7 @@
   EnableArc();
   identity_test_env()->WaitForAccessTokenRequestIfNecessaryAndRespondWithToken(
       identity_manager()->GetPrimaryAccountId(signin::ConsentLevel::kSignin),
-      kUnmanagedAuthToken, base::Time::Max());
+      policy::kUnmanagedAuthToken, base::Time::Max());
   ASSERT_EQ(ArcSessionManager::State::ACTIVE,
             ArcSessionManager::Get()->state());
 }
@@ -268,7 +265,7 @@
   EnableArc();
   identity_test_env()->WaitForAccessTokenRequestIfNecessaryAndRespondWithToken(
       identity_manager()->GetPrimaryAccountId(signin::ConsentLevel::kSignin),
-      kManagedAuthToken, base::Time::Max());
+      policy::kManagedAuthToken, base::Time::Max());
   ArcPlayStoreDisabledWaiter().Wait();
   EXPECT_FALSE(IsArcPlayStoreEnabledForProfile(profile()));
 }
diff --git a/chrome/browser/ash/arc/video/gpu_arc_video_service_host.cc b/chrome/browser/ash/arc/video/gpu_arc_video_service_host.cc
index ada4658..f329431 100644
--- a/chrome/browser/ash/arc/video/gpu_arc_video_service_host.cc
+++ b/chrome/browser/ash/arc/video/gpu_arc_video_service_host.cc
@@ -22,11 +22,14 @@
 #include "base/no_destructor.h"
 #include "base/rand_util.h"
 #include "base/strings/string_number_conversions.h"
+#include "base/task/bind_post_task.h"
 #include "base/threading/thread_checker.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
+#include "content/public/browser/gpu_feature_checker.h"
 #include "content/public/browser/gpu_service_registry.h"
 #include "content/public/browser/service_process_host.h"
+#include "content/public/common/content_switches.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "mojo/public/cpp/bindings/remote_set.h"
@@ -60,20 +63,93 @@
 
 class VideoAcceleratorFactoryService : public mojom::VideoAcceleratorFactory {
  public:
-  VideoAcceleratorFactoryService() = default;
+  VideoAcceleratorFactoryService() {
+    DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  }
 
   VideoAcceleratorFactoryService(const VideoAcceleratorFactoryService&) =
       delete;
   VideoAcceleratorFactoryService& operator=(
       const VideoAcceleratorFactoryService&) = delete;
 
-  ~VideoAcceleratorFactoryService() override = default;
+  ~VideoAcceleratorFactoryService() override {
+    // A VideoAcceleratorFactoryService is owned by a GpuArcVideoServiceHost
+    // which is a singleton that never destroys its
+    // VideoAcceleratorFactoryService. If this behavior ever changes,
+    // VideoAcceleratorFactoryService will need to be adapted because methods
+    // such as CreateDecodeAccelerator() assume that the
+    // VideoAcceleratorFactoryService never dies. Thus the CHECK(false) here:
+    // violating this assumption without appropriate changes would be a security
+    // problem.
+    CHECK(false);
+  }
 
   void CreateDecodeAccelerator(
       mojo::PendingReceiver<mojom::VideoDecodeAccelerator> receiver,
       mojo::PendingRemote<
           mojom::ProtectedBufferManager> /*protected_buffer_manager*/)
       override {
+    DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+    // Don't create a video decode accelerator if this functionality has been
+    // disabled by the command-line switch.
+    CHECK(base::CommandLine::InitializedForCurrentProcess());
+    const base::CommandLine* command_line =
+        base::CommandLine::ForCurrentProcess();
+    if (command_line->HasSwitch(switches::kDisableAcceleratedVideoDecode)) {
+      LOG(WARNING) << "Video decode acceleration has been disabled through the "
+                      "command line";
+      return;
+    }
+
+    // Now check if video decode acceleration has been disabled by the GPU
+    // blocklist. Note: base::Unretained(this) is safe because *|this| should
+    // never die. See the CHECK() in the destructor.
+    const scoped_refptr<base::SingleThreadTaskRunner>& task_runner =
+        base::ThreadTaskRunnerHandle::Get();
+    CHECK(task_runner);
+    auto gpu_feature_checker = content::GpuFeatureChecker::Create(
+        gpu::GpuFeatureType::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE,
+        base::BindPostTask(
+            task_runner,
+            base::BindOnce(&VideoAcceleratorFactoryService::
+                               ContinueCreatingDecodeAccelerator,
+                           base::Unretained(this), std::move(receiver))));
+    CHECK(gpu_feature_checker);
+    gpu_feature_checker->CheckGpuFeatureAvailability();
+  }
+
+  void CreateVideoDecoder(
+      mojo::PendingReceiver<mojom::VideoDecoder> receiver) override {
+    DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+    content::BindInterfaceInGpuProcess(std::move(receiver));
+  }
+
+  void CreateEncodeAccelerator(
+      mojo::PendingReceiver<mojom::VideoEncodeAccelerator> receiver) override {
+    DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+    content::BindInterfaceInGpuProcess(std::move(receiver));
+  }
+
+  void CreateProtectedBufferAllocator(
+      mojo::PendingReceiver<mojom::VideoProtectedBufferAllocator> receiver)
+      override {
+    DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+    content::BindInterfaceInGpuProcess(std::move(receiver));
+  }
+
+ private:
+  void ContinueCreatingDecodeAccelerator(
+      mojo::PendingReceiver<mojom::VideoDecodeAccelerator> receiver,
+      bool accelerated_video_decode_enabled) {
+    DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+    if (!accelerated_video_decode_enabled) {
+      LOG(WARNING) << "Video decode acceleration has been disabled due to the "
+                      "GPU blocklist";
+      return;
+    }
+
     if (base::FeatureList::IsEnabled(arc::kOutOfProcessVideoDecoding)) {
       // TODO(b/195769334): we should check if accelerated video decode is
       // disabled by means of a flag/switch or by GPU bug workarounds.
@@ -106,23 +182,6 @@
     content::BindInterfaceInGpuProcess(std::move(receiver));
   }
 
-  void CreateVideoDecoder(
-      mojo::PendingReceiver<mojom::VideoDecoder> receiver) override {
-    content::BindInterfaceInGpuProcess(std::move(receiver));
-  }
-
-  void CreateEncodeAccelerator(
-      mojo::PendingReceiver<mojom::VideoEncodeAccelerator> receiver) override {
-    content::BindInterfaceInGpuProcess(std::move(receiver));
-  }
-
-  void CreateProtectedBufferAllocator(
-      mojo::PendingReceiver<mojom::VideoProtectedBufferAllocator> receiver)
-      override {
-    content::BindInterfaceInGpuProcess(std::move(receiver));
-  }
-
- private:
   mojo::RemoteSet<mojom::VideoAcceleratorFactory> oop_video_factories_;
 };
 
diff --git a/chrome/browser/ash/child_accounts/child_status_reporting_service.cc b/chrome/browser/ash/child_accounts/child_status_reporting_service.cc
index 83aced2..1f375ea 100644
--- a/chrome/browser/ash/child_accounts/child_status_reporting_service.cc
+++ b/chrome/browser/ash/child_accounts/child_status_reporting_service.cc
@@ -65,8 +65,8 @@
 
 void ChildStatusReportingService::CreateStatusUploaderIfNeeded(
     policy::CloudPolicyClient* client) {
-  const base::DictionaryValue* time_limit = &base::Value::AsDictionaryValue(
-      *pref_change_registrar_->prefs()->GetDictionary(prefs::kUsageTimeLimit));
+  const base::Value* time_limit =
+      pref_change_registrar_->prefs()->GetDictionary(prefs::kUsageTimeLimit);
   const base::TimeDelta new_day_reset_time =
       usage_time_limit::GetTimeUsageLimitResetTime(*time_limit);
 
diff --git a/chrome/browser/ash/child_accounts/child_user_service.cc b/chrome/browser/ash/child_accounts/child_user_service.cc
index 1cf8c6cc..ae3a7189 100644
--- a/chrome/browser/ash/child_accounts/child_user_service.cc
+++ b/chrome/browser/ash/child_accounts/child_user_service.cc
@@ -189,9 +189,8 @@
 }
 
 void ChildUserService ::ReportTimeLimitPolicy() const {
-  const base::DictionaryValue* time_limit_prefs =
-      &base::Value::AsDictionaryValue(
-          *profile_->GetPrefs()->GetDictionary(prefs::kUsageTimeLimit));
+  const base::Value* time_limit_prefs =
+      profile_->GetPrefs()->GetDictionary(prefs::kUsageTimeLimit);
   DCHECK(time_limit_prefs);
 
   std::set<usage_time_limit::PolicyType> enabled_policies =
diff --git a/chrome/browser/ash/child_accounts/screen_time_controller.cc b/chrome/browser/ash/child_accounts/screen_time_controller.cc
index e372e58..728a1595 100644
--- a/chrome/browser/ash/child_accounts/screen_time_controller.cc
+++ b/chrome/browser/ash/child_accounts/screen_time_controller.cc
@@ -76,8 +76,8 @@
       clock_(base::DefaultClock::GetInstance()),
       next_state_timer_(std::make_unique<base::OneShotTimer>()),
       usage_time_limit_warning_timer_(std::make_unique<base::OneShotTimer>()),
-      last_policy_(base::DictionaryValue::From(base::Value::ToUniquePtrValue(
-          pref_service_->GetDictionary(prefs::kUsageTimeLimit)->Clone()))),
+      last_policy_(
+          pref_service_->GetDictionary(prefs::kUsageTimeLimit)->Clone()),
       time_limit_notifier_(context) {
   session_manager::SessionManager::Get()->AddObserver(this);
   UsageTimeStateNotifier::GetInstance()->AddObserver(this);
@@ -147,10 +147,10 @@
   const icu::TimeZone& time_zone =
       system::TimezoneSettings::GetInstance()->GetTimezone();
   absl::optional<usage_time_limit::State> last_state = GetLastStateFromPref();
-  const base::DictionaryValue* time_limit = &base::Value::AsDictionaryValue(
-      *pref_service_->GetDictionary(prefs::kUsageTimeLimit));
-  const base::DictionaryValue* local_override = &base::Value::AsDictionaryValue(
-      *pref_service_->GetDictionary(prefs::kTimeLimitLocalOverride));
+  const base::Value* time_limit =
+      pref_service_->GetDictionary(prefs::kUsageTimeLimit);
+  const base::Value* local_override =
+      pref_service_->GetDictionary(prefs::kTimeLimitLocalOverride);
 
   // TODO(agawronska): Usage timestamp should be passed instead of second |now|.
   usage_time_limit::State state = usage_time_limit::GetState(
@@ -182,9 +182,9 @@
   }
 
   // Trigger policy update notifications.
-  DCHECK(last_policy_);
+  DCHECK(last_policy_.is_dict());
   auto updated_policy_types =
-      usage_time_limit::UpdatedPolicyTypes(*last_policy_, *time_limit);
+      usage_time_limit::UpdatedPolicyTypes(last_policy_, *time_limit);
   for (const auto& policy_type : updated_policy_types) {
     absl::optional<base::Time> lock_time;
     if (policy_type == usage_time_limit::PolicyType::kOverride)
@@ -196,7 +196,7 @@
     time_limit_notifier_.ShowPolicyUpdateNotification(notification_type.value(),
                                                       lock_time);
   }
-  last_policy_ = time_limit->CreateDeepCopy();
+  last_policy_ = time_limit->Clone();
 
   // TODO(agawronska): We are creating UsageTimeLimitProcessor second time in
   // this method. Could expected reset time be returned as a part of the state?
@@ -444,10 +444,10 @@
   base::Time now = clock_->Now();
   const icu::TimeZone& time_zone =
       system::TimezoneSettings::GetInstance()->GetTimezone();
-  const base::DictionaryValue* time_limit = &base::Value::AsDictionaryValue(
-      *pref_service_->GetDictionary(prefs::kUsageTimeLimit));
-  const base::DictionaryValue* local_override = &base::Value::AsDictionaryValue(
-      *pref_service_->GetDictionary(prefs::kTimeLimitLocalOverride));
+  const base::Value* time_limit =
+      pref_service_->GetDictionary(prefs::kUsageTimeLimit);
+  const base::Value* local_override =
+      pref_service_->GetDictionary(prefs::kTimeLimitLocalOverride);
 
   absl::optional<base::TimeDelta> remaining_usage =
       usage_time_limit::GetRemainingTimeUsage(*time_limit, local_override, now,
diff --git a/chrome/browser/ash/child_accounts/screen_time_controller.h b/chrome/browser/ash/child_accounts/screen_time_controller.h
index 5ff9a120..d8284bb 100644
--- a/chrome/browser/ash/child_accounts/screen_time_controller.h
+++ b/chrome/browser/ash/child_accounts/screen_time_controller.h
@@ -12,6 +12,7 @@
 #include "base/observer_list.h"
 #include "base/observer_list_types.h"
 #include "base/time/time.h"
+#include "base/values.h"
 #include "chrome/browser/ash/child_accounts/parent_access_code/parent_access_service.h"
 #include "chrome/browser/ash/child_accounts/time_limit_notifier.h"
 #include "chrome/browser/ash/child_accounts/usage_time_limit_processor.h"
@@ -169,7 +170,7 @@
 
   // Contains the last time limit policy processed by this class. Used to
   // generate notifications when the policy changes.
-  std::unique_ptr<base::DictionaryValue> last_policy_;
+  base::Value last_policy_{base::Value::Type::DICTIONARY};
 
   // Used to set up timers when a time limit is approaching.
   TimeLimitNotifier time_limit_notifier_;
diff --git a/chrome/browser/ash/child_accounts/time_limits/app_time_controller.cc b/chrome/browser/ash/child_accounts/time_limits/app_time_controller.cc
index fd96c5e..64d8f364 100644
--- a/chrome/browser/ash/child_accounts/time_limits/app_time_controller.cc
+++ b/chrome/browser/ash/child_accounts/time_limits/app_time_controller.cc
@@ -403,9 +403,8 @@
     const std::string& pref_name) {
   DCHECK_EQ(pref_name, prefs::kPerAppTimeLimitsAllowlistPolicy);
 
-  const base::DictionaryValue* policy =
-      &base::Value::AsDictionaryValue(*pref_registrar_->prefs()->GetDictionary(
-          prefs::kPerAppTimeLimitsAllowlistPolicy));
+  const base::Value* policy = pref_registrar_->prefs()->GetDictionary(
+      prefs::kPerAppTimeLimitsAllowlistPolicy);
 
   // Figure out a way to avoid cloning
   AppTimeLimitsAllowlistPolicyWrapper wrapper(policy);
diff --git a/chrome/browser/ash/crosapi/browser_data_migrator.cc b/chrome/browser/ash/crosapi/browser_data_migrator.cc
index 5f9c376a..38b46ee 100644
--- a/chrome/browser/ash/crosapi/browser_data_migrator.cc
+++ b/chrome/browser/ash/crosapi/browser_data_migrator.cc
@@ -173,6 +173,10 @@
   // If the user is a new user, then there shouldn't be anything to migrate.
   // Also mark the user as migration completed.
   if (user_manager::UserManager::Get()->IsCurrentUserNew()) {
+    crosapi::browser_util::RecordDataVer(g_browser_process->local_state(),
+                                         user_id_hash,
+                                         version_info::GetVersion());
+
     crosapi::browser_util::SetProfileMigrationCompletedForUser(
         g_browser_process->local_state(), user_id_hash);
     // TODO(crbug.com/1277848): Once `BrowserDataMigrator` stabilises, remove
diff --git a/chrome/browser/ash/crostini/crostini_unsupported_action_notifier.cc b/chrome/browser/ash/crostini/crostini_unsupported_action_notifier.cc
index e98b4b5..c6287673 100644
--- a/chrome/browser/ash/crostini/crostini_unsupported_action_notifier.cc
+++ b/chrome/browser/ash/crostini/crostini_unsupported_action_notifier.cc
@@ -8,8 +8,9 @@
 
 #include "ash/constants/app_types.h"
 #include "ash/public/cpp/keyboard/keyboard_controller.h"
+#include "ash/public/cpp/system/toast_catalog.h"
+#include "ash/public/cpp/system/toast_manager.h"
 #include "ash/public/cpp/tablet_mode.h"
-#include "ash/public/cpp/toast_manager.h"
 #include "base/check.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/strings/utf_string_conversions.h"
@@ -113,6 +114,7 @@
   if (!virtual_keyboard_unsupported_message_shown_) {
     ash::ToastData data = {
         /*id=*/"VKUnsupportedInCrostini",
+        ash::ToastCatalogName::kCrostiniUnsupportedVirtualKeyboard,
         /*text=*/
         l10n_util::GetStringUTF16(IDS_CROSTINI_UNSUPPORTED_VIRTUAL_KEYBOARD),
         /*timeout_ms=*/delegate_->ToastTimeoutMs()};
@@ -135,6 +137,7 @@
         base::UTF8ToUTF16(delegate_->GetLocalizedDisplayName(method));
     ash::ToastData data = {
         /*id=*/"IMEUnsupportedInCrostini",
+        ash::ToastCatalogName::kCrostiniUnsupportedIME,
         /*text=*/
         l10n_util::GetStringFUTF16(IDS_CROSTINI_UNSUPPORTED_IME, ime_name),
         /*timeout_ms=*/delegate_->ToastTimeoutMs()};
diff --git a/chrome/browser/ash/crostini/crostini_unsupported_action_notifier.h b/chrome/browser/ash/crostini/crostini_unsupported_action_notifier.h
index 415da35..8fded3c 100644
--- a/chrome/browser/ash/crostini/crostini_unsupported_action_notifier.h
+++ b/chrome/browser/ash/crostini/crostini_unsupported_action_notifier.h
@@ -9,8 +9,8 @@
 #include <string>
 
 #include "ash/public/cpp/keyboard/keyboard_controller_observer.h"
+#include "ash/public/cpp/system/toast_data.h"
 #include "ash/public/cpp/tablet_mode_observer.h"
-#include "ash/public/cpp/toast_data.h"
 #include "chrome/browser/profiles/profile.h"
 #include "ui/aura/client/focus_change_observer.h"
 #include "ui/base/ime/ash/input_method_manager.h"
diff --git a/chrome/browser/ash/login/auth/chrome_cryptohome_authenticator.cc b/chrome/browser/ash/login/auth/chrome_cryptohome_authenticator.cc
index dcba36c..d3c7a1f 100644
--- a/chrome/browser/ash/login/auth/chrome_cryptohome_authenticator.cc
+++ b/chrome/browser/ash/login/auth/chrome_cryptohome_authenticator.cc
@@ -9,6 +9,7 @@
 #include "chrome/browser/ash/ownership/owner_settings_service_ash.h"
 #include "chrome/browser/ash/ownership/owner_settings_service_ash_factory.h"
 #include "chrome/browser/ash/settings/cros_settings.h"
+#include "chrome/browser/browser_process.h"
 #include "chromeos/login/login_state/login_state.h"
 #include "components/ownership/owner_key_util.h"
 #include "content/public/browser/browser_thread.h"
@@ -20,9 +21,10 @@
 ChromeCryptohomeAuthenticator::ChromeCryptohomeAuthenticator(
     AuthStatusConsumer* consumer)
     : CryptohomeAuthenticator(base::ThreadTaskRunnerHandle::Get(),
+                              g_browser_process->local_state(),
                               std::make_unique<ChromeSafeModeDelegate>(),
                               consumer) {}
 
-ChromeCryptohomeAuthenticator::~ChromeCryptohomeAuthenticator() {}
+ChromeCryptohomeAuthenticator::~ChromeCryptohomeAuthenticator() = default;
 
 }  // namespace ash
diff --git a/chrome/browser/ash/login/existing_user_controller.cc b/chrome/browser/ash/login/existing_user_controller.cc
index 9ee4981..0b463e4 100644
--- a/chrome/browser/ash/login/existing_user_controller.cc
+++ b/chrome/browser/ash/login/existing_user_controller.cc
@@ -447,6 +447,8 @@
       user_manager::UserManager::Get();
   // By default disable offline login from the error screen.
   ErrorScreen::AllowOfflineLogin(false /* allowed */);
+  // Counts regular device users that can log in.
+  int regular_users_counter = 0;
   for (auto* user : users) {
     // Skip kiosk apps for login screen user list. Kiosk apps as pods (aka new
     // kiosk UI) is currently disabled and it gets the apps directly from
@@ -459,6 +461,7 @@
         user->GetType() == user_manager::USER_TYPE_CHILD ||
         user->GetType() == user_manager::USER_TYPE_ACTIVE_DIRECTORY) {
       ErrorScreen::AllowOfflineLogin(true /* allowed */);
+      regular_users_counter++;
     }
     const bool meets_allowlist_requirements =
         !user->HasGaiaAccount() ||
@@ -467,6 +470,10 @@
       saml_users_for_password_sync.push_back(user);
   }
 
+  // Records total number of users on the login screen.
+  base::UmaHistogramCounts100("Login.NumberOfUsersOnLoginScreen",
+                              regular_users_counter);
+
   auto login_users = ExtractLoginUsers(users);
 
   // ExistingUserController owns PasswordSyncTokenLoginCheckers only if user
diff --git a/chrome/browser/ash/login/oobe_interactive_ui_test.cc b/chrome/browser/ash/login/oobe_interactive_ui_test.cc
index 4bfb29fd..a3ebb91 100644
--- a/chrome/browser/ash/login/oobe_interactive_ui_test.cc
+++ b/chrome/browser/ash/login/oobe_interactive_ui_test.cc
@@ -29,13 +29,13 @@
 #include "chrome/browser/ash/login/screens/recommend_apps/recommend_apps_fetcher_delegate.h"
 #include "chrome/browser/ash/login/screens/recommend_apps/scoped_test_recommend_apps_fetcher_factory.h"
 #include "chrome/browser/ash/login/test/device_state_mixin.h"
+#include "chrome/browser/ash/login/test/embedded_policy_test_server_mixin.h"
 #include "chrome/browser/ash/login/test/embedded_test_server_setup_mixin.h"
 #include "chrome/browser/ash/login/test/enrollment_ui_mixin.h"
 #include "chrome/browser/ash/login/test/fake_arc_tos_mixin.h"
 #include "chrome/browser/ash/login/test/fake_eula_mixin.h"
 #include "chrome/browser/ash/login/test/fake_gaia_mixin.h"
 #include "chrome/browser/ash/login/test/js_checker.h"
-#include "chrome/browser/ash/login/test/local_policy_test_server_mixin.h"
 #include "chrome/browser/ash/login/test/login_manager_mixin.h"
 #include "chrome/browser/ash/login/test/login_or_lock_screen_visible_waiter.h"
 #include "chrome/browser/ash/login/test/oobe_base_test.h"
@@ -812,7 +812,7 @@
                                      PROFILE_ENTERPRISE_ENROLLMENT_CERTIFICATE,
                                  ""));
     OobeInteractiveUITest::SetUpOnMainThread();
-    policy_server_.ConfigureFakeStatisticsForZeroTouch(
+    policy_test_server_mixin_.ConfigureFakeStatisticsForZeroTouch(
         &fake_statistics_provider_);
   }
 
@@ -832,13 +832,13 @@
   void ZeroTouchEndToEnd();
 
  private:
-  LocalPolicyTestServerMixin policy_server_{&mixin_host_};
+  EmbeddedPolicyTestServerMixin policy_test_server_mixin_{&mixin_host_};
   test::EnrollmentUIMixin enrollment_ui_{&mixin_host_};
   system::ScopedFakeStatisticsProvider fake_statistics_provider_;
 };
 
 void OobeZeroTouchInteractiveUITest::ZeroTouchEndToEnd() {
-  policy_server_.SetupZeroTouchForcedEnrollment();
+  policy_test_server_mixin_.SetupZeroTouchForcedEnrollment();
 
   PerformStepsBeforeEnrollmentCheck();
 
diff --git a/chrome/browser/ash/login/saml/saml_browsertest.cc b/chrome/browser/ash/login/saml/saml_browsertest.cc
index 63397c77..77c8ce9 100644
--- a/chrome/browser/ash/login/saml/saml_browsertest.cc
+++ b/chrome/browser/ash/login/saml/saml_browsertest.cc
@@ -35,10 +35,10 @@
 #include "chrome/browser/ash/login/saml/fake_saml_idp_mixin.h"
 #include "chrome/browser/ash/login/startup_utils.h"
 #include "chrome/browser/ash/login/test/device_state_mixin.h"
+#include "chrome/browser/ash/login/test/embedded_policy_test_server_mixin.h"
 #include "chrome/browser/ash/login/test/enrollment_ui_mixin.h"
 #include "chrome/browser/ash/login/test/fake_gaia_mixin.h"
 #include "chrome/browser/ash/login/test/js_checker.h"
-#include "chrome/browser/ash/login/test/local_policy_test_server_mixin.h"
 #include "chrome/browser/ash/login/test/login_manager_mixin.h"
 #include "chrome/browser/ash/login/test/oobe_base_test.h"
 #include "chrome/browser/ash/login/test/oobe_screen_waiter.h"
@@ -898,7 +898,7 @@
   void StartSamlAndWaitForIdpPageLoad(const std::string& gaia_email) override;
 
  protected:
-  LocalPolicyTestServerMixin local_policy_mixin_{&mixin_host_};
+  EmbeddedPolicyTestServerMixin policy_test_server_mixin_{&mixin_host_};
   test::EnrollmentUIMixin enrollment_ui_{&mixin_host_};
 };
 
diff --git a/chrome/browser/ash/login/screens/terms_of_service_screen_browsertest.cc b/chrome/browser/ash/login/screens/terms_of_service_screen_browsertest.cc
index fb398196..c039f4e 100644
--- a/chrome/browser/ash/login/screens/terms_of_service_screen_browsertest.cc
+++ b/chrome/browser/ash/login/screens/terms_of_service_screen_browsertest.cc
@@ -7,6 +7,7 @@
 #include "ash/constants/ash_features.h"
 #include "ash/public/cpp/login_screen_test_api.h"
 #include "base/bind.h"
+#include "base/files/file_util.h"
 #include "base/run_loop.h"
 #include "base/threading/thread_restrictions.h"
 #include "chrome/browser/ash/login/existing_user_controller.h"
@@ -15,9 +16,9 @@
 #include "chrome/browser/ash/login/session/user_session_manager_test_api.h"
 #include "chrome/browser/ash/login/test/cryptohome_mixin.h"
 #include "chrome/browser/ash/login/test/device_state_mixin.h"
+#include "chrome/browser/ash/login/test/embedded_policy_test_server_mixin.h"
 #include "chrome/browser/ash/login/test/embedded_test_server_setup_mixin.h"
 #include "chrome/browser/ash/login/test/js_checker.h"
-#include "chrome/browser/ash/login/test/local_policy_test_server_mixin.h"
 #include "chrome/browser/ash/login/test/login_manager_mixin.h"
 #include "chrome/browser/ash/login/test/oobe_base_test.h"
 #include "chrome/browser/ash/login/test/oobe_screen_waiter.h"
@@ -130,9 +131,9 @@
 
   void UploadDeviceLocalAccountPolicy() {
     BuildDeviceLocalAccountPolicy();
-    ASSERT_TRUE(local_policy_mixin_.server()->UpdatePolicy(
+    policy_test_server_mixin_.UpdatePolicy(
         policy::dm_protocol::kChromePublicAccountPolicyType, kAccountId,
-        device_local_account_policy_.payload().SerializeAsString()));
+        device_local_account_policy_.payload().SerializeAsString());
   }
 
   void UploadAndInstallDeviceLocalAccountPolicy() {
@@ -145,7 +146,7 @@
     em::ChromeDeviceSettingsProto& proto(device_policy()->payload());
     policy::DeviceLocalAccountTestHelper::AddPublicSession(&proto, kAccountId);
     RefreshDevicePolicy();
-    ASSERT_TRUE(local_policy_mixin_.UpdateDevicePolicy(proto));
+    policy_test_server_mixin_.UpdateDevicePolicy(proto);
   }
 
   void WaitForDisplayName() {
@@ -237,7 +238,7 @@
           kAccountId,
           policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION));
   policy::DevicePolicyCrosTestHelper policy_helper_;
-  LocalPolicyTestServerMixin local_policy_mixin_{&mixin_host_};
+  EmbeddedPolicyTestServerMixin policy_test_server_mixin_{&mixin_host_};
   DeviceStateMixin device_state_{
       &mixin_host_, DeviceStateMixin::State::OOBE_COMPLETED_CLOUD_ENROLLED};
 };
diff --git a/chrome/browser/ash/login/session_login_browsertest.cc b/chrome/browser/ash/login/session_login_browsertest.cc
index 4580feb..77afebf 100644
--- a/chrome/browser/ash/login/session_login_browsertest.cc
+++ b/chrome/browser/ash/login/session_login_browsertest.cc
@@ -13,8 +13,8 @@
 #include "chrome/browser/ash/login/session/user_session_manager_test_api.h"
 #include "chrome/browser/ash/login/startup_utils.h"
 #include "chrome/browser/ash/login/test/device_state_mixin.h"
+#include "chrome/browser/ash/login/test/embedded_policy_test_server_mixin.h"
 #include "chrome/browser/ash/login/test/fake_gaia_mixin.h"
-#include "chrome/browser/ash/login/test/local_policy_test_server_mixin.h"
 #include "chrome/browser/ash/login/test/login_manager_mixin.h"
 #include "chrome/browser/ash/login/test/oobe_screen_exit_waiter.h"
 #include "chrome/browser/ash/login/test/oobe_screen_waiter.h"
@@ -139,7 +139,7 @@
   AccountId regular_user_{
       AccountId::FromUserEmailGaiaId(test::kTestEmail, test::kTestGaiaId)};
 
-  LocalPolicyTestServerMixin policy_server_mixin_{&mixin_host_};
+  EmbeddedPolicyTestServerMixin policy_server_mixin_{&mixin_host_};
 
   UserPolicyMixin user_policy_mixin_{&mixin_host_, regular_user_,
                                      &policy_server_mixin_};
diff --git a/chrome/browser/ash/login/signin/token_handle_util.cc b/chrome/browser/ash/login/signin/token_handle_util.cc
index b2e3319..f0e87fbb 100644
--- a/chrome/browser/ash/login/signin/token_handle_util.cc
+++ b/chrome/browser/ash/login/signin/token_handle_util.cc
@@ -58,43 +58,40 @@
                      const std::string& token,
                      const AccountId& account_id,
                      TokenHandleUtil::TokenHandleStatus status) {
+  user_manager::KnownUser known_user(g_browser_process->local_state());
   // Check that the token that was checked matches the latest known token.
   // (This may happen if token check took too long, and user went through
   // online sign-in and obtained new token during that time.
-  const base::DictionaryValue* dict = nullptr;
   std::string latest_token;
-  if (user_manager::known_user::FindPrefs(account_id, &dict)) {
-    auto* latest_token = dict->FindStringPath(kTokenHandlePref);
-    if (latest_token) {
-      if (token != *latest_token) {
-        LOG(WARNING) << "Outdated token, assuming status is unknown";
-        std::move(callback).Run(account_id, TokenHandleUtil::UNKNOWN);
-        return;
-      }
+  if (known_user.GetStringPref(account_id, kTokenHandlePref, &latest_token)) {
+    if (token != latest_token) {
+      LOG(WARNING) << "Outdated token, assuming status is unknown";
+      std::move(callback).Run(account_id, TokenHandleUtil::UNKNOWN);
+      return;
     }
   }
 
   if (status != TokenHandleUtil::UNKNOWN) {
     // Update last checked timestamp.
-    user_manager::known_user::SetPref(account_id, kTokenHandleLastCheckedPref,
-                                      base::TimeToValue(base::Time::Now()));
+    known_user.SetPath(account_id, kTokenHandleLastCheckedPref,
+                       base::TimeToValue(base::Time::Now()));
   }
 
   if (status == TokenHandleUtil::INVALID) {
-    user_manager::known_user::SetStringPref(account_id, kTokenHandleStatusPref,
-                                            kHandleStatusInvalid);
+    known_user.SetStringPref(account_id, kTokenHandleStatusPref,
+                             kHandleStatusInvalid);
   }
   std::move(callback).Run(account_id, status);
 }
 
 // Checks if token handle is explicitly marked as INVALID for |account_id|.
 bool HasTokenStatusInvalid(const AccountId& account_id) {
-  const base::DictionaryValue* dict = nullptr;
-  std::string token;
-  if (!user_manager::known_user::FindPrefs(account_id, &dict))
+  std::string status;
+  if (!user_manager::known_user::GetStringPref(
+          account_id, kTokenHandleStatusPref, &status)) {
     return false;
-  auto* status = dict->FindStringPath(kTokenHandleStatusPref);
-  return status && *status == kHandleStatusInvalid;
+  }
+  return status == kHandleStatusInvalid;
 }
 
 }  // namespace
@@ -150,18 +147,14 @@
     const AccountId& account_id,
     scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
     TokenValidationCallback callback) {
-  const base::DictionaryValue* dict = nullptr;
-  if (!user_manager::known_user::FindPrefs(account_id, &dict)) {
-    std::move(callback).Run(account_id, UNKNOWN);
-    return;
-  }
-  const std::string* token = dict->FindStringKey(kTokenHandlePref);
-  if (!token) {
+  std::string token;
+  if (!user_manager::known_user::GetStringPref(account_id, kTokenHandlePref,
+                                               &token)) {
     std::move(callback).Run(account_id, UNKNOWN);
     return;
   }
 
-  if (g_invalid_token_for_testing && g_invalid_token_for_testing == *token) {
+  if (g_invalid_token_for_testing && g_invalid_token_for_testing == token) {
     std::move(callback).Run(account_id, INVALID);
     return;
   }
@@ -179,10 +172,10 @@
   }
 
   // Constructor starts validation.
-  validation_delegates_[*token] = std::make_unique<TokenDelegate>(
-      weak_factory_.GetWeakPtr(), account_id, *token,
+  validation_delegates_[token] = std::make_unique<TokenDelegate>(
+      weak_factory_.GetWeakPtr(), account_id, token,
       std::move(url_loader_factory),
-      base::BindOnce(&OnStatusChecked, std::move(callback), *token));
+      base::BindOnce(&OnStatusChecked, std::move(callback), token));
 }
 
 // static
@@ -194,7 +187,7 @@
   known_user.SetStringPref(account_id, kTokenHandleStatusPref,
                            kHandleStatusValid);
   known_user.SetBooleanPref(account_id, kTokenHandleRotated, true);
-  known_user.SetPref(account_id, kTokenHandleLastCheckedPref,
+  known_user.SetPath(account_id, kTokenHandleLastCheckedPref,
                      base::TimeToValue(base::Time::Now()));
 }
 
@@ -216,8 +209,9 @@
 // static
 void TokenHandleUtil::SetLastCheckedPrefForTesting(const AccountId& account_id,
                                                    base::Time time) {
-  user_manager::known_user::SetPref(account_id, kTokenHandleLastCheckedPref,
-                                    base::TimeToValue(time));
+  user_manager::KnownUser known_user(g_browser_process->local_state());
+  known_user.SetPath(account_id, kTokenHandleLastCheckedPref,
+                     base::TimeToValue(time));
 }
 
 void TokenHandleUtil::OnValidationComplete(const std::string& token) {
@@ -239,7 +233,7 @@
   gaia_client_.GetTokenHandleInfo(token_, kMaxRetries, this);
 }
 
-TokenHandleUtil::TokenDelegate::~TokenDelegate() {}
+TokenHandleUtil::TokenDelegate::~TokenDelegate() = default;
 
 void TokenHandleUtil::TokenDelegate::OnOAuthError() {
   std::move(callback_).Run(account_id_, INVALID);
diff --git a/chrome/browser/ash/login/test/embedded_policy_test_server_mixin.cc b/chrome/browser/ash/login/test/embedded_policy_test_server_mixin.cc
index 729bb78..2acdbea 100644
--- a/chrome/browser/ash/login/test/embedded_policy_test_server_mixin.cc
+++ b/chrome/browser/ash/login/test/embedded_policy_test_server_mixin.cc
@@ -26,12 +26,9 @@
 #include "components/policy/test_support/embedded_policy_test_server.h"
 #include "components/policy/test_support/policy_storage.h"
 #include "components/policy/test_support/signature_provider.h"
-#include "crypto/sha2.h"
 #include "net/http/http_status_code.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
-namespace em = enterprise_management;
-
 namespace ash {
 
 namespace {
@@ -130,17 +127,7 @@
     const std::string& type,
     const std::string& entity_id,
     const std::string& raw_policy) {
-  // Register raw policy to be served by external endpoint.
-  policy_test_server_->policy_storage()->SetExternalPolicyPayload(
-      type, entity_id, raw_policy);
-
-  // Register proto policy with details on how to fetch the raw policy.
-  em::ExternalPolicyData external_policy_data;
-  external_policy_data.set_download_url(
-      policy_test_server_->GetExternalPolicyDataURL(type, entity_id).spec());
-  external_policy_data.set_secure_hash(crypto::SHA256HashString(raw_policy));
-  policy_test_server_->policy_storage()->SetPolicyPayload(
-      type, entity_id, external_policy_data.SerializeAsString());
+  policy_test_server_->UpdateExternalPolicy(type, entity_id, raw_policy);
 }
 
 void EmbeddedPolicyTestServerMixin::SetUpdateDeviceAttributesPermission(
diff --git a/chrome/browser/ash/login/test/embedded_policy_test_server_mixin.h b/chrome/browser/ash/login/test/embedded_policy_test_server_mixin.h
index a8f9b9e..fa6d448 100644
--- a/chrome/browser/ash/login/test/embedded_policy_test_server_mixin.h
+++ b/chrome/browser/ash/login/test/embedded_policy_test_server_mixin.h
@@ -81,7 +81,7 @@
                     const std::string& serialized_policy);
 
   // Updates policy selected by |type| and optional |entity_id|. The
-  // |raw_policy| is served via an external data point. This does not trigger
+  // |raw_policy| is served via an external endpoint. This does not trigger
   // policy invalidation, hence test authors must manually trigger a policy
   // fetch.
   void UpdateExternalPolicy(const std::string& type,
diff --git a/chrome/browser/ash/login/webview_login_browsertest.cc b/chrome/browser/ash/login/webview_login_browsertest.cc
index 0e0b39a..39acfcb 100644
--- a/chrome/browser/ash/login/webview_login_browsertest.cc
+++ b/chrome/browser/ash/login/webview_login_browsertest.cc
@@ -35,9 +35,9 @@
 #include "chrome/browser/ash/login/saml/lockscreen_reauth_dialog_test_helper.h"
 #include "chrome/browser/ash/login/signin_partition_manager.h"
 #include "chrome/browser/ash/login/test/device_state_mixin.h"
+#include "chrome/browser/ash/login/test/embedded_policy_test_server_mixin.h"
 #include "chrome/browser/ash/login/test/fake_gaia_mixin.h"
 #include "chrome/browser/ash/login/test/js_checker.h"
-#include "chrome/browser/ash/login/test/local_policy_test_server_mixin.h"
 #include "chrome/browser/ash/login/test/login_manager_mixin.h"
 #include "chrome/browser/ash/login/test/oobe_base_test.h"
 #include "chrome/browser/ash/login/test/oobe_screen_exit_waiter.h"
@@ -1922,7 +1922,8 @@
   }
 
   void UpdateServedPolicyFromDevicePolicyTestHelper() {
-    local_policy_mixin_.UpdateDevicePolicy(device_policy_builder()->payload());
+    policy_test_server_mixin_.UpdateDevicePolicy(
+        device_policy_builder()->payload());
   }
 
   policy::DevicePolicyBuilder* device_policy_builder() {
@@ -1942,7 +1943,7 @@
   // A proxy server which requires authentication using the 'Basic'
   // authentication method.
   std::unique_ptr<net::SpawnedTestServer> auth_proxy_server_;
-  LocalPolicyTestServerMixin local_policy_mixin_{&mixin_host_};
+  EmbeddedPolicyTestServerMixin policy_test_server_mixin_{&mixin_host_};
   policy::DevicePolicyBuilder device_policy_builder_;
 
   DeviceStateMixin device_state_{
@@ -2009,9 +2010,9 @@
   AccountId child_account_id_{
       AccountId::FromUserEmailGaiaId(FakeGaiaMixin::kFakeUserEmail,
                                      FakeGaiaMixin::kFakeUserGaiaId)};
-  LocalPolicyTestServerMixin local_policy_mixin_{&mixin_host_};
+  EmbeddedPolicyTestServerMixin policy_test_server_mixin_{&mixin_host_};
   UserPolicyMixin user_policy_mixin_{&mixin_host_, child_account_id_,
-                                     &local_policy_mixin_};
+                                     &policy_test_server_mixin_};
 };
 
 // Test verfies case when user info message sent before authentication is
diff --git a/chrome/browser/ash/preferences.cc b/chrome/browser/ash/preferences.cc
index 746c210a..8621db2 100644
--- a/chrome/browser/ash/preferences.cc
+++ b/chrome/browser/ash/preferences.cc
@@ -1041,9 +1041,10 @@
     if (value &&
         prefs_->IsManagedPreference(::prefs::kParentAccessCodeConfig) &&
         user_->IsChild()) {
-      user_manager::known_user::SetPref(
-          user_->GetAccountId(), ::prefs::kKnownUserParentAccessCodeConfig,
-          value->Clone());
+      user_manager::KnownUser known_user(g_browser_process->local_state());
+      known_user.SetPath(user_->GetAccountId(),
+                         ::prefs::kKnownUserParentAccessCodeConfig,
+                         value->Clone());
       parent_access::ParentAccessService::Get().LoadConfigForUser(user_);
     } else {
       user_manager::known_user::RemovePref(
diff --git a/chrome/browser/ash/sharesheet/copy_to_clipboard_share_action.cc b/chrome/browser/ash/sharesheet/copy_to_clipboard_share_action.cc
index 0453f34..b75870a 100644
--- a/chrome/browser/ash/sharesheet/copy_to_clipboard_share_action.cc
+++ b/chrome/browser/ash/sharesheet/copy_to_clipboard_share_action.cc
@@ -6,8 +6,9 @@
 
 #include <string>
 
-#include "ash/public/cpp/toast_data.h"
-#include "ash/public/cpp/toast_manager.h"
+#include "ash/public/cpp/system/toast_catalog.h"
+#include "ash/public/cpp/system/toast_data.h"
+#include "ash/public/cpp/system/toast_manager.h"
 #include "ash/resources/vector_icons/vector_icons.h"
 #include "base/containers/flat_set.h"
 #include "chrome/browser/apps/app_service/file_utils.h"
@@ -106,7 +107,7 @@
     controller->CloseBubble(::sharesheet::SharesheetResult::kSuccess);
   }
 
-  ToastData toast(kToastId,
+  ToastData toast(kToastId, ToastCatalogName::kCopyToClipboardShareAction,
                   l10n_util::GetStringUTF16(
                       IDS_SHARESHEET_COPY_TO_CLIPBOARD_SUCCESS_TOAST_LABEL));
   ShowToast(toast);
diff --git a/chrome/browser/ash/throttle_service_unittest.cc b/chrome/browser/ash/throttle_service_unittest.cc
index 1a4bf11..0f79c19 100644
--- a/chrome/browser/ash/throttle_service_unittest.cc
+++ b/chrome/browser/ash/throttle_service_unittest.cc
@@ -14,6 +14,9 @@
 
 namespace {
 
+constexpr const char kFirstObserverName[] = "o1";
+constexpr const char kSecondObserverName[] = "o2";
+
 class TestObserver : public ThrottleService::ServiceObserver {
  public:
   TestObserver() = default;
@@ -79,8 +82,9 @@
  public:
   ThrottleServiceTest() : service_(&profile_) {
     std::vector<std::unique_ptr<ThrottleObserver>> observers;
-    observers.push_back(std::make_unique<ThrottleObserver>("o1"));
-    observers.push_back(std::make_unique<ThrottleObserver>("o2"));
+    observers.push_back(std::make_unique<ThrottleObserver>(kFirstObserverName));
+    observers.push_back(
+        std::make_unique<ThrottleObserver>(kSecondObserverName));
     service_.SetObserversForTesting(std::move(observers));
   }
 
@@ -217,4 +221,14 @@
   EXPECT_EQ(0, test_observer.GetUpdateCountAndReset());
 }
 
+// Tests that getting an observer by its name works.
+TEST_F(ThrottleServiceTest, TestGetObserverByName) {
+  auto* first_observer = service()->GetObserverByName(kFirstObserverName);
+  auto* second_observer = service()->GetObserverByName(kSecondObserverName);
+  EXPECT_NE(nullptr, first_observer);
+  EXPECT_NE(nullptr, second_observer);
+  EXPECT_NE(first_observer, second_observer);
+  EXPECT_EQ(nullptr, service()->GetObserverByName("NonExistentObserverName"));
+}
+
 }  // namespace ash
diff --git a/chrome/browser/autofill/autofill_interactive_uitest.cc b/chrome/browser/autofill/autofill_interactive_uitest.cc
index de7dfea..4c3682b 100644
--- a/chrome/browser/autofill/autofill_interactive_uitest.cc
+++ b/chrome/browser/autofill/autofill_interactive_uitest.cc
@@ -863,12 +863,12 @@
   std::unique_ptr<URLLoaderInterceptor> url_loader_interceptor_;
 };
 
-// Test is flaky on Linux TSAN, see http://crbug.com/1045709.
-#if defined(THREAD_SANITIZER)
+// Test is flaky on Linux TSAN and Mac, see http://crbug.com/1045709.
+#if defined(THREAD_SANITIZER) || defined(OS_MAC)
 #define MAYBE_BasicFormFill DISABLED_BasicFormFill
 #else
 #define MAYBE_BasicFormFill BasicFormFill
-#endif  // THREAD_SANITIZER
+#endif  // defined(THREAD_SANITIZER) || defined(OS_MAC)
 // Test that basic form fill is working.
 IN_PROC_BROWSER_TEST_F(AutofillInteractiveTestWithHistogramTester,
                        MAYBE_BasicFormFill) {
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 5230339..4934e37 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -57,7 +57,6 @@
 #include "chrome/browser/federated_learning/floc_id_provider_factory.h"
 #include "chrome/browser/first_party_sets/first_party_sets_pref_names.h"
 #include "chrome/browser/first_party_sets/first_party_sets_util.h"
-#include "chrome/browser/font_access/chrome_font_access_delegate.h"
 #include "chrome/browser/font_family_cache.h"
 #include "chrome/browser/gpu/chrome_browser_main_extra_parts_gpu.h"
 #include "chrome/browser/hid/chrome_hid_delegate.h"
@@ -257,7 +256,6 @@
 #include "content/public/browser/child_process_security_policy.h"
 #include "content/public/browser/client_certificate_delegate.h"
 #include "content/public/browser/file_url_loader.h"
-#include "content/public/browser/font_access_delegate.h"
 #include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/navigation_throttle.h"
 #include "content/public/browser/overlay_window.h"
@@ -5437,13 +5435,6 @@
   return hid_delegate_.get();
 }
 
-content::FontAccessDelegate*
-ChromeContentBrowserClient::GetFontAccessDelegate() {
-  if (!font_access_delegate_)
-    font_access_delegate_ = std::make_unique<ChromeFontAccessDelegate>();
-  return static_cast<content::FontAccessDelegate*>(font_access_delegate_.get());
-}
-
 content::WebAuthenticationDelegate*
 ChromeContentBrowserClient::GetWebAuthenticationDelegate() {
   if (!web_authentication_delegate_) {
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h
index 7392f7d..d14f659 100644
--- a/chrome/browser/chrome_content_browser_client.h
+++ b/chrome/browser/chrome_content_browser_client.h
@@ -55,7 +55,6 @@
 
 namespace content {
 class BrowserContext;
-class FontAccessDelegate;
 class QuotaPermissionContext;
 enum class SmsFetchFailureType;
 struct ServiceWorkerVersionBaseInfo;
@@ -96,7 +95,6 @@
 enum class Channel;
 }  // namespace version_info
 
-class ChromeFontAccessDelegate;
 class ChromeHidDelegate;
 class ChromeSerialDelegate;
 class ChromeWebAuthenticationDelegate;
@@ -577,7 +575,6 @@
       override;
   content::SerialDelegate* GetSerialDelegate() override;
   content::HidDelegate* GetHidDelegate() override;
-  content::FontAccessDelegate* GetFontAccessDelegate() override;
   content::WebAuthenticationDelegate* GetWebAuthenticationDelegate() override;
   std::unique_ptr<content::AuthenticatorRequestClientDelegate>
   GetWebAuthenticationRequestDelegate(
@@ -886,7 +883,6 @@
 #else
   std::unique_ptr<ChromeSerialDelegate> serial_delegate_;
   std::unique_ptr<ChromeHidDelegate> hid_delegate_;
-  std::unique_ptr<ChromeFontAccessDelegate> font_access_delegate_;
   std::unique_ptr<ChromeWebAuthenticationDelegate> web_authentication_delegate_;
 #endif
   std::unique_ptr<permissions::BluetoothDelegateImpl> bluetooth_delegate_;
diff --git a/chrome/browser/chrome_security_exploit_browsertest.cc b/chrome/browser/chrome_security_exploit_browsertest.cc
index 8902f577..db06e9c9 100644
--- a/chrome/browser/chrome_security_exploit_browsertest.cc
+++ b/chrome/browser/chrome_security_exploit_browsertest.cc
@@ -319,7 +319,7 @@
       blink::StorageKey(url::Origin::Create(target_url)));
 
   // Now navigate to |target_url| in a new tab. It should not contain |payload|.
-  AddTabAtIndex(0, target_url, ui::PAGE_TRANSITION_TYPED);
+  ASSERT_FALSE(AddTabAtIndex(0, target_url, ui::PAGE_TRANSITION_TYPED));
   EXPECT_FALSE(content::WaitForLoadStop(
       browser()->tab_strip_model()->GetWebContentsAt(0)));
   rfh = browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
@@ -399,7 +399,7 @@
       blink::StorageKey(url::Origin::Create(target_url)));
 
   // Now navigate to |target_url| in a new tab. It should not contain |payload|.
-  AddTabAtIndex(0, target_url, ui::PAGE_TRANSITION_TYPED);
+  ASSERT_FALSE(AddTabAtIndex(0, target_url, ui::PAGE_TRANSITION_TYPED));
   EXPECT_FALSE(content::WaitForLoadStop(
       browser()->tab_strip_model()->GetWebContentsAt(0)));
   rfh = browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index 7f18993..b783a40 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -246,7 +246,6 @@
     "//chromeos/dbus/cryptohome",
     "//chromeos/dbus/cryptohome:attestation_proto",
     "//chromeos/dbus/cryptohome:cryptohome_proto",
-    "//chromeos/dbus/cryptohome:cryptohome_signkey_proto",
     "//chromeos/dbus/cups_proxy",
     "//chromeos/dbus/dlcservice",
     "//chromeos/dbus/dlcservice:dlcservice_proto",
diff --git a/chrome/browser/chromeos/extensions/login_screen/login/login_apitest.cc b/chrome/browser/chromeos/extensions/login_screen/login/login_apitest.cc
index 9085603..c326352 100644
--- a/chrome/browser/chromeos/extensions/login_screen/login/login_apitest.cc
+++ b/chrome/browser/chromeos/extensions/login_screen/login/login_apitest.cc
@@ -162,9 +162,9 @@
     auto registry_observer =
         GetTestExtensionRegistryObserver(kInSessionExtensionId);
 
-    ASSERT_TRUE(local_policy_mixin_.server()->UpdatePolicy(
+    policy_test_server_mixin_.UpdatePolicy(
         policy::dm_protocol::kChromePublicAccountPolicyType, kAccountId,
-        user_policy_builder->payload().SerializeAsString()));
+        user_policy_builder->payload().SerializeAsString());
     session_manager_client()->set_device_local_account_policy(
         kAccountId, user_policy_builder->GetBlob());
     RefreshPolicies();
@@ -192,7 +192,7 @@
   void LockScreen() { ScreenLockerTester().Lock(); }
 
  private:
-  ash::LocalPolicyTestServerMixin local_policy_mixin_{&mixin_host_};
+  ash::EmbeddedPolicyTestServerMixin policy_test_server_mixin_{&mixin_host_};
   base::DictionaryValue config_;
 };
 
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier.cc b/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier.cc
index 636ce14..e730b6bc6 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier.cc
@@ -20,8 +20,9 @@
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "ash/public/cpp/new_window_delegate.h"
-#include "ash/public/cpp/toast_data.h"
-#include "ash/public/cpp/toast_manager.h"
+#include "ash/public/cpp/system/toast_catalog.h"
+#include "ash/public/cpp/system/toast_data.h"
+#include "ash/public/cpp/system/toast_manager.h"
 #include "ash/public/cpp/window_tree_host_lookup.h"
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
@@ -119,6 +120,7 @@
   if (data_dst) {
     if (data_dst->type() == ui::EndpointType::kCrostini) {
       ShowToast(kClipboardBlockCrostiniToastId,
+                ash::ToastCatalogName::kClipboardBlockedAction,
                 l10n_util::GetStringFUTF16(
                     IDS_POLICY_DLP_CLIPBOARD_BLOCKED_ON_COPY_VM, host_name,
                     l10n_util::GetStringUTF16(IDS_CROSTINI_LINUX)));
@@ -126,6 +128,7 @@
     }
     if (data_dst->type() == ui::EndpointType::kPluginVm) {
       ShowToast(kClipboardBlockPluginVmToastId,
+                ash::ToastCatalogName::kClipboardBlockedAction,
                 l10n_util::GetStringFUTF16(
                     IDS_POLICY_DLP_CLIPBOARD_BLOCKED_ON_COPY_VM, host_name,
                     l10n_util::GetStringUTF16(IDS_PLUGIN_VM_APP_NAME)));
@@ -133,6 +136,7 @@
     }
     if (data_dst->type() == ui::EndpointType::kArc) {
       ShowToast(kClipboardBlockArcToastId,
+                ash::ToastCatalogName::kClipboardBlockedAction,
                 l10n_util::GetStringFUTF16(
                     IDS_POLICY_DLP_CLIPBOARD_BLOCKED_ON_COPY_VM, host_name,
                     l10n_util::GetStringUTF16(IDS_POLICY_DLP_ANDROID_APPS)));
@@ -159,6 +163,7 @@
   if (data_dst) {
     if (data_dst->type() == ui::EndpointType::kCrostini) {
       ShowToast(kClipboardWarnCrostiniToastId,
+                ash::ToastCatalogName::kClipboardWarnOnPaste,
                 l10n_util::GetStringFUTF16(
                     IDS_POLICY_DLP_CLIPBOARD_WARN_ON_COPY_VM,
                     l10n_util::GetStringUTF16(IDS_CROSTINI_LINUX)));
@@ -166,6 +171,7 @@
     }
     if (data_dst->type() == ui::EndpointType::kPluginVm) {
       ShowToast(kClipboardWarnPluginVmToastId,
+                ash::ToastCatalogName::kClipboardWarnOnPaste,
                 l10n_util::GetStringFUTF16(
                     IDS_POLICY_DLP_CLIPBOARD_WARN_ON_COPY_VM,
                     l10n_util::GetStringUTF16(IDS_PLUGIN_VM_APP_NAME)));
@@ -173,6 +179,7 @@
     }
     if (data_dst->type() == ui::EndpointType::kArc) {
       ShowToast(kClipboardWarnArcToastId,
+                ash::ToastCatalogName::kClipboardWarnOnPaste,
                 l10n_util::GetStringFUTF16(
                     IDS_POLICY_DLP_CLIPBOARD_WARN_ON_COPY_VM,
                     l10n_util::GetStringUTF16(IDS_POLICY_DLP_ANDROID_APPS)));
@@ -268,9 +275,10 @@
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 void DlpClipboardNotifier::ShowToast(const std::string& id,
+                                     ash::ToastCatalogName catalog_name,
                                      const std::u16string& text) const {
   ash::ToastData toast(
-      id, text, ash::ToastData::kDefaultToastDurationMs,
+      id, catalog_name, text, ash::ToastData::kDefaultToastDurationMs,
       /*visible_on_lock_screen=*/false,
       l10n_util::GetStringUTF16(IDS_POLICY_DLP_CLIPBOARD_BLOCK_TOAST_BUTTON));
   toast.is_managed = true;
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier.h b/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier.h
index 619b20a..9d13073 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier.h
+++ b/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier.h
@@ -11,6 +11,10 @@
 #include "content/public/browser/web_contents_observer.h"
 #include "ui/base/clipboard/clipboard_observer.h"
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+#include "ash/public/cpp/system/toast_catalog.h"
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+
 namespace content {
 class WebContents;
 }
@@ -70,6 +74,7 @@
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   // Virtual for tests to override.
   virtual void ShowToast(const std::string& id,
+                         ash::ToastCatalogName catalog_name,
                          const std::u16string& text) const;
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier_unittest.cc b/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier_unittest.cc
index a171ff4e..784fa36 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier_unittest.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier_unittest.cc
@@ -28,6 +28,10 @@
 #include "url/gurl.h"
 #include "url/origin.h"
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+#include "ash/public/cpp/system/toast_catalog.h"
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+
 namespace policy {
 
 namespace {
@@ -72,8 +76,10 @@
                     base::RepeatingCallback<void(views::Widget*)> proceed_cb,
                     base::RepeatingCallback<void(views::Widget*)> cancel_cb));
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-  MOCK_CONST_METHOD2(ShowToast,
-                     void(const std::string& id, const std::u16string& text));
+  MOCK_CONST_METHOD3(ShowToast,
+                     void(const std::string& id,
+                          ash::ToastCatalogName catalog_name,
+                          const std::u16string& text));
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
   MOCK_METHOD2(CloseWidget,
                void(views::Widget* widget, views::Widget::ClosedReason reason));
@@ -377,7 +383,10 @@
       base::UTF8ToUTF16(origin.host()),
       l10n_util::GetStringUTF16(GetParam().expected_dst_name_id));
 
-  EXPECT_CALL(notifier, ShowToast(testing::_, expected_toast_str));
+  EXPECT_CALL(
+      notifier,
+      ShowToast(testing::_, ash::ToastCatalogName::kClipboardBlockedAction,
+                expected_toast_str));
 
   notifier.NotifyBlockedAction(&data_src, &data_dst);
 }
@@ -392,7 +401,9 @@
       IDS_POLICY_DLP_CLIPBOARD_WARN_ON_COPY_VM,
       l10n_util::GetStringUTF16(GetParam().expected_dst_name_id));
 
-  EXPECT_CALL(notifier, ShowToast(testing::_, expected_toast_str));
+  EXPECT_CALL(notifier, ShowToast(testing::_,
+                                  ash::ToastCatalogName::kClipboardWarnOnPaste,
+                                  expected_toast_str));
 
   EXPECT_CALL(notifier, CloseWidget(testing::_,
                                     views::Widget::ClosedReason::kUnspecified));
diff --git a/chrome/browser/client_hints/client_hints_browsertest.cc b/chrome/browser/client_hints/client_hints_browsertest.cc
index f903d13c9..856e151 100644
--- a/chrome/browser/client_hints/client_hints_browsertest.cc
+++ b/chrome/browser/client_hints/client_hints_browsertest.cc
@@ -2958,8 +2958,9 @@
       accept_ch_frame_observer_interceptor_;
 };
 
-#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
-// Flaky: https://crbug.com/1195790
+// TODO(crbug.com/1195790): Flaky on multiple bots.
+#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) || \
+    (BUILDFLAG(IS_WIN) && defined(ADDRESS_SANITIZER))
 #define MAYBE_AcceptCHFrame DISABLED_AcceptCHFrame
 #else
 #define MAYBE_AcceptCHFrame AcceptCHFrame
diff --git a/chrome/browser/component_updater/pki_metadata_component_installer.cc b/chrome/browser/component_updater/pki_metadata_component_installer.cc
index b61f967..03e37e0 100644
--- a/chrome/browser/component_updater/pki_metadata_component_installer.cc
+++ b/chrome/browser/component_updater/pki_metadata_component_installer.cc
@@ -34,6 +34,14 @@
 
 namespace {
 
+// This is the last version of CT log lists that this version of Chrome will
+// accept. If a list is delivered with a compatibility version higher than this,
+// it will be ignored (though the emergency disable flag will still be followed
+// if it is set). This should never be decreased since that will cause CT
+// enforcement to eventually stop. This should also only be increased if Chrome
+// is compatible with the version it is being incremented to.
+const uint64_t kMaxSupportedCTCompatibilityVersion = 1;
+
 const char kGoogleOperatorName[] = "Google";
 
 // The SHA256 of the SubjectPublicKeyInfo used to sign the extension.
@@ -149,6 +157,11 @@
     return;
   }
 
+  if (proto->log_list().compatibility_version() >
+      kMaxSupportedCTCompatibilityVersion) {
+    return;
+  }
+
   std::vector<network::mojom::CTLogInfoPtr> log_list_mojo;
 
   // The log list shipped via component updater is a single message of CTLogList
diff --git a/chrome/browser/devtools/devtools_browsertest.cc b/chrome/browser/devtools/devtools_browsertest.cc
index 1750a58..d33f6cc 100644
--- a/chrome/browser/devtools/devtools_browsertest.cc
+++ b/chrome/browser/devtools/devtools_browsertest.cc
@@ -13,6 +13,7 @@
 #include "base/compiler_specific.h"
 #include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
+#include "base/files/file_util.h"
 #include "base/location.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/ref_counted.h"
diff --git a/chrome/browser/extensions/api/permissions/permissions_apitest.cc b/chrome/browser/extensions/api/permissions/permissions_apitest.cc
index 2c07b8b..4d7f599 100644
--- a/chrome/browser/extensions/api/permissions/permissions_apitest.cc
+++ b/chrome/browser/extensions/api/permissions/permissions_apitest.cc
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "base/files/file_util.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
diff --git a/chrome/browser/extensions/api/web_request/web_request_apitest.cc b/chrome/browser/extensions/api/web_request/web_request_apitest.cc
index e35a701..0d5eda4 100644
--- a/chrome/browser/extensions/api/web_request/web_request_apitest.cc
+++ b/chrome/browser/extensions/api/web_request/web_request_apitest.cc
@@ -10,6 +10,7 @@
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "base/containers/contains.h"
+#include "base/files/file_util.h"
 #include "base/json/json_reader.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/raw_ptr.h"
diff --git a/chrome/browser/extensions/app_background_page_apitest.cc b/chrome/browser/extensions/app_background_page_apitest.cc
index eed4f2e..049bd57 100644
--- a/chrome/browser/extensions/app_background_page_apitest.cc
+++ b/chrome/browser/extensions/app_background_page_apitest.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include "base/bind.h"
+#include "base/files/file_util.h"
 #include "base/location.h"
 #include "base/memory/raw_ptr.h"
 #include "base/path_service.h"
diff --git a/chrome/browser/extensions/extension_management.cc b/chrome/browser/extensions/extension_management.cc
index cab63771..e26e1b3 100644
--- a/chrome/browser/extensions/extension_management.cc
+++ b/chrome/browser/extensions/extension_management.cc
@@ -31,6 +31,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/themes/theme_service.h"
 #include "chrome/browser/themes/theme_service_factory.h"
+#include "chrome/common/chrome_features.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/common/pref_names.h"
 #include "components/crx_file/id_util.h"
@@ -528,11 +529,15 @@
   if (dict_pref) {
     // Parse new extension management preference.
 
+    bool defer_load_settings = base::FeatureList::IsEnabled(
+        features::kExtensionDeferredIndividualSettings);
     std::unordered_set<std::string> installed_extensions;
-    auto* extension_prefs = ExtensionPrefs::Get(profile_);
-    auto extensions_info = extension_prefs->GetInstalledExtensionsInfo();
-    for (auto& extension_info : *extensions_info)
-      installed_extensions.insert(extension_info->extension_id);
+    if (defer_load_settings) {
+      auto* extension_prefs = ExtensionPrefs::Get(profile_);
+      auto extensions_info = extension_prefs->GetInstalledExtensionsInfo();
+      for (auto& extension_info : *extensions_info)
+        installed_extensions.insert(extension_info->extension_id);
+    }
 
     for (auto iter : dict_pref->DictItems()) {
       if (iter.first == schema_constants::kWildcard)
@@ -565,29 +570,31 @@
             continue;
           }
 
-          auto should_defer = [&extension_id, &installed_extensions](
-                                  const base::Value* subdict,
-                                  const SettingsIdMap* settings_by_id) {
-            // If in legacy force list, don't defer since already have an
-            // entry. This ensures that the entry in these settings matches
-            // the entry in the forcelist. Also don't defer if the extension
-            // is installed.
-            if (base::Contains(*settings_by_id, extension_id) ||
-                base::Contains(installed_extensions, extension_id)) {
-              return false;
-            }
-            auto* install_mode =
-                subdict->FindStringKey(schema_constants::kInstallationMode);
-            if (!install_mode)
-              return true;
-            // Don't defer if the extension needs to be installed.
-            return *install_mode != schema_constants::kForceInstalled &&
-                   *install_mode != schema_constants::kNormalInstalled;
-          };
+          if (defer_load_settings) {
+            auto should_defer = [&extension_id, &installed_extensions](
+                                    const base::Value* subdict,
+                                    const SettingsIdMap* settings_by_id) {
+              // If in legacy force list, don't defer since already have an
+              // entry. This ensures that the entry in these settings matches
+              // the entry in the forcelist. Also don't defer if the extension
+              // is installed.
+              if (base::Contains(*settings_by_id, extension_id) ||
+                  base::Contains(installed_extensions, extension_id)) {
+                return false;
+              }
+              auto* install_mode =
+                  subdict->FindStringKey(schema_constants::kInstallationMode);
+              if (!install_mode)
+                return true;
+              // Don't defer if the extension needs to be installed.
+              return *install_mode != schema_constants::kForceInstalled &&
+                     *install_mode != schema_constants::kNormalInstalled;
+            };
 
-          if (should_defer(subdict, &settings_by_id_)) {
-            deferred_ids_.insert(extension_id);
-            continue;
+            if (should_defer(subdict, &settings_by_id_)) {
+              deferred_ids_.insert(extension_id);
+              continue;
+            }
           }
 
           internal::IndividualSettings* by_id = AccessById(extension_id);
@@ -651,11 +658,11 @@
   // No need to check again later.
   deferred_ids_.erase(extension_id);
 
-  const base::DictionaryValue* extension_settings = nullptr;
   const base::DictionaryValue* dict_pref =
       static_cast<const base::DictionaryValue*>(
           LoadPreference(pref_names::kExtensionManagement, true,
                          base::Value::Type::DICTIONARY));
+  bool found = false;
   for (auto iter : dict_pref->DictItems()) {
     if (iter.first == schema_constants::kWildcard ||
         base::StartsWith(iter.first, schema_constants::kUpdateUrlPrefix,
@@ -669,14 +676,13 @@
     auto extension_ids = base::SplitStringPiece(
         iter.first, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
     if (base::Contains(extension_ids, extension_id)) {
-      // Found our settings!
-      extension_settings = subdict;
-      break;
+      // Found our settings. After parsing, continue looking for more entries.
+      ParseById(extension_id, subdict);
+      found = true;
     }
   }
 
-  DCHECK(extension_settings);
-  ParseById(extension_id, extension_settings);
+  DCHECK(found) << "Couldn't find dictionary for extension in deferred_ids_.";
 }
 
 const base::Value* ExtensionManagement::LoadPreference(
diff --git a/chrome/browser/extensions/extension_management_unittest.cc b/chrome/browser/extensions/extension_management_unittest.cc
index b789cfe..513524f 100644
--- a/chrome/browser/extensions/extension_management_unittest.cc
+++ b/chrome/browser/extensions/extension_management_unittest.cc
@@ -77,6 +77,15 @@
   }
 })";
 
+const char kExampleDictPreferenceWithMultipleEntries[] = R"({
+  "abcdefghijklmnopabcdefghijklmnop,bcdefghijklmnopabcdefghijklmnopa" : {
+    "installation_mode": "blocked",
+  },
+  "bcdefghijklmnopabcdefghijklmnopa,cdefghijklmnopabcdefghijklmnopab" : {
+    "minimum_version_required": "2.0"
+  }
+})";
+
 const char kExampleDictPreference[] =
     R"(
 {
@@ -624,6 +633,16 @@
   EXPECT_EQ(100u, GetPolicyAllowedHosts(kTargetExtension).size());
 }
 
+// Tests that multiple entries for a dictionary are all applied.
+TEST_F(ExtensionManagementServiceTest, MultipleEntries) {
+  SetExampleDictPref(kExampleDictPreferenceWithMultipleEntries);
+
+  EXPECT_EQ(GetInstallationModeById(kTargetExtension2),
+            ExtensionManagement::INSTALLATION_BLOCKED);
+
+  EXPECT_FALSE(CheckMinimumVersion(kTargetExtension2, "1.0"));
+}
+
 // Tests parsing of new dictionary preference.
 TEST_F(ExtensionManagementServiceTest, PreferenceParsing) {
   SetExampleDictPref(kExampleDictPreference);
diff --git a/chrome/browser/extensions/extension_resource_request_policy_apitest.cc b/chrome/browser/extensions/extension_resource_request_policy_apitest.cc
index 4431abee..40a70e0 100644
--- a/chrome/browser/extensions/extension_resource_request_policy_apitest.cc
+++ b/chrome/browser/extensions/extension_resource_request_policy_apitest.cc
@@ -4,6 +4,7 @@
 
 #include "base/command_line.h"
 #include "base/containers/contains.h"
+#include "base/files/file_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/branding_buildflags.h"
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/followmanagement/FollowManagementCoordinator.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/followmanagement/FollowManagementCoordinator.java
index 6b80ffc..d51341b 100644
--- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/followmanagement/FollowManagementCoordinator.java
+++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/followmanagement/FollowManagementCoordinator.java
@@ -19,6 +19,8 @@
 import org.chromium.ui.modelutil.LayoutViewBuilder;
 import org.chromium.ui.modelutil.MVCListAdapter.ModelList;
 import org.chromium.ui.modelutil.SimpleRecyclerViewAdapter;
+import org.chromium.ui.widget.Toast;
+
 /**
  * Sets up the model, adapter, and mediator for FollowManagement surface.  It is based on the doc at
  * https://chromium.googlesource.com/chromium/src/+/HEAD/docs/ui/android/mvc_simple_list_tutorial.md
@@ -60,7 +62,7 @@
         toolbar.setNavigationOnClickListener(this::handleBackArrowClick);
 
         mMediator = new FollowManagementMediator(
-                activity, listItems, WebFeedFaviconFetcher.createDefault());
+                activity, listItems, new MediatorObserver(), WebFeedFaviconFetcher.createDefault());
     }
 
     public View getView() {
@@ -71,4 +73,16 @@
         // Navigate back.
         mActivity.finish();
     }
+
+    private class MediatorObserver implements FollowManagementMediator.Observer {
+        @Override
+        public void networkConnectionError() {
+            Toast.makeText(mActivity, R.string.feed_follow_no_connection_error, Toast.LENGTH_LONG)
+                    .show();
+        }
+        @Override
+        public void otherOperationError() {
+            Toast.makeText(mActivity, R.string.feed_follow_unknown_error, Toast.LENGTH_LONG).show();
+        }
+    }
 }
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/followmanagement/FollowManagementMediator.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/followmanagement/FollowManagementMediator.java
index ec292ac..581c2113047 100644
--- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/followmanagement/FollowManagementMediator.java
+++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/followmanagement/FollowManagementMediator.java
@@ -18,6 +18,7 @@
 import org.chromium.chrome.browser.feed.webfeed.WebFeedBridge;
 import org.chromium.chrome.browser.feed.webfeed.WebFeedBridge.WebFeedMetadata;
 import org.chromium.chrome.browser.feed.webfeed.WebFeedFaviconFetcher;
+import org.chromium.chrome.browser.feed.webfeed.WebFeedSubscriptionRequestStatus;
 import org.chromium.chrome.browser.feed.webfeed.WebFeedSubscriptionStatus;
 import org.chromium.ui.modelutil.MVCListAdapter.ModelList;
 import org.chromium.ui.modelutil.PropertyModel;
@@ -32,15 +33,24 @@
 class FollowManagementMediator {
     private static final String TAG = "FollowManagementMdtr";
     private ModelList mModelList;
+    private Observer mObserver;
     private Context mContext;
     private WebFeedFaviconFetcher mFaviconFetcher;
 
+    public interface Observer {
+        /** An operation failed because there is no network connection. */
+        void networkConnectionError();
+        /** An operation failed for an unknown reason. */
+        void otherOperationError();
+    }
+
     /**
      * Build a FollowManagementMediator.
      */
-    FollowManagementMediator(
-            Context context, ModelList modelList, WebFeedFaviconFetcher faviconFetcher) {
+    FollowManagementMediator(Context context, ModelList modelList, Observer observer,
+            WebFeedFaviconFetcher faviconFetcher) {
         mModelList = modelList;
+        mObserver = observer;
         mContext = context;
         mFaviconFetcher = faviconFetcher;
 
@@ -51,13 +61,13 @@
         mModelList.add(listItem);
 
         // Control flow is to refresh the feeds, then get the feed list, then display it.
-        // TODO(https://.crbug.com/1197286) Add a spinner while waiting for results.
+        // TODO(https://crbug.com/1197286) Add a spinner while waiting for results.
         WebFeedBridge.refreshFollowedWebFeeds(this::getFollowedWebFeeds);
     }
 
     // Once the list of feeds has been refreshed, get the list.
     private void getFollowedWebFeeds(boolean success) {
-        // TODO(https://.crbug.com/1197286) If this fails, show a snackbar with a failure message.
+        // TODO(https://crbug.com/1197286) If this fails, show a snackbar with a failure message.
         WebFeedBridge.getAllFollowedWebFeeds(this::fillRecyclerView);
     }
 
@@ -145,6 +155,7 @@
                     FeedUserActionType.TAPPED_FOLLOW_ON_MANAGEMENT_SURFACE);
             // The lambda will set the item as subscribed if the follow operation succeeds.
             WebFeedBridge.followFromId(id, results -> {
+                reportRequestStatus(results.requestStatus);
                 itemModel.set(FollowManagementItemProperties.SUBSCRIBED_KEY,
                         results.requestStatus == SUCCESS);
                 itemModel.set(FollowManagementItemProperties.CHECKBOX_ENABLED_KEY, true);
@@ -154,6 +165,7 @@
                     FeedUserActionType.TAPPED_UNFOLLOW_ON_MANAGEMENT_SURFACE);
             // The lambda will set the item as unsubscribed if the unfollow operation succeeds.
             WebFeedBridge.unfollow(id, results -> {
+                reportRequestStatus(results.requestStatus);
                 itemModel.set(FollowManagementItemProperties.SUBSCRIBED_KEY,
                         results.requestStatus != SUCCESS);
                 itemModel.set(FollowManagementItemProperties.CHECKBOX_ENABLED_KEY, true);
@@ -163,4 +175,12 @@
         itemModel.set(FollowManagementItemProperties.CHECKBOX_ENABLED_KEY, false);
         itemModel.set(FollowManagementItemProperties.SUBSCRIBED_KEY, !subscribed);
     }
+
+    void reportRequestStatus(@WebFeedSubscriptionRequestStatus int status) {
+        if (status == WebFeedSubscriptionRequestStatus.FAILED_OFFLINE) {
+            mObserver.networkConnectionError();
+        } else if (status != WebFeedSubscriptionRequestStatus.SUCCESS) {
+            mObserver.otherOperationError();
+        }
+    }
 }
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/followmanagement/FollowManagementMediatorTest.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/followmanagement/FollowManagementMediatorTest.java
index adf1e61..af855ba 100644
--- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/followmanagement/FollowManagementMediatorTest.java
+++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/followmanagement/FollowManagementMediatorTest.java
@@ -7,6 +7,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.notNull;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
 import android.app.Activity;
@@ -72,6 +73,8 @@
 
     @Mock
     private FeedServiceBridge.Natives mFeedServiceBridgeJniMock;
+    @Mock
+    private FollowManagementMediator.Observer mObserver;
 
     TestWebFeedFaviconFetcher mFaviconFetcher = new TestWebFeedFaviconFetcher();
 
@@ -84,7 +87,7 @@
         mocker.mock(FeedServiceBridgeJni.TEST_HOOKS, mFeedServiceBridgeJniMock);
 
         mFollowManagementMediator =
-                new FollowManagementMediator(mActivity, mModelList, mFaviconFetcher);
+                new FollowManagementMediator(mActivity, mModelList, mObserver, mFaviconFetcher);
 
         // WebFeedBridge.refreshFollowedWebFeeds() gets called once with non-null pointer to a
         // callback.
@@ -151,6 +154,7 @@
                 new WebFeedBridge.UnfollowResults(WebFeedSubscriptionRequestStatus.FAILED_OFFLINE));
 
         assertEquals("ID1 title=Title1 url=https://www.one.com/ subscribed", modelListToString());
+        verify(mObserver, times(1)).networkConnectionError();
     }
 
     @Test
@@ -191,10 +195,11 @@
 
         verify(mWebFeedBridgeJni).followWebFeedById(eq(ID1), mFollowCallbackCaptor.capture());
         mFollowCallbackCaptor.getValue().onResult(new WebFeedBridge.FollowResults(
-                WebFeedSubscriptionRequestStatus.FAILED_OFFLINE, null));
+                WebFeedSubscriptionRequestStatus.FAILED_UNKNOWN_ERROR, null));
 
         assertEquals(
                 "ID1 title=Title1 url=https://www.one.com/ not-subscribed", modelListToString());
+        verify(mObserver, times(1)).otherOperationError();
     }
 
     @Test
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index 6c40b276f..4ce196dd 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -3219,17 +3219,7 @@
   {
     "name": "font-access",
     "owners": [ "cmp", "pwnall" ],
-    "expiry_milestone": 96
-  },
-  {
-    "name": "font-access-chooser",
-    "owners": [ "pwnall" ],
-    "expiry_milestone": 96
-  },
-  {
-    "name": "font-access-persistent",
-    "owners": [ "pwnall" ],
-    "expiry_milestone": 96
+    "expiry_milestone": 102
   },
   {
     "name": "force-color-profile",
@@ -5396,6 +5386,11 @@
     "expiry_milestone": 100
   },
   {
+    "name": "throttle-foreground-timers",
+    "owners": [ "fdoray", "scheduler-dev" ],
+    "expiry_milestone": 102
+  },
+  {
     "name": "tint-composited-content",
     "owners": [ "chromeos-gfx@google.com" ],
     // This flag is used for QA & development on ChromeOS, which has no way to
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index c16d08aa..a3a8659 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -611,12 +611,6 @@
     "Enables the experimental Font Access APIs, giving websites access "
     "to enumerate local fonts and access their table data.";
 
-const char kFontAccessPersistentName[] =
-    "Enable persistent access to the Font Access API";
-const char kFontAccessPersistentDescription[] =
-    "Enables persistent access to the Font Access API, giving websites access "
-    "to enumerate local fonts after being granted a permission.";
-
 const char kForceColorProfileSRGB[] = "sRGB";
 const char kForceColorProfileP3[] = "Display P3 D65";
 const char kForceColorProfileColorSpin[] = "Color spin with gamma 2.4";
@@ -859,7 +853,7 @@
 const char kDesktopPWAsUrlHandlingDescription[] =
     "Enable web app manifests to declare URL handling behavior. Prototype "
     "implementation of: "
-    "https://github.com/WICG/pwa-url-handler/blob/master/explainer.md";
+    "https://github.com/WICG/pwa-url-handler/blob/main/explainer.md";
 
 const char kDesktopPWAsWindowControlsOverlayName[] =
     "Desktop PWA Window Controls Overlay";
@@ -2419,6 +2413,12 @@
     "this can dramatically hurt scrolling performance of most websites and is "
     "intended for testing purposes only.";
 
+const char kThrottleForegroundTimersName[] =
+    "Throttle Foreground Timers to 30 Hz";
+const char kThrottleForegroundTimersDescription[] =
+    "On foreground pages, run DOM timers with a non-zero delay on a periodic "
+    "30 Hz tick, instead of as soon as their delay has passed.";
+
 const char kThrottleDisplayNoneAndVisibilityHiddenCrossOriginIframesName[] =
     "Throttle non-visible cross-origin iframes";
 const char
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index e78c1ed..d1effc3 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -365,9 +365,6 @@
 extern const char kFontAccessAPIName[];
 extern const char kFontAccessAPIDescription[];
 
-extern const char kFontAccessPersistentName[];
-extern const char kFontAccessPersistentDescription[];
-
 extern const char kForceColorProfileSRGB[];
 extern const char kForceColorProfileP3[];
 extern const char kForceColorProfileColorSpin[];
@@ -1393,6 +1390,9 @@
 extern const char kThreadedScrollingName[];
 extern const char kThreadedScrollingDescription[];
 
+extern const char kThrottleForegroundTimersName[];
+extern const char kThrottleForegroundTimersDescription[];
+
 extern const char
     kThrottleDisplayNoneAndVisibilityHiddenCrossOriginIframesName[];
 extern const char
diff --git a/chrome/browser/font_access/DIR_METADATA b/chrome/browser/font_access/DIR_METADATA
deleted file mode 100644
index be579e9..0000000
--- a/chrome/browser/font_access/DIR_METADATA
+++ /dev/null
@@ -1 +0,0 @@
-mixins: "//content/browser/font_access/COMMON_METADATA"
diff --git a/chrome/browser/font_access/OWNERS b/chrome/browser/font_access/OWNERS
deleted file mode 100644
index 92a7265..0000000
--- a/chrome/browser/font_access/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-file://content/browser/font_access/OWNERS
diff --git a/chrome/browser/font_access/chrome_font_access_delegate.cc b/chrome/browser/font_access/chrome_font_access_delegate.cc
deleted file mode 100644
index 7262851..0000000
--- a/chrome/browser/font_access/chrome_font_access_delegate.cc
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/font_access/chrome_font_access_delegate.h"
-
-#include "chrome/browser/ui/browser_dialogs.h"
-#include "chrome/browser/ui/font_access/font_access_chooser.h"
-#include "chrome/browser/ui/font_access/font_access_chooser_controller.h"
-#include "content/public/browser/render_frame_host.h"
-
-ChromeFontAccessDelegate::ChromeFontAccessDelegate() = default;
-ChromeFontAccessDelegate::~ChromeFontAccessDelegate() = default;
-
-std::unique_ptr<content::FontAccessChooser>
-ChromeFontAccessDelegate::RunChooser(
-    content::RenderFrameHost* frame,
-    const std::vector<std::string>& selection,
-    content::FontAccessChooser::Callback callback) {
-  // TODO(crbug.com/1151464): Decide whether or not to extend/refactor the
-  // bubble view launched by chrome::ShowDeviceChooserDialog() or build a new
-  // one.
-  return std::make_unique<FontAccessChooser>(chrome::ShowDeviceChooserDialog(
-      frame, std::make_unique<FontAccessChooserController>(
-                 frame, selection, std::move(callback))));
-}
diff --git a/chrome/browser/font_access/chrome_font_access_delegate.h b/chrome/browser/font_access/chrome_font_access_delegate.h
deleted file mode 100644
index d7278b9..0000000
--- a/chrome/browser/font_access/chrome_font_access_delegate.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_FONT_ACCESS_CHROME_FONT_ACCESS_DELEGATE_H_
-#define CHROME_BROWSER_FONT_ACCESS_CHROME_FONT_ACCESS_DELEGATE_H_
-
-#include "content/public/browser/font_access_chooser.h"
-#include "content/public/browser/font_access_delegate.h"
-
-class ChromeFontAccessDelegate : public content::FontAccessDelegate {
- public:
-  ChromeFontAccessDelegate();
-  ~ChromeFontAccessDelegate() override;
-
-  ChromeFontAccessDelegate(ChromeFontAccessDelegate&) = delete;
-  ChromeFontAccessDelegate& operator=(ChromeFontAccessDelegate&) = delete;
-
-  std::unique_ptr<content::FontAccessChooser> RunChooser(
-      content::RenderFrameHost* frame,
-      const std::vector<std::string>& selection,
-      content::FontAccessChooser::Callback callback) override;
-};
-
-#endif  // CHROME_BROWSER_FONT_ACCESS_CHROME_FONT_ACCESS_DELEGATE_H_
diff --git a/chrome/browser/font_access/font_access_context_browsertest.cc b/chrome/browser/font_access/font_access_context_browsertest.cc
deleted file mode 100644
index e69c357..0000000
--- a/chrome/browser/font_access/font_access_context_browsertest.cc
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/files/file_path.h"
-#include "base/run_loop.h"
-#include "base/test/bind.h"
-#include "base/test/scoped_feature_list.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/test/base/in_process_browser_test.h"
-#include "chrome/test/base/ui_test_utils.h"
-#include "content/public/browser/font_access_context.h"
-#include "content/public/browser/render_frame_host.h"
-#include "content/public/browser/storage_partition.h"
-#include "content/public/browser/web_contents.h"
-#include "content/public/test/browser_test.h"
-#include "content/public/test/browser_test_utils.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/common/features.h"
-#include "third_party/blink/public/mojom/font_access/font_access.mojom.h"
-
-namespace {
-
-class FontAccessContextBrowserTest : public InProcessBrowserTest {
- public:
-  FontAccessContextBrowserTest() {
-    scoped_feature_list_.InitAndEnableFeature(blink::features::kFontAccess);
-  }
-
- protected:
-  base::test::ScopedFeatureList scoped_feature_list_;
-};
-
-#if defined(PLATFORM_HAS_LOCAL_FONT_ENUMERATION_IMPL)
-
-IN_PROC_BROWSER_TEST_F(FontAccessContextBrowserTest, BasicEnumerationTest) {
-  ASSERT_TRUE(ui_test_utils::NavigateToURL(
-      browser(), ui_test_utils::GetTestUrl(
-                     base::FilePath(),
-                     base::FilePath(FILE_PATH_LITERAL("simple_page.html")))));
-  content::FontAccessContext* context = browser()
-                                            ->tab_strip_model()
-                                            ->GetActiveWebContents()
-                                            ->GetMainFrame()
-                                            ->GetStoragePartition()
-                                            ->GetFontAccessContext();
-
-  base::RunLoop run_loop;
-  context->FindAllFonts(base::BindLambdaForTesting(
-      [&](blink::mojom::FontEnumerationStatus status,
-          std::vector<blink::mojom::FontMetadata> fonts) {
-        EXPECT_EQ(status, blink::mojom::FontEnumerationStatus::kOk)
-            << "Enumeration expected to be successful.";
-        EXPECT_GT(fonts.size(), 0u)
-            << "Enumeration expected to yield at least 1 font";
-        run_loop.Quit();
-      }));
-  run_loop.Run();
-}
-
-#endif
-
-}  // namespace
diff --git a/chrome/browser/lacros/browser_service_lacros.cc b/chrome/browser/lacros/browser_service_lacros.cc
index b3afc4f..91dc695e 100644
--- a/chrome/browser/lacros/browser_service_lacros.cc
+++ b/chrome/browser/lacros/browser_service_lacros.cc
@@ -130,17 +130,13 @@
   Profile* profile = ProfileManager::GetLastUsedProfileAllowedByPolicy();
   DCHECK(profile) << "No last used profile is found.";
 
-  bool session_restore_available = false;
-  if (should_trigger_session_restore) {
-    SessionService* session_service =
-        SessionServiceFactory::GetForProfileForSessionRestore(profile);
-    if (session_service && session_service->ShouldRestore(nullptr))
-      session_restore_available = true;
-  }
-
-  if (ProfilePicker::ShouldShowAtLaunch() && !session_restore_available &&
-      !incognito) {
-    // Profile picker does not support passing through the incognito param.
+  if (ProfilePicker::ShouldShowAtLaunch() && !incognito) {
+    // Profile picker does not support passing through the incognito param. It
+    // also does not support passing though the `should_trigger_session_restore`
+    // param but that's true very common (left clicking the launcher icon) so
+    // we can't skip the picker in this case. The default behavior for the first
+    // browser window supports session restore, additional windows are opened
+    // blank and thus it works reasonably well for BrowserServiceLacros.
     ProfilePicker::Show(
         ProfilePicker::EntryPoint::kNewSessionOnExistingProcess);
   } else {
diff --git a/chrome/browser/lacros/cert_db_initializer_factory.cc b/chrome/browser/lacros/cert_db_initializer_factory.cc
index d408862..a618dc0 100644
--- a/chrome/browser/lacros/cert_db_initializer_factory.cc
+++ b/chrome/browser/lacros/cert_db_initializer_factory.cc
@@ -7,6 +7,7 @@
 #include "base/no_destructor.h"
 #include "base/system/sys_info.h"
 #include "chrome/browser/lacros/cert_db_initializer_impl.h"
+#include "chrome/browser/profiles/incognito_helpers.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chromeos/lacros/lacros_service.h"
@@ -55,3 +56,8 @@
 bool CertDbInitializerFactory::ServiceIsNULLWhileTesting() const {
   return true;
 }
+
+content::BrowserContext* CertDbInitializerFactory::GetBrowserContextToUse(
+    content::BrowserContext* context) const {
+  return chrome::GetBrowserContextOwnInstanceInIncognito(context);
+}
diff --git a/chrome/browser/lacros/cert_db_initializer_factory.h b/chrome/browser/lacros/cert_db_initializer_factory.h
index fd58990..f0bc2df 100644
--- a/chrome/browser/lacros/cert_db_initializer_factory.h
+++ b/chrome/browser/lacros/cert_db_initializer_factory.h
@@ -50,6 +50,8 @@
   KeyedService* BuildServiceInstanceFor(
       content::BrowserContext* context) const override;
   bool ServiceIsNULLWhileTesting() const override;
+  content::BrowserContext* GetBrowserContextToUse(
+      content::BrowserContext* context) const override;
 
   bool should_create_with_browser_context_ = true;
 };
diff --git a/chrome/browser/media/router/discovery/access_code/access_code_cast_discovery_interface.cc b/chrome/browser/media/router/discovery/access_code/access_code_cast_discovery_interface.cc
index 04367095..d017dab 100644
--- a/chrome/browser/media/router/discovery/access_code/access_code_cast_discovery_interface.cc
+++ b/chrome/browser/media/router/discovery/access_code/access_code_cast_discovery_interface.cc
@@ -37,11 +37,12 @@
 constexpr char kGetMethod[] = "GET";
 constexpr char kContentType[] = "application/json; charset=UTF-8";
 constexpr char kDiscoveryOAuth2Scope[] =
-    "https://www.googleapis.com/auth/applicense.bytebot";
+    "https://www.googleapis.com/auth/cast-edu-messaging";
+// TODO(b/215241542): Add a command-line switch to change Cast2Class endpoint
+// URL.
 constexpr char kDiscoveryEndpoint[] =
     "https://castedumessaging-pa.googleapis.com/";
 constexpr char kDiscoveryServicePath[] = "v1/receivers/";
-constexpr char kDiscoveryServiceQuery[] = "?checkOnly=true&access_token=";
 constexpr char kDiscoveryOAuthConsumerName[] = "access_code_cast_discovery";
 constexpr char kEmptyPostData[] = "";
 
@@ -64,10 +65,6 @@
 
 const int64_t kTimeoutMs = 30000;
 
-const GURL GetDiscoveryEndpoint() {
-  return GURL(base::StrCat({kDiscoveryEndpoint, kDiscoveryServicePath}));
-}
-
 const net::NetworkTrafficAnnotationTag kTrafficAnnotation =
     net::DefineNetworkTrafficAnnotation("chrome_cast_discovery_api",
                                         R"(
@@ -131,8 +128,7 @@
     const std::string& access_code)
     : profile_(profile),
       access_code_(access_code),
-      endpoint_fetcher_(CreateEndpointFetcher(access_code)),
-      discovery_url_(GetDiscoveryEndpoint()) {
+      endpoint_fetcher_(CreateEndpointFetcher(access_code)) {
   DCHECK(profile_);
 }
 
@@ -142,8 +138,7 @@
     std::unique_ptr<EndpointFetcher> endpoint_fetcher)
     : profile_(profile),
       access_code_(access_code),
-      endpoint_fetcher_(std::move(endpoint_fetcher)),
-      discovery_url_(GetDiscoveryEndpoint()) {
+      endpoint_fetcher_(std::move(endpoint_fetcher)) {
   DCHECK(profile_);
 }
 
@@ -194,7 +189,7 @@
   return std::make_unique<EndpointFetcher>(
       profile_, kDiscoveryOAuthConsumerName,
       GURL(base::StrCat(
-          {discovery_url_.spec(), access_code, kDiscoveryServiceQuery})),
+          {kDiscoveryEndpoint, kDiscoveryServicePath, access_code})),
       kGetMethod, kContentType, discovery_scopes, kTimeoutMs, kEmptyPostData,
       kTrafficAnnotation);
 }
diff --git a/chrome/browser/media/router/discovery/access_code/access_code_cast_discovery_interface.h b/chrome/browser/media/router/discovery/access_code/access_code_cast_discovery_interface.h
index 9d251f5..ddd927e 100644
--- a/chrome/browser/media/router/discovery/access_code/access_code_cast_discovery_interface.h
+++ b/chrome/browser/media/router/discovery/access_code/access_code_cast_discovery_interface.h
@@ -83,8 +83,6 @@
 
   std::unique_ptr<EndpointFetcher> endpoint_fetcher_;
 
-  const GURL discovery_url_;
-
   DiscoveryDeviceCallback callback_;
 
   base::WeakPtrFactory<AccessCodeCastDiscoveryInterface> weak_ptr_factory_{
diff --git a/chrome/browser/media/webrtc/chrome_camera_pan_tilt_zoom_permission_context_delegate.cc b/chrome/browser/media/webrtc/chrome_camera_pan_tilt_zoom_permission_context_delegate.cc
index c982ce0..23be6e5 100644
--- a/chrome/browser/media/webrtc/chrome_camera_pan_tilt_zoom_permission_context_delegate.cc
+++ b/chrome/browser/media/webrtc/chrome_camera_pan_tilt_zoom_permission_context_delegate.cc
@@ -40,8 +40,6 @@
   // The PTZ permission is automatically granted on Android. It is safe to do so
   // because pan and tilt are not supported on Android.
   *content_setting_result = CONTENT_SETTING_ALLOW;
-  // Suppress unused private field warning on Android.
-  ALLOW_UNUSED_LOCAL(browser_context_);
   return true;
 #elif BUILDFLAG(ENABLE_EXTENSIONS) && BUILDFLAG(IS_CHROMEOS_ASH)
   // Extensions running in kiosk mode that have declared the "videoCapture"
diff --git a/chrome/browser/media/webrtc/chrome_camera_pan_tilt_zoom_permission_context_delegate.h b/chrome/browser/media/webrtc/chrome_camera_pan_tilt_zoom_permission_context_delegate.h
index 450ec6165..bd072e3 100644
--- a/chrome/browser/media/webrtc/chrome_camera_pan_tilt_zoom_permission_context_delegate.h
+++ b/chrome/browser/media/webrtc/chrome_camera_pan_tilt_zoom_permission_context_delegate.h
@@ -33,7 +33,8 @@
   bool IsPermissionGrantedForExtension(const GURL& origin) const;
 #endif
 
-  raw_ptr<content::BrowserContext> browser_context_;
+  // Unused on Android so annotated as [[maybe_unused]].
+  [[maybe_unused]] raw_ptr<content::BrowserContext> browser_context_;
 };
 
 #endif  // CHROME_BROWSER_MEDIA_WEBRTC_CHROME_CAMERA_PAN_TILT_ZOOM_PERMISSION_CONTEXT_DELEGATE_H_
diff --git a/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc b/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc
index 75e5d962..bdc974e 100644
--- a/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc
+++ b/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc
@@ -4,6 +4,7 @@
 
 #include <string>
 
+#include "base/files/file_util.h"
 #include "base/memory/raw_ptr.h"
 #include "base/path_service.h"
 #include "base/strings/strcat.h"
diff --git a/chrome/browser/metrics/chrome_metrics_service_client_unittest.cc b/chrome/browser/metrics/chrome_metrics_service_client_unittest.cc
index 7dc613a..29569ba 100644
--- a/chrome/browser/metrics/chrome_metrics_service_client_unittest.cc
+++ b/chrome/browser/metrics/chrome_metrics_service_client_unittest.cc
@@ -6,7 +6,6 @@
 
 #include <string>
 
-#include "base/compiler_specific.h"
 #include "base/files/file_path.h"
 #include "base/metrics/persistent_histogram_allocator.h"
 #include "base/process/process_handle.h"
@@ -269,16 +268,11 @@
 TEST_F(ChromeMetricsServiceClientTest, GetUploadSigningKey_NotEmpty) {
   std::unique_ptr<ChromeMetricsServiceClient> chrome_metrics_service_client =
       ChromeMetricsServiceClient::Create(metrics_state_manager_.get());
-  const std::string signing_key =
+  [[maybe_unused]] const std::string signing_key =
       chrome_metrics_service_client->GetUploadSigningKey();
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
   // The signing key should never be an empty string for a Chrome-branded build.
   EXPECT_FALSE(signing_key.empty());
-#else
-  // In non-branded builds, we may still have a valid signing key if
-  // USE_OFFICIAL_GOOGLE_API_KEYS is true. However, that macro is not available
-  // in this file.
-  ALLOW_UNUSED_LOCAL(signing_key);
 #endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING)
 }
 
diff --git a/chrome/browser/metrics/extensions_metrics_provider.cc b/chrome/browser/metrics/extensions_metrics_provider.cc
index 7c108429..9853ff8 100644
--- a/chrome/browser/metrics/extensions_metrics_provider.cc
+++ b/chrome/browser/metrics/extensions_metrics_provider.cc
@@ -257,10 +257,8 @@
        ExtensionInstallProto::REINSTALL},
       {extensions::disable_reason::DISABLE_NOT_ALLOWLISTED,
        ExtensionInstallProto::NOT_ALLOWLISTED},
-      // TODO(crbug.com/1268846): Uncomment after ExtensionInstallProto is
-      // updated in third party.
-      // {extensions::disable_reason::DISABLE_NOT_ASH_KEEPLISTED,
-      // ExtensionInstallProto::NOT_ASH_KEEPLISTED},
+      {extensions::disable_reason::DISABLE_NOT_ASH_KEEPLISTED,
+       ExtensionInstallProto::NOT_ASH_KEEPLISTED},
   };
 
   int disable_reasons = prefs->GetDisableReasons(id);
diff --git a/chrome/browser/metrics/thread_watcher_report_hang.cc b/chrome/browser/metrics/thread_watcher_report_hang.cc
index 74e3c69..e950464 100644
--- a/chrome/browser/metrics/thread_watcher_report_hang.cc
+++ b/chrome/browser/metrics/thread_watcher_report_hang.cc
@@ -17,8 +17,7 @@
 // thread was unresponsive. Inhibiting tail calls to this function ensures that
 // the caller will appear on the call stack.
 NOINLINE NOT_TAIL_CALLED void ReportThreadHang() {
-  volatile const char* inhibit_comdat = __func__;
-  ALLOW_UNUSED_LOCAL(inhibit_comdat);
+  [[maybe_unused]] volatile const char* inhibit_comdat = __func__;
 
   // The first 8 characters of sha1 of "ReportThreadHang".
   // echo -n "ReportThreadHang" | sha1sum
@@ -42,28 +41,24 @@
   // TODO(rtenneti): http://crbug.com/440885 enable crashing after fixing false
   // positive startup hang data.
   // ReportThreadHang();
-  volatile int inhibit_comdat = __LINE__;
-  ALLOW_UNUSED_LOCAL(inhibit_comdat);
+  [[maybe_unused]] volatile int inhibit_comdat = __LINE__;
 }
 
 NOINLINE void ShutdownHang() {
   ReportThreadHang();
-  volatile int inhibit_comdat = __LINE__;
-  ALLOW_UNUSED_LOCAL(inhibit_comdat);
+  [[maybe_unused]] volatile int inhibit_comdat = __LINE__;
 }
 
 #endif  // !BUILDFLAG(IS_ANDROID)
 
 NOINLINE void ThreadUnresponsive_UI() {
   ReportThreadHang();
-  volatile int inhibit_comdat = __LINE__;
-  ALLOW_UNUSED_LOCAL(inhibit_comdat);
+  [[maybe_unused]] volatile int inhibit_comdat = __LINE__;
 }
 
 NOINLINE void ThreadUnresponsive_IO() {
   ReportThreadHang();
-  volatile int inhibit_comdat = __LINE__;
-  ALLOW_UNUSED_LOCAL(inhibit_comdat);
+  [[maybe_unused]] volatile int inhibit_comdat = __LINE__;
 }
 
 NOINLINE void CrashBecauseThreadWasUnresponsive(
@@ -80,4 +75,3 @@
 }
 
 }  // namespace metrics
-
diff --git a/chrome/browser/metrics/ukm_browsertest.cc b/chrome/browser/metrics/ukm_browsertest.cc
index c9f5ff8b..26da72a 100644
--- a/chrome/browser/metrics/ukm_browsertest.cc
+++ b/chrome/browser/metrics/ukm_browsertest.cc
@@ -1235,8 +1235,8 @@
       embedded_test_server()->GetURL("/title3.html")};
 
   // Open a blank new tab.
-  AddTabAtIndexToBrowser(sync_browser, 1, GURL(url::kAboutBlankURL),
-                         ui::PAGE_TRANSITION_TYPED, true);
+  ASSERT_TRUE(AddTabAtIndexToBrowser(sync_browser, 1, GURL(url::kAboutBlankURL),
+                                     ui::PAGE_TRANSITION_TYPED, true));
   // Gather source id from the NavigationHandle assigned to navigations that
   // start with the expected URL.
   content::NavigationHandleObserver tab_1_observer(
@@ -1263,8 +1263,8 @@
   EXPECT_FALSE(has_source_id2);
 
   // Navigate to another URL in a new tab.
-  AddTabAtIndexToBrowser(sync_browser, 2, GURL(url::kAboutBlankURL),
-                         ui::PAGE_TRANSITION_TYPED, true);
+  ASSERT_TRUE(AddTabAtIndexToBrowser(sync_browser, 2, GURL(url::kAboutBlankURL),
+                                     ui::PAGE_TRANSITION_TYPED, true));
   content::NavigationHandleObserver tab_2_observer(
       sync_browser->tab_strip_model()->GetActiveWebContents(), test_urls[1]);
   ASSERT_TRUE(ui_test_utils::NavigateToURL(sync_browser, test_urls[1]));
diff --git a/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer.cc
index 5c5ac37..eb4bb75 100644
--- a/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer.cc
+++ b/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer.cc
@@ -137,6 +137,22 @@
   return 0;
 }
 
+// These are the high bounds of each bucket, in enum order. The index into this
+// array is cast to an enum value when recording UKM. These should correspond to
+// the upper bounds of the BitsPerPixelExponential enum in
+// tools/metrics/enums.xml.
+static const double kLCPEntropyBucketThresholds[] = {
+    0.0,  0.00001, 0.0001, 0.001, 0.01, 0.02, 0.03, 0.04,  0.05,   0.06,   0.07,
+    0.08, 0.09,    0.1,    0.2,   0.3,  0.4,  0.5,  0.6,   0.7,    0.8,    0.9,
+    1.0,  2.0,     3.0,    4.0,   5.0,  6.0,  7.0,  8.0,   9.0,    10.0,   20.0,
+    30.0, 40.0,    50.0,   60.0,  70.0, 80.0, 90.0, 100.0, 1000.0, 10000.0};
+
+int64_t CalculateLCPEntropyBucket(double bpp) {
+  return std::lower_bound(std::begin(kLCPEntropyBucketThresholds),
+                          std::end(kLCPEntropyBucketThresholds), bpp) -
+         std::begin(kLCPEntropyBucketThresholds);
+}
+
 }  // namespace
 
 // static
@@ -606,6 +622,13 @@
         all_frames_largest_contentful_paint.Time().value().InMilliseconds());
     builder.SetPaintTiming_LargestContentfulPaintType(
         all_frames_largest_contentful_paint.Type());
+    if (all_frames_largest_contentful_paint.TextOrImage() ==
+        page_load_metrics::ContentfulPaintTimingInfo::
+            LargestContentTextOrImage::kImage) {
+      builder.SetPaintTiming_LargestContentfulPaintBPP(
+          CalculateLCPEntropyBucket(
+              all_frames_largest_contentful_paint.ImageBPP()));
+    }
   }
   const page_load_metrics::ContentfulPaintTimingInfo&
       cross_site_sub_frame_largest_contentful_paint =
diff --git a/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer_unittest.cc
index c3b46bb9..762036f 100644
--- a/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer_unittest.cc
+++ b/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer_unittest.cc
@@ -156,10 +156,12 @@
   // Tests that LCP reports the given |value|,
   // and tests that the LCP content type reported is |text_or_image|. If
   // |test_main_frame| is set, also tests that the main frame LCP histograms
-  // also report |value|.
+  // also report |value|. If |text_or_image| is kText, then tests that image
+  // BPP is not reported, and otherwise tests that it matches |bpp_bucket|.
   void TestLCP(int value,
                LargestContentTextOrImage text_or_image,
-               bool test_main_frame) {
+               bool test_main_frame,
+               uint32_t bpp_bucket = 0) {
     std::map<ukm::SourceId, ukm::mojom::UkmEntryPtr> merged_entries =
         tester()->test_ukm_recorder().GetMergedEntriesByName(
             PageLoad::kEntryName);
@@ -181,6 +183,15 @@
     EXPECT_TRUE(tester()->test_ukm_recorder().EntryHasMetric(
         entry, PageLoad::kPageTiming_ForegroundDurationName));
 
+    if (text_or_image == LargestContentTextOrImage::kText) {
+      EXPECT_FALSE(tester()->test_ukm_recorder().EntryHasMetric(
+          entry, PageLoad::kPaintTiming_LargestContentfulPaintBPPName));
+    } else {
+      tester()->test_ukm_recorder().ExpectEntryMetric(
+          entry, PageLoad::kPaintTiming_LargestContentfulPaintBPPName,
+          bpp_bucket);
+    }
+
     std::map<ukm::SourceId, ukm::mojom::UkmEntryPtr> internal_merged_entries =
         tester()->test_ukm_recorder().GetMergedEntriesByName(
             PageLoad_Internal::kEntryName);
@@ -413,6 +424,7 @@
   timing.paint_timing->largest_contentful_paint->largest_image_paint =
       base::Milliseconds(600);
   timing.paint_timing->largest_contentful_paint->largest_image_paint_size = 50u;
+  timing.paint_timing->largest_contentful_paint->image_bpp = 8.5;
   PopulateExperimentalLCP(timing.paint_timing);
   PopulateRequiredTimingFields(&timing);
 
@@ -422,7 +434,8 @@
   // Simulate closing the tab.
   DeleteContents();
 
-  TestLCP(600, LargestContentTextOrImage::kImage, true /* test_main_frame */);
+  TestLCP(600, LargestContentTextOrImage::kImage, true /* test_main_frame */,
+          30 /* image_bpp = "8.0 - 9.0" */);
 }
 
 TEST_F(UkmPageLoadMetricsObserverTest, LargestImageLoading) {
diff --git a/chrome/browser/performance_monitor/resource_coalition_mac_unittest.mm b/chrome/browser/performance_monitor/resource_coalition_mac_unittest.mm
index ff0686b3..4ac6100 100644
--- a/chrome/browser/performance_monitor/resource_coalition_mac_unittest.mm
+++ b/chrome/browser/performance_monitor/resource_coalition_mac_unittest.mm
@@ -9,7 +9,6 @@
 #include <limits>
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "base/files/file_path.h"
 #include "base/logging.h"
 #include "base/path_service.h"
@@ -80,13 +79,12 @@
 
   base::TimeTicks begin = base::TimeTicks::Now();
   constexpr base::TimeDelta busy_time = base::Seconds(1);
-  volatile double number = 1;
+  [[maybe_unused]] volatile double number = 1;
   while (base::TimeTicks::Now() < (begin + busy_time)) {
     for (int i = 0; i < 10000; ++i) {
       number *= base::RandDouble() / std::numeric_limits<double>::max() * 2;
     }
   }
-  ALLOW_UNUSED_LOCAL(number);
 
   auto sample = coalition.GetDataRate();
   EXPECT_TRUE(sample.has_value());
diff --git a/chrome/browser/policy/cloud/component_cloud_policy_browsertest.cc b/chrome/browser/policy/cloud/component_cloud_policy_browsertest.cc
index df9f9d8..7e280a1 100644
--- a/chrome/browser/policy/cloud/component_cloud_policy_browsertest.cc
+++ b/chrome/browser/policy/cloud/component_cloud_policy_browsertest.cc
@@ -34,7 +34,9 @@
 #include "components/policy/proto/chrome_extension_policy.pb.h"
 #include "components/policy/proto/cloud_policy.pb.h"
 #include "components/policy/proto/device_management_backend.pb.h"
-#include "components/policy/test_support/local_policy_test_server.h"
+#include "components/policy/test_support/client_storage.h"
+#include "components/policy/test_support/embedded_policy_test_server.h"
+#include "components/policy/test_support/policy_storage.h"
 #include "components/signin/public/base/signin_metrics.h"
 #include "content/public/test/browser_test.h"
 #include "content/public/test/test_utils.h"
@@ -99,8 +101,8 @@
 
 class ComponentCloudPolicyTest : public extensions::ExtensionBrowserTest {
  protected:
-  ComponentCloudPolicyTest() {}
-  ~ComponentCloudPolicyTest() override {}
+  ComponentCloudPolicyTest() = default;
+  ~ComponentCloudPolicyTest() override = default;
 
   void SetUpCommandLine(base::CommandLine* command_line) override {
     extensions::ExtensionBrowserTest::SetUpCommandLine(command_line);
@@ -118,10 +120,17 @@
   }
 
   void SetUpInProcessBrowserTestFixture() override {
-    test_server_.RegisterClient(kDMToken, kDeviceID, {} /* state_keys */);
-    EXPECT_TRUE(test_server_.UpdatePolicyData(
-        dm_protocol::kChromeExtensionPolicyType, kTestExtension, kTestPolicy));
+    ClientStorage::ClientInfo client_info;
+    client_info.device_id = kDeviceID;
+    client_info.device_token = kDMToken;
+    client_info.allowed_policy_types = {
+        policy::dm_protocol::kChromeExtensionPolicyType,
+        policy::dm_protocol::kChromeUserPolicyType,
+    };
+    test_server_.client_storage()->RegisterClient(client_info);
     ASSERT_TRUE(test_server_.Start());
+    test_server_.UpdateExternalPolicy(dm_protocol::kChromeExtensionPolicyType,
+                                      kTestExtension, kTestPolicy);
 
     std::string url = test_server_.GetServiceURL().spec();
     base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
@@ -239,7 +248,7 @@
     run_loop.Run();
   }
 
-  LocalPolicyTestServer test_server_;
+  EmbeddedPolicyTestServer test_server_;
   scoped_refptr<const extensions::Extension> extension_;
   std::unique_ptr<ExtensionTestMessageListener> event_listener_;
   raw_ptr<CloudPolicyClient> client_ = nullptr;
@@ -276,8 +285,8 @@
   event_listener_ =
       std::make_unique<ExtensionTestMessageListener>("event", true);
   policy_listener.Reply("idle");
-  EXPECT_TRUE(test_server_.UpdatePolicyData(
-      dm_protocol::kChromeExtensionPolicyType, kTestExtension, kTestPolicy2));
+  test_server_.UpdateExternalPolicy(dm_protocol::kChromeExtensionPolicyType,
+                                    kTestExtension, kTestPolicy2);
   RefreshPolicies();
 
   // Check that the update event was received, and verify the new policy
@@ -304,8 +313,8 @@
   event_listener_->Reply("idle");
   event_listener_.reset();
 
-  EXPECT_TRUE(test_server_.UpdatePolicyData(
-      dm_protocol::kChromeExtensionPolicyType, kTestExtension2, kTestPolicy2));
+  test_server_.UpdateExternalPolicy(dm_protocol::kChromeExtensionPolicyType,
+                                    kTestExtension2, kTestPolicy2);
   // Installing a new extension doesn't trigger another policy fetch because
   // the server always sends down the list of all extensions that have policy.
   // Fetch now that the configuration has been updated and before installing
@@ -400,7 +409,7 @@
 class KeyRotationComponentCloudPolicyTest : public ComponentCloudPolicyTest {
  protected:
   void SetUpInProcessBrowserTestFixture() override {
-    test_server_.EnableAutomaticRotationOfSigningKeys();
+    test_server_.policy_storage()->signature_provider()->set_rotate_keys(true);
     ComponentCloudPolicyTest::SetUpInProcessBrowserTestFixture();
   }
 
@@ -437,8 +446,8 @@
   event_listener_ =
       std::make_unique<ExtensionTestMessageListener>("event", true);
   policy_listener.Reply("idle");
-  EXPECT_TRUE(test_server_.UpdatePolicyData(
-      dm_protocol::kChromeExtensionPolicyType, kTestExtension, kTestPolicy2));
+  test_server_.UpdateExternalPolicy(dm_protocol::kChromeExtensionPolicyType,
+                                    kTestExtension, kTestPolicy2);
   RefreshPolicies();
 
   // Check that the update event was received, and verify that the policy has
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
index b3b85ff..5dad1ad 100644
--- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc
+++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -772,6 +772,9 @@
   { key::kNTPCardsVisible,
     prefs::kNtpModulesVisible,
     base::Value::Type::BOOLEAN },
+  { key::kNTPMiddleSlotAnnouncementVisible,
+    prefs::kNtpPromoVisible,
+    base::Value::Type::BOOLEAN },
   { key::kPromotionalTabsEnabled,
     prefs::kPromotionalTabsEnabled,
     base::Value::Type::BOOLEAN },
diff --git a/chrome/browser/printing/print_browsertest.cc b/chrome/browser/printing/print_browsertest.cc
index cb024d1..369f466 100644
--- a/chrome/browser/printing/print_browsertest.cc
+++ b/chrome/browser/printing/print_browsertest.cc
@@ -934,6 +934,25 @@
   EXPECT_EQ(new_height, 0);
 }
 
+IN_PROC_BROWSER_TEST_F(PrintBrowserTest, LazyLoadedImagesFetched) {
+  ASSERT_TRUE(embedded_test_server()->Started());
+  GURL url(embedded_test_server()->GetURL(
+      "/printing/lazy-loaded-image-offscreen.html"));
+  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
+
+  auto* contents = browser()->tab_strip_model()->GetActiveWebContents();
+  const char kExpression[] = "target.offsetHeight";
+
+  double old_height = content::EvalJs(contents, kExpression).ExtractDouble();
+
+  PrintAndWaitUntilPreviewIsReady();
+
+  // The non-printed document should have loaded the image, which will have
+  // a different height.
+  double new_height = content::EvalJs(contents, kExpression).ExtractDouble();
+  EXPECT_NE(old_height, new_height);
+}
+
 // Before invoking print preview, page scale is changed to a different value.
 // Test that when print preview is ready, in other words when printing is
 // finished, the page scale factor gets reset to initial scale.
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation.js b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation.js
index 5de65f5..0643442 100644
--- a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation.js
+++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation.js
@@ -15,6 +15,7 @@
 const StopEvent = chrome.speechRecognitionPrivate.SpeechRecognitionStopEvent;
 const SpeechRecognitionType =
     chrome.speechRecognitionPrivate.SpeechRecognitionType;
+const IconType = chrome.accessibilityPrivate.DictationBubbleIconType;
 
 /**
  * Main class for the Chrome OS dictation feature.
@@ -382,7 +383,8 @@
     // although SODA does not seem to do that. The newline character looks wrong
     // here.
     this.interimText_ = text;
-    this.inputController_.showBubble(this.interimText_);
+    this.inputController_.showBubble(
+        /*icon=*/ IconType.HIDDEN, /*text=*/ this.interimText_);
     if (this.clearUITextTimeoutId_) {
       clearTimeout(this.clearUITextTimeoutId_);
       this.clearUITextTimeoutId_ = null;
@@ -400,7 +402,7 @@
     }
 
     this.interimText_ = '';
-    this.inputController_.showBubble();
+    this.inputController_.showBubble(/*icon=*/ IconType.STANDBY);
     if (this.clearUITextTimeoutId_) {
       clearTimeout(this.clearUITextTimeoutId_);
       this.clearUITextTimeoutId_ = null;
@@ -428,7 +430,8 @@
       return;
     }
     this.interimText_ = '';
-    this.inputController_.showBubble('☑' + transcript);
+    this.inputController_.showBubble(
+        /*icon=*/ IconType.MACRO_SUCCESS, /*text=*/ transcript);
     this.clearUITextTimeoutId_ = setTimeout(
         () => this.clearInterimText_(),
         Dictation.Timeouts.SHOW_COMMAND_MESSAGE_MS);
@@ -454,7 +457,9 @@
 
     this.interimText_ = '';
     // TODO(crbug.com/1252037): Finalize string and internationalization.
-    this.inputController_.showBubble(`ⓘ Failed to execute: ` + transcript);
+    this.inputController_.showBubble(
+        /*icon=*/ IconType.MACRO_FAIL,
+        /*text=*/ `Failed to run command: ` + transcript);
     this.clearUITextTimeoutId_ = setTimeout(
         () => this.clearInterimText_(),
         Dictation.Timeouts.SHOW_COMMAND_MESSAGE_MS);
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/input_controller.js b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/input_controller.js
index 163d6cc8b..c404bfe3 100644
--- a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/input_controller.js
+++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/input_controller.js
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+const IconType = chrome.accessibilityPrivate.DictationBubbleIconType;
+
 /**
  * InputController handles interaction with input fields for Dictation.
  */
@@ -134,15 +136,18 @@
 
   /**
    * Shows the bubble UI with the given text.
+   * @param {!IconType} icon
    * @param {string=} text
    */
-  showBubble(text) {
-    chrome.accessibilityPrivate.updateDictationBubble(/*visible=*/ true, text);
+  showBubble(icon, text) {
+    chrome.accessibilityPrivate.updateDictationBubble(
+        {visible: true, icon, text});
   }
 
   /** Hides the bubble UI. */
   hideBubble() {
-    chrome.accessibilityPrivate.updateDictationBubble(/*visible=*/ false);
+    chrome.accessibilityPrivate.updateDictationBubble(
+        {visible: false, icon: IconType.HIDDEN});
   }
 
   /**
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/background_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/background_test.js
index 8b5247b..5189b49 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/background_test.js
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/background_test.js
@@ -2143,12 +2143,12 @@
   const mockFeedback = this.createMockFeedback();
   const site = `
     <h3><a href="#a">inner</a></h3>
-    <p aria-invalid="spelling">some txet</p>
+    <p>some <span aria-invalid="spelling">txet</span></p>
     <button>button A</button>
     <p aria-invalid="true">some other reason</p>
     <p>no error text 1</P>
     <p aria-invalid=false>no error text 2</P>
-    <p aria-invalid="grammar">this are a text</p>
+    <p><span aria-invalid="grammar">this are</span> a test</span></p>
     <p aria-invalid="unknown">error is this</p>
     <a href="#b">outer1</a>
     <h3>outer2</h3>
@@ -2159,21 +2159,21 @@
         RoleType.LINK, ChromeVoxState.instance.currentRange.start.node.role);
     assertEquals('inner', ChromeVoxState.instance.currentRange.start.node.name);
     mockFeedback.call(doCmd('nextInvalidItem'))
-        .expectSpeech('some txet', 'misspelled')
+        .expectSpeech('txet', 'misspelled')
         .call(doCmd('nextInvalidItem'))
         .expectSpeech('some other reason')
         .call(doCmd('nextInvalidItem'))
-        .expectSpeech('this are a text', 'grammar error')
+        .expectSpeech('this are', 'grammar error')
         .call(doCmd('nextInvalidItem'))
         .expectSpeech('error is this')
         // Ensure wrap.
         .call(doCmd('nextInvalidItem'))
-        .expectSpeech('some txet')
+        .expectSpeech('txet')
         // Wrap backward.
         .call(doCmd('previousInvalidItem'))
         .expectSpeech('error is this')
         .call(doCmd('previousInvalidItem'))
-        .expectSpeech('this are a text', 'grammar error');
+        .expectSpeech('this are', 'grammar error');
 
     mockFeedback.replay();
   });
diff --git a/chrome/browser/resources/chromeos/accessibility/common/automation_predicate.js b/chrome/browser/resources/chromeos/accessibility/common/automation_predicate.js
index bc10535..c7ca920 100644
--- a/chrome/browser/resources/chromeos/accessibility/common/automation_predicate.js
+++ b/chrome/browser/resources/chromeos/accessibility/common/automation_predicate.js
@@ -228,7 +228,9 @@
    * @return {boolean}
    */
   static isInvalid(node) {
-    return node.invalidState === InvalidState.TRUE;
+    return node.invalidState === InvalidState.TRUE ||
+        AutomationPredicate.hasInvalidGrammarMarker(node) ||
+        AutomationPredicate.hasInvalidSpellingMarker(node);
   }
 
 
diff --git a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_css.html b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_css.html
index 68ffbd3..40816e1 100644
--- a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_css.html
+++ b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_css.html
@@ -205,7 +205,7 @@
     }
 
     .secondary {
-      color: var(--google-grey-refresh-700);
+      color: var(--google-grey-700);
       font-weight: 400;
     }
 
diff --git a/chrome/browser/resources/extensions/extensions.ts b/chrome/browser/resources/extensions/extensions.ts
index 378090e6..67185bb 100644
--- a/chrome/browser/resources/extensions/extensions.ts
+++ b/chrome/browser/resources/extensions/extensions.ts
@@ -7,12 +7,14 @@
 export {getToastManager} from 'chrome://resources/cr_elements/cr_toast/cr_toast_manager.js';
 export {ActivityLogPageState} from './activity_log/activity_log_history.js';
 export {ARG_URL_PLACEHOLDER} from './activity_log/activity_log_stream_item.js';
+export {ItemDelegate} from './item.js';
 export {UserAction} from './item_util.js';
 // <if expr="chromeos">
-export {KioskBrowserProxyImpl} from './kiosk_browser_proxy.js';
+export {KioskAppSettings, KioskBrowserProxy, KioskBrowserProxyImpl, KioskSettings} from './kiosk_browser_proxy.js';
 // </if>
 export {Dialog, navigation, NavigationHelper, Page} from './navigation_helper.js';
 export {OptionsDialogMaxHeight, OptionsDialogMinWidth} from './options_dialog.js';
 export {getPatternFromSite} from './runtime_hosts_dialog.js';
-export {Service} from './service.js';
+export {Service, ServiceInterface} from './service.js';
 export {isValidKeyCode, Key, keystrokeToString} from './shortcut_util.js';
+export {ExtensionsToggleRowElement} from './toggle_row.js';
diff --git a/chrome/browser/resources/extensions/kiosk_browser_proxy.ts b/chrome/browser/resources/extensions/kiosk_browser_proxy.ts
index 83f1daf..cb10652 100644
--- a/chrome/browser/resources/extensions/kiosk_browser_proxy.ts
+++ b/chrome/browser/resources/extensions/kiosk_browser_proxy.ts
@@ -9,7 +9,7 @@
 
 import {sendWithPromise} from 'chrome://resources/js/cr.m.js';
 
-type KioskSettings = {
+export type KioskSettings = {
   kioskEnabled: boolean,
   autoLaunchEnabled: boolean,
 };
diff --git a/chrome/browser/resources/extensions/service.ts b/chrome/browser/resources/extensions/service.ts
index 232415c..e29c3a3 100644
--- a/chrome/browser/resources/extensions/service.ts
+++ b/chrome/browser/resources/extensions/service.ts
@@ -15,10 +15,14 @@
 import {PackDialogDelegate} from './pack_dialog.js';
 import {ToolbarDelegate} from './toolbar.js';
 
-export class Service implements ActivityLogDelegate, ActivityLogEventDelegate,
-                                ErrorPageDelegate, ItemDelegate,
-                                KeyboardShortcutDelegate, LoadErrorDelegate,
-                                PackDialogDelegate, ToolbarDelegate {
+export interface ServiceInterface extends ActivityLogDelegate,
+                                          ActivityLogEventDelegate,
+                                          ErrorPageDelegate, ItemDelegate,
+                                          KeyboardShortcutDelegate,
+                                          LoadErrorDelegate, PackDialogDelegate,
+                                          ToolbarDelegate {}
+
+export class Service implements ServiceInterface {
   private isDeleting_: boolean = false;
   private eventsToIgnoreOnce_: Set<string> = new Set();
 
@@ -301,8 +305,7 @@
     chrome.developerPrivate.packDirectory(rootPath, keyPath, flag, callback);
   }
 
-  updateAllExtensions(extensions: chrome.developerPrivate.ExtensionInfo[]):
-      Promise<string> {
+  updateAllExtensions(extensions: chrome.developerPrivate.ExtensionInfo[]) {
     /**
      * Attempt to reload local extensions. If an extension fails to load, the
      * user is prompted to try updating the broken extension using loadUnpacked
@@ -313,7 +316,7 @@
              chrome.metricsPrivate.recordUserAction('Options_UpdateExtensions');
            })
         .then(() => {
-          return new Promise((resolve, reject) => {
+          return new Promise<void>((resolve, reject) => {
             const loadLocalExtensions = async () => {
               for (const extension of extensions) {
                 if (extension.location === 'UNPACKED') {
@@ -325,7 +328,7 @@
                   }
                 }
               }
-              resolve('Loaded local extensions.');
+              resolve();
             };
             loadLocalExtensions();
           });
diff --git a/chrome/browser/resources/extensions/toggle_row.ts b/chrome/browser/resources/extensions/toggle_row.ts
index 3b84cc34..188d2f9 100644
--- a/chrome/browser/resources/extensions/toggle_row.ts
+++ b/chrome/browser/resources/extensions/toggle_row.ts
@@ -88,5 +88,11 @@
   }
 }
 
+declare global {
+  interface HTMLElementTagNameMap {
+    'extensions-toggle-row': ExtensionsToggleRowElement;
+  }
+}
+
 customElements.define(
     ExtensionsToggleRowElement.is, ExtensionsToggleRowElement);
diff --git a/chrome/browser/resources/extensions/toolbar.ts b/chrome/browser/resources/extensions/toolbar.ts
index e45bb84..7f38b08 100644
--- a/chrome/browser/resources/extensions/toolbar.ts
+++ b/chrome/browser/resources/extensions/toolbar.ts
@@ -27,7 +27,7 @@
 
   /** Updates all extensions. */
   updateAllExtensions(extensions: chrome.developerPrivate.ExtensionInfo[]):
-      Promise<string>;
+      Promise<void>;
 }
 
 interface ExtensionsToolbarElement {
diff --git a/chrome/browser/resources/new_tab_page_third_party/new_tab_page_third_party.html b/chrome/browser/resources/new_tab_page_third_party/new_tab_page_third_party.html
index 7e6f5ad..36ba21b 100644
--- a/chrome/browser/resources/new_tab_page_third_party/new_tab_page_third_party.html
+++ b/chrome/browser/resources/new_tab_page_third_party/new_tab_page_third_party.html
@@ -18,7 +18,7 @@
 
       @media (prefers-color-scheme: dark) {
         html {
-          --ntp-focus-shadow-color: rgba(var(--google-blue-refresh-300-rgb), .5);
+          --ntp-focus-shadow-color: rgba(var(--google-blue-300-rgb), .5);
           --ntp-theme-text-color: white;
         }
       }
diff --git a/chrome/browser/resources/ntp4/incognito_and_guest_tab.css b/chrome/browser/resources/ntp4/incognito_and_guest_tab.css
index 5d9d7a7..4421f93 100644
--- a/chrome/browser/resources/ntp4/incognito_and_guest_tab.css
+++ b/chrome/browser/resources/ntp4/incognito_and_guest_tab.css
@@ -48,7 +48,7 @@
 
 @media (prefers-color-scheme: dark) {
   :-webkit-any(a, .learn-more-button) {
-    color: rgb(138, 180, 248);  /* --google-blue-refresh-300 */
+    color: rgb(138, 180, 248);  /* --google-blue-300 */
   }
 }
 
diff --git a/chrome/browser/resources/read_later/app.html b/chrome/browser/resources/read_later/app.html
index 3e5f31c9..873081b 100644
--- a/chrome/browser/resources/read_later/app.html
+++ b/chrome/browser/resources/read_later/app.html
@@ -103,13 +103,13 @@
   }
 
   :host([side-panel]) .hr {
-    border-top: 1px solid var(--google-grey-refresh-300);
+    border-top: 1px solid var(--google-grey-300);
     margin-block-start: 8px;
   }
 
   @media (prefers-color-scheme: dark) {
     :host([side-panel]) .hr {
-      border-top: 1px solid var(--google-grey-refresh-700);
+      border-top: 1px solid var(--google-grey-700);
     }
   }
 
diff --git a/chrome/browser/resources/read_later/side_panel/app.html b/chrome/browser/resources/read_later/side_panel/app.html
index c050cde4..22654a7 100644
--- a/chrome/browser/resources/read_later/side_panel/app.html
+++ b/chrome/browser/resources/read_later/side_panel/app.html
@@ -9,14 +9,14 @@
   }
 
   header {
-    border-bottom: solid 1px var(--google-grey-refresh-300);
+    border-bottom: solid 1px var(--google-grey-300);
     display: flex;
     padding-block-start: 4px;
   }
 
   @media (prefers-color-scheme: dark) {
     header {
-      border-bottom: solid 1px var(--google-grey-refresh-700);
+      border-bottom: solid 1px var(--google-grey-700);
     }
   }
 
diff --git a/chrome/browser/resources/read_later/side_panel/bookmark_folder.html b/chrome/browser/resources/read_later/side_panel/bookmark_folder.html
index 5ccf8a7..ecb2422 100644
--- a/chrome/browser/resources/read_later/side_panel/bookmark_folder.html
+++ b/chrome/browser/resources/read_later/side_panel/bookmark_folder.html
@@ -142,7 +142,7 @@
 
   [drop-position='above']::after,
   [drop-position='below']::after {
-    background: var(--google-blue-refresh-500);
+    background: var(--google-blue-500);
     content: '';
     display: block;
     height: 2px;
diff --git a/chrome/browser/resources/read_later/side_panel/bookmarks_list.ts b/chrome/browser/resources/read_later/side_panel/bookmarks_list.ts
index 0792911..89cbdbb 100644
--- a/chrome/browser/resources/read_later/side_panel/bookmarks_list.ts
+++ b/chrome/browser/resources/read_later/side_panel/bookmarks_list.ts
@@ -276,7 +276,7 @@
     event.preventDefault();
     const eventTarget = event.composedPath()[0] as HTMLElement;
     const bookmarkData = getBookmarkFromElement(eventTarget);
-    if (!bookmarkData) {
+    if (!bookmarkData || !eventTarget.matches(':focus-visible')) {
       return;
     }
 
diff --git a/chrome/browser/resources/read_later/side_panel/reader_mode/app.ts b/chrome/browser/resources/read_later/side_panel/reader_mode/app.ts
index dec3b2b..9aff43ac 100644
--- a/chrome/browser/resources/read_later/side_panel/reader_mode/app.ts
+++ b/chrome/browser/resources/read_later/side_panel/reader_mode/app.ts
@@ -5,16 +5,14 @@
 import '../../strings.m.js';
 
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
-import {WebUIListenerBehavior} from 'chrome://resources/js/web_ui_listener_behavior.m.js';
-import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {WebUIListenerMixin} from 'chrome://resources/js/web_ui_listener_mixin.js';
+import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {ReadLaterApiProxy, ReadLaterApiProxyImpl} from '../../read_later_api_proxy.js';
 
 import {ReaderModeApiProxy} from './reader_mode_api_proxy.js';
 
-const ReaderModeElementBase =
-    mixinBehaviors([WebUIListenerBehavior], PolymerElement) as
-    {new (): PolymerElement & WebUIListenerBehavior};
+const ReaderModeElementBase = WebUIListenerMixin(PolymerElement);
 
 export class ReaderModeElement extends ReaderModeElementBase {
   static get is() {
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/supported_links_item.html b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/supported_links_item.html
index a2eb1a8..f246084 100644
--- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/supported_links_item.html
+++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/supported_links_item.html
@@ -1,5 +1,5 @@
 <style include="app-management-cros-shared-css settings-shared">
-  #explanation-text {
+  #disabled-explanation-text {
     align-items: center;
     display: flex;
     flex-direction: row;
@@ -22,7 +22,7 @@
   </localized-link>
 </div>
 <template is="dom-if" if="[[disabled_]]">
-  <span class="info-text-row">
+  <span class="info-text-row" id="disabled-explanation-text">
     <iron-icon id="info-icon" icon="app-management:info"></iron-icon>
     <localized-link id="info-string"
       localized-string="[[getDisabledExplanation_(app)]]">
diff --git a/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.html b/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.html
index 28062a4..88154190 100644
--- a/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.html
+++ b/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.html
@@ -194,13 +194,13 @@
   }
 
   #removeConfirmationButton {
-    --active-shadow-action-rgb: var(--google-red-refresh-500-rgb);
+    --active-shadow-action-rgb: var(--google-red-500-rgb);
     --bg-action: var(--google-red-600);
     --focus-shadow-color: rgba(var(--google-red-600-rgb), .4);
     --hover-bg-action: rgba(var(--google-red-600-rgb), .9);
-    --hover-shadow-action-rgb: var(--google-red-refresh-500-rgb);
+    --hover-shadow-action-rgb: var(--google-red-500-rgb);
     --hover-border-color: var(--google-red-100);
-    --hover-shadow-action-rgb: var(--google-red-refresh-500-rgb);
+    --hover-shadow-action-rgb: var(--google-red-500-rgb);
   }
 </style>
 <!-- Account management description -->
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_review/privacy_review_page.ts b/chrome/browser/resources/settings/privacy_page/privacy_review/privacy_review_page.ts
index 5b76312..0f84064 100644
--- a/chrome/browser/resources/settings/privacy_page/privacy_review/privacy_review_page.ts
+++ b/chrome/browser/resources/settings/privacy_page/privacy_review/privacy_review_page.ts
@@ -396,7 +396,8 @@
       }
     } else {
       if (this.animationsEnabled_ && playAnimation) {
-        this.$.viewManager.switchView(this.privacyReviewStep_);
+        this.$.viewManager.switchView(
+            this.privacyReviewStep_, 'slide-in-fade-in', 'no-animation');
       } else {
         this.$.viewManager.switchView(
             this.privacyReviewStep_, 'no-animation', 'no-animation');
diff --git a/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.html b/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.html
index b0d14eb..5ca35ed5 100644
--- a/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.html
+++ b/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.html
@@ -107,14 +107,14 @@
                     </div>
                     <div class="user-name">[[item.userName]]</div>
                     <cr-icon-button iron-icon="settings:create"
-                        aria-label$="$i18n{edit}"
+                        aria-label="$i18n{edit}"
                         class="edit-button"
                         on-click="onUpdateButtonClick_"
                         hidden="[[!editButtonVisible_]]"
                         data-credentialid$="[[item.credentialId]]">
                     </cr-icon-button>
                     <cr-icon-button iron-icon="cr:delete"
-                        aria-label$="$i18n{delete}"
+                        aria-label="$i18n{delete}"
                         class="delete-button"
                         on-click="onDeleteButtonClick_"
                         data-credentialid$="[[item.credentialId]]">
diff --git a/chrome/browser/resources/signin/enterprise_profile_welcome/enterprise_profile_welcome_app.html b/chrome/browser/resources/signin/enterprise_profile_welcome/enterprise_profile_welcome_app.html
index 1f46222..2ab226d 100644
--- a/chrome/browser/resources/signin/enterprise_profile_welcome/enterprise_profile_welcome_app.html
+++ b/chrome/browser/resources/signin/enterprise_profile_welcome/enterprise_profile_welcome_app.html
@@ -117,7 +117,7 @@
     align-items: center;
     border: 1px solid var(--google-grey-200);
     border-radius: 8px;
-    color: var(--google-grey-refresh-700);
+    color: var(--google-grey-700);
     display: flex;
     flex-direction: row;
     margin-inline: var(--info-box-margin-inline);
@@ -136,7 +136,7 @@
   .icon-container {
     --icon-container-size: 28px;
     --icon-container-margin: 16px;
-    background-color: var(--google-grey-refresh-100);
+    background-color: var(--google-grey-100);
     border-radius: 50%;
     height: var(--icon-container-size);
     margin-inline: var(--icon-container-margin);
@@ -171,11 +171,11 @@
 
     .info-box {
       border-color: var(--google-grey-600);
-      color: var(--google-grey-refresh-100);
+      color: var(--google-grey-100);
     }
 
     .icon-container {
-      background-color: var(--google-grey-refresh-700);
+      background-color: var(--google-grey-700);
     }
   }
 </style>
diff --git a/chrome/browser/resources/signin/profile_picker/profile_card.html b/chrome/browser/resources/signin/profile_picker/profile_card.html
index e196cdf..8429baa 100644
--- a/chrome/browser/resources/signin/profile_picker/profile_card.html
+++ b/chrome/browser/resources/signin/profile_picker/profile_card.html
@@ -45,7 +45,7 @@
   }
 
   iron-icon {
-    --iron-icon-fill-color: var(--google-grey-refresh-700);
+    --iron-icon-fill-color: var(--google-grey-700);
   }
 
   #forceSigninContainer {
@@ -72,7 +72,7 @@
   }
 
   #hoverUnderline {
-    border-bottom: 2px solid var(--google-grey-refresh-300);
+    border-bottom: 2px solid var(--google-grey-300);
     border-radius: 0;
     height: 0;
     left: 0;
@@ -114,7 +114,7 @@
     }
 
     #hoverUnderline {
-      border-color: var(--google-grey-refresh-700);
+      border-color: var(--google-grey-700);
     }
   }
 </style>
diff --git a/chrome/browser/resources/signin/profile_picker/profile_card_menu.html b/chrome/browser/resources/signin/profile_picker/profile_card_menu.html
index e0a20a09..97b3233 100644
--- a/chrome/browser/resources/signin/profile_picker/profile_card_menu.html
+++ b/chrome/browser/resources/signin/profile_picker/profile_card_menu.html
@@ -49,7 +49,7 @@
 
   #removeActionDialogBody {
     align-items: center;
-    border: 1px solid var(--google-grey-refresh-100);
+    border: 1px solid var(--google-grey-100);
     border-radius: 12px;
     box-sizing: border-box;
     display: flex;
@@ -100,18 +100,18 @@
 
   .count {
     align-self: center;
-    color: var(--google-grey-refresh-500);
+    color: var(--google-grey-500);
     text-align: end;
   }
 
   #removeConfirmationButton {
-    --active-shadow-action-rgb: var(--google-red-refresh-500-rgb);
+    --active-shadow-action-rgb: var(--google-red-500-rgb);
     --bg-action: var(--google-red-600);
     --focus-shadow-color: rgba(var(--google-red-600-rgb), .4);
     --hover-bg-action: rgba(var(--google-red-600-rgb), .9);
-    --hover-shadow-action-rgb: var(--google-red-refresh-500-rgb);
+    --hover-shadow-action-rgb: var(--google-red-500-rgb);
     --hover-border-color: var(--google-red-100);
-    --hover-shadow-action-rgb: var(--google-red-refresh-500-rgb);
+    --hover-shadow-action-rgb: var(--google-red-500-rgb);
   }
 
 
@@ -129,12 +129,12 @@
     }
 
     #removeActionDialogBody {
-      border-color: var(--google-grey-refresh-700);
+      border-color: var(--google-grey-700);
     }
 
     #removeConfirmationButton {
-      --bg-action: var(--google-red-refresh-300);
-      --focus-shadow-color: rgba(var(--google-red-refresh-300-rgb), .5);
+      --bg-action: var(--google-red-300);
+      --focus-shadow-color: rgba(var(--google-red-300-rgb), .5);
       --hover-bg-action: var(--bg-action)
           linear-gradient(rgba(0, 0, 0, .08), rgba(0, 0, 0, .08));
     }
diff --git a/chrome/browser/resources/signin/profile_picker/profile_creation_flow/account_selection_lacros.html b/chrome/browser/resources/signin/profile_picker/profile_creation_flow/account_selection_lacros.html
index 249768a..1284583 100644
--- a/chrome/browser/resources/signin/profile_picker/profile_creation_flow/account_selection_lacros.html
+++ b/chrome/browser/resources/signin/profile_picker/profile_creation_flow/account_selection_lacros.html
@@ -107,7 +107,7 @@
 
     #accountsContainer {
       background-color: var(--md-background-color);
-      border-color: var(--google-grey-refresh-700);
+      border-color: var(--google-grey-700);
     }
   }
 </style>
diff --git a/chrome/browser/resources/signin/profile_picker/profile_creation_flow/local_profile_customization.html b/chrome/browser/resources/signin/profile_picker/profile_creation_flow/local_profile_customization.html
index a6b85ff..0b38095 100644
--- a/chrome/browser/resources/signin/profile_picker/profile_creation_flow/local_profile_customization.html
+++ b/chrome/browser/resources/signin/profile_picker/profile_creation_flow/local_profile_customization.html
@@ -87,7 +87,7 @@
   }
 
   #colorPickerContainer {
-    border: 1px solid var(--google-grey-refresh-300);
+    border: 1px solid var(--google-grey-300);
     border-radius: 4px;
     display: flex;
     flex-direction: column;
@@ -163,11 +163,11 @@
     }
 
     #customizeAvatarIcon {
-      border: 1px solid var(--google-grey-refresh-500);
+      border: 1px solid var(--google-grey-500);
     }
 
     #colorPickerContainer {
-      border-color: var(--google-grey-refresh-700);
+      border-color: var(--google-grey-700);
     }
   }
 </style>
diff --git a/chrome/browser/resources/signin/profile_picker/profile_creation_flow/profile_type_choice.html b/chrome/browser/resources/signin/profile_picker/profile_creation_flow/profile_type_choice.html
index e7f9bb805..a042f53 100644
--- a/chrome/browser/resources/signin/profile_picker/profile_creation_flow/profile_type_choice.html
+++ b/chrome/browser/resources/signin/profile_picker/profile_creation_flow/profile_type_choice.html
@@ -18,7 +18,7 @@
     align-items: center;
     border: 1px solid var(--google-grey-200);
     border-radius: 8px;
-    color: var(--google-grey-refresh-700);
+    color: var(--google-grey-700);
     display: inline-flex;
     flex-direction: row;
     margin-inline: auto;
@@ -36,7 +36,7 @@
   .icon-container {
     --icon-container-size: 28px;
     --icon-container-margin: 16px;
-    background-color: var(--google-grey-refresh-100);
+    background-color: var(--google-grey-100);
     border-radius: 50%;
     height: var(--icon-container-size);
     margin-inline: var(--icon-container-margin);
@@ -69,11 +69,11 @@
   @media (prefers-color-scheme: dark) {
     .info-box {
       border-color: var(--google-grey-600);
-      color: var(--google-grey-refresh-100);
+      color: var(--google-grey-100);
     }
 
     .icon-container {
-      background-color: var(--google-grey-refresh-700);
+      background-color: var(--google-grey-700);
     }
   }
 </style>
diff --git a/chrome/browser/resources/signin/profile_picker/profile_picker_main_view.html b/chrome/browser/resources/signin/profile_picker/profile_picker_main_view.html
index e0dce931..a2ff4369 100644
--- a/chrome/browser/resources/signin/profile_picker/profile_picker_main_view.html
+++ b/chrome/browser/resources/signin/profile_picker/profile_picker_main_view.html
@@ -112,8 +112,8 @@
   iron-icon[icon='profiles:add'] {
     --iron-icon-height: var(--profile-card-avatar-icon-size);
     --iron-icon-width: var(--profile-card-avatar-icon-size);
-    --iron-icon-fill-color: var(--google-grey-refresh-100);
-    --iron-icon-stroke-color: var(--google-grey-refresh-700);
+    --iron-icon-fill-color: var(--google-grey-100);
+    --iron-icon-stroke-color: var(--google-grey-700);
   }
 
   #browseAsGuestButton {
@@ -145,11 +145,11 @@
 
     .profile-item,
     #addProfile.profile-item {
-      border-color: var(--google-grey-refresh-700);
+      border-color: var(--google-grey-700);
     }
 
     iron-icon[icon='profiles:add'] {
-      --iron-icon-fill-color: var(--google-grey-refresh-500);
+      --iron-icon-fill-color: var(--google-grey-500);
       --iron-icon-stroke-color: rgb(48, 48, 50);
     }
   }
diff --git a/chrome/browser/resources/signin/profile_picker/profile_picker_shared_css.html b/chrome/browser/resources/signin/profile_picker/profile_picker_shared_css.html
index 6e6c8c7..b252e20 100644
--- a/chrome/browser/resources/signin/profile_picker/profile_picker_shared_css.html
+++ b/chrome/browser/resources/signin/profile_picker/profile_picker_shared_css.html
@@ -4,7 +4,7 @@
       --profile-card-avatar-icon-size: 74px;
       --text-font-size: 1.16em;
       --scrollbar-width: 4px;
-      --scrollbar-background: var(--google-grey-refresh-100);
+      --scrollbar-background: var(--google-grey-100);
       --footer-spacing: 40px;
       --profile-card-hover-color: var(--md-background-color);
       --profile-item-height: 178px;
@@ -61,7 +61,7 @@
     }
 
     .footer.division-line {
-      border-top: 1px solid var(--google-grey-refresh-300);
+      border-top: 1px solid var(--google-grey-300);
     }
 
     .custom-scrollbar::-webkit-scrollbar {
diff --git a/chrome/browser/resources/signin/profile_picker/profile_switch.html b/chrome/browser/resources/signin/profile_picker/profile_switch.html
index c7210857..48184fa 100644
--- a/chrome/browser/resources/signin/profile_picker/profile_switch.html
+++ b/chrome/browser/resources/signin/profile_picker/profile_switch.html
@@ -54,7 +54,7 @@
   }
 
   iron-icon {
-    --iron-icon-fill-color: var(--google-grey-refresh-700);
+    --iron-icon-fill-color: var(--google-grey-700);
   }
 
   #titleContainer {
diff --git a/chrome/browser/resources/tab_search/app.html b/chrome/browser/resources/tab_search/app.html
index 7b937ba4..56c02a9 100644
--- a/chrome/browser/resources/tab_search/app.html
+++ b/chrome/browser/resources/tab_search/app.html
@@ -15,7 +15,7 @@
 
   #feedback-footer {
     border: none;
-    border-top: 1px solid var(--google-grey-refresh-500);
+    border-top: 1px solid var(--google-grey-500);
     height: 40px;
     width: 100%;
   }
@@ -26,14 +26,14 @@
   }
 
   #feedback-icon {
-    --iron-icon-fill-color: var(--google-grey-refresh-700);
+    --iron-icon-fill-color: var(--google-grey-700);
     height: var(--mwb-icon-size);
     width: var(--mwb-icon-size);
   }
 
   @media (prefers-color-scheme: dark) {
     #feedback-icon {
-      --iron-icon-fill-color: var(--google-blue-refresh-300);
+      --iron-icon-fill-color: var(--google-blue-300);
     }
   }
 
@@ -58,6 +58,7 @@
     --cr-expand-button-size: 24px;
     --cr-expand-button-icon-size: 16px;
     --cr-section-vertical-padding: 0;
+    -webkit-tap-highlight-color: transparent;
     flex-grow: 1;
   }
 </style>
diff --git a/chrome/browser/resources/tab_search/tab_search_search_field.html b/chrome/browser/resources/tab_search/tab_search_search_field.html
index 5dc223c..4366a1d7 100644
--- a/chrome/browser/resources/tab_search/tab_search_search_field.html
+++ b/chrome/browser/resources/tab_search/tab_search_search_field.html
@@ -57,7 +57,7 @@
 
   @media (prefers-color-scheme: dark) {
     #searchIcon {
-      color: var(--google-blue-refresh-300);
+      color: var(--google-blue-300);
     }
   }
 
diff --git a/chrome/browser/resources/welcome/ntp_background/nux_ntp_background.html b/chrome/browser/resources/welcome/ntp_background/nux_ntp_background.html
index fead178..b9ada88 100644
--- a/chrome/browser/resources/welcome/ntp_background/nux_ntp_background.html
+++ b/chrome/browser/resources/welcome/ntp_background/nux_ntp_background.html
@@ -84,7 +84,7 @@
   }
 
   #backgroundPreview.active + .content .option {
-    border-color: var(--google-grey-refresh-700);
+    border-color: var(--google-grey-700);
   }
 
   /* Remove outline when button is focused using the mouse. */
diff --git a/chrome/browser/resources/welcome/shared/navi_colors_css.html b/chrome/browser/resources/welcome/shared/navi_colors_css.html
index 772ebce..1ac5ab6 100644
--- a/chrome/browser/resources/welcome/shared/navi_colors_css.html
+++ b/chrome/browser/resources/welcome/shared/navi_colors_css.html
@@ -1,13 +1,13 @@
 <template>
   <style>
     :host {
-      --navi-border-color: var(--google-grey-refresh-300);
+      --navi-border-color: var(--google-grey-300);
       --navi-check-icon-color: lightgrey;
       --navi-keyboard-focus-color: rgba(var(--google-blue-600-rgb), .4);
       --navi-option-box-shadow:
           0 1px 2px 0 rgba(var(--google-grey-800-rgb), .3),
           0 3px 6px 2px rgba(var(--google-grey-800-rgb), .15);
-      --navi-option-icon-shadow-color: var(--google-grey-refresh-100);
+      --navi-option-icon-shadow-color: var(--google-grey-100);
       --navi-shape-blue-color: rgb(26, 115, 232);  /* #1A73E8 */
       --navi-shape-green-color: rgb(49, 167, 83); /* #31A753 */
       --navi-shape-grey-color: rgb(241, 243, 244); /* #F1F3F4 */
@@ -16,26 +16,26 @@
       --navi-shape-yellow-semicircle-color: rgb(250, 207, 76); /* #FACF4C */
       --navi-step-indicator-active-color: var(--google-blue-600);
       --navi-step-indicator-color: var(--google-grey-200);
-      --navi-wallpaper-text-color: var(--google-grey-refresh-700);
+      --navi-wallpaper-text-color: var(--google-grey-700);
     }
 
     @media (prefers-color-scheme: dark) {
       :host {
-        --navi-border-color: var(--google-grey-refresh-700);
-        --navi-check-icon-color: var(--google-grey-refresh-700);
+        --navi-border-color: var(--google-grey-700);
+        --navi-check-icon-color: var(--google-grey-700);
         --navi-keyboard-focus-color:
-            rgba(var(--google-blue-refresh-300-rgb), .5);
+            rgba(var(--google-blue-300-rgb), .5);
         --navi-option-box-shadow: 0 1px 2px 0 rgba(0, 0, 0, .3),
                                   0 3px 6px 2px rgba(0, 0, 0, .15);
-        --navi-option-icon-shadow-color: var(--google-grey-refresh-700);
+        --navi-option-icon-shadow-color: var(--google-grey-700);
         --navi-shape-blue-color: rgb(138, 180, 248); /* #8AB4F8 */
         --navi-shape-green-color: rgb(129, 201, 149); /* #81C995 */
         --navi-shape-grey-color: rgb(154, 160, 166); /* #9AA0A6 */
         --navi-shape-red-color: rgb(238, 103, 92); /* #EE675C */
         /* --navi-shape-yellow-dots-color is same color in dark mode */
         --navi-shape-yellow-semicircle-color: rgb(253, 214, 99); /* #FDD663 */
-        --navi-step-indicator-active-color: var(--google-blue-refresh-300);
-        --navi-step-indicator-color: var(--google-grey-refresh-500);
+        --navi-step-indicator-active-color: var(--google-blue-300);
+        --navi-step-indicator-color: var(--google-grey-500);
         --navi-wallpaper-text-color: var(--google-grey-200);
       }
     }
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_browsertest_win.cc b/chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_browsertest_win.cc
index 41534f8..17983c3 100644
--- a/chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_browsertest_win.cc
+++ b/chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_browsertest_win.cc
@@ -250,8 +250,7 @@
   // |invocation|.
   base::Process LaunchReporterProcess(
       const SwReporterInvocation& invocation,
-      const base::LaunchOptions& options) override {
-    ANALYZER_ALLOW_UNUSED(options);
+      [[maybe_unused]] const base::LaunchOptions& options) override {
     ++reporter_launch_count_;
     reporter_launch_parameters_.push_back(invocation);
     if (first_launch_callback_)
@@ -260,8 +259,8 @@
     return base::Process::Current();
   }
 
-  int WaitForReporterExit(const base::Process& reporter_process) const {
-    ANALYZER_ALLOW_UNUSED(reporter_process);
+  int WaitForReporterExit([
+      [maybe_unused]] const base::Process& reporter_process) const {
     return exit_code_to_report_;
   }
 
diff --git a/chrome/browser/safe_browsing/tailored_security/consented_message_android.cc b/chrome/browser/safe_browsing/tailored_security/consented_message_android.cc
index 7b9d3fb..a50dbbc 100644
--- a/chrome/browser/safe_browsing/tailored_security/consented_message_android.cc
+++ b/chrome/browser/safe_browsing/tailored_security/consented_message_android.cc
@@ -70,14 +70,14 @@
     description = l10n_util::GetStringUTF16(
         IDS_TAILORED_SECURITY_CONSENTED_DISABLE_MESSAGE_DESCRIPTION);
     icon_resource_id =
-        ResourceMapper::MapToJavaDrawableId(IDR_ANDROID_MESSAGE_GPP_MAYBE_GREY);
+        ResourceMapper::MapToJavaDrawableId(IDR_ANDROID_MESSAGE_SHIELD);
+    message_->DisableIconTint();
   }
   message_->SetTitle(title);
   message_->SetDescription(description);
   message_->SetPrimaryButtonText(l10n_util::GetStringUTF16(
       IDS_TAILORED_SECURITY_CONSENTED_MESSAGE_OK_BUTTON));
   message_->SetIconResourceId(icon_resource_id);
-  message_->DisableIconTint();
   message_->SetSecondaryIconResourceId(
       ResourceMapper::MapToJavaDrawableId(IDR_ANDROID_MESSAGE_SETTINGS));
   message_->SetSecondaryActionCallback(base::BindOnce(
diff --git a/chrome/browser/safe_browsing/tailored_security/notification_handler_desktop.cc b/chrome/browser/safe_browsing/tailored_security/notification_handler_desktop.cc
index b2dc3746..4431a12 100644
--- a/chrome/browser/safe_browsing/tailored_security/notification_handler_desktop.cc
+++ b/chrome/browser/safe_browsing/tailored_security/notification_handler_desktop.cc
@@ -47,10 +47,10 @@
     "chrome://settings/security?q=enhanced";
 
 // |is_esb_enabled_in_sync| records if ESB was enabled in sync with Account-ESB
-void TurnOnEsbAndOpenSettings(Profile* profile, bool is_esb_enabled_in_sync) {
-  SetSafeBrowsingState(profile->GetPrefs(),
-                       SafeBrowsingState::ENHANCED_PROTECTION,
-                       is_esb_enabled_in_sync);
+void ChangeSafeBrowsingStateAndOpenSettings(Profile* profile,
+                                            SafeBrowsingState new_state,
+                                            bool is_esb_enabled_in_sync) {
+  SetSafeBrowsingState(profile->GetPrefs(), new_state, is_esb_enabled_in_sync);
   Browser* browser = chrome::ScopedTabbedBrowserDisplayer(profile).browser();
   chrome::ShowSafeBrowsingEnhancedProtection(browser);
 }
@@ -120,20 +120,21 @@
   } else {
     bool is_enable = (notification_id == kTailoredSecurityEnableNotificationId);
     if (*action_index == 0) {
-      // Enable: Pressed Turn on is acceptance, Disable: Turn back on is
-      // rejection
-      TailoredSecurityOutcome outcome =
-          is_enable ? TailoredSecurityOutcome::kAccepted
-                    : TailoredSecurityOutcome::kRejected;
-      LogConsentedOutcome(outcome, is_enable);
-      TurnOnEsbAndOpenSettings(profile, is_enable);
-    } else {
-      // Enable: Pressed No Thanks is rejection, Disable: Pressed OK is
+      // Enable: Pressed Turn on, Disable: Pressed Turn off. Both are
       // acceptance
-      TailoredSecurityOutcome outcome =
-          is_enable ? TailoredSecurityOutcome::kRejected
-                    : TailoredSecurityOutcome::kAccepted;
-      LogConsentedOutcome(outcome, is_enable);
+      LogConsentedOutcome(TailoredSecurityOutcome::kAccepted, is_enable);
+      if (is_enable) {
+        ChangeSafeBrowsingStateAndOpenSettings(
+            profile, SafeBrowsingState::ENHANCED_PROTECTION,
+            /*is_esb_enabled_in_sync=*/true);
+      } else {
+        ChangeSafeBrowsingStateAndOpenSettings(
+            profile, SafeBrowsingState::STANDARD_PROTECTION,
+            /*is_esb_enabled_in_sync=*/false);
+      }
+    } else {
+      // Both enable and disable dialogs display No Thanks, and are rejecting.
+      LogConsentedOutcome(TailoredSecurityOutcome::kRejected, is_enable);
     }
   }
 
@@ -174,7 +175,7 @@
         IDS_TAILORED_SECURITY_CONSENTED_DISABLE_NOTIFICATION_DESCRIPTION);
     primary_button = l10n_util::GetStringUTF16(
         IDS_TAILORED_SECURITY_CONSENTED_DISABLE_NOTIFICATION_TURN_OFF);
-    secondary_button = l10n_util::GetStringUTF16(IDS_OK);
+    secondary_button = l10n_util::GetStringUTF16(IDS_NO_THANKS);
     SkColor icon_color =
         color_provider->GetColor(ui::kColorSecondaryForeground);
     icon = gfx::Image(gfx::CreateVectorIcon(
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProvider.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProvider.java
index 2810c86..49cd79d 100644
--- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProvider.java
+++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProvider.java
@@ -498,7 +498,7 @@
                             mActivity, mShareParams.getFileUris().get(0), (bitmap) -> {
                                 SaveBitmapDelegate saveBitmapDelegate = new SaveBitmapDelegate(
                                         mActivity, bitmap, R.string.save_image_filename_prefix,
-                                        null, mTabProvider.get().getWindowAndroid());
+                                        null, mShareParams.getWindow());
                                 saveBitmapDelegate.save();
                             });
                 })
diff --git a/chrome/browser/signin/account_consistency_mode_manager.cc b/chrome/browser/signin/account_consistency_mode_manager.cc
index 6c1f0f0..77f0d83 100644
--- a/chrome/browser/signin/account_consistency_mode_manager.cc
+++ b/chrome/browser/signin/account_consistency_mode_manager.cc
@@ -66,12 +66,11 @@
   }
 
   // Only log this once.
-  static bool logged_warning = []() {
+  [[maybe_unused]] static bool logged_warning = []() {
     LOG(WARNING) << "Desktop Identity Consistency cannot be enabled as no "
                     "OAuth client ID and client secret have been configured.";
     return true;
   }();
-  ALLOW_UNUSED_LOCAL(logged_warning);
 
   return false;
 }
diff --git a/chrome/browser/ssl/ssl_browsertest.cc b/chrome/browser/ssl/ssl_browsertest.cc
index 4b16138..341958e 100644
--- a/chrome/browser/ssl/ssl_browsertest.cc
+++ b/chrome/browser/ssl/ssl_browsertest.cc
@@ -13,6 +13,7 @@
 #include "base/command_line.h"
 #include "base/containers/contains.h"
 #include "base/feature_list.h"
+#include "base/files/file_util.h"
 #include "base/json/json_reader.h"
 #include "base/location.h"
 #include "base/memory/raw_ptr.h"
diff --git a/chrome/browser/translate/translate_manager_browsertest.cc b/chrome/browser/translate/translate_manager_browsertest.cc
index 296cc8c..a30b962 100644
--- a/chrome/browser/translate/translate_manager_browsertest.cc
+++ b/chrome/browser/translate/translate_manager_browsertest.cc
@@ -291,10 +291,11 @@
     ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient();
 
     // Load a page with hrefTranslate tags.
-    AddTabAtIndex(0,
-                  GURL(embedded_test_server()->GetURL(
-                      "www.google.com", "/href_translate_test.html")),
-                  ui::PAGE_TRANSITION_TYPED);
+    ASSERT_TRUE(
+        AddTabAtIndex(0,
+                      GURL(embedded_test_server()->GetURL(
+                          "www.google.com", "/href_translate_test.html")),
+                      ui::PAGE_TRANSITION_TYPED));
     ResetObserver();
     chrome_translate_client = GetChromeTranslateClient();
     WaitUntilLanguageDetermined(chrome_translate_client);
@@ -389,8 +390,9 @@
   ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient();
 
   // Open a new tab with a page in French.
-  AddTabAtIndex(0, GURL(embedded_test_server()->GetURL("/french_page.html")),
-                ui::PAGE_TRANSITION_TYPED);
+  ASSERT_TRUE(AddTabAtIndex(
+      0, GURL(embedded_test_server()->GetURL("/french_page.html")),
+      ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
   chrome_translate_client = GetChromeTranslateClient();
   WaitUntilLanguageDetermined(chrome_translate_client);
@@ -413,10 +415,10 @@
   // Open a new tab with a page in Korean with incorrect HTML language
   // attribute specified. The language attribute should not be overridden by the
   // language detection.
-  AddTabAtIndex(
+  ASSERT_TRUE(AddTabAtIndex(
       0,
       GURL(embedded_test_server()->GetURL("/korean_page_lang_conflict.html")),
-      ui::PAGE_TRANSITION_TYPED);
+      ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
   ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient();
   WaitUntilLanguageDetermined(chrome_translate_client);
@@ -434,10 +436,10 @@
   // Open a new tab with a page in French with incorrect HTML language
   // attribute specified. The language attribute should be overridden by the
   // language detection.
-  AddTabAtIndex(
+  ASSERT_TRUE(AddTabAtIndex(
       0,
       GURL(embedded_test_server()->GetURL("/french_page_lang_conflict.html")),
-      ui::PAGE_TRANSITION_TYPED);
+      ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
   ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient();
   WaitUntilLanguageDetermined(chrome_translate_client);
@@ -454,8 +456,9 @@
   base::HistogramTester histograms;
 
   // Open a new tab with a page in French.
-  AddTabAtIndex(0, GURL(embedded_test_server()->GetURL("/french_page.html")),
-                ui::PAGE_TRANSITION_TYPED);
+  ASSERT_TRUE(AddTabAtIndex(
+      0, GURL(embedded_test_server()->GetURL("/french_page.html")),
+      ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
   chrome_translate_client = GetChromeTranslateClient();
   WaitUntilLanguageDetermined(chrome_translate_client);
@@ -485,8 +488,9 @@
 // Disabled due to flakiness: https://crbug.com/1202065.
 IN_PROC_BROWSER_TEST_F(TranslateManagerBrowserTest,
                        DISABLED_PageTranslationAboutBlank) {
-  AddTabAtIndex(0, GURL(embedded_test_server()->GetURL("/french_page.html")),
-                ui::PAGE_TRANSITION_TYPED);
+  ASSERT_TRUE(AddTabAtIndex(
+      0, GURL(embedded_test_server()->GetURL("/french_page.html")),
+      ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
 
   // Open a pop-up window and leave it at the initial about:blank URL.
@@ -557,9 +561,9 @@
   SetTranslateScript(kTestValidScript);
 
   // Load a page with hrefTranslate tags.
-  AddTabAtIndex(
+  ASSERT_TRUE(AddTabAtIndex(
       0, GURL(embedded_test_server()->GetURL("/href_translate_test.html")),
-      ui::PAGE_TRANSITION_TYPED);
+      ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
   chrome_translate_client = GetChromeTranslateClient();
   WaitUntilLanguageDetermined(chrome_translate_client);
@@ -601,10 +605,10 @@
   SetTranslateScript(kTestValidScript);
 
   // Load a page with hrefTranslate tags.
-  AddTabAtIndex(0,
-                GURL(embedded_test_server()->GetURL(
-                    "www.google.com", "/href_translate_test.html")),
-                ui::PAGE_TRANSITION_TYPED);
+  ASSERT_TRUE(AddTabAtIndex(0,
+                            GURL(embedded_test_server()->GetURL(
+                                "www.google.com", "/href_translate_test.html")),
+                            ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
   chrome_translate_client = GetChromeTranslateClient();
   WaitUntilLanguageDetermined(chrome_translate_client);
@@ -659,10 +663,10 @@
   SetTranslateScript(kTestValidScript);
 
   // Load a page with hrefTranslate tags.
-  AddTabAtIndex(0,
-                GURL(embedded_test_server()->GetURL(
-                    "www.google.com", "/href_translate_test.html")),
-                ui::PAGE_TRANSITION_TYPED);
+  ASSERT_TRUE(AddTabAtIndex(0,
+                            GURL(embedded_test_server()->GetURL(
+                                "www.google.com", "/href_translate_test.html")),
+                            ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
   chrome_translate_client = GetChromeTranslateClient();
   // TODO(crbug.com/1258185): Migrate to better mechanism for testing around
@@ -712,10 +716,10 @@
   SetTranslateScript(kTestValidScript);
 
   // Load a page with hrefTranslate tags.
-  AddTabAtIndex(0,
-                GURL(embedded_test_server()->GetURL(
-                    "www.google.com", "/href_translate_test.html")),
-                ui::PAGE_TRANSITION_TYPED);
+  ASSERT_TRUE(AddTabAtIndex(0,
+                            GURL(embedded_test_server()->GetURL(
+                                "www.google.com", "/href_translate_test.html")),
+                            ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
   chrome_translate_client = GetChromeTranslateClient();
   // TODO(crbug.com/1258185): Migrate to better mechanism for testing around
@@ -1069,8 +1073,9 @@
   // error.
   // TODO(crbug.com/1258185): Migrate to better mechanism for testing around
   // language detection. All pages will return "fr" as the detected language.
-  AddTabAtIndex(0, GURL(embedded_test_server()->GetURL("/french_page.html")),
-                ui::PAGE_TRANSITION_TYPED);
+  ASSERT_TRUE(AddTabAtIndex(
+      0, GURL(embedded_test_server()->GetURL("/french_page.html")),
+      ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
   chrome_translate_client = GetChromeTranslateClient();
   WaitUntilLanguageDetermined(chrome_translate_client);
@@ -1095,8 +1100,9 @@
   ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient();
 
   // Open a new tab with a page in French.
-  AddTabAtIndex(0, GURL(embedded_test_server()->GetURL("/french_page.html")),
-                ui::PAGE_TRANSITION_TYPED);
+  ASSERT_TRUE(AddTabAtIndex(
+      0, GURL(embedded_test_server()->GetURL("/french_page.html")),
+      ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
   chrome_translate_client = GetChromeTranslateClient();
   WaitUntilLanguageDetermined(chrome_translate_client);
@@ -1124,8 +1130,9 @@
   ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient();
 
   // Open a new tab with a page in French.
-  AddTabAtIndex(0, GURL(embedded_test_server()->GetURL("/french_page.html")),
-                ui::PAGE_TRANSITION_TYPED);
+  ASSERT_TRUE(AddTabAtIndex(
+      0, GURL(embedded_test_server()->GetURL("/french_page.html")),
+      ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
   chrome_translate_client = GetChromeTranslateClient();
   WaitUntilLanguageDetermined(chrome_translate_client);
@@ -1153,8 +1160,9 @@
   ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient();
 
   // Open a new tab with a page in French.
-  AddTabAtIndex(0, GURL(embedded_test_server()->GetURL("/french_page.html")),
-                ui::PAGE_TRANSITION_TYPED);
+  ASSERT_TRUE(AddTabAtIndex(
+      0, GURL(embedded_test_server()->GetURL("/french_page.html")),
+      ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
   chrome_translate_client = GetChromeTranslateClient();
   WaitUntilLanguageDetermined(chrome_translate_client);
@@ -1180,8 +1188,9 @@
   ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient();
 
   // Open a new tab with a page in French.
-  AddTabAtIndex(0, GURL(embedded_test_server()->GetURL("/french_page.html")),
-                ui::PAGE_TRANSITION_TYPED);
+  ASSERT_TRUE(AddTabAtIndex(
+      0, GURL(embedded_test_server()->GetURL("/french_page.html")),
+      ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
   chrome_translate_client = GetChromeTranslateClient();
   WaitUntilLanguageDetermined(chrome_translate_client);
@@ -1209,8 +1218,9 @@
 
   ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient();
 
-  AddTabAtIndex(0, GURL(embedded_test_server()->GetURL("/french_page.html")),
-                ui::PAGE_TRANSITION_TYPED);
+  ASSERT_TRUE(AddTabAtIndex(
+      0, GURL(embedded_test_server()->GetURL("/french_page.html")),
+      ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
   chrome_translate_client = GetChromeTranslateClient();
   WaitUntilLanguageDetermined(chrome_translate_client);
@@ -1238,8 +1248,9 @@
   ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient();
 
   // Open a new tab with a page in French.
-  AddTabAtIndex(0, GURL(embedded_test_server()->GetURL("/french_page.html")),
-                ui::PAGE_TRANSITION_TYPED);
+  ASSERT_TRUE(AddTabAtIndex(
+      0, GURL(embedded_test_server()->GetURL("/french_page.html")),
+      ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
   chrome_translate_client = GetChromeTranslateClient();
   WaitUntilLanguageDetermined(chrome_translate_client);
@@ -1310,10 +1321,10 @@
   SetTranslateScript(kTestValidScript);
 
   // Load a German page and detect it's language
-  AddTabAtIndex(0,
-                GURL(embedded_test_server()->GetURL(
-                    "www.google.com", "/href_translate_test.html")),
-                ui::PAGE_TRANSITION_TYPED);
+  ASSERT_TRUE(AddTabAtIndex(0,
+                            GURL(embedded_test_server()->GetURL(
+                                "www.google.com", "/href_translate_test.html")),
+                            ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
   chrome_translate_client = GetChromeTranslateClient();
   WaitUntilLanguageDetermined(chrome_translate_client);
@@ -1351,9 +1362,9 @@
   base::HistogramTester histograms;
 
   // Open a new tab with a page in French.
-  AddTabAtIndex(
+  ASSERT_TRUE(AddTabAtIndex(
       0, GURL(embedded_test_server()->GetURL("/translate/fr_iframe_test.html")),
-      ui::PAGE_TRANSITION_TYPED);
+      ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
   chrome_translate_client = GetChromeTranslateClient();
   WaitUntilLanguageDetermined(chrome_translate_client);
@@ -1403,8 +1414,9 @@
 IN_PROC_BROWSER_TEST_F(TranslateManagerWithSubFrameSupportBrowserTest,
                        DISABLED_PageLanguageDetection) {
   // Open a new tab with a page in English.
-  AddTabAtIndex(0, GURL(embedded_test_server()->GetURL("/english_page.html")),
-                ui::PAGE_TRANSITION_TYPED);
+  ASSERT_TRUE(AddTabAtIndex(
+      0, GURL(embedded_test_server()->GetURL("/english_page.html")),
+      ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
   ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient();
   WaitUntilLanguageDetermined(chrome_translate_client);
@@ -1431,10 +1443,10 @@
   // Open a new tab with a page in French with incorrect HTML language
   // attribute specified. The language attribute should be overridden by the
   // language detection.
-  AddTabAtIndex(
+  ASSERT_TRUE(AddTabAtIndex(
       0,
       GURL(embedded_test_server()->GetURL("/french_page_lang_conflict.html")),
-      ui::PAGE_TRANSITION_TYPED);
+      ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
   ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient();
   WaitUntilLanguageDetermined(chrome_translate_client);
@@ -1445,10 +1457,10 @@
   // Open a new tab with a page in Korean with incorrect HTML language
   // attribute specified. The language attribute should not be overridden by the
   // language detection.
-  AddTabAtIndex(
+  ASSERT_TRUE(AddTabAtIndex(
       0,
       GURL(embedded_test_server()->GetURL("/korean_page_lang_conflict.html")),
-      ui::PAGE_TRANSITION_TYPED);
+      ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
   chrome_translate_client = GetChromeTranslateClient();
   WaitUntilLanguageDetermined(chrome_translate_client);
@@ -1464,8 +1476,9 @@
   SetTranslateScript(kTestValidScript);
 
   // Open a new tab with a page in French.
-  AddTabAtIndex(0, GURL(embedded_test_server()->GetURL("/french_page.html")),
-                ui::PAGE_TRANSITION_TYPED);
+  ASSERT_TRUE(AddTabAtIndex(
+      0, GURL(embedded_test_server()->GetURL("/french_page.html")),
+      ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
   ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient();
   WaitUntilLanguageDetermined(chrome_translate_client);
@@ -1499,10 +1512,10 @@
   SetTranslateScript(kTestValidScript);
 
   // Load a German page and detect it's language
-  AddTabAtIndex(0,
-                GURL(embedded_test_server()->GetURL(
-                    "www.google.com", "/href_translate_test.html")),
-                ui::PAGE_TRANSITION_TYPED);
+  ASSERT_TRUE(AddTabAtIndex(0,
+                            GURL(embedded_test_server()->GetURL(
+                                "www.google.com", "/href_translate_test.html")),
+                            ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
   chrome_translate_client = GetChromeTranslateClient();
   WaitUntilLanguageDetermined(chrome_translate_client);
@@ -1556,9 +1569,9 @@
   SetTranslateScript(kTestValidScript);
 
   // Load a German page and detect it's language
-  AddTabAtIndex(
+  ASSERT_TRUE(AddTabAtIndex(
       0, GURL(embedded_test_server()->GetURL("/href_translate_test.html")),
-      ui::PAGE_TRANSITION_TYPED);
+      ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
   chrome_translate_client = GetChromeTranslateClient();
   WaitUntilLanguageDetermined(chrome_translate_client);
@@ -1595,10 +1608,10 @@
   SetTranslateScript(kTestValidScript);
 
   // Load a German page and detect it's language
-  AddTabAtIndex(0,
-                GURL(embedded_test_server()->GetURL(
-                    "www.google.com", "/href_translate_test.html")),
-                ui::PAGE_TRANSITION_TYPED);
+  ASSERT_TRUE(AddTabAtIndex(0,
+                            GURL(embedded_test_server()->GetURL(
+                                "www.google.com", "/href_translate_test.html")),
+                            ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
   chrome_translate_client = GetChromeTranslateClient();
   WaitUntilLanguageDetermined(chrome_translate_client);
@@ -1646,10 +1659,10 @@
   SetTranslateScript(kTestValidScript);
 
   // Load a German page and detect it's language
-  AddTabAtIndex(0,
-                GURL(embedded_test_server()->GetURL(
-                    "www.google.com", "/href_translate_test.html")),
-                ui::PAGE_TRANSITION_TYPED);
+  ASSERT_TRUE(AddTabAtIndex(0,
+                            GURL(embedded_test_server()->GetURL(
+                                "www.google.com", "/href_translate_test.html")),
+                            ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
   chrome_translate_client = GetChromeTranslateClient();
   WaitUntilLanguageDetermined(chrome_translate_client);
@@ -1698,10 +1711,10 @@
   SetTranslateScript(kTestValidScript);
 
   // Load a German page and detect it's language
-  AddTabAtIndex(0,
-                GURL(embedded_test_server()->GetURL(
-                    "www.google.com", "/href_translate_test.html")),
-                ui::PAGE_TRANSITION_TYPED);
+  ASSERT_TRUE(AddTabAtIndex(0,
+                            GURL(embedded_test_server()->GetURL(
+                                "www.google.com", "/href_translate_test.html")),
+                            ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
   chrome_translate_client = GetChromeTranslateClient();
   WaitUntilLanguageDetermined(chrome_translate_client);
@@ -1754,10 +1767,10 @@
       ->AddLanguagePairToAlwaysTranslateList("fr", "zh-CN");
 
   // Load a German page and detect it's language
-  AddTabAtIndex(0,
-                GURL(embedded_test_server()->GetURL(
-                    "www.google.com", "/href_translate_test.html")),
-                ui::PAGE_TRANSITION_TYPED);
+  ASSERT_TRUE(AddTabAtIndex(0,
+                            GURL(embedded_test_server()->GetURL(
+                                "www.google.com", "/href_translate_test.html")),
+                            ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
   chrome_translate_client = GetChromeTranslateClient();
   WaitUntilLanguageDetermined(chrome_translate_client);
@@ -1802,8 +1815,9 @@
 
   ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient();
 
-  AddTabAtIndex(0, GURL(embedded_test_server()->GetURL("/french_page.html")),
-                ui::PAGE_TRANSITION_TYPED);
+  ASSERT_TRUE(AddTabAtIndex(
+      0, GURL(embedded_test_server()->GetURL("/french_page.html")),
+      ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
   chrome_translate_client = GetChromeTranslateClient();
   TranslateManager* manager = chrome_translate_client->GetTranslateManager();
@@ -1825,8 +1839,9 @@
   ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient();
 
   // Open a new tab with a page in French.
-  AddTabAtIndex(0, GURL(embedded_test_server()->GetURL("/french_page.html")),
-                ui::PAGE_TRANSITION_TYPED);
+  ASSERT_TRUE(AddTabAtIndex(
+      0, GURL(embedded_test_server()->GetURL("/french_page.html")),
+      ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
   chrome_translate_client = GetChromeTranslateClient();
   WaitUntilLanguageDetermined(chrome_translate_client);
@@ -1854,8 +1869,9 @@
   ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient();
 
   // Open a new tab with a page in French.
-  AddTabAtIndex(0, GURL(embedded_test_server()->GetURL("/french_page.html")),
-                ui::PAGE_TRANSITION_TYPED);
+  ASSERT_TRUE(AddTabAtIndex(
+      0, GURL(embedded_test_server()->GetURL("/french_page.html")),
+      ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
   chrome_translate_client = GetChromeTranslateClient();
   WaitUntilLanguageDetermined(chrome_translate_client);
@@ -1885,8 +1901,9 @@
   ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient();
 
   // Open a new tab with a page in French.
-  AddTabAtIndex(0, GURL(embedded_test_server()->GetURL("/french_page.html")),
-                ui::PAGE_TRANSITION_TYPED);
+  ASSERT_TRUE(AddTabAtIndex(
+      0, GURL(embedded_test_server()->GetURL("/french_page.html")),
+      ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
   chrome_translate_client = GetChromeTranslateClient();
   WaitUntilLanguageDetermined(chrome_translate_client);
@@ -1914,8 +1931,9 @@
   ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient();
 
   // Open a new tab with a page in French.
-  AddTabAtIndex(0, GURL(embedded_test_server()->GetURL("/french_page.html")),
-                ui::PAGE_TRANSITION_TYPED);
+  ASSERT_TRUE(AddTabAtIndex(
+      0, GURL(embedded_test_server()->GetURL("/french_page.html")),
+      ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
   chrome_translate_client = GetChromeTranslateClient();
   WaitUntilLanguageDetermined(chrome_translate_client);
@@ -1941,8 +1959,9 @@
   ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient();
 
   // Open a new tab with a page in French.
-  AddTabAtIndex(0, GURL(embedded_test_server()->GetURL("/french_page.html")),
-                ui::PAGE_TRANSITION_TYPED);
+  ASSERT_TRUE(AddTabAtIndex(
+      0, GURL(embedded_test_server()->GetURL("/french_page.html")),
+      ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
   chrome_translate_client = GetChromeTranslateClient();
   WaitUntilLanguageDetermined(chrome_translate_client);
@@ -1971,8 +1990,9 @@
   ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient();
 
   // Open a new tab with a page in French.
-  AddTabAtIndex(0, GURL(embedded_test_server()->GetURL("/french_page.html")),
-                ui::PAGE_TRANSITION_TYPED);
+  ASSERT_TRUE(AddTabAtIndex(
+      0, GURL(embedded_test_server()->GetURL("/french_page.html")),
+      ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
   chrome_translate_client = GetChromeTranslateClient();
   WaitUntilLanguageDetermined(chrome_translate_client);
@@ -2000,8 +2020,9 @@
   ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient();
 
   // Open a new tab with a page in French.
-  AddTabAtIndex(0, GURL(embedded_test_server()->GetURL("/french_page.html")),
-                ui::PAGE_TRANSITION_TYPED);
+  ASSERT_TRUE(AddTabAtIndex(
+      0, GURL(embedded_test_server()->GetURL("/french_page.html")),
+      ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
   chrome_translate_client = GetChromeTranslateClient();
   WaitUntilLanguageDetermined(chrome_translate_client);
@@ -2073,10 +2094,10 @@
   SetTranslateScript(kTestValidScript);
 
   // Load a German page and detect it's language
-  AddTabAtIndex(0,
-                GURL(embedded_test_server()->GetURL(
-                    "www.google.com", "/href_translate_test.html")),
-                ui::PAGE_TRANSITION_TYPED);
+  ASSERT_TRUE(AddTabAtIndex(0,
+                            GURL(embedded_test_server()->GetURL(
+                                "www.google.com", "/href_translate_test.html")),
+                            ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
   chrome_translate_client = GetChromeTranslateClient();
   WaitUntilLanguageDetermined(chrome_translate_client);
@@ -2112,9 +2133,9 @@
   ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient();
 
   // Open a new tab with a page in French.
-  AddTabAtIndex(
+  ASSERT_TRUE(AddTabAtIndex(
       0, GURL(embedded_test_server()->GetURL("/translate/fr_iframe_test.html")),
-      ui::PAGE_TRANSITION_TYPED);
+      ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
   chrome_translate_client = GetChromeTranslateClient();
   WaitUntilLanguageDetermined(chrome_translate_client);
@@ -2179,9 +2200,9 @@
   ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient();
 
   // Open a new tab with a page in French.
-  AddTabAtIndex(
+  ASSERT_TRUE(AddTabAtIndex(
       0, GURL(embedded_test_server()->GetURL("/translate/fr_iframe_test.html")),
-      ui::PAGE_TRANSITION_TYPED);
+      ui::PAGE_TRANSITION_TYPED));
   ResetObserver();
   chrome_translate_client = GetChromeTranslateClient();
   WaitUntilLanguageDetermined(chrome_translate_client);
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index d198b088..ca209cda 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -796,6 +796,8 @@
       "android/infobars/update_password_infobar.cc",
       "android/infobars/update_password_infobar.h",
       "android/login_handler_android.cc",
+      "android/logo/logo_bridge.cc",
+      "android/logo/logo_bridge.h",
       "android/omnibox/omnibox_view_util.cc",
       "android/omnibox/omnibox_view_util.h",
       "android/overlay/overlay_window_android.cc",
@@ -913,6 +915,7 @@
       "//components/page_info/core:proto",
       "//components/query_tiles",
       "//components/resources:android_resources",
+      "//components/search_provider_logos",
       "//components/security_state/content/android",
       "//components/subresource_filter/core/browser",
       "//components/thin_webview:thin_webview",
@@ -1069,10 +1072,6 @@
       "find_bar/find_bar_platform_helper.h",
       "focus_tab_after_navigation_helper.cc",
       "focus_tab_after_navigation_helper.h",
-      "font_access/font_access_chooser.cc",
-      "font_access/font_access_chooser.h",
-      "font_access/font_access_chooser_controller.cc",
-      "font_access/font_access_chooser_controller.h",
       "global_error/global_error.cc",
       "global_error/global_error.h",
       "global_error/global_error_bubble_view_base.h",
diff --git a/chrome/browser/ui/android/logo/BUILD.gn b/chrome/browser/ui/android/logo/BUILD.gn
new file mode 100644
index 0000000..0bd6bae
--- /dev/null
+++ b/chrome/browser/ui/android/logo/BUILD.gn
@@ -0,0 +1,71 @@
+# Copyright 2022 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//build/config/android/config.gni")
+import("//build/config/android/rules.gni")
+import("//chrome/browser/buildflags.gni")
+
+android_library("java") {
+  sources = [
+    "java/src/org/chromium/chrome/browser/logo/LogoBridge.java",
+    "java/src/org/chromium/chrome/browser/logo/LogoDelegateImpl.java",
+    "java/src/org/chromium/chrome/browser/logo/LogoView.java",
+  ]
+
+  deps = [
+    ":java_resources",
+    "//base:base_java",
+    "//base:jni_java",
+    "//chrome/browser/profiles/android:java",
+    "//chrome/browser/search_engines/android:java",
+    "//components/image_fetcher:java",
+    "//components/search_engines/android:java",
+    "//content/public/android:content_full_java",
+    "//third_party/androidx:androidx_annotation_annotation_java",
+    "//third_party/gif_player:gif_player_java",
+    "//ui/android:ui_no_recycler_view_java",
+  ]
+  annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
+  resources_package = "org.chromium.chrome.browser.logo"
+}
+
+generate_jni("jni_headers") {
+  sources = [ "java/src/org/chromium/chrome/browser/logo/LogoBridge.java" ]
+}
+
+android_resources("java_resources") {
+  sources = [
+    "java/res/drawable-hdpi/google_logo.png",
+    "java/res/drawable-mdpi/google_logo.png",
+    "java/res/drawable-sw600dp-hdpi/google_logo.png",
+    "java/res/drawable-sw600dp-mdpi/google_logo.png",
+    "java/res/drawable-sw600dp-xhdpi/google_logo.png",
+    "java/res/drawable-sw600dp-xxhdpi/google_logo.png",
+    "java/res/drawable-sw600dp-xxxhdpi/google_logo.png",
+    "java/res/drawable-xhdpi/google_logo.png",
+    "java/res/drawable-xxhdpi/google_logo.png",
+    "java/res/drawable-xxxhdpi/google_logo.png",
+    "java/res/values-night/colors.xml",
+    "java/res/values/colors.xml",
+  ]
+
+  deps = [ "//chrome/browser/ui/android/strings:ui_strings_grd" ]
+}
+
+android_library("javatests") {
+  testonly = true
+  sources = [ "java/src/org/chromium/chrome/browser/logo/LogoViewTest.java" ]
+
+  deps = [
+    ":java",
+    "//base:base_java_test_support",
+    "//chrome/browser/search_engines/android:java",
+    "//components/search_engines/android:java",
+    "//content/public/test/android:content_java_test_support",
+    "//third_party/androidx:androidx_test_runner_java",
+    "//third_party/junit:junit",
+    "//third_party/mockito:mockito_java",
+    "//ui/android:ui_java_test_support",
+  ]
+}
diff --git a/chrome/browser/ui/android/logo/DEPS b/chrome/browser/ui/android/logo/DEPS
new file mode 100644
index 0000000..5a91d10
--- /dev/null
+++ b/chrome/browser/ui/android/logo/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+"+components/image_fetcher/android",
+]
diff --git a/chrome/browser/ui/android/logo/DIR_METADATA b/chrome/browser/ui/android/logo/DIR_METADATA
new file mode 100644
index 0000000..13f4924
--- /dev/null
+++ b/chrome/browser/ui/android/logo/DIR_METADATA
@@ -0,0 +1,4 @@
+monorail {
+  component: "UI>Browser>NewTabPage"
+}
+os: ANDROID
\ No newline at end of file
diff --git a/chrome/browser/ui/android/logo/OWNERS b/chrome/browser/ui/android/logo/OWNERS
new file mode 100644
index 0000000..c1e9864a9
--- /dev/null
+++ b/chrome/browser/ui/android/logo/OWNERS
@@ -0,0 +1 @@
+file://chrome/android/java/src/org/chromium/chrome/browser/ntp/OWNERS
\ No newline at end of file
diff --git a/chrome/android/java/res/drawable-hdpi/google_logo.png b/chrome/browser/ui/android/logo/java/res/drawable-hdpi/google_logo.png
similarity index 100%
rename from chrome/android/java/res/drawable-hdpi/google_logo.png
rename to chrome/browser/ui/android/logo/java/res/drawable-hdpi/google_logo.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/google_logo.png b/chrome/browser/ui/android/logo/java/res/drawable-mdpi/google_logo.png
similarity index 100%
rename from chrome/android/java/res/drawable-mdpi/google_logo.png
rename to chrome/browser/ui/android/logo/java/res/drawable-mdpi/google_logo.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-sw600dp-hdpi/google_logo.png b/chrome/browser/ui/android/logo/java/res/drawable-sw600dp-hdpi/google_logo.png
similarity index 100%
rename from chrome/android/java/res/drawable-sw600dp-hdpi/google_logo.png
rename to chrome/browser/ui/android/logo/java/res/drawable-sw600dp-hdpi/google_logo.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-sw600dp-mdpi/google_logo.png b/chrome/browser/ui/android/logo/java/res/drawable-sw600dp-mdpi/google_logo.png
similarity index 100%
rename from chrome/android/java/res/drawable-sw600dp-mdpi/google_logo.png
rename to chrome/browser/ui/android/logo/java/res/drawable-sw600dp-mdpi/google_logo.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-sw600dp-xhdpi/google_logo.png b/chrome/browser/ui/android/logo/java/res/drawable-sw600dp-xhdpi/google_logo.png
similarity index 100%
rename from chrome/android/java/res/drawable-sw600dp-xhdpi/google_logo.png
rename to chrome/browser/ui/android/logo/java/res/drawable-sw600dp-xhdpi/google_logo.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-sw600dp-xxhdpi/google_logo.png b/chrome/browser/ui/android/logo/java/res/drawable-sw600dp-xxhdpi/google_logo.png
similarity index 100%
rename from chrome/android/java/res/drawable-sw600dp-xxhdpi/google_logo.png
rename to chrome/browser/ui/android/logo/java/res/drawable-sw600dp-xxhdpi/google_logo.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-sw600dp-xxxhdpi/google_logo.png b/chrome/browser/ui/android/logo/java/res/drawable-sw600dp-xxxhdpi/google_logo.png
similarity index 100%
rename from chrome/android/java/res/drawable-sw600dp-xxxhdpi/google_logo.png
rename to chrome/browser/ui/android/logo/java/res/drawable-sw600dp-xxxhdpi/google_logo.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/google_logo.png b/chrome/browser/ui/android/logo/java/res/drawable-xhdpi/google_logo.png
similarity index 100%
rename from chrome/android/java/res/drawable-xhdpi/google_logo.png
rename to chrome/browser/ui/android/logo/java/res/drawable-xhdpi/google_logo.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/google_logo.png b/chrome/browser/ui/android/logo/java/res/drawable-xxhdpi/google_logo.png
similarity index 100%
rename from chrome/android/java/res/drawable-xxhdpi/google_logo.png
rename to chrome/browser/ui/android/logo/java/res/drawable-xxhdpi/google_logo.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/google_logo.png b/chrome/browser/ui/android/logo/java/res/drawable-xxxhdpi/google_logo.png
similarity index 100%
rename from chrome/android/java/res/drawable-xxxhdpi/google_logo.png
rename to chrome/browser/ui/android/logo/java/res/drawable-xxxhdpi/google_logo.png
Binary files differ
diff --git a/chrome/browser/ui/android/logo/java/res/values-night/colors.xml b/chrome/browser/ui/android/logo/java/res/values-night/colors.xml
new file mode 100644
index 0000000..9b5f108
--- /dev/null
+++ b/chrome/browser/ui/android/logo/java/res/values-night/colors.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2022 The Chromium Authors. All rights reserved.
+     Use of this source code is governed by a BSD-style license that can be
+     found in the LICENSE file. -->
+
+<resources xmlns:tools="http://schemas.android.com/tools">
+  <color name="google_logo_tint_color">@android:color/white</color>
+</resources>
diff --git a/chrome/browser/ui/android/logo/java/res/values/colors.xml b/chrome/browser/ui/android/logo/java/res/values/colors.xml
new file mode 100644
index 0000000..51ae6794
--- /dev/null
+++ b/chrome/browser/ui/android/logo/java/res/values/colors.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2022 The Chromium Authors. All rights reserved.
+     Use of this source code is governed by a BSD-style license that can be
+     found in the LICENSE file. -->
+
+<resources xmlns:tools="http://schemas.android.com/tools">
+  <color name="google_logo_tint_color">@android:color/transparent</color>
+</resources>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/LogoBridge.java b/chrome/browser/ui/android/logo/java/src/org/chromium/chrome/browser/logo/LogoBridge.java
similarity index 98%
rename from chrome/android/java/src/org/chromium/chrome/browser/ntp/LogoBridge.java
rename to chrome/browser/ui/android/logo/java/src/org/chromium/chrome/browser/logo/LogoBridge.java
index 5b43599..1151c96 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/LogoBridge.java
+++ b/chrome/browser/ui/android/logo/java/src/org/chromium/chrome/browser/logo/LogoBridge.java
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.chromium.chrome.browser.ntp;
+package org.chromium.chrome.browser.logo;
 
 import android.graphics.Bitmap;
 
@@ -14,7 +14,6 @@
  * Provides access to the search provider's logo via the C++ LogoService.
  */
 public class LogoBridge {
-
     /**
      * A logo for a search provider (e.g. the Yahoo! logo or Google doodle).
      */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/LogoDelegateImpl.java b/chrome/browser/ui/android/logo/java/src/org/chromium/chrome/browser/logo/LogoDelegateImpl.java
similarity index 86%
rename from chrome/android/java/src/org/chromium/chrome/browser/ntp/LogoDelegateImpl.java
rename to chrome/browser/ui/android/logo/java/src/org/chromium/chrome/browser/logo/LogoDelegateImpl.java
index 9f9b411..94f351c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/LogoDelegateImpl.java
+++ b/chrome/browser/ui/android/logo/java/src/org/chromium/chrome/browser/logo/LogoDelegateImpl.java
@@ -2,21 +2,20 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.chromium.chrome.browser.ntp;
+package org.chromium.chrome.browser.logo;
 
 import androidx.annotation.Nullable;
 
+import org.chromium.base.Callback;
 import org.chromium.base.metrics.RecordHistogram;
-import org.chromium.chrome.browser.ntp.LogoBridge.Logo;
-import org.chromium.chrome.browser.ntp.LogoBridge.LogoObserver;
+import org.chromium.chrome.browser.logo.LogoBridge.Logo;
+import org.chromium.chrome.browser.logo.LogoBridge.LogoObserver;
 import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.chrome.browser.suggestions.SuggestionsNavigationDelegate;
 import org.chromium.components.image_fetcher.ImageFetcher;
 import org.chromium.components.image_fetcher.ImageFetcherConfig;
 import org.chromium.components.image_fetcher.ImageFetcherFactory;
 import org.chromium.content_public.browser.LoadUrlParams;
 import org.chromium.ui.base.PageTransition;
-import org.chromium.ui.mojom.WindowOpenDisposition;
 
 import jp.tomorrowkey.android.gifplayer.BaseGifImage;
 
@@ -39,7 +38,7 @@
     private static final int CTA_IMAGE_CLICKED = 1;
     private static final int ANIMATED_LOGO_CLICKED = 2;
 
-    private final SuggestionsNavigationDelegate mNavigationDelegate;
+    private final Callback<LoadUrlParams> mLogoClickedCallback;
     private LogoView mLogoView;
 
     private LogoBridge mLogoBridge;
@@ -53,19 +52,19 @@
 
     /**
      * Construct a new {@link LogoDelegateImpl}.
-     * @param navigationDelegate The delegate for loading the URL when the logo is clicked. May be
+     * @param logoClickedCallback A callback for loading the URL when the logo is clicked. May be
      *         null when click events are not supported.
      * @param logoView The view that shows the search provider logo. Maybe null when the client is
      *         controlling the View presentation itself.
      * @param profile The profile to show the logo for.
      */
-    public LogoDelegateImpl(@Nullable SuggestionsNavigationDelegate navigationDelegate,
+    public LogoDelegateImpl(Callback<LoadUrlParams> logoClickedCallback,
             @Nullable LogoView logoView, Profile profile) {
-        mNavigationDelegate = navigationDelegate;
         mLogoView = logoView;
         mLogoBridge = new LogoBridge(profile);
         mImageFetcher = ImageFetcherFactory.createImageFetcher(
                 ImageFetcherConfig.DISK_CACHE_ONLY, profile.getProfileKey());
+        mLogoClickedCallback = logoClickedCallback;
     }
 
     public void destroy() {
@@ -91,8 +90,7 @@
         } else if (mOnLogoClickUrl != null) {
             RecordHistogram.recordSparseHistogram(LOGO_CLICK_UMA_NAME,
                     isAnimatedLogoShowing ? ANIMATED_LOGO_CLICKED : STATIC_LOGO_CLICKED);
-            mNavigationDelegate.openUrl(WindowOpenDisposition.CURRENT_TAB,
-                    new LoadUrlParams(mOnLogoClickUrl, PageTransition.LINK));
+            mLogoClickedCallback.onResult(new LoadUrlParams(mOnLogoClickUrl, PageTransition.LINK));
         }
     }
 
@@ -132,8 +130,7 @@
                     mShouldRecordLoadTime = false;
                 }
 
-                mOnLogoClickUrl =
-                        (logo != null && mNavigationDelegate != null) ? logo.onClickUrl : null;
+                mOnLogoClickUrl = logo != null ? logo.onClickUrl : null;
                 mAnimatedLogoUrl =
                         (logo != null && mLogoView != null) ? logo.animatedLogoUrl : null;
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/LogoView.java b/chrome/browser/ui/android/logo/java/src/org/chromium/chrome/browser/logo/LogoView.java
similarity index 92%
rename from chrome/android/java/src/org/chromium/chrome/browser/ntp/LogoView.java
rename to chrome/browser/ui/android/logo/java/src/org/chromium/chrome/browser/logo/LogoView.java
index e3c3238..e3fffaa 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/LogoView.java
+++ b/chrome/browser/ui/android/logo/java/src/org/chromium/chrome/browser/logo/LogoView.java
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.chromium.chrome.browser.ntp;
+package org.chromium.chrome.browser.logo;
 
 import android.animation.Animator;
 import android.animation.ObjectAnimator;
@@ -30,8 +30,7 @@
 import androidx.annotation.VisibleForTesting;
 
 import org.chromium.base.ApiCompatibilityUtils;
-import org.chromium.chrome.R;
-import org.chromium.chrome.browser.ntp.LogoBridge.Logo;
+import org.chromium.chrome.browser.logo.LogoBridge.Logo;
 import org.chromium.chrome.browser.search_engines.TemplateUrlServiceFactory;
 import org.chromium.ui.widget.LoadingView;
 
@@ -46,7 +45,6 @@
  * this view and we have an animated GIF logo ready.
  */
 public class LogoView extends FrameLayout implements OnClickListener {
-
     // Number of milliseconds for a new logo to fade in.
     private static final int LOGO_TRANSITION_TIME_MS = 400;
 
@@ -80,21 +78,21 @@
 
     private final Property<LogoView, Float> mTransitionProperty =
             new Property<LogoView, Float>(Float.class, "") {
-        @Override
-        public Float get(LogoView logoView) {
-            return logoView.mTransitionAmount;
-        }
+                @Override
+                public Float get(LogoView logoView) {
+                    return logoView.mTransitionAmount;
+                }
 
-        @Override
-        public void set(LogoView logoView, Float amount) {
-            assert amount >= 0f;
-            assert amount <= 1f;
-            if (logoView.mTransitionAmount != amount) {
-                logoView.mTransitionAmount = amount;
-                invalidate();
-            }
-        }
-    };
+                @Override
+                public void set(LogoView logoView, Float amount) {
+                    assert amount >= 0f;
+                    assert amount <= 1f;
+                    if (logoView.mTransitionAmount != amount) {
+                        logoView.mTransitionAmount = amount;
+                        invalidate();
+                    }
+                }
+            };
 
     /**
      * Handles tasks for the {@link LogoView} shown on an NTP.
@@ -246,12 +244,10 @@
         mFadeAnimation.setDuration(LOGO_TRANSITION_TIME_MS);
         mFadeAnimation.addListener(new Animator.AnimatorListener() {
             @Override
-            public void onAnimationStart(Animator animation) {
-            }
+            public void onAnimationStart(Animator animation) {}
 
             @Override
-            public void onAnimationRepeat(Animator animation) {
-            }
+            public void onAnimationRepeat(Animator animation) {}
 
             @Override
             public void onAnimationEnd(Animator animation) {
@@ -303,8 +299,8 @@
      * @param preventUpscaling Whether the image should not be scaled up. If true, the image might
      *                         not fill the entire view but will still be centered.
      */
-    private void setMatrix(int imageWidth, int imageHeight, Matrix matrix,
-            boolean preventUpscaling) {
+    private void setMatrix(
+            int imageWidth, int imageHeight, Matrix matrix, boolean preventUpscaling) {
         int width = getWidth();
         int height = getHeight();
 
@@ -329,7 +325,7 @@
         if (!TemplateUrlServiceFactory.get().isDefaultSearchEngineGoogle()) return null;
 
         Bitmap defaultLogo = sDefaultLogo == null ? null : sDefaultLogo.get();
-        final int tint = ApiCompatibilityUtils.getColor(resources, R.color.google_logo_tint);
+        final int tint = ApiCompatibilityUtils.getColor(resources, R.color.google_logo_tint_color);
         if (defaultLogo == null || sDefaultLogoTint != tint) {
             if (tint == Color.TRANSPARENT) {
                 defaultLogo = BitmapFactory.decodeResource(resources, R.drawable.google_logo);
@@ -364,8 +360,11 @@
         // doesn't invalidate the right area. Instead invalidate the entire view; the drawable takes
         // up most of the view anyway so this is just as efficient.
         // @see ImageView#invalidateDrawable().
-        if (drawable == mAnimatedLogoDrawable) invalidate();
-        else super.invalidateDrawable(drawable);
+        if (drawable == mAnimatedLogoDrawable) {
+            invalidate();
+        } else {
+            super.invalidateDrawable(drawable);
+        }
     }
 
     @Override
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/LogoViewTest.java b/chrome/browser/ui/android/logo/java/src/org/chromium/chrome/browser/logo/LogoViewTest.java
similarity index 95%
rename from chrome/android/javatests/src/org/chromium/chrome/browser/ntp/LogoViewTest.java
rename to chrome/browser/ui/android/logo/java/src/org/chromium/chrome/browser/logo/LogoViewTest.java
index 02d5c62..dca36ba 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/LogoViewTest.java
+++ b/chrome/browser/ui/android/logo/java/src/org/chromium/chrome/browser/logo/LogoViewTest.java
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.chromium.chrome.browser.ntp;
+package org.chromium.chrome.browser.logo;
 
 import static org.mockito.Mockito.doReturn;
 
@@ -26,7 +26,7 @@
 
 import org.chromium.base.test.BaseJUnit4ClassRunner;
 import org.chromium.base.test.util.Batch;
-import org.chromium.chrome.browser.ntp.LogoBridge.Logo;
+import org.chromium.chrome.browser.logo.LogoBridge.Logo;
 import org.chromium.chrome.browser.search_engines.TemplateUrlServiceFactory;
 import org.chromium.components.search_engines.TemplateUrlService;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
@@ -56,7 +56,7 @@
             mView = new LogoView(activity, null);
             mBitmap = Bitmap.createBitmap(1, 1, Config.ALPHA_8);
             LayoutParams params =
-                new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
+                    new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
             TemplateUrlServiceFactory.setInstanceForTesting(mTemplateUrlService);
             getActivity().setContentView(mView, params);
         });
diff --git a/chrome/browser/android/logo_bridge.cc b/chrome/browser/ui/android/logo/logo_bridge.cc
similarity index 97%
rename from chrome/browser/android/logo_bridge.cc
rename to chrome/browser/ui/android/logo/logo_bridge.cc
index 1df1de69..3f8c18d 100644
--- a/chrome/browser/android/logo_bridge.cc
+++ b/chrome/browser/ui/android/logo/logo_bridge.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/android/logo_bridge.h"
+#include "chrome/browser/ui/android/logo/logo_bridge.h"
 
 #include <jni.h>
 #include <stdint.h>
@@ -12,10 +12,10 @@
 #include "base/android/jni_string.h"
 #include "base/bind.h"
 #include "base/metrics/histogram_macros.h"
-#include "chrome/android/chrome_jni_headers/LogoBridge_jni.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_android.h"
 #include "chrome/browser/search_provider_logos/logo_service_factory.h"
+#include "chrome/browser/ui/android/logo/jni_headers/LogoBridge_jni.h"
 #include "components/search_provider_logos/logo_observer.h"
 #include "components/search_provider_logos/logo_service.h"
 #include "content/public/browser/storage_partition.h"
diff --git a/chrome/browser/android/logo_bridge.h b/chrome/browser/ui/android/logo/logo_bridge.h
similarity index 89%
rename from chrome/browser/android/logo_bridge.h
rename to chrome/browser/ui/android/logo/logo_bridge.h
index 5058dc8d..539e3e7 100644
--- a/chrome/browser/android/logo_bridge.h
+++ b/chrome/browser/ui/android/logo/logo_bridge.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_ANDROID_LOGO_BRIDGE_H_
-#define CHROME_BROWSER_ANDROID_LOGO_BRIDGE_H_
+#ifndef CHROME_BROWSER_UI_ANDROID_LOGO_LOGO_BRIDGE_H_
+#define CHROME_BROWSER_UI_ANDROID_LOGO_LOGO_BRIDGE_H_
 
 #include <jni.h>
 
@@ -48,4 +48,4 @@
   base::WeakPtrFactory<LogoBridge> weak_ptr_factory_{this};
 };
 
-#endif  // CHROME_BROWSER_ANDROID_LOGO_BRIDGE_H_
+#endif  // CHROME_BROWSER_UI_ANDROID_LOGO_LOGO_BRIDGE_H_
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd
index 840bbcd..8650d3f 100644
--- a/chrome/browser/ui/android/strings/android_chrome_strings.grd
+++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -3021,6 +3021,12 @@
       <message name="IDS_FOLLOW_MANAGE_WAITING_FOR_CONTENT" desc="Label this web feed source as waiting for content so the user will know to check  back later.">
         Waiting for content
       </message>
+      <message name="IDS_FEED_FOLLOW_UNKNOWN_ERROR" desc="Toast displayed when a failure occurs attempting to follow or unfollow a web feed.">
+        Something went wrong. Try again later.
+      </message>
+      <message name="IDS_FEED_FOLLOW_NO_CONNECTION_ERROR" desc="Toast displayed when there is no network connection when the user tries to follow or unfollow a web feed.">
+        No connection. Try again later.
+      </message>
       <message name="IDS_NTP_TURN_OFF_FEED" desc="Content description to turn off the feed from the feed header overflow menu.">
         Turn off
       </message>
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_FEED_FOLLOW_NO_CONNECTION_ERROR.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_FEED_FOLLOW_NO_CONNECTION_ERROR.png.sha1
new file mode 100644
index 0000000..37e7f3bd
--- /dev/null
+++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_FEED_FOLLOW_NO_CONNECTION_ERROR.png.sha1
@@ -0,0 +1 @@
+5c07af5d0a326420360c65ed3646a890427d2080
\ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_FEED_FOLLOW_UNKNOWN_ERROR.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_FEED_FOLLOW_UNKNOWN_ERROR.png.sha1
new file mode 100644
index 0000000..37e7f3bd
--- /dev/null
+++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_FEED_FOLLOW_UNKNOWN_ERROR.png.sha1
@@ -0,0 +1 @@
+5c07af5d0a326420360c65ed3646a890427d2080
\ No newline at end of file
diff --git a/chrome/browser/ui/android/toolbar/java/res/layout/tab_switcher_toolbar.xml b/chrome/browser/ui/android/toolbar/java/res/layout/tab_switcher_toolbar.xml
index 9e9bf16..7c3ad4a 100644
--- a/chrome/browser/ui/android/toolbar/java/res/layout/tab_switcher_toolbar.xml
+++ b/chrome/browser/ui/android/toolbar/java/res/layout/tab_switcher_toolbar.xml
@@ -21,6 +21,7 @@
         android:orientation="horizontal"
         android:visibility="gone">
         <ImageView
+            android:id="@+id/new_tab_view_button"
             android:layout_width="wrap_content"
             android:layout_height="56dp"
             android:layout_gravity="start|top"
@@ -31,6 +32,7 @@
             app:srcCompat="@drawable/new_tab_icon"
             android:contentDescription="@string/accessibility_toolbar_btn_new_tab"/>
         <TextView
+            android:id="@+id/new_tab_view_desc"
             android:layout_width="wrap_content"
             android:layout_height="match_parent"
             android:paddingEnd="16dp"
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTopToolbar.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTopToolbar.java
index 379225ce..4bb08fb 100644
--- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTopToolbar.java
+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTopToolbar.java
@@ -12,10 +12,12 @@
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewStub;
+import android.widget.TextView;
 
 import androidx.annotation.Nullable;
 import androidx.appcompat.content.res.AppCompatResources;
 
+import org.chromium.base.ApiCompatibilityUtils;
 import org.chromium.base.supplier.BooleanSupplier;
 import org.chromium.chrome.browser.device.DeviceClassManager;
 import org.chromium.chrome.browser.tabmodel.IncognitoStateProvider;
@@ -30,6 +32,7 @@
 import org.chromium.components.browser_ui.widget.highlight.ViewHighlighter;
 import org.chromium.components.browser_ui.widget.highlight.ViewHighlighter.HighlightParams;
 import org.chromium.components.browser_ui.widget.highlight.ViewHighlighter.HighlightShape;
+import org.chromium.ui.base.DeviceFormFactor;
 import org.chromium.ui.util.ColorUtils;
 import org.chromium.ui.widget.OptimizedFrameLayout;
 
@@ -251,13 +254,11 @@
     /** Called when incognito tab existence changes. */
     void onIncognitoTabsExistenceChanged(boolean doesExist) {
         if (!doesExist == mShouldShowNewTabVariation) return;
-        mShouldShowNewTabVariation = !doesExist;
+        mShouldShowNewTabVariation = shouldShowNewTabVariation(doesExist);
 
-        // TODO(crbug.com/1012014): Address the empty top toolbar issue when adaptive toolbar and
-        // new tab variation are both on.
-        // Show new tab variation when there are no incognito tabs.
-        assert mIncognitoToggleTabLayout != null;
-        mIncognitoToggleTabLayout.setVisibility(mShouldShowNewTabVariation ? GONE : VISIBLE);
+        if (mIncognitoToggleTabLayout != null) {
+            mIncognitoToggleTabLayout.setVisibility(mShouldShowNewTabVariation ? GONE : VISIBLE);
+        }
         updateNewTabButtonVisibility();
     }
 
@@ -316,6 +317,15 @@
         if (mToggleTabStackButton != null) {
             mToggleTabStackButton.setUseLightDrawables(useLightIcons);
         }
+
+        if (mNewTabViewButton != null) {
+            ApiCompatibilityUtils.setImageTintList(
+                    mNewTabViewButton.findViewById(R.id.new_tab_view_button),
+                    useLightIcons ? mLightIconTint : mDarkIconTint);
+            final TextView newTabViewDesc = mNewTabViewButton.findViewById(R.id.new_tab_view_desc);
+            newTabViewDesc.setTextColor(useLightIcons ? mLightIconTint.getDefaultColor()
+                                                      : mDarkIconTint.getDefaultColor());
+        }
     }
 
     private int getToolbarColorForCurrentState() {
@@ -360,10 +370,23 @@
     }
 
     /**
-     * @return Whether or not incognito toggle should be visible based on the enabled features
-     *         and incognito status.
+     * @return Whether or not incognito toggle should be visible based on the enabled features,
+     *         incognito status and form-factor.
      */
     private boolean shouldShowIncognitoToggle() {
-        return mIsGridTabSwitcherEnabled && mIsIncognitoModeEnabledSupplier.getAsBoolean();
+        return mIsGridTabSwitcherEnabled && mIsIncognitoModeEnabledSupplier.getAsBoolean()
+                && !DeviceFormFactor.isNonMultiDisplayContextOnTablet(getContext());
+    }
+
+    /**
+     * @return Whether or not new tab variant should be enabled based on if incognito tabs exists
+     * and form factor. Always returns true for tablets.
+     */
+    private boolean shouldShowNewTabVariation(boolean incognitoTabExists) {
+        if (DeviceFormFactor.isNonMultiDisplayContextOnTablet(getContext())) {
+            return true;
+        }
+
+        return !incognitoTabExists;
     }
 }
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java
index 6e628df..c4cf6b0 100644
--- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java
+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java
@@ -22,6 +22,8 @@
 import org.chromium.base.supplier.Supplier;
 import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider;
 import org.chromium.chrome.browser.device.DeviceClassManager;
+import org.chromium.chrome.browser.flags.CachedFeatureFlags;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.layouts.LayoutManager;
 import org.chromium.chrome.browser.layouts.LayoutStateProvider;
 import org.chromium.chrome.browser.layouts.LayoutType;
@@ -159,28 +161,26 @@
 
         mTabModelSelectorSupplier = tabModelSelectorSupplier;
 
-        if (mToolbarLayout instanceof ToolbarPhone) {
-            if (isStartSurfaceEnabled) {
-                if (shouldHideToolbarLayoutOnStart) mToolbarLayout.setVisibility(View.GONE);
-                View.OnClickListener homeButtonOnClickListener = v -> {
-                    if (tabController != null) {
-                        tabController.openHomepage();
-                    }
-                };
-                mStartSurfaceToolbarCoordinator = new StartSurfaceToolbarCoordinator(
-                        controlContainer.getRootView().findViewById(R.id.tab_switcher_toolbar_stub),
-                        userEducationHelper, identityDiscStateSupplier, overviewThemeColorProvider,
-                        overviewModeMenuButtonCoordinator, identityDiscButtonSupplier,
-                        isGridTabSwitcherEnabled, homepageEnabledSupplier,
-                        startSurfaceAsHomepageSupplier, homepageManagedByPolicySupplier,
-                        homeButtonOnClickListener, isTabGroupsAndroidContinuationEnabled,
-                        isIncognitoModeEnabledSupplier);
-            } else {
+        if (mToolbarLayout instanceof ToolbarPhone && isStartSurfaceEnabled) {
+            if (shouldHideToolbarLayoutOnStart) mToolbarLayout.setVisibility(View.GONE);
+            View.OnClickListener homeButtonOnClickListener = v -> {
+                if (tabController != null) {
+                    tabController.openHomepage();
+                }
+            };
+            mStartSurfaceToolbarCoordinator = new StartSurfaceToolbarCoordinator(
+                    controlContainer.getRootView().findViewById(R.id.tab_switcher_toolbar_stub),
+                    userEducationHelper, identityDiscStateSupplier, overviewThemeColorProvider,
+                    overviewModeMenuButtonCoordinator, identityDiscButtonSupplier,
+                    isGridTabSwitcherEnabled, homepageEnabledSupplier,
+                    startSurfaceAsHomepageSupplier, homepageManagedByPolicySupplier,
+                    homeButtonOnClickListener, isTabGroupsAndroidContinuationEnabled,
+                    isIncognitoModeEnabledSupplier);
+        } else if (mToolbarLayout instanceof ToolbarPhone || isTabletGridTabSwitcherEnabled()) {
                 mTabSwitcherModeCoordinator = new TabSwitcherModeTTCoordinator(
-                        controlContainer.getRootView().findViewById(R.id.tab_switcher_toolbar_stub),
-                        overviewModeMenuButtonCoordinator, isGridTabSwitcherEnabled,
-                        isTabToGtsAnimationEnabled, isIncognitoModeEnabledSupplier);
-            }
+                    controlContainer.getRootView().findViewById(R.id.tab_switcher_toolbar_stub),
+                    overviewModeMenuButtonCoordinator, isGridTabSwitcherEnabled,
+                    isTabToGtsAnimationEnabled, isIncognitoModeEnabledSupplier);
         }
         mIsGridTabSwitcherEnabled = isGridTabSwitcherEnabled;
         controlContainer.setToolbar(this, initializeWithIncognitoColors);
@@ -194,6 +194,10 @@
         mToolbarLayout.setInvalidatorCallback(invalidatorCallback);
     }
 
+    private boolean isTabletGridTabSwitcherEnabled() {
+        return CachedFeatureFlags.isEnabled(ChromeFeatureList.GRID_TAB_SWITCHER_FOR_TABLETS);
+    }
+
     /**
      * @param appMenuButtonHelper The helper for managing menu button interactions.
      */
diff --git a/chrome/browser/ui/apps/chrome_app_delegate.cc b/chrome/browser/ui/apps/chrome_app_delegate.cc
index f39a2c32..80c3ce2 100644
--- a/chrome/browser/ui/apps/chrome_app_delegate.cc
+++ b/chrome/browser/ui/apps/chrome_app_delegate.cc
@@ -9,6 +9,7 @@
 #include <vector>
 
 #include "base/bind.h"
+#include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/app_mode/app_mode_utils.h"
 #include "chrome/browser/apps/platform_apps/audio_focus_web_contents_observer.h"
@@ -54,7 +55,7 @@
 #include "chrome/browser/ash/lock_screen_apps/state_controller.h"
 #endif
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 #include "chrome/browser/chromeos/policy/dlp/dlp_content_tab_helper.h"
 #endif
 
@@ -229,7 +230,7 @@
 
   apps::AudioFocusWebContentsObserver::CreateForWebContents(web_contents);
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   policy::DlpContentTabHelper::MaybeCreateForWebContents(web_contents);
 #endif
 
diff --git a/chrome/browser/ui/apps/chrome_app_window_client.cc b/chrome/browser/ui/apps/chrome_app_window_client.cc
index cf7e01a..524fe73 100644
--- a/chrome/browser/ui/apps/chrome_app_window_client.cc
+++ b/chrome/browser/ui/apps/chrome_app_window_client.cc
@@ -23,7 +23,7 @@
 
 // TODO(jamescook): We probably shouldn't compile this class at all on Android.
 // See http://crbug.com/343612
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 #include "chrome/browser/ui/apps/chrome_app_delegate.h"
 #endif
 
@@ -43,7 +43,7 @@
 extensions::AppWindow* ChromeAppWindowClient::CreateAppWindow(
     content::BrowserContext* context,
     const extensions::Extension* extension) {
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   return NULL;
 #else
   Profile* profile = Profile::FromBrowserContext(context);
@@ -73,7 +73,7 @@
 extensions::NativeAppWindow* ChromeAppWindowClient::CreateNativeAppWindow(
     extensions::AppWindow* window,
     extensions::AppWindow::CreateParams* params) {
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   return nullptr;
 #else
   return CreateNativeAppWindowImpl(window, *params);
diff --git a/chrome/browser/ui/ash/accessibility/fake_accessibility_controller.cc b/chrome/browser/ui/ash/accessibility/fake_accessibility_controller.cc
index a9ca9b9..83a7252 100644
--- a/chrome/browser/ui/ash/accessibility/fake_accessibility_controller.cc
+++ b/chrome/browser/ui/ash/accessibility/fake_accessibility_controller.cc
@@ -107,4 +107,5 @@
 
 void FakeAccessibilityController::UpdateDictationBubble(
     bool visible,
+    ash::DictationBubbleIconType icon,
     const absl::optional<std::u16string>& text) {}
diff --git a/chrome/browser/ui/ash/accessibility/fake_accessibility_controller.h b/chrome/browser/ui/ash/accessibility/fake_accessibility_controller.h
index 9398f92..29a53c62 100644
--- a/chrome/browser/ui/ash/accessibility/fake_accessibility_controller.h
+++ b/chrome/browser/ui/ash/accessibility/fake_accessibility_controller.h
@@ -69,6 +69,7 @@
       const std::u16string& display_language) override;
   void UpdateDictationBubble(
       bool visible,
+      ash::DictationBubbleIconType icon,
       const absl::optional<std::u16string>& text) override;
 
  private:
diff --git a/chrome/browser/ui/ash/desks_templates/chrome_desks_templates_delegate.cc b/chrome/browser/ui/ash/desks_templates/chrome_desks_templates_delegate.cc
index bdb95c3..45f3e47 100644
--- a/chrome/browser/ui/ash/desks_templates/chrome_desks_templates_delegate.cc
+++ b/chrome/browser/ui/ash/desks_templates/chrome_desks_templates_delegate.cc
@@ -7,8 +7,9 @@
 #include "ash/constants/app_types.h"
 #include "ash/constants/ash_features.h"
 #include "ash/public/cpp/desk_template.h"
-#include "ash/public/cpp/toast_data.h"
-#include "ash/public/cpp/toast_manager.h"
+#include "ash/public/cpp/system/toast_catalog.h"
+#include "ash/public/cpp/system/toast_data.h"
+#include "ash/public/cpp/system/toast_manager.h"
 #include "ash/strings/grit/ash_strings.h"
 #include "base/bind.h"
 #include "base/check.h"
@@ -144,6 +145,7 @@
   }
 
   ash::ToastData toast_data = {/*id=*/kAppNotAvailableTemplateToastName,
+                               ash::ToastCatalogName::kAppNotAvailable,
                                /*text=*/toast_string};
   ash::ToastManager::Get()->Show(toast_data);
 }
diff --git a/chrome/browser/ui/ash/desks_templates/desks_templates_client_browsertest.cc b/chrome/browser/ui/ash/desks_templates/desks_templates_client_browsertest.cc
index 54d1d491..72a7cf9f 100644
--- a/chrome/browser/ui/ash/desks_templates/desks_templates_client_browsertest.cc
+++ b/chrome/browser/ui/ash/desks_templates/desks_templates_client_browsertest.cc
@@ -15,6 +15,7 @@
 #include "ash/public/cpp/shell_window_ids.h"
 #include "ash/session/session_controller_impl.h"
 #include "ash/shell.h"
+#include "ash/wm/desks/desk.h"
 #include "ash/wm/desks/desks_test_util.h"
 #include "ash/wm/desks/templates/desks_templates_test_util.h"
 #include "ash/wm/overview/overview_test_util.h"
@@ -48,6 +49,7 @@
 #include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/ui_test_utils.h"
 #include "chromeos/ui/base/window_state_type.h"
 #include "components/app_restore/app_launch_info.h"
 #include "components/app_restore/features.h"
@@ -70,6 +72,7 @@
 #include "ui/display/screen.h"
 #include "ui/events/test/event_generator.h"
 #include "ui/views/controls/button/button.h"
+#include "ui/views/controls/button/label_button.h"
 #include "url/gurl.h"
 
 using ::testing::_;
@@ -106,6 +109,8 @@
   return urls;
 }
 
+// TODO(crbug.com/1286515): Remove this. Tests should navigate to overview and
+// click the button using an event generator.
 std::unique_ptr<ash::DeskTemplate> CaptureActiveDeskAndSaveTemplate() {
   base::RunLoop run_loop;
   std::unique_ptr<ash::DeskTemplate> desk_template;
@@ -172,11 +177,34 @@
   event_generator.ClickLeftButton();
 }
 
-void ClickSaveDeskAsTemplateButton() {
+// If `wait_for_ui` is true, wait for the callback from the model to update the
+// UI.
+void ClickSaveDeskAsTemplateButton(bool wait_for_ui) {
   views::Button* save_desk_as_template_button =
       ash::GetSaveDeskAsTemplateButton();
   DCHECK(save_desk_as_template_button);
   ClickButton(save_desk_as_template_button);
+  if (wait_for_ui)
+    ash::WaitForDesksTemplatesUI();
+}
+
+void ClickSaveDeskAsTemplateButton() {
+  ClickSaveDeskAsTemplateButton(/*wait_for_ui=*/true);
+}
+
+void ClickZeroStateTemplatesButton() {
+  views::Button* zero_state_templates_button =
+      ash::GetZeroStateDesksTemplatesButton();
+  ASSERT_TRUE(zero_state_templates_button);
+  ClickButton(zero_state_templates_button);
+  ash::WaitForDesksTemplatesUI();
+}
+
+void ClickExpandedStateTemplatesButton() {
+  views::Button* expanded_state_templates_button =
+      ash::GetExpandedStateDesksTemplatesButton();
+  ASSERT_TRUE(expanded_state_templates_button);
+  ClickButton(expanded_state_templates_button);
   ash::WaitForDesksTemplatesUI();
 }
 
@@ -189,6 +217,22 @@
   ash::WaitForDesksTemplatesUI();
 }
 
+const std::vector<ash::DeskTemplate*> GetAllEntries() {
+  std::vector<ash::DeskTemplate*> templates;
+  base::RunLoop loop;
+  DesksTemplatesClient::Get()->GetDeskModel()->GetAllEntries(
+      base::BindLambdaForTesting(
+          [&](desks_storage::DeskModel::GetAllEntriesStatus status,
+              const std::vector<ash::DeskTemplate*>& entries) {
+            DCHECK_EQ(desks_storage::DeskModel::GetAllEntriesStatus::kOk,
+                      status);
+            templates = entries;
+            loop.Quit();
+          }));
+  loop.Run();
+  return templates;
+}
+
 class MockDesksTemplatesAppLaunchHandler
     : public DesksTemplatesAppLaunchHandler {
  public:
@@ -474,7 +518,6 @@
   const std::u16string kDeskName(u"Test Desk Name");
 
   auto* desks_controller = ash::DesksController::Get();
-
   ASSERT_EQ(0, desks_controller->GetActiveDeskIndex());
 
   // TODO(crbug.com/1273532): Note that `SetTemplate` allows setting an empty
@@ -1028,7 +1071,9 @@
 }
 
 // Tests that basic operations using the native UI work as expected.
-// TODO(crbug.com/1286515): Remove the NativeUI prefix from these tests.
+// TODO(crbug.com/1286515): Remove the NativeUI prefix from these tests. Remove
+// the tests that do not have the NativeUI prefix other than GetDeskTemplateJson
+// once the extension is deprecated.
 IN_PROC_BROWSER_TEST_F(DesksTemplatesClientTest, NativeUIBasic) {
   auto* desk_model = DesksTemplatesClient::Get()->GetDeskModel();
   ASSERT_EQ(0, desk_model->GetEntryCount());
@@ -1118,6 +1163,90 @@
             browser_window->parent());
 }
 
+// Tests that a browser's urls can be captured correctly in the desk template.
+IN_PROC_BROWSER_TEST_F(DesksTemplatesClientTest,
+                       NativeUICaptureBrowserUrlsTest) {
+  // Create a new browser and add a few tabs to it.
+  Browser* browser = CreateBrowser({GURL(kExampleUrl1), GURL(kExampleUrl2)});
+  aura::Window* window = browser->window()->GetNativeWindow();
+
+  const int32_t browser_window_id =
+      window->GetProperty(app_restore::kWindowIdKey);
+  // Get current tabs from browser.
+  std::vector<GURL> urls = GetURLsForBrowserWindow(browser);
+
+  ash::ToggleOverview();
+  ash::WaitForOverviewEnterAnimation();
+
+  ClickSaveDeskAsTemplateButton();
+
+  std::vector<ash::DeskTemplate*> templates = GetAllEntries();
+  ASSERT_EQ(1u, templates.size());
+
+  ash::DeskTemplate* desk_template = templates.front();
+  const app_restore::RestoreData* restore_data =
+      desk_template->desk_restore_data();
+  const auto& app_id_to_launch_list = restore_data->app_id_to_launch_list();
+  EXPECT_EQ(app_id_to_launch_list.size(), 1u);
+
+  // Find `browser` window's app restore data.
+  auto iter = app_id_to_launch_list.find(extension_misc::kChromeAppId);
+  ASSERT_TRUE(iter != app_id_to_launch_list.end());
+  auto app_restore_data_iter = iter->second.find(browser_window_id);
+  ASSERT_TRUE(app_restore_data_iter != iter->second.end());
+  const auto& data = app_restore_data_iter->second;
+  // Check the urls are captured correctly in the `desk_template`.
+  EXPECT_EQ(data->urls.value(), urls);
+}
+
+// Tests that incognito browser windows will NOT be captured in the desk
+// template.
+IN_PROC_BROWSER_TEST_F(DesksTemplatesClientTest,
+                       NativeUICaptureIncognitoBrowserTest) {
+  Browser* incognito_browser = CreateIncognitoBrowser();
+  chrome::AddTabAt(incognito_browser, GURL(kExampleUrl1), /*index=*/-1,
+                   /*foreground=*/true);
+  chrome::AddTabAt(incognito_browser, GURL(kExampleUrl2), /*index=*/-1,
+                   /*foreground=*/true);
+  incognito_browser->window()->Show();
+  aura::Window* window = incognito_browser->window()->GetNativeWindow();
+
+  const int32_t incognito_browser_window_id =
+      window->GetProperty(app_restore::kWindowIdKey);
+
+  ash::ToggleOverview();
+  ash::WaitForOverviewEnterAnimation();
+
+  // Incognito browsers are unsupported so a dialog will popup asking users if
+  // they are sure. Use a key press to accept the dialog instead of a click as
+  // dialog buttons think a click generated by the event generator is an
+  // accidentally click and therefore ignores it.
+  ClickSaveDeskAsTemplateButton(/*wait_for_ui=*/false);
+  views::Button* dialog_accept_button =
+      ash::GetDesksTemplatesDialogAcceptButton();
+  ASSERT_TRUE(dialog_accept_button);
+  aura::Window* root_window =
+      dialog_accept_button->GetWidget()->GetNativeWindow()->GetRootWindow();
+  ui::test::EventGenerator event_generator(root_window);
+  event_generator.PressAndReleaseKey(ui::VKEY_RETURN);
+
+  std::vector<ash::DeskTemplate*> templates = GetAllEntries();
+  ASSERT_EQ(1u, templates.size());
+
+  ash::DeskTemplate* desk_template = templates.front();
+  const app_restore::RestoreData* restore_data =
+      desk_template->desk_restore_data();
+  const auto& app_id_to_launch_list = restore_data->app_id_to_launch_list();
+  EXPECT_EQ(1u, app_id_to_launch_list.size());
+
+  // Find `browser` window's app restore data.
+  auto iter = app_id_to_launch_list.find(extension_misc::kChromeAppId);
+  ASSERT_FALSE(iter == app_id_to_launch_list.end());
+  auto app_restore_data_iter = iter->second.find(incognito_browser_window_id);
+  // Created incognito window is NOT in restore list.
+  EXPECT_TRUE(iter->second.end() == app_restore_data_iter);
+}
+
 // Tests that launching a template that contains a system web app works as
 // expected.
 IN_PROC_BROWSER_TEST_F(DesksTemplatesClientTest,
@@ -1150,12 +1279,7 @@
   ash::ToggleOverview();
   ash::WaitForOverviewEnterAnimation();
 
-  views::Button* zero_state_templates_button =
-      ash::GetZeroStateDesksTemplatesButton();
-  ASSERT_TRUE(zero_state_templates_button);
-  ClickButton(zero_state_templates_button);
-  ash::WaitForDesksTemplatesUI();
-
+  ClickZeroStateTemplatesButton();
   ClickFirstTemplateItem();
 
   for (auto* browser : *BrowserList::GetInstance()) {
@@ -1210,12 +1334,8 @@
   // template.
   ash::ToggleOverview();
   ash::WaitForOverviewEnterAnimation();
-  views::Button* zero_state_templates_button =
-      ash::GetZeroStateDesksTemplatesButton();
-  ASSERT_TRUE(zero_state_templates_button);
-  ClickButton(zero_state_templates_button);
-  ash::WaitForDesksTemplatesUI();
 
+  ClickZeroStateTemplatesButton();
   ClickFirstTemplateItem();
 
   // Wait for the tabs to load.
@@ -1240,6 +1360,549 @@
   EXPECT_EQ(gfx::Rect(), settings_window->layer()->clip_rect());
 }
 
+// Tests that browser windows created from a template have the correct bounds
+// and window state.
+IN_PROC_BROWSER_TEST_F(DesksTemplatesClientTest,
+                       NativeUIBrowserWindowRestorationTest) {
+  // Create a new browser and set its bounds.
+  Browser* browser_1 = CreateBrowser({GURL(kExampleUrl1), GURL(kExampleUrl2)});
+  const gfx::Rect browser_bounds_1 = gfx::Rect(100, 100, 600, 200);
+  aura::Window* window_1 = browser_1->window()->GetNativeWindow();
+  window_1->SetBounds(browser_bounds_1);
+
+  // Create a new minimized browser.
+  Browser* browser_2 = CreateBrowser({GURL(kExampleUrl1)});
+  const gfx::Rect browser_bounds_2 = gfx::Rect(150, 150, 500, 300);
+  aura::Window* window_2 = browser_2->window()->GetNativeWindow();
+  window_2->SetBounds(browser_bounds_2);
+  EXPECT_EQ(browser_bounds_2, window_2->bounds());
+  browser_2->window()->Minimize();
+
+  // Create a new maximized browser.
+  Browser* browser_3 = CreateBrowser({GURL(kExampleUrl1)});
+  browser_3->window()->Maximize();
+
+  EXPECT_EQ(browser_bounds_1, window_1->bounds());
+  EXPECT_EQ(browser_bounds_2, window_2->bounds());
+  ASSERT_TRUE(browser_2->window()->IsMinimized());
+  ASSERT_TRUE(browser_3->window()->IsMaximized());
+
+  const int32_t browser_window_id_1 =
+      window_1->GetProperty(app_restore::kWindowIdKey);
+  const int32_t browser_window_id_2 =
+      window_2->GetProperty(app_restore::kWindowIdKey);
+  const int32_t browser_window_id_3 =
+      browser_3->window()->GetNativeWindow()->GetProperty(
+          app_restore::kWindowIdKey);
+
+  // Capture the active desk, which contains the three browser windows.
+  ash::ToggleOverview();
+  ash::WaitForOverviewEnterAnimation();
+  ClickSaveDeskAsTemplateButton();
+
+  ClickFirstTemplateItem();
+
+  // Wait for the tabs to load.
+  content::RunAllTasksUntilIdle();
+
+  // Verify that the browser was launched with the correct bounds.
+  Browser* new_browser_1 = FindBrowser(browser_window_id_1);
+  ASSERT_TRUE(new_browser_1);
+  EXPECT_EQ(browser_bounds_1,
+            new_browser_1->window()->GetNativeWindow()->bounds());
+
+  // Verify that the browser was launched and minimized.
+  Browser* new_browser_2 = FindBrowser(browser_window_id_2);
+  ASSERT_TRUE(new_browser_2);
+  ASSERT_TRUE(new_browser_2->window()->IsMinimized());
+  EXPECT_EQ(browser_bounds_2,
+            new_browser_2->window()->GetNativeWindow()->bounds());
+
+  // Verify that the browser was launched and maximized.
+  Browser* new_browser_3 = FindBrowser(browser_window_id_3);
+  ASSERT_TRUE(new_browser_3);
+  ASSERT_TRUE(new_browser_3->window()->IsMaximized());
+}
+
+// Tests that saving and launching a template that contains a PWA works as
+// expected.
+IN_PROC_BROWSER_TEST_F(DesksTemplatesClientTest,
+                       NativeUILaunchTemplateWithPWA) {
+  Browser* pwa_browser =
+      InstallAndLaunchPWA(GURL(kExampleUrl1), /*launch_in_browser=*/false);
+  ASSERT_TRUE(pwa_browser->is_type_app());
+  aura::Window* pwa_window = pwa_browser->window()->GetNativeWindow();
+  const gfx::Rect pwa_bounds(50, 50, 500, 500);
+  pwa_window->SetBounds(pwa_bounds);
+  const int32_t pwa_window_id =
+      pwa_window->GetProperty(app_restore::kWindowIdKey);
+  const std::string* app_name =
+      pwa_window->GetProperty(app_restore::kBrowserAppNameKey);
+  ASSERT_TRUE(app_name);
+
+  // Capture the active desk, which contains the PWA.
+  ash::ToggleOverview();
+  ash::WaitForOverviewEnterAnimation();
+  ClickSaveDeskAsTemplateButton();
+
+  std::vector<ash::DeskTemplate*> templates = GetAllEntries();
+  ASSERT_EQ(1u, templates.size());
+
+  // Find `pwa_browser` window's app restore data.
+  ash::DeskTemplate* desk_template = templates.front();
+  const app_restore::RestoreData* restore_data =
+      desk_template->desk_restore_data();
+  const auto& app_id_to_launch_list = restore_data->app_id_to_launch_list();
+  EXPECT_EQ(1u, app_id_to_launch_list.size());
+  ASSERT_TRUE(restore_data->HasAppTypeBrowser());
+  auto iter = app_id_to_launch_list.find(extension_misc::kChromeAppId);
+  ASSERT_TRUE(iter != app_id_to_launch_list.end());
+  auto app_restore_data_iter = iter->second.find(pwa_window_id);
+  ASSERT_TRUE(app_restore_data_iter != iter->second.end());
+  const auto& data = app_restore_data_iter->second;
+  // Verify window info are correctly captured.
+  EXPECT_EQ(pwa_bounds, data->current_bounds.value());
+  ASSERT_TRUE(data->app_type_browser.has_value() &&
+              data->app_type_browser.value());
+  EXPECT_EQ(*app_name, *data->app_name);
+
+  // Launch the template.
+  ClickFirstTemplateItem();
+
+  // Verify that the PWA was launched correctly.
+  Browser* new_pwa_browser = FindBrowser(pwa_window_id);
+  ASSERT_TRUE(new_pwa_browser);
+  ASSERT_TRUE(new_pwa_browser->is_type_app());
+  aura::Window* new_browser_window =
+      new_pwa_browser->window()->GetNativeWindow();
+  EXPECT_NE(new_browser_window, pwa_window);
+  EXPECT_EQ(pwa_bounds, new_browser_window->bounds());
+  const std::string* new_app_name =
+      new_browser_window->GetProperty(app_restore::kBrowserAppNameKey);
+  ASSERT_TRUE(new_app_name);
+  EXPECT_EQ(*app_name, *new_app_name);
+}
+
+// Tests that saving and launching a template that contains a PWA in a browser
+// window works as expected.
+IN_PROC_BROWSER_TEST_F(DesksTemplatesClientTest,
+                       NativeUILaunchTemplateWithPWAInBrowser) {
+  Browser* pwa_browser =
+      InstallAndLaunchPWA(GURL(kYoutubeUrl), /*launch_in_browser=*/true);
+  aura::Window* pwa_window = pwa_browser->window()->GetNativeWindow();
+  const int32_t pwa_window_id =
+      pwa_window->GetProperty(app_restore::kWindowIdKey);
+
+  // Capture the active desk, which contains the PWA.
+  ash::ToggleOverview();
+  ash::WaitForOverviewEnterAnimation();
+  ClickSaveDeskAsTemplateButton();
+
+  std::vector<ash::DeskTemplate*> templates = GetAllEntries();
+  ASSERT_EQ(1u, templates.size());
+
+  // Test that `pwa_browser` restore data can be found.
+  ash::DeskTemplate* desk_template = templates.front();
+  const app_restore::RestoreData* restore_data =
+      desk_template->desk_restore_data();
+  const auto& app_id_to_launch_list = restore_data->app_id_to_launch_list();
+  EXPECT_EQ(1u, app_id_to_launch_list.size());
+
+  // Test that `pwa_browser`'s restore data is saved under the Chrome browser
+  // app id extension_misc::kChromeAppId, not Youtube app id
+  // extension_misc::kYoutubeAppId.
+  auto iter = app_id_to_launch_list.find(extension_misc::kChromeAppId);
+  ASSERT_TRUE(iter != app_id_to_launch_list.end());
+  auto app_restore_data_iter = iter->second.find(pwa_window_id);
+  ASSERT_TRUE(app_restore_data_iter != iter->second.end());
+
+  iter = app_id_to_launch_list.find(extension_misc::kYoutubeAppId);
+  EXPECT_TRUE(iter == app_id_to_launch_list.end());
+}
+
+// Tests that browsers and SWAs can be captured correctly in the desk template.
+IN_PROC_BROWSER_TEST_F(DesksTemplatesClientTest,
+                       NativeUICaptureActiveDeskAsTemplateTest) {
+  // Change `browser`'s bounds.
+  const gfx::Rect browser_bounds(800, 200);
+  aura::Window* window = browser()->window()->GetNativeWindow();
+  window->SetBounds(browser_bounds);
+  // Make the window visible on all desks.
+  window->SetProperty(aura::client::kWindowWorkspaceKey,
+                      aura::client::kWindowWorkspaceVisibleOnAllWorkspaces);
+  const int32_t browser_window_id =
+      window->GetProperty(app_restore::kWindowIdKey);
+
+  // Create the settings app, which is a system web app.
+  web_app::AppId settings_app_id =
+      CreateSettingsSystemWebApp(browser()->profile());
+
+  // Change the Settings app's bounds too.
+  const gfx::Rect settings_app_bounds(100, 100, 800, 300);
+  aura::Window* settings_window = FindBrowserWindow(kSettingsWindowId);
+  const int32_t settings_window_id =
+      settings_window->GetProperty(app_restore::kWindowIdKey);
+  ASSERT_TRUE(settings_window);
+  settings_window->SetBounds(settings_app_bounds);
+
+  auto* desks_controller = ash::DesksController::Get();
+  const std::u16string desk_name =
+      desks_controller->GetDeskName(desks_controller->GetActiveDeskIndex());
+
+  ash::ToggleOverview();
+  ash::WaitForOverviewEnterAnimation();
+
+  ClickSaveDeskAsTemplateButton();
+
+  std::vector<ash::DeskTemplate*> templates = GetAllEntries();
+  ASSERT_EQ(1u, templates.size());
+
+  ash::DeskTemplate* desk_template = templates.front();
+
+  // Test the default template's name is the desk's name it was created from.
+  EXPECT_EQ(desk_name, desk_template->template_name());
+
+  const app_restore::RestoreData* restore_data =
+      desk_template->desk_restore_data();
+  const auto& app_id_to_launch_list = restore_data->app_id_to_launch_list();
+  EXPECT_EQ(2u, app_id_to_launch_list.size());
+
+  // Find `browser` window's app restore data.
+  auto iter = app_id_to_launch_list.find(extension_misc::kChromeAppId);
+  ASSERT_NE(iter, app_id_to_launch_list.end());
+  auto app_restore_data_iter = iter->second.find(browser_window_id);
+  ASSERT_NE(iter->second.end(), app_restore_data_iter);
+  const auto& data = app_restore_data_iter->second;
+  // Verify window info are correctly captured.
+  EXPECT_EQ(browser_bounds, data->current_bounds.value());
+  // `visible_on_all_workspaces` should have been reset even though
+  // the captured window is visible on all workspaces.
+  EXPECT_FALSE(data->desk_id.has_value());
+  auto* screen = display::Screen::GetScreen();
+  EXPECT_EQ(screen->GetDisplayNearestWindow(window).id(),
+            data->display_id.value());
+  EXPECT_EQ(window->GetProperty(aura::client::kShowStateKey),
+            chromeos::ToWindowShowState(data->window_state_type.value()));
+  // We don't capture the window's desk_id as a template will always
+  // create in a new desk.
+  EXPECT_FALSE(data->desk_id.has_value());
+
+  // Find Setting app's app restore data.
+  auto iter2 = app_id_to_launch_list.find(settings_app_id);
+  ASSERT_NE(app_id_to_launch_list.end(), iter2);
+  auto app_restore_data_iter2 = iter2->second.find(settings_window_id);
+  ASSERT_NE(iter->second.end(), app_restore_data_iter2);
+  const auto& data2 = app_restore_data_iter2->second;
+  EXPECT_EQ(
+      static_cast<int>(apps::mojom::LaunchContainer::kLaunchContainerWindow),
+      data2->container.value());
+  EXPECT_EQ(static_cast<int>(WindowOpenDisposition::NEW_WINDOW),
+            data2->disposition.value());
+  // Verify window info are correctly captured.
+  EXPECT_EQ(settings_app_bounds, data2->current_bounds.value());
+  EXPECT_FALSE(data2->desk_id.has_value());
+  EXPECT_EQ(screen->GetDisplayNearestWindow(window).id(),
+            data->display_id.value());
+  EXPECT_EQ(window->GetProperty(aura::client::kShowStateKey),
+            chromeos::ToWindowShowState(data->window_state_type.value()));
+  EXPECT_EQ(window->GetProperty(aura::client::kShowStateKey),
+            chromeos::ToWindowShowState(data->window_state_type.value()));
+  EXPECT_FALSE(data2->desk_id.has_value());
+}
+
+// Tests that launching a template that contains a chrome app works as expected.
+IN_PROC_BROWSER_TEST_F(DesksTemplatesClientTest,
+                       NativeUILaunchTemplateWithChromeApp) {
+  // Create a chrome app.
+  const extensions::Extension* extension =
+      LoadAndLaunchPlatformApp("launch", "Launched");
+  ASSERT_TRUE(extension);
+
+  const std::string extension_id = extension->id();
+  ::full_restore::SaveAppLaunchInfo(
+      profile()->GetPath(),
+      std::make_unique<app_restore::AppLaunchInfo>(
+          extension_id, apps::mojom::LaunchContainer::kLaunchContainerWindow,
+          WindowOpenDisposition::NEW_WINDOW, display::kDefaultDisplayId,
+          std::vector<base::FilePath>{}, nullptr));
+
+  extensions::AppWindow* app_window = CreateAppWindow(profile(), extension);
+  ASSERT_TRUE(app_window);
+  ASSERT_TRUE(GetFirstAppWindowForApp(extension_id));
+
+  // Enter overview and save the current desk as a template.
+  ash::ToggleOverview();
+  ash::WaitForOverviewEnterAnimation();
+
+  ClickSaveDeskAsTemplateButton();
+
+  // Close the chrome app window. We'll need to verify if it reopens later.
+  views::Widget* app_widget =
+      views::Widget::GetWidgetForNativeWindow(app_window->GetNativeWindow());
+  app_widget->CloseNow();
+  ASSERT_FALSE(GetFirstAppWindowForApp(extension_id));
+
+  ash::DesksController* desks_controller = ash::DesksController::Get();
+  ASSERT_EQ(0, desks_controller->GetActiveDeskIndex());
+
+  // `BrowserAppLauncher::LaunchAppWithParams()` does not launch the chrome app
+  // in tests, so here we set up a mock app launch handler and just verify a
+  // `LaunchSystemWebAppOrChromeApp()` call with the associated extension is
+  // seen.
+  auto mock_app_launch_handler =
+      std::make_unique<MockDesksTemplatesAppLaunchHandler>(profile());
+  MockDesksTemplatesAppLaunchHandler* mock_app_launch_handler_ptr =
+      mock_app_launch_handler.get();
+  ScopedDesksTemplatesAppLaunchHandlerSetter scoped_launch_handler(
+      std::move(mock_app_launch_handler));
+
+  EXPECT_CALL(*mock_app_launch_handler_ptr,
+              LaunchSystemWebAppOrChromeApp(_, extension_id, _));
+
+  // Launch the template we saved.
+  ClickFirstTemplateItem();
+}
+
+// Tests that launching the same desk template multiple times creates desks with
+// different/incremented names.
+IN_PROC_BROWSER_TEST_F(DesksTemplatesClientTest,
+                       NativeUILaunchMultipleDeskTemplates) {
+  const base::GUID kDeskUuid = base::GUID::GenerateRandomV4();
+  const std::u16string kDeskName(u"Test Desk Name");
+
+  auto* desks_controller = ash::DesksController::Get();
+
+  ASSERT_EQ(0, desks_controller->GetActiveDeskIndex());
+  desks_controller->desks()[0]->SetName(kDeskName, true);
+
+  // Save a template.
+  ash::ToggleOverview();
+  ash::WaitForOverviewEnterAnimation();
+
+  ClickSaveDeskAsTemplateButton();
+
+  // Helper that launches a template by entering the grid and clicking on the
+  // lone template item, and then checks the expected name.
+  bool first_run = true;
+  auto check_launch_template_desk_name =
+      [kDeskUuid, &first_run](const std::u16string& desk_name) {
+        SCOPED_TRACE(desk_name);
+
+        // We are already on the templates grid after saving the template, so no
+        // need to click the templates button the first time we use this helper.
+        if (!first_run)
+          ClickExpandedStateTemplatesButton();
+
+        ClickFirstTemplateItem();
+
+        // Wait for the tabs to load.
+        content::RunAllTasksUntilIdle();
+
+        // A DCHECK related to the desks templates animation fails without this
+        // wait.
+        // TODO(sammiequon): Find a proper fix and remove this delay.
+        base::RunLoop run_loop;
+        base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+            FROM_HERE, run_loop.QuitClosure(), base::Milliseconds(500));
+        run_loop.Run();
+
+        first_run = false;
+      };
+
+  // Launching a desk from the template creates a desk with the same name as the
+  // template.
+  desks_controller->desks()[0]->SetName(u"Desk", true);
+  check_launch_template_desk_name(kDeskName);
+
+  // Launch more desks from the template and verify that the newly created desks
+  // have unique names.
+  check_launch_template_desk_name(std::u16string(kDeskName).append(u" (1)"));
+  check_launch_template_desk_name(std::u16string(kDeskName).append(u" (2)"));
+
+  // Remove "Test Desk Name (1)", which means the next created desk from
+  // template will have that name. Then it will skip (2) since it already
+  // exists, and create the next desk with (3).
+  RemoveDesk(desks_controller->desks()[2].get());
+  check_launch_template_desk_name(std::u16string(kDeskName).append(u" (1)"));
+  check_launch_template_desk_name(std::u16string(kDeskName).append(u" (3)"));
+
+  // Same as above, but make sure that deleting the desk with the exact template
+  // name still functions the same by only filling in whatever name is
+  // available.
+  RemoveDesk(desks_controller->desks()[1].get());
+  check_launch_template_desk_name(kDeskName);
+  check_launch_template_desk_name(std::u16string(kDeskName).append(u" (4)"));
+}
+
+// Tests that the windows and tabs count histogram is recorded properly.
+IN_PROC_BROWSER_TEST_F(DesksTemplatesClientTest,
+                       NativeUIDeskTemplateWindowAndTabCountHistogram) {
+  base::HistogramTester histogram_tester;
+
+  // Create the settings app, which is a system web app.
+  CreateSettingsSystemWebApp(browser()->profile());
+
+  CreateBrowser({GURL(kExampleUrl1), GURL(kExampleUrl2)});
+  CreateBrowser({GURL(kExampleUrl1), GURL(kExampleUrl2), GURL(kExampleUrl3)});
+
+  // Save a template.
+  ash::ToggleOverview();
+  ash::WaitForOverviewEnterAnimation();
+  ClickSaveDeskAsTemplateButton();
+
+  constexpr char kWindowCountHistogramName[] = "Ash.DeskTemplate.WindowCount";
+  constexpr char kTabCountHistogramName[] = "Ash.DeskTemplate.TabCount";
+  constexpr char kWindowAndTabCountHistogramName[] =
+      "Ash.DeskTemplate.WindowAndTabCount";
+  // NOTE: there is an existing browser with 1 tab created by BrowserMain().
+  histogram_tester.ExpectBucketCount(kWindowCountHistogramName, 4, 1);
+  histogram_tester.ExpectBucketCount(kTabCountHistogramName, 6, 1);
+  histogram_tester.ExpectBucketCount(kWindowAndTabCountHistogramName, 7, 1);
+}
+
+// Tests that the launch from template histogram is recorded properly.
+IN_PROC_BROWSER_TEST_F(DesksTemplatesClientTest,
+                       NativeUIDeskTemplateLaunchFromTemplateHistogram) {
+  base::HistogramTester histogram_tester;
+
+  // Create a new browser.
+  CreateBrowser({});
+
+  // Save a template.
+  ash::ToggleOverview();
+  ash::WaitForOverviewEnterAnimation();
+  ClickSaveDeskAsTemplateButton();
+
+  const int launches = 5;
+  for (int i = 0; i < launches; i++) {
+    ClickFirstTemplateItem();
+
+    // A DCHECK related to the desks templates animation fails without this
+    // wait.
+    // TODO(sammiequon): Find a proper fix and remove this delay.
+    base::RunLoop run_loop;
+    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+        FROM_HERE, run_loop.QuitClosure(), base::Milliseconds(500));
+    run_loop.Run();
+
+    ClickExpandedStateTemplatesButton();
+  }
+
+  // TODO(crbug.com/1287649): This histogram is double counted when a template
+  // is launched from the UI.
+  constexpr char kLaunchFromTemplateHistogramName[] =
+      "Ash.DeskTemplate.LaunchFromTemplate";
+  histogram_tester.ExpectTotalCount(kLaunchFromTemplateHistogramName,
+                                    2 * launches);
+}
+
+// Tests that the template count histogram is recorded properly.
+IN_PROC_BROWSER_TEST_F(DesksTemplatesClientTest,
+                       NativeUIDeskTemplateUserTemplateCountHistogram) {
+  base::HistogramTester histogram_tester;
+
+  ash::ToggleOverview();
+  ash::WaitForOverviewEnterAnimation();
+
+  // Save 3 templates.
+  const int saves = 3;
+  for (int i = 0; i < saves; i++) {
+    ClickSaveDeskAsTemplateButton();
+
+    // Exit and renenter overview to save the next template. Once we are viewing
+    // the grid we can't go back to regular overview unless we exit overview or
+    // delete all the templates.
+    if (i != saves - 1) {
+      ash::ToggleOverview();
+      ash::WaitForOverviewExitAnimation();
+      ash::ToggleOverview();
+      ash::WaitForOverviewEnterAnimation();
+    }
+  }
+
+  views::Button* delete_button = ash::GetTemplateItemDeleteButton(/*index=*/0);
+  ClickButton(delete_button);
+
+  // Confirm deleting a template. Use a key press to accept the dialog instead
+  // of a click as dialog buttons think a click generated by the event generator
+  // is an accidentally click and therefore ignores it.
+  views::Button* dialog_accept_button =
+      ash::GetDesksTemplatesDialogAcceptButton();
+  ASSERT_TRUE(dialog_accept_button);
+  aura::Window* root_window =
+      dialog_accept_button->GetWidget()->GetNativeWindow()->GetRootWindow();
+  ui::test::EventGenerator event_generator(root_window);
+  event_generator.PressAndReleaseKey(ui::VKEY_RETURN);
+
+  // Wait for the model to update.
+  ash::WaitForDesksTemplatesUI();
+
+  // Save one more template.
+  ash::ToggleOverview();
+  ash::WaitForOverviewExitAnimation();
+  ash::ToggleOverview();
+  ash::WaitForOverviewEnterAnimation();
+  ClickSaveDeskAsTemplateButton();
+
+  // Verify that all template saves and deletes are captured by the histogram.
+  constexpr char kUserTemplateCountHistogramName[] =
+      "Ash.DeskTemplate.UserTemplateCount";
+  histogram_tester.ExpectBucketCount(kUserTemplateCountHistogramName, 1, 1);
+  histogram_tester.ExpectBucketCount(kUserTemplateCountHistogramName, 2, 2);
+  histogram_tester.ExpectBucketCount(kUserTemplateCountHistogramName, 3, 2);
+}
+
+// Tests that browser session restore isn't triggered when we launch a template
+// that contains a browser window.
+IN_PROC_BROWSER_TEST_F(DesksTemplatesClientTest,
+                       NativeUIPreventBrowserSessionRestoreTest) {
+  // Do not exit from test or delete the Profile* when last browser is closed.
+  ScopedKeepAlive keep_alive(KeepAliveOrigin::BROWSER,
+                             KeepAliveRestartOption::DISABLED);
+  ScopedProfileKeepAlive profile_keep_alive(
+      browser()->profile(), ProfileKeepAliveOrigin::kBrowserWindow);
+
+  // Enable session service.
+  SessionStartupPref pref(SessionStartupPref::LAST);
+  Profile* profile = browser()->profile();
+  SessionStartupPref::SetStartupPref(profile, pref);
+
+  const int expected_tab_count = 2;
+  chrome::AddTabAt(browser(), GURL(kExampleUrl2), /*index=*/-1,
+                   /*foreground=*/true);
+  EXPECT_EQ(expected_tab_count, browser()->tab_strip_model()->count());
+  const int32_t browser_window_id =
+      browser()->window()->GetNativeWindow()->GetProperty(
+          app_restore::kWindowIdKey);
+
+  // Enter overview and save the current desk as a template.
+  ash::ToggleOverview();
+  ash::WaitForOverviewEnterAnimation();
+
+  ClickSaveDeskAsTemplateButton();
+
+  // Exit overview, close the browser and verify that all browser windows are
+  // closed.
+  ash::ToggleOverview();
+  ash::WaitForOverviewExitAnimation();
+  CloseBrowserSynchronously(browser());
+  EXPECT_EQ(0u, chrome::GetTotalBrowserCount());
+
+  // Reenter overview and launch the template we saved.
+  ash::ToggleOverview();
+  ash::WaitForOverviewEnterAnimation();
+  ash::WaitForDesksTemplatesUI();
+  ClickZeroStateTemplatesButton();
+  ClickFirstTemplateItem();
+
+  // Verify that the browser was launched with the correct number of tabs, and
+  // that browser session restore did not restore any windows/tabs.
+  Browser* new_browser = FindBrowser(browser_window_id);
+  ASSERT_TRUE(new_browser);
+  EXPECT_EQ(expected_tab_count, GetURLsForBrowserWindow(new_browser).size());
+  EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
+}
+
 class DesksTemplatesClientArcTest : public InProcessBrowserTest {
  public:
   DesksTemplatesClientArcTest() {
@@ -1320,12 +1983,8 @@
   // template.
   ash::ToggleOverview();
   ash::WaitForOverviewEnterAnimation();
-  views::Button* zero_state_templates_button =
-      ash::GetZeroStateDesksTemplatesButton();
-  ASSERT_TRUE(zero_state_templates_button);
-  ClickButton(zero_state_templates_button);
-  ash::WaitForDesksTemplatesUI();
 
+  ClickZeroStateTemplatesButton();
   ClickFirstTemplateItem();
 
   ash::ToggleOverview();
@@ -1347,15 +2006,6 @@
   arc_helper()->StopInstance();
 }
 
-// TODO(crbug.com/1273532): Add more tests:
-// - Deleting templates.
-// - Launching templates with uninstalled apps.
-// - Launching ARC apps which already have an instance open.
-// - Test for spoken feedback.
-// - Port tests that use `DesksTemplatesClient` directly. These were meant to
-//   test launching while the prototype extension was being built, but now we
-//   can do end to end tests with the native UI.
-
 class DesksTemplatesClientMultiProfileTest : public ash::LoginManagerTest {
  public:
   DesksTemplatesClientMultiProfileTest() : ash::LoginManagerTest() {
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_ui_browsertest.cc b/chrome/browser/ui/ash/holding_space/holding_space_ui_browsertest.cc
index 9dff61ea..8fa941b 100644
--- a/chrome/browser/ui/ash/holding_space/holding_space_ui_browsertest.cc
+++ b/chrome/browser/ui/ash/holding_space/holding_space_ui_browsertest.cc
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/ui/ash/holding_space/holding_space_browsertest_base.h"
-
 #include <set>
 #include <unordered_map>
 #include <vector>
@@ -31,11 +29,13 @@
 #include "base/scoped_observation.h"
 #include "base/test/bind.h"
 #include "base/test/scoped_locale.h"
+#include "build/build_config.h"
 #include "chrome/browser/ash/crosapi/crosapi_ash.h"
 #include "chrome/browser/ash/crosapi/crosapi_manager.h"
 #include "chrome/browser/ash/profiles/profile_helper.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/ui/ash/holding_space/holding_space_browsertest_base.h"
 #include "chrome/browser/ui/ash/holding_space/holding_space_downloads_delegate.h"
 #include "chrome/browser/ui/ash/holding_space/holding_space_keyed_service_factory.h"
 #include "chrome/browser/ui/ash/holding_space/holding_space_util.h"
@@ -693,7 +693,7 @@
 }
 
 // Disabled due to flakiness. http://crbug.com/1261364
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 #define MAYBE_DragAndDropToPin DISABLED_DragAndDropToPin
 #else
 #define MAYBE_DragAndDropToPin DragAndDropToPin
diff --git a/chrome/browser/ui/ash/media_client_impl.cc b/chrome/browser/ui/ash/media_client_impl.cc
index b31a952..77fc82b 100644
--- a/chrome/browser/ui/ash/media_client_impl.cc
+++ b/chrome/browser/ui/ash/media_client_impl.cc
@@ -9,8 +9,9 @@
 #include "ash/constants/ash_features.h"
 #include "ash/public/cpp/media_controller.h"
 #include "ash/public/cpp/notification_utils.h"
-#include "ash/public/cpp/toast_data.h"
-#include "ash/public/cpp/toast_manager.h"
+#include "ash/public/cpp/system/toast_catalog.h"
+#include "ash/public/cpp/system/toast_data.h"
+#include "ash/public/cpp/system/toast_manager.h"
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/check_op.h"
@@ -397,6 +398,7 @@
       ash::ToastManager::Get()->Cancel(kCameraPrivacySwitchOffToastId);
       ash::ToastData toast(
           kCameraPrivacySwitchOnToastId,
+          ash::ToastCatalogName::kCameraPrivacySwitchOn,
           l10n_util::GetStringUTF16(IDS_CAMERA_PRIVACY_SWITCH_ON_TOAST),
           ash::ToastData::kDefaultToastDurationMs,
           /*visible_on_lock_screen=*/true);
@@ -432,6 +434,7 @@
       ash::ToastManager::Get()->Cancel(kCameraPrivacySwitchOnToastId);
       ash::ToastData toast(
           kCameraPrivacySwitchOffToastId,
+          ash::ToastCatalogName::kCameraPrivacySwitchOff,
           l10n_util::GetStringUTF16(IDS_CAMERA_PRIVACY_SWITCH_OFF_TOAST),
           ash::ToastData::kDefaultToastDurationMs,
           /*visible_on_lock_screen=*/true);
diff --git a/chrome/browser/ui/ash/projector/pending_screencast_manager.cc b/chrome/browser/ui/ash/projector/pending_screencast_manager.cc
index 8c038e9a..b940d8d 100644
--- a/chrome/browser/ui/ash/projector/pending_screencast_manager.cc
+++ b/chrome/browser/ui/ash/projector/pending_screencast_manager.cc
@@ -174,7 +174,7 @@
 }
 
 void PendingSreencastManager::OnUnmounted() {
-  if (pending_screencast_cache_.empty()) {
+  if (!pending_screencast_cache_.empty()) {
     pending_screencast_cache_.clear();
     // Since DriveFS is unmounted, screencasts stop uploading. Notifies pending
     // screencast status has changed.
diff --git a/chrome/browser/ui/ash/tablet_mode_page_behavior_browsertest.cc b/chrome/browser/ui/ash/tablet_mode_page_behavior_browsertest.cc
index e4d74a0..23121f2 100644
--- a/chrome/browser/ui/ash/tablet_mode_page_behavior_browsertest.cc
+++ b/chrome/browser/ui/ash/tablet_mode_page_behavior_browsertest.cc
@@ -119,9 +119,9 @@
 }
 
 IN_PROC_BROWSER_TEST_F(TabletModePageBehaviorTest, ExcludeInternalPages) {
-  AddTabAtIndexToBrowser(browser(), 0, GURL(chrome::kChromeUIVersionURL),
-                         ui::PAGE_TRANSITION_LINK,
-                         false /* check_navigation_success */);
+  ASSERT_TRUE(AddTabAtIndexToBrowser(
+      browser(), 0, GURL(chrome::kChromeUIVersionURL), ui::PAGE_TRANSITION_LINK,
+      false /* check_navigation_success */));
   auto* web_contents = GetActiveWebContents(browser());
   ASSERT_TRUE(web_contents);
   EXPECT_STREQ(web_contents->GetLastCommittedURL().spec().c_str(),
@@ -157,9 +157,9 @@
 }
 
 IN_PROC_BROWSER_TEST_F(TabletModePageBehaviorTest, ExcludeNTPs) {
-  AddTabAtIndexToBrowser(browser(), 0, GURL(chrome::kChromeUINewTabPageURL),
-                         ui::PAGE_TRANSITION_LINK,
-                         false /* check_navigation_success */);
+  ASSERT_TRUE(AddTabAtIndexToBrowser(
+      browser(), 0, GURL(chrome::kChromeUINewTabPageURL),
+      ui::PAGE_TRANSITION_LINK, false /* check_navigation_success */));
   auto* web_contents = GetActiveWebContents(browser());
   ASSERT_TRUE(web_contents);
   EXPECT_STREQ(web_contents->GetLastCommittedURL().spec().c_str(),
diff --git a/chrome/browser/ui/autofill/autofill_popup_controller_utils.cc b/chrome/browser/ui/autofill/autofill_popup_controller_utils.cc
index 8449aee..e13e0b2 100644
--- a/chrome/browser/ui/autofill/autofill_popup_controller_utils.cc
+++ b/chrome/browser/ui/autofill/autofill_popup_controller_utils.cc
@@ -41,7 +41,7 @@
     {"settings", IDR_ANDROID_AUTOFILL_SETTINGS},
     {"create", IDR_ANDROID_AUTOFILL_CREATE},
     {"offerTag", IDR_ANDROID_AUTOFILL_OFFER_TAG_GREEN},
-#endif  // OS_ANDROID
+#endif  // BUILDFLAG(IS_ANDROID)
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
     {"googlePay", IDR_AUTOFILL_GOOGLE_PAY},
 #if !BUILDFLAG(IS_ANDROID)
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.cc b/chrome/browser/ui/autofill/chrome_autofill_client.cc
index cd311e1..11fb02e 100644
--- a/chrome/browser/ui/autofill/chrome_autofill_client.cc
+++ b/chrome/browser/ui/autofill/chrome_autofill_client.cc
@@ -101,7 +101,7 @@
 #include "components/messages/android/messages_feature.h"
 #include "components/webauthn/android/internal_authenticator_android.h"
 #include "ui/android/window_android.h"
-#else  // !OS_ANDROID
+#else  // BUILDFLAG(IS_ANDROID)
 #include "chrome/browser/ui/autofill/payments/offer_notification_bubble_controller_impl.h"
 #include "chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.h"
 #include "chrome/browser/ui/autofill/payments/save_upi_bubble_controller_impl.h"
@@ -115,7 +115,7 @@
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
 #include "components/zoom/zoom_controller.h"
-#endif
+#endif  // BUILDFLAG(IS_ANDROID)
 
 namespace autofill {
 
@@ -348,7 +348,7 @@
       NOTREACHED();
       return;
   }
-#endif  // OS_ANDROID
+#endif  // BUILDFLAG(IS_ANDROID)
 }
 
 void ChromeAutofillClient::ShowUnmaskAuthenticatorSelectionDialog(
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.h b/chrome/browser/ui/autofill/chrome_autofill_client.h
index fff934d..adaedbc 100644
--- a/chrome/browser/ui/autofill/chrome_autofill_client.h
+++ b/chrome/browser/ui/autofill/chrome_autofill_client.h
@@ -31,11 +31,11 @@
 #include "chrome/browser/ui/android/autofill/save_card_message_controller_android.h"
 #include "components/autofill/core/browser/ui/payments/card_expiration_date_fix_flow_controller_impl.h"
 #include "components/autofill/core/browser/ui/payments/card_name_fix_flow_controller_impl.h"
-#else  // !OS_ANDROID
+#else
 #include "chrome/browser/ui/autofill/payments/manage_migration_ui_controller.h"
 #include "chrome/browser/ui/autofill/payments/save_card_bubble_controller.h"
 #include "components/zoom/zoom_observer.h"
-#endif
+#endif  // BUILDFLAG(IS_ANDROID)
 
 namespace autofill {
 
@@ -123,7 +123,7 @@
   void OfferVirtualCardOptions(
       const std::vector<CreditCard*>& candidates,
       base::OnceCallback<void(const std::string&)> callback) override;
-#else  // BUILDFLAG(IS_ANDROID)
+#else  // !BUILDFLAG(IS_ANDROID)
   void ConfirmAccountNameFixFlow(
       base::OnceCallback<void(const std::u16string&)> callback) override;
   void ConfirmExpirationDateFixFlow(
diff --git a/chrome/browser/ui/autofill/save_update_address_profile_bubble_controller_impl_browsertest.cc b/chrome/browser/ui/autofill/save_update_address_profile_bubble_controller_impl_browsertest.cc
index 9788f8a..72246687 100644
--- a/chrome/browser/ui/autofill/save_update_address_profile_bubble_controller_impl_browsertest.cc
+++ b/chrome/browser/ui/autofill/save_update_address_profile_bubble_controller_impl_browsertest.cc
@@ -35,9 +35,10 @@
         browser()->tab_strip_model()->GetActiveWebContents();
     autofill::ChromeAutofillClient* autofill_client =
         autofill::ChromeAutofillClient::FromWebContents(web_contents);
+    AutofillProfile profile = test::GetFullProfile();
+    AutofillProfile* original_profile = (name == "Update") ? &profile : nullptr;
     autofill_client->ConfirmSaveAddressProfile(
-        test::GetFullProfile(),
-        /*original_profile=*/nullptr,
+        profile, original_profile,
         AutofillClient::SaveAddressProfilePromptOptions{.show_prompt = true},
         base::DoNothing());
     controller_ = SaveUpdateAddressProfileBubbleControllerImpl::FromWebContents(
@@ -60,6 +61,11 @@
 }
 
 IN_PROC_BROWSER_TEST_F(SaveUpdateAddressProfileBubbleControllerImplTest,
+                       InvokeUi_Update) {
+  ShowAndVerifyUi();
+}
+
+IN_PROC_BROWSER_TEST_F(SaveUpdateAddressProfileBubbleControllerImplTest,
                        InvokeUi_SaveCloseThenReopen) {
   ShowAndVerifyUi();
   controller()->OnBubbleClosed();
diff --git a/chrome/browser/ui/bluetooth/chrome_bluetooth_chooser_controller.cc b/chrome/browser/ui/bluetooth/chrome_bluetooth_chooser_controller.cc
index 46718b7..45c8265 100644
--- a/chrome/browser/ui/bluetooth/chrome_bluetooth_chooser_controller.cc
+++ b/chrome/browser/ui/bluetooth/chrome_bluetooth_chooser_controller.cc
@@ -32,13 +32,13 @@
 #include "chrome/common/webui_url_constants.h"
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #include "chrome/browser/external_protocol/external_protocol_handler.h"
 #endif
 
 namespace {
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 static constexpr char kBluetoothSettingsUri[] =
     "x-apple.systempreferences:com.apple.preference.security?Privacy_"
     "Bluetooth";
@@ -85,7 +85,7 @@
 }
 
 void ChromeBluetoothChooserController::OpenPermissionPreferences() const {
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   if (web_contents_) {
     ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck(
         GURL(kBluetoothSettingsUri), web_contents_.get(),
diff --git a/chrome/browser/ui/bookmarks/bookmark_browsertest.cc b/chrome/browser/ui/bookmarks/bookmark_browsertest.cc
index 6505387c..3ac63a8c 100644
--- a/chrome/browser/ui/bookmarks/bookmark_browsertest.cc
+++ b/chrome/browser/ui/bookmarks/bookmark_browsertest.cc
@@ -87,7 +87,7 @@
  public:
   BookmarkBrowsertest() {
     // This needs to be disabled so that animations are guaranteed to work.
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
     feature_list_.InitWithFeatures(
         {}, {features::kApplyNativeOcclusionToCompositor});
 #endif
@@ -127,7 +127,7 @@
   base::HistogramTester* histogram_tester() { return &histogram_tester_; }
 
  private:
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   base::test::ScopedFeatureList feature_list_;
 #endif
 
@@ -157,7 +157,7 @@
                                 kPersistBookmarkTitle);
 }
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 // TODO(crbug.com/935607): The test fails on Windows.
 #define MAYBE_Persist DISABLED_Persist
 #else
@@ -334,7 +334,7 @@
             ui::FilenameToURLPolicy::DO_NOT_CONVERT_FILENAMES, &url, &title));
         EXPECT_EQ(page_url, url);
         EXPECT_EQ(page_title, title);
-#if !defined(OS_WIN)
+#if !BUILDFLAG(IS_WIN)
         // On Windows, GetDragImage() is a NOTREACHED() as the Windows
         // implementation of OSExchangeData just sets the drag image on the OS
         // API.
@@ -376,7 +376,7 @@
                                   gfx::NativeView native_view,
                                   ui::mojom::DragEventSource source,
                                   gfx::Point point, int operation) {
-#if !defined(OS_MAC)
+#if !BUILDFLAG(IS_MAC)
         GURL url;
         std::u16string title;
         // On Mac 10.11 and 10.12, this returns true, even though we set no url.
@@ -384,7 +384,7 @@
         EXPECT_FALSE(drag_data->provider().GetURLAndTitle(
             ui::FilenameToURLPolicy::DO_NOT_CONVERT_FILENAMES, &url, &title));
 #endif
-#if !defined(OS_WIN)
+#if !BUILDFLAG(IS_WIN)
         // On Windows, GetDragImage() is a NOTREACHED() as the Windows
         // implementation of OSExchangeData just sets the drag image on the OS
         // API.
diff --git a/chrome/browser/ui/bookmarks/bookmark_drag_drop.cc b/chrome/browser/ui/bookmarks/bookmark_drag_drop.cc
index 99acf28..94ffc91 100644
--- a/chrome/browser/ui/bookmarks/bookmark_drag_drop.cc
+++ b/chrome/browser/ui/bookmarks/bookmark_drag_drop.cc
@@ -46,7 +46,7 @@
                             bool copy) {
   DCHECK(profile);
   BookmarkModel* model = BookmarkModelFactory::GetForBrowserContext(profile);
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
   bookmarks::ScopedGroupBookmarkActions group_drops(model);
 #endif
   if (data.IsFromProfilePath(profile->GetPath())) {
diff --git a/chrome/browser/ui/bookmarks/bookmark_utils.cc b/chrome/browser/ui/bookmarks/bookmark_utils.cc
index 726dcce..128a113 100644
--- a/chrome/browser/ui/bookmarks/bookmark_utils.cc
+++ b/chrome/browser/ui/bookmarks/bookmark_utils.cc
@@ -277,7 +277,7 @@
     BookmarkFolderIconType icon_type,
     absl::variant<ui::ColorId, SkColor> color) {
   int default_id = IDR_FOLDER_CLOSED;
-#if defined(OS_WIN) || defined(OS_MAC)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
   // This block must be #ifdefed because only these platforms actually have this
   // resource ID.
   if (icon_type == BookmarkFolderIconType::kManaged)
@@ -287,11 +287,11 @@
                             absl::variant<ui::ColorId, SkColor> color,
                             const ui::ColorProvider* color_provider) {
     gfx::ImageSkia folder;
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
     // TODO(bsep): vectorize the Windows versions: crbug.com/564112
     folder =
         *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(default_id);
-#elif defined(OS_MAC)
+#elif BUILDFLAG(IS_MAC)
     SkColor sk_color;
     if (absl::holds_alternative<SkColor>(color)) {
       sk_color = absl::get<SkColor>(color);
diff --git a/chrome/browser/ui/bookmarks/bookmark_utils_desktop.cc b/chrome/browser/ui/bookmarks/bookmark_utils_desktop.cc
index e47f96e..394979e 100644
--- a/chrome/browser/ui/bookmarks/bookmark_utils_desktop.cc
+++ b/chrome/browser/ui/bookmarks/bookmark_utils_desktop.cc
@@ -79,7 +79,7 @@
                          count_children);
 }
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 // Returns in |urls|, the url and title pairs for each open tab in browser.
 void GetURLsAndFoldersForOpenTabs(
     Browser* browser,
@@ -143,7 +143,7 @@
 
 }  // namespace
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 void OpenAllIfAllowed(
     Browser* browser,
     base::OnceCallback<content::PageNavigator*()> get_navigator,
@@ -321,6 +321,6 @@
     }
   }
 }
-#endif  // !defined(OS_ANDROID)
+#endif  // !BUILDFLAG(IS_ANDROID)
 
 }  // namespace chrome
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index 81b1178..a7a64eff 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -242,7 +242,7 @@
 #include "url/origin.h"
 #include "url/scheme_host_port.h"
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 // windows.h must be included before shellapi.h
 #include <windows.h>
 
@@ -251,7 +251,7 @@
 #include "chrome/browser/ui/view_ids.h"
 #include "components/autofill/core/browser/autofill_ie_toolbar_import_win.h"
 #include "ui/base/win/shell.h"
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/ui/settings_window_manager_chromeos.h"
@@ -544,11 +544,11 @@
 
   // TODO(beng): move to ChromeBrowserMain:
   if (first_run::ShouldDoPersonalDataManagerFirstRun()) {
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
     // Notify PDM that this is a first run.
     ImportAutofillDataWin(
         autofill::PersonalDataManagerFactory::GetForProfile(profile_));
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
   }
 
   exclusive_access_manager_ = std::make_unique<ExclusiveAccessManager>(
@@ -785,7 +785,7 @@
   if (title.empty() && (is_type_normal() || is_type_popup()))
     title = CoreTabHelper::GetDefaultTitle();
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   // On Mac, we don't want to suffix the page title with the application name.
   return title;
 #else
@@ -919,7 +919,7 @@
       TabRestoreServiceFactory::GetForProfile(profile());
 
   bool notify_restore_service = is_type_normal() && tab_strip_model_->count();
-#if defined(USE_AURA) || defined(OS_MAC)
+#if defined(USE_AURA) || BUILDFLAG(IS_MAC)
   notify_restore_service |= is_type_app() || is_type_app_popup();
 #endif
 
@@ -1614,7 +1614,7 @@
                              const gfx::Rect& initial_rect,
                              bool user_gesture,
                              bool* was_blocked) {
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   // On the Mac, the convention is to turn popups into new tabs when in
   // fullscreen mode. Only worry about user-initiated fullscreen as showing a
   // popup in HTML5 fullscreen would have kicked the page out of fullscreen.
@@ -2339,7 +2339,7 @@
 // background color, so it does not need this block of code. Aura should
 // implement this as well.
 // https://crbug.com/719230
-#if !defined(OS_MAC)
+#if !BUILDFLAG(IS_MAC)
   // Copies the background color from an old WebContents to a new one that
   // replaces it on the screen. This allows the new WebContents to use the
   // old one's background color as the starting background color, before having
@@ -2651,7 +2651,7 @@
 // Browser, In-progress download termination handling (private):
 
 bool Browser::CanCloseWithInProgressDownloads() {
-#if defined(OS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH)
+#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH)
   // On Mac and ChromeOS, non-incognito and non-Guest downloads can still
   // continue after window is closed.
   if (!profile_->IsOffTheRecord())
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h
index e3858ca3..1cda4516 100644
--- a/chrome/browser/ui/browser.h
+++ b/chrome/browser/ui/browser.h
@@ -45,7 +45,7 @@
 #include "ui/gfx/geometry/rect.h"
 #include "ui/shell_dialogs/select_file_dialog.h"
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 #error This file should only be included on desktop.
 #endif
 
@@ -263,7 +263,7 @@
 
     CreationSource creation_source = CreationSource::kUnknown;
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
     // The id from the restore data to restore the browser window.
     int32_t restore_id = kDefaultRestoreId;
 #endif
diff --git a/chrome/browser/ui/browser_browsertest.cc b/chrome/browser/ui/browser_browsertest.cc
index ea90689..df471ed 100644
--- a/chrome/browser/ui/browser_browsertest.cc
+++ b/chrome/browser/ui/browser_browsertest.cc
@@ -132,13 +132,13 @@
 #include "ui/base/page_transition_types.h"
 #include "ui/base/ui_base_features.h"
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #include "base/mac/scoped_nsautorelease_pool.h"
 #include "chrome/browser/ui/cocoa/test/run_loop_testing.h"
 #include "ui/accelerated_widget_mac/ca_transaction_observer.h"
 #endif
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 #include "base/i18n/rtl.h"
 #include "chrome/browser/browser_process.h"
 #endif
@@ -170,7 +170,7 @@
 
 // Given a page title, returns the expected window caption string.
 std::u16string WindowCaptionFromPageTitle(const std::u16string& page_title) {
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   // On Mac, we don't want to suffix the page title with the application name.
   if (page_title.empty())
     return l10n_util::GetStringUTF16(IDS_BROWSER_WINDOW_MAC_TAB_UNTITLED);
@@ -332,7 +332,7 @@
   std::u16string LocaleWindowCaptionFromPageTitle(
       const std::u16string& expected_title) {
     std::u16string page_title = WindowCaptionFromPageTitle(expected_title);
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
     std::string locale = g_browser_process->GetApplicationLocale();
     if (base::i18n::GetTextDirectionForLocale(locale.c_str()) ==
         base::i18n::RIGHT_TO_LEFT) {
@@ -525,7 +525,7 @@
 // Warning: this test can take >30 seconds when running on a slow (low
 // memory?) Mac builder.
 // Test is flaky on Win, Linux, Mac: https://crbug.com/1099186.
-#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_MAC)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC)
 #define MAYBE_ThirtyFourTabs DISABLED_ThirtyFourTabs
 #else
 #define MAYBE_ThirtyFourTabs ThirtyFourTabs
@@ -774,7 +774,7 @@
   EXPECT_FALSE(contents->GetMainFrame()->GetProcess()->IsBlocked());
 }
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 // Flaky on Mac 10.11 CI builder. See https://crbug.com/1251684.
 #define MAYBE_SadTabCancelsDialogs DISABLED_SadTabCancelsDialogs
 #else
@@ -1099,7 +1099,7 @@
   // loop. It also drains the NSAutoreleasePool.
   void CycleRunLoops() {
     content::RunAllPendingInMessageLoop();
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
     chrome::testing::NSRunLoopRunAllPending();
     AutoreleasePool()->Recycle();
 #endif
@@ -1243,8 +1243,8 @@
   EXPECT_EQ(expected_favicon_url.spec(), entry->GetFavicon().url.spec());
 }
 
-#if defined(OS_MAC) || defined(OS_LINUX) || defined(OS_CHROMEOS) || \
-    defined(OS_WIN)
+#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \
+    BUILDFLAG(IS_WIN)
 // http://crbug.com/83828. On Mac 10.6, the failure rate is 14%
 #define MAYBE_FaviconChange DISABLED_FaviconChange
 #else
@@ -1564,7 +1564,7 @@
       FROM_HERE, base::BindOnce(&RunCloseWithAppMenuCallback, browser()));
 }
 
-#if !defined(OS_MAC)
+#if !BUILDFLAG(IS_MAC)
 IN_PROC_BROWSER_TEST_F(BrowserTest, OpenAppWindowLikeNtp) {
   ASSERT_TRUE(embedded_test_server()->Start());
 
@@ -1610,7 +1610,7 @@
   EXPECT_NE(app_name.find(extension_app->id()), std::string::npos)
       << "Name " << app_name << " should contain id " << extension_app->id();
 }
-#endif  // !defined(OS_MAC)
+#endif  // !BUILDFLAG(IS_MAC)
 
 // Makes sure the browser doesn't crash when
 // set_show_state(ui::SHOW_STATE_MAXIMIZED) has been invoked.
@@ -2048,7 +2048,7 @@
 // Disabled because of timeouts in several builders.
 // https://crbug.com/1129313
 IN_PROC_BROWSER_TEST_F(BrowserTest, DISABLED_WindowOpenClose3) {
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   // Ensure that tests don't wait for frames that will never come.
   ui::CATransactionCoordinator::Get().DisableForTesting();
 #endif
@@ -2072,13 +2072,14 @@
 // Mac disabled: http://crbug.com/169820
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
-#if !defined(OS_MAC) && !(defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
+#if !BUILDFLAG(IS_MAC) && \
+    !(BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
 IN_PROC_BROWSER_TEST_F(BrowserTest, FullscreenBookmarkBar) {
   chrome::ToggleBookmarkBar(browser());
   EXPECT_EQ(BookmarkBar::SHOW, browser()->bookmark_bar_state());
   chrome::ToggleFullscreenMode(browser());
   EXPECT_TRUE(browser()->window()->IsFullscreen());
-#if defined(OS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH)
+#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH)
   // Mac and Chrome OS both have an "immersive style" fullscreen where the
   // bookmark bar is visible when the top views slide down.
   EXPECT_EQ(BookmarkBar::SHOW, browser()->bookmark_bar_state());
@@ -2112,7 +2113,7 @@
 
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
-#if defined(OS_MAC) || (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
+#if BUILDFLAG(IS_MAC) || (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
 // Mac: http://crbug.com/103912
 // Linux: http://crbug.com/163931
 #define MAYBE_EnableKioskModeTest DISABLED_EnableKioskModeTest
@@ -2125,7 +2126,7 @@
   ASSERT_FALSE(browser()->window()->IsFullscreenBubbleVisible());
 }
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 // This test verifies that Chrome can be launched with a user-data-dir path
 // which contains non ASCII characters.
 class LaunchBrowserWithNonAsciiUserDatadir : public BrowserTest {
@@ -2155,9 +2156,9 @@
                     ->GetProfileAttributesStorage()
                     .GetNumberOfProfiles());
 }
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 // This test verifies that Chrome can be launched with a user-data-dir path
 // which trailing slashes.
 class LaunchBrowserWithTrailingSlashDatadir : public BrowserTest {
@@ -2187,7 +2188,7 @@
                     ->GetProfileAttributesStorage()
                     .GetNumberOfProfiles());
 }
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 
 #if BUILDFLAG(ENABLE_BACKGROUND_MODE)
 // Tests to ensure that the browser continues running in the background after
@@ -2396,7 +2397,7 @@
 // Control-clicks open in a background tab.
 // On OSX meta [the command key] takes the place of control.
 IN_PROC_BROWSER_TEST_F(ClickModifierTest, WindowOpenControlClickTest) {
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   int modifiers = blink::WebInputEvent::kMetaKey;
 #else
   int modifiers = blink::WebInputEvent::kControlKey;
@@ -2409,7 +2410,7 @@
 // Control-shift-clicks open in a foreground tab.
 // On OSX meta [the command key] takes the place of control.
 IN_PROC_BROWSER_TEST_F(ClickModifierTest, WindowOpenControlShiftClickTest) {
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   int modifiers = blink::WebInputEvent::kMetaKey;
 #else
   int modifiers = blink::WebInputEvent::kControlKey;
@@ -2443,7 +2444,7 @@
 // Control-clicks open in a background tab.
 // On OSX meta [the command key] takes the place of control.
 IN_PROC_BROWSER_TEST_F(ClickModifierTest, HrefControlClickTest) {
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   int modifiers = blink::WebInputEvent::kMetaKey;
 #else
   int modifiers = blink::WebInputEvent::kControlKey;
@@ -2456,7 +2457,7 @@
 // Control-shift-clicks open in a foreground tab.
 // On OSX meta [the command key] takes the place of control.
 IN_PROC_BROWSER_TEST_F(ClickModifierTest, HrefControlShiftClickTest) {
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   int modifiers = blink::WebInputEvent::kMetaKey;
 #else
   int modifiers = blink::WebInputEvent::kControlKey;
@@ -2543,7 +2544,7 @@
 // In OSX, the wcv does not change size until after the commit, when the
 // bookmark bar disappears (correct).
 // In views, the wcv changes size at commit time.
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   EXPECT_EQ(gfx::Size(wcv_commit_size0.width(), wcv_commit_size0.height()),
             web_contents->GetContainerBounds().size());
 #else
@@ -2596,7 +2597,7 @@
             rwhv_create_size2);
   gfx::Size exp_commit_size(initial_wcv_size);
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   exp_commit_size.Enlarge(wcv_resize_insets.width(),
                           wcv_resize_insets.height());
 #else
diff --git a/chrome/browser/ui/browser_close_unittest.cc b/chrome/browser/ui/browser_close_unittest.cc
index 5bcc3801..d3e541a6 100644
--- a/chrome/browser/ui/browser_close_unittest.cc
+++ b/chrome/browser/ui/browser_close_unittest.cc
@@ -274,7 +274,7 @@
   EXPECT_EQ(Browser::DownloadCloseType::kBrowserShutdown,
             browser->OkToCloseWithInProgressDownloads(&num_downloads_blocking));
   EXPECT_EQ(num_downloads_blocking, 1);
-#if defined(OS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH)
+#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH)
   EXPECT_EQ(true, browser->CanCloseWithInProgressDownloads());
 #else
   EXPECT_EQ(false, browser->CanCloseWithInProgressDownloads());
diff --git a/chrome/browser/ui/browser_command_controller.cc b/chrome/browser/ui/browser_command_controller.cc
index dfa2156..92f10fa 100644
--- a/chrome/browser/ui/browser_command_controller.cc
+++ b/chrome/browser/ui/browser_command_controller.cc
@@ -70,11 +70,11 @@
 #include "ui/base/ui_base_features.h"
 #include "ui/events/keycodes/keyboard_codes.h"
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #include "chrome/browser/ui/browser_commands_mac.h"
 #endif
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 #include "base/win/windows_version.h"
 #include "content/public/browser/gpu_data_manager.h"
 #endif
@@ -88,7 +88,7 @@
 
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
-#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
 #include "ui/base/ime/linux/text_edit_key_bindings_delegate_auralinux.h"
 #endif
 
@@ -194,7 +194,7 @@
       prefs::kDownloadRestrictions,
       base::BindRepeating(&BrowserCommandController::UpdateSaveAsState,
                           base::Unretained(this)));
-#if !defined(OS_MAC)
+#if !BUILDFLAG(IS_MAC)
   profile_pref_registrar_.Add(
       prefs::kFullscreenAllowed,
       base::BindRepeating(
@@ -256,7 +256,7 @@
     // found in http://crbug.com/680809.
     const bool is_exit_fullscreen =
         (command_id == IDC_EXIT || command_id == IDC_FULLSCREEN);
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
     // This behavior is different on Mac OS, which has a unique user-initiated
     // full-screen mode. According to the discussion in http://crbug.com/702251,
     // the commands should be reserved for browser-side handling if the browser
@@ -274,7 +274,7 @@
 
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
-#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
   // If this key was registered by the user as a content editing hotkey, then
   // it is not reserved.
   ui::TextEditKeyBindingsDelegateAuraLinux* delegate =
@@ -307,7 +307,7 @@
   UpdateCommandsForFullscreenMode();
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 void BrowserCommandController::LockedFullscreenStateChanged() {
   UpdateCommandsForLockedFullscreenMode();
 }
@@ -510,7 +510,7 @@
 
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
-#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
     case IDC_MINIMIZE_WINDOW:
       browser_->window()->Minimize();
       break;
@@ -528,7 +528,7 @@
     }
 #endif
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
     case IDC_TOGGLE_FULLSCREEN_TOOLBAR:
       chrome::ToggleFullscreenToolbar(browser_);
       break;
@@ -1026,7 +1026,7 @@
 #endif
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
-#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
   command_updater_.UpdateCommandEnabled(IDC_MINIMIZE_WINDOW, true);
   command_updater_.UpdateCommandEnabled(IDC_MAXIMIZE_WINDOW, true);
   command_updater_.UpdateCommandEnabled(IDC_RESTORE_WINDOW, true);
@@ -1335,7 +1335,7 @@
   command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_TOGGLE,
                                         dev_tools_enabled);
   command_updater_.UpdateCommandEnabled(IDC_VIEW_SOURCE, dev_tools_enabled);
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   command_updater_.UpdateCommandEnabled(IDC_TOGGLE_JAVASCRIPT_APPLE_EVENTS,
                                         dev_tools_enabled);
 #endif
@@ -1349,7 +1349,7 @@
                                         CanBookmarkCurrentTab(browser_));
   command_updater_.UpdateCommandEnabled(IDC_BOOKMARK_ALL_TABS,
                                         CanBookmarkAllTabs(browser_));
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   command_updater_.UpdateCommandEnabled(IDC_PIN_TO_START_SCREEN, true);
 #endif
 }
@@ -1440,7 +1440,7 @@
   if (base::debug::IsProfilingSupported())
     command_updater_.UpdateCommandEnabled(IDC_PROFILING_ENABLED, show_main_ui);
 
-#if !defined(OS_MAC)
+#if !BUILDFLAG(IS_MAC)
   // Disable toggling into fullscreen mode if disallowed by pref.
   const bool fullscreen_enabled =
       is_fullscreen ||
@@ -1469,7 +1469,7 @@
   command_updater_.UpdateCommandEnabled(IDC_SHOW_APP_MENU, has_toolbar);
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 namespace {
 
 #if DCHECK_IS_ON()
@@ -1612,12 +1612,12 @@
 }
 
 void BrowserCommandController::UpdateCommandsForWebContentsFocus() {
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   // On Mac, toggling caret browsing changes whether it's enabled or not
   // based on web contents focus.
   command_updater_.UpdateCommandEnabled(IDC_CARET_BROWSING_TOGGLE,
                                         CanToggleCaretBrowsing(browser_));
-#endif  // defined(OS_MAC)
+#endif  // BUILDFLAG(IS_MAC)
 }
 
 BrowserWindow* BrowserCommandController::window() {
diff --git a/chrome/browser/ui/browser_command_controller.h b/chrome/browser/ui/browser_command_controller.h
index f3a13f85..0f7d8b1e 100644
--- a/chrome/browser/ui/browser_command_controller.h
+++ b/chrome/browser/ui/browser_command_controller.h
@@ -7,6 +7,7 @@
 
 #include "base/gtest_prod_util.h"
 #include "base/memory/raw_ptr.h"
+#include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/command_updater.h"
 #include "chrome/browser/command_updater_delegate.h"
@@ -53,7 +54,7 @@
   void ZoomStateChanged();
   void ContentRestrictionsChanged();
   void FullscreenStateChanged();
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   // Called when the browser goes in or out of the special locked fullscreen
   // mode. In this mode the user is basically locked into the current browser
   // window and tab hence we disable most keyboard shortcuts and we also
@@ -156,7 +157,7 @@
   // app windows.
   void UpdateCommandsForHostedAppAvailability();
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   // Update commands whose state depends on whether the window is in locked
   // fullscreen mode or not.
   void UpdateCommandsForLockedFullscreenMode();
diff --git a/chrome/browser/ui/browser_command_controller_interactive_browsertest.cc b/chrome/browser/ui/browser_command_controller_interactive_browsertest.cc
index dc9e0321..23a52e5 100644
--- a/chrome/browser/ui/browser_command_controller_interactive_browsertest.cc
+++ b/chrome/browser/ui/browser_command_controller_interactive_browsertest.cc
@@ -10,13 +10,13 @@
 #include "content/public/test/browser_test.h"
 #include "ui/events/keycodes/keyboard_codes.h"
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #include "base/mac/mac_util.h"
 #endif
 
 using BrowserCommandControllerInteractiveTest =
     FullscreenKeyboardBrowserTestBase;
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 // Flaky http://crbug.com/852285
 #define MAYBE_ShortcutsShouldTakeEffectInWindowMode \
   DISABLED_ShortcutsShouldTakeEffectInWindowMode
@@ -51,7 +51,7 @@
   ASSERT_NO_FATAL_FAILURE(FinishTestAndVerifyResult());
 }
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 // TODO(zijiehe): Figure out why this test crashes on Mac OSX. The suspicious
 // command is "SendFullscreenShortcutAndWait()". See, http://crbug.com/738949.
 #define MAYBE_KeyEventsShouldBeConsumedByWebPageInBrowserFullscreen \
@@ -79,7 +79,7 @@
   ASSERT_FALSE(IsInBrowserFullscreen());
 }
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 // https://crbug.com/850594
 #define MAYBE_KeyEventsShouldBeConsumedByWebPageInJsFullscreenExceptForEsc \
   DISABLED_KeyEventsShouldBeConsumedByWebPageInJsFullscreenExceptForEsc
@@ -100,7 +100,7 @@
   ASSERT_NO_FATAL_FAILURE(FinishTestAndVerifyResult());
 }
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 // Triggers a DCHECK in MacViews: http://crbug.com/823478
 #define MAYBE_KeyEventsShouldBeConsumedByWebPageInJsFullscreenExceptForF11 \
   DISABLED_KeyEventsShouldBeConsumedByWebPageInJsFullscreenExceptForF11
@@ -124,7 +124,7 @@
   ASSERT_NO_FATAL_FAILURE(FinishTestAndVerifyResult());
 }
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 // TODO(zijiehe): Figure out why this test crashes on Mac OSX. The suspicious
 // command is "SendFullscreenShortcutAndWait()". See, http://crbug.com/738949.
 #define MAYBE_ShortcutsShouldTakeEffectInBrowserFullscreen \
@@ -138,7 +138,7 @@
   ASSERT_NO_FATAL_FAILURE(SendShortcutsAndExpectNotPrevented(false));
 }
 
-#if !defined(OS_MAC)
+#if !BUILDFLAG(IS_MAC)
 // HTML fullscreen is automatically exited after some commands are executed,
 // such as Ctrl + T (new tab). But some commands won't have this effect, such as
 // Ctrl + N (new window).
@@ -161,7 +161,7 @@
                        MAYBE_ShortcutsShouldTakeEffectInJsFullscreen) {
 // This test is flaky. See http://crbug.com/759704.
 // TODO(zijiehe): Find out the root cause.
-#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
   return;
 #endif
   ASSERT_NO_FATAL_FAILURE(SendShortcutsAndExpectNotPrevented(true));
diff --git a/chrome/browser/ui/browser_command_controller_unittest.cc b/chrome/browser/ui/browser_command_controller_unittest.cc
index eeb2ca5..1a58624 100644
--- a/chrome/browser/ui/browser_command_controller_unittest.cc
+++ b/chrome/browser/ui/browser_command_controller_unittest.cc
@@ -418,7 +418,7 @@
               commands[i].reserved_in_fullscreen);
   }
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   // When the toolbar is showing, commands should be reserved as if the content
   // were in a tab; IDC_FULLSCREEN should also be reserved.
   static_cast<FullscreenTestBrowserWindow*>(window())->set_toolbar_showing(
diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc
index 73c784e..2e42236 100644
--- a/chrome/browser/ui/browser_commands.cc
+++ b/chrome/browser/ui/browser_commands.cc
@@ -680,7 +680,7 @@
 
 void NewWindow(Browser* browser) {
   Profile* const profile = browser->profile();
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   // Web apps should open a window to their launch page.
   if (browser->app_controller()) {
     const web_app::AppId app_id = browser->app_controller()->app_id();
@@ -715,7 +715,7 @@
     return;
   }
 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
-#endif  // defined(OS_MAC)
+#endif  // BUILDFLAG(IS_MAC)
   NewEmptyWindow(profile->GetOriginalProfile());
 }
 
@@ -1189,7 +1189,7 @@
 }
 
 void MaybeShowBookmarkBarForReadLater(Browser* browser) {
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
   if (base::FeatureList::IsEnabled(features::kSidePanel))
     return;
   PrefService* pref_service = browser->profile()->GetPrefs();
@@ -1205,7 +1205,7 @@
     if (browser->bookmark_bar_state() == BookmarkBar::HIDDEN)
       ToggleBookmarkBar(browser);
   }
-#endif  // defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_ANDROID)
 }
 
 void ShowOffersAndRewardsForPage(Browser* browser) {
@@ -1535,7 +1535,7 @@
 }
 
 bool CanOpenTaskManager() {
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
   return true;
 #else
   return false;
@@ -1554,11 +1554,11 @@
   }
   // Invoke task manager UI in ash, which will call chrome::OpenTaskManager()
   // in ash to run through the code path in the next section
-  // (!defined(OS_ANDROID)).
+  // (!BUILDFLAG(IS_ANDROID)).
   chromeos::LacrosService::Get()
       ->GetRemote<crosapi::mojom::TaskManager>()
       ->ShowTaskManager();
-#elif !defined(OS_ANDROID)
+#elif !BUILDFLAG(IS_ANDROID)
   base::RecordAction(UserMetricsAction("TaskManager"));
   chrome::ShowTaskManager(browser);
 #else
@@ -1747,7 +1747,7 @@
 }
 
 bool CanToggleCaretBrowsing(Browser* browser) {
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   // On Mac, ignore the keyboard shortcut unless web contents is focused,
   // because the keyboard shortcut interferes with a Japenese IME when the
   // omnibox is focused.  See https://crbug.com/1138475
@@ -1760,7 +1760,7 @@
   return rwhv && rwhv->HasFocus();
 #else
   return true;
-#endif  // defined(OS_MAC)
+#endif  // BUILDFLAG(IS_MAC)
 }
 
 void ToggleCaretBrowsing(Browser* browser) {
diff --git a/chrome/browser/ui/browser_dialogs.h b/chrome/browser/ui/browser_dialogs.h
index 875f10c..0f71021 100644
--- a/chrome/browser/ui/browser_dialogs.h
+++ b/chrome/browser/ui/browser_dialogs.h
@@ -26,8 +26,8 @@
 #include "ui/base/models/dialog_model.h"
 #include "ui/gfx/native_widget_types.h"
 
-#if defined(OS_WIN) || defined(OS_MAC) || \
-    (defined(OS_LINUX) && !BUILDFLAG(IS_CHROMEOS_LACROS))
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || \
+    (BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS_LACROS))
 #include "chrome/browser/web_applications/web_app_id.h"
 #endif
 
@@ -80,8 +80,8 @@
 struct SelectedFileInfo;
 }  // namespace ui
 
-#if defined(OS_WIN) || defined(OS_MAC) || \
-    (defined(OS_LINUX) && !BUILDFLAG(IS_CHROMEOS_LACROS))
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || \
+    (BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS_LACROS))
 namespace web_app {
 struct UrlHandlerLaunchParams;
 }
@@ -185,7 +185,7 @@
 // without any user interaction.
 void SetAutoAcceptAppIdentityUpdateForTesting(bool auto_accept);
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 // Callback used to indicate whether a user has accepted the launch of a
 // web app. The |allowed| is true when the user allows the app to launch.
 // |remember_user_choice| is true if the user wants to persist the decision.
@@ -205,10 +205,10 @@
                                 Profile* profile,
                                 const web_app::AppId& app_id,
                                 WebAppLaunchAcceptanceCallback close_callback);
-#endif  // !defined(OS_ANDROID)
+#endif  // !BUILDFLAG(IS_ANDROID)
 
-#if defined(OS_WIN) || defined(OS_MAC) || \
-    (defined(OS_LINUX) && !BUILDFLAG(IS_CHROMEOS_LACROS))
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || \
+    (BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS_LACROS))
 // Callback that runs when the Web App URL Handler Intent Picker dialog is
 // closed. `accepted` is true when the dialog is accepted, false otherwise.
 // `launch_params` contains information of the app that is selected to open by
@@ -259,7 +259,7 @@
 // user interaction.
 void SetAutoAcceptPWAInstallConfirmationForTesting(bool auto_accept);
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 
 // Shows the print job confirmation dialog bubble anchored to the toolbar icon
 // for the extension.
@@ -274,15 +274,15 @@
                                     const std::u16string& printer_name,
                                     base::OnceCallback<void(bool)> callback);
 
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 
 // Bridging methods that show/hide the toolkit-views based Task Manager on Mac.
 task_manager::TaskManagerTableModel* ShowTaskManagerViews(Browser* browser);
 void HideTaskManagerViews();
 
-#endif  // OS_MAC
+#endif  // BUILDFLAG(IS_MAC)
 
 #if defined(TOOLKIT_VIEWS)
 
@@ -421,7 +421,7 @@
 // Record an UMA metric counting the creation of a dialog box of this type.
 void RecordDialogCreation(DialogIdentifier identifier);
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 
 // Shows the settings reset prompt dialog asking the user if they want to reset
 // some of their settings.
@@ -444,7 +444,7 @@
     Browser* browser,
     safe_browsing::ChromeCleanerRebootDialogController* dialog_controller);
 
-#endif  // OS_WIN
+#endif  // BUILDFLAG(IS_WIN)
 
 // Displays a dialog to notify the user that the extension installation is
 // blocked due to policy. It also show additional information from administrator
diff --git a/chrome/browser/ui/browser_finder.cc b/chrome/browser/ui/browser_finder.cc
index 6e9c4e2e..629e382 100644
--- a/chrome/browser/ui/browser_finder.cc
+++ b/chrome/browser/ui/browser_finder.cc
@@ -40,7 +40,7 @@
 const uint32_t kMatchCanSupportWindowFeature = 1 << 1;
 const uint32_t kMatchNormal = 1 << 2;
 const uint32_t kMatchDisplayId = 1 << 3;
-#if defined(OS_WIN) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS)
 const uint32_t kMatchCurrentWorkspace = 1 << 4;
 #endif
 
@@ -101,13 +101,13 @@
   if ((match_types & kMatchNormal) && !browser->is_type_normal())
     return false;
 
-#if defined(OS_WIN) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS)
   // Note that |browser->window()| might be nullptr in tests.
   if ((match_types & kMatchCurrentWorkspace) &&
       (!browser->window() || !browser->window()->IsOnCurrentWorkspace())) {
     return false;
   }
-#endif  // OS_WIN
+#endif  // BUILDFLAG(IS_WIN)
 
   if (match_types & kMatchDisplayId) {
     return display::Screen::GetScreen()
@@ -151,7 +151,7 @@
     match_types |= kMatchOriginalProfile;
   if (display_id != display::kInvalidDisplayId)
     match_types |= kMatchDisplayId;
-#if defined(OS_WIN) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS)
   if (match_current_workspace)
     match_types |= kMatchCurrentWorkspace;
 #endif
diff --git a/chrome/browser/ui/browser_focus_uitest.cc b/chrome/browser/ui/browser_focus_uitest.cc
index 26eacdd..9f2b5802 100644
--- a/chrome/browser/ui/browser_focus_uitest.cc
+++ b/chrome/browser/ui/browser_focus_uitest.cc
@@ -59,7 +59,7 @@
 using content::RenderViewHost;
 using content::WebContents;
 
-#if defined(OS_POSIX)
+#if BUILDFLAG(IS_POSIX)
 // The delay waited in some cases where we don't have a notifications for an
 // action we take.
 const int kActionDelayMs = 500;
@@ -95,7 +95,7 @@
                                   "googleLink", "gmailLink",    "gmapLink"};
     SCOPED_TRACE(base::StringPrintf("TestFocusTraversal: reverse=%d", reverse));
     ui::KeyboardCode key = ui::VKEY_TAB;
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
     // TODO(msw): Mac requires ui::VKEY_BACKTAB for reverse cycling. Sigh...
     key = reverse ? ui::VKEY_BACKTAB : ui::VKEY_TAB;
 #endif
@@ -108,7 +108,7 @@
       // Mac requires an extra Tab key press to traverse the app menu button
       // iff "Full Keyboard Access" is enabled. In reverse, four Tab key presses
       // are required to traverse the back/forward buttons and the tab strip.
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
       constexpr int kFocusableElementsBeforeOmnibox = 4;
       constexpr int kFocusableElementsAfterOmnibox = 1;
       if (ui_controls::IsFullKeyboardAccessEnabled()) {
@@ -159,7 +159,7 @@
 
       // Except on Mac, where extra tabs are once again required to traverse the
       // other top chrome elements.
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
       if (ui_controls::IsFullKeyboardAccessEnabled()) {
         for (int j = 0; j < (reverse ? kFocusableElementsAfterOmnibox
                                      : kFocusableElementsBeforeOmnibox);
@@ -193,7 +193,7 @@
 };
 
 // Flaky on Mac (http://crbug.com/67301).
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #define MAYBE_ClickingMovesFocus DISABLED_ClickingMovesFocus
 #else
 // If this flakes, disable and log details in http://crbug.com/523255.
@@ -201,14 +201,14 @@
 #endif
 IN_PROC_BROWSER_TEST_F(BrowserFocusTest, MAYBE_ClickingMovesFocus) {
   ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
-#if defined(OS_POSIX)
+#if BUILDFLAG(IS_POSIX)
   // It seems we have to wait a little bit for the widgets to spin up before
   // we can start clicking on them.
   base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
       FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated(),
       base::Milliseconds(kActionDelayMs));
   content::RunMessageLoop();
-#endif  // defined(OS_POSIX)
+#endif  // BUILDFLAG(IS_POSIX)
 
   ASSERT_TRUE(IsViewFocused(VIEW_ID_OMNIBOX));
 
@@ -420,7 +420,7 @@
 }
 
 // Test that find-in-page UI can request focus, even when it is already open.
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #define MAYBE_FindFocusTest DISABLED_FindFocusTest
 #else
 // If this flakes, disable and log details in http://crbug.com/523255.
@@ -529,7 +529,7 @@
 }
 
 // Tests that focus goes where expected when using reload on a crashed tab.
-#if defined(OS_CHROMEOS) || defined(OS_LINUX)
+#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
 // Hangy, http://crbug.com/50025.
 #define MAYBE_FocusOnReloadCrashedTab DISABLED_FocusOnReloadCrashedTab
 #else
@@ -751,7 +751,7 @@
 // Tests that the location bar is focusable when showing, which is the case in
 // popup windows.
 // TODO(crbug.com/1255472): Flaky on Linux.
-#if defined(OS_LINUX)
+#if BUILDFLAG(IS_LINUX)
 #define MAYBE_PopupLocationBar DISABLED_PopupLocationBar
 #else
 #define MAYBE_PopupLocationBar PopupLocationBar
diff --git a/chrome/browser/ui/browser_instant_controller.h b/chrome/browser/ui/browser_instant_controller.h
index 157dc01..d1c3ff9 100644
--- a/chrome/browser/ui/browser_instant_controller.h
+++ b/chrome/browser/ui/browser_instant_controller.h
@@ -12,7 +12,7 @@
 #include "chrome/browser/search/search_engine_base_url_tracker.h"
 #include "chrome/browser/ui/search/instant_controller.h"
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 #error "Instant is only used on desktop";
 #endif
 
diff --git a/chrome/browser/ui/browser_list.h b/chrome/browser/ui/browser_list.h
index 80fccac..8f215d7b2 100644
--- a/chrome/browser/ui/browser_list.h
+++ b/chrome/browser/ui/browser_list.h
@@ -15,7 +15,7 @@
 #include "base/observer_list.h"
 #include "build/build_config.h"
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 #error This file should only be included on desktop.
 #endif
 
diff --git a/chrome/browser/ui/browser_list_observer.h b/chrome/browser/ui/browser_list_observer.h
index c700a6b..3e09476 100644
--- a/chrome/browser/ui/browser_list_observer.h
+++ b/chrome/browser/ui/browser_list_observer.h
@@ -7,7 +7,7 @@
 
 #include "build/build_config.h"
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 #error This file should only be included on desktop.
 #endif
 
diff --git a/chrome/browser/ui/browser_navigator.cc b/chrome/browser/ui/browser_navigator.cc
index 0fd3649..cfdbd577 100644
--- a/chrome/browser/ui/browser_navigator.cc
+++ b/chrome/browser/ui/browser_navigator.cc
@@ -180,7 +180,7 @@
 
   switch (params.disposition) {
     case WindowOpenDisposition::SWITCH_TO_TAB:
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
     {
       std::pair<Browser*, int> index =
           GetIndexAndBrowserOfExistingTab(profile, params);
@@ -766,7 +766,7 @@
     return true;
 
   if (host == chrome::kChromeUIChromeSigninHost) {
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
     // Allow incognito mode for the chrome-signin url if we only want to
     // retrieve the login scope token without touching any profiles. This
     // option is only available on Windows for use with Google Credential
@@ -775,7 +775,7 @@
            signin_metrics::Reason::kFetchLstOnly;
 #else
     return false;
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
   }
 
   // Most URLs are allowed in incognito; the following are exceptions.
diff --git a/chrome/browser/ui/browser_navigator_browsertest.cc b/chrome/browser/ui/browser_navigator_browsertest.cc
index f6b69b2..efd2a61 100644
--- a/chrome/browser/ui/browser_navigator_browsertest.cc
+++ b/chrome/browser/ui/browser_navigator_browsertest.cc
@@ -744,7 +744,7 @@
             OmniboxFocusState::OMNIBOX_FOCUS_NONE);
 }
 
-#if defined(OS_LINUX)
+#if BUILDFLAG(IS_LINUX)
 // Flaky on Linux Ozone. See https://crbug.com/1230723.
 #define MAYBE_SwitchToTabCorrectWindow DISABLED_SwitchToTabCorrectWindow
 #else
@@ -941,7 +941,7 @@
   EXPECT_EQ(browser(), test_browser);
 }
 
-#if defined(OS_MAC) && defined(ADDRESS_SANITIZER)
+#if BUILDFLAG(IS_MAC) && defined(ADDRESS_SANITIZER)
 // Flaky on ASAN on Mac. See https://crbug.com/674497.
 #define MAYBE_Disposition_Incognito DISABLED_Disposition_Incognito
 #else
@@ -1022,7 +1022,7 @@
   EXPECT_EQ(2, browser()->tab_strip_model()->count());
 }
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 // This tests adding a popup with a predefined WebContents.
 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, DISABLED_TargetContents_Popup) {
   NavigateParams params(MakeNavigateParams());
@@ -1531,7 +1531,7 @@
 
 // TODO(crbug.com/1171245): This is disabled for Mac OS due to flakiness.
 // TODO(1024166): Timing out on linux-chromeos-dbg.
-#if BUILDFLAG(IS_CHROMEOS_ASH) || defined(OS_MAC)
+#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_MAC)
 #define MAYBE_NavigateFromNTPToOptionsPageInSameTab \
   DISABLED_NavigateFromNTPToOptionsPageInSameTab
 #else
@@ -1668,7 +1668,7 @@
 }
 
 // TODO(linux_aura) http://crbug.com/163931
-#if (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) && defined(USE_AURA)
+#if (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) && defined(USE_AURA)
 #define MAYBE_NavigateFromDefaultToBookmarksInSameTab \
   DISABLED_NavigateFromDefaultToBookmarksInSameTab
 #else
@@ -1846,7 +1846,7 @@
 // RenderViewHost's GetMainFrame() when it was invalid in RenderViewCreated().
 // See https://crbug.com/627027.
 // Flaky on Mac. See https://crbug.com/1044335.
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #define MAYBE_ReuseRVHWithWebUI DISABLED_ReuseRVHWithWebUI
 #else
 #define MAYBE_ReuseRVHWithWebUI ReuseRVHWithWebUI
diff --git a/chrome/browser/ui/browser_navigator_params.cc b/chrome/browser/ui/browser_navigator_params.cc
index d8149ec7..6c0e895 100644
--- a/chrome/browser/ui/browser_navigator_params.cc
+++ b/chrome/browser/ui/browser_navigator_params.cc
@@ -13,7 +13,7 @@
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/web_contents.h"
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 #include "chrome/browser/ui/browser.h"
 #endif
 
@@ -21,7 +21,7 @@
 using content::NavigationController;
 using content::WebContents;
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 NavigateParams::NavigateParams(std::unique_ptr<WebContents> contents_to_insert)
     : contents_to_insert(std::move(contents_to_insert)) {}
 #else
@@ -33,7 +33,7 @@
 NavigateParams::NavigateParams(Browser* a_browser,
                                std::unique_ptr<WebContents> contents_to_insert)
     : contents_to_insert(std::move(contents_to_insert)), browser(a_browser) {}
-#endif  // !defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_ANDROID)
 
 NavigateParams::NavigateParams(Profile* a_profile,
                                const GURL& a_url,
diff --git a/chrome/browser/ui/browser_navigator_params.h b/chrome/browser/ui/browser_navigator_params.h
index c4b460d..148cfff 100644
--- a/chrome/browser/ui/browser_navigator_params.h
+++ b/chrome/browser/ui/browser_navigator_params.h
@@ -29,7 +29,7 @@
 #include "ui/gfx/geometry/rect.h"
 #include "url/gurl.h"
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "components/tab_groups/tab_group_id.h"
 #endif
@@ -67,7 +67,7 @@
 
 // TODO(thestig): Split or ifdef out more fields that are not used on Android.
 struct NavigateParams {
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   explicit NavigateParams(
       std::unique_ptr<content::WebContents> contents_to_insert);
 #else
@@ -236,7 +236,7 @@
   };
   PathBehavior path_behavior = RESPECT;
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
   // [in]  Specifies a Browser object where the navigation could occur or the
   //       tab could be added. Navigate() is not obliged to use this Browser if
   //       it is not compatible with the operation being performed. This can be
diff --git a/chrome/browser/ui/browser_tabrestore.cc b/chrome/browser/ui/browser_tabrestore.cc
index a47d033..0722a70f 100644
--- a/chrome/browser/ui/browser_tabrestore.cc
+++ b/chrome/browser/ui/browser_tabrestore.cc
@@ -188,7 +188,7 @@
     raw_web_contents->WasHidden();
   } else {
     const bool should_activate =
-#if defined(OS_WIN) || defined(OS_MAC)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
         // Activating a window on another space causes the system to switch to
         // that space. Since the session restore process shows and activates
         // windows itself, activating windows here should be safe to skip.
@@ -210,9 +210,9 @@
 // On OS_MAC, app restorations take longer than the normal browser window to
 // be restored and that will cause LoadRestoredTabIfVisible() to fail.
 // Skip LoadRestoreTabIfVisible if OS_MAC && the browser is an app browser.
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   if (browser->type() != Browser::Type::TYPE_APP)
-#endif  // defined(OS_MAC)
+#endif  // BUILDFLAG(IS_MAC)
     LoadRestoredTabIfVisible(browser, raw_web_contents);
 
   return raw_web_contents;
diff --git a/chrome/browser/ui/browser_ui_prefs.cc b/chrome/browser/ui/browser_ui_prefs.cc
index 20bb8b5..e2fb6a2 100644
--- a/chrome/browser/ui/browser_ui_prefs.cc
+++ b/chrome/browser/ui/browser_ui_prefs.cc
@@ -25,14 +25,14 @@
 #include "ui/accessibility/accessibility_features.h"
 #endif
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 #include "base/win/windows_version.h"
 #endif
 
 namespace {
 
 uint32_t GetHomeButtonAndHomePageIsNewTabPageFlags() {
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   return PrefRegistry::NO_REGISTRATION_FLAGS;
 #else
   return user_prefs::PrefRegistrySyncable::SYNCABLE_PREF;
@@ -44,7 +44,7 @@
 void RegisterBrowserPrefs(PrefRegistrySimple* registry) {
   registry->RegisterBooleanPref(prefs::kAllowFileSelectionDialogs, true);
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
   registry->RegisterIntegerPref(prefs::kRelaunchNotification, 0);
   registry->RegisterIntegerPref(
       prefs::kRelaunchNotificationPeriod,
@@ -52,12 +52,12 @@
           UpgradeDetector::GetDefaultHighAnnoyanceThreshold()
               .InMilliseconds()));
   registry->RegisterDictionaryPref(prefs::kRelaunchWindow);
-#endif  // !defined(OS_ANDROID)
+#endif  // !BUILDFLAG(IS_ANDROID)
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   registry->RegisterIntegerPref(
       prefs::kMacRestoreLocationPermissionsExperimentCount, 0);
-#endif  // defined(OS_MAC)
+#endif  // BUILDFLAG(IS_MAC)
 }
 
 void RegisterBrowserUserPrefs(user_prefs::PrefRegistrySyncable* registry) {
@@ -68,7 +68,7 @@
 
   registry->RegisterInt64Pref(prefs::kDefaultBrowserLastDeclined, 0);
   bool reset_check_default = false;
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   reset_check_default = base::win::GetVersion() >= base::win::Version::WIN10;
 #endif
   registry->RegisterBooleanPref(prefs::kResetCheckDefaultBrowser,
@@ -88,7 +88,7 @@
   registry->RegisterBooleanPref(
       prefs::kEnableDoNotTrack, false,
       user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
-#if !BUILDFLAG(IS_CHROMEOS_ASH) && !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_ANDROID)
   registry->RegisterBooleanPref(prefs::kPrintPreviewUseSystemDefaultPrinter,
                                 false);
 #endif
@@ -117,7 +117,7 @@
   registry->RegisterBooleanPref(prefs::kClickToCallEnabled, true);
 #endif  // BUILDFLAG(ENABLE_CLICK_TO_CALL)
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   // This really belongs in platform code, but there's no good place to
   // initialize it between the time when the AppController is created
   // (where there's no profile) and the time the controller gets another
@@ -149,7 +149,7 @@
   registry->RegisterListPref(prefs::kTabCaptureAllowedByOrigins);
   registry->RegisterListPref(prefs::kSameOriginTabCaptureAllowedByOrigins);
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
   registry->RegisterBooleanPref(prefs::kCaretBrowsingEnabled, false);
   registry->RegisterBooleanPref(prefs::kShowCaretBrowsingDialog, true);
 #endif
diff --git a/chrome/browser/ui/browser_unittest.cc b/chrome/browser/ui/browser_unittest.cc
index 5d9ccfc..fabfbce 100644
--- a/chrome/browser/ui/browser_unittest.cc
+++ b/chrome/browser/ui/browser_unittest.cc
@@ -92,7 +92,7 @@
 
 // This tests a workaround which is not necessary on Mac.
 // https://crbug.com/719230
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #define MAYBE_SetBackgroundColorForNewTab DISABLED_SetBackgroundColorForNewTab
 #else
 #define MAYBE_SetBackgroundColorForNewTab SetBackgroundColorForNewTab
diff --git a/chrome/browser/ui/browser_view_prefs.cc b/chrome/browser/ui/browser_view_prefs.cc
index 9c51fe8..7473c3c 100644
--- a/chrome/browser/ui/browser_view_prefs.cc
+++ b/chrome/browser/ui/browser_view_prefs.cc
@@ -17,7 +17,7 @@
 
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
-#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
 bool GetCustomFramePrefDefault() {
 #if defined(USE_OZONE)
     return ui::OzonePlatform::GetInstance()
@@ -35,9 +35,8 @@
     user_prefs::PrefRegistrySyncable* registry) {
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
-#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
   registry->RegisterBooleanPref(prefs::kUseCustomChromeFrame,
                                 GetCustomFramePrefDefault());
-#endif  // (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) &&
-        // defined(!OS_CHROMEOS)
+#endif
 }
diff --git a/chrome/browser/ui/browser_window.h b/chrome/browser/ui/browser_window.h
index 69bcd2a..76497f5 100644
--- a/chrome/browser/ui/browser_window.h
+++ b/chrome/browser/ui/browser_window.h
@@ -31,7 +31,7 @@
 #include "ui/gfx/native_widget_types.h"
 #include "url/origin.h"
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 #error This file should only be included on desktop.
 #endif
 
diff --git a/chrome/browser/ui/chrome_pages.cc b/chrome/browser/ui/chrome_pages.cc
index 491195f..af80cd6 100644
--- a/chrome/browser/ui/chrome_pages.cc
+++ b/chrome/browser/ui/chrome_pages.cc
@@ -15,6 +15,7 @@
 #include "base/strings/strcat.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
+#include "build/build_config.h"
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
 #include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
@@ -60,7 +61,7 @@
 #include "chrome/browser/ui/signin_view_controller.h"
 #endif
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "components/signin/public/base/signin_pref_names.h"
 #include "components/signin/public/identity_manager/identity_manager.h"
diff --git a/chrome/browser/ui/chrome_pages.h b/chrome/browser/ui/chrome_pages.h
index c45e1bb..3947a46 100644
--- a/chrome/browser/ui/chrome_pages.h
+++ b/chrome/browser/ui/chrome_pages.h
@@ -17,7 +17,7 @@
 #include "components/signin/public/base/signin_buildflags.h"
 #include "url/gurl.h"
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 #include "chrome/browser/signin/signin_promo.h"
 #endif
 
diff --git a/chrome/browser/ui/cocoa/applescript/scripting.sdef b/chrome/browser/ui/cocoa/applescript/scripting.sdef
index 3117c332..88ce33d 100644
--- a/chrome/browser/ui/cocoa/applescript/scripting.sdef
+++ b/chrome/browser/ui/cocoa/applescript/scripting.sdef
@@ -270,7 +270,9 @@
         <cocoa key="uniqueID"/>
       </property>
       <property name="title" code="pnam" description="The title of the folder." type="text"/>
-      <property name="index" code="indx" description="Returns the index with respect to its parent bookmark folder" type="number" access="r"/>
+      <property name="parent index" code="Pidx" description="Returns the index with respect to its parent bookmark folder" type="number" access="r">
+        <cocoa key="index"/>
+      </property>
     </class>
 
     <class name="bookmark item" code="CrBI" description="An item consists of an URL and the title of a bookmark">
@@ -280,7 +282,9 @@
       </property>
       <property name="title" code="pnam" description="The title of the bookmark item." type="text"/>
       <property name="URL" code="URL " description="The URL of the bookmark." type="text"/>
-      <property name="index" code="indx" description="Returns the index with respect to its parent bookmark folder" type="number" access="r"/>
+      <property name="parent index" code="Pidx" description="Returns the index with respect to its parent bookmark folder" type="number" access="r">
+        <cocoa key="index"/>
+      </property>
     </class>
 
     <command name="reload" code="CrSuRlod" description="Reload a tab.">
diff --git a/chrome/browser/ui/cocoa/last_active_browser_cocoa.h b/chrome/browser/ui/cocoa/last_active_browser_cocoa.h
index 932fe0f4..41b6105 100644
--- a/chrome/browser/ui/cocoa/last_active_browser_cocoa.h
+++ b/chrome/browser/ui/cocoa/last_active_browser_cocoa.h
@@ -12,7 +12,7 @@
 // the Cocoa frontend that cannot be allowed via C++ friendship as these places
 // are in Obj-C objects.
 // Do NOT include or build this file on non-Mac platforms.
-#if !defined(OS_MAC)
+#if !BUILDFLAG(IS_MAC)
 #error This file is intended for use in the Cocoa frontend only.
 #endif
 
diff --git a/chrome/browser/ui/color/native_chrome_color_mixer.cc b/chrome/browser/ui/color/native_chrome_color_mixer.cc
index 4eb7302..2a1531b 100644
--- a/chrome/browser/ui/color/native_chrome_color_mixer.cc
+++ b/chrome/browser/ui/color/native_chrome_color_mixer.cc
@@ -6,7 +6,7 @@
 
 #include "build/build_config.h"
 
-#if !defined(OS_WIN)
+#if !BUILDFLAG(IS_WIN)
 void AddNativeChromeColorMixer(ui::ColorProvider* provider,
                                const ui::ColorProviderManager::Key& key) {}
 #endif
diff --git a/chrome/browser/ui/color/tools/dump_colors.cc b/chrome/browser/ui/color/tools/dump_colors.cc
index 00fcacd..f125f7a9 100644
--- a/chrome/browser/ui/color/tools/dump_colors.cc
+++ b/chrome/browser/ui/color/tools/dump_colors.cc
@@ -30,7 +30,7 @@
 
 #include "ui/color/color_id_macros.inc"
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #include "ui/color/color_mixers.h"
 #endif
 
diff --git a/chrome/browser/ui/dialogs/outdated_upgrade_bubble.cc b/chrome/browser/ui/dialogs/outdated_upgrade_bubble.cc
index 1500f222..ad150da 100644
--- a/chrome/browser/ui/dialogs/outdated_upgrade_bubble.cc
+++ b/chrome/browser/ui/dialogs/outdated_upgrade_bubble.cc
@@ -27,7 +27,7 @@
 #include "ui/base/models/dialog_model.h"
 #include "url/gurl.h"
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 #include "chrome/installer/util/google_update_util.h"
 #endif
 
@@ -85,7 +85,7 @@
         GURL(update_browser_redirect_url), content::Referrer(),
         WindowOpenDisposition::NEW_FOREGROUND_TAB, ui::PAGE_TRANSITION_LINK,
         false));
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   } else {
     DCHECK(UpgradeDetector::GetInstance()->is_outdated_install_no_au());
     UMA_HISTOGRAM_CUSTOM_COUNTS("OutdatedUpgradeBubble.NumLaterPerEnableAU",
@@ -105,7 +105,7 @@
         {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
          base::TaskShutdownBehavior::BLOCK_SHUTDOWN},
         base::BindOnce(&google_update::ElevateIfNeededToReenableUpdates));
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
   }
 }
 
diff --git a/chrome/browser/ui/extensions/application_launch.cc b/chrome/browser/ui/extensions/application_launch.cc
index 45930f9..df9fea2 100644
--- a/chrome/browser/ui/extensions/application_launch.cc
+++ b/chrome/browser/ui/extensions/application_launch.cc
@@ -55,7 +55,7 @@
 #include "ui/display/scoped_display_for_new_windows.h"
 #include "ui/gfx/geometry/rect.h"
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #include "chrome/browser/ui/browser_commands_mac.h"
 #endif
 
diff --git a/chrome/browser/ui/extensions/extension_install_ui_default.cc b/chrome/browser/ui/extensions/extension_install_ui_default.cc
index 681483b9..28c9f94 100644
--- a/chrome/browser/ui/extensions/extension_install_ui_default.cc
+++ b/chrome/browser/ui/extensions/extension_install_ui_default.cc
@@ -31,8 +31,9 @@
 #include "extensions/common/extension.h"
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-#include "ash/public/cpp/toast_data.h"
-#include "ash/public/cpp/toast_manager.h"
+#include "ash/public/cpp/system/toast_catalog.h"
+#include "ash/public/cpp/system/toast_data.h"
+#include "ash/public/cpp/system/toast_manager.h"
 #include "chrome/grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
 #else
@@ -62,8 +63,10 @@
 // Toast id and duration for extension install success.
 constexpr char kExtensionInstallSuccessToastId[] = "extension_install_success";
 
-void ShowToast(const std::string& id, const std::u16string& text) {
-  ash::ToastManager::Get()->Show(ash::ToastData(id, text));
+void ShowToast(const std::string& id,
+               ash::ToastCatalogName catalog_name,
+               const std::u16string& text) {
+  ash::ToastManager::Get()->Show(ash::ToastData(id, catalog_name, text));
 }
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
@@ -101,16 +104,17 @@
       return;
     }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
     // TODO(crbug.com/1286603): Show Toast for Lacros.
 #if BUILDFLAG(IS_CHROMEOS_ASH)
     ShowToast(kExtensionInstallSuccessToastId,
+              ash::ToastCatalogName::kExtensionInstallSuccess,
               l10n_util::GetStringFUTF16(IDS_EXTENSION_NOTIFICATION_INSTALLED,
                                          base::UTF8ToUTF16(extension->name())));
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
-#else   // defined(OS_CHROMEOS)
+#else   // BUILDFLAG(IS_CHROMEOS)
     OpenAppInstalledUI(extension->id());
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
     return;
   }
 
@@ -135,7 +139,7 @@
 }
 
 void ExtensionInstallUIDefault::OpenAppInstalledUI(const std::string& app_id) {
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   // chrome://apps/ is not available on ChromeOS.
   // Toast is shown for Ash (not yet Lacros: crbug.com/1286603).
   NOTREACHED();
diff --git a/chrome/browser/ui/extensions/extension_message_bubble_factory.cc b/chrome/browser/ui/extensions/extension_message_bubble_factory.cc
index a91c1d6..b5032c9 100644
--- a/chrome/browser/ui/extensions/extension_message_bubble_factory.cc
+++ b/chrome/browser/ui/extensions/extension_message_bubble_factory.cc
@@ -47,7 +47,7 @@
 }
 
 bool EnableSettingsApiBubble() {
-#if defined(OS_WIN) || defined(OS_MAC)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
   return true;
 #else
   return g_override_for_testing ==
@@ -56,7 +56,7 @@
 }
 
 bool EnableProxyOverrideBubble() {
-#if defined(OS_WIN) || defined(OS_MAC)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
   return true;
 #else
   return g_override_for_testing ==
@@ -76,7 +76,7 @@
   if (command_line->HasSwitch(switches::kEnableAutomation))
     return false;
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   if (chrome::GetChannel() >= version_info::Channel::BETA)
     return true;
 #endif
diff --git a/chrome/browser/ui/extensions/hosted_app_browsertest.cc b/chrome/browser/ui/extensions/hosted_app_browsertest.cc
index 91b8e28c..510b50f 100644
--- a/chrome/browser/ui/extensions/hosted_app_browsertest.cc
+++ b/chrome/browser/ui/extensions/hosted_app_browsertest.cc
@@ -374,7 +374,7 @@
 
 // Tests that Ctrl + Clicking a link opens a foreground tab.
 // TODO(crbug.com/1190448): Flaky on Linux.
-#if defined(OS_LINUX)
+#if BUILDFLAG(IS_LINUX)
 #define MAYBE_CtrlClickLink DISABLED_CtrlClickLink
 #else
 #define MAYBE_CtrlClickLink CtrlClickLink
@@ -399,7 +399,7 @@
             ui_test_utils::UrlLoadObserver url_observer(
                 target_url, content::NotificationService::AllSources());
             int ctrl_key;
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
             ctrl_key = blink::WebInputEvent::Modifiers::kMetaKey;
 #else
             ctrl_key = blink::WebInputEvent::Modifiers::kControlKey;
@@ -573,7 +573,7 @@
 }
 
 // Flaky, mostly on Windows: http://crbug.com/1032319
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 #define MAYBE_ShouldShowCustomTabBarForHTTPAppHTTPSUrl \
   DISABLED_ShouldShowCustomTabBarForHTTPAppHTTPSUrl
 #else
@@ -1182,7 +1182,7 @@
 // OOPIF unless there is another reason to create it, but popups from outside
 // the app will swap into the app.
 // TODO(crbug.com/807471): Flaky on Windows 7.
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 #define MAYBE_FromOutsideHostedApp DISABLED_FromOutsideHostedApp
 #else
 #define MAYBE_FromOutsideHostedApp FromOutsideHostedApp
@@ -1282,7 +1282,7 @@
 // site URL. See https://crbug.com/1016954.
 // The navigation currently fails/results in a 404 on Windows, so it's currently
 // disabled.  TODO(crbug.com/1137323): Fix this.
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 #define MAYBE_NavigateToAppURLWithDoubleSlashPath \
   DISABLED_NavigateToAppURLWithDoubleSlashPath
 #else
diff --git a/chrome/browser/ui/extensions/settings_api_bubble_helpers.cc b/chrome/browser/ui/extensions/settings_api_bubble_helpers.cc
index 4cdc08e..a21788e 100644
--- a/chrome/browser/ui/extensions/settings_api_bubble_helpers.cc
+++ b/chrome/browser/ui/extensions/settings_api_bubble_helpers.cc
@@ -36,7 +36,7 @@
 
 // Whether the NTP post-install UI is enabled. By default, this is limited to
 // Windows, Mac, and ChromeOS, but can be overridden for testing.
-#if defined(OS_WIN) || defined(OS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH)
 bool g_ntp_post_install_ui_enabled = true;
 #else
 bool g_ntp_post_install_ui_enabled = false;
@@ -49,7 +49,7 @@
 // false (and keep the logic around for when/if we decide to expand the warning
 // treatment to Linux).
 bool g_acknowledge_existing_ntp_extensions =
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
     true;
 #else
     false;
@@ -60,7 +60,7 @@
 const char kDidAcknowledgeExistingNtpExtensions[] =
     "ack_existing_ntp_extensions";
 
-#if defined(OS_WIN) || defined(OS_MAC)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
 void ShowSettingsApiBubble(SettingsApiOverrideType type,
                            Browser* browser) {
   ToolbarActionsModel* model = ToolbarActionsModel::Get(browser->profile());
@@ -125,7 +125,7 @@
 }
 
 void MaybeShowExtensionControlledHomeNotification(Browser* browser) {
-#if defined(OS_WIN) || defined(OS_MAC)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
   ShowSettingsApiBubble(BUBBLE_TYPE_HOME_PAGE, browser);
 #endif
 }
@@ -133,7 +133,7 @@
 void MaybeShowExtensionControlledSearchNotification(
     content::WebContents* web_contents,
     AutocompleteMatch::Type match_type) {
-#if defined(OS_WIN) || defined(OS_MAC)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
   if (!AutocompleteMatch::IsSearchType(match_type) ||
       match_type == AutocompleteMatchType::SEARCH_OTHER_ENGINE) {
     return;
diff --git a/chrome/browser/ui/extensions/settings_overridden_params_providers_browsertest.cc b/chrome/browser/ui/extensions/settings_overridden_params_providers_browsertest.cc
index 132e3b4c..4706438 100644
--- a/chrome/browser/ui/extensions/settings_overridden_params_providers_browsertest.cc
+++ b/chrome/browser/ui/extensions/settings_overridden_params_providers_browsertest.cc
@@ -87,7 +87,7 @@
 
 // The chrome_settings_overrides API that allows extensions to override the
 // default search provider is only available on Windows and Mac.
-#if defined(OS_WIN) || defined(OS_MAC)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
 
 // NOTE: It's very unfortunate that this has to be a browsertest. Unfortunately,
 // a few bits here - the TemplateURLService in particular - don't play nicely
@@ -273,7 +273,7 @@
   EXPECT_FALSE(params) << "Unexpected params: " << params->dialog_title;
 }
 
-#endif  // defined(OS_WIN) || defined(OS_MAC)
+#endif  // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
 
 // Tests the dialog display when the default search engine has changed; in this
 // case, we should display the generic dialog.
diff --git a/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc b/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc
index ddb7f38..db7d2d2 100644
--- a/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc
+++ b/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc
@@ -45,7 +45,7 @@
 #include "ui/base/accelerators/accelerator.h"
 #include "ui/events/keycodes/keyboard_codes.h"
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 #include "ui/aura/window.h"
 #include "ui/aura/window_tree_host.h"
 #endif
@@ -496,9 +496,9 @@
 
 // Find in a very large page.
 // TODO(crbug.com/1077855): Test is flaky on Mac debug builds.
-#if defined(OS_MAC) && !defined(NDEBUG)
+#if BUILDFLAG(IS_MAC) && !defined(NDEBUG)
 #define MAYBE_LargePage DISABLED_LargePage
-#elif defined(OS_LINUX) && (!defined(NDEBUG) || defined(ADDRESS_SANITIZER))
+#elif BUILDFLAG(IS_LINUX) && (!defined(NDEBUG) || defined(ADDRESS_SANITIZER))
 // TODO(crbug.com/1181717): Test is flaky on Linux debug builds.
 // TODO(crbug.com/1198685): Test is flaky on Linux ASAN builds.
 #define MAYBE_LargePage DISABLED_LargePage
@@ -517,9 +517,9 @@
 
 // Find a very long string in a large page.
 // TODO(crbug.com/1096911): Test is flaky on Mac debug builds and Linux asan.
-#if (defined(OS_MAC) && !defined(NDEBUG)) || defined(ADDRESS_SANITIZER)
+#if (BUILDFLAG(IS_MAC) && !defined(NDEBUG)) || defined(ADDRESS_SANITIZER)
 #define MAYBE_FindLongString DISABLED_FindLongString
-#elif defined(OS_LINUX) && !defined(NDEBUG)
+#elif BUILDFLAG(IS_LINUX) && !defined(NDEBUG)
 // TODO(crbug.com/1181717): Test is flaky on Linux debug builds.
 #define MAYBE_FindLongString DISABLED_FindLongString
 #else
@@ -1196,7 +1196,7 @@
 // with the last search from the same tab rather than the last overall search.
 // The only exception is if there is a global pasteboard (for example on Mac).
 // http://crbug.com/30006
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #define MAYBE_PreferPreviousSearch DISABLED_PreferPreviousSearch
 #else
 #define MAYBE_PreferPreviousSearch PreferPreviousSearch
@@ -1527,7 +1527,7 @@
 
 // Verify that if there's a global pasteboard (for example on Mac) then doing
 // a search on one tab will clear the matches label on the other tabs.
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 // TODO(http://crbug.com/843878): Remove the interactive UI test
 // FindBarPlatformHelperMacInteractiveUITest.GlobalPasteBoardClearMatches
 // once http://crbug.com/843878 is fixed.
@@ -1614,7 +1614,7 @@
 
 // Find text in regular window, send IDC_FIND_NEXT to incognito. It should
 // search for the first phrase.
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #define MAYBE_IncognitoFindNextShared DISABLED_IncognitoFindNextShared
 #else
 #define MAYBE_IncognitoFindNextShared IncognitoFindNextShared
diff --git a/chrome/browser/ui/find_bar/find_bar_platform_helper.cc b/chrome/browser/ui/find_bar/find_bar_platform_helper.cc
index d1cd055..fedafaae 100644
--- a/chrome/browser/ui/find_bar/find_bar_platform_helper.cc
+++ b/chrome/browser/ui/find_bar/find_bar_platform_helper.cc
@@ -6,7 +6,7 @@
 
 #include "build/build_config.h"
 
-#if !defined(OS_MAC)
+#if !BUILDFLAG(IS_MAC)
 // static
 std::unique_ptr<FindBarPlatformHelper> FindBarPlatformHelper::Create(
     FindBarController* find_bar_controller) {
diff --git a/chrome/browser/ui/font_access/DIR_METADATA b/chrome/browser/ui/font_access/DIR_METADATA
deleted file mode 100644
index be579e9..0000000
--- a/chrome/browser/ui/font_access/DIR_METADATA
+++ /dev/null
@@ -1 +0,0 @@
-mixins: "//content/browser/font_access/COMMON_METADATA"
diff --git a/chrome/browser/ui/font_access/OWNERS b/chrome/browser/ui/font_access/OWNERS
deleted file mode 100644
index 92a7265..0000000
--- a/chrome/browser/ui/font_access/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-file://content/browser/font_access/OWNERS
diff --git a/chrome/browser/ui/font_access/font_access_chooser.cc b/chrome/browser/ui/font_access/font_access_chooser.cc
deleted file mode 100644
index 9cf97e3c..0000000
--- a/chrome/browser/ui/font_access/font_access_chooser.cc
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ui/font_access/font_access_chooser.h"
-#include "content/public/browser/font_access_chooser.h"
-
-FontAccessChooser::FontAccessChooser(base::OnceClosure close_callback)
-    : closure_runner_(std::move(close_callback)) {}
diff --git a/chrome/browser/ui/font_access/font_access_chooser.h b/chrome/browser/ui/font_access/font_access_chooser.h
deleted file mode 100644
index ecdb6c7..0000000
--- a/chrome/browser/ui/font_access/font_access_chooser.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_UI_FONT_ACCESS_FONT_ACCESS_CHOOSER_H_
-#define CHROME_BROWSER_UI_FONT_ACCESS_FONT_ACCESS_CHOOSER_H_
-
-#include "base/callback_helpers.h"
-#include "content/public/browser/font_access_chooser.h"
-
-class FontAccessChooser : public content::FontAccessChooser {
- public:
-  explicit FontAccessChooser(base::OnceClosure close_callback);
-  ~FontAccessChooser() override = default;
-
- private:
-  base::ScopedClosureRunner closure_runner_;
-};
-
-#endif  // CHROME_BROWSER_UI_FONT_ACCESS_FONT_ACCESS_CHOOSER_H_
diff --git a/chrome/browser/ui/font_access/font_access_chooser_controller.cc b/chrome/browser/ui/font_access/font_access_chooser_controller.cc
deleted file mode 100644
index 07d2f1b..0000000
--- a/chrome/browser/ui/font_access/font_access_chooser_controller.cc
+++ /dev/null
@@ -1,166 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ui/font_access/font_access_chooser_controller.h"
-
-#include "base/containers/contains.h"
-#include "base/strings/utf_string_conversions.h"
-#include "chrome/grit/generated_resources.h"
-#include "components/permissions/chooser_title_util.h"
-#include "content/public/browser/font_access_chooser.h"
-#include "content/public/browser/font_access_context.h"
-#include "content/public/browser/render_frame_host.h"
-#include "content/public/browser/storage_partition.h"
-#include "content/public/browser/web_contents.h"
-#include "third_party/blink/public/mojom/font_access/font_access.mojom-shared.h"
-#include "ui/base/l10n/l10n_util.h"
-
-namespace {
-
-content::FontAccessContext* GetChooserContext(content::RenderFrameHost* frame) {
-  return frame->GetStoragePartition()->GetFontAccessContext();
-}
-
-}  // namespace
-
-FontAccessChooserController::FontAccessChooserController(
-    content::RenderFrameHost* frame,
-    const std::vector<std::string>& selection,
-    content::FontAccessChooser::Callback callback)
-    : ChooserController(permissions::CreateChooserTitle(
-          frame,
-          IDS_FONT_ACCESS_CHOOSER_PROMPT_ORIGIN)),
-      callback_(std::move(callback)) {
-  DCHECK(frame);
-
-  content::FontAccessContext* chooser_context = GetChooserContext(frame);
-  if (chooser_context == nullptr) {
-    std::move(callback_).Run(
-        blink::mojom::FontEnumerationStatus::kUnexpectedError, {});
-    return;
-  }
-
-  selection_ = base::flat_set<std::string>(selection);
-
-  chooser_context->FindAllFonts(
-      base::BindOnce(&FontAccessChooserController::DidFindAllFonts,
-                     weak_factory_.GetWeakPtr()));
-}
-
-FontAccessChooserController::~FontAccessChooserController() {
-  if (callback_) {
-    std::move(callback_).Run(
-        blink::mojom::FontEnumerationStatus::kUnexpectedError, {});
-  }
-}
-
-std::u16string FontAccessChooserController::GetNoOptionsText() const {
-  return l10n_util::GetStringUTF16(
-      IDS_FONT_ACCESS_CHOOSER_NO_FONTS_FOUND_PROMPT);
-}
-
-std::u16string FontAccessChooserController::GetOkButtonLabel() const {
-  return l10n_util::GetStringUTF16(IDS_FONT_ACCESS_CHOOSER_IMPORT_BUTTON_TEXT);
-}
-
-std::pair<std::u16string, std::u16string>
-FontAccessChooserController::GetThrobberLabelAndTooltip() const {
-  return {
-      l10n_util::GetStringUTF16(IDS_FONT_ACCESS_CHOOSER_LOADING_LABEL),
-      l10n_util::GetStringUTF16(IDS_FONT_ACCESS_CHOOSER_LOADING_LABEL_TOOLTIP)};
-}
-
-size_t FontAccessChooserController::NumOptions() const {
-  return items_.size();
-}
-
-std::u16string FontAccessChooserController::GetOption(size_t index) const {
-  DCHECK_LT(index, items_.size());
-  DCHECK(base::Contains(font_metadata_map_, items_[index]));
-
-  return base::UTF8ToUTF16(items_[index]);
-}
-
-std::u16string FontAccessChooserController::GetSelectAllCheckboxLabel() const {
-  return l10n_util::GetStringUTF16(
-      IDS_FONT_ACCESS_CHOOSER_SELECT_ALL_CHECKBOX_TEXT);
-}
-
-bool FontAccessChooserController::ShouldShowHelpButton() const {
-  return false;
-}
-
-bool FontAccessChooserController::ShouldShowReScanButton() const {
-  return false;
-}
-
-bool FontAccessChooserController::BothButtonsAlwaysEnabled() const {
-  // Import button is disabled if there isn't at least one selection.
-  return false;
-}
-
-bool FontAccessChooserController::AllowMultipleSelection() const {
-  return true;
-}
-
-bool FontAccessChooserController::ShouldShowSelectAllCheckbox() const {
-  return true;
-}
-
-bool FontAccessChooserController::TableViewAlwaysDisabled() const {
-  return false;
-}
-
-void FontAccessChooserController::Select(const std::vector<size_t>& indices) {
-  DCHECK_GT(indices.size(), 0u);
-
-  std::vector<blink::mojom::FontMetadataPtr> fonts;
-
-  for (auto& index : indices) {
-    DCHECK_LT(index, items_.size());
-    auto found = font_metadata_map_.find(items_[index]);
-    if (found == font_metadata_map_.end()) {
-      continue;
-    }
-    fonts.push_back(found->second.Clone());
-  }
-
-  std::move(callback_).Run(blink::mojom::FontEnumerationStatus::kOk,
-                           std::move(fonts));
-}
-
-void FontAccessChooserController::Cancel() {
-  std::move(callback_).Run(blink::mojom::FontEnumerationStatus::kCanceled, {});
-}
-
-void FontAccessChooserController::Close() {
-  std::move(callback_).Run(blink::mojom::FontEnumerationStatus::kCanceled, {});
-}
-
-void FontAccessChooserController::OpenHelpCenterUrl() const {
-  NOTIMPLEMENTED();
-}
-
-void FontAccessChooserController::DidFindAllFonts(
-    blink::mojom::FontEnumerationStatus status,
-    std::vector<blink::mojom::FontMetadata> fonts) {
-  for (auto& font : fonts) {
-    auto found = font_metadata_map_.find(font.postscript_name);
-    // If the font is already in the map, skip it.
-    if (found != font_metadata_map_.end()) {
-      continue;
-    }
-    // If a selection list is provided and the font isn't in the list, skip it.
-    if (!selection_.empty() && !selection_.contains(font.postscript_name)) {
-      continue;
-    }
-    items_.push_back(font.postscript_name);
-    font_metadata_map_[font.postscript_name] = std::move(font);
-  }
-  if (view())
-    view()->OnOptionsInitialized();
-
-  if (ready_callback_for_testing_)
-    std::move(ready_callback_for_testing_).Run();
-}
diff --git a/chrome/browser/ui/font_access/font_access_chooser_controller.h b/chrome/browser/ui/font_access/font_access_chooser_controller.h
deleted file mode 100644
index 5ed8d68..0000000
--- a/chrome/browser/ui/font_access/font_access_chooser_controller.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-#ifndef CHROME_BROWSER_UI_FONT_ACCESS_FONT_ACCESS_CHOOSER_CONTROLLER_H_
-#define CHROME_BROWSER_UI_FONT_ACCESS_FONT_ACCESS_CHOOSER_CONTROLLER_H_
-
-#include "base/callback.h"
-#include "base/containers/flat_set.h"
-#include "components/permissions/chooser_controller.h"
-#include "content/public/browser/font_access_chooser.h"
-#include "content/public/browser/render_frame_host.h"
-#include "third_party/blink/public/mojom/font_access/font_access.mojom-shared.h"
-#include "third_party/blink/public/mojom/font_access/font_access.mojom.h"
-
-namespace content {
-
-class RenderFrameHost;
-
-}  // namespace content
-
-class FontAccessChooserController : public permissions::ChooserController {
- public:
-  FontAccessChooserController(content::RenderFrameHost* render_frame_host,
-                              const std::vector<std::string>& selection,
-                              content::FontAccessChooser::Callback callback);
-  ~FontAccessChooserController() override;
-
-  // Disallow copy and assign.
-  FontAccessChooserController(FontAccessChooserController&) = delete;
-  FontAccessChooserController& operator=(FontAccessChooserController&) = delete;
-
-  // permissions::ChooserController:
-  std::u16string GetNoOptionsText() const override;
-  std::u16string GetOkButtonLabel() const override;
-  std::pair<std::u16string, std::u16string> GetThrobberLabelAndTooltip()
-      const override;
-  size_t NumOptions() const override;
-  std::u16string GetOption(size_t index) const override;
-  std::u16string GetSelectAllCheckboxLabel() const override;
-
-  bool ShouldShowHelpButton() const override;
-  bool ShouldShowReScanButton() const override;
-  bool BothButtonsAlwaysEnabled() const override;
-  bool TableViewAlwaysDisabled() const override;
-  bool AllowMultipleSelection() const override;
-  bool ShouldShowSelectAllCheckbox() const override;
-
-  void Select(const std::vector<size_t>& indices) override;
-  void Cancel() override;
-  void Close() override;
-  void OpenHelpCenterUrl() const override;
-
-  void SetReadyCallbackForTesting(base::OnceClosure callback) {
-    ready_callback_for_testing_ = std::move(callback);
-  }
-
- private:
-  void DidFindAllFonts(blink::mojom::FontEnumerationStatus status,
-                       std::vector<blink::mojom::FontMetadata> fonts);
-  content::FontAccessChooser::Callback callback_;
-  base::OnceClosure ready_callback_for_testing_;
-
-  std::map<std::string, blink::mojom::FontMetadata> font_metadata_map_;
-  // An ordered list of font names that determines the order of items in the
-  // chooser.
-  std::vector<std::string> items_;
-
-  // If supplied, this will limit the choices the user gets to see to
-  // those in this list.
-  base::flat_set<std::string> selection_;
-
-  base::WeakPtrFactory<FontAccessChooserController> weak_factory_{this};
-};
-
-#endif  // CHROME_BROWSER_UI_FONT_ACCESS_FONT_ACCESS_CHOOSER_CONTROLLER_H_
diff --git a/chrome/browser/ui/font_access/font_access_chooser_controller_unittest.cc b/chrome/browser/ui/font_access/font_access_chooser_controller_unittest.cc
deleted file mode 100644
index c528d21..0000000
--- a/chrome/browser/ui/font_access/font_access_chooser_controller_unittest.cc
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ui/font_access/font_access_chooser_controller.h"
-
-#include "base/test/bind.h"
-#include "base/test/scoped_feature_list.h"
-#include "chrome/test/base/chrome_render_view_host_test_harness.h"
-#include "components/permissions/mock_chooser_controller_view.h"
-#include "content/public/test/test_utils.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/common/features.h"
-
-class FontAccessChooserControllerTest : public ChromeRenderViewHostTestHarness {
- public:
-  FontAccessChooserControllerTest() {
-    scoped_feature_list_.InitAndEnableFeature(blink::features::kFontAccess);
-  }
-
-  void SetUp() override {
-    ChromeRenderViewHostTestHarness::SetUp();
-    mock_font_chooser_view_ =
-        std::make_unique<permissions::MockChooserControllerView>();
-  }
-
- protected:
-  std::unique_ptr<permissions::MockChooserControllerView>
-      mock_font_chooser_view_;
-  base::test::ScopedFeatureList scoped_feature_list_;
-};
-
-TEST_F(FontAccessChooserControllerTest, MultiSelectTest) {
-  base::RunLoop run_loop;
-  FontAccessChooserController controller(
-      main_rfh(), /*selection=*/std::vector<std::string>(),
-      base::BindLambdaForTesting(
-          [&](blink::mojom::FontEnumerationStatus status,
-              std::vector<blink::mojom::FontMetadataPtr> items) {
-            EXPECT_EQ(status, blink::mojom::FontEnumerationStatus::kOk);
-            EXPECT_EQ(items.size(), 2u);
-            run_loop.Quit();
-          }));
-
-  base::RunLoop readiness_loop;
-  controller.SetReadyCallbackForTesting(readiness_loop.QuitClosure());
-  readiness_loop.Run();
-
-  controller.set_view(mock_font_chooser_view_.get());
-  EXPECT_GT(controller.NumOptions(), 1u)
-      << "FontAccessChooserController has more than 2 options";
-  controller.Select(std::vector<size_t>({0, 1}));
-  run_loop.Run();
-}
-
-TEST_F(FontAccessChooserControllerTest, CancelTest) {
-  base::RunLoop run_loop;
-  FontAccessChooserController controller(
-      main_rfh(),
-      /*selection=*/std::vector<std::string>(),
-      base::BindLambdaForTesting(
-          [&](blink::mojom::FontEnumerationStatus status,
-              std::vector<blink::mojom::FontMetadataPtr> items) {
-            EXPECT_EQ(status, blink::mojom::FontEnumerationStatus::kCanceled);
-            EXPECT_EQ(items.size(), 0u);
-            run_loop.Quit();
-          }));
-
-  base::RunLoop readiness_loop;
-  controller.SetReadyCallbackForTesting(readiness_loop.QuitClosure());
-  readiness_loop.Run();
-
-  controller.set_view(mock_font_chooser_view_.get());
-  controller.Cancel();
-  run_loop.Run();
-}
-
-TEST_F(FontAccessChooserControllerTest, CloseTest) {
-  base::RunLoop run_loop;
-  FontAccessChooserController controller(
-      main_rfh(),
-      /*selection=*/std::vector<std::string>(),
-      base::BindLambdaForTesting(
-          [&](blink::mojom::FontEnumerationStatus status,
-              std::vector<blink::mojom::FontMetadataPtr> items) {
-            EXPECT_EQ(status, blink::mojom::FontEnumerationStatus::kCanceled);
-            EXPECT_EQ(items.size(), 0u);
-            run_loop.Quit();
-          }));
-
-  base::RunLoop readiness_loop;
-  controller.SetReadyCallbackForTesting(readiness_loop.QuitClosure());
-  readiness_loop.Run();
-
-  controller.set_view(mock_font_chooser_view_.get());
-  controller.Close();
-  run_loop.Run();
-}
-
-TEST_F(FontAccessChooserControllerTest, DestructorTest) {
-  base::RunLoop run_loop;
-  std::unique_ptr<FontAccessChooserController> controller =
-      std::make_unique<FontAccessChooserController>(
-          main_rfh(),
-          /*selection=*/std::vector<std::string>(),
-          base::BindLambdaForTesting(
-              [&](blink::mojom::FontEnumerationStatus status,
-                  std::vector<blink::mojom::FontMetadataPtr> items) {
-                EXPECT_EQ(
-                    status,
-                    blink::mojom::FontEnumerationStatus::kUnexpectedError);
-                EXPECT_EQ(items.size(), 0u);
-                run_loop.Quit();
-              }));
-
-  base::RunLoop readiness_loop;
-  controller->SetReadyCallbackForTesting(readiness_loop.QuitClosure());
-  readiness_loop.Run();
-
-  controller.reset();
-  run_loop.Run();
-}
diff --git a/chrome/browser/ui/frame/window_frame_util.cc b/chrome/browser/ui/frame/window_frame_util.cc
index 9b26827..ac7ae62 100644
--- a/chrome/browser/ui/frame/window_frame_util.cc
+++ b/chrome/browser/ui/frame/window_frame_util.cc
@@ -7,11 +7,11 @@
 #include "build/build_config.h"
 #include "ui/gfx/geometry/size.h"
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 #include "base/win/windows_version.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/ui_features.h"
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 
 // static
 SkAlpha WindowFrameUtil::CalculateWindows10GlassCaptionButtonBackgroundAlpha(
@@ -34,11 +34,11 @@
 // static
 bool WindowFrameUtil::IsWin10TabSearchCaptionButtonEnabled(
     const Browser* browser) {
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   return browser->is_type_normal() &&
          base::win::GetVersion() >= base::win::Version::WIN10 &&
          base::FeatureList::IsEnabled(features::kWin10TabSearchCaptionButton);
 #else
   return false;
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 }
diff --git a/chrome/browser/ui/fullscreen_keyboard_browsertest_base.cc b/chrome/browser/ui/fullscreen_keyboard_browsertest_base.cc
index 9534e19..49ee3e24 100644
--- a/chrome/browser/ui/fullscreen_keyboard_browsertest_base.cc
+++ b/chrome/browser/ui/fullscreen_keyboard_browsertest_base.cc
@@ -29,7 +29,7 @@
 #include "url/gurl.h"
 #include "url/url_constants.h"
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #include "base/mac/mac_util.h"
 #endif
 
@@ -45,7 +45,7 @@
 // On MacOSX command key is used for most of the shortcuts, so replace it with
 // control to reduce the complexity of comparison of the results.
 void NormalizeMetaKeyForMacOS(std::string* output) {
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   base::ReplaceSubstringsAfterOffset(output, 0, "MetaLeft", "ControlLeft");
 #endif
 }
@@ -153,7 +153,7 @@
 
 void FullscreenKeyboardBrowserTestBase::SendShortcut(ui::KeyboardCode key,
                                                      bool shift /* = false */) {
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   const bool control_modifier = false;
   const bool command_modifier = true;
 #else
@@ -186,7 +186,7 @@
   // for the observer to notice the change of fullscreen state.
   FullscreenNotificationObserver observer(GetActiveBrowser());
 // Enter fullscreen.
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   // On MACOSX, Command + Control + F is used.
   ASSERT_TRUE(ui_test_utils::SendKeyPressSync(GetActiveBrowser(), ui::VKEY_F,
                                               true, false, false, true));
@@ -204,7 +204,7 @@
 // fullscreen. For more details, see ScopedFakeNSWindowFullscreen.
 // TODO(crbug.com/837438): Remove this once ScopedFakeNSWindowFullscreen fires
 // OnFullscreenStateChanged.
-#if !defined(OS_MAC)
+#if !BUILDFLAG(IS_MAC)
   observer.Wait();
 #endif
 }
diff --git a/chrome/browser/ui/global_error/global_error.cc b/chrome/browser/ui/global_error/global_error.cc
index d3fbc94..0bdce47 100644
--- a/chrome/browser/ui/global_error/global_error.cc
+++ b/chrome/browser/ui/global_error/global_error.cc
@@ -11,7 +11,7 @@
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/base/ui_base_types.h"
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 #include "chrome/app/vector_icons/vector_icons.h"
 #include "ui/gfx/color_palette.h"
 #include "ui/gfx/paint_vector_icon.h"
@@ -26,7 +26,7 @@
 GlobalError::Severity GlobalError::GetSeverity() { return SEVERITY_MEDIUM; }
 
 ui::ImageModel GlobalError::MenuItemIcon() {
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   return ui::ImageModel(
       ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed(
           IDR_INPUT_ALERT_MENU));
diff --git a/chrome/browser/ui/global_error/global_error_browsertest.cc b/chrome/browser/ui/global_error/global_error_browsertest.cc
index 8c3a4f6..354a9bc 100644
--- a/chrome/browser/ui/global_error/global_error_browsertest.cc
+++ b/chrome/browser/ui/global_error/global_error_browsertest.cc
@@ -243,7 +243,7 @@
 }
 
 // RecoveryInstallGlobalError only exists on Windows and Mac.
-#if defined(OS_WIN) || defined(OS_MAC)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
 IN_PROC_BROWSER_TEST_F(GlobalErrorBubbleTest,
                        InvokeUi_RecoveryInstallGlobalError) {
   ShowAndVerifyUi();
diff --git a/chrome/browser/ui/global_media_controls/media_notification_device_monitor.cc b/chrome/browser/ui/global_media_controls/media_notification_device_monitor.cc
index 70471a91..9aadf49 100644
--- a/chrome/browser/ui/global_media_controls/media_notification_device_monitor.cc
+++ b/chrome/browser/ui/global_media_controls/media_notification_device_monitor.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include "chrome/browser/ui/global_media_controls/media_notification_device_monitor.h"
+
 #include <algorithm>
 #include <iterator>
 
@@ -12,6 +13,7 @@
 #include "base/task/single_thread_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
+#include "build/build_config.h"
 #include "chrome/browser/ui/global_media_controls/media_notification_device_provider.h"
 
 // MediaNotificationDeviceMonitor
@@ -23,7 +25,7 @@
 // The device monitor implementation on linux does not reliably detect
 // connection changes for some devices. In this case we fall back to polling the
 // device provider. See crbug.com/1112480 for more information.
-#if (defined(OS_LINUX) || defined(OS_CHROMEOS)) && defined(USE_UDEV)
+#if (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)) && defined(USE_UDEV)
   return std::make_unique<PollingDeviceMonitorImpl>(device_provider);
 #else
   return std::make_unique<SystemMonitorDeviceMonitorImpl>();
@@ -42,7 +44,7 @@
 
 MediaNotificationDeviceMonitor::MediaNotificationDeviceMonitor() = default;
 
-#if !((defined(OS_LINUX) || defined(OS_CHROMEOS)) && defined(USE_UDEV))
+#if !((BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)) && defined(USE_UDEV))
 // SystemMonitorDeviceMonitorImpl
 SystemMonitorDeviceMonitorImpl::SystemMonitorDeviceMonitorImpl() {
   base::SystemMonitor::Get()->AddDevicesChangedObserver(this);
diff --git a/chrome/browser/ui/global_media_controls/media_notification_device_monitor.h b/chrome/browser/ui/global_media_controls/media_notification_device_monitor.h
index 1a88109..eeca5a29 100644
--- a/chrome/browser/ui/global_media_controls/media_notification_device_monitor.h
+++ b/chrome/browser/ui/global_media_controls/media_notification_device_monitor.h
@@ -46,7 +46,7 @@
   base::ObserverList<DevicesChangedObserver> observers_;
 };
 
-#if !((defined(OS_LINUX) || defined(OS_CHROMEOS)) && defined(USE_UDEV))
+#if !((BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)) && defined(USE_UDEV))
 // Monitors device changes by observing the SystemMonitor
 class SystemMonitorDeviceMonitorImpl
     : public MediaNotificationDeviceMonitor,
@@ -89,6 +89,7 @@
 
   base::WeakPtrFactory<PollingDeviceMonitorImpl> weak_ptr_factory_{this};
 };
-#endif  // !((defined(OS_LINUX) || defined(OS_CHROMEOS)) && defined(USE_UDEV))
+#endif  // !((BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)) &&
+        // defined(USE_UDEV))
 
 #endif  // CHROME_BROWSER_UI_GLOBAL_MEDIA_CONTROLS_MEDIA_NOTIFICATION_DEVICE_MONITOR_H_
diff --git a/chrome/browser/ui/intent_picker_tab_helper.cc b/chrome/browser/ui/intent_picker_tab_helper.cc
index 5aab1821..ca25bb6 100644
--- a/chrome/browser/ui/intent_picker_tab_helper.cc
+++ b/chrome/browser/ui/intent_picker_tab_helper.cc
@@ -7,6 +7,7 @@
 #include <utility>
 
 #include "base/bind.h"
+#include "build/build_config.h"
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
 #include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
 #include "chrome/browser/apps/intent_helper/intent_picker_helpers.h"
@@ -23,7 +24,7 @@
 #include "ui/gfx/favicon_size.h"
 #include "ui/gfx/image/image.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 #include "chrome/browser/apps/intent_helper/metrics/intent_handling_metrics.h"
 #endif
 
@@ -68,7 +69,7 @@
   if (!tab_helper)
     return;
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   if (should_show_icon && !tab_helper->should_show_icon_) {
     // This point doesn't exactly match when the icon is shown in the UI (e.g.
     // if the tab is not active), but recording here corresponds more closely to
diff --git a/chrome/browser/ui/javascript_dialogs/chrome_javascript_app_modal_dialog_view_factory.h b/chrome/browser/ui/javascript_dialogs/chrome_javascript_app_modal_dialog_view_factory.h
index 605ee54..24626ea 100644
--- a/chrome/browser/ui/javascript_dialogs/chrome_javascript_app_modal_dialog_view_factory.h
+++ b/chrome/browser/ui/javascript_dialogs/chrome_javascript_app_modal_dialog_view_factory.h
@@ -9,7 +9,7 @@
 
 void InstallChromeJavaScriptAppModalDialogViewFactory();
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 void InstallChromeJavaScriptAppModalDialogViewCocoaFactory();
 #endif
 
diff --git a/chrome/browser/ui/javascript_dialogs/javascript_dialog_browsertest.cc b/chrome/browser/ui/javascript_dialogs/javascript_dialog_browsertest.cc
index 573cf59..6a90a45 100644
--- a/chrome/browser/ui/javascript_dialogs/javascript_dialog_browsertest.cc
+++ b/chrome/browser/ui/javascript_dialogs/javascript_dialog_browsertest.cc
@@ -320,7 +320,7 @@
   chrome::CloseTab(browser());
 // There are differences in the implementations of Views on different platforms
 // that cause different dismissal causes.
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   // On MacOS 10.13, |kDialogClosed| is logged, while for other versions
   // |kCancelDialogsCalled| is logged. Expect only one but not both.
   EXPECT_TRUE(tester.GetLastDismissalCause() ==
diff --git a/chrome/browser/ui/keyboard_lock_interactive_browsertest.cc b/chrome/browser/ui/keyboard_lock_interactive_browsertest.cc
index 82a911f..c0f6ef5 100644
--- a/chrome/browser/ui/keyboard_lock_interactive_browsertest.cc
+++ b/chrome/browser/ui/keyboard_lock_interactive_browsertest.cc
@@ -21,7 +21,7 @@
 #include "third_party/blink/public/common/features.h"
 #include "ui/base/ui_base_features.h"
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #include "ui/base/test/scoped_fake_nswindow_fullscreen.h"
 #endif
 
@@ -116,7 +116,7 @@
   base::test::ScopedFeatureList scoped_feature_list_;
   net::EmbeddedTestServer https_test_server_;
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   ui::test::ScopedFakeNSWindowFullscreen fake_fullscreen_;
 #endif
 };
@@ -271,7 +271,7 @@
 // https://crbug.com/1108391 Flakey on ChromeOS.
 // https://crbug.com/1121172 Also flaky on Lacros and Mac
 #if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) || \
-    defined(OS_MAC)
+    BUILDFLAG(IS_MAC)
 #define MAYBE_SubsequentLockCallSupersedesPreviousCall \
   DISABLED_SubsequentLockCallSupersedesPreviousCall
 #else
@@ -347,7 +347,7 @@
   ASSERT_FALSE(IsKeyboardLockActive());
 }
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 // TODO(crbug.com/837438): Enable once browser fullscreen is reliable in tests.
 #define MAYBE_RequestedButNotActiveInBrowserFullscreen \
   DISABLED_RequestedButNotActiveInBrowserFullscreen
@@ -449,7 +449,7 @@
   ASSERT_FALSE(IsKeyboardLockActive());
 }
 
-#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
 // BringBrowserWindowToFront hangs on Linux: http://crbug.com/163931
 #define MAYBE_GainAndLoseFocusInWindowMode DISABLED_GainAndLoseFocusInWindowMode
 #else
@@ -510,7 +510,7 @@
   ASSERT_FALSE(IsKeyboardLockActive());
 }
 
-#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
 // BringBrowserWindowToFront hangs on Linux: http://crbug.com/163931
 #define MAYBE_GainAndLoseFocusInFullscreen DISABLED_GainAndLoseFocusInFullscreen
 #else
diff --git a/chrome/browser/ui/layout_constants.cc b/chrome/browser/ui/layout_constants.cc
index 8efee5f..b067212 100644
--- a/chrome/browser/ui/layout_constants.cc
+++ b/chrome/browser/ui/layout_constants.cc
@@ -5,10 +5,11 @@
 #include "chrome/browser/ui/layout_constants.h"
 
 #include "base/notreached.h"
+#include "build/build_config.h"
 #include "chrome/browser/ui/ui_features.h"
 #include "ui/base/pointer/touch_ui_controller.h"
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 int GetCocoaLayoutConstant(LayoutConstant constant) {
   switch (constant) {
     case BOOKMARK_BAR_HEIGHT:
diff --git a/chrome/browser/ui/layout_constants.h b/chrome/browser/ui/layout_constants.h
index a7496b8..af43677 100644
--- a/chrome/browser/ui/layout_constants.h
+++ b/chrome/browser/ui/layout_constants.h
@@ -18,7 +18,7 @@
   // The height of a button within the Bookmarks Bar.
   BOOKMARK_BAR_BUTTON_HEIGHT,
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   // This is a little smaller than the bookmarkbar height because of the visual
   // overlap with the main toolbar. This height should not be used when
   // computing the height of the toolbar.
@@ -28,7 +28,7 @@
   // The height of Bookmarks Bar, when visible in "New Tab Page" mode.
   BOOKMARK_BAR_NTP_HEIGHT,
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   // The amount of space between the inner bookmark bar and the outer toolbar on
   // new tab pages.
   BOOKMARK_BAR_NTP_PADDING,
@@ -128,7 +128,7 @@
 };
 
 int GetLayoutConstant(LayoutConstant constant);
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 // Use this function instead of GetLayoutConstant() for Cocoa browser.
 // This will handle Cocoa specific layout constants. For non Cocoa specific
 // constants, it will call GetLayoutConstant() anyway.
diff --git a/chrome/browser/ui/login/login_handler.cc b/chrome/browser/ui/login/login_handler.cc
index 1e42eb8d..c0e80b2a1 100644
--- a/chrome/browser/ui/login/login_handler.cc
+++ b/chrome/browser/ui/login/login_handler.cc
@@ -429,7 +429,7 @@
     authority_url = auth_info.challenger.GetURL();
   } else {
     *authority = url_formatter::FormatUrlForSecurityDisplay(request_url);
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
     // Android concatenates with a space rather than displaying on two separate
     // lines, so it needs some surrounding text.
     *authority =
diff --git a/chrome/browser/ui/login/login_handler_browsertest.cc b/chrome/browser/ui/login/login_handler_browsertest.cc
index 2f3d1758..b237af59 100644
--- a/chrome/browser/ui/login/login_handler_browsertest.cc
+++ b/chrome/browser/ui/login/login_handler_browsertest.cc
@@ -1632,7 +1632,7 @@
 // the omnibox.
 
 // Fails occasionally on Mac. http://crbug.com/852703
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #define MAYBE_CancelLoginInterstitialOnRedirect \
   DISABLED_CancelLoginInterstitialOnRedirect
 #else
@@ -2109,7 +2109,7 @@
 }
 
 // Tests that basic proxy auth works as expected, for HTTPS pages.
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 // TODO(https://crbug.com/1000446): Re-enable this test.
 #define MAYBE_ProxyAuthHTTPS DISABLED_ProxyAuthHTTPS
 #else
diff --git a/chrome/browser/ui/login/login_handler_unittest.cc b/chrome/browser/ui/login/login_handler_unittest.cc
index f8322a2..cc371f3 100644
--- a/chrome/browser/ui/login/login_handler_unittest.cc
+++ b/chrome/browser/ui/login/login_handler_unittest.cc
@@ -104,7 +104,7 @@
   // Proxies and Android have additional surrounding text. Otherwise, only the
   // host URL is shown.
   bool extra_text = is_proxy;
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   extra_text = true;
 #endif
   if (extra_text)
diff --git a/chrome/browser/ui/managed_ui.cc b/chrome/browser/ui/managed_ui.cc
index 48a01e1..de52d24 100644
--- a/chrome/browser/ui/managed_ui.cc
+++ b/chrome/browser/ui/managed_ui.cc
@@ -79,7 +79,7 @@
   return enterprise_util::IsBrowserManaged(profile);
 }
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 std::u16string GetManagedUiMenuItemLabel(Profile* profile) {
   absl::optional<std::string> account_manager =
       GetAccountManagerIdentity(profile);
@@ -108,7 +108,7 @@
 
   return l10n_util::GetStringFUTF16(string_id, replacements, nullptr);
 }
-#endif  // !defined(OS_ANDROID)
+#endif  // !BUILDFLAG(IS_ANDROID)
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 std::u16string GetDeviceManagedUiWebUILabel() {
diff --git a/chrome/browser/ui/managed_ui.h b/chrome/browser/ui/managed_ui.h
index 31bf4d19..f434050 100644
--- a/chrome/browser/ui/managed_ui.h
+++ b/chrome/browser/ui/managed_ui.h
@@ -27,14 +27,14 @@
 // users.
 bool ShouldDisplayManagedUi(Profile* profile);
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 // The label for the App Menu item for Managed UI.
 std::u16string GetManagedUiMenuItemLabel(Profile* profile);
 
 // The label for the WebUI footnote for Managed UI indicating that the browser
 // is managed. These strings contain HTML for an <a> element.
 std::u16string GetManagedUiWebUILabel(Profile* profile);
-#endif  // !defined(OS_ANDROID)
+#endif  // !BUILDFLAG(IS_ANDROID)
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 // The label for the WebUI footnote for Managed UI indicating that the device
diff --git a/chrome/browser/ui/media_router/media_router_ui.cc b/chrome/browser/ui/media_router/media_router_ui.cc
index 80bcd14..8bb7fae 100644
--- a/chrome/browser/ui/media_router/media_router_ui.cc
+++ b/chrome/browser/ui/media_router/media_router_ui.cc
@@ -57,7 +57,7 @@
 #include "ui/display/display.h"
 #include "url/origin.h"
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #include "base/mac/mac_util.h"
 #include "ui/base/cocoa/permissions_utils.h"
 #endif
@@ -102,7 +102,7 @@
     std::move(callback).Run(result);
 }
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 bool RequiresScreenCapturePermission(MediaCastMode cast_mode) {
   return base::mac::IsAtLeastOS10_15() &&
          cast_mode == MediaCastMode::DESKTOP_MIRROR;
@@ -222,7 +222,7 @@
   logger_->LogInfo(mojom::LogCategory::kUi, kLoggerComponent,
                    "CreateRoute requested by MediaRouterViewsUI.", sink_id, "",
                    "");
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   if (RequiresScreenCapturePermission(cast_mode)) {
     const bool screen_capture_allowed =
         screen_capture_allowed_for_testing_.has_value()
@@ -613,7 +613,7 @@
   AddIssue(issue_info);
 }
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 void MediaRouterUI::SendIssueForScreenPermission(const MediaSink::Id& sink_id) {
   std::string issue_title = l10n_util::GetStringUTF8(
       IDS_MEDIA_ROUTER_ISSUE_MAC_SCREEN_CAPTURE_PERMISSION_ERROR);
diff --git a/chrome/browser/ui/media_router/media_router_ui.h b/chrome/browser/ui/media_router/media_router_ui.h
index e235a00..1e78d49 100644
--- a/chrome/browser/ui/media_router/media_router_ui.h
+++ b/chrome/browser/ui/media_router/media_router_ui.h
@@ -127,7 +127,7 @@
 
   void SimulateDocumentAvailableForTest();
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   void set_screen_capture_allowed_for_testing(bool allowed) {
     screen_capture_allowed_for_testing_ = allowed;
   }
@@ -249,7 +249,7 @@
 
 // Creates and sends an issue if casting fails due to lack of screen
 // permissions.
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   void SendIssueForScreenPermission(const MediaSink::Id& sink_id);
 #endif
 
@@ -376,7 +376,7 @@
   // controlling window.
   std::unique_ptr<WebContentsDisplayObserver> display_observer_;
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   absl::optional<bool> screen_capture_allowed_for_testing_;
 #endif
   raw_ptr<LoggerImpl> logger_;
diff --git a/chrome/browser/ui/media_router/media_router_ui_service_factory.cc b/chrome/browser/ui/media_router/media_router_ui_service_factory.cc
index e59c3851..604ed5fe 100644
--- a/chrome/browser/ui/media_router/media_router_ui_service_factory.cc
+++ b/chrome/browser/ui/media_router/media_router_ui_service_factory.cc
@@ -50,7 +50,7 @@
   return new MediaRouterUIService(Profile::FromBrowserContext(context));
 }
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 bool MediaRouterUIServiceFactory::ServiceIsCreatedWithBrowserContext() const {
   return true;
 }
diff --git a/chrome/browser/ui/media_router/media_router_ui_service_factory.h b/chrome/browser/ui/media_router/media_router_ui_service_factory.h
index ff6ea2c..1a92e0d 100644
--- a/chrome/browser/ui/media_router/media_router_ui_service_factory.h
+++ b/chrome/browser/ui/media_router/media_router_ui_service_factory.h
@@ -45,7 +45,7 @@
       content::BrowserContext* context) const override;
   KeyedService* BuildServiceInstanceFor(
       content::BrowserContext* context) const override;
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
   bool ServiceIsCreatedWithBrowserContext() const override;
 #endif
   bool ServiceIsNULLWhileTesting() const override;
diff --git a/chrome/browser/ui/media_router/media_router_ui_unittest.cc b/chrome/browser/ui/media_router/media_router_ui_unittest.cc
index 42b2047..fc2481b 100644
--- a/chrome/browser/ui/media_router/media_router_ui_unittest.cc
+++ b/chrome/browser/ui/media_router/media_router_ui_unittest.cc
@@ -39,7 +39,7 @@
 #include "ui/display/display.h"
 #include "url/origin.h"
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #include "base/mac/mac_util.h"
 #include "ui/base/cocoa/permissions_utils.h"
 #endif
@@ -484,7 +484,7 @@
 }
 
 TEST_F(MediaRouterViewsUITest, RouteCreationTimeoutForDesktop) {
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   if (base::mac::IsAtLeastOS10_15())
     ui_->set_screen_capture_allowed_for_testing(true);
 #endif
@@ -508,7 +508,7 @@
       20);
 }
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 TEST_F(MediaRouterViewsUITest, DesktopMirroringFailsWhenDisallowedOnMac) {
   // Failure due to a lack of screen capture permissions only happens on macOS
   // 10.15 or later. See crbug.com/1087236 for more info.
diff --git a/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc b/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc
index 514f491..e48377f 100644
--- a/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc
+++ b/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc
@@ -603,7 +603,7 @@
       browser()->tab_strip_model()->GetActiveWebContents();
 
   // Create another tab in the foreground.
-  AddTabAtIndex(1, url1, ui::PAGE_TRANSITION_TYPED);
+  ASSERT_TRUE(AddTabAtIndex(1, url1, ui::PAGE_TRANSITION_TYPED));
   EXPECT_EQ(2, browser()->tab_strip_model()->count());
   EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
 
diff --git a/chrome/browser/ui/permission_bubble/permission_bubble_browser_test_util.h b/chrome/browser/ui/permission_bubble/permission_bubble_browser_test_util.h
index 479b3193..2b32d72 100644
--- a/chrome/browser/ui/permission_bubble/permission_bubble_browser_test_util.h
+++ b/chrome/browser/ui/permission_bubble/permission_bubble_browser_test_util.h
@@ -109,7 +109,7 @@
   void SetUpCommandLine(base::CommandLine* command_line) override;
 
  private:
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   // Toggling fullscreen mode on Mac can be flaky for tests run in parallel
   // because only one window may be animating into or out of fullscreen at a
   // time.
diff --git a/chrome/browser/ui/popup_browsertest.cc b/chrome/browser/ui/popup_browsertest.cc
index 8ac209b..cf910e0 100644
--- a/chrome/browser/ui/popup_browsertest.cc
+++ b/chrome/browser/ui/popup_browsertest.cc
@@ -161,7 +161,7 @@
 
 // Ensure popups cannot be moved beyond the available display space by script.
 // TODO(crbug.com/1228795): Flaking on Linux Ozone
-#if defined(OS_LINUX) && defined(USE_OZONE)
+#if BUILDFLAG(IS_LINUX) && defined(USE_OZONE)
 #define Maybe_MoveClampedToCurrentDisplay DISABLED_MoveClampedToCurrentDisplay
 #else
 #define Maybe_MoveClampedToCurrentDisplay MoveClampedToCurrentDisplay
diff --git a/chrome/browser/ui/profile_error_dialog.cc b/chrome/browser/ui/profile_error_dialog.cc
index 885f9d66..6d8bbd3 100644
--- a/chrome/browser/ui/profile_error_dialog.cc
+++ b/chrome/browser/ui/profile_error_dialog.cc
@@ -18,7 +18,7 @@
 
 namespace {
 
-#if !defined(OS_ANDROID) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if !BUILDFLAG(IS_ANDROID) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 constexpr char kProfileErrorFeedbackCategory[] = "FEEDBACK_PROFILE_ERROR";
 
 bool g_is_showing_profile_error_dialog = false;
@@ -38,16 +38,16 @@
                            std::string() /* description_placeholder_text */,
                            kProfileErrorFeedbackCategory, diagnostics);
 }
-#endif  // !defined(OS_ANDROID) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#endif  // !BUILDFLAG(IS_ANDROID) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 
 }  // namespace
 
 void ShowProfileErrorDialog(ProfileErrorType type,
                             int message_id,
                             const std::string& diagnostics) {
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   NOTIMPLEMENTED();
-#else  // defined(OS_ANDROID)
+#else  // BUILDFLAG(IS_ANDROID)
   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
           switches::kNoErrorDialogs)) {
     return;
@@ -69,5 +69,5 @@
       l10n_util::GetStringUTF16(message_id));
 #endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING)
 
-#endif  // !defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_ANDROID)
 }
diff --git a/chrome/browser/ui/read_later/reading_list_model_factory.cc b/chrome/browser/ui/read_later/reading_list_model_factory.cc
index 5dd55f5..d89231d 100644
--- a/chrome/browser/ui/read_later/reading_list_model_factory.cc
+++ b/chrome/browser/ui/read_later/reading_list_model_factory.cc
@@ -89,11 +89,11 @@
   registry->RegisterBooleanPref(
       reading_list::prefs::kReadingListHasUnseenEntries, false,
       PrefRegistry::NO_REGISTRATION_FLAGS);
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
   registry->RegisterBooleanPref(
       reading_list::prefs::kReadingListDesktopFirstUseExperienceShown, false,
       PrefRegistry::NO_REGISTRATION_FLAGS);
-#endif  // !defined(OS_ANDROID)
+#endif  // !BUILDFLAG(IS_ANDROID)
 }
 
 content::BrowserContext* ReadingListModelFactory::GetBrowserContextToUse(
diff --git a/chrome/browser/ui/sad_tab.cc b/chrome/browser/ui/sad_tab.cc
index f480697..070761c 100644
--- a/chrome/browser/ui/sad_tab.cc
+++ b/chrome/browser/ui/sad_tab.cc
@@ -25,7 +25,7 @@
 #include "content/public/browser/web_contents.h"
 #include "ui/base/l10n/l10n_util.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 #include "chrome/browser/memory/oom_memory_details.h"
 #endif
 
@@ -90,18 +90,18 @@
   switch (status) {
     case base::TERMINATION_STATUS_ABNORMAL_TERMINATION:
     case base::TERMINATION_STATUS_PROCESS_WAS_KILLED:
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
     case base::TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM:
 #endif
     case base::TERMINATION_STATUS_PROCESS_CRASHED:
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
     case base::TERMINATION_STATUS_INTEGRITY_FAILURE:
 #endif
     case base::TERMINATION_STATUS_OOM:
       return true;
     case base::TERMINATION_STATUS_NORMAL_TERMINATION:
     case base::TERMINATION_STATUS_STILL_RUNNING:
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
     case base::TERMINATION_STATUS_OOM_PROTECTED:
 #endif
     case base::TERMINATION_STATUS_LAUNCH_FAILED:
@@ -116,12 +116,12 @@
   if (!is_repeatedly_crashing_)
     return IDS_SAD_TAB_TITLE;
   switch (kind_) {
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
     case SAD_TAB_KIND_KILLED_BY_OOM:
       return IDS_SAD_TAB_RELOAD_TITLE;
 #endif
     case SAD_TAB_KIND_OOM:
-#if defined(OS_WIN)  // Only Windows has OOM sad tab strings.
+#if BUILDFLAG(IS_WIN)  // Only Windows has OOM sad tab strings.
       return IDS_SAD_TAB_OOM_TITLE;
 #endif
     case SAD_TAB_KIND_CRASHED:
@@ -138,7 +138,7 @@
 
 int SadTab::GetInfoMessage() {
   switch (kind_) {
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
     case SAD_TAB_KIND_KILLED_BY_OOM:
       return IDS_KILLED_TAB_BY_OOM_MESSAGE;
 #endif
@@ -175,7 +175,7 @@
     return std::vector<int>();
 
   switch (kind_) {
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
     case SAD_TAB_KIND_KILLED_BY_OOM:
       return std::vector<int>();
 #endif
@@ -188,7 +188,7 @@
       // Only show Incognito suggestion if not already in Incognito mode.
       if (!web_contents_->GetBrowserContext()->IsOffTheRecord())
         message_ids.insert(message_ids.begin(), IDS_SAD_TAB_RELOAD_INCOGNITO);
-#if defined(OS_MAC) || defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
       // Note: on macOS, Linux and ChromeOS, the first bullet is either one of
       // IDS_SAD_TAB_RELOAD_CLOSE_TABS or IDS_SAD_TAB_RELOAD_CLOSE_NOTABS
       // followed by one of the above suggestions.
@@ -217,7 +217,7 @@
     case SAD_TAB_KIND_OOM:
       UMA_SAD_TAB_COUNTER("Tabs.SadTab.OomDisplayed");
       break;
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
     case SAD_TAB_KIND_KILLED_BY_OOM:
       UMA_SAD_TAB_COUNTER("Tabs.SadTab.KillDisplayed.OOM");
       [[fallthrough]];
@@ -279,7 +279,7 @@
     case SAD_TAB_KIND_OOM:
       UMA_SAD_TAB_COUNTER("Tabs.SadTab.OomCreated");
       break;
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
     case SAD_TAB_KIND_KILLED_BY_OOM:
       UMA_SAD_TAB_COUNTER("Tabs.SadTab.KillCreated.OOM");
       {
diff --git a/chrome/browser/ui/sad_tab_helper.cc b/chrome/browser/ui/sad_tab_helper.cc
index 283a9a0..a2a5d5e 100644
--- a/chrome/browser/ui/sad_tab_helper.cc
+++ b/chrome/browser/ui/sad_tab_helper.cc
@@ -15,7 +15,7 @@
 
 SadTabKind SadTabKindFromTerminationStatus(base::TerminationStatus status) {
   switch (status) {
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
     case base::TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM:
       return SAD_TAB_KIND_KILLED_BY_OOM;
 #endif
diff --git a/chrome/browser/ui/search/instant_controller.h b/chrome/browser/ui/search/instant_controller.h
index 01a61db..7051b90 100644
--- a/chrome/browser/ui/search/instant_controller.h
+++ b/chrome/browser/ui/search/instant_controller.h
@@ -12,7 +12,7 @@
 #include "build/build_config.h"
 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 #error "Instant is only used on desktop";
 #endif
 
diff --git a/chrome/browser/ui/search/ntp_user_data_logger.h b/chrome/browser/ui/search/ntp_user_data_logger.h
index 86624f9..19d60e4 100644
--- a/chrome/browser/ui/search/ntp_user_data_logger.h
+++ b/chrome/browser/ui/search/ntp_user_data_logger.h
@@ -18,7 +18,7 @@
 #include "components/ntp_tiles/ntp_tile_impression.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 #error "Instant is only used on desktop";
 #endif
 
diff --git a/chrome/browser/ui/search/search_ipc_router.h b/chrome/browser/ui/search/search_ipc_router.h
index bb2a6e9f..5720a9f 100644
--- a/chrome/browser/ui/search/search_ipc_router.h
+++ b/chrome/browser/ui/search/search_ipc_router.h
@@ -20,7 +20,7 @@
 #include "components/omnibox/common/omnibox_focus_state.h"
 #include "mojo/public/cpp/bindings/associated_receiver.h"
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 #error "Instant is only used on desktop";
 #endif
 
diff --git a/chrome/browser/ui/search/search_ipc_router_policy_impl.h b/chrome/browser/ui/search/search_ipc_router_policy_impl.h
index 8800c56..f7d5b91 100644
--- a/chrome/browser/ui/search/search_ipc_router_policy_impl.h
+++ b/chrome/browser/ui/search/search_ipc_router_policy_impl.h
@@ -9,7 +9,7 @@
 #include "build/build_config.h"
 #include "chrome/browser/ui/search/search_ipc_router.h"
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 #error "Instant is only used on desktop";
 #endif
 
diff --git a/chrome/browser/ui/search/search_tab_helper.h b/chrome/browser/ui/search/search_tab_helper.h
index 21db2a12..3932a0e 100644
--- a/chrome/browser/ui/search/search_tab_helper.h
+++ b/chrome/browser/ui/search/search_tab_helper.h
@@ -25,7 +25,7 @@
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/browser/web_contents_user_data.h"
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 #error "Instant is only used on desktop";
 #endif
 
diff --git a/chrome/browser/ui/serial/serial_chooser_controller_unittest.cc b/chrome/browser/ui/serial/serial_chooser_controller_unittest.cc
index 1f97104..1fd5310 100644
--- a/chrome/browser/ui/serial/serial_chooser_controller_unittest.cc
+++ b/chrome/browser/ui/serial/serial_chooser_controller_unittest.cc
@@ -116,7 +116,7 @@
   port->token = base::UnguessableToken::Create();
   port->display_name = "Test Port 1";
   port->path = base::FilePath(FILE_PATH_LITERAL("/dev/ttyS0"));
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   // This path will be ignored and not generate additional chooser entries or
   // be displayed in the device name.
   port->alternate_path = base::FilePath(FILE_PATH_LITERAL("/dev/alternateS0"));
diff --git a/chrome/browser/ui/side_search/side_search_side_contents_helper.cc b/chrome/browser/ui/side_search/side_search_side_contents_helper.cc
index d495b29..bf2b1480 100644
--- a/chrome/browser/ui/side_search/side_search_side_contents_helper.cc
+++ b/chrome/browser/ui/side_search/side_search_side_contents_helper.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/ui/side_search/side_search_side_contents_helper.h"
 
+#include "build/build_config.h"
 #include "chrome/browser/ui/side_search/side_search_config.h"
 #include "chrome/browser/ui/side_search/side_search_metrics.h"
 #include "chrome/browser/ui/side_search/side_search_tab_contents_helper.h"
@@ -20,11 +21,11 @@
 constexpr char kSideSearchQueryParam[] = "sidesearch";
 constexpr char kSideSearchVersion[] = "1";
 
-#if !defined(OS_CHROMEOS)
+#if !BUILDFLAG(IS_CHROMEOS)
 constexpr char kChromeOSUserAgent[] =
     "Mozilla/5.0 (X11; CrOS x86_64 14233.0.0) AppleWebKit/537.36 (KHTML, like "
     "Gecko) Chrome/96.0.4650.0 Safari/537.36";
-#endif  // !defined(OS_CHROMEOS)
+#endif  // !BUILDFLAG(IS_CHROMEOS)
 
 class SideSearchContentsThrottle : public content::NavigationThrottle {
  public:
@@ -168,11 +169,11 @@
   // Fake the user agent on non ChromeOS systems to allow for development and
   // testing. This is needed as the side search SRP is only served to ChromeOS
   // user agents.
-#if !defined(OS_CHROMEOS)
+#if !BUILDFLAG(IS_CHROMEOS)
   load_url_params.transition_type = ui::PAGE_TRANSITION_AUTO_TOPLEVEL;
   load_url_params.override_user_agent =
       content::NavigationController::UA_OVERRIDE_TRUE;
-#endif  // defined(OS_CHROMEOS)
+#endif  // !BUILDFLAG(IS_CHROMEOS)
 
   web_contents()->GetController().LoadURLWithParams(load_url_params);
 
@@ -193,12 +194,12 @@
                         "SideSearch.LoadCompletedTime") {
   Observe(web_contents);
 
-#if !defined(OS_CHROMEOS)
+#if !BUILDFLAG(IS_CHROMEOS)
   web_contents->SetUserAgentOverride(
       blink::UserAgentOverride::UserAgentOnly(kChromeOSUserAgent), true);
   web_contents->SetRendererInitiatedUserAgentOverrideOption(
       content::NavigationController::UA_OVERRIDE_TRUE);
-#endif  // !defined(OS_CHROMEOS)
+#endif  // !BUILDFLAG(IS_CHROMEOS)
 
   web_contents->SetDelegate(this);
 }
diff --git a/chrome/browser/ui/signin/dice_web_signin_interceptor_delegate.cc b/chrome/browser/ui/signin/dice_web_signin_interceptor_delegate.cc
index eb20bf2..85bf254 100644
--- a/chrome/browser/ui/signin/dice_web_signin_interceptor_delegate.cc
+++ b/chrome/browser/ui/signin/dice_web_signin_interceptor_delegate.cc
@@ -65,7 +65,7 @@
  private:
   void ShowEnterpriseProfileInterceptionDialog(const AccountInfo& account_info,
                                                SkColor profile_color) {
-#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) || \
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \
     BUILDFLAG(IS_CHROMEOS_LACROS)
     if (base::FeatureList::IsEnabled(kAccountPoliciesLoadedWithoutSync)) {
       browser_->signin_view_controller()->ShowModalEnterpriseConfirmationDialog(
diff --git a/chrome/browser/ui/signin_view_controller.cc b/chrome/browser/ui/signin_view_controller.cc
index 1c83a7e..4b6a398 100644
--- a/chrome/browser/ui/signin_view_controller.cc
+++ b/chrome/browser/ui/signin_view_controller.cc
@@ -8,6 +8,7 @@
 #include <utility>
 
 #include "base/bind.h"
+#include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
@@ -251,7 +252,7 @@
     const AccountInfo& account_info,
     SkColor profile_color,
     base::OnceCallback<void(bool)> callback) {
-#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) || \
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \
     BUILDFLAG(IS_CHROMEOS_LACROS)
   CloseModalSignin();
   dialog_ = std::make_unique<SigninModalDialogImpl>(
diff --git a/chrome/browser/ui/signin_view_controller.h b/chrome/browser/ui/signin_view_controller.h
index 6159e186..c79247e 100644
--- a/chrome/browser/ui/signin_view_controller.h
+++ b/chrome/browser/ui/signin_view_controller.h
@@ -22,7 +22,7 @@
 #include "chrome/browser/ui/webui/signin/signin_email_confirmation_dialog.h"
 #endif
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 #error This file should only be included on desktop.
 #endif
 
diff --git a/chrome/browser/ui/signin_view_controller_delegate.h b/chrome/browser/ui/signin_view_controller_delegate.h
index 30b5c7a3..38860ee7 100644
--- a/chrome/browser/ui/signin_view_controller_delegate.h
+++ b/chrome/browser/ui/signin_view_controller_delegate.h
@@ -73,7 +73,7 @@
       Browser* browser);
 #endif  // BUILDFLAG(ENABLE_DICE_SUPPORT)
 
-#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) || \
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \
     BUILDFLAG(IS_CHROMEOS_LACROS)
   // Returns a platform-specific SigninViewContolllerDelegate instance that
   // displays the enterprise confirmation modal dialog. The returned object
diff --git a/chrome/browser/ui/signin_view_controller_interactive_uitest.cc b/chrome/browser/ui/signin_view_controller_interactive_uitest.cc
index ad0a72a..f304f43 100644
--- a/chrome/browser/ui/signin_view_controller_interactive_uitest.cc
+++ b/chrome/browser/ui/signin_view_controller_interactive_uitest.cc
@@ -98,7 +98,7 @@
 
   ui_test_utils::TabAddedWaiter wait_for_new_tab(browser());
 // Press Ctrl/Cmd+T, which will open a new tab.
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
       browser(), ui::VKEY_T, /*control=*/false, /*shift=*/false, /*alt=*/false,
       /*command=*/true));
@@ -141,7 +141,7 @@
 // Tests that the confirm button is focused by default in the signin email
 // confirmation dialog.
 // TODO(http://crbug.com/1286855): Flaky on MacOS.
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #define MAYBE_EmailConfirmationDefaultFocus \
   DISABLED_EmailConfirmationDefaultFocus
 #else
diff --git a/chrome/browser/ui/sync/profile_signin_confirmation_helper_browsertest.cc b/chrome/browser/ui/sync/profile_signin_confirmation_helper_browsertest.cc
index e6ba2df..a776e1f 100644
--- a/chrome/browser/ui/sync/profile_signin_confirmation_helper_browsertest.cc
+++ b/chrome/browser/ui/sync/profile_signin_confirmation_helper_browsertest.cc
@@ -35,7 +35,7 @@
 
 // http://crbug.com/321302
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING) && \
-    (defined(OS_MAC) || defined(OS_LINUX) || defined(OS_CHROMEOS))
+    (BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS))
 #define MAYBE_HasNotBeenShutdown DISABLED_HasNotBeenShutdown
 #else
 #define MAYBE_HasNotBeenShutdown HasNotBeenShutdown
@@ -50,7 +50,7 @@
 
 // http://crbug.com/321302
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING) && \
-    (defined(OS_MAC) || defined(OS_LINUX) || defined(OS_CHROMEOS))
+    (BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS))
 #define MAYBE_HasNoSyncedExtensions DISABLED_HasNoSyncedExtensions
 #else
 #define MAYBE_HasNoSyncedExtensions HasNoSyncedExtensions
diff --git a/chrome/browser/ui/sync/profile_signin_confirmation_helper_unittest.cc b/chrome/browser/ui/sync/profile_signin_confirmation_helper_unittest.cc
index 90ef393..038dc3c 100644
--- a/chrome/browser/ui/sync/profile_signin_confirmation_helper_unittest.cc
+++ b/chrome/browser/ui/sync/profile_signin_confirmation_helper_unittest.cc
@@ -93,10 +93,10 @@
 };
 
 #if BUILDFLAG(ENABLE_EXTENSIONS)
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 const base::FilePath::CharType kExtensionFilePath[] =
     FILE_PATH_LITERAL("c:\\foo");
-#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
+#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
 const base::FilePath::CharType kExtensionFilePath[] = FILE_PATH_LITERAL("/oo");
 #endif
 
diff --git a/chrome/browser/ui/tab_contents/core_tab_helper.cc b/chrome/browser/ui/tab_contents/core_tab_helper.cc
index 1e59594..7d1b2b0 100644
--- a/chrome/browser/ui/tab_contents/core_tab_helper.cc
+++ b/chrome/browser/ui/tab_contents/core_tab_helper.cc
@@ -39,7 +39,7 @@
 #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
 #include "ui/base/l10n/l10n_util.h"
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 #include "chrome/browser/android/tab_android.h"
 #else
 #include "chrome/browser/ui/browser.h"
@@ -83,7 +83,7 @@
 
 void CoreTabHelper::UpdateContentRestrictions(int content_restrictions) {
   content_restrictions_ = content_restrictions;
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
   Browser* browser = chrome::FindBrowserWithWebContents(web_contents());
   if (!browser)
     return;
@@ -193,7 +193,7 @@
     std::unique_ptr<content::WebContents> new_contents,
     bool did_start_load,
     bool did_finish_load) {
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   TabAndroid* tab = TabAndroid::FromWebContents(web_contents());
   return tab->SwapWebContents(std::move(new_contents), did_start_load,
                               did_finish_load);
@@ -324,7 +324,7 @@
 
 // Update back/forward buttons for web_contents that are active.
 void CoreTabHelper::NavigationEntriesDeleted() {
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
   for (Browser* browser : *BrowserList::GetInstance()) {
     if (web_contents() == browser->tab_strip_model()->GetActiveWebContents())
       browser->command_controller()->TabStateChanged();
@@ -336,20 +336,20 @@
 // web contents or not.
 void CoreTabHelper::OnWebContentsFocused(
     content::RenderWidgetHost* render_widget_host) {
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
   Browser* browser = chrome::FindBrowserWithWebContents(web_contents());
   if (browser)
     browser->command_controller()->WebContentsFocusChanged();
-#endif  // defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_ANDROID)
 }
 
 void CoreTabHelper::OnWebContentsLostFocus(
     content::RenderWidgetHost* render_widget_host) {
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
   Browser* browser = chrome::FindBrowserWithWebContents(web_contents());
   if (browser)
     browser->command_controller()->WebContentsFocusChanged();
-#endif  // defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_ANDROID)
 }
 
 // Handles the image thumbnail for the context node, composes a image search
@@ -408,12 +408,12 @@
         content_type.c_str());
   }
   if (use_side_panel) {
-#if !defined(OS_ANDROID) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if !BUILDFLAG(IS_ANDROID) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
     lens::OpenLensSidePanel(chrome::FindBrowserWithWebContents(web_contents()),
                             open_url_params);
 #else
     web_contents()->OpenURL(open_url_params);
-#endif  // !defined(OS_ANDROID) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#endif  // !BUILDFLAG(IS_ANDROID) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
   } else {
     web_contents()->OpenURL(open_url_params);
   }
diff --git a/chrome/browser/ui/tab_helpers.cc b/chrome/browser/ui/tab_helpers.cc
index 4f7c4fb..695213b 100644
--- a/chrome/browser/ui/tab_helpers.cc
+++ b/chrome/browser/ui/tab_helpers.cc
@@ -135,7 +135,7 @@
 #include "ppapi/buildflags/buildflags.h"
 #include "printing/buildflags/buildflags.h"
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 #include "chrome/browser/android/oom_intervention/oom_intervention_tab_helper.h"
 #include "chrome/browser/banners/android/chrome_app_banner_manager_android.h"
 #include "chrome/browser/content_settings/request_desktop_site_web_contents_observer_android.h"
@@ -161,7 +161,7 @@
 #include "components/omnibox/common/omnibox_features.h"
 #include "components/web_modal/web_contents_modal_dialog_manager.h"
 #include "components/zoom/zoom_controller.h"
-#endif  // defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_ANDROID)
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/ash/child_accounts/time_limits/web_time_navigation_observer.h"
@@ -172,23 +172,23 @@
 #include "chrome/browser/lacros/web_contents_can_go_back_observer.h"
 #endif
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 #include "chrome/browser/chromeos/policy/dlp/dlp_content_tab_helper.h"
 #endif
 
-#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) || \
-    defined(OS_CHROMEOS) || defined(OS_FUCHSIA)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \
+    BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_FUCHSIA)
 #include "chrome/browser/ui/blocked_content/framebust_block_tab_helper.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/hats/hats_helper.h"
 #include "chrome/browser/ui/shared_highlighting/shared_highlighting_promo.h"
 #endif
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #include "chrome/browser/ui/cocoa/screentime/tab_helper.h"
 #endif
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 #include "chrome/browser/font_prewarmer_tab_helper.h"
 #endif
 
@@ -263,7 +263,7 @@
   // helpers may rely on that.
   CreateSessionServiceTabHelper(web_contents);
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
   // ZoomController comes before common tab helpers since ChromeAutofillClient
   // may want to register as a ZoomObserver with it.
   zoom::ZoomController::CreateForWebContents(web_contents);
@@ -349,12 +349,12 @@
   PrefsTabHelper::CreateForWebContents(web_contents);
   prerender::NoStatePrefetchTabHelper::CreateForWebContents(web_contents);
   RecentlyAudibleHelper::CreateForWebContents(web_contents);
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   if (base::FeatureList::IsEnabled(features::kRequestDesktopSiteExceptions)) {
     RequestDesktopSiteWebContentsObserverAndroid::CreateForWebContents(
         web_contents);
   }
-#endif  // defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_ANDROID)
   // TODO(siggi): Remove this once the Resource Coordinator refactoring is done.
   //     See https://crbug.com/910288.
   resource_coordinator::ResourceCoordinatorTabHelper::CreateForWebContents(
@@ -408,7 +408,7 @@
 
   // --- Section 2: Platform-specific tab helpers ---
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   {
     // Remove after fixing https://crbug/905919
     TRACE_EVENT0("browser", "AppBannerManagerAndroid::CreateForWebContents");
@@ -464,7 +464,7 @@
   }
 #endif
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   if (screentime::TabHelper::IsScreentimeEnabledForProfile(profile))
     screentime::TabHelper::CreateForWebContents(web_contents);
 #endif
@@ -479,20 +479,20 @@
   WebContentsCanGoBackObserver::CreateForWebContents(web_contents);
 #endif
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   policy::DlpContentTabHelper::MaybeCreateForWebContents(web_contents);
   webapps::PreRedirectionURLObserver::CreateForWebContents(web_contents);
 #endif
 
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
-#if defined(OS_WIN) || defined(OS_MAC) || \
-    (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || \
+    (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
   metrics::DesktopSessionDurationObserver::CreateForWebContents(web_contents);
 #endif
 
-#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) || \
-    defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \
+    BUILDFLAG(IS_CHROMEOS)
   if (base::FeatureList::IsEnabled(
           features::kHappinessTrackingSurveysForDesktopDemo) ||
       base::FeatureList::IsEnabled(features::kTrustSafetySentimentSurvey) ||
@@ -502,14 +502,14 @@
   }
 #endif
 
-#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) || \
-    defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \
+    BUILDFLAG(IS_CHROMEOS)
   if (Browser* browser = chrome::FindBrowserWithProfile(profile)) {
     SharedHighlightingPromo::CreateForWebContents(web_contents, browser);
   }
 #endif
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   if (base::FeatureList::IsEnabled(features::kPrewarmSearchResultsPageFonts))
     FontPrewarmerTabHelper::CreateForWebContents(web_contents);
 #endif
diff --git a/chrome/browser/ui/tab_helpers.h b/chrome/browser/ui/tab_helpers.h
index 507898b..413e357 100644
--- a/chrome/browser/ui/tab_helpers.h
+++ b/chrome/browser/ui/tab_helpers.h
@@ -7,7 +7,7 @@
 
 #include "build/build_config.h"
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 
 namespace android {
 class TabWebContentsDelegateAndroid;
@@ -25,7 +25,7 @@
 class BrowserTabStripModelDelegate;
 }
 
-#endif  // defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_ANDROID)
 
 namespace content {
 class WebContents;
@@ -48,7 +48,7 @@
 // only Browser and BrowserTabStripModelDelegate.)
 class TabHelpers {
  private:
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   // ThinWebView is used to host WebContents on non-tab UIs in Android. Most
   // clients of ThinWebView will need a major subset of the tab helpers.
   friend class thin_webview::android::ChromeThinWebViewInitializer;
@@ -58,7 +58,7 @@
 #else
   friend class Browser;
   friend class chrome::BrowserTabStripModelDelegate;
-#endif  // defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_ANDROID)
 
   // chrome::Navigate creates WebContents that are destined for the tab strip,
   // and that might have WebUI that immediately calls back into random tab
diff --git a/chrome/browser/ui/tab_ui_helper.cc b/chrome/browser/ui/tab_ui_helper.cc
index bea7546..0e21e72 100644
--- a/chrome/browser/ui/tab_ui_helper.cc
+++ b/chrome/browser/ui/tab_ui_helper.cc
@@ -47,7 +47,7 @@
   if (tab_ui_data_)
     return tab_ui_data_->title;
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   return l10n_util::GetStringUTF16(IDS_BROWSER_WINDOW_MAC_TAB_UNTITLED);
 #else
   return std::u16string();
diff --git a/chrome/browser/ui/tabs/tab_menu_model.cc b/chrome/browser/ui/tabs/tab_menu_model.cc
index df6759e..3c1d272 100644
--- a/chrome/browser/ui/tabs/tab_menu_model.cc
+++ b/chrome/browser/ui/tabs/tab_menu_model.cc
@@ -122,7 +122,7 @@
     AddSeparator(ui::NORMAL_SEPARATOR);
 
     if (send_tab_to_self::GetValidDeviceCount(tab_strip->profile()) == 1) {
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
       AddItem(TabStripModel::CommandSendTabToSelfSingleTarget,
               l10n_util::GetStringFUTF16(
                   IDS_CONTEXT_MENU_SEND_TAB_TO_SELF_SINGLE_TARGET,
@@ -141,7 +141,7 @@
           std::make_unique<send_tab_to_self::SendTabToSelfSubMenuModel>(
               tab_strip->GetWebContentsAt(index),
               send_tab_to_self::SendTabToSelfMenuType::kTab);
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
       AddSubMenuWithStringId(TabStripModel::CommandSendTabToSelf,
                              IDS_CONTEXT_MENU_SEND_TAB_TO_SELF,
                              send_tab_to_self_sub_menu_model_.get());
diff --git a/chrome/browser/ui/tabs/tab_renderer_data.cc b/chrome/browser/ui/tabs/tab_renderer_data.cc
index 3f36724..48a5fb5c 100644
--- a/chrome/browser/ui/tabs/tab_renderer_data.cc
+++ b/chrome/browser/ui/tabs/tab_renderer_data.cc
@@ -100,7 +100,7 @@
 
 bool TabRendererData::IsCrashed() const {
   return (crashed_status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED ||
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
           crashed_status ==
               base::TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM ||
 #endif
diff --git a/chrome/browser/ui/tabs/tab_strip_model.h b/chrome/browser/ui/tabs/tab_strip_model.h
index ba75b4a..d789d6b0 100644
--- a/chrome/browser/ui/tabs/tab_strip_model.h
+++ b/chrome/browser/ui/tabs/tab_strip_model.h
@@ -34,7 +34,7 @@
 #include "ui/base/models/list_selection_model.h"
 #include "ui/base/page_transition_types.h"
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 #error This file should only be included on desktop.
 #endif
 
diff --git a/chrome/browser/ui/task_manager/task_manager_columns.cc b/chrome/browser/ui/task_manager/task_manager_columns.cc
index 4fa4c767..68ae548 100644
--- a/chrome/browser/ui/task_manager/task_manager_columns.cc
+++ b/chrome/browser/ui/task_manager/task_manager_columns.cc
@@ -40,15 +40,15 @@
 // to make it the primary sort column a caret appears to the right of the
 // column's label. Without a little extra space, the tableview squeezes the
 // caret in by tail-truncating the label, which looks terrible.
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
     {IDS_TASK_MANAGER_CPU_COLUMN, ui::TableColumn::RIGHT, -1, 0,
      base::size("0099.9") * kCharWidth, -1, true, false, true},
 #else
     {IDS_TASK_MANAGER_CPU_COLUMN, ui::TableColumn::RIGHT, -1, 0,
      base::size("99.9") * kCharWidth, -1, true, false, true},
-#endif  // defined(OS_MAC)
+#endif  // BUILDFLAG(IS_MAC)
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
     {IDS_TASK_MANAGER_CPU_TIME_COLUMN, ui::TableColumn::RIGHT, -1, 0,
      base::size("1234h 42m 30s") * kCharWidth, -1, true, false, false},
     {IDS_TASK_MANAGER_START_TIME_COLUMN, ui::TableColumn::RIGHT, -1, 0,
@@ -59,7 +59,7 @@
     {IDS_TASK_MANAGER_PROCESS_ID_COLUMN, ui::TableColumn::RIGHT, -1, 0,
      base::size("73099  ") * kCharWidth, -1, true, true, true},
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
     {IDS_TASK_MANAGER_GDI_HANDLES_COLUMN, ui::TableColumn::RIGHT, -1, 0, 0, 0,
      true, false, false},
     {IDS_TASK_MANAGER_USER_HANDLES_COLUMN, ui::TableColumn::RIGHT, -1, 0, 0, 0,
@@ -89,15 +89,15 @@
     {IDS_TASK_MANAGER_IDLE_WAKEUPS_COLUMN, ui::TableColumn::RIGHT, -1, 0,
      base::size("idlewakeups") * kCharWidth, -1, true, false, false},
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
     {IDS_TASK_MANAGER_HARD_FAULTS_COLUMN, ui::TableColumn::RIGHT, -1, 0,
      base::size("100000") * kCharWidth, -1, true, false, false},
 #endif
 
-#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC)
     {IDS_TASK_MANAGER_OPEN_FD_COUNT_COLUMN, ui::TableColumn::RIGHT, -1, 0,
      base::size("999") * kCharWidth, -1, true, false, false},
-#endif  // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC)
+#endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC)
     {IDS_TASK_MANAGER_PROCESS_PRIORITY_COLUMN, ui::TableColumn::LEFT, -1, 0,
      base::size("background") * kCharWidth, -1, true, true, false},
     {IDS_TASK_MANAGER_KEEPALIVE_COUNT_COLUMN, ui::TableColumn::RIGHT, -1, 0,
diff --git a/chrome/browser/ui/task_manager/task_manager_table_model.cc b/chrome/browser/ui/task_manager/task_manager_table_model.cc
index 14d84f5..63193c26 100644
--- a/chrome/browser/ui/task_manager/task_manager_table_model.cc
+++ b/chrome/browser/ui/task_manager/task_manager_table_model.cc
@@ -37,12 +37,12 @@
 
 const char kCpuTextFormatString[] = "%.1f";
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 // Match Activity Monitor's default refresh rate.
 const int64_t kRefreshTimeMS = 2000;
 #else
 const int64_t kRefreshTimeMS = 1000;
-#endif  // defined(OS_MAC)
+#endif  // BUILDFLAG(IS_MAC)
 
 // The columns that are shared by a group will show the value of the column
 // only once per group.
@@ -161,7 +161,7 @@
     if (memory_usage == -1)
       return n_a_string_;
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
     // System expectation is to show "100 kB", "200 MB", etc.
     // TODO(thakis): [This TODO has been taken as is from the old task manager]:
     // Switch to metric units (as opposed to powers of two).
@@ -172,7 +172,7 @@
     base::i18n::AdjustStringForLocaleDirection(&memory_text);
     memory_text = l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_MEM_CELL_TEXT,
                                              memory_text);
-#endif  // defined(OS_MAC)
+#endif  // BUILDFLAG(IS_MAC)
 
     if (has_duplicates)
       memory_text += asterisk_string_;
@@ -451,13 +451,13 @@
           ? stringifier_->backgrounded_string()
           : stringifier_->foregrounded_string();
 
-#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC)
     case IDS_TASK_MANAGER_OPEN_FD_COUNT_COLUMN: {
       const int fd_count = observed_task_manager()->GetOpenFdCount(tasks_[row]);
       return fd_count >= 0 ? base::FormatNumber(fd_count)
                            : stringifier_->n_a_string();
     }
-#endif  // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC)
+#endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC)
 
     case IDS_TASK_MANAGER_KEEPALIVE_COUNT_COLUMN: {
       return stringifier_->GetKeepaliveCountText(
@@ -618,7 +618,7 @@
       return BooleanCompare(is_proc1_bg, is_proc2_bg);
     }
 
-#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC)
     case IDS_TASK_MANAGER_OPEN_FD_COUNT_COLUMN: {
       const int proc1_fd_count =
           observed_task_manager()->GetOpenFdCount(tasks_[row1]);
@@ -626,7 +626,7 @@
           observed_task_manager()->GetOpenFdCount(tasks_[row2]);
       return ValueCompare(proc1_fd_count, proc2_fd_count);
     }
-#endif  // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC)
+#endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC)
 
     default:
       NOTREACHED();
@@ -792,11 +792,11 @@
       type = REFRESH_TYPE_KEEPALIVE_COUNT;
       break;
 
-#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC)
     case IDS_TASK_MANAGER_OPEN_FD_COUNT_COLUMN:
       type = REFRESH_TYPE_FD_COUNT;
       break;
-#endif  // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC)
+#endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC)
 
     default:
       NOTREACHED();
diff --git a/chrome/browser/ui/test/test_browser_dialog.cc b/chrome/browser/ui/test/test_browser_dialog.cc
index 21f5c682..f0dbd280 100644
--- a/chrome/browser/ui/test/test_browser_dialog.cc
+++ b/chrome/browser/ui/test/test_browser_dialog.cc
@@ -20,7 +20,7 @@
 #include "ash/shell.h"
 #endif
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #include "chrome/browser/ui/test/test_browser_dialog_mac.h"
 #endif
 
@@ -118,7 +118,7 @@
 // TODO(https://crbug.com/958242) support Mac for pixel tests.
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
-#if defined(OS_WIN) || (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
+#if BUILDFLAG(IS_WIN) || (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
   dialog_widget->SetBlockCloseForTesting(true);
   // Deactivate before taking screenshot. Deactivated dialog pixel outputs
   // is more predictable than activated dialog.
@@ -138,7 +138,7 @@
   }
   if (is_active)
     dialog_widget->Activate();
-#endif  // OS_MAC
+#endif  // BUILDFLAG(IS_MAC)
 
   if (!should_verify_dialog_bounds_)
     return true;
@@ -165,7 +165,7 @@
 }
 
 void TestBrowserDialog::WaitForUserDismissal() {
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   internal::TestBrowserDialogInteractiveSetUp();
 #endif
 
diff --git a/chrome/browser/ui/test/test_browser_ui.cc b/chrome/browser/ui/test/test_browser_ui.cc
index 37b7ca6b..b73da86 100644
--- a/chrome/browser/ui/test/test_browser_ui.cc
+++ b/chrome/browser/ui/test/test_browser_ui.cc
@@ -15,8 +15,8 @@
 
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
-#if defined(OS_WIN) || defined(OS_MAC) || \
-    (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || \
+    (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
 #include "chrome/test/pixel/browser_skia_gold_pixel_diff.h"
 #include "ui/base/test/skia_gold_matching_algorithm.h"
 #include "ui/compositor/test/draw_waiter_for_test.h"
@@ -37,9 +37,9 @@
 
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
-#if defined(OS_WIN) || (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
+#if BUILDFLAG(IS_WIN) || (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
 void InstallUIControlsAura() {
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   ui_controls::InstallUIControlsAura(aura::test::CreateUIControlsAura(nullptr));
 #elif defined(USE_OZONE)
   ui_controls::InstallUIControlsAura(
@@ -55,7 +55,7 @@
 TestBrowserUi::TestBrowserUi() {
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
-#if defined(OS_WIN) || (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
+#if BUILDFLAG(IS_WIN) || (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
   // Default to fuzzy diff. The magic number is chosen based on
   // past experiments.
   SetPixelMatchAlgorithm(
@@ -68,7 +68,7 @@
 // TODO(https://crbug.com/958242) support Mac for pixel tests.
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
-#if defined(OS_WIN) || (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
+#if BUILDFLAG(IS_WIN) || (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
 bool TestBrowserUi::VerifyPixelUi(views::Widget* widget,
                                   const std::string& screenshot_prefix,
                                   const std::string& screenshot_name) {
diff --git a/chrome/browser/ui/test/test_browser_ui.h b/chrome/browser/ui/test/test_browser_ui.h
index b86670c..d04c27b0 100644
--- a/chrome/browser/ui/test/test_browser_ui.h
+++ b/chrome/browser/ui/test/test_browser_ui.h
@@ -99,7 +99,7 @@
 
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
-#if defined(OS_WIN) || (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
+#if BUILDFLAG(IS_WIN) || (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
   // Can be called by VerifyUi() to ensure pixel correctness.
   bool VerifyPixelUi(views::Widget* widget,
                      const std::string& screenshot_prefix,
@@ -135,8 +135,8 @@
  private:
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
-#if defined(OS_WIN) || defined(OS_MAC) || \
-    (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || \
+    (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
   std::unique_ptr<ui::test::SkiaGoldMatchingAlgorithm> algorithm_;
 #endif
 };
diff --git a/chrome/browser/ui/thumbnails/thumbnail_tab_helper_browsertest.cc b/chrome/browser/ui/thumbnails/thumbnail_tab_helper_browsertest.cc
index ee685c4..c235733e 100644
--- a/chrome/browser/ui/thumbnails/thumbnail_tab_helper_browsertest.cc
+++ b/chrome/browser/ui/thumbnails/thumbnail_tab_helper_browsertest.cc
@@ -157,7 +157,7 @@
 };
 
 // Flaky on Mac: https://crbug.com/1288117
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #define MAYBE_TabLoadTriggersScreenshot DISABLED_TabLoadTriggersScreenshot
 #else
 #define MAYBE_TabLoadTriggersScreenshot TabLoadTriggersScreenshot
@@ -177,7 +177,7 @@
 #if BUILDFLAG(ENABLE_SESSION_SERVICE)
 
 // Flaky on Win: https://crbug.com/1211377
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 #define MAYBE_CapturesRestoredTabWhenRequested \
   DISABLED_CapturesRestoredTabWhenRequested
 #else
diff --git a/chrome/browser/ui/ui_features.cc b/chrome/browser/ui/ui_features.cc
index 2f9abfe..663e443 100644
--- a/chrome/browser/ui/ui_features.cc
+++ b/chrome/browser/ui/ui_features.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/ui/ui_features.h"
 
 #include "base/feature_list.h"
+#include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "ui_features.h"
 
@@ -253,12 +254,12 @@
 const base::Feature kWebUIFeedback{"WebUIFeedback",
                                    base::FEATURE_DISABLED_BY_DEFAULT};
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 const base::Feature kChromeOSTabSearchCaptionButton{
     "ChromeOSTabSearchCaptionButton", base::FEATURE_DISABLED_BY_DEFAULT};
 #endif
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 // Enabled an experiment which increases the prominence to grant MacOS system
 // location permission to Chrome when location permissions have already been
 // approved. https://crbug.com/1211052
@@ -288,7 +289,7 @@
 }
 #endif
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 
 // Moves the Tab Search button into the browser frame's caption button area on
 // Windows 10 (crbug.com/1223847).
diff --git a/chrome/browser/ui/ui_features.h b/chrome/browser/ui/ui_features.h
index a0f59c6..08a4034 100644
--- a/chrome/browser/ui/ui_features.h
+++ b/chrome/browser/ui/ui_features.h
@@ -191,12 +191,12 @@
 
 extern const base::Feature kWebUIFeedback;
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 extern const base::Feature kChromeOSTabSearchCaptionButton;
 #endif
 
 // Cocoa to views migration.
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 extern const base::Feature kLocationPermissionsExperiment;
 
 extern const base::Feature kViewsFirstRunDialog;
@@ -207,7 +207,7 @@
 int GetLocationPermissionsExperimentLabelPromptLimit();
 #endif
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 extern const base::Feature kWin10TabSearchCaptionButton;
 #endif
 
diff --git a/chrome/browser/ui/user_education/tutorial/tutorial_service_manager.cc b/chrome/browser/ui/user_education/tutorial/tutorial_service_manager.cc
index e537afe..69dad33a 100644
--- a/chrome/browser/ui/user_education/tutorial/tutorial_service_manager.cc
+++ b/chrome/browser/ui/user_education/tutorial/tutorial_service_manager.cc
@@ -8,7 +8,7 @@
 #include "chrome/browser/ui/user_education/tutorial/tutorial_bubble_factory_registry.h"
 
 // TODO: as more platforms are tested for reliability we will add them here.
-#if defined(OS_MAC) || defined(OS_WIN)
+#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
 #include "chrome/browser/ui/user_education/tutorial/browser_tutorial_service_factory.h"
 #endif
 
@@ -24,10 +24,10 @@
 
 TutorialService* TutorialServiceManager::GetTutorialServiceForProfile(
     Profile* profile) {
-#if defined(OS_MAC) || defined(OS_WIN)
+#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
   return BrowserTutorialServiceFactory::GetForProfile(profile);
 #endif
-#if !defined(OS_MAC) && !defined(OS_WIN)
+#if !BUILDFLAG(IS_MAC) && !BUILDFLAG(IS_WIN)
   return nullptr;
 #endif
 }
diff --git a/chrome/browser/ui/views/accelerator_table.cc b/chrome/browser/ui/views/accelerator_table.cc
index 941520c..21eccd4 100644
--- a/chrome/browser/ui/views/accelerator_table.cc
+++ b/chrome/browser/ui/views/accelerator_table.cc
@@ -112,7 +112,7 @@
     {ui::VKEY_8, ui::EF_ALT_DOWN, IDC_SELECT_TAB_7},
     {ui::VKEY_NUMPAD8, ui::EF_ALT_DOWN, IDC_SELECT_TAB_7},
     {ui::VKEY_BROWSER_FAVORITES, ui::EF_NONE, IDC_SHOW_BOOKMARK_BAR},
-#endif  // OS_LINUX && !OS_CHROMEOS
+#endif  // BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS)
     {ui::VKEY_B, ui::EF_SHIFT_DOWN | ui::EF_PLATFORM_ACCELERATOR,
      IDC_SHOW_BOOKMARK_BAR},
     {ui::VKEY_OEM_MINUS, ui::EF_PLATFORM_ACCELERATOR, IDC_ZOOM_MINUS},
@@ -152,7 +152,7 @@
     // Chrome OS keyboard does not have delete key, so assign it to backspace.
     {ui::VKEY_BACK, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN,
      IDC_CLEAR_BROWSING_DATA},
-#else   // !(BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS))
+#else  // !(BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS))
     {ui::VKEY_DELETE, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN,
      IDC_CLEAR_BROWSING_DATA},
 #endif  // !(BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS))
@@ -166,7 +166,7 @@
     {ui::VKEY_BROWSER_STOP, ui::EF_NONE, IDC_STOP},
     // On Chrome OS, Search + Esc is used to call out task manager.
     {ui::VKEY_ESCAPE, ui::EF_COMMAND_DOWN, IDC_TASK_MANAGER},
-#else  // !OS_CHROMEOS
+#else   // BUILDFLAG(IS_CHROMEOS_ASH)
     {ui::VKEY_ESCAPE, ui::EF_SHIFT_DOWN, IDC_TASK_MANAGER},
     {ui::VKEY_LMENU, ui::EF_NONE, IDC_FOCUS_MENU_BAR},
     {ui::VKEY_MENU, ui::EF_NONE, IDC_FOCUS_MENU_BAR},
@@ -174,11 +174,11 @@
     // On Windows, all VKEY_BROWSER_* keys except VKEY_BROWSER_SEARCH are
     // handled via WM_APPCOMMAND.
     {ui::VKEY_BROWSER_SEARCH, ui::EF_NONE, IDC_FOCUS_SEARCH},
-#endif  // !OS_CHROMEOS
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING) && !BUILDFLAG(IS_MAC)
     {ui::VKEY_I, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, IDC_FEEDBACK},
-#endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING) && !OS_MAC
+#endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING) && !BUILDFLAG(IS_MAC)
     {ui::VKEY_N, ui::EF_SHIFT_DOWN | ui::EF_PLATFORM_ACCELERATOR,
      IDC_NEW_INCOGNITO_WINDOW},
     {ui::VKEY_T, ui::EF_PLATFORM_ACCELERATOR, IDC_NEW_TAB},
@@ -226,8 +226,8 @@
     // uses this for switching IMEs, but since this feature is only exposed via
     // command line flag at the moment, we'll exclude them entirely for now.
     {ui::VKEY_SPACE, ui::EF_CONTROL_DOWN, IDC_TOGGLE_COMMANDER},
-#endif  // !OS_CHROMEOS
-#endif  // !OS_MAC
+#endif  // !BUILDFLAG(IS_CHROMEOS_ASH)
+#endif  // !BUILDFLAG(IS_MAC)
 };
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/chrome/browser/ui/views/accessibility/browser_accessibility_uitest_auralinux.cc b/chrome/browser/ui/views/accessibility/browser_accessibility_uitest_auralinux.cc
index f11a56a..0bd4be0 100644
--- a/chrome/browser/ui/views/accessibility/browser_accessibility_uitest_auralinux.cc
+++ b/chrome/browser/ui/views/accessibility/browser_accessibility_uitest_auralinux.cc
@@ -176,7 +176,7 @@
                          ->GetNativeViewAccessible());
 
   GURL url(url::kAboutBlankURL);
-  AddTabAtIndex(0, url, ui::PAGE_TRANSITION_LINK);
+  ASSERT_TRUE(AddTabAtIndex(0, url, ui::PAGE_TRANSITION_LINK));
   EXPECT_EQ(2, browser()->tab_strip_model()->count());
   EXPECT_EQ(0, browser()->tab_strip_model()->active_index());
 
diff --git a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc
index 484a7ec..317b63b 100644
--- a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc
+++ b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc
@@ -405,15 +405,22 @@
   // GetSubtexts();
   void UpdateLayoutSize(views::BoxLayout* layout_manager, int64_t num_subtexts);
 
+  // Returns true if the mouse is within the bounds of this item. This is not
+  // affected by whether or not the item is overlaid by another popup.
+  bool IsMouseInsideItemBounds() const { return IsMouseHovered(); }
+
+  // We want a mouse click to accept a suggestion only if the user has made an
+  // explicit choice. Therefore, we shall ignore mouse clicks unless the mouse
+  // has been moved into the item's screen bounds. For example, if the item is
+  // hovered by the mouse at the time it's first shown, we want to ignore clicks
+  // until the mouse has left and re-entered the bounds of the item
+  // (crbug.com/1240472, crbug.com/1241585, crbug.com/1287364).
+  bool mouse_observed_outside_item_bounds_ = false;
+
   const int frontend_id_;
 
   // All the labels inside this view.
   std::vector<views::Label*> inner_labels_;
-
-  // The Autofill popup may be hovered by the mouse after its creation. In this
-  // case, we want to ignore clicks on the hovered menu item until the user made
-  // an explicit choice (crbug.com/1240472, crbug.com/1241585).
-  bool mouse_observed_outside_of_item_ = false;
 };
 
 int AutofillPopupItemView::GetFrontendId() const {
@@ -619,14 +626,14 @@
 
 void AutofillPopupItemView::OnPaint(gfx::Canvas* canvas) {
   AutofillPopupRowView::OnPaint(canvas);
-  mouse_observed_outside_of_item_ |= !IsMouseHovered();
+  mouse_observed_outside_item_bounds_ |= !IsMouseInsideItemBounds();
 }
 
 void AutofillPopupItemView::OnMouseEntered(const ui::MouseEvent& event) {
-  // OnMouseEntered() also fires if the had been hovering over the item and
-  // moved only a little bit. In that case, clicks shall still be ignored and we
-  // don't want to show a preview (crbug.com/1240472, crbug.com/1241585).
-  if (!mouse_observed_outside_of_item_)
+  // OnMouseEntered() does not imply that the mouse had been outside of the
+  // item's bounds before: OnMouseEntered() also fires if the mouse moves just a
+  // little bit on the item. We don't want to show a preview in such a case.
+  if (!mouse_observed_outside_item_bounds_)
     return;
 
   base::WeakPtr<AutofillPopupController> controller =
@@ -636,7 +643,11 @@
 }
 
 void AutofillPopupItemView::OnMouseExited(const ui::MouseEvent& event) {
-  mouse_observed_outside_of_item_ = true;
+  // OnMouseExited() does not imply that the mouse has left the item's screen
+  // bounds: OnMouseExited() also fires (on Windows, at least) even when another
+  // popup overlays this item (crbug.com/1287364).
+  mouse_observed_outside_item_bounds_ |= !IsMouseInsideItemBounds();
+
   base::WeakPtr<AutofillPopupController> controller =
       popup_view()->controller();
   if (controller)
@@ -644,10 +655,9 @@
 }
 
 void AutofillPopupItemView::OnMouseReleased(const ui::MouseEvent& event) {
-  // Ignore mouse clicks in case the popup appeared directly under the mouse
-  // cursor and we have no indication that the user intentionally selected the
-  // current item (crbug.com/1240472, crbug.com/1241585).
-  if (!mouse_observed_outside_of_item_)
+  // Ignore mouse clicks unless the user made the explicit choice to selected
+  // the current item.
+  if (!mouse_observed_outside_item_bounds_)
     return;
 
   // Ignore clicks immediately after the popup was shown. This is to prevent
diff --git a/chrome/browser/ui/views/autofill/payments/save_card_bubble_views_browsertest.cc b/chrome/browser/ui/views/autofill/payments/save_card_bubble_views_browsertest.cc
index 1b4f3787..4c6afb7 100644
--- a/chrome/browser/ui/views/autofill/payments/save_card_bubble_views_browsertest.cc
+++ b/chrome/browser/ui/views/autofill/payments/save_card_bubble_views_browsertest.cc
@@ -1104,7 +1104,7 @@
   EXPECT_EQ(cardholder_name_textfield->GetText(), u"John Smith");
 }
 
-#endif  // !OS_CHROMEOS
+#endif  // !BUILDFLAG(IS_CHROMEOS_ASH)
 
 // Tests the fully-syncing state. Ensures that the Butter (i) info icon does not
 // appear for fully-syncing users.
diff --git a/chrome/browser/ui/views/autofill/update_address_profile_view.cc b/chrome/browser/ui/views/autofill/update_address_profile_view.cc
index c8fdc6fb..cb77eea 100644
--- a/chrome/browser/ui/views/autofill/update_address_profile_view.cc
+++ b/chrome/browser/ui/views/autofill/update_address_profile_view.cc
@@ -22,14 +22,13 @@
 #include "ui/views/controls/button/image_button_factory.h"
 #include "ui/views/controls/image_view.h"
 #include "ui/views/layout/flex_layout.h"
-#include "ui/views/layout/grid_layout.h"
+#include "ui/views/layout/table_layout_view.h"
 #include "ui/views/style/typography.h"
 
 namespace autofill {
 
 namespace {
 
-constexpr int kColumnSetId = 0;
 constexpr int kIconSize = 16;
 constexpr int kValuesLabelWidth = 190;
 
@@ -105,32 +104,25 @@
 
 // Add a row in `layout` that contains a label and a view displays all the
 // values in `values`. Labels are added only if `show_row_label` is true.
-void AddValuesRow(views::GridLayout* layout,
+void AddValuesRow(views::TableLayoutView* layout_view,
                   const std::vector<ProfileValueDifference>& diff,
                   bool show_row_label,
                   views::Button::PressedCallback edit_button_callback) {
   bool are_new_values = !!edit_button_callback;
-  layout->StartRow(/*vertical_resize=*/views::GridLayout::kFixedSize,
-                   kColumnSetId);
+  layout_view->AddRows(1, /*vertical_resize=*/views::GridLayout::kFixedSize);
 
   if (show_row_label) {
-    std::unique_ptr<views::Label> label(new views::Label(
+    auto label = std::make_unique<views::Label>(
         l10n_util::GetStringUTF16(
             are_new_values
                 ? IDS_AUTOFILL_UPDATE_ADDRESS_PROMPT_NEW_VALUES_SECTION_LABEL
                 : IDS_AUTOFILL_UPDATE_ADDRESS_PROMPT_OLD_VALUES_SECTION_LABEL),
-        views::style::CONTEXT_LABEL, views::style::STYLE_SECONDARY));
-    layout->AddView(std::move(label), /*col_span=*/1, /*row_span=*/1,
-                    /*h_align=*/views::GridLayout::LEADING,
-                    /*v_align=*/views::GridLayout::LEADING);
+        views::style::CONTEXT_LABEL, views::style::STYLE_SECONDARY);
+    layout_view->AddChildView(std::move(label));
   }
   ui::ColorId icon_color = are_new_values ? ui::kColorButtonBackgroundProminent
                                           : ui::kColorIconSecondary;
-  layout->AddView(CreateValuesView(diff, are_new_values, icon_color),
-                  /*col_span=*/1,
-                  /*row_span=*/1,
-                  /*h_align=*/views::GridLayout::FILL,
-                  /*v_align=*/views::GridLayout::FILL);
+  layout_view->AddChildView(CreateValuesView(diff, are_new_values, icon_color));
   if (are_new_values) {
     std::unique_ptr<views::ImageButton> edit_button =
         views::CreateVectorImageButtonWithNativeTheme(
@@ -141,9 +133,7 @@
         IDS_AUTOFILL_SAVE_ADDRESS_PROMPT_EDIT_BUTTON_TOOLTIP));
     edit_button->SetTooltipText(l10n_util::GetStringUTF16(
         IDS_AUTOFILL_SAVE_ADDRESS_PROMPT_EDIT_BUTTON_TOOLTIP));
-    layout->AddView(std::move(edit_button), /*col_span=*/1, /*row_span=*/1,
-                    /*h_align=*/views::GridLayout::LEADING,
-                    /*v_align=*/views::GridLayout::LEADING);
+    layout_view->AddChildView(std::move(edit_button));
   }
 }
 
@@ -176,7 +166,9 @@
   // would have been a save prompt.
   DCHECK(controller_->GetOriginalProfile());
 
-  set_fixed_width(views::LayoutProvider::Get()->GetDistanceMetric(
+  auto* layout_provider = views::LayoutProvider::Get();
+
+  set_fixed_width(layout_provider->GetDistanceMetric(
       views::DISTANCE_BUBBLE_PREFERRED_WIDTH));
 
   SetAcceptCallback(base::BindOnce(
@@ -201,12 +193,11 @@
       .SetCrossAxisAlignment(views::LayoutAlignment::kStretch)
       .SetIgnoreDefaultMainAxisMargins(true)
       .SetCollapseMargins(true)
-      .SetDefault(
-          views::kMarginsKey,
-          gfx::Insets(
-              /*vertical=*/ChromeLayoutProvider::Get()->GetDistanceMetric(
-                  DISTANCE_CONTROL_LIST_VERTICAL),
-              /*horizontal=*/0));
+      .SetDefault(views::kMarginsKey,
+                  gfx::Insets(
+                      /*vertical=*/layout_provider->GetDistanceMetric(
+                          DISTANCE_CONTROL_LIST_VERTICAL),
+                      /*horizontal=*/0));
 
   std::vector<ProfileValueDifference> profile_diff = GetProfileDifferenceForUi(
       controller_->GetProfileToSave(), *controller_->GetOriginalProfile(),
@@ -223,42 +214,41 @@
         gfx::HorizontalAlignment::ALIGN_LEFT);
   }
 
-  views::View* main_content_view =
-      AddChildView(std::make_unique<views::View>());
+  auto* main_content_view =
+      AddChildView(std::make_unique<views::TableLayoutView>());
 
   bool has_non_empty_original_values = HasNonEmptySecondValues(profile_diff);
 
-  // Build the GridLayout column set.
-  views::GridLayout* layout = main_content_view->SetLayoutManager(
-      std::make_unique<views::GridLayout>());
-  views::ColumnSet* column_set = layout->AddColumnSet(kColumnSetId);
-  const int column_divider = ChromeLayoutProvider::Get()->GetDistanceMetric(
+  // Build the TableLayoutView columns.
+  const int column_divider = layout_provider->GetDistanceMetric(
       views::DISTANCE_RELATED_CONTROL_HORIZONTAL);
   if (has_non_empty_original_values) {
     // Label column exists only if there is a section for original values.
-    column_set->AddColumn(
-        /*h_align=*/views::GridLayout::LEADING,
-        /*v_align=*/views::GridLayout::LEADING,
-        /*resize_percent=*/views::GridLayout::kFixedSize,
-        /*size_type=*/views::GridLayout::ColumnSize::kUsePreferred,
-        /*fixed_width=*/0, /*min_width=*/0);
-    column_set->AddPaddingColumn(views::GridLayout::kFixedSize, column_divider);
+    main_content_view
+        ->AddColumn(
+            /*h_align=*/views::LayoutAlignment::kStart,
+            /*v_align=*/views::LayoutAlignment::kStart,
+            /*horizontal_resize=*/views::TableLayout::kFixedSize,
+            /*size_type=*/views::TableLayout::ColumnSize::kUsePreferred,
+            /*fixed_width=*/0, /*min_width=*/0)
+        .AddPaddingColumn(views::TableLayout::kFixedSize, column_divider);
   }
-  column_set->AddColumn(
-      /*h_align=*/views::GridLayout::FILL,
-      /*v_align=*/views::GridLayout::FILL,
-      /*resize_percent=*/1.0,
-      /*size_type=*/views::GridLayout::ColumnSize::kUsePreferred,
-      /*fixed_width=*/0, /*min_width=*/0);
-  column_set->AddColumn(
-      /*h_align=*/views::GridLayout::LEADING,
-      /*v_align=*/views::GridLayout::LEADING,
-      /*resize_percent=*/views::GridLayout::kFixedSize,
-      /*size_type=*/views::GridLayout::ColumnSize::kUsePreferred,
-      /*fixed_width=*/0, /*min_width=*/0);
+  main_content_view
+      ->AddColumn(
+          /*h_align=*/views::LayoutAlignment::kStretch,
+          /*v_align=*/views::LayoutAlignment::kStretch,
+          /*horizontal_resize=*/1.0,
+          /*size_type=*/views::TableLayout::ColumnSize::kUsePreferred,
+          /*fixed_width=*/0, /*min_width=*/0)
+      .AddColumn(
+          /*h_align=*/views::LayoutAlignment::kStart,
+          /*v_align=*/views::LayoutAlignment::kStart,
+          /*horizontal_resize=*/views::TableLayout::kFixedSize,
+          /*size_type=*/views::TableLayout::ColumnSize::kUsePreferred,
+          /*fixed_width=*/0, /*min_width=*/0);
 
   AddValuesRow(
-      layout, profile_diff,
+      main_content_view, profile_diff,
       /*show_row_label=*/has_non_empty_original_values,
       /*edit_button_callback=*/
       base::BindRepeating(
@@ -266,10 +256,11 @@
           base::Unretained(controller_)));
 
   if (has_non_empty_original_values) {
-    layout->AddPaddingRow(views::GridLayout::kFixedSize,
-                          ChromeLayoutProvider::Get()->GetDistanceMetric(
-                              DISTANCE_UNRELATED_CONTROL_VERTICAL_LARGE));
-    AddValuesRow(layout, profile_diff, /*show_row_label=*/true,
+    main_content_view->AddPaddingRow(
+        views::TableLayout::kFixedSize,
+        layout_provider->GetDistanceMetric(
+            DISTANCE_UNRELATED_CONTROL_VERTICAL_LARGE));
+    AddValuesRow(main_content_view, profile_diff, /*show_row_label=*/true,
                  /*edit_button_callback=*/{});
   }
 }
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
index dfb100c7..8138e50a 100644
--- a/chrome/browser/ui/views/frame/browser_view.cc
+++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -13,7 +13,6 @@
 #include "base/auto_reset.h"
 #include "base/bind.h"
 #include "base/command_line.h"
-#include "base/compiler_specific.h"
 #include "base/containers/contains.h"
 #include "base/containers/flat_set.h"
 #include "base/feature_list.h"
@@ -365,7 +364,7 @@
       return true;
     }
   }
-#endif  // OS_MAC
+#endif  // BUILDFLAG(IS_MAC)
   return false;
 }
 
@@ -491,7 +490,7 @@
     }
   }
 }
-#endif  // OS_MAC
+#endif  // BUILDFLAG(IS_MAC)
 
 }  // namespace
 
@@ -1621,7 +1620,7 @@
     base::ThreadTaskRunnerHandle::Get()->PostTask(
         FROM_HERE, std::move(restore_pre_fullscreen_bounds_callback_));
   }
-#endif  // OS_MAC
+#endif  // BUILDFLAG(IS_MAC)
 }
 
 void BrowserView::SetToolbarButtonProvider(ToolbarButtonProvider* provider) {
@@ -2476,7 +2475,7 @@
   if (change.type() != TabStripModelChange::kInserted)
     return;
 
-  for (const auto& contents : change.GetInsert()->contents) {
+  for ([[maybe_unused]] const auto& contents : change.GetInsert()->contents) {
 #if defined(USE_AURA)
     // WebContents inserted in tabs might not have been added to the root
     // window yet. Per http://crbug/342672 add them now since drawing the
@@ -2489,8 +2488,6 @@
                                             root_window->GetBoundsInScreen());
       DCHECK(contents.contents->GetNativeView()->GetRootWindow());
     }
-#else
-    ALLOW_UNUSED_LOCAL(contents);
 #endif
     web_contents_close_handler_->TabInserted();
   }
@@ -3664,7 +3661,7 @@
   // TODO(crbug.com/1034783): Implement at lower layers to avoid transitions.
 #if BUILDFLAG(IS_MAC)
   bool entering_cross_screen_fullscreen = false;
-#endif  // OS_MAC
+#endif  // BUILDFLAG(IS_MAC)
   bool swapping_screens_during_fullscreen = false;
   if (fullscreen && display_id != display::kInvalidDisplayId) {
     display::Screen* screen = display::Screen::GetScreen();
@@ -3675,7 +3672,7 @@
         current_display.id() != display_id) {
 #if BUILDFLAG(IS_MAC)
       entering_cross_screen_fullscreen = true;
-#endif  // OS_MAC
+#endif  // BUILDFLAG(IS_MAC)
 
       // Fullscreen windows must exit fullscreen to move to another display.
       if (IsFullscreen()) {
@@ -3732,13 +3729,13 @@
   else if (entering_cross_screen_fullscreen)
     delay = base::Milliseconds(1);
   frame_->SetFullscreen(fullscreen, delay);
-#else   // OS_MAC
+#else   // BUILDFLAG(IS_MAC)
   frame_->SetFullscreen(fullscreen);
   // On Mac, the pre-fullscreen bounds must be restored after an asynchronous
   // transition out of the fullscreen workspace; see http://crbug.com/1039874
   if (!fullscreen && restore_pre_fullscreen_bounds_callback_)
     std::move(restore_pre_fullscreen_bounds_callback_).Run();
-#endif  // OS_MAC
+#endif  // BUILDFLAG(IS_MAC)
 
   // Enable immersive before the browser refreshes its list of enabled commands.
   const bool should_stay_in_immersive =
diff --git a/chrome/browser/ui/views/frame/browser_view_focus_uitest.cc b/chrome/browser/ui/views/frame/browser_view_focus_uitest.cc
index 50ad7bad..628aabf9 100644
--- a/chrome/browser/ui/views/frame/browser_view_focus_uitest.cc
+++ b/chrome/browser/ui/views/frame/browser_view_focus_uitest.cc
@@ -151,7 +151,7 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
 
   // Create another tab.
-  AddTabAtIndex(1, url, ui::PAGE_TRANSITION_TYPED);
+  ASSERT_TRUE(AddTabAtIndex(1, url, ui::PAGE_TRANSITION_TYPED));
 
   // Begin recording focus changes.
   gfx::NativeWindow window = browser()->window()->GetNativeWindow();
diff --git a/chrome/browser/ui/views/frame/browser_view_interactive_uitest.cc b/chrome/browser/ui/views/frame/browser_view_interactive_uitest.cc
index b72e033..be53f49a 100644
--- a/chrome/browser/ui/views/frame/browser_view_interactive_uitest.cc
+++ b/chrome/browser/ui/views/frame/browser_view_interactive_uitest.cc
@@ -192,7 +192,7 @@
   // other platforms.
   chrome::ToggleFullscreenToolbar(browser());
 #endif
-  AddTabAtIndex(0, GURL("about:blank"), ui::PAGE_TRANSITION_TYPED);
+  ASSERT_TRUE(AddTabAtIndex(0, GURL("about:blank"), ui::PAGE_TRANSITION_TYPED));
 
   // Now the bookmark bar should show up in regular mode.
   EXPECT_FALSE(browser_view->IsFullscreen());
diff --git a/chrome/browser/ui/views/frame/immersive_mode_browser_view_test.cc b/chrome/browser/ui/views/frame/immersive_mode_browser_view_test.cc
index 953f6d4..f0799ac 100644
--- a/chrome/browser/ui/views/frame/immersive_mode_browser_view_test.cc
+++ b/chrome/browser/ui/views/frame/immersive_mode_browser_view_test.cc
@@ -168,11 +168,11 @@
 
   // Create three more tabs plus the existing one that browser tests start with.
   const GURL about_blank(url::kAboutBlankURL);
-  AddTabAtIndex(0, about_blank, ui::PAGE_TRANSITION_TYPED);
+  ASSERT_TRUE(AddTabAtIndex(0, about_blank, ui::PAGE_TRANSITION_TYPED));
   browser()->tab_strip_model()->GetActiveWebContents()->Focus();
-  AddTabAtIndex(0, about_blank, ui::PAGE_TRANSITION_TYPED);
+  ASSERT_TRUE(AddTabAtIndex(0, about_blank, ui::PAGE_TRANSITION_TYPED));
   browser()->tab_strip_model()->GetActiveWebContents()->Focus();
-  AddTabAtIndex(0, about_blank, ui::PAGE_TRANSITION_TYPED);
+  ASSERT_TRUE(AddTabAtIndex(0, about_blank, ui::PAGE_TRANSITION_TYPED));
   browser()->tab_strip_model()->GetActiveWebContents()->Focus();
 
   // Toggle fullscreen mode.
@@ -356,7 +356,8 @@
 IN_PROC_BROWSER_TEST_P(ImmersiveModeBrowserViewTest, TabAndBrowserFullscreen) {
   BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser());
 
-  AddTabAtIndex(0, GURL(url::kAboutBlankURL), ui::PAGE_TRANSITION_TYPED);
+  ASSERT_TRUE(
+      AddTabAtIndex(0, GURL(url::kAboutBlankURL), ui::PAGE_TRANSITION_TYPED));
 
   // The shelf should start out as visible.
   EXPECT_TRUE(IsShelfVisible());
diff --git a/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos_browsertest.cc b/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos_browsertest.cc
index 40206e92..a01b4166 100644
--- a/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos_browsertest.cc
+++ b/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos_browsertest.cc
@@ -358,7 +358,7 @@
   }
 
   void OpenUrlAtIndex(const GURL& url, int index) {
-    AddTabAtIndex(index, url, ui::PAGE_TRANSITION_TYPED);
+    ASSERT_TRUE(AddTabAtIndex(index, url, ui::PAGE_TRANSITION_TYPED));
     auto* active_contents = browser_view()->GetActiveWebContents();
     EXPECT_TRUE(content::WaitForLoadStop(active_contents));
     SynchronizeBrowserWithRenderer(active_contents);
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
index 88aa9f0..193ecd3a 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
@@ -546,7 +546,7 @@
 #if BUILDFLAG(IS_WIN)
   // Update the input type with the input method on Windows for CJK.
   SetTextInputType(GetPreferredTextInputType());
-#endif  // OS_WIN
+#endif  // BUILDFLAG(IS_WIN)
 }
 
 ui::TextInputType OmniboxViewViews::GetPreferredTextInputType() const {
@@ -563,7 +563,7 @@
     if (input_method && input_method->IsInputLocaleCJK())
       return ui::TEXT_INPUT_TYPE_SEARCH;
   }
-#endif  // OS_WIN
+#endif  // BUILDFLAG(IS_WIN)
   return ui::TEXT_INPUT_TYPE_URL;
 }
 
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views_browsertest.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views_browsertest.cc
index dff363d..75f57372 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_view_views_browsertest.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_view_views_browsertest.cc
@@ -283,7 +283,7 @@
   EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
 #else
   EXPECT_FALSE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
-#endif  // OS_LINUX && !OS_CHROMEOS
+#endif
   EXPECT_FALSE(omnibox_view->IsSelectAll());
 }
 
@@ -335,7 +335,7 @@
   EXPECT_EQ(u"http://www.goo4567123gle.com/", omnibox_view->GetText());
   EXPECT_EQ(18U, omnibox_view_views->GetCursorPosition());
 }
-#endif  // OS_LINUX && !OS_CHROMEOS
+#endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
 
 // No touch on desktop Mac. Tracked in http://crbug.com/445520.
 #if !BUILDFLAG(IS_MAC) || defined(USE_AURA)
@@ -917,7 +917,7 @@
   omnibox_view_views->OnInputMethodChanged();
   EXPECT_EQ(ui::TEXT_INPUT_TYPE_URL, omnibox_view_views->GetTextInputType());
 }
-#endif  // OS_WIN
+#endif  // BUILDFLAG(IS_WIN)
 
 // ClickOnView(VIEW_ID_OMNIBOX) does not set focus to omnibox on Mac.
 // Looks like the same problem as in the SelectAllOnClick().
diff --git a/chrome/browser/ui/views/overlay/overlay_window_views.cc b/chrome/browser/ui/views/overlay/overlay_window_views.cc
index 3191f129..6636961 100644
--- a/chrome/browser/ui/views/overlay/overlay_window_views.cc
+++ b/chrome/browser/ui/views/overlay/overlay_window_views.cc
@@ -1111,7 +1111,7 @@
     controller_->Close(true /* should_pause_video */);
     event->SetHandled();
   }
-#endif  // OS_WIN
+#endif  // BUILDFLAG(IS_WIN)
 
   views::Widget::OnKeyEvent(event);
 }
diff --git a/chrome/browser/ui/views/payments/payment_request_journey_logger_browsertest.cc b/chrome/browser/ui/views/payments/payment_request_journey_logger_browsertest.cc
index e9f2e0e..6220073a 100644
--- a/chrome/browser/ui/views/payments/payment_request_journey_logger_browsertest.cc
+++ b/chrome/browser/ui/views/payments/payment_request_journey_logger_browsertest.cc
@@ -1758,6 +1758,65 @@
   EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_COULD_NOT_SHOW);
 }
 
+using PaymentRequestCompleteSuggestionsForEverythingBasicCardDisabledTest =
+    BasicCardDisabledTestBase;
+
+IN_PROC_BROWSER_TEST_F(
+    PaymentRequestCompleteSuggestionsForEverythingBasicCardDisabledTest,
+    UserHadCompleteSuggestionsForEverything) {
+  // Installs two apps to ensure that the payment request UI is shown.
+  std::string a_method_name;
+  InstallPaymentApp("a.com", "payment_request_success_responder.js",
+                    &a_method_name);
+  std::string b_method_name;
+  InstallPaymentApp("b.com", "payment_request_success_responder.js",
+                    &b_method_name);
+
+  NavigateTo("/payment_request_email_test.html");
+  base::HistogramTester histogram_tester;
+
+  // Add a profile.
+  AddAutofillProfile(autofill::test::GetFullProfile());
+
+  // Show a Payment Request.
+  InvokePaymentRequestUIWithJs(content::JsReplace(
+      "buyWithMethods([{supportedMethods:$1}, {supportedMethods:$2}]);",
+      a_method_name, b_method_name));
+
+  // Navigate away to abort the Payment Request and trigger the logs.
+  NavigateTo("/payment_request_email_test.html");
+
+  // Make sure the correct events were logged.
+  std::vector<base::Bucket> buckets =
+      histogram_tester.GetAllSamples("PaymentRequest.Events");
+  ASSERT_EQ(1U, buckets.size());
+  EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_SHOWN);
+  EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_PAY_CLICKED);
+  EXPECT_FALSE(buckets[0].min &
+               JourneyLogger::EVENT_RECEIVED_INSTRUMENT_DETAILS);
+  EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_SKIPPED_SHOW);
+  EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_COMPLETED);
+  EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_USER_ABORTED);
+  EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_OTHER_ABORTED);
+  EXPECT_TRUE(buckets[0].min &
+              JourneyLogger::EVENT_HAD_INITIAL_FORM_OF_PAYMENT);
+  EXPECT_TRUE(buckets[0].min &
+              JourneyLogger::EVENT_HAD_NECESSARY_COMPLETE_SUGGESTIONS);
+  EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_SHIPPING);
+  EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_NAME);
+  EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_PHONE);
+  EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_EMAIL);
+  EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE);
+  EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE);
+  EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_METHOD_BASIC_CARD);
+  EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_METHOD_GOOGLE);
+  EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_REQUEST_METHOD_OTHER);
+  EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_SELECTED_CREDIT_CARD);
+  EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_SELECTED_GOOGLE);
+  EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_SELECTED_OTHER);
+  EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_COULD_NOT_SHOW);
+}
+
 class PaymentRequestIframeTest : public BasicCardEnabledTestBase {
  public:
   PaymentRequestIframeTest(const PaymentRequestIframeTest&) = delete;
diff --git a/chrome/browser/ui/views/profiles/profile_picker_view.cc b/chrome/browser/ui/views/profiles/profile_picker_view.cc
index 8fb7370..e984d92 100644
--- a/chrome/browser/ui/views/profiles/profile_picker_view.cc
+++ b/chrome/browser/ui/views/profiles/profile_picker_view.cc
@@ -916,7 +916,7 @@
       AddAccelerator(accelerator);
     }
   }
-#endif  // OS_MAC
+#endif  // BUILDFLAG(IS_MAC)
 }
 
 void ProfilePickerView::ShowDialog(content::BrowserContext* browser_context,
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
index f461fd7..7a876ab24 100644
--- a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
+++ b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
@@ -460,7 +460,7 @@
               // Disable NativeWinOcclusion to avoid it interfering with test
               // for dragging over occluded browser window.
               features::kCalculateNativeWinOcclusion,
-#endif  // OS_WIN
+#endif  // BUILDFLAG(IS_WIN)
         });
   }
   DetachToBrowserTabDragControllerTest(
@@ -481,7 +481,7 @@
     // be obscured by other windows if there are any. This should be fixed in
     // order to be consistent with other platforms.
     EXPECT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
-#endif  // OS_MAC
+#endif  // BUILDFLAG(IS_MAC)
   }
 
   InputSource input_source() const {
@@ -1486,7 +1486,7 @@
   EXPECT_EQ(3u, browser_list->size());
 }
 
-#endif  // OS_WIN
+#endif  // BUILDFLAG(IS_WIN)
 
 namespace {
 
diff --git a/chrome/browser/ui/web_applications/pwa_mixed_content_browsertest.cc b/chrome/browser/ui/web_applications/pwa_mixed_content_browsertest.cc
index 700f05b..c80cb7b 100644
--- a/chrome/browser/ui/web_applications/pwa_mixed_content_browsertest.cc
+++ b/chrome/browser/ui/web_applications/pwa_mixed_content_browsertest.cc
@@ -238,7 +238,8 @@
 // Tests that iframes can't dynamically load mixed content in a regular browser
 // tab, when the iframe was created in a PWA window.
 // https://crbug.com/1087382: Flaky on Windows, CrOS and ASAN
-#if defined(OS_WIN) || BUILDFLAG(IS_CHROMEOS_ASH) || defined(ADDRESS_SANITIZER)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS_ASH) || \
+    defined(ADDRESS_SANITIZER)
 #define MAYBE_IFrameDynamicMixedContentInPWAOpenInChrome \
   DISABLED_IFrameDynamicMixedContentInPWAOpenInChrome
 #else
diff --git a/chrome/browser/ui/web_applications/share_target_utils.cc b/chrome/browser/ui/web_applications/share_target_utils.cc
index e33b7aab..a3886d6 100644
--- a/chrome/browser/ui/web_applications/share_target_utils.cc
+++ b/chrome/browser/ui/web_applications/share_target_utils.cc
@@ -72,7 +72,7 @@
   NavigateParams nav_params(browser, share_target.action,
                             ui::PAGE_TRANSITION_AUTO_TOPLEVEL);
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   std::vector<std::string> names;
   std::vector<std::string> values;
   std::vector<bool> is_value_file_uris;
@@ -203,7 +203,7 @@
   // TODO(crbug.com/1153194): Support Web Share Target on Windows.
   // TODO(crbug.com/1153195): Support Web Share Target on Mac.
   NOTIMPLEMENTED();
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
   return nav_params;
 }
diff --git a/chrome/browser/ui/web_applications/system_web_app_ui_utils.cc b/chrome/browser/ui/web_applications/system_web_app_ui_utils.cc
index e243ea2..928c3bf 100644
--- a/chrome/browser/ui/web_applications/system_web_app_ui_utils.cc
+++ b/chrome/browser/ui/web_applications/system_web_app_ui_utils.cc
@@ -10,6 +10,7 @@
 #include "base/check_op.h"
 #include "base/debug/dump_without_crashing.h"
 #include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
 #include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
@@ -195,7 +196,7 @@
 
   auto* system_app = provider->system_web_app_manager().GetSystemApp(app_type);
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   DCHECK(url.DeprecatedGetOriginAsURL() == provider->registrar()
                                                .GetAppLaunchUrl(params.app_id)
                                                .DeprecatedGetOriginAsURL() ||
diff --git a/chrome/browser/ui/web_applications/test/system_web_app_interactive_uitest.cc b/chrome/browser/ui/web_applications/test/system_web_app_interactive_uitest.cc
index bd83ea5..0a17ae7b 100644
--- a/chrome/browser/ui/web_applications/test/system_web_app_interactive_uitest.cc
+++ b/chrome/browser/ui/web_applications/test/system_web_app_interactive_uitest.cc
@@ -144,11 +144,11 @@
 }
 
 // This test is flaky on MacOS with ASAN or DBG. https://crbug.com/1173317
-#if defined(OS_MAC) && (defined(ADDRESS_SANITIZER) || !defined(NDEBUG))
+#if BUILDFLAG(IS_MAC) && (defined(ADDRESS_SANITIZER) || !defined(NDEBUG))
 #define MAYBE_AnchorLinkClick DISABLED_AnchorLinkClick
 #else
 #define MAYBE_AnchorLinkClick AnchorLinkClick
-#endif  // OS_MAC && (ADDRESS_SANITIZER || !NDEBUG)
+#endif  // BUILDFLAG(IS_MAC) && (defined(ADDRESS_SANITIZER) || !defined(NDEBUG))
 IN_PROC_BROWSER_TEST_P(SystemWebAppLinkCaptureBrowserTest,
                        MAYBE_AnchorLinkClick) {
   WaitForTestSystemAppInstall();
diff --git a/chrome/browser/ui/web_applications/test/web_app_browsertest_util.cc b/chrome/browser/ui/web_applications/test/web_app_browsertest_util.cc
index 30f62c5..dfe72ac0 100644
--- a/chrome/browser/ui/web_applications/test/web_app_browsertest_util.cc
+++ b/chrome/browser/ui/web_applications/test/web_app_browsertest_util.cc
@@ -51,12 +51,12 @@
 #include "ui/base/models/menu_model.h"
 #include "ui/base/page_transition_types.h"
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #include <ImageIO/ImageIO.h>
 #import "skia/ext/skia_utils_mac.h"
 #endif
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 #include <windows.h>
 
 #include <shellapi.h>
@@ -83,7 +83,7 @@
 }  // namespace
 
 SkColor GetIconTopLeftColor(const base::FilePath& shortcut_path) {
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   base::FilePath icon_path =
       shortcut_path.AppendASCII("Contents/Resources/app.icns");
   base::ScopedCFTypeRef<CFDictionaryRef> empty_dict(
@@ -98,7 +98,7 @@
   SkBitmap bitmap = skia::CGImageToSkBitmap(cg_image);
   return bitmap.getColor(0, 0);
 #else
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   SHFILEINFO file_info = {0};
   if (SHGetFileInfo(shortcut_path.value().c_str(), FILE_ATTRIBUTE_NORMAL,
                     &file_info, sizeof(file_info),
diff --git a/chrome/browser/ui/web_applications/web_app_browsertest.cc b/chrome/browser/ui/web_applications/web_app_browsertest.cc
index 63d5a3f..878c248 100644
--- a/chrome/browser/ui/web_applications/web_app_browsertest.cc
+++ b/chrome/browser/ui/web_applications/web_app_browsertest.cc
@@ -95,11 +95,11 @@
 #include "chrome/browser/ui/ash/shelf/chrome_shelf_controller.h"
 #endif
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #include "ui/base/test/scoped_fake_nswindow_fullscreen.h"
 #endif
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 #include "base/test/test_reg_util_win.h"
 #include "base/win/windows_version.h"
 #include "chrome/browser/web_applications/web_app_handler_registration_utils_win.h"
@@ -143,7 +143,7 @@
   return popup_browser;
 }
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 std::vector<std::wstring> GetFileExtensionsForProgId(
     const std::wstring& file_handler_prog_id) {
   const std::wstring prog_id_path =
@@ -161,7 +161,7 @@
                            base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
 }
 
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 
 }  // namespace
 
@@ -244,13 +244,13 @@
 };
 
 // TODO(crbug.com/1257751): Stabilize the test.
-#if defined(OS_POSIX)
+#if BUILDFLAG(IS_POSIX)
 #define DISABLE_POSIX(TEST) DISABLED_##TEST
 #else
 #define DISABLE_POSIX(TEST) TEST
 #endif
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 using WebAppBrowserTest_ShortcutMenu = WebAppBrowserTest;
 #endif
 
@@ -403,7 +403,7 @@
 }
 
 // Check the 'App info' menu button for web app windows.
-#if defined(OS_LINUX)
+#if BUILDFLAG(IS_LINUX)
 // Disabled on Linux because the test only completes unless unrelated
 // events are received to wake up the message loop.
 #define MAYBE_AppInfoOpensPageInfo DISABLED_AppInfoOpensPageInfo
@@ -616,7 +616,7 @@
 // Tests that using window.open to create a popup window out of scope results in
 // a correctly sized window.
 // TODO(crbug.com/1234260): Stabilize the test.
-#if defined(OS_LINUX)
+#if BUILDFLAG(IS_LINUX)
 #define MAYBE_OffScopePWAPopupsHaveCorrectSize \
   DISABLED_OffScopePWAPopupsHaveCorrectSize
 #else
@@ -661,7 +661,7 @@
 // Tests that using window.open to create a popup window in scope results in
 // a correctly sized window.
 // TODO(crbug.com/1234260): Stabilize the test.
-#if defined(OS_LINUX)
+#if BUILDFLAG(IS_LINUX)
 #define MAYBE_InScopePWAPopupsHaveCorrectSize \
   DISABLED_InScopePWAPopupsHaveCorrectSize
 #else
@@ -818,7 +818,7 @@
 
 // Tests that PWA menus have an uninstall option.
 // TODO(crbug.com/1271118): Flaky on mac arm64.
-#if defined(OS_MAC) && defined(ARCH_CPU_ARM64)
+#if BUILDFLAG(IS_MAC) && defined(ARCH_CPU_ARM64)
 #define MAYBE_UninstallMenuOption DISABLED_UninstallMenuOption
 #else
 #define MAYBE_UninstallMenuOption UninstallMenuOption
@@ -835,7 +835,7 @@
   int index = -1;
   const bool found = app_menu_model->GetModelAndIndexForCommandId(
       WebAppMenuModel::kUninstallAppCommandId, &model, &index);
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   EXPECT_FALSE(found);
 #else
   EXPECT_TRUE(found);
@@ -848,7 +848,7 @@
                             MENU_ACTION_UNINSTALL_APP, 1);
   tester.ExpectUniqueSample("WrenchMenu.MenuAction", MENU_ACTION_UNINSTALL_APP,
                             1);
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 }
 
 // Tests that both installing a PWA and creating a shortcut app are disabled for
@@ -1065,7 +1065,7 @@
   ASSERT_EQ(app_browser->app_controller()->app_id(), app_id);
 }
 
-#if defined(OS_MAC) || defined(OS_WIN)
+#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
 IN_PROC_BROWSER_TEST_F(WebAppBrowserTest,
                        DISABLE_POSIX(ShortcutIconCorrectColor)) {
   os_hooks_suppress_.reset();
@@ -1094,10 +1094,10 @@
   base::FilePath shortcut_path;
   auto* provider = WebAppProvider::GetForTest(profile());
   std::vector<SkColor> expected_pixel_colors = {SkColorSetRGB(92, 92, 92)};
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   shortcut_path = shortcut_override->chrome_apps_folder.GetPath().Append(
       provider->registrar().GetAppShortName(app_id) + ".app");
-#elif defined(OS_WIN)
+#elif BUILDFLAG(IS_WIN)
   shortcut_path = shortcut_override->application_menu.GetPath().AppendASCII(
       provider->registrar().GetAppShortName(app_id) + ".lnk");
   expected_pixel_colors.push_back(SkColorSetRGB(91, 91, 91));
@@ -1121,7 +1121,7 @@
 }
 #endif
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 IN_PROC_BROWSER_TEST_F(WebAppBrowserTest_ShortcutMenu, ShortcutsMenu) {
   struct ShortcutsMenuItem {
    public:
@@ -1210,7 +1210,7 @@
 }
 #endif
 
-#if defined(OS_MAC) || defined(OS_WIN) || defined(OS_LINUX)
+#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX)
 IN_PROC_BROWSER_TEST_F(WebAppBrowserTest, WebAppCreateAndDeleteShortcut) {
   os_hooks_suppress_.reset();
 
@@ -1239,7 +1239,7 @@
   EXPECT_EQ(provider->registrar().GetAppShortName(app_id),
             GetInstallableAppName());
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
   std::wstring shortcut_filename = converter.from_bytes(
       provider->registrar().GetAppShortName(app_id) + ".lnk");
@@ -1249,13 +1249,13 @@
       shortcut_override->application_menu.GetPath().Append(shortcut_filename);
   EXPECT_TRUE(base::PathExists(desktop_shortcut_path));
   EXPECT_TRUE(base::PathExists(app_menu_shortcut_path));
-#elif defined(OS_MAC)
+#elif BUILDFLAG(IS_MAC)
   std::string shortcut_filename =
       provider->registrar().GetAppShortName(app_id) + ".app";
   base::FilePath app_shortcut_path =
       shortcut_override->chrome_apps_folder.GetPath().Append(shortcut_filename);
   EXPECT_TRUE(base::PathExists(app_shortcut_path));
-#elif defined(OS_LINUX)
+#elif BUILDFLAG(IS_LINUX)
   std::string shortcut_filename = "chrome-" + app_id + "-Default.desktop";
   base::FilePath desktop_shortcut_path =
       shortcut_override->desktop.GetPath().Append(shortcut_filename);
@@ -1272,12 +1272,12 @@
       }));
   run_loop_uninstall.Run();
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   EXPECT_FALSE(base::PathExists(desktop_shortcut_path));
   EXPECT_FALSE(base::PathExists(app_menu_shortcut_path));
-#elif defined(OS_MAC)
+#elif BUILDFLAG(IS_MAC)
   EXPECT_FALSE(base::PathExists(app_shortcut_path));
-#elif defined(OS_LINUX)
+#elif BUILDFLAG(IS_LINUX)
   EXPECT_FALSE(base::PathExists(desktop_shortcut_path));
 #endif
 }  // namespace web_app
@@ -1547,7 +1547,7 @@
       EvalJs(subframe, "document.body.innerText.trim();").ExtractString());
 }
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 
 IN_PROC_BROWSER_TEST_F(WebAppBrowserTest, NewAppWindow) {
   BrowserList* const browser_list = BrowserList::GetInstance();
@@ -1579,7 +1579,7 @@
 #endif
 
 IN_PROC_BROWSER_TEST_F(WebAppBrowserTest, PopupLocationBar) {
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   ui::test::ScopedFakeNSWindowFullscreen fake_fullscreen;
 #endif
   const GURL app_url = GetSecureAppURL();
@@ -1781,7 +1781,7 @@
       app_id);
 }
 
-#if defined(OS_MAC) || defined(OS_WIN)
+#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
 class WebAppBrowserTest_FileHandler : public WebAppBrowserTest {
  public:
   WebAppBrowserTest_FileHandler() {
@@ -1804,7 +1804,7 @@
 };
 
 // TODO(crbug.com/1270961): Flaky on Win and Mac.
-#if defined(OS_WIN) || defined(OS_MAC)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
 #define MAYBE_WebAppFileHandler DISABLED_WebAppFileHandler
 #else
 #define MAYBE_WebAppFileHandler WebAppFileHandler
@@ -1835,7 +1835,7 @@
   content::RunAllTasksUntilIdle();
   chrome::SetAutoAcceptWebAppDialogForTesting(false, false);
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   const std::wstring prog_id =
       GetProgIdForApp(browser()->profile()->GetPath(), app_id);
   const std::vector<std::wstring> file_handler_prog_ids =
@@ -1863,7 +1863,7 @@
       EXPECT_TRUE(key.HasValue(file_handler_prog_id.data()));
     }
   }
-#elif defined(OS_MAC)
+#elif BUILDFLAG(IS_MAC)
   std::vector<GURL> test_file_urls;
   for (auto extension : expected_extensions) {
     const base::FilePath test_file_path =
@@ -1914,7 +1914,7 @@
       }));
   run_loop_uninstall.Run();
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   // Check file associations after the web app is uninstalled.
 
   // Check that HKCU/Software Classes/<filext>/ doesn't have the ProgId.
diff --git a/chrome/browser/ui/web_applications/web_app_launch_manager_unittest.cc b/chrome/browser/ui/web_applications/web_app_launch_manager_unittest.cc
index 3ed6218..787ada0 100644
--- a/chrome/browser/ui/web_applications/web_app_launch_manager_unittest.cc
+++ b/chrome/browser/ui/web_applications/web_app_launch_manager_unittest.cc
@@ -40,12 +40,12 @@
               (override));
 };
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 const base::FilePath::CharType kCurrentDirectory[] =
     FILE_PATH_LITERAL("\\path");
 #else
 const base::FilePath::CharType kCurrentDirectory[] = FILE_PATH_LITERAL("/path");
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 
 const char kTestAppId[] = "test_app_id";
 
diff --git a/chrome/browser/ui/web_applications/web_app_launch_process.cc b/chrome/browser/ui/web_applications/web_app_launch_process.cc
index 1b5b78c..a696b1e5 100644
--- a/chrome/browser/ui/web_applications/web_app_launch_process.cc
+++ b/chrome/browser/ui/web_applications/web_app_launch_process.cc
@@ -34,7 +34,7 @@
 #include "ui/display/scoped_display_for_new_windows.h"
 #include "url/gurl.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 #include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h"
 #endif
 
@@ -82,7 +82,7 @@
   bool is_file_handling = false;
   std::tie(launch_url, is_file_handling) = GetLaunchUrl(share_target);
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   // TODO(crbug.com/1265381): URL Handlers allows web apps to be opened with
   // associated origin URLs. There's no utility function to test whether a URL
   // is in a web app's extended scope at the moment.
diff --git a/chrome/browser/ui/web_applications/web_app_link_capturing_browsertest.cc b/chrome/browser/ui/web_applications/web_app_link_capturing_browsertest.cc
index 0d9c628..6c0e3f82 100644
--- a/chrome/browser/ui/web_applications/web_app_link_capturing_browsertest.cc
+++ b/chrome/browser/ui/web_applications/web_app_link_capturing_browsertest.cc
@@ -407,7 +407,7 @@
 }
 
 // TODO(crbug.com/1185680): Flaky on Linux and lacros.
-#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
 #define MAYBE_CaptureLinksNewClient DISABLED_CaptureLinksNewClient
 #else
 #define MAYBE_CaptureLinksNewClient CaptureLinksNewClient
diff --git a/chrome/browser/ui/web_applications/web_app_menu_model.cc b/chrome/browser/ui/web_applications/web_app_menu_model.cc
index 633a6db..29e159f 100644
--- a/chrome/browser/ui/web_applications/web_app_menu_model.cc
+++ b/chrome/browser/ui/web_applications/web_app_menu_model.cc
@@ -127,7 +127,7 @@
 
 // Chrome OS's app list is prominent enough to not need a separate uninstall
 // option in the app menu.
-#if !defined(OS_CHROMEOS)
+#if !BUILDFLAG(IS_CHROMEOS)
   DCHECK(browser()->app_controller());
   if (browser()->app_controller()->IsInstalled()) {
     AddSeparator(ui::NORMAL_SEPARATOR);
@@ -137,7 +137,7 @@
                 ui::EscapeMenuLabelAmpersands(
                     browser()->app_controller()->GetAppShortName())));
   }
-#endif  // !defined(OS_CHROMEOS)
+#endif  // !BUILDFLAG(IS_CHROMEOS)
   AddSeparator(ui::LOWER_SEPARATOR);
 
   CreateZoomMenu();
diff --git a/chrome/browser/ui/web_applications/web_app_profile_deletion_browsertest.cc b/chrome/browser/ui/web_applications/web_app_profile_deletion_browsertest.cc
index 7cdb428..8cc78cb 100644
--- a/chrome/browser/ui/web_applications/web_app_profile_deletion_browsertest.cc
+++ b/chrome/browser/ui/web_applications/web_app_profile_deletion_browsertest.cc
@@ -33,7 +33,7 @@
 };
 
 // Flaky on Windows: https://crbug.com/1247547.
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 #define MAYBE_AppRegistrarNotifiesProfileDeletion \
   DISABLED_AppRegistrarNotifiesProfileDeletion
 #else
diff --git a/chrome/browser/ui/web_applications/web_app_ui_manager_impl.cc b/chrome/browser/ui/web_applications/web_app_ui_manager_impl.cc
index ea4099f..1b09875 100644
--- a/chrome/browser/ui/web_applications/web_app_ui_manager_impl.cc
+++ b/chrome/browser/ui/web_applications/web_app_ui_manager_impl.cc
@@ -50,7 +50,7 @@
 #include "chrome/browser/ui/ash/shelf/chrome_shelf_controller_util.h"
 #endif
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 #include "base/process/process.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/ui/browser_list.h"
@@ -58,7 +58,7 @@
 #include "components/keep_alive_registry/keep_alive_types.h"
 #include "components/keep_alive_registry/scoped_keep_alive.h"
 #include "ui/gfx/native_widget_types.h"
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 
 namespace web_app {
 
@@ -74,7 +74,7 @@
   return installed;
 }
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 // ScopedKeepAlive not only keeps the process from terminating early
 // during uninstall, it also ensures the process will terminate when it
 // is destroyed if there is no active browser window.
@@ -107,7 +107,7 @@
   }
 }
 
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 
 DisplayMode GetExtensionDisplayMode(Profile* profile,
                                     const extensions::Extension* extension) {
@@ -395,7 +395,7 @@
 bool WebAppUiManagerImpl::CanReparentAppTabToWindow(
     const AppId& app_id,
     bool shortcut_created) const {
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   // On macOS it is only possible to reparent the window when the shortcut (app
   // shim) was created. See https://crbug.com/915571.
   return shortcut_created;
@@ -474,7 +474,7 @@
   windows_closed_requests_map_.erase(app_id);
 }
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 void WebAppUiManagerImpl::UninstallWebAppFromStartupSwitch(
     const AppId& app_id) {
   WebAppProvider* provider = WebAppProvider::GetForWebApps(profile_);
@@ -482,7 +482,7 @@
       FROM_HERE, base::BindOnce(&UninstallWebAppWithDialogFromStartupSwitch,
                                 app_id, profile_, provider));
 }
-#endif  //  defined(OS_WIN)
+#endif  //  BUILDFLAG(IS_WIN)
 
 bool WebAppUiManagerImpl::IsBrowserForInstalledApp(Browser* browser) {
   if (browser->profile() != profile_)
diff --git a/chrome/browser/ui/web_applications/web_app_ui_manager_impl.h b/chrome/browser/ui/web_applications/web_app_ui_manager_impl.h
index 09ebb95..8940e03 100644
--- a/chrome/browser/ui/web_applications/web_app_ui_manager_impl.h
+++ b/chrome/browser/ui/web_applications/web_app_ui_manager_impl.h
@@ -80,7 +80,7 @@
   void OnBrowserAdded(Browser* browser) override;
   void OnBrowserRemoved(Browser* browser) override;
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   // Attempts to uninstall the given web app id. Meant to be used with OS-level
   // uninstallation support/hooks.
   void UninstallWebAppFromStartupSwitch(const AppId& app_id);
diff --git a/chrome/browser/ui/webauthn/authenticator_dialog_browsertest.cc b/chrome/browser/ui/webauthn/authenticator_dialog_browsertest.cc
index fa80b2a..8bda4d0d 100644
--- a/chrome/browser/ui/webauthn/authenticator_dialog_browsertest.cc
+++ b/chrome/browser/ui/webauthn/authenticator_dialog_browsertest.cc
@@ -299,7 +299,7 @@
   ShowAndVerifyUi();
 }
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 IN_PROC_BROWSER_TEST_F(AuthenticatorDialogTest, InvokeUi_touchid) {
   ShowAndVerifyUi();
 }
@@ -307,7 +307,7 @@
 IN_PROC_BROWSER_TEST_F(AuthenticatorDialogTest, InvokeUi_touchid_incognito) {
   ShowAndVerifyUi();
 }
-#endif  // defined(OS_MAC)
+#endif  // BUILDFLAG(IS_MAC)
 
 IN_PROC_BROWSER_TEST_F(AuthenticatorDialogTest, InvokeUi_cable_activate) {
   ShowAndVerifyUi();
diff --git a/chrome/browser/ui/webid/identity_dialog_controller.cc b/chrome/browser/ui/webid/identity_dialog_controller.cc
index ceb6b4f..895cebdf 100644
--- a/chrome/browser/ui/webid/identity_dialog_controller.cc
+++ b/chrome/browser/ui/webid/identity_dialog_controller.cc
@@ -113,7 +113,7 @@
     AccountSelectionCallback on_selected) {
   // IDP scheme is expected to always be `https://`.
   CHECK(idp_url.SchemeIs(url::kHttpsScheme));
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
   std::move(on_selected)
       .Run(accounts[0].account_id,
            accounts[0].login_state ==
diff --git a/chrome/browser/ui/webui/about_ui.cc b/chrome/browser/ui/webui/about_ui.cc
index e259e360..ef4eceb 100644
--- a/chrome/browser/ui/webui/about_ui.cc
+++ b/chrome/browser/ui/webui/about_ui.cc
@@ -54,7 +54,7 @@
 #include "ui/base/webui/web_ui_util.h"
 #include "url/gurl.h"
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 #include "chrome/browser/ui/webui/theme_source.h"
 #endif
 
@@ -82,10 +82,10 @@
 #include "chrome/browser/lacros/lacros_url_handling.h"
 #endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 #include "chrome/common/webui_url_constants.h"
 #include "ui/base/l10n/l10n_util.h"
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
 using content::BrowserThread;
 
@@ -508,7 +508,7 @@
   }
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 // This function returns true if Lacros is the primary browser - or if the
 // calling browser is Lacros.
 bool isLacrosPrimaryOrCurrentBrowser() {
@@ -552,7 +552,7 @@
   output->append("</body>\n</html>\n");
 }
 
-#else  // !defined(OS_CHROMEOS)
+#else  // BUILDFLAG(IS_CHROMEOS)
 
 void AppendBody(std::string *output) {
   output->append("</head>\n<body>\n");
@@ -562,7 +562,7 @@
   output->append("</body>\n</html>\n");
 }
 
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
 }  // namespace about_ui
 
@@ -656,7 +656,7 @@
   return html;
 }
 
-#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_OPENBSD)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_OPENBSD)
 std::string AboutLinuxProxyConfig() {
   std::string data;
   AppendHeader(&data,
@@ -712,7 +712,7 @@
       response =
           ui::ResourceBundle::GetSharedInstance().LoadDataResourceString(idr);
     }
-#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_OPENBSD)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_OPENBSD)
   } else if (source_name_ == chrome::kChromeUILinuxProxyConfigHost) {
     response = AboutLinuxProxyConfig();
 #endif
@@ -724,7 +724,7 @@
     CrostiniCreditsHandler::Start(profile(), path, std::move(callback));
     return;
 #endif
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
   } else if (source_name_ == chrome::kChromeUITermsHost) {
 #if BUILDFLAG(IS_CHROMEOS_ASH)
     if (!path.empty()) {
@@ -786,7 +786,7 @@
     : WebUIController(web_ui) {
   Profile* profile = Profile::FromWebUI(web_ui);
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
   // Set up the chrome://theme/ source.
   content::URLDataSource::Add(profile, std::make_unique<ThemeSource>(profile));
 #endif
@@ -795,7 +795,7 @@
       profile, std::make_unique<AboutUIHTMLSource>(name, profile));
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 
 bool AboutUI::OverrideHandleWebUIMessage(const GURL& source_url,
                                          const std::string& message,
@@ -813,4 +813,4 @@
   return true;
 }
 
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
diff --git a/chrome/browser/ui/webui/about_ui.h b/chrome/browser/ui/webui/about_ui.h
index 782a1d7..f4b1045 100644
--- a/chrome/browser/ui/webui/about_ui.h
+++ b/chrome/browser/ui/webui/about_ui.h
@@ -8,6 +8,7 @@
 #include <string>
 
 #include "base/memory/raw_ptr.h"
+#include "build/build_config.h"
 #include "content/public/browser/url_data_source.h"
 #include "content/public/browser/web_ui_controller.h"
 
@@ -56,7 +57,7 @@
 
   ~AboutUI() override = default;
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   bool OverrideHandleWebUIMessage(const GURL& source_url,
                                   const std::string& message,
                                   const base::ListValue& args) override;
diff --git a/chrome/browser/ui/webui/app_launcher_page_ui.cc b/chrome/browser/ui/webui/app_launcher_page_ui.cc
index a3aa1c9..5280b80 100644
--- a/chrome/browser/ui/webui/app_launcher_page_ui.cc
+++ b/chrome/browser/ui/webui/app_launcher_page_ui.cc
@@ -45,7 +45,7 @@
 #include "ui/base/webui/web_ui_util.h"
 #include "ui/gfx/animation/animation.h"
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #include "chrome/browser/platform_util.h"
 #endif
 
@@ -129,7 +129,7 @@
                         .spec());
 
   bool is_swipe_tracking_from_scroll_events_enabled = false;
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   // On Mac OS X 10.7+, horizontal scrolling can be treated as a back or
   // forward gesture. Pass through a flag that indicates whether or not that
   // feature is enabled.
diff --git a/chrome/browser/ui/webui/app_management/app_management_page_handler.cc b/chrome/browser/ui/webui/app_management/app_management_page_handler.cc
index 853d24c..ded86a1 100644
--- a/chrome/browser/ui/webui/app_management/app_management_page_handler.cc
+++ b/chrome/browser/ui/webui/app_management/app_management_page_handler.cc
@@ -11,6 +11,7 @@
 #include "base/containers/flat_map.h"
 #include "base/containers/flat_set.h"
 #include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
 #include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
@@ -42,12 +43,12 @@
 
 namespace {
 
-constexpr char const* kAppIdsWithHiddenMoreSettings[] = {
+const char* kAppIdsWithHiddenMoreSettings[] = {
     extensions::kWebStoreAppId,
     extension_misc::kFilesManagerAppId,
 };
 
-constexpr char const* kAppIdsWithHiddenPinToShelf[] = {
+const char* kAppIdsWithHiddenPinToShelf[] = {
     extension_misc::kChromeAppId,
     extension_misc::kLacrosAppId,
 };
@@ -265,7 +266,7 @@
 void AppManagementPageHandler::SetWindowMode(
     const std::string& app_id,
     apps::mojom::WindowMode window_mode) {
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   NOTREACHED();
 #else
   apps::AppServiceProxyFactory::GetForProfile(profile_)->SetWindowMode(
diff --git a/chrome/browser/ui/webui/certificates_handler.cc b/chrome/browser/ui/webui/certificates_handler.cc
index d3011b0..6c87b7f 100644
--- a/chrome/browser/ui/webui/certificates_handler.cc
+++ b/chrome/browser/ui/webui/certificates_handler.cc
@@ -1150,11 +1150,11 @@
 }
 
 bool CertificatesHandler::IsClientCertificateManagementAllowed(Slot slot) {
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   if (!IsClientCertificateManagementAllowedPolicy(slot)) {
     return false;
   }
-#endif  //  defined(OS_CHROMEOS)
+#endif  //  BUILDFLAG(IS_CHROMEOS)
 
   return ShouldDisplayClientCertificates();
 }
@@ -1170,13 +1170,13 @@
   if (!Profile::FromWebUI(web_ui())->IsMainProfile()) {
     return false;
   }
-#endif  // #if BUILDFLAG(IS_CHROMEOS_LACROS)
+#endif
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   if (!IsCACertificateManagementAllowedPolicy(source)) {
     return false;
   }
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
   return true;
 }
@@ -1194,7 +1194,7 @@
   return true;
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 bool CertificatesHandler::IsClientCertificateManagementAllowedPolicy(
     Slot slot) {
   Profile* profile = Profile::FromWebUI(web_ui());
@@ -1244,7 +1244,7 @@
       return policy_value != CACertificateManagementPermission::kNone;
   }
 }
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
 bool CertificatesHandler::CanDeleteCertificate(
     const CertificateManagerModel::CertInfo* cert_info) {
@@ -1281,7 +1281,7 @@
   return IsCACertificateManagementAllowed(source);
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 void CertificatesHandler::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   // Allow users to manage all client certificates by default. This can be
@@ -1296,6 +1296,6 @@
       prefs::kCACertificateManagementAllowed,
       static_cast<int>(CACertificateManagementPermission::kAll));
 }
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
 }  // namespace certificate_manager
diff --git a/chrome/browser/ui/webui/certificates_handler.h b/chrome/browser/ui/webui/certificates_handler.h
index 3bdebe54..395c32c 100644
--- a/chrome/browser/ui/webui/certificates_handler.h
+++ b/chrome/browser/ui/webui/certificates_handler.h
@@ -11,6 +11,7 @@
 #include "base/containers/id_map.h"
 #include "base/memory/weak_ptr.h"
 #include "base/task/cancelable_task_tracker.h"
+#include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/certificate_manager_model.h"
 #include "content/public/browser/web_ui_message_handler.h"
@@ -76,10 +77,10 @@
                     void* params) override;
   void FileSelectionCanceled(void* params) override;
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   // Register profile preferences.
   static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
  private:
   // View certificate.
@@ -212,7 +213,7 @@
   // Returns true if the user may manage CA certificates.
   bool IsCACertificateManagementAllowed(CertificateSource source);
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   // Returns true if the user may manage certificates on |slot| according
   // to ClientCertificateManagementAllowed policy.
   bool IsClientCertificateManagementAllowedPolicy(Slot slot);
@@ -220,7 +221,7 @@
   // Returns true if the user may manage certificates according
   // to CACertificateManagementAllowed policy.
   bool IsCACertificateManagementAllowedPolicy(CertificateSource source);
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
   // Returns true if the certificate represented by |cert_info| can be deleted.
   bool CanDeleteCertificate(const CertificateManagerModel::CertInfo* cert_info);
diff --git a/chrome/browser/ui/webui/certificates_handler_unittest.cc b/chrome/browser/ui/webui/certificates_handler_unittest.cc
index e195c628..a3535e4c 100644
--- a/chrome/browser/ui/webui/certificates_handler_unittest.cc
+++ b/chrome/browser/ui/webui/certificates_handler_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/ui/webui/certificates_handler.h"
 
+#include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
@@ -22,11 +23,11 @@
     pref_service_ = profile()->GetTestingPrefService();
   }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   bool IsCACertificateManagementAllowedPolicy(CertificateSource source) {
     return cert_handler_.IsCACertificateManagementAllowedPolicy(source);
   }
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
   bool CanDeleteCertificate(
       const CertificateManagerModel::CertInfo* cert_info) {
@@ -43,7 +44,7 @@
   sync_preferences::TestingPrefServiceSyncable* pref_service_ = nullptr;
 };
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 TEST_F(CertificateHandlerTest, IsCACertificateManagementAllowedPolicyTest) {
   {
     pref_service_->SetInteger(
@@ -78,7 +79,7 @@
         IsCACertificateManagementAllowedPolicy(CertificateSource::kBuiltIn));
   }
 }
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
 TEST_F(CertificateHandlerTest, CanDeleteCertificateCommonTest) {
   CertificateManagerModel::CertInfo default_cert_info(
@@ -126,7 +127,7 @@
     EXPECT_TRUE(CanDeleteCertificate(&cert_info));
   }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   {
     pref_service_->SetInteger(
         prefs::kClientCertificateManagementAllowed,
@@ -162,7 +163,7 @@
     cert_info.device_wide_ = true;
     EXPECT_FALSE(CanDeleteCertificate(&cert_info));
   }
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 }
 
 TEST_F(CertificateHandlerTest, CanDeleteCACertificateTest) {
@@ -180,7 +181,7 @@
     EXPECT_TRUE(CanDeleteCertificate(&cert_info));
   }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   {
     pref_service_->SetInteger(
         prefs::kCACertificateManagementAllowed,
@@ -215,7 +216,7 @@
     cert_info.can_be_deleted_ = true;
     EXPECT_FALSE(CanDeleteCertificate(&cert_info));
   }
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 }
 
 TEST_F(CertificateHandlerTest, CanEditCertificateCommonTest) {
@@ -259,7 +260,7 @@
     EXPECT_FALSE(CanEditCertificate(&cert_info));
   }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   {
     pref_service_->SetInteger(
         prefs::kClientCertificateManagementAllowed,
@@ -295,7 +296,7 @@
     cert_info.device_wide_ = true;
     EXPECT_FALSE(CanEditCertificate(&cert_info));
   }
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 }
 
 TEST_F(CertificateHandlerTest, CanEditCACertificateTest) {
@@ -313,7 +314,7 @@
     EXPECT_TRUE(CanEditCertificate(&cert_info));
   }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   {
     pref_service_->SetInteger(
         prefs::kCACertificateManagementAllowed,
@@ -349,7 +350,7 @@
     cert_info.can_be_deleted_ = true;
     EXPECT_FALSE(CanEditCertificate(&cert_info));
   }
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 }
 
 
diff --git a/chrome/browser/ui/webui/chrome_untrusted_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_untrusted_web_ui_controller_factory.cc
index 0fafe54..78d2b6e 100644
--- a/chrome/browser/ui/webui/chrome_untrusted_web_ui_controller_factory.cc
+++ b/chrome/browser/ui/webui/chrome_untrusted_web_ui_controller_factory.cc
@@ -21,9 +21,9 @@
 #include "chrome/browser/ui/webui/print_preview/print_preview_ui_untrusted.h"
 #endif  // BUILDFLAG(ENABLE_PRINT_PREVIEW)
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 #include "chrome/browser/ui/webui/video_tutorials/video_player_ui.h"
-#endif  // defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_ANDROID)
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "ash/constants/ash_features.h"
@@ -52,23 +52,22 @@
 // constructing from a vector is O(n log n).
 WebUIConfigList CreateConfigs() {
   WebUIConfigList config_list;
-  auto register_config =
+  // Delete [[maybe_unused]] once register_config is used outside of Chrome OS.
+  [[maybe_unused]] auto register_config =
       [&config_list](std::unique_ptr<ui::WebUIConfig> config) {
         DCHECK_EQ(config->scheme(), content::kChromeUIUntrustedScheme);
         const std::string& host = config->host();
         config_list.emplace_back(host, std::move(config));
       };
-  // Delete once register_config is used outside of Chrome OS.
-  ALLOW_UNUSED_LOCAL(register_config);
 
   // Register WebUIConfigs below.
 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
   register_config(std::make_unique<printing::PrintPreviewUIUntrustedConfig>());
 #endif  // BUILDFLAG(ENABLE_PRINT_PREVIEW)
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   register_config(std::make_unique<video_tutorials::VideoPlayerUIConfig>());
-#endif  // defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_ANDROID)
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   register_config(std::make_unique<CroshUIConfig>());
diff --git a/chrome/browser/ui/webui/chrome_url_data_manager_browsertest.cc b/chrome/browser/ui/webui/chrome_url_data_manager_browsertest.cc
index 8e796e07..01187d1e 100644
--- a/chrome/browser/ui/webui/chrome_url_data_manager_browsertest.cc
+++ b/chrome/browser/ui/webui/chrome_url_data_manager_browsertest.cc
@@ -286,7 +286,7 @@
     "chrome://web-app-internals",
     "chrome://webrtc-internals",
     "chrome://webrtc-logs",
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
     "chrome://explore-sites-internals",
     "chrome://internals/notifications",
     "chrome://internals/query-tiles",
@@ -329,7 +329,7 @@
     "chrome://sys-internals",
     "chrome-untrusted://terminal",
 #endif
-#if !defined(OS_CHROMEOS)
+#if !BUILDFLAG(IS_CHROMEOS)
     "chrome://apps",
     "chrome://browser-switch",
     "chrome://welcome",
@@ -337,13 +337,13 @@
 #if !BUILDFLAG(IS_CHROMEOS_ASH)
     "chrome://signin-email-confirmation",
 #endif
-#if !defined(OS_MAC)
+#if !BUILDFLAG(IS_MAC)
     "chrome://sandbox",
     "chrome://nacl",
     // TODO(https://crbug.com/1219651): this test is flaky on mac.
     "chrome://bluetooth-internals",
 #endif
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
     "chrome://conflicts",
 #endif
 };
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
index 33fe45e..f31c3a1 100644
--- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
+++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -111,14 +111,14 @@
 #include "chrome/browser/ui/webui/tab_strip/tab_strip_ui.h"
 #endif
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 #include "chrome/browser/ui/webui/explore_sites_internals/explore_sites_internals_ui.h"
 #include "chrome/browser/ui/webui/feed_internals/feed_internals_ui.h"
 #include "chrome/browser/ui/webui/offline/offline_internals_ui.h"
 #include "chrome/browser/ui/webui/webapks/webapks_ui.h"
 #include "components/feed/buildflags.h"
 #include "components/feed/feed_feature_list.h"
-#else  // defined(OS_ANDROID)
+#else  // BUILDFLAG(IS_ANDROID)
 #include "chrome/browser/media/router/media_router_feature.h"
 #include "chrome/browser/ui/ui_features.h"
 #include "chrome/browser/ui/webui/access_code_cast/access_code_cast_ui.h"
@@ -149,7 +149,7 @@
 #include "chrome/browser/ui/webui/tab_search/tab_search_ui.h"
 #include "chrome/browser/ui/webui/whats_new/whats_new_ui.h"
 #include "media/base/media_switches.h"
-#endif  // defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_ANDROID)
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "ash/constants/ash_features.h"
@@ -262,7 +262,7 @@
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #endif
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 #include "chromeos/crosapi/cpp/gurl_os_handler_utils.h"
 #include "url/url_util.h"
 #endif
@@ -275,25 +275,25 @@
 #include "chrome/browser/ui/webui/chromeos/emulator/device_emulator_ui.h"
 #endif
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 #include "chrome/browser/ui/webui/chromeos/chrome_url_disabled/chrome_url_disabled_ui.h"
 #endif
 
-#if !defined(OS_CHROMEOS)
+#if !BUILDFLAG(IS_CHROMEOS)
 #include "chrome/browser/ui/webui/app_launcher_page_ui.h"
 #endif
 
-#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
 #include "chrome/browser/ui/webui/webui_js_error/webui_js_error_ui.h"
 #endif
 
-#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_CHROMEOS) && !BUILDFLAG(IS_ANDROID)
 #include "chrome/browser/ui/webui/browser_switch/browser_switch_ui.h"
 #include "chrome/browser/ui/webui/welcome/helpers.h"
 #include "chrome/browser/ui/webui/welcome/welcome_ui.h"
 #endif
 
-#if !BUILDFLAG(IS_CHROMEOS_ASH) && !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_ANDROID)
 #include "chrome/browser/ui/sync/sync_promo_ui.h"
 #include "chrome/browser/ui/webui/signin/enterprise_profile_welcome_ui.h"
 #include "chrome/browser/ui/webui/signin/profile_customization_ui.h"
@@ -302,21 +302,21 @@
 #include "chrome/browser/ui/webui/signin/signin_error_ui.h"
 #endif
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 #include "chrome/browser/ui/webui/conflicts/conflicts_ui.h"
 #endif
 
-#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) || \
-    defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \
+    BUILDFLAG(IS_CHROMEOS)
 #include "chrome/browser/ui/webui/discards/discards_ui.h"
 #endif
 
-#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS) || \
-    defined(OS_ANDROID)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \
+    BUILDFLAG(IS_ANDROID)
 #include "chrome/browser/ui/webui/sandbox/sandbox_internals_ui.h"
 #endif
 
-#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) || \
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \
     BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/ui/webui/connectors_internals/connectors_internals_ui.h"
 #endif
@@ -389,7 +389,7 @@
   return new WEB_UI_CONTROLLER(web_ui, std::move(delegate));
 }
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 template <>
 WebUIController* NewWebUI<PageNotAvailableForGuestUI>(WebUI* web_ui,
                                                       const GURL& url) {
@@ -602,15 +602,15 @@
 WebUIController* NewWebUI<WelcomeUI>(WebUI* web_ui, const GURL& url) {
   return new WelcomeUI(web_ui, url);
 }
-#endif  // !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
+#endif  // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
 
 bool IsAboutUI(const GURL& url) {
   return (url.host_piece() == chrome::kChromeUIChromeURLsHost ||
           url.host_piece() == chrome::kChromeUICreditsHost
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
           || url.host_piece() == chrome::kChromeUITermsHost
 #endif
-#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_OPENBSD)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_OPENBSD)
           || url.host_piece() == chrome::kChromeUILinuxProxyConfigHost
 #endif
 #if BUILDFLAG(IS_CHROMEOS_ASH)
@@ -648,10 +648,10 @@
   if (url.host_piece() == chrome::kChromeUIAutofillInternalsHost)
     return &NewWebUI<AutofillInternalsUI>;
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   if (url.host_piece() == chrome::kChromeUIAppDisabledHost)
     return &NewWebUI<chromeos::ChromeURLDisabledUI>;
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
   if (url.host_piece() == chrome::kChromeUIBluetoothInternalsHost)
     return &NewWebUI<BluetoothInternalsUI>;
@@ -723,15 +723,15 @@
   if (url.host_piece() == chrome::kChromeUIVersionHost)
     return &NewWebUI<VersionUI>;
 
-#if !defined(OS_ANDROID)
-#if !defined(OS_CHROMEOS)
+#if !BUILDFLAG(IS_ANDROID)
+#if !BUILDFLAG(IS_CHROMEOS)
   // AppLauncherPage is not needed on Android or ChromeOS.
   if (url.host_piece() == chrome::kChromeUIAppLauncherPageHost && profile &&
       extensions::ExtensionSystem::Get(profile)->extension_service() &&
       !profile->IsGuestSession()) {
     return &NewWebUI<AppLauncherPageUI>;
   }
-#endif  // !defined(OS_CHROMEOS)
+#endif  // !BUILDFLAG(IS_CHROMEOS)
   if (profile->IsGuestSession() &&
       (url.host_piece() == chrome::kChromeUIAppLauncherPageHost ||
        url.host_piece() == chrome::kChromeUIBookmarksHost ||
@@ -792,8 +792,8 @@
   if (base::FeatureList::IsEnabled(features::kSupportTool) &&
       url.host_piece() == chrome::kChromeUISupportToolHost)
     return &NewWebUI<SupportToolUI>;
-#endif  // !defined(OS_ANDROID)
-#if defined(OS_WIN)
+#endif  // !BUILDFLAG(IS_ANDROID)
+#if BUILDFLAG(IS_WIN)
   if (url.host_piece() == chrome::kChromeUIConflictsHost)
     return &NewWebUI<ConflictsUI>;
 #endif
@@ -1002,11 +1002,11 @@
     return &NewWebUI<ash::SampleSystemWebAppUI>;
 #endif  // !defined(OFFICIAL_BUILD)
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
-#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
   if (url.host_piece() == chrome::kChromeUIWebUIJsErrorHost)
     return &NewWebUI<WebUIJsErrorUI>;
 #endif
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   if (url.host_piece() == chrome::kChromeUIExploreSitesInternalsHost &&
       !profile->IsOffTheRecord())
     return &NewWebUI<explore_sites::ExploreSitesInternalsUI>;
@@ -1022,7 +1022,7 @@
   }
   if (url.host_piece() == chrome::kChromeUIWebApksHost)
     return &NewWebUI<WebApksUI>;
-#else  // !defined(OS_ANDROID)
+#else   // BUILDFLAG(IS_ANDROID)
   if (url.SchemeIs(content::kChromeDevToolsScheme)) {
     if (!DevToolsUIBindings::IsValidFrontendURL(url))
       return nullptr;
@@ -1040,8 +1040,8 @@
   if (url.host_piece() == chrome::kChromeUIImageEditorHost) {
     return &NewWebUI<image_editor::ImageEditorUI>;
   }
-#endif  // defined(OS_ANDROID)
-#if !BUILDFLAG(IS_CHROMEOS_ASH) && !defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_ANDROID)
+#if !BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_ANDROID)
   if (url.host_piece() == chrome::kChromeUIEnterpriseProfileWelcomeHost)
     return &NewWebUI<EnterpriseProfileWelcomeUI>;
   if (url.host_piece() == chrome::kChromeUIProfileCustomizationHost)
@@ -1060,7 +1060,8 @@
   if (url.host_piece() == chrome::kChromeUINaClHost)
     return &NewWebUI<NaClUI>;
 #endif
-#if ((defined(OS_LINUX) || defined(OS_CHROMEOS)) && defined(TOOLKIT_VIEWS)) || \
+#if ((BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)) && \
+     defined(TOOLKIT_VIEWS)) ||                         \
     defined(USE_AURA)
   if (url.host_piece() == chrome::kChromeUITabModalConfirmDialogHost)
     return &NewWebUI<ConstrainedWebDialogUI>;
@@ -1072,7 +1073,7 @@
 
   if (url.host_piece() == chrome::kChromeUIPolicyHost)
     return &NewWebUI<PolicyUI>;
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
   if (url.host_piece() == chrome::kChromeUIManagementHost)
     return &NewWebUI<ManagementUI>;
 #endif
@@ -1098,7 +1099,7 @@
 
   if (url.host_piece() == chrome::kChromeUIWebRtcLogsHost)
     return &NewWebUI<WebRtcLogsUI>;
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
   if (url.host_piece() == chrome::kChromeUICastFeedbackHost &&
       media_router::MediaRouterEnabled(profile)) {
@@ -1114,23 +1115,23 @@
     return &NewWebUI<media_router::MediaRouterInternalsUI>;
   }
 #endif
-#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS) || \
-    defined(OS_ANDROID)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \
+    BUILDFLAG(IS_ANDROID)
   if (url.host_piece() == chrome::kChromeUISandboxHost) {
     return &NewWebUI<SandboxInternalsUI>;
   }
 #endif
-#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) || \
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \
     BUILDFLAG(IS_CHROMEOS_ASH)
   if (url.host_piece() == chrome::kChromeUIConnectorsInternalsHost)
     return &NewWebUI<enterprise_connectors::ConnectorsInternalsUI>;
 #endif
-#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) || \
-    defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \
+    BUILDFLAG(IS_CHROMEOS)
   if (url.host_piece() == chrome::kChromeUIDiscardsHost)
     return &NewWebUI<DiscardsUI>;
 #endif
-#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
   if (url.host_piece() == chrome::kChromeUIBrowserSwitchHost)
     return &NewWebUI<BrowserSwitchUI>;
 #endif
@@ -1318,7 +1319,7 @@
 base::RefCountedMemory* ChromeWebUIControllerFactory::GetFaviconResourceBytes(
     const GURL& page_url,
     ui::ResourceScaleFactor scale_factor) const {
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
   // The extension scheme is handled in GetFaviconForURL.
   if (page_url.SchemeIs(extensions::kExtensionScheme)) {
     NOTREACHED();
@@ -1332,7 +1333,7 @@
   if (page_url.host_piece() == chrome::kChromeUIComponentsHost)
     return ComponentsUI::GetFaviconResourceBytes(scale_factor);
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   if (page_url.host_piece() == chrome::kChromeUIConflictsHost)
     return ConflictsUI::GetFaviconResourceBytes(scale_factor);
 #endif
@@ -1343,12 +1344,12 @@
   if (page_url.host_piece() == chrome::kChromeUIFlagsHost)
     return FlagsUI::GetFaviconResourceBytes(scale_factor);
 
-#if !defined(OS_ANDROID)
-#if !defined(OS_CHROMEOS)
+#if !BUILDFLAG(IS_ANDROID)
+#if !BUILDFLAG(IS_CHROMEOS)
   // The Apps launcher page is not available on android or ChromeOS.
   if (page_url.host_piece() == chrome::kChromeUIAppLauncherPageHost)
     return AppLauncherPageUI::GetFaviconResourceBytes(scale_factor);
-#endif  // !defined(OS_CHROMEOS)
+#endif  // !BUILDFLAG(IS_CHROMEOS)
 
   if (page_url.host_piece() == chrome::kChromeUINewTabPageHost)
     return NewTabPageUI::GetFaviconResourceBytes(scale_factor);
@@ -1384,7 +1385,7 @@
     return extensions::ExtensionsUI::GetFaviconResourceBytes(scale_factor);
   }
 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
-#endif  // !defined(OS_ANDROID)
+#endif  // !BUILDFLAG(IS_ANDROID)
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   if (page_url.host_piece() == chrome::kChromeUIOSSettingsHost)
@@ -1394,7 +1395,7 @@
   return nullptr;
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 std::vector<GURL> ChromeWebUIControllerFactory::GetListOfAcceptableURLs() {
   // TODO(crbug/1234594): Need to refactor this entire class to generate the
   // list automatically - which will be a giant CL touching lots of files.
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.h b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.h
index afdc1317..39653da 100644
--- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.h
+++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.h
@@ -9,6 +9,7 @@
 #include <vector>
 
 #include "base/memory/singleton.h"
+#include "build/build_config.h"
 #include "components/favicon_base/favicon_callback.h"
 #include "content/public/browser/web_ui.h"
 #include "content/public/browser/web_ui_controller_factory.h"
@@ -55,7 +56,7 @@
                         const std::vector<int>& desired_sizes_in_pixel,
                         favicon_base::FaviconResultsCallback callback) const;
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   // Called to retrieve a list of URLs which can be handled by this browser.
   // For Ash this means that they are shown in an SWA application and for
   // Lacros it means that Lacros will handle them themselves.
diff --git a/chrome/browser/ui/webui/components/components_handler.cc b/chrome/browser/ui/webui/components/components_handler.cc
index dbe5432..5feac0e 100644
--- a/chrome/browser/ui/webui/components/components_handler.cc
+++ b/chrome/browser/ui/webui/components/components_handler.cc
@@ -11,11 +11,12 @@
 #include "base/check.h"
 #include "base/notreached.h"
 #include "base/values.h"
+#include "build/build_config.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/update_client/crx_update_item.h"
 #include "ui/base/l10n/l10n_util.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 #include "chrome/common/webui_url_constants.h"
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/ash/crosapi/browser_manager.h"
@@ -24,7 +25,7 @@
 #elif BUILDFLAG(IS_CHROMEOS_LACROS)
 #include "chrome/browser/lacros/lacros_url_handling.h"
 #endif
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
 ComponentsHandler::ComponentsHandler(
     component_updater::ComponentUpdateService* component_updater)
@@ -43,7 +44,7 @@
       "checkUpdate", base::BindRepeating(&ComponentsHandler::HandleCheckUpdate,
                                          base::Unretained(this)));
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   web_ui()->RegisterDeprecatedMessageCallback(
       "crosUrlComponentsRedirect",
       base::BindRepeating(&ComponentsHandler::HandleCrosUrlComponentsRedirect,
@@ -68,14 +69,14 @@
   result.SetKey("components",
                 base::Value::FromUniquePtrValue(LoadComponents()));
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   const bool showSystemFlagsLink = crosapi::browser_util::IsLacrosEnabled();
 #else
   const bool showSystemFlagsLink = true;
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
   result.SetBoolean("showOsLink", showSystemFlagsLink);
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
   ResolveJavascriptCallback(callback_id, result);
 }
@@ -171,7 +172,7 @@
   return l10n_util::GetStringUTF16(IDS_COMPONENTS_UNKNOWN);
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 void ComponentsHandler::HandleCrosUrlComponentsRedirect(
     const base::ListValue* args) {
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
@@ -182,7 +183,7 @@
   crosapi::BrowserManager::Get()->OpenUrl(GURL(chrome::kChromeUIComponentsUrl));
 #endif
 }
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
 void ComponentsHandler::OnDemandUpdate(const std::string& component_id) {
   component_updater_->GetOnDemandUpdater().OnDemandUpdate(
diff --git a/chrome/browser/ui/webui/components/components_handler.h b/chrome/browser/ui/webui/components/components_handler.h
index 900b899..05205dc 100644
--- a/chrome/browser/ui/webui/components/components_handler.h
+++ b/chrome/browser/ui/webui/components/components_handler.h
@@ -10,6 +10,7 @@
 
 #include "base/memory/raw_ptr.h"
 #include "base/scoped_observation.h"
+#include "build/build_config.h"
 #include "components/component_updater/component_updater_service.h"
 #include "components/update_client/update_client.h"
 #include "content/public/browser/web_ui_message_handler.h"
@@ -42,7 +43,7 @@
   // ServiceObserver implementation.
   void OnEvent(Events event, const std::string& id) override;
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   // Callback for the "crosUrlComponentsRedirect" message.
   void HandleCrosUrlComponentsRedirect(const base::ListValue* args);
 #endif
diff --git a/chrome/browser/ui/webui/components/components_ui.cc b/chrome/browser/ui/webui/components/components_ui.cc
index 440d7f6..97445ed 100644
--- a/chrome/browser/ui/webui/components/components_ui.cc
+++ b/chrome/browser/ui/webui/components/components_ui.cc
@@ -60,7 +60,7 @@
     {"noComponents", IDS_COMPONENTS_NO_COMPONENTS},
     {"statusLabel", IDS_COMPONENTS_STATUS_LABEL},
     {"checkingLabel", IDS_COMPONENTS_CHECKING_LABEL},
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
     {"os-components-text1", IDS_COMPONENTS_OS_TEXT1_LABEL},
     {"os-components-text2", IDS_COMPONENTS_OS_TEXT2_LABEL},
     {"os-components-link", IDS_COMPONENTS_OS_LINK},
diff --git a/chrome/browser/ui/webui/connectors_internals/zero_trust_utils.cc b/chrome/browser/ui/webui/connectors_internals/zero_trust_utils.cc
index 7e0a3f7c..66aba70 100644
--- a/chrome/browser/ui/webui/connectors_internals/zero_trust_utils.cc
+++ b/chrome/browser/ui/webui/connectors_internals/zero_trust_utils.cc
@@ -9,7 +9,7 @@
 #include "base/strings/string_util.h"
 #include "build/build_config.h"
 
-#if defined(OS_LINUX) || defined(OS_WIN) || defined(OS_MAC)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/policy/chrome_browser_policy_connector.h"
 #include "components/enterprise/browser/controller/chrome_browser_cloud_management_controller.h"
@@ -18,7 +18,7 @@
 #include "crypto/signature_verifier.h"
 
 using BPKUR = enterprise_management::BrowserPublicKeyUploadRequest;
-#endif  // defined(OS_LINUX) || defined(OS_WIN) || defined(OS_MAC)
+#endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
 
 namespace enterprise_connectors {
 namespace utils {
@@ -66,7 +66,7 @@
       std::vector<base::StringPiece>(values.begin(), values.end()), ", ");
 }
 
-#if defined(OS_LINUX) || defined(OS_WIN) || defined(OS_MAC)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
 
 connectors_internals::mojom::KeyTrustLevel ParseTrustLevel(
     BPKUR::KeyTrustLevel trust_level) {
@@ -92,7 +92,7 @@
   }
 }
 
-#endif  // defined(OS_LINUX) || defined(OS_WIN) || defined(OS_MAC)
+#endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
 
 }  // namespace
 
@@ -171,7 +171,7 @@
 }
 
 connectors_internals::mojom::KeyInfoPtr GetKeyInfo() {
-#if defined(OS_LINUX) || defined(OS_WIN) || defined(OS_MAC)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
   auto* key_manager = g_browser_process->browser_policy_connector()
                           ->chrome_browser_cloud_management_controller()
                           ->GetDeviceTrustKeyManager();
@@ -189,7 +189,7 @@
           connectors_internals::mojom::KeyType::UNKNOWN);
     }
   }
-#endif  // defined(OS_LINUX) || defined(OS_WIN) || defined(OS_MAC)
+#endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
   return connectors_internals::mojom::KeyInfo::New(
       connectors_internals::mojom::KeyManagerInitializedValue::UNSUPPORTED,
       connectors_internals::mojom::KeyTrustLevel::UNSPECIFIED,
diff --git a/chrome/browser/ui/webui/constrained_web_dialog_ui_browsertest.cc b/chrome/browser/ui/webui/constrained_web_dialog_ui_browsertest.cc
index a719923..49bdf8b 100644
--- a/chrome/browser/ui/webui/constrained_web_dialog_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/constrained_web_dialog_ui_browsertest.cc
@@ -94,7 +94,7 @@
 
 // Tests that opening/closing the constrained window won't crash it.
 // Flaky on trusty builder: http://crbug.com/1020490.
-#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
 #define MAYBE_BasicTest DISABLED_BasicTest
 #else
 #define MAYBE_BasicTest BasicTest
@@ -114,7 +114,7 @@
 }
 
 // TODO(https://crbug.com/1020038): Crashy on Linux
-#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
 #define MAYBE_ReleaseWebContents DISABLED_ReleaseWebContents
 #else
 #define MAYBE_ReleaseWebContents ReleaseWebContents
diff --git a/chrome/browser/ui/webui/crashes_ui.cc b/chrome/browser/ui/webui/crashes_ui.cc
index ec3bd2b..ab1f9ba 100644
--- a/chrome/browser/ui/webui/crashes_ui.cc
+++ b/chrome/browser/ui/webui/crashes_ui.cc
@@ -42,7 +42,7 @@
 #include "chromeos/dbus/debug_daemon/debug_daemon_client.h"
 #endif
 
-#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
 #include "components/crash/core/app/crashpad.h"
 #endif
 
@@ -189,11 +189,11 @@
 #endif
 
   bool using_crashpad = false;
-#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_ANDROID)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_ANDROID)
   using_crashpad = true;
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
-#elif defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
   // ChromeOS uses crash_sender instead of Crashpad for uploads even when
   // Crashpad is enabled for dump generation.
   using_crashpad = crash_reporter::IsCrashpadEnabled();
diff --git a/chrome/browser/ui/webui/devtools_ui_data_source_unittest.cc b/chrome/browser/ui/webui/devtools_ui_data_source_unittest.cc
index 563cd6f..f748b3b 100644
--- a/chrome/browser/ui/webui/devtools_ui_data_source_unittest.cc
+++ b/chrome/browser/ui/webui/devtools_ui_data_source_unittest.cc
@@ -132,7 +132,7 @@
 }
 
 TEST_F(DevToolsUIDataSourceTest, TestDevToolsBundledFileURLWithSwitch) {
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   const char* flag_value = "file://C:/tmp/";
 #else
   const char* flag_value = "file://tmp/";
@@ -205,7 +205,7 @@
 }
 
 TEST_F(DevToolsUIDataSourceTest, TestDevToolsRemoteFileURLWithSwitch) {
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   const char* flag_value = "file://C:/tmp/";
 #else
   const char* flag_value = "file://tmp/";
@@ -221,7 +221,7 @@
 
 TEST_F(DevToolsUIDataSourceTest,
        TestDevToolsRemoteFileURLWithSwitchAndParameters) {
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   const char* flag_value = "file://C:/tmp/";
 #else
   const char* flag_value = "file://tmp/";
diff --git a/chrome/browser/ui/webui/feedback/feedback_handler.cc b/chrome/browser/ui/webui/feedback/feedback_handler.cc
index 6016550..0ec0144 100644
--- a/chrome/browser/ui/webui/feedback/feedback_handler.cc
+++ b/chrome/browser/ui/webui/feedback/feedback_handler.cc
@@ -10,6 +10,7 @@
 #include "base/bind.h"
 #include "base/strings/strcat.h"
 #include "base/values.h"
+#include "build/build_config.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/webui/feedback/child_web_dialog.h"
 #include "chrome/browser/ui/webui/feedback/feedback_dialog.h"
@@ -57,7 +58,7 @@
   web_ui()->RegisterDeprecatedMessageCallback(
       "showDialog", base::BindRepeating(&FeedbackHandler::HandleShowDialog,
                                         base::Unretained(this)));
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   web_ui()->RegisterDeprecatedMessageCallback(
       "showAssistantLogsInfo",
       base::BindRepeating(&FeedbackHandler::HandleShowAssistantLogsInfo,
@@ -66,7 +67,7 @@
       "showBluetoothLogsInfo",
       base::BindRepeating(&FeedbackHandler::HandleShowBluetoothLogsInfo,
                           base::Unretained(this)));
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
   web_ui()->RegisterDeprecatedMessageCallback(
       "showSystemInfo",
       base::BindRepeating(&FeedbackHandler::HandleShowSystemInfo,
@@ -80,7 +81,7 @@
   dialog_->Show();
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 void FeedbackHandler::HandleShowAssistantLogsInfo(const base::ListValue* args) {
   ShowChildPage(Profile::FromWebUI(web_ui()), dialog_,
                 ChildPageURL("html/assistant_logs_info.html"), std::u16string(),
@@ -93,7 +94,7 @@
                 /*dialog_width=*/400, /*dialog_height=*/120,
                 /*can_resize=*/false, /*can_minimize=*/false);
 }
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
 void FeedbackHandler::HandleShowSystemInfo(const base::ListValue* args) {
   ShowChildPage(Profile::FromWebUI(web_ui()), dialog_,
diff --git a/chrome/browser/ui/webui/feedback/feedback_handler.h b/chrome/browser/ui/webui/feedback/feedback_handler.h
index 894b44e..0628b66b 100644
--- a/chrome/browser/ui/webui/feedback/feedback_handler.h
+++ b/chrome/browser/ui/webui/feedback/feedback_handler.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_UI_WEBUI_FEEDBACK_FEEDBACK_HANDLER_H_
 
 #include "base/memory/raw_ptr.h"
+#include "build/build_config.h"
 #include "chrome/browser/ui/webui/feedback/feedback_dialog.h"
 #include "content/public/browser/web_ui_message_handler.h"
 
@@ -25,10 +26,10 @@
 
  private:
   void HandleShowDialog(const base::ListValue* args);
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   void HandleShowAssistantLogsInfo(const base::ListValue* args);
   void HandleShowBluetoothLogsInfo(const base::ListValue* args);
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
   void HandleShowMetrics(const base::ListValue* args);
   void HandleShowSystemInfo(const base::ListValue* args);
 
diff --git a/chrome/browser/ui/webui/fileicon_source_unittest.cc b/chrome/browser/ui/webui/fileicon_source_unittest.cc
index 6ce0a9a..ea50c96 100644
--- a/chrome/browser/ui/webui/fileicon_source_unittest.cc
+++ b/chrome/browser/ui/webui/fileicon_source_unittest.cc
@@ -73,7 +73,7 @@
      FILE_PATH_LITERAL("a?iconsize=small"), 1.0f, IconLoader::LARGE},
     {"?path=o%40%23%24%25%26*()%20%2B%3D%3F%2C%3A%3B%22.jpg",
      FILE_PATH_LITERAL("o@#$%&*() +=?,:;\".jpg"), 1.0f, IconLoader::NORMAL},
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
     {"?path=c%3A%2Ffoo%2Fbar%2Fbaz", FILE_PATH_LITERAL("c:\\foo\\bar\\baz"),
      1.0f, IconLoader::NORMAL},
     {"?path=%2Ffoo&bar=asdf&asdf", FILE_PATH_LITERAL("\\foo"), 1.0f,
diff --git a/chrome/browser/ui/webui/flags/flags_ui.cc b/chrome/browser/ui/webui/flags/flags_ui.cc
index 26632b9..29f5370 100644
--- a/chrome/browser/ui/webui/flags/flags_ui.cc
+++ b/chrome/browser/ui/webui/flags/flags_ui.cc
@@ -13,6 +13,7 @@
 #include "base/memory/ref_counted_memory.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
+#include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/profiles/profile.h"
@@ -178,7 +179,7 @@
   source->AddLocalizedString("search-label", IDS_FLAGS_UI_SEARCH_LABEL);
   source->AddLocalizedString("search-placeholder",
                              IDS_FLAGS_UI_SEARCH_PLACEHOLDER);
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   source->AddLocalizedString("os-flags-link", IDS_FLAGS_UI_OS_FLAGS_LINK);
   source->AddLocalizedString("os-flags-text1", IDS_FLAGS_UI_OS_FLAGS_TEXT1);
   source->AddLocalizedString("os-flags-text2", IDS_FLAGS_UI_OS_FLAGS_TEXT2);
@@ -218,7 +219,7 @@
   source->AddLocalizedString("search-label", IDS_FLAGS_UI_SEARCH_LABEL);
   source->AddLocalizedString("search-placeholder",
                              IDS_DEPRECATED_FEATURES_SEARCH_PLACEHOLDER);
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   source->AddLocalizedString("os-flags-link",
                              IDS_DEPRECATED_FLAGS_UI_OS_FLAGS_LINK);
   source->AddLocalizedString("os-flags-text1",
diff --git a/chrome/browser/ui/webui/flags/flags_ui_handler.cc b/chrome/browser/ui/webui/flags/flags_ui_handler.cc
index 2ea1a7b..15dd57e 100644
--- a/chrome/browser/ui/webui/flags/flags_ui_handler.cc
+++ b/chrome/browser/ui/webui/flags/flags_ui_handler.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/ui/webui/flags/flags_ui_handler.h"
 
 #include "base/bind.h"
+#include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/about_flags.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
@@ -50,7 +51,7 @@
       flags_ui::kResetAllFlags,
       base::BindRepeating(&FlagsUIHandler::HandleResetAllFlags,
                           base::Unretained(this)));
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   web_ui()->RegisterDeprecatedMessageCallback(
       flags_ui::kCrosUrlFlagsRedirect,
       base::BindRepeating(&FlagsUIHandler::HandleCrosUrlFlagsRedirect,
@@ -113,7 +114,7 @@
 #endif
   results.SetBoolean(flags_ui::kShowSystemFlagsLink, showSystemFlagsLink);
 
-#if defined(OS_WIN) || defined(OS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH)
   version_info::Channel channel = chrome::GetChannel();
   results.SetBoolean(
       flags_ui::kShowBetaChannelPromotion,
@@ -201,7 +202,7 @@
   about_flags::ResetAllFlags(flags_storage_.get());
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 void FlagsUIHandler::HandleCrosUrlFlagsRedirect(const base::ListValue* args) {
   about_flags::CrosUrlFlagsRedirect();
 }
diff --git a/chrome/browser/ui/webui/flags/flags_ui_handler.h b/chrome/browser/ui/webui/flags/flags_ui_handler.h
index b22d3f0..88ccc45 100644
--- a/chrome/browser/ui/webui/flags/flags_ui_handler.h
+++ b/chrome/browser/ui/webui/flags/flags_ui_handler.h
@@ -57,7 +57,7 @@
   // Callback for the "resetAllFlags" message.
   void HandleResetAllFlags(const base::ListValue* args);
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   // Callback for the "CrosUrlFlagsRedirect" message.
   void HandleCrosUrlFlagsRedirect(const base::ListValue* args);
 #endif
diff --git a/chrome/browser/ui/webui/help/test_version_updater.h b/chrome/browser/ui/webui/help/test_version_updater.h
index 18849db..c33cd2c 100644
--- a/chrome/browser/ui/webui/help/test_version_updater.h
+++ b/chrome/browser/ui/webui/help/test_version_updater.h
@@ -27,7 +27,7 @@
   void SetReturnedStatus(Status status) { status_ = status; }
 
 // VersionUpdater implementation:
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   void PromoteUpdater() const override {}
 #endif
 #if BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/chrome/browser/ui/webui/help/version_updater.h b/chrome/browser/ui/webui/help/version_updater.h
index 265c461..5bb550b3 100644
--- a/chrome/browser/ui/webui/help/version_updater.h
+++ b/chrome/browser/ui/webui/help/version_updater.h
@@ -93,7 +93,7 @@
   virtual void CheckForUpdate(StatusCallback status_callback,
                               PromoteCallback promote_callback) = 0;
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   // Make updates available for all users.
   virtual void PromoteUpdater() const = 0;
 #endif
diff --git a/chrome/browser/ui/webui/history/browsing_history_handler_unittest.cc b/chrome/browser/ui/webui/history/browsing_history_handler_unittest.cc
index cf1fee5..50da2fa 100644
--- a/chrome/browser/ui/webui/history/browsing_history_handler_unittest.cc
+++ b/chrome/browser/ui/webui/history/browsing_history_handler_unittest.cc
@@ -270,7 +270,7 @@
   }
 }
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 TEST_F(BrowsingHistoryHandlerTest, MdTruncatesTitles) {
   history::BrowsingHistoryService::HistoryEntry long_url_entry;
   long_url_entry.url = GURL(
diff --git a/chrome/browser/ui/webui/internals/internals_ui.cc b/chrome/browser/ui/webui/internals/internals_ui.cc
index 0fb6c9b..ccafc08 100644
--- a/chrome/browser/ui/webui/internals/internals_ui.cc
+++ b/chrome/browser/ui/webui/internals/internals_ui.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/ui/webui/internals/internals_ui.h"
 
+#include "build/build_config.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/grit/dev_ui_browser_resources.h"
 #include "chrome/grit/internals_resources.h"
@@ -12,14 +13,14 @@
 #include "content/public/browser/web_ui_controller.h"
 #include "content/public/browser/web_ui_data_source.h"
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 #include "chrome/browser/ui/webui/internals/lens/lens_internals_ui_message_handler.h"
 #include "chrome/browser/ui/webui/internals/notifications/notifications_internals_ui_message_handler.h"
 #include "chrome/browser/ui/webui/internals/query_tiles/query_tiles_internals_ui_message_handler.h"
 #else
 #include "chrome/browser/ui/webui/internals/user_education/user_education_internals_page_handler_impl.h"
 #include "mojo/public/cpp/bindings/self_owned_receiver.h"
-#endif  // defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_ANDROID)
 
 #if BUILDFLAG(ENABLE_SESSION_SERVICE)
 #include "chrome/browser/ui/webui/internals/sessions/session_service_internals_handler.h"
@@ -64,7 +65,7 @@
 
   // Add your sub-URL internals WebUI here.
   // Keep this set of sub-URLs in sync with |kChromeInternalsPathURLs|.
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   // chrome://internals/lens
   AddLensInternals(web_ui);
   // chrome://internals/notifications
@@ -86,7 +87,7 @@
   // WebAppInternalsSource.
   // TODO(crbug.com/1226263): Clean up this redirect after M94 goes stable.
   source_->AddResourcePath("web-app", IDR_WEB_APP_INTERNALS_HTML);
-#endif  // defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_ANDROID)
 
   // chrome://internals/session-service
   source_->SetRequestFilter(
@@ -98,7 +99,7 @@
 
 InternalsUI::~InternalsUI() = default;
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 void InternalsUI::AddLensInternals(content::WebUI* web_ui) {
   source_->AddResourcePath("lens", IDR_LENS_INTERNALS_LENS_INTERNALS_HTML);
 
@@ -115,7 +116,7 @@
   web_ui->AddMessageHandler(
       std::make_unique<QueryTilesInternalsUIMessageHandler>(profile_));
 }
-#else   // defined(OS_ANDROID)
+#else   // BUILDFLAG(IS_ANDROID)
 void InternalsUI::BindInterface(
     mojo::PendingReceiver<
         mojom::user_education_internals::UserEducationInternalsPageHandler>
@@ -124,6 +125,6 @@
       std::make_unique<UserEducationInternalsPageHandlerImpl>(profile_),
       std::move(receiver));
 }
-#endif  // defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_ANDROID)
 
 WEB_UI_CONTROLLER_TYPE_IMPL(InternalsUI)
diff --git a/chrome/browser/ui/webui/internals/internals_ui.h b/chrome/browser/ui/webui/internals/internals_ui.h
index 7a4721f..f66afba 100644
--- a/chrome/browser/ui/webui/internals/internals_ui.h
+++ b/chrome/browser/ui/webui/internals/internals_ui.h
@@ -11,8 +11,8 @@
 #include "content/public/browser/web_ui_data_source.h"
 #include "ui/webui/mojo_web_ui_controller.h"
 
-#if !defined(OS_ANDROID)
-// gn check doesn't understand "#if !defined(OS_ANDROID)" and fails this
+#if !BUILDFLAG(IS_ANDROID)
+// gn check doesn't understand "#if !BUILDFLAG(IS_ANDROID)" and fails this
 // non-Android include on Android.
 #include "chrome/browser/ui/webui/internals/user_education/user_education_internals.mojom.h"  // nogncheck
 #endif
@@ -28,23 +28,23 @@
   explicit InternalsUI(content::WebUI* web_ui);
   ~InternalsUI() override;
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
   void BindInterface(
       mojo::PendingReceiver<
           mojom::user_education_internals::UserEducationInternalsPageHandler>
           receiver);
-#endif  // !defined(OS_ANDROID)
+#endif  // !BUILDFLAG(IS_ANDROID)
 
  private:
   WEB_UI_CONTROLLER_TYPE_DECL();
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   // Add resources and message handler for chrome://internals/query-tiles.
   void AddQueryTilesInternals(content::WebUI* web_ui);
 
   // Add resources and message handler for chrome://internals/lens.
   void AddLensInternals(content::WebUI* web_ui);
-#endif  // defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_ANDROID)
 
   raw_ptr<Profile> profile_;
   raw_ptr<content::WebUIDataSource> source_;
diff --git a/chrome/browser/ui/webui/interstitials/interstitial_ui_browsertest.cc b/chrome/browser/ui/webui/interstitials/interstitial_ui_browsertest.cc
index 625ca4f89..a77b44b 100644
--- a/chrome/browser/ui/webui/interstitials/interstitial_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/interstitials/interstitial_ui_browsertest.cc
@@ -226,7 +226,7 @@
 // chrome://interstitials (using chrome://interstitials/ssl).
 
 // Test is currently flaky on Windows (crbug.com/926392)
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 #define MAYBE_InterstitialWithPathViewSource \
   DISABLED_InterstitialWithPathViewSource
 #else
diff --git a/chrome/browser/ui/webui/media/media_engagement_ui.cc b/chrome/browser/ui/webui/media/media_engagement_ui.cc
index ce760c0..77af964 100644
--- a/chrome/browser/ui/webui/media/media_engagement_ui.cc
+++ b/chrome/browser/ui/webui/media/media_engagement_ui.cc
@@ -31,7 +31,7 @@
 #include "third_party/blink/public/common/web_preferences/web_preferences.h"
 #include "third_party/blink/public/mojom/webpreferences/web_preferences.mojom.h"
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 #include "chrome/common/pref_names.h"
 #include "components/prefs/pref_service.h"
 #endif
@@ -124,7 +124,7 @@
 
   // Pref is not available on Android.
   bool GetBlockAutoplayPref() {
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
     return false;
 #else
     return profile_->GetPrefs()->GetBoolean(prefs::kBlockAutoplayEnabled);
diff --git a/chrome/browser/ui/webui/memory_internals_ui.cc b/chrome/browser/ui/webui/memory_internals_ui.cc
index cdce3cf..b5325c1 100644
--- a/chrome/browser/ui/webui/memory_internals_ui.cc
+++ b/chrome/browser/ui/webui/memory_internals_ui.cc
@@ -239,7 +239,7 @@
 
   AllowJavascript();
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   base::Value result("Saving...");
   FireWebUIListener("save-dump-progress", result);
 
diff --git a/chrome/browser/ui/webui/nacl_ui.cc b/chrome/browser/ui/webui/nacl_ui.cc
index 582b160..0b2a7ec9 100644
--- a/chrome/browser/ui/webui/nacl_ui.cc
+++ b/chrome/browser/ui/webui/nacl_ui.cc
@@ -44,7 +44,7 @@
 #include "services/network/public/mojom/content_security_policy.mojom.h"
 #include "ui/base/l10n/l10n_util.h"
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 #include "base/win/windows_version.h"
 #endif
 
@@ -196,7 +196,7 @@
   // TODO(jvoung): refactor this to share the extra windows labeling
   // with about:flash, or something.
   std::string os_label = version_info::GetOSType();
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   base::win::OSInfo* os = base::win::OSInfo::GetInstance();
   switch (os->version()) {
     case base::win::Version::XP:
diff --git a/chrome/browser/ui/webui/net_export_ui.cc b/chrome/browser/ui/webui/net_export_ui.cc
index ec205a3..c5e3430 100644
--- a/chrome/browser/ui/webui/net_export_ui.cc
+++ b/chrome/browser/ui/webui/net_export_ui.cc
@@ -45,7 +45,7 @@
 #include "net/log/net_log_capture_mode.h"
 #include "ui/shell_dialogs/select_file_dialog.h"
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 #include "components/browser_ui/share/android/intent_helper.h"
 #endif
 
@@ -256,7 +256,7 @@
                chrome_browser_net::GetPrerenderInfo(profile));
   SetIfNotNull(ui_thread_polled_data.get(), "extensionInfo",
                chrome_browser_net::GetExtensionInfo(profile));
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   SetIfNotNull(ui_thread_polled_data.get(), "serviceProviders",
                chrome_browser_net::GetWindowsServiceProviders());
 #endif
@@ -302,7 +302,7 @@
 // static
 void NetExportMessageHandler::SendEmail(const base::FilePath& file_to_send) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   if (file_to_send.empty())
     return;
   std::string email;
@@ -342,7 +342,7 @@
 
 // static
 bool NetExportMessageHandler::UsingMobileUI() {
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   return true;
 #else
   return false;
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 807b8d1..1152088e 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
@@ -109,7 +109,8 @@
                      base::FeatureList::IsEnabled(ntp_features::kNtpLogo));
   source->AddBoolean(
       "middleSlotPromoEnabled",
-      base::FeatureList::IsEnabled(ntp_features::kNtpMiddleSlotPromo));
+      base::FeatureList::IsEnabled(ntp_features::kNtpMiddleSlotPromo) &&
+          profile->GetPrefs()->GetBoolean(prefs::kNtpPromoVisible));
   source->AddBoolean(
       "modulesDragAndDropEnabled",
       base::FeatureList::IsEnabled(ntp_features::kNtpModulesDragAndDrop));
@@ -438,6 +439,7 @@
   registry->RegisterTimePref(kPrevNavigationTimePrefName, base::Time());
   registry->RegisterBooleanPref(ntp_prefs::kNtpUseMostVisitedTiles, false);
   registry->RegisterBooleanPref(ntp_prefs::kNtpShortcutsVisible, true);
+  registry->RegisterBooleanPref(prefs::kNtpPromoVisible, true);
 }
 
 // static
diff --git a/chrome/browser/ui/webui/ntp/app_launcher_handler.cc b/chrome/browser/ui/webui/ntp/app_launcher_handler.cc
index a71d04b..207e22c 100644
--- a/chrome/browser/ui/webui/ntp/app_launcher_handler.cc
+++ b/chrome/browser/ui/webui/ntp/app_launcher_handler.cc
@@ -306,7 +306,7 @@
       base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode));
 
   bool is_deprecated_app = false;
-#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
   is_deprecated_app = extensions::IsExtensionUnsupportedDeprecatedApp(
       extension_service_->GetBrowserContext(), extension->id());
 #endif
@@ -735,7 +735,7 @@
 
   Profile* profile = extension_service_->profile();
 
-#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
   if (extensions::IsExtensionUnsupportedDeprecatedApp(profile, extension_id)) {
     // TODO(crbug.com/1225779): Show the deprecated apps dialog.
     return;
@@ -1328,8 +1328,8 @@
   options.os_hooks[web_app::OsHookType::kUninstallationViaOsSettings] =
       web_app->CanUserUninstallWebApp();
 
-#if defined(OS_WIN) || defined(OS_MAC) || \
-    (defined(OS_LINUX) && !BUILDFLAG(IS_CHROMEOS_LACROS))
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || \
+    (BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS_LACROS))
   options.os_hooks[web_app::OsHookType::kUrlHandlers] = true;
 #else
   options.os_hooks[web_app::OsHookType::kUrlHandlers] = false;
diff --git a/chrome/browser/ui/webui/ntp/new_tab_ui.cc b/chrome/browser/ui/webui/ntp/new_tab_ui.cc
index 6ea7e26..fdc2b1b3 100644
--- a/chrome/browser/ui/webui/ntp/new_tab_ui.cc
+++ b/chrome/browser/ui/webui/ntp/new_tab_ui.cc
@@ -13,6 +13,7 @@
 #include "base/memory/ref_counted_memory.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
+#include "build/build_config.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/webui/ntp/cookie_controls_handler.h"
 #include "chrome/browser/ui/webui/ntp/core_app_launcher_handler.h"
@@ -34,7 +35,7 @@
 #include "ui/native_theme/native_theme.h"
 #include "url/gurl.h"
 
-#if !defined(OS_CHROMEOS)
+#if !BUILDFLAG(IS_CHROMEOS)
 #include "chrome/browser/ui/webui/ntp/app_launcher_handler.h"
 #endif
 
@@ -89,7 +90,7 @@
 void NewTabUI::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   CoreAppLauncherHandler::RegisterProfilePrefs(registry);
-#if !defined(OS_CHROMEOS)
+#if !BUILDFLAG(IS_CHROMEOS)
   AppLauncherHandler::RegisterProfilePrefs(registry);
 #endif
 }
diff --git a/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc b/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc
index a1efa187..bf763ab 100644
--- a/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc
+++ b/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc
@@ -59,7 +59,7 @@
 #include "chromeos/strings/grit/chromeos_strings.h"
 #endif
 
-#if !defined(OS_CHROMEOS)
+#if !BUILDFLAG(IS_CHROMEOS)
 #include "chrome/browser/ui/webui/ntp/app_launcher_handler.h"
 #endif
 
diff --git a/chrome/browser/ui/webui/ntp_tiles_internals_ui.cc b/chrome/browser/ui/webui/ntp_tiles_internals_ui.cc
index fbab061..c195014 100644
--- a/chrome/browser/ui/webui/ntp_tiles_internals_ui.cc
+++ b/chrome/browser/ui/webui/ntp_tiles_internals_ui.cc
@@ -90,13 +90,13 @@
     case ntp_tiles::TileSource::POPULAR_BAKED_IN:
     case ntp_tiles::TileSource::POPULAR:
     case ntp_tiles::TileSource::EXPLORE:
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
       return true;
 #else
       return false;
 #endif
     case ntp_tiles::TileSource::CUSTOM_LINKS:
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
       return false;
 #else
       return true;
diff --git a/chrome/browser/ui/webui/omnibox/omnibox_ui.cc b/chrome/browser/ui/webui/omnibox/omnibox_ui.cc
index 9cae4d9..67e62ff 100644
--- a/chrome/browser/ui/webui/omnibox/omnibox_ui.cc
+++ b/chrome/browser/ui/webui/omnibox/omnibox_ui.cc
@@ -8,6 +8,7 @@
 
 #include "base/bind.h"
 #include "base/feature_list.h"
+#include "build/build_config.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/webui/omnibox/omnibox_page_handler.h"
 #include "chrome/browser/ui/webui/version/version_handler.h"
@@ -23,7 +24,7 @@
 #include "services/network/public/mojom/content_security_policy.mojom.h"
 #include "ui/base/webui/web_ui_util.h"
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 #include "chrome/browser/ui/webui/omnibox/omnibox_popup_handler.h"
 #endif
 
@@ -45,7 +46,7 @@
       base::make_span(kOmniboxResources, kOmniboxResourcesSize));
   source->SetDefaultResource(IDR_OMNIBOX_OMNIBOX_HTML);
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
   if (base::FeatureList::IsEnabled(omnibox::kWebUIOmniboxPopup)) {
     popup_handler_ = std::make_unique<OmniboxPopupHandler>();
   }
diff --git a/chrome/browser/ui/webui/omnibox/omnibox_ui.h b/chrome/browser/ui/webui/omnibox/omnibox_ui.h
index 4823976..816d417 100644
--- a/chrome/browser/ui/webui/omnibox/omnibox_ui.h
+++ b/chrome/browser/ui/webui/omnibox/omnibox_ui.h
@@ -12,7 +12,7 @@
 
 class OmniboxPageHandler;
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 class OmniboxPopupHandler;
 #endif
 
@@ -30,7 +30,7 @@
   // interface passing the pending receiver that will be internally bound.
   void BindInterface(mojo::PendingReceiver<mojom::OmniboxPageHandler> receiver);
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
   // This is needed for the Views native UI to call into the WebUI code.
   OmniboxPopupHandler* popup_handler() { return popup_handler_.get(); }
 #endif
@@ -38,7 +38,7 @@
  private:
   std::unique_ptr<OmniboxPageHandler> omnibox_handler_;
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
   std::unique_ptr<OmniboxPopupHandler> popup_handler_;
 #endif
 
diff --git a/chrome/browser/ui/webui/policy/policy_ui.cc b/chrome/browser/ui/webui/policy/policy_ui.cc
index 8c3fed7..2c9bc67 100644
--- a/chrome/browser/ui/webui/policy/policy_ui.cc
+++ b/chrome/browser/ui/webui/policy/policy_ui.cc
@@ -69,7 +69,7 @@
     {"status", IDS_POLICY_STATUS},
     {"statusDevice", IDS_POLICY_STATUS_DEVICE},
     {"statusMachine", IDS_POLICY_STATUS_MACHINE},
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
     {"statusUpdater", IDS_POLICY_STATUS_UPDATER},
 #endif
     {"statusUser", IDS_POLICY_STATUS_USER},
diff --git a/chrome/browser/ui/webui/policy/policy_ui_browsertest.cc b/chrome/browser/ui/webui/policy/policy_ui_browsertest.cc
index 7d0375e8..18d1141 100644
--- a/chrome/browser/ui/webui/policy/policy_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/policy/policy_ui_browsertest.cc
@@ -512,13 +512,13 @@
         it.key(), std::string(), std::string(), nullptr, false));
   }
 
-#if !defined(OS_CHROMEOS)
+#if !BUILDFLAG(IS_CHROMEOS)
   // Add policies found in the Policy Precedence table.
   for (auto* policy : policy::metapolicy::kPrecedence) {
     expected_policies.push_back(PopulateExpectedPolicy(
         policy, std::string(), std::string(), nullptr, false));
   }
-#endif  // !defined(OS_CHROMEOS)
+#endif  // !BUILDFLAG(IS_CHROMEOS)
 
   // Retrieve the contents of the policy table from the UI and verify that it
   // matches the expectation.
@@ -601,20 +601,20 @@
           kUnknownPolicyWithDots, expected_values[kUnknownPolicyWithDots],
           "Platform", values.Get(kUnknownPolicyWithDots), true));
 
-#if !defined(OS_CHROMEOS)
+#if !BUILDFLAG(IS_CHROMEOS)
   // Add policies found in the Policy Precedence table.
   for (auto* policy : policy::metapolicy::kPrecedence) {
     expected_policies.push_back(PopulateExpectedPolicy(
         policy, std::string(), std::string(), values.Get(policy), false));
   }
-#endif  // !defined(OS_CHROMEOS)
+#endif  // !BUILDFLAG(IS_CHROMEOS)
 
   // Retrieve the contents of the policy table from the UI and verify that it
   // matches the expectation.
   VerifyPolicies(expected_policies);
 }
 
-#if !defined(OS_CHROMEOS)
+#if !BUILDFLAG(IS_CHROMEOS)
 class PolicyPrecedenceUITest
     : public PolicyUITest,
       public ::testing::WithParamInterface<std::tuple<
@@ -701,7 +701,7 @@
                          testing::Combine(testing::Values(false, true),
                                           testing::Values(false, true),
                                           testing::Values(false, true)));
-#endif  // !defined(OS_CHROMEOS)
+#endif  // !BUILDFLAG(IS_CHROMEOS)
 
 // TODO(https://crbug.com/1027135) Add tests to verify extension policies are
 // exported correctly.
@@ -835,13 +835,13 @@
         it.key(), std::string(), std::string(), nullptr, false));
   }
 
-#if !defined(OS_CHROMEOS)
+#if !BUILDFLAG(IS_CHROMEOS)
   // Add policies found in the precedence policy table.
   for (auto* policy : policy::metapolicy::kPrecedence) {
     expected_chrome_policies.push_back(PopulateExpectedPolicy(
         policy, std::string(), std::string(), nullptr, false));
   }
-#endif  // !defined(OS_CHROMEOS)
+#endif  // !BUILDFLAG(IS_CHROMEOS)
 
   // Add extension policy to expected policy list.
   std::vector<std::vector<std::string>> expected_policies =
diff --git a/chrome/browser/ui/webui/policy/policy_ui_handler.cc b/chrome/browser/ui/webui/policy/policy_ui_handler.cc
index 7301dba..e1a2b58 100644
--- a/chrome/browser/ui/webui/policy/policy_ui_handler.cc
+++ b/chrome/browser/ui/webui/policy/policy_ui_handler.cc
@@ -86,7 +86,7 @@
 #include "ui/base/l10n/time_format.h"
 #include "ui/base/webui/web_ui_util.h"
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 #include "chrome/browser/ui/android/android_about_app_info.h"
 #endif
 
@@ -111,11 +111,11 @@
 #include "components/policy/core/common/policy_loader_lacros.h"
 #endif
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #include "base/mac/mac_util.h"
 #endif
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 #include "chrome/browser/ui/webui/version/version_util_win.h"
 #endif
 
@@ -126,7 +126,7 @@
 #include "extensions/common/manifest_constants.h"
 #endif
 
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 #include <windows.h>
 
 #include <DSRole.h>
@@ -135,7 +135,7 @@
 #include "chrome/install_static/install_util.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
-#endif  // defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#endif  // BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 
 namespace em = enterprise_management;
 
@@ -202,11 +202,11 @@
 // `device policies`. This is a helper function that retrieves the expected
 // labelKey
 std::string GetMachineStatusLegendKey() {
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   return "statusDevice";
 #else
   return "statusMachine";
-#endif  // defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_ANDROID)
 }
 
 }  // namespace
@@ -408,7 +408,7 @@
 };
 #endif
 
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 class UpdaterStatusProvider : public policy::PolicyStatusProvider {
  public:
   UpdaterStatusProvider();
@@ -653,7 +653,7 @@
 
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 UpdaterStatusProvider::UpdaterStatusProvider() {
   base::ThreadPool::PostTaskAndReplyWithResult(
       FROM_HERE,
@@ -703,7 +703,7 @@
   NotifyStatusChange();
 }
 
-#endif  // defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#endif  // BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 
 PolicyUIHandler::PolicyUIHandler() = default;
 
@@ -850,9 +850,9 @@
   }
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
   ReloadUpdaterPoliciesAndState();
-#endif  // defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#endif  // BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 
   if (!user_status_provider_.get())
     user_status_provider_ = std::make_unique<policy::PolicyStatusProvider>();
@@ -955,7 +955,7 @@
   chrome_values.SetKey("policyNames", std::move(chrome_policy_names));
   names.SetKey("chrome", std::move(chrome_values));
 
-#if !defined(OS_CHROMEOS)
+#if !BUILDFLAG(IS_CHROMEOS)
   // Add precedence policy names.
   base::Value precedence_policy_names(base::Value::Type::LIST);
   for (auto* policy : policy::metapolicy::kPrecedence) {
@@ -965,16 +965,16 @@
   precedence_values.SetStringKey("name", "Policy Precedence");
   precedence_values.SetKey("policyNames", std::move(precedence_policy_names));
   names.SetKey("precedence", std::move(precedence_values));
-#endif  // !defined(OS_CHROMEOS)
+#endif  // !BUILDFLAG(IS_CHROMEOS)
 
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
   if (updater_policies_) {
     base::Value updater_policies(base::Value::Type::DICTIONARY);
     updater_policies.SetStringKey("name", "Google Update Policies");
     updater_policies.SetKey("policyNames", GetGoogleUpdatePolicyNames());
     names.SetKey("updater", std::move(updater_policies));
   }
-#endif  // defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#endif  // BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 
 #if BUILDFLAG(ENABLE_EXTENSIONS)
   // Add extension policy names.
@@ -993,7 +993,7 @@
   auto client = std::make_unique<policy::ChromePolicyConversionsClient>(
       web_ui()->GetWebContents()->GetBrowserContext());
 
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
   if (updater_policies_) {
     return policy::ArrayPolicyConversions(std::move(client))
         .EnableConvertValues(true)
@@ -1002,7 +1002,7 @@
         .WithUpdaterPolicySchemas(GetGoogleUpdatePolicySchemas())
         .ToValue();
   }
-#endif  // defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#endif  // BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 
   return policy::ArrayPolicyConversions(std::move(client))
       .EnableConvertValues(true)
@@ -1119,7 +1119,7 @@
 }
 
 void PolicyUIHandler::HandleExportPoliciesJson(const base::ListValue* args) {
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   // TODO(crbug.com/1228691): Unify download logic between all platforms to
   // use the WebUI download solution (and remove the Android check).
   if (!IsJavascriptAllowed()) {
@@ -1198,9 +1198,9 @@
     service->GetRemote<crosapi::mojom::PolicyService>()->ReloadPolicy();
 #endif
 
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
   ReloadUpdaterPoliciesAndState();
-#endif  // defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#endif  // BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 
   GetPolicyService()->RefreshPolicies(base::BindOnce(
       &PolicyUIHandler::OnRefreshPoliciesDone, weak_factory_.GetWeakPtr()));
@@ -1214,7 +1214,7 @@
 
 std::string PolicyUIHandler::GetPoliciesAsJson() {
   absl::optional<std::string> cohort_name;
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   std::u16string cohort_version_info =
       version_utils::win::GetCohortVersionInfo();
   if (!cohort_version_info.empty()) {
@@ -1228,13 +1228,13 @@
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   platform_name = chromeos::version_loader::GetVersion(
       chromeos::version_loader::VERSION_FULL);
-#elif defined(OS_MAC)
+#elif BUILDFLAG(IS_MAC)
   os_name = base::mac::GetOSDisplayName();
 #else
   os_name = version_info::GetOSType();
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   os_name = os_name.value() + " " + version_utils::win::GetFullWindowsVersion();
-#elif defined(OS_ANDROID)
+#elif BUILDFLAG(IS_ANDROID)
   os_name = os_name.value() + " " + AndroidAboutAppInfo::GetOsInfo();
 #endif
 #endif
@@ -1299,7 +1299,7 @@
     FireWebUIListener("policies-updated", GetPolicyNames(), GetPolicyValues());
 }
 
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 void PolicyUIHandler::SetUpdaterPoliciesAndState(
     std::unique_ptr<GoogleUpdatePoliciesAndState> updater_policies_and_state) {
   updater_policies_ = std::move(updater_policies_and_state->policies);
@@ -1322,7 +1322,7 @@
                      weak_factory_.GetWeakPtr()));
 }
 
-#endif  // defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#endif  // BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 
 void PolicyUIHandler::OnRefreshPoliciesDone() {
   SendPolicies();
diff --git a/chrome/browser/ui/webui/policy/policy_ui_handler.h b/chrome/browser/ui/webui/policy/policy_ui_handler.h
index 26087ad..d72ebf1 100644
--- a/chrome/browser/ui/webui/policy/policy_ui_handler.h
+++ b/chrome/browser/ui/webui/policy/policy_ui_handler.h
@@ -101,7 +101,7 @@
   // metadata is sent.
   void SendPolicies();
 
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
   // Sets |updater_policies_| in this instance, updates
   // |updater_status_provider_| with a new state and refreshes the UI via
   // SendPolicies.
@@ -109,7 +109,7 @@
       std::unique_ptr<GoogleUpdatePoliciesAndState> updater_policies_and_state);
 
   void ReloadUpdaterPoliciesAndState();
-#endif  // defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#endif  // BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 
   // Send the status of cloud policy to the UI.
   void SendStatus();
@@ -141,9 +141,9 @@
   std::unique_ptr<policy::PolicyStatusProvider> machine_status_provider_;
   std::unique_ptr<policy::PolicyStatusProvider> updater_status_provider_;
 
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
   std::unique_ptr<policy::PolicyMap> updater_policies_;
-#endif  // defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#endif  // BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 
   std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_;
 
diff --git a/chrome/browser/ui/webui/print_preview/local_printer_handler_default.cc b/chrome/browser/ui/webui/print_preview/local_printer_handler_default.cc
index 89d80e5..d0abe4bc 100644
--- a/chrome/browser/ui/webui/print_preview/local_printer_handler_default.cc
+++ b/chrome/browser/ui/webui/print_preview/local_printer_handler_default.cc
@@ -25,11 +25,11 @@
 #include "printing/mojom/print.mojom.h"
 #include "printing/printing_features.h"
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #include "chrome/common/printing/printer_capabilities_mac.h"
 #endif
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 #include "base/threading/thread_restrictions.h"
 #endif
 
@@ -45,7 +45,7 @@
 
 scoped_refptr<base::TaskRunner> CreatePrinterHandlerTaskRunner() {
   // USER_VISIBLE because the result is displayed in the print preview dialog.
-#if !defined(OS_WIN)
+#if !BUILDFLAG(IS_WIN)
   static constexpr base::TaskTraits kTraits = {
       base::MayBlock(), base::TaskPriority::USER_VISIBLE};
 #endif
@@ -53,7 +53,7 @@
 #if defined(USE_CUPS)
   // CUPS is thread safe.
   return base::ThreadPool::CreateTaskRunner(kTraits);
-#elif defined(OS_WIN)
+#elif BUILDFLAG(IS_WIN)
   // Windows drivers are likely not thread-safe and need to be accessed on the
   // UI thread.
   return content::GetUIThreadTaskRunner(
@@ -147,7 +147,7 @@
 // static
 PrinterList LocalPrinterHandlerDefault::EnumeratePrintersAsync(
     const std::string& locale) {
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   // Blocking is needed here because Windows printer drivers are oftentimes
   // not thread-safe and have to be accessed on the UI thread.
   base::ScopedAllowBlocking allow_blocking;
@@ -170,11 +170,11 @@
     const std::string& device_name,
     const std::string& locale) {
   PrinterSemanticCapsAndDefaults::Papers user_defined_papers;
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   user_defined_papers = GetMacCustomPaperSizes();
 #endif
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   // Blocking is needed here because Windows printer drivers are oftentimes
   // not thread-safe and have to be accessed on the UI thread.
   base::ScopedAllowBlocking allow_blocking;
@@ -200,7 +200,7 @@
 // static
 std::string LocalPrinterHandlerDefault::GetDefaultPrinterAsync(
     const std::string& locale) {
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   // Blocking is needed here because Windows printer drivers are oftentimes
   // not thread-safe and have to be accessed on the UI thread.
   base::ScopedAllowBlocking allow_blocking;
diff --git a/chrome/browser/ui/webui/print_preview/pdf_printer_handler.cc b/chrome/browser/ui/webui/print_preview/pdf_printer_handler.cc
index c4442ea..e5dfa76 100644
--- a/chrome/browser/ui/webui/print_preview/pdf_printer_handler.cc
+++ b/chrome/browser/ui/webui/print_preview/pdf_printer_handler.cc
@@ -47,7 +47,7 @@
 #include "ui/gfx/geometry/size.h"
 #include "url/gurl.h"
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #include "chrome/common/printing/printer_capabilities_mac.h"
 #endif
 
@@ -242,7 +242,7 @@
                                            GetCapabilityCallback callback) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   // Read the Mac custom paper sizes on a separate thread.
   // USER_VISIBLE because the result is displayed in the print preview dialog.
   base::ThreadPool::PostTaskAndReplyWithResult(
@@ -332,9 +332,9 @@
 base::FilePath PdfPrinterHandler::GetFileNameForPrintJobTitle(
     const std::u16string& job_title) {
   DCHECK(!job_title.empty());
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   base::FilePath::StringType print_job_title(base::AsWString(job_title));
-#elif defined(OS_POSIX)
+#elif BUILDFLAG(IS_POSIX)
   base::FilePath::StringType print_job_title = base::UTF16ToUTF8(job_title);
 #endif
 
diff --git a/chrome/browser/ui/webui/print_preview/pdf_printer_handler_unittest.cc b/chrome/browser/ui/webui/print_preview/pdf_printer_handler_unittest.cc
index 74b46d3..df2eaf0 100644
--- a/chrome/browser/ui/webui/print_preview/pdf_printer_handler_unittest.cc
+++ b/chrome/browser/ui/webui/print_preview/pdf_printer_handler_unittest.cc
@@ -16,7 +16,7 @@
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #include "chrome/common/printing/printer_capabilities_mac.h"
 #include "printing/backend/print_backend.h"
 #include "ui/gfx/geometry/size.h"
@@ -122,7 +122,7 @@
   std::move(done_closure).Run();
 }
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 base::Value GetValueFromCustomPaper(
     const PrinterSemanticCapsAndDefaults::Paper& paper) {
   base::Value paper_value(base::Value::Type::DICTIONARY);
@@ -270,7 +270,7 @@
   EXPECT_EQ(expected_capability.value(), capability);
 }
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 TEST_F(PdfPrinterHandlerGetCapabilityTest,
        GetMacCustomPaperSizesInCapabilities) {
   constexpr char kPaperOptionPath[] = "capabilities.printer.media_size.option";
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
index 18682a7..029a4ee 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
@@ -78,7 +78,7 @@
 #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
 #include "third_party/icu/source/i18n/unicode/ulocdata.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 #include "chromeos/crosapi/mojom/local_printer.mojom.h"
 #include "components/account_manager_core/account_manager_facade.h"
 #include "components/account_manager_core/chromeos/account_manager_facade_factory.h"
@@ -171,7 +171,7 @@
 // Name of a dictionary pref holding the policy value for the paper size
 // setting.
 const char kMediaSize[] = "mediaSize";
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 // Name of a dictionary field holding policy value for the setting.
 const char kValue[] = "value";
 // Name of a dictionary pref holding the policy value for the sheets number.
@@ -182,7 +182,7 @@
 const char kDuplex[] = "duplex";
 // Name of a dictionary pref holding the policy value for the pin setting.
 const char kPin[] = "pin";
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 // Name of a dictionary field indicating whether the 'Save to PDF' destination
 // is disabled.
 const char kPdfPrinterDisabled[] = "pdfPrinterDisabled";
@@ -196,12 +196,12 @@
 // mounted.
 const char kIsDriveMounted[] = "isDriveMounted";
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
-#if defined(OS_WIN) || defined(OS_MAC)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
 // Name of a dictionary pref holding the policy value for whether the
 // "Print as image" option should be available to the user in the Print Preview
 // for a PDF job.
 const char kPrintPdfAsImageAvailability[] = "printPdfAsImageAvailability";
-#endif  // defined(OS_WIN) || defined(OS_MAC)
+#endif  // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
 // Name of dictionary pref holding policy value for whether the
 // "Print as image" option should default to set in Print Preview for
 // a PDF job.
@@ -225,7 +225,7 @@
 }
 
 UserActionBuckets DetermineUserAction(const base::Value& settings) {
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   if (settings.FindKey(kSettingOpenPDFInPreview))
     return UserActionBuckets::kOpenInMacPreview;
 #endif
@@ -262,7 +262,7 @@
   return UserActionBuckets::kPrintToPrinter;
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 base::Value PoliciesToValue(crosapi::mojom::PoliciesPtr ptr) {
   base::Value policies(base::Value::Type::DICTIONARY);
 
@@ -401,7 +401,7 @@
   if (!paper_size_policy.DictEmpty())
     policies.SetKey(kMediaSize, std::move(paper_size_policy));
 
-#if defined(OS_WIN) || defined(OS_MAC)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
   base::Value print_as_image_available_for_pdf_policy(
       base::Value::Type::DICTIONARY);
   if (prefs.HasPrefPath(prefs::kPrintPdfAsImageAvailability)) {
@@ -412,7 +412,7 @@
     policies.SetKey(kPrintPdfAsImageAvailability,
                     std::move(print_as_image_available_for_pdf_policy));
   }
-#endif  // defined(OS_WIN) || defined(OS_MAC)
+#endif  // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
 
   base::Value print_as_image_for_pdf_default_policy(
       base::Value::Type::DICTIONARY);
@@ -427,7 +427,7 @@
 
   return policies;
 }
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
 }  // namespace
 
@@ -534,7 +534,7 @@
 }
 
 void PrintPreviewHandler::ReadPrinterTypeDenyListFromPrefs() {
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   if (!local_printer_)
     return;
 
@@ -578,7 +578,7 @@
     deny_list.push_back(printer_type);
   }
   OnPrinterTypeDenyListReady(deny_list);
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 }
 
 void PrintPreviewHandler::OnPrinterTypeDenyListReady(
@@ -853,7 +853,7 @@
   Profile* profile = Profile::FromWebUI(web_ui());
   DCHECK(profile);
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   if (AccountConsistencyModeManager::IsMirrorEnabledForProfile(profile)) {
     // Chrome OS Account Manager is enabled on this Profile and hence, all
     // account management flows will go through native UIs and not through a
@@ -863,7 +863,7 @@
                                    AccountAdditionSource::kPrintPreviewDialog);
     return;
   }
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
   chrome::ScopedTabbedBrowserDisplayer displayer(profile);
   CreateCloudPrintSigninTab(
@@ -945,7 +945,7 @@
   base::OnceCallback<void(base::Value, const std::string&)> cb =
       base::BindOnce(&PrintPreviewHandler::SendInitialSettings,
                      weak_factory_.GetWeakPtr(), callback_id);
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   if (!local_printer_) {
     LOG(ERROR) << "Local printer not available";
     handler->GetDefaultPrinter(base::BindOnce(std::move(cb), base::Value()));
@@ -1305,7 +1305,7 @@
 }
 
 void PrintPreviewHandler::HandleManagePrinters(const base::ListValue* args) {
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   if (!local_printer_) {
     LOG(ERROR) << "Local printer not available";
     return;
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler.h b/chrome/browser/ui/webui/print_preview/print_preview_handler.h
index 633f9d1a..a79d692 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_handler.h
+++ b/chrome/browser/ui/webui/print_preview/print_preview_handler.h
@@ -15,6 +15,7 @@
 #include "base/gtest_prod_util.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
+#include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/common/buildflags.h"
 #include "components/prefs/pref_service.h"
@@ -26,7 +27,7 @@
 #include "printing/mojom/print.mojom.h"
 #include "printing/print_job_constants.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 namespace crosapi {
 namespace mojom {
 class DriveIntegrationService;
@@ -310,7 +311,7 @@
   // Used to transmit mojo interface method calls to the associated receiver.
   mojo::AssociatedRemote<mojom::PrintRenderFrame> print_render_frame_;
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   // Used to transmit mojo interface method calls to ash chrome.
   // Null if the interface is unavailable.
   // Note that this is not propagated to LocalPrinterHandlerLacros.
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler_unittest.cc b/chrome/browser/ui/webui/print_preview/print_preview_handler_unittest.cc
index 7061276..4b9d5d2 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_handler_unittest.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_handler_unittest.cc
@@ -22,6 +22,7 @@
 #include "base/test/icu_test_util.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/values.h"
+#include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/printing/print_test_utils.h"
 #include "chrome/browser/printing/print_view_manager.h"
@@ -47,7 +48,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 #include "chromeos/crosapi/mojom/local_printer.mojom.h"
 #endif
 
@@ -443,7 +444,7 @@
         ->PrintPreviewDone();
   }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   void DisableAshChrome() { handler_->local_printer_ = nullptr; }
 #endif
 
@@ -753,7 +754,7 @@
                                      absl::nullopt);
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 TEST_F(PrintPreviewHandlerTest, InitialSettingsNoAsh) {
   DisableAshChrome();
   Initialize();
@@ -976,7 +977,7 @@
       std::move(expected_initial_settings_policy));
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 TEST_F(PrintPreviewHandlerTest, InitialSettingsMaxSheetsAllowedPolicy) {
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
   crosapi::mojom::Policies policies;
@@ -1075,7 +1076,7 @@
   ValidateInitialSettingsAllowedDefaultModePolicy(
       *web_ui()->call_data().back(), "pin", absl::nullopt, base::Value(2));
 }
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
 TEST_F(PrintPreviewHandlerTest, GetPrinters) {
   Initialize();
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_ui.cc b/chrome/browser/ui/webui/print_preview/print_preview_ui.cc
index f35a751..da70f60 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_ui.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_ui.cc
@@ -72,7 +72,7 @@
 #include "ui/web_dialogs/web_dialog_delegate.h"
 #include "ui/web_dialogs/web_dialog_ui.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 #include "chrome/browser/ui/webui/print_preview/print_preview_handler_chromeos.h"
 #endif
 
@@ -91,9 +91,9 @@
 
 namespace {
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 const char16_t kBasicPrintShortcut[] = u"\u0028\u21e7\u2318\u0050\u0029";
-#elif !defined(OS_CHROMEOS)
+#elif !BUILDFLAG(IS_CHROMEOS)
 const char16_t kBasicPrintShortcut[] = u"(Ctrl+Shift+P)";
 #endif
 
@@ -274,7 +274,7 @@
     {"printButton", IDS_PRINT_PREVIEW_PRINT_BUTTON},
     {"printDestinationsTitle", IDS_PRINT_PREVIEW_PRINT_DESTINATIONS_TITLE},
     {"printPagesLabel", IDS_PRINT_PREVIEW_PRINT_PAGES_LABEL},
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
     {"printToGoogleDrive", IDS_PRINT_PREVIEW_PRINT_TO_GOOGLE_DRIVE},
 #endif
     {"printToPDF", IDS_PRINT_PREVIEW_PRINT_TO_PDF},
@@ -299,14 +299,14 @@
     {"selectButton", IDS_PRINT_PREVIEW_BUTTON_SELECT},
     {"seeMore", IDS_PRINT_PREVIEW_SEE_MORE},
     {"seeMoreDestinationsLabel", IDS_PRINT_PREVIEW_SEE_MORE_DESTINATIONS_LABEL},
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
     {"serverSearchBoxPlaceholder",
      IDS_PRINT_PREVIEW_SERVER_SEARCH_BOX_PLACEHOLDER},
 #endif
     {"title", IDS_PRINT_PREVIEW_TITLE},
     {"top", IDS_PRINT_PREVIEW_TOP_MARGIN_LABEL},
     {"unsupportedCloudPrinter", IDS_PRINT_PREVIEW_UNSUPPORTED_CLOUD_PRINTER},
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
     {"configuringFailedText", IDS_PRINT_CONFIGURING_FAILED_TEXT},
     {"configuringInProgressText", IDS_PRINT_CONFIGURING_IN_PROGRESS_TEXT},
     {"optionPin", IDS_PRINT_PREVIEW_OPTION_PIN},
@@ -331,7 +331,7 @@
     {"printerStatusStopped", IDS_PRINT_PREVIEW_PRINTER_STATUS_STOPPED},
     {"printerStatusTrayMissing", IDS_PRINT_PREVIEW_PRINTER_STATUS_TRAY_MISSING},
 #endif
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
     {"openPdfInPreviewOption", IDS_PRINT_PREVIEW_OPEN_PDF_IN_PREVIEW_APP},
     {"openingPDFInPreview", IDS_PRINT_PREVIEW_OPENING_PDF_IN_PREVIEW_APP},
 #endif
@@ -341,7 +341,7 @@
   source->AddString("gcpCertificateErrorLearnMoreURL",
                     chrome::kCloudPrintCertificateErrorLearnMoreURL);
 
-#if !defined(OS_CHROMEOS)
+#if !BUILDFLAG(IS_CHROMEOS)
   const std::u16string shortcut_text(kBasicPrintShortcut);
   source->AddString("systemDialogOption",
                     l10n_util::GetStringFUTF16(
@@ -358,7 +358,7 @@
 }
 
 void AddPrintPreviewFlags(content::WebUIDataSource* source, Profile* profile) {
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   source->AddBoolean("useSystemDefaultPrinter", false);
 #else
   bool system_default_printer = profile->GetPrefs()->GetBoolean(
@@ -398,7 +398,7 @@
 PrintPreviewHandler* CreatePrintPreviewHandlers(content::WebUI* web_ui) {
   auto handler = std::make_unique<PrintPreviewHandler>();
   PrintPreviewHandler* handler_ptr = handler.get();
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   web_ui->AddMessageHandler(std::make_unique<PrintPreviewHandlerChromeOS>());
 #endif
   web_ui->AddMessageHandler(std::move(handler));
@@ -410,7 +410,7 @@
       "printPreviewPageSummaryLabel", IDS_PRINT_PREVIEW_PAGE_SUMMARY_LABEL);
   plural_string_handler->AddLocalizedString(
       "printPreviewSheetSummaryLabel", IDS_PRINT_PREVIEW_SHEET_SUMMARY_LABEL);
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   plural_string_handler->AddLocalizedString(
       "sheetsLimitErrorMessage", IDS_PRINT_PREVIEW_SHEETS_LIMIT_ERROR_MESSAGE);
 #endif
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_ui_browsertest.cc b/chrome/browser/ui/webui/print_preview/print_preview_ui_browsertest.cc
index e477049..4062bbd 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_ui_browsertest.cc
@@ -26,7 +26,7 @@
 #include "printing/buildflags/buildflags.h"
 #include "url/url_constants.h"
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 #include "ui/aura/window.h"
 #include "ui/aura/window_tree_host.h"
 #endif
@@ -90,7 +90,7 @@
 }
 
 // Disable the test for mac, see http://crbug/367665.
-#if defined(OS_MAC) || defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
 #define MAYBE_TaskManagerNewPrintPreview DISABLED_TaskManagerNewPrintPreview
 #else
 #define MAYBE_TaskManagerNewPrintPreview TaskManagerNewPrintPreview
@@ -128,7 +128,7 @@
       WaitForTaskManagerRows(1, MatchPrint(url::kAboutBlankURL)));
 }
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 // http://crbug.com/396360
 IN_PROC_BROWSER_TEST_F(PrintPreviewBrowserTest,
                        DISABLED_NoCrashOnCloseWithOtherTabs) {
@@ -148,6 +148,6 @@
   browser()->tab_strip_model()->ActivateTabAt(
       1, {TabStripModel::GestureType::kOther});
 }
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 
 }  // namespace
diff --git a/chrome/browser/ui/webui/print_preview/printer_handler.cc b/chrome/browser/ui/webui/print_preview/printer_handler.cc
index 6735fca..460ef97 100644
--- a/chrome/browser/ui/webui/print_preview/printer_handler.cc
+++ b/chrome/browser/ui/webui/print_preview/printer_handler.cc
@@ -4,13 +4,14 @@
 
 #include "chrome/browser/ui/webui/print_preview/printer_handler.h"
 
+#include "build/build_config.h"
 #include "build/buildflag.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/ui/webui/print_preview/extension_printer_handler.h"
 #include "chrome/browser/ui/webui/print_preview/pdf_printer_handler.h"
 #include "chrome/common/buildflags.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 #include "chrome/browser/ui/webui/print_preview/local_printer_handler_chromeos.h"
 #else
 #include "chrome/browser/ui/webui/print_preview/local_printer_handler_default.h"
@@ -28,7 +29,7 @@
 std::unique_ptr<PrinterHandler> PrinterHandler::CreateForLocalPrinters(
     content::WebContents* preview_web_contents,
     Profile* profile) {
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   return LocalPrinterHandlerChromeos::Create(preview_web_contents);
 #else
   return std::make_unique<LocalPrinterHandlerDefault>(preview_web_contents);
@@ -53,7 +54,7 @@
   NOTREACHED();
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 void PrinterHandler::StartGetEulaUrl(const std::string& destination_id,
                                      GetEulaUrlCallback callback) {
   NOTREACHED();
diff --git a/chrome/browser/ui/webui/print_preview/printer_handler.h b/chrome/browser/ui/webui/print_preview/printer_handler.h
index daf3041..1ca0c39 100644
--- a/chrome/browser/ui/webui/print_preview/printer_handler.h
+++ b/chrome/browser/ui/webui/print_preview/printer_handler.h
@@ -12,6 +12,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/ref_counted_memory.h"
 #include "base/values.h"
+#include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/common/buildflags.h"
 
@@ -49,7 +50,7 @@
   using PrintCallback = base::OnceCallback<void(const base::Value& error)>;
   using GetPrinterInfoCallback =
       base::OnceCallback<void(const base::DictionaryValue& printer_info)>;
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   using GetEulaUrlCallback =
       base::OnceCallback<void(const std::string& license)>;
   using PrinterStatusRequestCallback =
@@ -111,7 +112,7 @@
                           scoped_refptr<base::RefCountedMemory> print_data,
                           PrintCallback callback) = 0;
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   // Starts getting the printer's PPD EULA URL with the provided destination ID.
   // |destination_id|: The ID of the printer.
   // |callback| should be called in response to the request.
diff --git a/chrome/browser/ui/webui/profile_helper_browsertest.cc b/chrome/browser/ui/webui/profile_helper_browsertest.cc
index 8e3991f..4304eca 100644
--- a/chrome/browser/ui/webui/profile_helper_browsertest.cc
+++ b/chrome/browser/ui/webui/profile_helper_browsertest.cc
@@ -112,7 +112,7 @@
   void SetUp() override {
     // Shortcut deletion delays tests shutdown on Win-7 and results in time out.
     // See crbug.com/1073451.
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
     AppShortcutManager::SuppressShortcutsForTesting();
 #endif
     InProcessBrowserTest::SetUp();
@@ -149,7 +149,7 @@
 // the same issue as BrowserWindowCocoa::Activate(), and execute call
 // BrowserList::SetLastActive() directly. Not sure if it is a bug or desired
 // behaviour.
-#if !defined(OS_MAC)
+#if !BUILDFLAG(IS_MAC)
   // Switch to original browser. Only LastActive should change.
   activation_observer =
       std::make_unique<ExpectBrowserActivationForProfile>(original_profile);
@@ -281,7 +281,7 @@
   }
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 INSTANTIATE_TEST_SUITE_P(DestroyProfileOnBrowserClose,
                          ProfileHelperTestWithDestroyProfile,
                          testing::Values(false));
@@ -289,4 +289,4 @@
 INSTANTIATE_TEST_SUITE_P(DestroyProfileOnBrowserClose,
                          ProfileHelperTestWithDestroyProfile,
                          testing::Bool());
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
diff --git a/chrome/browser/ui/webui/quota_internals/quota_internals_handler.cc b/chrome/browser/ui/webui/quota_internals/quota_internals_handler.cc
index 67c570a..d0322042 100644
--- a/chrome/browser/ui/webui/quota_internals/quota_internals_handler.cc
+++ b/chrome/browser/ui/webui/quota_internals/quota_internals_handler.cc
@@ -22,7 +22,7 @@
 namespace {
 
 bool IsStoragePressureEnabled() {
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   return false;
 #else
   return true;
diff --git a/chrome/browser/ui/webui/sandbox/sandbox_internals_ui.cc b/chrome/browser/ui/webui/sandbox/sandbox_internals_ui.cc
index 26c92703..ca29326 100644
--- a/chrome/browser/ui/webui/sandbox/sandbox_internals_ui.cc
+++ b/chrome/browser/ui/webui/sandbox/sandbox_internals_ui.cc
@@ -15,23 +15,23 @@
 #include "content/public/browser/web_ui.h"
 #include "content/public/browser/web_ui_data_source.h"
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 #include "chrome/browser/ui/webui/sandbox/sandbox_handler.h"
 #endif
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 #include "chrome/common/sandbox_status_extension_android.mojom.h"
 #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
 #endif
 
-#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
 #include "content/public/browser/zygote_host/zygote_host_linux.h"
 #include "sandbox/policy/sandbox.h"
 #endif
 
 namespace {
 
-#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
 static void SetSandboxStatusData(content::WebUIDataSource* source) {
   // Get expected sandboxing status of renderers.
   const int status =
@@ -71,7 +71,7 @@
   source->SetDefaultResource(IDR_SANDBOX_INTERNALS_HTML);
   source->AddResourcePath("sandbox_internals.js", IDR_SANDBOX_INTERNALS_JS);
 
-#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
   SetSandboxStatusData(source);
   source->UseStringsJs();
 #endif
@@ -83,7 +83,7 @@
 
 SandboxInternalsUI::SandboxInternalsUI(content::WebUI* web_ui)
     : content::WebUIController(web_ui) {
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   web_ui->AddMessageHandler(
       std::make_unique<sandbox_handler::SandboxHandler>());
 #endif
@@ -93,7 +93,7 @@
 
 void SandboxInternalsUI::WebUIRenderFrameCreated(
     content::RenderFrameHost* render_frame_host) {
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   mojo::AssociatedRemote<chrome::mojom::SandboxStatusExtension> sandbox_status;
   render_frame_host->GetRemoteAssociatedInterfaces()->GetInterface(
       &sandbox_status);
diff --git a/chrome/browser/ui/webui/settings/about_handler.cc b/chrome/browser/ui/webui/settings/about_handler.cc
index 1b7a5b1..56041037 100644
--- a/chrome/browser/ui/webui/settings/about_handler.cc
+++ b/chrome/browser/ui/webui/settings/about_handler.cc
@@ -337,7 +337,7 @@
       base::BindRepeating(&AboutHandler::HandleCheckInternetConnection,
                           base::Unretained(this)));
 #endif
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   web_ui()->RegisterDeprecatedMessageCallback(
       "promoteUpdater", base::BindRepeating(&AboutHandler::PromoteUpdater,
                                             base::Unretained(this)));
@@ -418,7 +418,7 @@
 #endif
 }
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 void AboutHandler::PromoteUpdater(const base::ListValue* args) {
   version_updater_->PromoteUpdater();
 }
@@ -650,12 +650,12 @@
   version_updater_->CheckForUpdate(
       base::BindRepeating(&AboutHandler::SetUpdateStatus,
                           base::Unretained(this)),
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
       base::BindRepeating(&AboutHandler::SetPromotionState,
                           base::Unretained(this)));
 #else
       VersionUpdater::PromoteCallback());
-#endif  // OS_MAC
+#endif  // BUILDFLAG(IS_MAC)
 }
 
 void AboutHandler::SetUpdateStatus(VersionUpdater::Status status,
@@ -693,7 +693,7 @@
   FireWebUIListener("update-status-changed", *event);
 }
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 void AboutHandler::SetPromotionState(VersionUpdater::PromotionState state) {
   // Worth noting: PROMOTE_DISABLED indicates that promotion is possible,
   // there's just something else going on right now (e.g. checking for update).
@@ -719,7 +719,7 @@
 
   FireWebUIListener("promotion-state-changed", promo_state);
 }
-#endif  // defined(OS_MAC)
+#endif  // BUILDFLAG(IS_MAC)
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 void AboutHandler::OnRegulatoryLabelDirFound(
diff --git a/chrome/browser/ui/webui/settings/about_handler.h b/chrome/browser/ui/webui/settings/about_handler.h
index 973f940..3e9c51d 100644
--- a/chrome/browser/ui/webui/settings/about_handler.h
+++ b/chrome/browser/ui/webui/settings/about_handler.h
@@ -74,7 +74,7 @@
   void HandleRefreshUpdateStatus(const base::ListValue* args);
   void RefreshUpdateStatus();
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   // Promotes the updater for all users.
   void PromoteUpdater(const base::ListValue* args);
 #endif
@@ -150,7 +150,7 @@
                        int64_t size,
                        const std::u16string& fail_message);
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   // Callback method which forwards promotion state to the page.
   void SetPromotionState(VersionUpdater::PromotionState state);
 #endif
diff --git a/chrome/browser/ui/webui/settings/appearance_handler.cc b/chrome/browser/ui/webui/settings/appearance_handler.cc
index 43f6381..86021bb 100644
--- a/chrome/browser/ui/webui/settings/appearance_handler.cc
+++ b/chrome/browser/ui/webui/settings/appearance_handler.cc
@@ -31,7 +31,7 @@
                           base::Unretained(this)));
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
-#if defined(OS_LINUX) && !BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS_LACROS)
   web_ui()->RegisterDeprecatedMessageCallback(
       "useSystemTheme",
       base::BindRepeating(&AppearanceHandler::HandleUseSystemTheme,
@@ -45,7 +45,7 @@
 
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
-#if defined(OS_LINUX) && !BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS_LACROS)
 void AppearanceHandler::HandleUseSystemTheme(const base::ListValue* args) {
   if (profile_->IsChild())
     NOTREACHED();
diff --git a/chrome/browser/ui/webui/settings/appearance_handler.h b/chrome/browser/ui/webui/settings/appearance_handler.h
index b30bca16..ab78d2b 100644
--- a/chrome/browser/ui/webui/settings/appearance_handler.h
+++ b/chrome/browser/ui/webui/settings/appearance_handler.h
@@ -44,7 +44,7 @@
 
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
-#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
   // Changes the UI theme of the browser to the system (GTK+) theme.
   void HandleUseSystemTheme(const base::ListValue* args);
 #endif
diff --git a/chrome/browser/ui/webui/settings/captions_handler.cc b/chrome/browser/ui/webui/settings/captions_handler.cc
index b00875a..a4ce773 100644
--- a/chrome/browser/ui/webui/settings/captions_handler.cc
+++ b/chrome/browser/ui/webui/settings/captions_handler.cc
@@ -22,7 +22,7 @@
 #include "ash/constants/ash_features.h"
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
-#if defined(OS_WIN) || defined(OS_MAC)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
 #include "chrome/browser/accessibility/caption_settings_dialog.h"
 #endif
 
@@ -68,7 +68,7 @@
 
 void CaptionsHandler::HandleOpenSystemCaptionsDialog(
     const base::ListValue* args) {
-#if defined(OS_WIN) || defined(OS_MAC)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
   captions::CaptionSettingsDialog::ShowCaptionSettingsDialog();
 #endif
 }
diff --git a/chrome/browser/ui/webui/settings/chrome_cleanup_handler_win.cc b/chrome/browser/ui/webui/settings/chrome_cleanup_handler_win.cc
index 64d4778..258053a 100644
--- a/chrome/browser/ui/webui/settings/chrome_cleanup_handler_win.cc
+++ b/chrome/browser/ui/webui/settings/chrome_cleanup_handler_win.cc
@@ -275,16 +275,16 @@
 
 void ChromeCleanupHandler::HandleGetMoreItemsPluralString(
     const base::ListValue* args) {
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
   GetPluralString(IDS_SETTINGS_RESET_CLEANUP_DETAILS_MORE, args);
-#endif  // defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#endif  // BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 }
 
 void ChromeCleanupHandler::HandleGetItemsToRemovePluralString(
     const base::ListValue* args) {
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
   GetPluralString(IDS_SETTINGS_RESET_CLEANUP_DETAILS_ITEMS_TO_BE_REMOVED, args);
-#endif  // defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#endif  // BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 }
 
 void ChromeCleanupHandler::GetPluralString(int id,
diff --git a/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.cc b/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.cc
index 9038f83..414efb5 100644
--- a/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.cc
@@ -7,8 +7,9 @@
 #include <utility>
 
 #include "ash/components/account_manager/account_manager_factory.h"
-#include "ash/public/cpp/toast_data.h"
-#include "ash/public/cpp/toast_manager.h"
+#include "ash/public/cpp/system/toast_catalog.h"
+#include "ash/public/cpp/system/toast_data.h"
+#include "ash/public/cpp/system/toast_manager.h"
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/logging.h"
@@ -86,8 +87,10 @@
   }
 }
 
-void ShowToast(const std::string& id, const std::u16string& message) {
-  ash::ToastManager::Get()->Show(ash::ToastData(id, message));
+void ShowToast(const std::string& id,
+               ash::ToastCatalogName catalog_name,
+               const std::u16string& message) {
+  ash::ToastManager::Get()->Show(ash::ToastData(id, catalog_name, message));
 }
 
 class AccountBuilder {
@@ -444,7 +447,7 @@
   const std::string email = email_value->GetString();
   DCHECK(!email.empty());
 
-  ShowToast(kAccountRemovedToastId,
+  ShowToast(kAccountRemovedToastId, ash::ToastCatalogName::kAccountRemoved,
             l10n_util::GetStringFUTF16(
                 IDS_SETTINGS_ACCOUNT_MANAGER_ACCOUNT_REMOVED_MESSAGE,
                 base::UTF8ToUTF16(email)));
diff --git a/chrome/browser/ui/webui/settings/font_handler.cc b/chrome/browser/ui/webui/settings/font_handler.cc
index c96e52e..01df8d9 100644
--- a/chrome/browser/ui/webui/settings/font_handler.cc
+++ b/chrome/browser/ui/webui/settings/font_handler.cc
@@ -22,14 +22,14 @@
 #include "content/public/browser/font_list_async.h"
 #include "content/public/browser/web_ui.h"
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #include "chrome/browser/ui/webui/settings/settings_utils.h"
 #endif
 
 namespace settings {
 
 FontHandler::FontHandler(Profile* profile) {
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   // Perform validation for saved fonts.
   settings_utils::ValidateSavedFonts(profile->GetPrefs());
 #endif
diff --git a/chrome/browser/ui/webui/settings/languages_handler.cc b/chrome/browser/ui/webui/settings/languages_handler.cc
index d9396ead..b04ed36 100644
--- a/chrome/browser/ui/webui/settings/languages_handler.cc
+++ b/chrome/browser/ui/webui/settings/languages_handler.cc
@@ -68,7 +68,7 @@
   AllowJavascript();
   CHECK_EQ(1U, args->GetList().size());
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   PrefService* prefs = g_browser_process->local_state();
   const std::string& language_code = args->GetList()[0].GetString();
   prefs->SetString(language::prefs::kApplicationLocale, language_code);
diff --git a/chrome/browser/ui/webui/settings/reset_settings_handler.cc b/chrome/browser/ui/webui/settings/reset_settings_handler.cc
index 11a1564..6437096 100644
--- a/chrome/browser/ui/webui/settings/reset_settings_handler.cc
+++ b/chrome/browser/ui/webui/settings/reset_settings_handler.cc
@@ -37,10 +37,10 @@
 #include "chrome/common/pref_names.h"
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 #include "chrome/browser/profile_resetter/triggered_profile_resetter.h"
 #include "chrome/browser/profile_resetter/triggered_profile_resetter_factory.h"
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 
 namespace settings {
 
@@ -271,7 +271,7 @@
   // Set up the localized strings for the triggered profile reset dialog.
   // Custom reset tool names are supported on Windows only.
   std::u16string reset_tool_name;
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   Profile* profile = Profile::FromWebUI(web_ui());
   TriggeredProfileResetter* triggered_profile_resetter =
       TriggeredProfileResetterFactory::GetForBrowserContext(profile);
@@ -282,7 +282,7 @@
     // Now that a reset UI has been shown, don't trigger again for this profile.
     triggered_profile_resetter->ClearResetTrigger();
   }
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 
   if (reset_tool_name.empty()) {
     reset_tool_name = l10n_util::GetStringUTF16(
diff --git a/chrome/browser/ui/webui/settings/safety_check_handler.cc b/chrome/browser/ui/webui/settings/safety_check_handler.cc
index 133069e..f8db9c8 100644
--- a/chrome/browser/ui/webui/settings/safety_check_handler.cc
+++ b/chrome/browser/ui/webui/settings/safety_check_handler.cc
@@ -14,6 +14,7 @@
 #include "base/metrics/user_metrics.h"
 #include "base/metrics/user_metrics_action.h"
 #include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/extensions/api/passwords_private/passwords_private_delegate_factory.h"
@@ -39,7 +40,7 @@
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/strings/grit/ui_strings.h"
 
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 #include "base/win/registry.h"
 #include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win.h"
 #include "components/chrome_cleaner/public/constants/constants.h"
@@ -58,7 +59,7 @@
 constexpr char kSafeBrowsingEvent[] =
     "safety-check-safe-browsing-status-changed";
 constexpr char kExtensionsEvent[] = "safety-check-extensions-status-changed";
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 constexpr char kChromeCleanerEvent[] =
     "safety-check-chrome-cleaner-status-changed";
 #endif
@@ -99,7 +100,7 @@
   }
 }
 
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 SafetyCheckHandler::ChromeCleanerStatus ConvertToChromeCleanerStatus(
     safe_browsing::ChromeCleanerController::State state,
     safe_browsing::ChromeCleanerController::IdleReason idle_reason,
@@ -170,7 +171,7 @@
   return base::Time::Now();
 }
 
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 base::Time TimestampDelegate::FetchChromeCleanerScanCompletionTimestamp() {
   // TODO(crbug.com/1139806): The cleaner scan completion timestamp is not
   // always written to the registry. As a workaround, it is also written to a
@@ -216,7 +217,7 @@
 SafetyCheckHandler::SafetyCheckHandler() = default;
 
 SafetyCheckHandler::~SafetyCheckHandler() {
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
   // It seems |OnJavascriptDisallowed| is not always called before the
   // deconstructor. Remove the CCT observer (no-op if not registered)
   // also here to ensure it does not stay registered.
@@ -240,7 +241,7 @@
   passwords_status_ = PasswordsStatus::kChecking;
   safe_browsing_status_ = SafeBrowsingStatus::kChecking;
   extensions_status_ = ExtensionsStatus::kChecking;
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
   // If the Chrome cleaner status results in the child being hidden,
   // then also hide it already in the "running" state.
   if (fetchChromeCleanerStatus(timestamp_delegate_).status ==
@@ -266,7 +267,7 @@
       kExtensionsEvent, static_cast<int>(extensions_status_),
       GetStringForExtensions(extensions_status_, Blocklisted(0),
                              ReenabledUser(0), ReenabledAdmin(0)));
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
   // Construct string without timestamp, using "null time" via |base::Time()|.
   FireBasicSafetyCheckWebUiListener(
       kChromeCleanerEvent, static_cast<int>(chrome_cleaner_status_),
@@ -336,7 +337,7 @@
   DCHECK(extension_service_);
   CheckExtensions();
 
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
   CheckChromeCleaner();
 #endif
 }
@@ -376,7 +377,7 @@
 
   // Send updated timestamp-based display strings to all SC children who have
   // such strings.
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
   // String update for Chrome Cleaner.
   base::DictionaryValue event;
   event.SetIntKey(kNewState, static_cast<int>(chrome_cleaner_status_));
@@ -467,7 +468,7 @@
   }
 }
 
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 void SafetyCheckHandler::CheckChromeCleaner() {
   if (safe_browsing::ChromeCleanerController::GetInstance()->HasObserver(
           this)) {
@@ -542,7 +543,7 @@
   CompleteParentIfChildrenCompleted();
 }
 
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 void SafetyCheckHandler::OnChromeCleanerCheckResult(
     SafetyCheckHandler::ChromeCleanerResult result) {
   base::DictionaryValue event;
@@ -735,7 +736,7 @@
   }
 }
 
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 std::u16string SafetyCheckHandler::GetStringForChromeCleaner(
     ChromeCleanerStatus status,
     base::Time cct_completion_time,
@@ -842,7 +843,7 @@
                                                    base::Time::Now());
 }
 
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 std::u16string SafetyCheckHandler::GetStringForChromeCleanerRan(
     base::Time cct_completion_time,
     base::Time system_time) {
@@ -995,7 +996,7 @@
   observed_insecure_credentials_manager_.Reset();
 }
 
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 void SafetyCheckHandler::OnIdle(
     safe_browsing::ChromeCleanerController::IdleReason idle_reason) {
   OnChromeCleanerCheckResult(fetchChromeCleanerStatus(timestamp_delegate_));
@@ -1045,7 +1046,7 @@
   // Destroy the version updater to prevent getting a callback and firing a
   // WebUI event, which would cause a crash.
   version_updater_.reset();
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
   // Remove |this| as an observer for the Chrome cleaner.
   safe_browsing::ChromeCleanerController::GetInstance()->RemoveObserver(this);
 #endif
@@ -1071,7 +1072,7 @@
       extensions_status_ == ExtensionsStatus::kChecking) {
     return;
   }
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
   if (chrome_cleaner_status_ == ChromeCleanerStatus::kChecking) {
     return;
   }
diff --git a/chrome/browser/ui/webui/settings/safety_check_handler.h b/chrome/browser/ui/webui/settings/safety_check_handler.h
index 21b55a5b..d249ec04 100644
--- a/chrome/browser/ui/webui/settings/safety_check_handler.h
+++ b/chrome/browser/ui/webui/settings/safety_check_handler.h
@@ -29,7 +29,7 @@
 #include "extensions/browser/extension_prefs.h"
 #include "extensions/browser/extension_registry.h"
 
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 #include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win.h"
 #include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_scanner_results_win.h"
 #endif
@@ -39,7 +39,7 @@
  public:
   virtual ~TimestampDelegate() = default;
   virtual base::Time GetSystemTime();
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
   virtual base::Time FetchChromeCleanerScanCompletionTimestamp();
 #endif
 };
@@ -49,7 +49,7 @@
 // software.
 class SafetyCheckHandler
     : public settings::SettingsPageUIHandler,
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
       public safe_browsing::ChromeCleanerController::Observer,
 #endif
       public password_manager::BulkLeakCheckServiceInterface::Observer,
@@ -134,7 +134,7 @@
   std::u16string GetStringForParentRan(base::Time safety_check_completion_time,
                                        base::Time system_time);
 
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
   // Constructs the string for the Chrome cleaner 'safe' state which depicts
   // how long ago its last check ran.
   std::u16string GetStringForChromeCleanerRan();
@@ -207,7 +207,7 @@
   // that case, if any of those were re-enabled.
   void CheckExtensions();
 
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
   // Checks for unwanted software via the Chrome Cleanup Tool. Only on Windows.
   void CheckChromeCleaner();
 #endif
@@ -223,7 +223,7 @@
                                Blocklisted blocklisted,
                                ReenabledUser reenabled_user,
                                ReenabledAdmin reenabled_admin);
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
   void OnChromeCleanerCheckResult(ChromeCleanerResult result);
 #endif
 
@@ -241,7 +241,7 @@
                                         Blocklisted blocklisted,
                                         ReenabledUser reenabled_user,
                                         ReenabledAdmin reenabled_admin);
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
   std::u16string GetStringForChromeCleaner(ChromeCleanerStatus status,
                                            base::Time cct_completion_time,
                                            base::Time system_time);
diff --git a/chrome/browser/ui/webui/settings/safety_check_handler_unittest.cc b/chrome/browser/ui/webui/settings/safety_check_handler_unittest.cc
index 8e5cdce..f18021e 100644
--- a/chrome/browser/ui/webui/settings/safety_check_handler_unittest.cc
+++ b/chrome/browser/ui/webui/settings/safety_check_handler_unittest.cc
@@ -48,7 +48,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 #include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win.h"
 #endif
 
@@ -56,7 +56,7 @@
 #include "ui/chromeos/devicetype_utils.h"
 #endif
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #include "base/mac/mac_util.h"
 #endif
 
@@ -66,7 +66,7 @@
 constexpr char kPasswords[] = "passwords";
 constexpr char kSafeBrowsing[] = "safe-browsing";
 constexpr char kExtensions[] = "extensions";
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 constexpr char kChromeCleaner[] = "chrome-cleaner";
 #endif
 
@@ -120,7 +120,7 @@
     return base::Time::FromDoubleT(1609459199).LocalMidnight() -
            base::Seconds(1);
   }
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
   base::Time FetchChromeCleanerScanCompletionTimestamp() override {
     // 2 seconds before midnight Dec 31st 2020.
     return base::Time::FromDoubleT(1609459199).LocalMidnight() -
@@ -272,7 +272,7 @@
   std::unordered_map<std::string, ExtensionState> state_map_;
 };
 
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 class TestChromeCleanerControllerDelegate
     : public safe_browsing::ChromeCleanerControllerDelegate {
  public:
@@ -320,7 +320,7 @@
   std::unique_ptr<TestingSafetyCheckHandler> safety_check_;
   base::HistogramTester histogram_tester_;
   base::test::ScopedFeatureList feature_list_;
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
   TestChromeCleanerControllerDelegate test_chrome_cleaner_controller_delegate_;
 #endif
 };
@@ -491,7 +491,7 @@
 
 TEST_F(SafetyCheckHandlerTest, CheckUpdates_Disabled) {
   const char* processor_variation = nullptr;
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   switch (base::mac::GetCPUType()) {
     case base::mac::CPUType::kIntel:
       processor_variation = " (x86_64)";
@@ -1387,7 +1387,7 @@
       SafetyCheckHandler::ExtensionsStatus::kBlocklistedReenabledSomeByUser, 1);
 }
 
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 class SafetyCheckHandlerChromeCleanerIdleTest
     : public SafetyCheckHandlerTest,
       public testing::WithParamInterface<
@@ -1686,7 +1686,7 @@
   }
 }
 
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 TEST_F(SafetyCheckHandlerTest, CheckChromeCleanerRanDisplayString) {
   // Test string without timestamp.
   base::Time null_time;
@@ -1775,7 +1775,7 @@
   test_leak_service_->set_state_and_notify(
       password_manager::BulkLeakCheckService::State::kSignedOut);
 
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
   // Set the Chrome cleaner mock response.
   safe_browsing::ChromeCleanerControllerImpl::ResetInstanceForTesting();
   safe_browsing::ChromeCleanerControllerImpl::GetInstance()->SetStateForTesting(
@@ -1789,7 +1789,7 @@
   ASSERT_TRUE(event_parent);
   VerifyDisplayString(event_parent, u"Safety check ran a moment ago");
 
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
   // Subsequent Chrome cleaner status updates without the user running safety
   // check again should not trigger further parent element completion events.
   safety_check_->OnIdle(safe_browsing::ChromeCleanerController::IdleReason::
diff --git a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
index 7301361..957b297 100644
--- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -116,11 +116,11 @@
 #include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom.h"
 #endif
 
-#if defined(OS_LINUX) && !BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS_LACROS)
 #include "ui/display/screen.h"
 #endif
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 #include "chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.h"
 #include "device/fido/win/webauthn_api.h"
 
@@ -130,13 +130,13 @@
 #include "chrome/grit/chrome_unscaled_resources.h"
 #include "ui/base/resource/resource_bundle.h"
 #endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING)
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 
 #if defined(USE_NSS_CERTS)
 #include "chrome/browser/ui/webui/certificate_manager_localized_strings_provider.h"
 #endif
 
-#if defined(OS_LINUX)
+#if BUILDFLAG(IS_LINUX)
 #include "ui/ozone/public/ozone_platform.h"
 #endif
 
@@ -241,7 +241,7 @@
   };
   html_source->AddLocalizedStrings(kLocalizedStrings);
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   html_source->AddBoolean("isWindows10OrNewer",
                           base::win::GetVersion() >= base::win::Version::WIN10);
 #endif
@@ -369,7 +369,7 @@
     {"huge", IDS_SETTINGS_HUGE_FONT_SIZE},
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
-#if defined(OS_LINUX) && !BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS_LACROS)
     {"systemTheme", IDS_SETTINGS_SYSTEM_THEME},
     {"useSystemTheme", IDS_SETTINGS_USE_SYSTEM_THEME},
     {"classicTheme", IDS_SETTINGS_CLASSIC_THEME},
@@ -377,10 +377,10 @@
 #else
     {"resetToDefaultTheme", IDS_SETTINGS_RESET_TO_DEFAULT_THEME},
 #endif
-#if defined(OS_LINUX) && !BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS_LACROS)
     {"showWindowDecorations", IDS_SHOW_WINDOW_DECORATIONS},
 #endif
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
     {"tabsToLinks", IDS_SETTINGS_TABS_TO_LINKS_PREF},
     {"warnBeforeQuitting", IDS_SETTINGS_WARN_BEFORE_QUITTING_PREF},
 #endif
@@ -398,7 +398,7 @@
 
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
-#if defined(OS_LINUX) && !BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS_LACROS)
   bool show_custom_chrome_frame = ui::OzonePlatform::GetInstance()
                                       ->GetPlatformRuntimeProperties()
                                       .supports_server_side_window_decorations;
@@ -541,7 +541,7 @@
                              IDS_SETTINGS_DOWNLOAD_WEB_DRIVE_LOCATION, kBox));
 }
 
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 void AddChromeCleanupStrings(content::WebUIDataSource* html_source) {
   const char16_t kUnwantedSoftwareProtectionWhitePaperUrl[] =
       u"https://www.google.ca/chrome/browser/privacy/"
@@ -666,11 +666,11 @@
   html_source->AddString("incompatibleApplicationsSubpageLearnHow",
                          learn_how_text);
 }
-#endif  // defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#endif  // BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 
 void AddResetStrings(content::WebUIDataSource* html_source, Profile* profile) {
   static constexpr webui::LocalizedString kLocalizedStrings[] = {
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
     {"resetPageTitle", IDS_SETTINGS_RESET_AND_CLEANUP},
 #else
     {"resetPageTitle", IDS_SETTINGS_RESET},
@@ -690,7 +690,7 @@
     {"resetAutomatedDialogTitle", IDS_SETTINGS_RESET_AUTOMATED_DIALOG_TITLE},
     {"resetProfileBannerButton", IDS_SETTINGS_RESET_BANNER_RESET_BUTTON_TEXT},
     {"resetProfileBannerDescription", IDS_SETTINGS_RESET_BANNER_TEXT},
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
     {"resetCleanupComputerTrigger",
      IDS_SETTINGS_RESET_CLEAN_UP_COMPUTER_TRIGGER},
 #endif
@@ -701,7 +701,7 @@
       "showResetProfileBanner",
       ResetSettingsHandler::ShouldShowResetProfileBanner(profile));
   bool is_reset_shortcuts_feature_enabled = false;
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   // TODO(crbug/1234599): Remove this flag from the JS.
   is_reset_shortcuts_feature_enabled = true;
 #endif
@@ -753,7 +753,7 @@
     {"removeLanguage", IDS_SETTINGS_LANGUAGES_LANGUAGES_LIST_REMOVE},
     {"addLanguages", IDS_SETTINGS_LANGUAGES_LANGUAGES_ADD},
     {"addLanguagesDialogTitle", IDS_SETTINGS_LANGUAGES_MANAGE_LANGUAGES_TITLE},
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
     {"isDisplayedInThisLanguage",
      IDS_SETTINGS_LANGUAGES_IS_DISPLAYED_IN_THIS_LANGUAGE},
     {"displayInThisLanguage", IDS_SETTINGS_LANGUAGES_DISPLAY_IN_THIS_LANGUAGE},
@@ -776,7 +776,7 @@
     // Managed dialog strings:
     {"languageManagedDialogTitle", IDS_SETTINGS_LANGUAGES_MANAGED_DIALOG_TITLE},
     {"languageManagedDialogBody", IDS_SETTINGS_LANGUAGES_MANAGED_DIALOG_BODY},
-#if !defined(OS_MAC)
+#if !BUILDFLAG(IS_MAC)
     {"spellCheckDisabledReason",
      IDS_SETTING_LANGUAGES_SPELL_CHECK_DISABLED_REASON},
     {"spellCheckLanguagesListTitle",
@@ -1749,12 +1749,12 @@
      IDS_SETTINGS_SAFETY_CHECK_EXTENSIONS_PRIMARY_LABEL},
     {"safetyCheckExtensionsButtonAriaLabel",
      IDS_SETTINGS_SAFETY_CHECK_EXTENSIONS_BUTTON_ARIA_LABEL},
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
     {"safetyCheckChromeCleanerPrimaryLabel",
      IDS_SETTINGS_SAFETY_CHECK_CHROME_CLEANER_PRIMARY_LABEL},
     {"safetyCheckChromeCleanerButtonAriaLabel",
      IDS_SETTINGS_SAFETY_CHECK_CHROME_CLEANER_BUTTON_ARIA_LABEL},
-#endif  // defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#endif  // BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
   };
   html_source->AddLocalizedStrings(kLocalizedStrings);
 }
@@ -2054,7 +2054,7 @@
      IDS_SETTINGS_SITE_SETTINGS_PROTECTED_CONTENT_BLOCKED},
     {"siteSettingsProtectedContentBlockedSubLabel",
      IDS_SETTINGS_SITE_SETTINGS_PROTECTED_CONTENT_BLOCKED_SUB_LABEL},
-#if BUILDFLAG(IS_CHROMEOS_ASH) || defined(OS_WIN)
+#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_WIN)
     {"siteSettingsProtectedContentIdentifiersExplanation",
      IDS_SETTINGS_SITE_SETTINGS_PROTECTED_CONTENT_IDENTIFIERS_EXPLANATION},
     {"siteSettingsProtectedContentEnableIdentifiers",
@@ -2713,7 +2713,7 @@
 void AddSystemStrings(content::WebUIDataSource* html_source) {
   static constexpr webui::LocalizedString kLocalizedStrings[] = {
     {"systemPageTitle", IDS_SETTINGS_SYSTEM},
-#if !defined(OS_MAC)
+#if !BUILDFLAG(IS_MAC)
     {"backgroundAppsLabel", IDS_SETTINGS_SYSTEM_BACKGROUND_APPS_LABEL},
 #endif
     {"hardwareAccelerationLabel",
@@ -2878,7 +2878,7 @@
   };
   html_source->AddLocalizedStrings(kSecurityKeysStrings);
   bool win_native_api_available = false;
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   win_native_api_available =
       base::FeatureList::IsEnabled(device::kWebAuthUseNativeWinApi) &&
       device::WinWebAuthnApi::GetDefault()->IsAvailable();
@@ -2907,10 +2907,10 @@
   AddAutofillStrings(html_source, profile, web_contents);
   AddAppearanceStrings(html_source, profile);
 
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
   AddChromeCleanupStrings(html_source);
   AddIncompatibleApplicationsStrings(html_source);
-#endif  // defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#endif  // BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 
   AddClearBrowsingDataStrings(html_source, profile);
   AddCommonStrings(html_source, profile);
diff --git a/chrome/browser/ui/webui/settings/settings_secure_dns_handler_browsertest.cc b/chrome/browser/ui/webui/settings/settings_secure_dns_handler_browsertest.cc
index 534791ae..041279f 100644
--- a/chrome/browser/ui/webui/settings/settings_secure_dns_handler_browsertest.cc
+++ b/chrome/browser/ui/webui/settings/settings_secure_dns_handler_browsertest.cc
@@ -23,7 +23,7 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 #include "base/win/win_util.h"
 #endif
 
@@ -103,7 +103,7 @@
   SecureDnsHandlerTest& operator=(const SecureDnsHandlerTest&) = delete;
 
  protected:
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   SecureDnsHandlerTest()
       // Mark as not enterprise managed to prevent the secure DNS mode from
       // being downgraded to off.
@@ -191,7 +191,7 @@
   testing::NiceMock<policy::MockConfigurationPolicyProvider> provider_;
 
  private:
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   base::win::ScopedDomainStateForTesting scoped_domain_;
 #endif
 };
@@ -269,7 +269,7 @@
 
 // On platforms where enterprise policies do not have default values, test
 // that DoH is disabled when non-DoH policies are set.
-#if !defined(OS_CHROMEOS)
+#if !BUILDFLAG(IS_CHROMEOS)
 IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, OtherPoliciesSet) {
   policy::PolicyMap policy_map;
   SetPolicyForPolicyKey(&policy_map, policy::key::kIncognitoModeAvailability,
diff --git a/chrome/browser/ui/webui/settings/settings_ui.cc b/chrome/browser/ui/webui/settings/settings_ui.cc
index 8001fe39..50fe425 100644
--- a/chrome/browser/ui/webui/settings/settings_ui.cc
+++ b/chrome/browser/ui/webui/settings/settings_ui.cc
@@ -79,7 +79,7 @@
 #include "printing/buildflags/buildflags.h"
 #include "ui/resources/grit/webui_resources.h"
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 #include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win.h"
 #include "chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.h"
 #include "chrome/browser/ui/webui/settings/chrome_cleanup_handler_win.h"
@@ -88,11 +88,11 @@
 #include "chrome/browser/win/conflicts/incompatible_applications_updater.h"
 #include "chrome/browser/win/conflicts/token_util.h"
 #endif
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 
-#if defined(OS_WIN) || BUILDFLAG(IS_CHROMEOS_ASH)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/ui/webui/settings/languages_handler.h"
-#endif  // defined(OS_WIN) || BUILDFLAG(IS_CHROMEOS_ASH)
+#endif  // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS_ASH)
 
 #if !BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_CHROMEOS_LACROS)
 #include "components/language/core/common/language_experiments.h"
@@ -136,12 +136,12 @@
 
 #if defined(USE_NSS_CERTS)
 #include "chrome/browser/ui/webui/certificates_handler.h"
-#elif defined(OS_WIN) || defined(OS_MAC)
+#elif BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
 #include "chrome/browser/ui/webui/settings/native_certificates_handler.h"
 #endif  // defined(USE_NSS_CERTS)
 
-#if defined(OS_WIN) || defined(OS_MAC) || \
-    (defined(OS_LINUX) && !BUILDFLAG(IS_CHROMEOS_LACROS))
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || \
+    (BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS_LACROS))
 #include "chrome/browser/ui/webui/settings/url_handlers_handler.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
 #endif
@@ -180,7 +180,7 @@
 #if defined(USE_NSS_CERTS)
   AddSettingsPageUIHandler(
       std::make_unique<certificate_manager::CertificatesHandler>());
-#elif defined(OS_WIN) || defined(OS_MAC)
+#elif BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
   AddSettingsPageUIHandler(std::make_unique<NativeCertificatesHandler>());
 #endif  // defined(USE_NSS_CERTS)
 #if BUILDFLAG(IS_CHROMEOS_ASH)
@@ -201,9 +201,9 @@
   AddSettingsPageUIHandler(std::make_unique<ImportDataHandler>());
   AddSettingsPageUIHandler(std::make_unique<HatsHandler>());
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   AddSettingsPageUIHandler(std::make_unique<LanguagesHandler>());
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   AddSettingsPageUIHandler(std::make_unique<LanguagesHandler>(profile));
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
@@ -240,19 +240,19 @@
   AddSettingsPageUIHandler(std::make_unique<SystemHandler>());
 #endif
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   AddSettingsPageUIHandler(std::make_unique<ChromeCleanupHandler>(profile));
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 
-#if defined(OS_WIN) || defined(OS_MAC) || \
-    (defined(OS_LINUX) && !BUILDFLAG(IS_CHROMEOS_LACROS))
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || \
+    (BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS_LACROS))
   if (web_app::WebAppProvider::GetForWebApps(profile) != nullptr) {
     AddSettingsPageUIHandler(std::make_unique<UrlHandlersHandler>(
         g_browser_process->local_state(), profile));
   }
 #endif
 
-#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
   bool has_incompatible_applications =
       IncompatibleApplicationsUpdater::HasCachedApplications();
   html_source->AddBoolean("showIncompatibleApplications",
@@ -262,7 +262,7 @@
   if (has_incompatible_applications)
     AddSettingsPageUIHandler(
         std::make_unique<IncompatibleApplicationsHandler>());
-#endif  // OS_WIN && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#endif  // BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 
   html_source->AddString(
       "enableBrandingUpdateAttribute",
diff --git a/chrome/browser/ui/webui/settings/settings_utils.cc b/chrome/browser/ui/webui/settings/settings_utils.cc
index 1349dc1..5e88ce1 100644
--- a/chrome/browser/ui/webui/settings/settings_utils.cc
+++ b/chrome/browser/ui/webui/settings/settings_utils.cc
@@ -42,7 +42,7 @@
   return font_name_or_list;
 }
 
-#if !defined(OS_WIN)
+#if !BUILDFLAG(IS_WIN)
 std::string MaybeGetLocalizedFontName(const std::string& font_name_or_list) {
   return ResolveFontList(font_name_or_list);
 }
diff --git a/chrome/browser/ui/webui/settings/settings_utils.h b/chrome/browser/ui/webui/settings/settings_utils.h
index bccc80a..4b4a930 100644
--- a/chrome/browser/ui/webui/settings/settings_utils.h
+++ b/chrome/browser/ui/webui/settings/settings_utils.h
@@ -41,7 +41,7 @@
 base::RefCountedMemory* GetPrivacySandboxFaviconResourceBytes(
     ui::ResourceScaleFactor scale_factor);
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 void ValidateSavedFonts(PrefService* prefs);
 #endif
 
diff --git a/chrome/browser/ui/webui/settings/site_settings_helper.cc b/chrome/browser/ui/webui/settings/site_settings_helper.cc
index 2aaaf04..3f151df 100644
--- a/chrome/browser/ui/webui/settings/site_settings_helper.cc
+++ b/chrome/browser/ui/webui/settings/site_settings_helper.cc
@@ -437,7 +437,7 @@
       ContentSettingsType::MIXEDSCRIPT,
       ContentSettingsType::NOTIFICATIONS,
       ContentSettingsType::POPUPS,
-#if defined(IS_CHROMEOS_ASH) || defined(OS_WIN)
+#if defined(IS_CHROMEOS_ASH) || BUILDFLAG(IS_WIN)
       ContentSettingsType::PROTECTED_MEDIA_IDENTIFIER,
 #endif
       ContentSettingsType::SENSORS,
diff --git a/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc b/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc
index 7a68181..6da1ddc5 100644
--- a/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc
+++ b/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc
@@ -83,10 +83,10 @@
 #include "net/base/url_util.h"
 #include "ui/base/l10n/l10n_util.h"
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 #include "base/strings/string_split.h"
 #include "chrome/credential_provider/common/gcp_strings.h"
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 
 namespace {
 
@@ -151,7 +151,7 @@
   }
 };
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 
 // Returns a list of valid signin domains that were passed in
 // |email_domains_parameter| as an argument to the gcpw signin dialog.
@@ -360,7 +360,7 @@
   if (reason == HandlerSigninReason::kFetchLstOnly) {
     // Constants are only available on Windows for the Google Credential
     // Provider for Windows.
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
     std::string json_retval;
     base::Value args(base::Value::Type::DICTIONARY);
     args.SetKey(credential_provider::kKeyEmail, base::Value(email_));
@@ -374,7 +374,7 @@
     handler_->SendLSTFetchResultsMessage(args);
 #else
     NOTREACHED() << "Google Credential Provider is only available on Windows";
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
     base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
     return;
   }
@@ -523,7 +523,7 @@
                    GaiaUrls::GetInstance()->oauth2_chrome_client_id());
   params.SetString("gaiaPath", url.path().substr(1));
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   if (reason == HandlerSigninReason::kFetchLstOnly) {
     std::string email_domains;
     if (net::GetValueForKeyInQuery(
@@ -573,7 +573,7 @@
       flow = "enterprisefsi";
       break;
     case HandlerSigninReason::kFetchLstOnly: {
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
       // Treat a sign in request that specifies a gaia id that must be validated
       // as a reauth request. We only get a gaia id from GCPW when trying to
       // reauth an existing user on the system.
@@ -701,7 +701,7 @@
   std::string validate_email;
   net::GetValueForKeyInQuery(params.url, "validateEmail", &validate_email);
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   if (reason == HandlerSigninReason::kFetchLstOnly) {
     std::string validate_gaia_id;
     net::GetValueForKeyInQuery(
@@ -796,7 +796,7 @@
 
   if (reason == HandlerSigninReason::kFetchLstOnly) {
     base::Value error_value(base::Value::Type::DICTIONARY);
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
     // If the error contains an integer error code, send it as part of the
     // result.
     if (error.type() ==
diff --git a/chrome/browser/ui/webui/signin/inline_login_ui.cc b/chrome/browser/ui/webui/signin/inline_login_ui.cc
index f8da340..3f711bf 100644
--- a/chrome/browser/ui/webui/signin/inline_login_ui.cc
+++ b/chrome/browser/ui/webui/signin/inline_login_ui.cc
@@ -230,7 +230,7 @@
       // Used by the profile picker.
       return true;
     case signin_metrics::Reason::kFetchLstOnly:
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
       // Used by the Google Credential Provider for Windows.
       return true;
 #else
diff --git a/chrome/browser/ui/webui/signin/signin_ui_error.cc b/chrome/browser/ui/webui/signin/signin_ui_error.cc
index 119a117a..eb3f6f4c 100644
--- a/chrome/browser/ui/webui/signin/signin_ui_error.cc
+++ b/chrome/browser/ui/webui/signin/signin_ui_error.cc
@@ -8,6 +8,7 @@
 
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
 #include "chrome/grit/chromium_strings.h"
 #include "chrome/grit/generated_resources.h"
 #include "google_apis/gaia/google_service_auth_error.h"
@@ -70,7 +71,7 @@
                        base::UTF8ToUTF16(error.ToString()));
 }
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 // static
 SigninUIError SigninUIError::FromCredentialProviderUiExitCode(
     const std::string& email,
@@ -112,7 +113,7 @@
   return another_profile_path_;
 }
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 credential_provider::UiExitCodes SigninUIError::credential_provider_exit_code()
     const {
   DCHECK(type() == Type::kFromCredentialProviderUiExitCode);
@@ -124,7 +125,7 @@
   bool result = std::tie(type_, email_, message_, another_profile_path_) ==
                 std::tie(other.type_, other.email_, other.message_,
                          other.another_profile_path_);
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   result = result && credential_provider_exit_code_ ==
                          other.credential_provider_exit_code_;
 #endif
diff --git a/chrome/browser/ui/webui/signin/signin_ui_error.h b/chrome/browser/ui/webui/signin/signin_ui_error.h
index 33006fcb..27caacc 100644
--- a/chrome/browser/ui/webui/signin/signin_ui_error.h
+++ b/chrome/browser/ui/webui/signin/signin_ui_error.h
@@ -10,7 +10,7 @@
 #include "base/files/file_path.h"
 #include "build/build_config.h"
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 #include "chrome/credential_provider/common/gcp_strings.h"
 #endif
 
@@ -51,7 +51,7 @@
   static SigninUIError FromGoogleServiceAuthError(
       const std::string& email,
       const GoogleServiceAuthError& error);
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   static SigninUIError FromCredentialProviderUiExitCode(
       const std::string& email,
       credential_provider::UiExitCodes exit_code);
@@ -72,7 +72,7 @@
   // `Type::kAccountAlreadyUsedByAnotherProfile`.
   const base::FilePath& another_profile_path() const;
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   // Should be called only if `type()` ==
   // `Type::kFromCredentialProviderUiExitCode`.
   credential_provider::UiExitCodes credential_provider_exit_code() const;
@@ -94,7 +94,7 @@
   // Defined only for Type::kAccountAlreadyUsedByAnotherProfile.
   base::FilePath another_profile_path_;
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   // Defined only for Type::kFromCredentialProviderUiExitCode.
   credential_provider::UiExitCodes credential_provider_exit_code_ =
       credential_provider::UiExitCodes::kUiecSuccess;
diff --git a/chrome/browser/ui/webui/tab_strip/tab_strip_ui_browsertest.cc b/chrome/browser/ui/webui/tab_strip/tab_strip_ui_browsertest.cc
index 3fca905..53f3ab5 100644
--- a/chrome/browser/ui/webui/tab_strip/tab_strip_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/tab_strip/tab_strip_ui_browsertest.cc
@@ -110,7 +110,7 @@
 // https://crbug.com/1246369: Test is flaky on Linux/Windows, disabled for
 // investigation.
 // https://crbug.com/1263485: Also flaky on chromeos.
-#if defined(OS_LINUX) || defined(OS_WIN) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS)
 #define MAYBE_ActivatingTabClosesEmbedder DISABLED_ActivatingTabClosesEmbedder
 #else
 #define MAYBE_ActivatingTabClosesEmbedder ActivatingTabClosesEmbedder
diff --git a/chrome/browser/ui/webui/version/version_ui.cc b/chrome/browser/ui/webui/version/version_ui.cc
index a16629b..ed92568 100644
--- a/chrome/browser/ui/webui/version/version_ui.cc
+++ b/chrome/browser/ui/webui/version/version_ui.cc
@@ -35,21 +35,21 @@
 #include "ui/base/webui/web_ui_util.h"
 #include "v8/include/v8-version-string.h"
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 #include "chrome/browser/ui/android/android_about_app_info.h"
-#else  // !defined(OS_ANDROID)
+#else
 #include "chrome/browser/ui/webui/theme_source.h"
 #endif
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 #include "chrome/browser/ui/webui/version/version_handler_chromeos.h"
-#endif  // defined(OS_CHROMEOS)
+#endif
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #include "base/mac/mac_util.h"
 #endif
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 #include "chrome/browser/ui/webui/version/version_handler_win.h"
 #endif
 
@@ -81,14 +81,14 @@
 #else
     {version_ui::kOSName, IDS_VERSION_UI_OS},
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
     {version_ui::kOsVersionHeaderText1, IDS_VERSION_UI_OS_TEXT1_LABEL},
     {version_ui::kOsVersionHeaderText2, IDS_VERSION_UI_OS_TEXT2_LABEL},
     {version_ui::kOsVersionHeaderLink, IDS_VERSION_UI_OS_LINK},
-#endif  // defined(OS_CHROMEOS)
-#if defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_CHROMEOS)
+#if BUILDFLAG(IS_ANDROID)
     {version_ui::kGmsName, IDS_VERSION_UI_GMS},
-#endif  // OS_ANDROID
+#endif  // BUILDFLAG(IS_ANDROID)
   };
   html_source->AddLocalizedStrings(kStrings);
 
@@ -99,13 +99,13 @@
   html_source->AddResourcePath(version_ui::kAboutVersionCSS,
                                IDR_VERSION_UI_CSS);
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   html_source->AddResourcePath(version_ui::kAboutVersionMobileCSS,
                                IDR_VERSION_UI_MOBILE_CSS);
   html_source->AddResourcePath("images/product_logo.png", IDR_PRODUCT_LOGO);
   html_source->AddResourcePath("images/product_logo_white.png",
                                IDR_PRODUCT_LOGO_WHITE);
-#endif  // defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_ANDROID)
   html_source->SetDefaultResource(IDR_VERSION_UI_HTML);
   return html_source;
 }
@@ -116,15 +116,15 @@
     : content::WebUIController(web_ui) {
   Profile* profile = Profile::FromWebUI(web_ui);
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   web_ui->AddMessageHandler(std::make_unique<VersionHandlerChromeOS>());
-#elif defined(OS_WIN)
+#elif BUILDFLAG(IS_WIN)
   web_ui->AddMessageHandler(std::make_unique<VersionHandlerWindows>());
 #else
   web_ui->AddMessageHandler(std::make_unique<VersionHandler>());
 #endif
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
   // Set up the chrome://theme/ source.
   content::URLDataSource::Add(profile, std::make_unique<ThemeSource>(profile));
 #endif
@@ -136,7 +136,7 @@
 
 // static
 int VersionUI::VersionProcessorVariation() {
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   // When building for Android, "unused" strings are removed. However, binaries
   // of both bitnesses are stripped of strings based on string analysis of one
   // bitness. Search the code for "generate_resource_allowlist" for more
@@ -145,8 +145,8 @@
   // never stripped. https://crbug.com/1119479
   IDS_VERSION_UI_32BIT;
   IDS_VERSION_UI_64BIT;
-#endif  // OS_ANDROID
-#if defined(OS_MAC)
+#endif  // BUILDFLAG(IS_ANDROID)
+#if BUILDFLAG(IS_MAC)
   switch (base::mac::GetCPUType()) {
     case base::mac::CPUType::kIntel:
       return IDS_VERSION_UI_64BIT_INTEL;
@@ -201,20 +201,20 @@
   html_source->AddString(version_ui::kExecutablePath, std::string());
   html_source->AddString(version_ui::kProfilePath, std::string());
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   html_source->AddString(version_ui::kOSType, base::mac::GetOSDisplayName());
 #elif !BUILDFLAG(IS_CHROMEOS_ASH)
   html_source->AddString(version_ui::kOSType, version_info::GetOSType());
-#endif  // OS_MAC
+#endif  // BUILDFLAG(IS_MAC)
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   html_source->AddString(version_ui::kOSVersion,
                          AndroidAboutAppInfo::GetOsInfo());
   html_source->AddString(version_ui::kGmsVersion,
                          AndroidAboutAppInfo::GetGmsInfo());
-#endif  // OS_ANDROID
+#endif  // BUILDFLAG(IS_ANDROID)
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   html_source->AddString(
       version_ui::kCommandLine,
       base::AsString16(
@@ -230,14 +230,14 @@
   html_source->AddString(version_ui::kCommandLine, command_line);
 #endif
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   html_source->AddString("linker", CHROMIUM_LINKER_NAME);
-#endif  // defined(OS_MAC)
+#endif  // BUILDFLAG(IS_MAC)
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   html_source->AddString(version_ui::kUpdateCohortName,
                          version_utils::win::GetCohortVersionInfo());
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 
   html_source->AddString(version_ui::kSanitizer,
                          version_info::GetSanitizerList());
diff --git a/chrome/browser/ui/webui/web_app_internals/web_app_internals_source.cc b/chrome/browser/ui/webui/web_app_internals/web_app_internals_source.cc
index 95eae71e..f8fdd9f 100644
--- a/chrome/browser/ui/webui/web_app_internals/web_app_internals_source.cc
+++ b/chrome/browser/ui/webui/web_app_internals/web_app_internals_source.cc
@@ -23,7 +23,7 @@
 #include "chrome/common/webui_url_constants.h"
 #include "components/prefs/pref_service.h"
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #include "chrome/browser/web_applications/app_shim_registry_mac.h"
 #endif
 
@@ -35,7 +35,7 @@
 constexpr char kExternallyManagedWebAppPrefs[] = "ExternallyManagedWebAppPrefs";
 constexpr char kIconErrorLog[] = "IconErrorLog";
 constexpr char kInstallationProcessErrorLog[] = "InstallationProcessErrorLog";
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 constexpr char kAppShimRegistryLocalStorage[] = "AppShimRegistryLocalStorage";
 #endif
 constexpr char kWebAppDirectoryDiskState[] = "WebAppDirectoryDiskState";
@@ -61,7 +61,7 @@
   index.Append(kExternallyManagedWebAppPrefs);
   index.Append(kIconErrorLog);
   index.Append(kInstallationProcessErrorLog);
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   index.Append(kAppShimRegistryLocalStorage);
 #endif
   index.Append(kWebAppDirectoryDiskState);
@@ -223,7 +223,7 @@
   return root;
 }
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 base::Value BuildAppShimRegistryLocalStorageJson() {
   base::Value root(base::Value::Type::DICTIONARY);
   root.SetKey(kAppShimRegistryLocalStorage,
@@ -259,7 +259,7 @@
   root.Append(BuildExternallyManagedWebAppPrefsJson(profile));
   root.Append(BuildIconErrorLogJson(*provider));
   root.Append(BuildInstallProcessErrorLogJson(*provider));
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   root.Append(BuildAppShimRegistryLocalStorageJson());
 #endif
   base::ThreadPool::PostTaskAndReplyWithResult(
diff --git a/chrome/browser/ui/webui/webui_util.cc b/chrome/browser/ui/webui/webui_util.cc
index 7aa822d..3298b3d 100644
--- a/chrome/browser/ui/webui/webui_util.cc
+++ b/chrome/browser/ui/webui/webui_util.cc
@@ -17,7 +17,7 @@
 #include "chrome/browser/ash/policy/core/browser_policy_connector_ash.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_process_platform_part.h"
-#elif defined(OS_WIN) || defined(OS_MAC)
+#elif BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
 #include "base/enterprise_util.h"
 #endif
 
@@ -59,7 +59,7 @@
   policy::BrowserPolicyConnectorAsh* connector =
       g_browser_process->platform_part()->browser_policy_connector_ash();
   return connector->IsDeviceEnterpriseManaged();
-#elif defined(OS_WIN) || defined(OS_MAC)
+#elif BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
   return base::IsMachineExternallyManaged();
 #else
   return false;
diff --git a/chrome/browser/ui/webui/webui_webview_browsertest.cc b/chrome/browser/ui/webui/webui_webview_browsertest.cc
index bc07887..2de57b7 100644
--- a/chrome/browser/ui/webui/webui_webview_browsertest.cc
+++ b/chrome/browser/ui/webui/webui_webview_browsertest.cc
@@ -29,7 +29,7 @@
 // Turn these tests off on Mac while we collect data on windows server crashes
 // on mac chromium builders.
 // http://crbug.com/653353
-#if !defined(OS_MAC)
+#if !BUILDFLAG(IS_MAC)
 
 #if !BUILDFLAG(IS_CHROMEOS_ASH) && defined(USE_AURA)
 #include "ui/aura/window.h"
@@ -443,4 +443,4 @@
 }
 #endif
 
-#endif  // !defined(OS_MAC)
+#endif  // !BUILDFLAG(IS_MAC)
diff --git a/chrome/browser/ui/webui/welcome/helpers.cc b/chrome/browser/ui/webui/welcome/helpers.cc
index caac59a..d96b5940 100644
--- a/chrome/browser/ui/webui/welcome/helpers.cc
+++ b/chrome/browser/ui/webui/welcome/helpers.cc
@@ -16,6 +16,7 @@
 #include "base/strings/string_util.h"
 #include "base/values.h"
 #include "build/branding_buildflags.h"
+#include "build/build_config.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/metrics/chrome_metrics_service_accessor.h"
 #include "chrome/browser/policy/browser_signin_policy_handler.h"
@@ -114,7 +115,7 @@
   return search::DefaultSearchProviderIsGoogle(profile);
 }
 
-#if BUILDFLAG(GOOGLE_CHROME_BRANDING) && defined(OS_WIN)
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING) && BUILDFLAG(IS_WIN)
 // These feature flags are used to tie our experiment to specific studies.
 // go/navi-app-variation for details.
 // TODO(hcarmona): find a solution that scales better.
@@ -146,10 +147,10 @@
   // "NaviOnboarding" match study name in configs.
   return base::GetFieldTrialParamValue("NaviOnboarding", "onboarding-group");
 }
-#endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING) && defined(OS_WIN)
+#endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING) && BUILDFLAG(IS_WIN)
 
 void JoinOnboardingGroup(Profile* profile) {
-#if BUILDFLAG(GOOGLE_CHROME_BRANDING) && defined(OS_WIN)
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING) && BUILDFLAG(IS_WIN)
   PrefService* prefs = profile->GetPrefs();
 
   std::string group;
@@ -180,7 +181,7 @@
     base::FeatureList::IsEnabled(kNaviNTPVariationEnabled);
   else if (group.compare("ShortcutVariationSynthetic-008") == 0)
     base::FeatureList::IsEnabled(kNaviShortcutVariationEnabled);
-#endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING) && defined(OS_WIN)
+#endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING) && BUILDFLAG(IS_WIN)
 }
 
 bool IsEnabled(Profile* profile) {
diff --git a/chrome/browser/ui/webui/welcome/welcome_ui.cc b/chrome/browser/ui/webui/welcome/welcome_ui.cc
index c49479e4..47deb10e 100644
--- a/chrome/browser/ui/webui/welcome/welcome_ui.cc
+++ b/chrome/browser/ui/webui/welcome/welcome_ui.cc
@@ -29,7 +29,7 @@
 #include "net/base/url_util.h"
 #include "ui/base/webui/web_ui_util.h"
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 #include "base/win/windows_version.h"
 #endif
 
@@ -141,7 +141,7 @@
                                IDR_PRODUCT_LOGO_24PX_1X);
 #endif
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   html_source->AddBoolean("is_win10",
                           base::win::GetVersion() >= base::win::Version::WIN10);
 #endif
diff --git a/chrome/browser/ui/window_sizer/window_sizer.cc b/chrome/browser/ui/window_sizer/window_sizer.cc
index 97895b3..5d95050 100644
--- a/chrome/browser/ui/window_sizer/window_sizer.cc
+++ b/chrome/browser/ui/window_sizer/window_sizer.cc
@@ -173,7 +173,7 @@
       browser, window_bounds, show_state);
 }
 
-#if !defined(OS_LINUX)
+#if !BUILDFLAG(IS_LINUX)
 // Linux has its own implementation, see WindowSizerLinux.
 // static
 void WindowSizer::GetBrowserWindowBoundsAndShowState(
@@ -194,7 +194,7 @@
   *bounds = specified_bounds;
   sizer.DetermineWindowBoundsAndShowState(specified_bounds, bounds, show_state);
 }
-#endif  // !defined(OS_LINUX)
+#endif  // !BUILDFLAG(IS_LINUX)
 
 void WindowSizer::DetermineWindowBoundsAndShowState(
     const gfx::Rect& specified_bounds,
@@ -271,7 +271,7 @@
                                kWindowMaxDefaultWidth);
   int default_height = work_area.height() - 2 * kWindowTilePixels;
 
-#if !defined(OS_MAC)
+#if !BUILDFLAG(IS_MAC)
   // For wider aspect ratio displays at higher resolutions, we might size the
   // window narrower to allow two windows to easily be placed side-by-side.
   gfx::Rect screen_size =
@@ -291,7 +291,7 @@
     default_width = static_cast<int>(work_area.width() / 2. -
         1.5 * kWindowTilePixels);
   }
-#endif  // !defined(OS_MAC)
+#endif  // !BUILDFLAG(IS_MAC)
   return gfx::Rect(kWindowTilePixels + work_area.x(),
                    kWindowTilePixels + work_area.y(), default_width,
                    default_height);
@@ -337,7 +337,7 @@
         bounds->y(), work_area.y(), work_area.bottom() - bounds->height()));
   }
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   // Limit the maximum height.  On the Mac the sizer is on the
   // bottom-right of the window, and a window cannot be moved "up"
   // past the menubar.  If the window is too tall you'll never be able
@@ -366,7 +366,7 @@
   // and migrate to base::clamp().
   bounds->set_y(BrokenClampThatShouldNotBeUsed(bounds->y(), min_y, max_y));
   bounds->set_x(BrokenClampThatShouldNotBeUsed(bounds->x(), min_x, max_x));
-#endif  // defined(OS_MAC)
+#endif  // BUILDFLAG(IS_MAC)
 }
 
 // static
diff --git a/chrome/browser/ui/window_sizer/window_sizer_common_unittest.cc b/chrome/browser/ui/window_sizer/window_sizer_common_unittest.cc
index 2812624c..eb2b345 100644
--- a/chrome/browser/ui/window_sizer/window_sizer_common_unittest.cc
+++ b/chrome/browser/ui/window_sizer/window_sizer_common_unittest.cc
@@ -122,7 +122,7 @@
       std::move(provider), passed_in, browser, out_bounds, &ignored);
 }
 
-#if !defined(OS_MAC)
+#if !BUILDFLAG(IS_MAC)
 
 #if !BUILDFLAG(IS_CHROMEOS_ASH)
 // Passing null for the browser parameter of GetWindowBounds makes the test skip
@@ -334,4 +334,4 @@
   }
 }
 
-#endif  // defined(OS_MAC)
+#endif  // !BUILDFLAG(IS_MAC)
diff --git a/chrome/browser/ui/window_sizer/window_sizer_unittest.cc b/chrome/browser/ui/window_sizer/window_sizer_unittest.cc
index 0aa9ec0..1f7afda 100644
--- a/chrome/browser/ui/window_sizer/window_sizer_unittest.cc
+++ b/chrome/browser/ui/window_sizer/window_sizer_unittest.cc
@@ -100,13 +100,13 @@
      // On all platforms except the Mac, for this size monitor the WindowSizer
      // returns a width that allows side-by-side positioning of two browser
      // windows.
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
     const int expected_window_width = WindowSizer::kWindowMaxDefaultWidth;
 #else
     const int window_width = 1680;
     const int expected_window_width =
         window_width / 2 - static_cast<int>(kWindowTilePixels * 1.5);
-#endif  // defined(OS_MAC)
+#endif  // BUILDFLAG(IS_MAC)
     gfx::Rect window_bounds;
     WindowSizerTestUtil::GetWindowBounds(p1680x1050, p1680x1050, gfx::Rect(),
                                          gfx::Rect(), gfx::Rect(), DEFAULT,
@@ -120,13 +120,13 @@
      // On all platforms except the Mac, for this size monitor the WindowSizer
      // returns a width that allows side-by-side positioning of two browser
      // windows.
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
     const int expected_window_width = WindowSizer::kWindowMaxDefaultWidth;
 #else
     const int window_width = 1920;
     const int expected_window_width =
         window_width / 2 - static_cast<int>(kWindowTilePixels * 1.5);
-#endif  // defined(OS_MAC)
+#endif  // BUILDFLAG(IS_MAC)
     gfx::Rect window_bounds;
     WindowSizerTestUtil::GetWindowBounds(p1920x1200, p1920x1200, gfx::Rect(),
                                          gfx::Rect(), gfx::Rect(), DEFAULT,
@@ -276,7 +276,7 @@
               window_bounds);
   }
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   { // Saved state is too tall to possibly be resized.  Mac resizers
     // are at the bottom of the window, and no piece of a window can
     // be moved higher than the menubar.  (Perhaps the user changed
@@ -288,7 +288,7 @@
         PERSISTED, NULL, gfx::Rect(), &window_bounds);
     EXPECT_EQ(p1024x768.height(), window_bounds.height());
   }
-#endif  // defined(OS_MAC)
+#endif  // BUILDFLAG(IS_MAC)
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -297,7 +297,7 @@
 // are run on Mac, and the *WithNonAggressiveRepositioning tests are run on
 // other platforms.
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 TEST(WindowSizerTest, LastWindowOffscreenWithAggressiveRepositioning) {
   { // taskbar on left.  The new window overlaps slightly with the taskbar, so
     // it is moved to be flush with the left edge of the work area.
@@ -498,7 +498,7 @@
   }
 
   // Linux does not tile windows, so tile adjustment tests don't make sense.
-#if !defined(OS_POSIX) || defined(OS_MAC)
+#if !BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_MAC)
   { // offset would put the new window offscreen at the bottom but the minimum
     // visibility condition is barely satisfied without relocation.
     gfx::Rect window_bounds;
@@ -547,7 +547,7 @@
     EXPECT_EQ(gfx::Rect(994 /* not 995 */, 738 /* not 739 */, 500, 400),
               window_bounds);
   }
-#endif  // !defined(OS_POSIX) || defined(OS_MAC)
+#endif  // !BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_MAC)
 }
 
-#endif  // defined(OS_MAC)
+#endif  // BUILDFLAG(IS_MAC)
diff --git a/chrome/browser/ui/zoom/zoom_controller_browsertest.cc b/chrome/browser/ui/zoom/zoom_controller_browsertest.cc
index a80918d..2457c55a 100644
--- a/chrome/browser/ui/zoom/zoom_controller_browsertest.cc
+++ b/chrome/browser/ui/zoom/zoom_controller_browsertest.cc
@@ -79,7 +79,7 @@
   }
 };  // ZoomControllerBrowserTest
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 #define MAYBE_CrashedTabsDoNotChangeZoom DISABLED_CrashedTabsDoNotChangeZoom
 #else
 #define MAYBE_CrashedTabsDoNotChangeZoom CrashedTabsDoNotChangeZoom
@@ -261,7 +261,7 @@
 }
 
 // Mac does not have touchscreen pinch.
-#if !defined(OS_MAC)
+#if !BUILDFLAG(IS_MAC)
 // Ensure that when a history navigation restores the page scale factor from a
 // previous pinch zoom, the browser is notified of the page scale restoration.
 IN_PROC_BROWSER_TEST_F(ZoomControllerBrowserTest,
@@ -338,7 +338,7 @@
   EXPECT_TRUE(chrome::CanResetZoom(web_contents));
   EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_NORMAL));
 }
-#endif  // !defined(OS_MAC)
+#endif  // !BUILDFLAG(IS_MAC)
 
 // TODO(https://crbug.com/1260291): Add support for Lacros.
 #if !BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_CHROMEOS_LACROS)
diff --git a/chrome/browser/vr/webxr_vr_input_browser_test.cc b/chrome/browser/vr/webxr_vr_input_browser_test.cc
index c24bcf9..4db803f 100644
--- a/chrome/browser/vr/webxr_vr_input_browser_test.cc
+++ b/chrome/browser/vr/webxr_vr_input_browser_test.cc
@@ -646,6 +646,8 @@
       return device_test::mojom::InteractionProfileType::kHPReverbG2;
     case device::OpenXrInteractionProfileType::kHandSelectGrasp:
       return device_test::mojom::InteractionProfileType::kHandSelectGrasp;
+    case device::OpenXrInteractionProfileType::kViveCosmos:
+      return device_test::mojom::InteractionProfileType::kViveCosmos;
     case device::OpenXrInteractionProfileType::kCount:
       return device_test::mojom::InteractionProfileType::kInvalid;
   }
diff --git a/chrome/browser/web_applications/web_app_file_handler_manager.cc b/chrome/browser/web_applications/web_app_file_handler_manager.cc
index babcb5e2..db0d180 100644
--- a/chrome/browser/web_applications/web_app_file_handler_manager.cc
+++ b/chrome/browser/web_applications/web_app_file_handler_manager.cc
@@ -83,14 +83,12 @@
     return;
   }
 
-#if BUILDFLAG(IS_MAC)
   // File handler registration is done via shortcuts creation on MacOS,
   // WebAppShortcutManager::BuildShortcutInfoForWebApp collects file handler
   // information to shortcut_info->file_handler_extensions, then used by MacOS
   // implementation of |internals::CreatePlatformShortcuts|. So we avoid
   // creating shortcuts twice here.
-  ALLOW_UNUSED_LOCAL(profile_);
-#else
+#if !BUILDFLAG(IS_MAC)
   const apps::FileHandlers* file_handlers = GetEnabledFileHandlers(app_id);
   if (file_handlers) {
     RegisterFileHandlersWithOs(app_id, GetRegistrar()->GetAppShortName(app_id),
diff --git a/chrome/browser/web_applications/web_app_file_handler_manager.h b/chrome/browser/web_applications/web_app_file_handler_manager.h
index 45d22ea8..a2b79eb 100644
--- a/chrome/browser/web_applications/web_app_file_handler_manager.h
+++ b/chrome/browser/web_applications/web_app_file_handler_manager.h
@@ -113,7 +113,7 @@
   static bool disable_automatic_file_handler_cleanup_for_testing_;
   bool disable_os_integration_for_testing_ = false;
 
-  const raw_ptr<Profile> profile_;
+  [[maybe_unused]] const raw_ptr<Profile> profile_;
   raw_ptr<WebAppSyncBridge> sync_bridge_ = nullptr;
 
   base::WeakPtrFactory<WebAppFileHandlerManager> weak_ptr_factory_{this};
diff --git a/chrome/browser/web_applications/web_app_install_manager_unittest.cc b/chrome/browser/web_applications/web_app_install_manager_unittest.cc
index cad377d..483490b1 100644
--- a/chrome/browser/web_applications/web_app_install_manager_unittest.cc
+++ b/chrome/browser/web_applications/web_app_install_manager_unittest.cc
@@ -10,7 +10,6 @@
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/callback_helpers.h"
-#include "base/compiler_specific.h"
 #include "base/containers/flat_set.h"
 #include "base/memory/raw_ptr.h"
 #include "base/run_loop.h"
@@ -376,8 +375,8 @@
   int GetNumFullyInstalledApps() const {
     int num_apps = 0;
 
-    for (const WebApp& app : fake_registry_controller_->registrar().GetApps()) {
-      ALLOW_UNUSED_LOCAL(app);
+    for ([[maybe_unused]] const WebApp& app :
+         fake_registry_controller_->registrar().GetApps()) {
       ++num_apps;
     }
 
diff --git a/chrome/browser/web_applications/web_app_registrar_unittest.cc b/chrome/browser/web_applications/web_app_registrar_unittest.cc
index a58e745..1fc9cb1 100644
--- a/chrome/browser/web_applications/web_app_registrar_unittest.cc
+++ b/chrome/browser/web_applications/web_app_registrar_unittest.cc
@@ -282,10 +282,10 @@
   Registry registry = CreateRegistryForTesting("https://example.com/path", 100);
   auto ids = RegisterAppsForTesting(std::move(registry));
 
-  for (const WebApp& web_app : mutable_registrar().FilterAppsMutable(
+  for ([[maybe_unused]] const WebApp& web_app :
+       mutable_registrar().FilterAppsMutable(
            [](const WebApp& web_app) { return false; })) {
     NOTREACHED();
-    ALLOW_UNUSED_LOCAL(web_app);
   }
 
   for (const WebApp& web_app : mutable_registrar().FilterAppsMutable(
@@ -317,8 +317,8 @@
   RegisterApp(std::move(web_app_in_sync2));
 
   int all_apps_count = 0;
-  for (const WebApp& web_app : registrar().GetAppsIncludingStubs()) {
-    ALLOW_UNUSED_LOCAL(web_app);
+  for ([[maybe_unused]] const WebApp& web_app :
+       registrar().GetAppsIncludingStubs()) {
     ++all_apps_count;
   }
   EXPECT_EQ(12, all_apps_count);
@@ -336,8 +336,7 @@
   UnregisterApp(web_app_id_in_sync2);
 
   not_in_sync_install_count = 0;
-  for (const WebApp& web_app : registrar().GetApps()) {
-    ALLOW_UNUSED_LOCAL(web_app);
+  for ([[maybe_unused]] const WebApp& web_app : registrar().GetApps()) {
     ++not_in_sync_install_count;
   }
   EXPECT_EQ(10, not_in_sync_install_count);
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index 7989270..0507e0aa8 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-main-1642507068-167d675bf148fb1197220db3a23067c047693dca.profdata
+chrome-linux-main-1642550315-109debcb95e05be97b1f2a74042e325a472f08ad.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index 523c724..609ca436 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-main-1642507068-3743159aa3e28736cb86ee101ae91d7b6e087ef4.profdata
+chrome-mac-main-1642528769-dbb43462ddeb0d1260e6ec2d2f9b006e8b9ec975.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index 32078baf..2d6212e 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1642517972-b0fbb5175050793ea8ac0b5679bdb492b56bf284.profdata
+chrome-win32-main-1642528769-f64a921f37803080ad5d6988a0f292c178dc8eaa.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index d25dd4a..af30e725 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1642517972-56e06703002ff94074041f7c00296ab1cf59ed71.profdata
+chrome-win64-main-1642539500-ca04c10767dc62e0b67cc500c6227b3b6ebc3c08.profdata
diff --git a/chrome/chrome_cleaner/engines/broker/cleaner_engine_requests_impl.h b/chrome/chrome_cleaner/engines/broker/cleaner_engine_requests_impl.h
index f5c4d1c..3196c7f 100644
--- a/chrome/chrome_cleaner/engines/broker/cleaner_engine_requests_impl.h
+++ b/chrome/chrome_cleaner/engines/broker/cleaner_engine_requests_impl.h
@@ -77,7 +77,7 @@
 
   scoped_refptr<MojoTaskRunner> mojo_task_runner_;
   mojo::AssociatedReceiver<mojom::CleanerEngineRequests> receiver_{this};
-  InterfaceMetadataObserver* metadata_observer_ = nullptr;
+  [[maybe_unused]] InterfaceMetadataObserver* metadata_observer_ = nullptr;
   std::unique_ptr<chrome_cleaner::FileRemoverAPI> file_remover_;
 };
 
diff --git a/chrome/chrome_cleaner/engines/broker/noop_cleaner_engine_requests_impl.cc b/chrome/chrome_cleaner/engines/broker/noop_cleaner_engine_requests_impl.cc
index 01577ad..57a655a 100644
--- a/chrome/chrome_cleaner/engines/broker/noop_cleaner_engine_requests_impl.cc
+++ b/chrome/chrome_cleaner/engines/broker/noop_cleaner_engine_requests_impl.cc
@@ -22,9 +22,7 @@
     std::unique_ptr<chrome_cleaner::FileRemoverAPI> file_remover)
     : mojo_task_runner_(mojo_task_runner),
       metadata_observer_(metadata_observer),
-      file_remover_(std::move(file_remover)) {
-  ANALYZER_ALLOW_UNUSED(metadata_observer_);
-}
+      file_remover_(std::move(file_remover)) {}
 
 CleanerEngineRequestsImpl::~CleanerEngineRequestsImpl() = default;
 
diff --git a/chrome/chrome_cleaner/ipc/mojo_task_runner.cc b/chrome/chrome_cleaner/ipc/mojo_task_runner.cc
index 468f297..6239901 100644
--- a/chrome/chrome_cleaner/ipc/mojo_task_runner.cc
+++ b/chrome/chrome_cleaner/ipc/mojo_task_runner.cc
@@ -16,11 +16,10 @@
 // static
 scoped_refptr<MojoTaskRunner> MojoTaskRunner::Create() {
   // Ensures thread-safe and unique initialization of the mojo lib.
-  static bool mojo_initialization = []() {  // Leaked.
+  [[maybe_unused]] static bool mojo_initialization = []() {  // Leaked.
     mojo::core::Init();
     return true;
   }();
-  ANALYZER_ALLOW_UNUSED(mojo_initialization);
 
   scoped_refptr<MojoTaskRunner> mojo_task_runner(new MojoTaskRunner());
   return mojo_task_runner->Initialize() ? mojo_task_runner : nullptr;
diff --git a/chrome/chrome_cleaner/os/disk_util.cc b/chrome/chrome_cleaner/os/disk_util.cc
index fddf038..5f3dd3a 100644
--- a/chrome/chrome_cleaner/os/disk_util.cc
+++ b/chrome/chrome_cleaner/os/disk_util.cc
@@ -336,7 +336,7 @@
 
 void InitializeDiskUtil() {
   // Only do this once.
-  static bool init_once = []() -> bool {
+  [[maybe_unused]] static bool init_once = []() -> bool {
     // Initialize the binary extension, so it can be used from different threads
     // without the initial creation race.
     DCHECK(g_active_extensions.empty());
@@ -346,7 +346,6 @@
     DCHECK(!g_active_extensions.empty());
     return true;
   }();
-  ANALYZER_ALLOW_UNUSED(init_once);
 }
 
 bool ExpandEnvPath(const base::FilePath& path, base::FilePath* expanded_path) {
diff --git a/chrome/chrome_cleaner/os/file_path_sanitization.cc b/chrome/chrome_cleaner/os/file_path_sanitization.cc
index a70a76e..69ada5d 100644
--- a/chrome/chrome_cleaner/os/file_path_sanitization.cc
+++ b/chrome/chrome_cleaner/os/file_path_sanitization.cc
@@ -177,7 +177,7 @@
 
 void InitializeFilePathSanitization() {
   // Only do this once.
-  static bool init_once = []() -> bool {
+  [[maybe_unused]] static bool init_once = []() -> bool {
     // Setup PathService to use OffsetCSIDLToPath so that SanitizePath can
     // benefit from the caching provided in PathService.
     base::PathService::RegisterProvider(&OffsetCSIDLToPath,
@@ -194,7 +194,6 @@
     sanitization_internal::initialize_file_path_sanitization_called = true;
     return true;
   }();
-  ANALYZER_ALLOW_UNUSED(init_once);
 }
 
 std::vector<base::FilePath> GetRewrittenPaths() {
diff --git a/chrome/common/channel_info.h b/chrome/common/channel_info.h
index eae9084..839d6e0 100644
--- a/chrome/common/channel_info.h
+++ b/chrome/common/channel_info.h
@@ -63,7 +63,7 @@
 // lack of support for extended stable on those configurations.
 bool IsExtendedStableChannel();
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 // Because the channel information on the Mac is baked into the Info.plist file,
 // and that file may change during an update, this function must be called
 // early in startup to cache the channel info so that the correct channel info
@@ -90,15 +90,15 @@
 void SetChannelIdForTesting(const std::string& channel_id);
 void ClearChannelIdForTesting();
 #endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING)
-#endif  // defined(OS_MAC)
+#endif  // BUILDFLAG(IS_MAC)
 
-#if defined(OS_FUCHSIA) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_FUCHSIA) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 // Set/clears information used in determining the browser's channel.
 void SetChannelForTesting(version_info::Channel, bool is_extended_stable);
 void ClearChannelForTesting();
-#endif  // defined(OS_FUCHSIA) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#endif  // BUILDFLAG(IS_FUCHSIA) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 
-#if defined(OS_POSIX) && !defined(OS_MAC) && !BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC) && !BUILDFLAG(IS_CHROMEOS_LACROS)
 // Returns a channel-specific suffix to use when constructing the path of the
 // default user data directory, allowing multiple channels to run side-by-side.
 // In the stable channel and in unbranded builds, this returns the empty string.
@@ -107,7 +107,7 @@
 
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
-#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
 // Returns the channel-specific filename of the desktop shortcut used to launch
 // the browser.
 std::string GetDesktopName(base::Environment* env);
diff --git a/chrome/common/channel_info_posix.cc b/chrome/common/channel_info_posix.cc
index 240a5dfd..5cd53f8 100644
--- a/chrome/common/channel_info_posix.cc
+++ b/chrome/common/channel_info_posix.cc
@@ -93,7 +93,7 @@
 
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
-#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
 std::string GetDesktopName(base::Environment* env) {
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
   // Google Chrome packaged as a snap is a special case: the application name
@@ -123,7 +123,7 @@
   return "chromium-browser.desktop";
 #endif
 }
-#endif  // defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
 
 version_info::Channel GetChannel() {
   return GetChannelImpl().channel;
diff --git a/chrome/common/channel_info_unittest.cc b/chrome/common/channel_info_unittest.cc
index ac9ada0..4039f9bc 100644
--- a/chrome/common/channel_info_unittest.cc
+++ b/chrome/common/channel_info_unittest.cc
@@ -116,15 +116,15 @@
   EXPECT_EQ(IsExtendedStableChannel(), GetParam().is_extended_stable);
 }
 
-#if defined(OS_WIN)
-#elif defined(OS_MAC)
+#if BUILDFLAG(IS_WIN)
+#elif BUILDFLAG(IS_MAC)
 
 TEST_P(ChannelInfoTest, GetChannelByName) {
   EXPECT_EQ(GetChannelByName(GetParam().channel_name_with_es),
             GetParam().channel);
 }
 
-#elif defined(OS_POSIX) && !BUILDFLAG(IS_CHROMEOS_LACROS)
+#elif BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_CHROMEOS_LACROS)
 
 TEST_P(ChannelInfoTest, GetChannelSuffixForDataDir) {
   EXPECT_EQ(GetChannelSuffixForDataDir(), GetParam().posix_data_dir_suffix);
@@ -170,8 +170,8 @@
                             version_info::Channel::DEV,
                             /*is_extended_stable=*/false,
                             /*posix_data_dir_suffix=*/"-unstable")));
-#if defined(OS_MAC) || defined(OS_WIN) || \
-    defined(OS_FUCHSIA)  // No canary channel on Linux.
+#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || \
+    BUILDFLAG(IS_FUCHSIA)  // No canary channel on Linux.
 INSTANTIATE_TEST_SUITE_P(
     Canary,
     ChannelInfoTest,
@@ -181,7 +181,7 @@
                             version_info::Channel::CANARY,
                             /*is_extended_stable=*/false,
                             /*posix_data_dir_suffix=*/"")));
-#endif  // defined(OS_MAC) || defined(OS_WIN)
+#endif  // BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
 #else   // BUILDFLAG(GOOGLE_CHROME_BRANDING)
 INSTANTIATE_TEST_SUITE_P(
     Chromium,
diff --git a/chrome/common/child_process_host_flags.h b/chrome/common/child_process_host_flags.h
index 8850e0b..64544376 100644
--- a/chrome/common/child_process_host_flags.h
+++ b/chrome/common/child_process_host_flags.h
@@ -13,12 +13,12 @@
 // Flags for Chrome specific child processes to resolve the appropriate process
 // via ChromeContentClient::GetChildProcessPath().
 enum ChildProcessHostFlags {
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   // Starts a child process with the macOS alert style to show notifications as
   // alerts instead of banners which are shown by the main app.
   kChildProcessHelperAlerts =
       content::ChildProcessHost::CHILD_EMBEDDER_FIRST + 1,
-#endif  // defined(OS_MAC)
+#endif  // BUILDFLAG(IS_MAC)
 };
 
 }  // namespace chrome
diff --git a/chrome/common/child_process_logging.h b/chrome/common/child_process_logging.h
index cf69a11..0a9e6cc 100644
--- a/chrome/common/child_process_logging.h
+++ b/chrome/common/child_process_logging.h
@@ -9,10 +9,10 @@
 
 namespace child_process_logging {
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 // Sets up the base/debug/crash_logging.h mechanism.
 void Init();
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 
 }  // namespace child_process_logging
 
diff --git a/chrome/common/chrome_constants.cc b/chrome/common/chrome_constants.cc
index 5e5e7a2..6fec2c1 100644
--- a/chrome/common/chrome_constants.cc
+++ b/chrome/common/chrome_constants.cc
@@ -11,7 +11,7 @@
 
 #define FPL FILE_PATH_LITERAL
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
 #define PRODUCT_STRING "Google Chrome"
 #elif BUILDFLAG(CHROMIUM_BRANDING)
@@ -19,7 +19,7 @@
 #else
 #error Unknown branding
 #endif
-#endif  // defined(OS_MAC)
+#endif  // BUILDFLAG(IS_MAC)
 
 namespace chrome {
 
@@ -42,60 +42,60 @@
 // in the UITest class we support switching to that version when told to
 // do so.
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 const base::FilePath::CharType kBrowserProcessExecutableName[] =
     FPL("chrome.exe");
 const base::FilePath::CharType kHelperProcessExecutableName[] =
     FPL("chrome.exe");
-#elif defined(OS_MAC)
+#elif BUILDFLAG(IS_MAC)
 const base::FilePath::CharType kBrowserProcessExecutableName[] =
     FPL(PRODUCT_STRING);
 const base::FilePath::CharType kHelperProcessExecutableName[] =
     FPL(PRODUCT_STRING " Helper");
-#elif defined(OS_ANDROID)
+#elif BUILDFLAG(IS_ANDROID)
 // NOTE: Keep it synced with the process names defined in AndroidManifest.xml.
 const base::FilePath::CharType kBrowserProcessExecutableName[] = FPL("chrome");
 const base::FilePath::CharType kHelperProcessExecutableName[] =
     FPL("sandboxed_process");
-#elif defined(OS_POSIX)
+#elif BUILDFLAG(IS_POSIX)
 const base::FilePath::CharType kBrowserProcessExecutableName[] = FPL("chrome");
 // Helper processes end up with a name of "exe" due to execing via
 // /proc/self/exe.  See bug 22703.
 const base::FilePath::CharType kHelperProcessExecutableName[] = FPL("exe");
 #endif  // OS_*
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 const base::FilePath::CharType kBrowserProcessExecutablePath[] =
     FPL("chrome.exe");
 const base::FilePath::CharType kHelperProcessExecutablePath[] =
     FPL("chrome.exe");
-#elif defined(OS_MAC)
+#elif BUILDFLAG(IS_MAC)
 const base::FilePath::CharType kBrowserProcessExecutablePath[] =
     FPL(PRODUCT_STRING ".app/Contents/MacOS/" PRODUCT_STRING);
 const base::FilePath::CharType kHelperProcessExecutablePath[] =
     FPL(PRODUCT_STRING " Helper.app/Contents/MacOS/" PRODUCT_STRING " Helper");
-#elif defined(OS_ANDROID)
+#elif BUILDFLAG(IS_ANDROID)
 const base::FilePath::CharType kBrowserProcessExecutablePath[] = FPL("chrome");
 const base::FilePath::CharType kHelperProcessExecutablePath[] = FPL("chrome");
-#elif defined(OS_POSIX)
+#elif BUILDFLAG(IS_POSIX)
 const base::FilePath::CharType kBrowserProcessExecutablePath[] = FPL("chrome");
 const base::FilePath::CharType kHelperProcessExecutablePath[] = FPL("chrome");
 #endif  // OS_*
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 const base::FilePath::CharType kFrameworkName[] =
     FPL(PRODUCT_STRING " Framework.framework");
 const base::FilePath::CharType kFrameworkExecutableName[] =
     FPL(PRODUCT_STRING " Framework");
 const char kMacHelperSuffixAlerts[] = " (Alerts)";
-#endif  // OS_MAC
+#endif  // BUILDFLAG(IS_MAC)
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 const base::FilePath::CharType kBrowserResourcesDll[] = FPL("chrome.dll");
 const base::FilePath::CharType kElfDll[] = FPL("chrome_elf.dll");
 const base::FilePath::CharType kStatusTrayWindowClass[] =
     FPL("Chrome_StatusTrayWindow");
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 
 const char kInitialProfile[] = "Default";
 const char kMultiProfileDirPrefix[] = "Profile ";
@@ -164,12 +164,12 @@
 const base::FilePath::CharType kReportingAndNelStoreFilename[] =
     FPL("Reporting and NEL");
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 const base::FilePath::CharType kJumpListIconDirname[] = FPL("JumpListIcons");
 #endif
 
 // directory names
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 const wchar_t kUserDataDirname[] = L"User Data";
 #endif
 
diff --git a/chrome/common/chrome_constants.h b/chrome/common/chrome_constants.h
index dee5b6d..0dc3a0a 100644
--- a/chrome/common/chrome_constants.h
+++ b/chrome/common/chrome_constants.h
@@ -20,7 +20,7 @@
 extern const base::FilePath::CharType kHelperProcessExecutableName[];
 extern const base::FilePath::CharType kBrowserProcessExecutablePath[];
 extern const base::FilePath::CharType kHelperProcessExecutablePath[];
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 // NOTE: if you change the value of kFrameworkName, please don't forget to
 // update components/test/run_all_unittests.cc as well.
 // TODO(tfarina): Remove the comment above, when you fix components to use plist
@@ -30,12 +30,12 @@
 // Suffix added to the helper app name to display alert notifications. Must be
 // kept in sync with the value in alert_helper_params (//chrome/BUILD.gn).
 extern const char kMacHelperSuffixAlerts[];
-#endif  // OS_MAC
-#if defined(OS_WIN)
+#endif  // BUILDFLAG(IS_MAC)
+#if BUILDFLAG(IS_WIN)
 extern const base::FilePath::CharType kBrowserResourcesDll[];
 extern const base::FilePath::CharType kElfDll[];
 extern const base::FilePath::CharType kStatusTrayWindowClass[];
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 
 extern const char kInitialProfile[];
 extern const char kMultiProfileDirPrefix[];
@@ -81,12 +81,12 @@
 extern const base::FilePath::CharType kVideoTutorialsStorageDirname[];
 extern const base::FilePath::CharType kWebAppDirname[];
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 extern const base::FilePath::CharType kJumpListIconDirname[];
 #endif
 
 // directory names
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 extern const wchar_t kUserDataDirname[];
 #endif
 
diff --git a/chrome/common/chrome_content_client.cc b/chrome/common/chrome_content_client.cc
index d0b86ae..9b71f51 100644
--- a/chrome/common/chrome_content_client.cc
+++ b/chrome/common/chrome_content_client.cc
@@ -61,12 +61,12 @@
 #include "ui/base/resource/resource_bundle.h"
 #include "url/url_constants.h"
 
-#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
 #include <fcntl.h>
 #include "sandbox/linux/services/credentials.h"
-#endif  // defined(OS_LINUX) || defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 #include "base/win/windows_version.h"
 #endif
 
@@ -88,7 +88,7 @@
 #include "chrome/common/media/cdm_host_file_path.h"
 #endif
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 #include "chrome/common/media/chrome_media_drm_bridge_client.h"
 #endif
 
@@ -266,7 +266,7 @@
 static const char* const kChromeStandardURLSchemes[] = {
     extensions::kExtensionScheme, chrome::kChromeNativeScheme,
     chrome::kChromeSearchScheme,  dom_distiller::kDomDistillerScheme,
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
     content::kAndroidAppScheme,
 #endif
 };
@@ -275,7 +275,7 @@
   for (auto* standard_scheme : kChromeStandardURLSchemes)
     schemes->standard_schemes.push_back(standard_scheme);
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   schemes->referrer_schemes.push_back(content::kAndroidAppScheme);
 #endif
 
@@ -317,7 +317,7 @@
   schemes->local_schemes.push_back(content::kExternalFileScheme);
 #endif
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   schemes->local_schemes.push_back(url::kContentScheme);
 #endif
 }
@@ -350,7 +350,7 @@
       resource_id);
 }
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 base::FilePath ChromeContentClient::GetChildProcessPath(
     int child_flags,
     const base::FilePath& helpers_path) {
@@ -365,7 +365,7 @@
   NOTREACHED() << "Unsupported child process flags!";
   return {};
 }
-#endif  // OS_MAC
+#endif  // BUILDFLAG(IS_MAC)
 
 std::string ChromeContentClient::GetProcessTypeNameInEnglish(int type) {
 #if BUILDFLAG(ENABLE_NACL)
@@ -392,11 +392,11 @@
   return origin_trial_policy_.get();
 }
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 media::MediaDrmBridgeClient* ChromeContentClient::GetMediaDrmBridgeClient() {
   return new ChromeMediaDrmBridgeClient();
 }
-#endif  // OS_ANDROID
+#endif  // BUILDFLAG(IS_ANDROID)
 
 void ChromeContentClient::ExposeInterfacesToBrowser(
     scoped_refptr<base::SequencedTaskRunner> io_task_runner,
diff --git a/chrome/common/chrome_content_client.h b/chrome/common/chrome_content_client.h
index 3ab707c..77a7c208 100644
--- a/chrome/common/chrome_content_client.h
+++ b/chrome/common/chrome_content_client.h
@@ -94,16 +94,16 @@
       ui::ResourceScaleFactor scale_factor) override;
   base::RefCountedMemory* GetDataResourceBytes(int resource_id) override;
   gfx::Image& GetNativeImageNamed(int resource_id) override;
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   base::FilePath GetChildProcessPath(
       int child_flags,
       const base::FilePath& helpers_path) override;
-#endif  // OS_MAC
+#endif  // BUILDFLAG(IS_MAC)
   std::string GetProcessTypeNameInEnglish(int type) override;
   blink::OriginTrialPolicy* GetOriginTrialPolicy() override;
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   media::MediaDrmBridgeClient* GetMediaDrmBridgeClient() override;
-#endif  // OS_ANDROID
+#endif  // BUILDFLAG(IS_ANDROID)
   void ExposeInterfacesToBrowser(
       scoped_refptr<base::SequencedTaskRunner> io_task_runner,
       mojo::BinderMap* binders) override;
diff --git a/chrome/common/chrome_descriptors.h b/chrome/common/chrome_descriptors.h
index dd14978..4721f6e 100644
--- a/chrome/common/chrome_descriptors.h
+++ b/chrome/common/chrome_descriptors.h
@@ -9,7 +9,7 @@
 #include "content/public/common/content_descriptors.h"
 
 enum {
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   kAndroidLocalePakDescriptor = kContentIPCDescriptorMax + 1,
   kAndroidSecondaryLocalePakDescriptor,
   kAndroidChrome100PercentPakDescriptor,
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
index 03dd5bd..5236fc4f 100644
--- a/chrome/common/chrome_features.cc
+++ b/chrome/common/chrome_features.cc
@@ -52,7 +52,7 @@
 const base::Feature kAlwaysReinstallSystemWebApps{
     "ReinstallSystemWebApps", base::FEATURE_DISABLED_BY_DEFAULT};
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 const base::Feature kAnonymousUpdateChecks{"AnonymousUpdateChecks",
                                            base::FEATURE_ENABLED_BY_DEFAULT};
 #endif
@@ -75,15 +75,15 @@
     "AppManagementIntentSettings", base::FEATURE_ENABLED_BY_DEFAULT};
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 // App Service related flags. See components/services/app_service/README.md.
 const base::Feature kAppServiceLoadIconWithoutMojom{
     "AppServiceLoadIconWithoutMojom", base::FEATURE_ENABLED_BY_DEFAULT};
 const base::Feature kAppServiceExtension{"AppServiceExtension",
                                          base::FEATURE_ENABLED_BY_DEFAULT};
-#endif  // !defined(OS_ANDROID)
+#endif  // !BUILDFLAG(IS_ANDROID)
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 // Can be used to disable RemoteCocoa (hosting NSWindows for apps in the app
 // process). For debugging purposes only.
 const base::Feature kAppShimRemoteCocoa{"AppShimRemoteCocoa",
@@ -94,26 +94,26 @@
 // https://crbug.com/1080729
 const base::Feature kAppShimNewCloseBehavior{"AppShimNewCloseBehavior",
                                              base::FEATURE_DISABLED_BY_DEFAULT};
-#endif  // defined(OS_MAC)
+#endif  // BUILDFLAG(IS_MAC)
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 // Controls whether ARC ghost window will be applied on ARC P version.
 const base::Feature kArcPiGhostWindow{"ArcPiGhostWindow",
                                       base::FEATURE_ENABLED_BY_DEFAULT};
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
 // Enables the built-in DNS resolver.
 const base::Feature kAsyncDns {
   "AsyncDns",
-#if defined(OS_CHROMEOS) || defined(OS_MAC) || defined(OS_ANDROID)
+#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_ANDROID)
       base::FEATURE_ENABLED_BY_DEFAULT
 #else
       base::FEATURE_DISABLED_BY_DEFAULT
 #endif
 };
 
-#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) || \
-    defined(OS_CHROMEOS) || defined(OS_FUCHSIA)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \
+    BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_FUCHSIA)
 // Enables or disables the Autofill survey triggered by opening a prompt to
 // save address info.
 const base::Feature kAutofillAddressSurvey{"AutofillAddressSurvey",
@@ -128,13 +128,13 @@
                                             base::FEATURE_DISABLED_BY_DEFAULT};
 #endif
 
-#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
 // Enables the Restart background mode optimization. When all Chrome UI is
 // closed and it goes in the background, allows to restart the browser to
 // discard memory.
 const base::Feature kBackgroundModeAllowRestart{
     "BackgroundModeAllowRestart", base::FEATURE_DISABLED_BY_DEFAULT};
-#endif  // defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 // Enable Borealis on Chrome OS.
@@ -145,13 +145,13 @@
 const base::Feature kChangePictureVideoMode{"ChangePictureVideoMode",
                                             base::FEATURE_ENABLED_BY_DEFAULT};
 
-#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
 // Controls whether Chrome Apps are supported. See https://crbug.com/1221251.
 // If the feature is disabled, Chrome Apps continue to work. If enabled, Chrome
 // Apps will not launch and will be marked in the UI as deprecated.
 const base::Feature kChromeAppsDeprecation{"ChromeAppsDeprecation",
                                            base::FEATURE_DISABLED_BY_DEFAULT};
-#endif  // defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX)
+#endif  // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
 
 const base::Feature kClientStorageAccessContextAuditing{
     "ClientStorageAccessContextAuditing", base::FEATURE_DISABLED_BY_DEFAULT};
@@ -159,7 +159,7 @@
 const base::Feature kConsolidatedSiteStorageControls{
     "ConsolidatedSiteStorageControls", base::FEATURE_DISABLED_BY_DEFAULT};
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 const base::Feature kContinuousSearch{"ContinuousSearch",
                                       base::FEATURE_DISABLED_BY_DEFAULT};
 #endif
@@ -223,7 +223,7 @@
     "CryptohomeUserDataAuthKillswitch", base::FEATURE_DISABLED_BY_DEFAULT};
 #endif
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 // Enables parsing and enforcing Data Leak Prevention policy rules that
 // restricts usage of some system features, e.g.clipboard, screenshot, etc.
 // for confidential content.
@@ -251,14 +251,14 @@
     "DMServerOAuthForChildUser", base::FEATURE_ENABLED_BY_DEFAULT};
 #endif
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 // Whether to allow installed-by-default web apps to be installed or not.
 const base::Feature kPreinstalledWebAppInstallation{
     "DefaultWebAppInstallation", base::FEATURE_ENABLED_BY_DEFAULT};
 #endif
 
-#if BUILDFLAG(IS_CHROMEOS_ASH) || defined(OS_MAC) || defined(OS_LINUX) || \
-    defined(OS_FUCHSIA)
+#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \
+    BUILDFLAG(IS_FUCHSIA)
 // Enables Desktop PWAs shortcuts menu to be visible and executable in ChromeOS,
 // MacOS and Linux.
 const base::Feature kDesktopPWAsAppIconShortcutsMenuUI{
@@ -305,7 +305,7 @@
 // Enables or disables Desktop PWAs to be auto-started on OS login.
 const base::Feature kDesktopPWAsRunOnOsLogin {
   "DesktopPWAsRunOnOsLogin",
-#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
       base::FEATURE_ENABLED_BY_DEFAULT
 #else
       base::FEATURE_DISABLED_BY_DEFAULT
@@ -338,8 +338,8 @@
 // Enable DNS over HTTPS (DoH).
 const base::Feature kDnsOverHttps {
   "DnsOverHttps",
-#if defined(OS_WIN) || defined(OS_CHROMEOS) || defined(OS_MAC) || \
-    defined(OS_ANDROID) || defined(OS_LINUX)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC) || \
+    BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX)
       base::FEATURE_ENABLED_BY_DEFAULT
 #else
       base::FEATURE_DISABLED_BY_DEFAULT
@@ -360,8 +360,8 @@
 // Sets whether the DoH setting is displayed in the settings UI.
 const base::FeatureParam<bool> kDnsOverHttpsShowUiParam {
   &kDnsOverHttps, "ShowUi",
-#if defined(OS_WIN) || defined(OS_CHROMEOS) || defined(OS_MAC) || \
-    defined(OS_ANDROID) || defined(OS_LINUX)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC) || \
+    BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX)
       true
 #else
       false
@@ -381,13 +381,13 @@
                                        base::FEATURE_DISABLED_BY_DEFAULT};
 #endif
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 // Enable loading native libraries earlier in startup on Android.
 const base::Feature kEarlyLibraryLoad{"EarlyLibraryLoad",
                                       base::FEATURE_DISABLED_BY_DEFAULT};
 #endif
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 // Under this flag Java bootstrap (aka startup) tasks that are run before native
 // initialization will not be specially prioritized by being posted at the front
 // of the Looper's queue.
@@ -396,7 +396,7 @@
     base::FEATURE_DISABLED_BY_DEFAULT};
 #endif
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 // Under this flag tab preloading at startup will be elided (i.e., not
 // performed).
 const base::Feature kElideTabPreloadAtStartup = {
@@ -408,7 +408,7 @@
 const base::Feature kEnableAllSystemWebApps{"EnableAllSystemWebApps",
                                             base::FEATURE_DISABLED_BY_DEFAULT};
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 // Enables users to create a desktop shortcut for incognito mode.
 const base::Feature kEnableIncognitoShortcutOnDesktop{
     "EnableIncognitoShortcutOnDesktop", base::FEATURE_DISABLED_BY_DEFAULT};
@@ -428,6 +428,13 @@
     "EnterpriseReportingExtensionManifestVersion",
     base::FEATURE_DISABLED_BY_DEFAULT};
 
+#if !defined(OS_ANDROID)
+// Lazy initialize IndividualSettings for extensions from enterprise policy
+// that are not installed.
+const base::Feature kExtensionDeferredIndividualSettings{
+    "ExtensionDeferredIndividualSettings", base::FEATURE_DISABLED_BY_DEFAULT};
+#endif
+
 // Controls whether the user justification text field is visible on the
 // extension request dialog.
 const base::Feature kExtensionWorkflowJustification{
@@ -455,7 +462,7 @@
 const base::Feature kGeoLanguage{"GeoLanguage",
                                  base::FEATURE_DISABLED_BY_DEFAULT};
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 // Gives Java tasks that are posted with the UiThreadTaskTraits.DEFAULT traits
 // user-blocking priority rather than their default user-visible priority.
 // See crbug.com/1259560.
@@ -464,7 +471,7 @@
     base::FEATURE_DISABLED_BY_DEFAULT};
 #endif
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 // Enables or disables the Happiness Tracking System demo mode for Desktop
 // Chrome.
 const base::Feature kHappinessTrackingSurveysForDesktopDemo{
@@ -556,7 +563,7 @@
         &kHappinessTrackingSurveysForDesktopWhatsNew, "whats-new-time",
         base::Seconds(20)};
 
-#endif  // !defined(OS_ANDROID)
+#endif  // !BUILDFLAG(IS_ANDROID)
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 // Enables or disables the Happiness Tracking System for the General survey.
@@ -596,12 +603,12 @@
 const base::Feature kHttpsOnlyMode{"HttpsOnlyMode",
                                    base::FEATURE_ENABLED_BY_DEFAULT};
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 const base::Feature kImmersiveFullscreen{"ImmersiveFullscreen",
                                          base::FEATURE_DISABLED_BY_DEFAULT};
 #endif
 
-#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
 const base::Feature kImproveAccessibilityTreeUsingLocalML{
     "ImproveAccessibilityTreeUsingLocalML", base::FEATURE_DISABLED_BY_DEFAULT};
 #endif
@@ -619,7 +626,7 @@
                                              base::FEATURE_ENABLED_BY_DEFAULT};
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 // A feature that controls whether Chrome warns about incompatible applications.
 // This feature requires Windows 10 or higher to work because it depends on
 // the "Apps & Features" system settings.
@@ -627,7 +634,7 @@
     "IncompatibleApplicationsWarning", base::FEATURE_DISABLED_BY_DEFAULT};
 #endif
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 // When enabled, keeps Incognito UI consistent regardless of any selected theme.
 const base::Feature kIncognitoBrandConsistencyForAndroid{
     "IncognitoBrandConsistencyForAndroid", base::FEATURE_DISABLED_BY_DEFAULT};
@@ -637,8 +644,8 @@
 const base::Feature kIncognitoNtpRevamp{"IncognitoNtpRevamp",
                                         base::FEATURE_DISABLED_BY_DEFAULT};
 
-#if defined(OS_MAC) || defined(OS_WIN) || defined(OS_LINUX) || \
-    defined(OS_CHROMEOS) || defined(OS_FUCHSIA)
+#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || \
+    BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_FUCHSIA)
 // When enabled, removes any theme or background customization done by the user
 // on the Incognito UI.
 const base::Feature kIncognitoBrandConsistencyForDesktop{
@@ -655,16 +662,16 @@
 const base::Feature kUpdateHistoryEntryPointsInIncognito{
     "UpdateHistoryEntryPointsInIncognito", base::FEATURE_DISABLED_BY_DEFAULT};
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 // Allow user to have preference for PWA in the intent picker.
 const base::Feature kIntentPickerPWAPersistence{
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   "IntentPickerPWAPersistence", base::FEATURE_ENABLED_BY_DEFAULT
 #else
   "IntentPickerPWAPersistence", base::FEATURE_DISABLED_BY_DEFAULT
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 };
-#endif  // !defined(OS_ANDROID)
+#endif  // !BUILDFLAG(IS_ANDROID)
 
 // If enabled, CloudPolicyInvalidator and RemoteCommandInvalidator instances
 // will have unique owner name.
@@ -680,12 +687,12 @@
                                    base::FEATURE_DISABLED_BY_DEFAULT};
 #endif
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 const base::Feature kLinkCapturingUiUpdate{"LinkCapturingUiUpdate",
                                            base::FEATURE_DISABLED_BY_DEFAULT};
 #endif
 
-#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS)
 COMPONENT_EXPORT(CHROME_FEATURES)
 const base::Feature kLinuxLowMemoryMonitor{"LinuxLowMemoryMonitor",
                                            base::FEATURE_DISABLED_BY_DEFAULT};
@@ -696,9 +703,9 @@
     &kLinuxLowMemoryMonitor, "moderate_level", 50};
 constexpr base::FeatureParam<int> kLinuxLowMemoryMonitorCriticalLevel{
     &kLinuxLowMemoryMonitor, "critical_level", 255};
-#endif  // defined(OS_LINUX) && !defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS)
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 // Uses NSFullSizeContentViewWindowMask where available instead of adding our
 // own views to the window frame. This is a temporary kill switch, it can be
 // removed once we feel okay about leaving it on.
@@ -707,13 +714,13 @@
 
 #endif
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 // Enables the Material Design download shelf on Mac.
 const base::Feature kMacMaterialDesignDownloadShelf{
     "MacMDDownloadShelf", base::FEATURE_ENABLED_BY_DEFAULT};
 #endif
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 // Enable screen capture system permission check on Mac 10.15+.
 const base::Feature kMacSystemScreenCapturePermissionCheck{
     "MacSystemScreenCapturePermissionCheck", base::FEATURE_ENABLED_BY_DEFAULT};
@@ -731,7 +738,7 @@
                                              base::FEATURE_ENABLED_BY_DEFAULT};
 #endif
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 // Enables the new design of metrics settings.
 const base::Feature kMetricsSettingsAndroid{"MetricsSettingsAndroid",
                                             base::FEATURE_DISABLED_BY_DEFAULT};
@@ -761,32 +768,32 @@
                                          base::FEATURE_ENABLED_BY_DEFAULT};
 #endif  // BUILDFLAG(ENABLE_SYSTEM_NOTIFICATIONS)
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 // Enables the usage of Apple's new Notification API on macOS 10.14+
 const base::Feature kNewMacNotificationAPI{"NewMacNotificationAPI",
                                            base::FEATURE_DISABLED_BY_DEFAULT};
-#endif  // OS_MAC
+#endif  // BUILDFLAG(IS_MAC)
 
 // When kNoReferrers is enabled, most HTTP requests will provide empty
 // referrers instead of their ordinary behavior.
 const base::Feature kNoReferrers{"NoReferrers",
                                  base::FEATURE_DISABLED_BY_DEFAULT};
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 // Changes behavior of requireInteraction for notifications. Instead of staying
 // on-screen until dismissed, they are instead shown for a very long time.
 const base::Feature kNotificationDurationLongForRequireInteraction{
     "NotificationDurationLongForRequireInteraction",
     base::FEATURE_DISABLED_BY_DEFAULT};
-#endif  // OS_WIN
+#endif  // BUILDFLAG(IS_WIN)
 
-#if defined(OS_POSIX)
+#if BUILDFLAG(IS_POSIX)
 // Enables NTLMv2, which implicitly disables NTLMv1.
 const base::Feature kNtlmV2Enabled{"NtlmV2Enabled",
                                    base::FEATURE_ENABLED_BY_DEFAULT};
 #endif
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 const base::Feature kOnConnectNative{"OnConnectNative",
                                      base::FEATURE_DISABLED_BY_DEFAULT};
 #endif
@@ -801,7 +808,7 @@
     "kOobeMarketingDoubleOptInCountriesSupported",
     base::FEATURE_ENABLED_BY_DEFAULT};
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 // Enables or disabled the OOM intervention.
 const base::Feature kOomIntervention{"OomIntervention",
                                      base::FEATURE_ENABLED_BY_DEFAULT};
@@ -903,7 +910,7 @@
     "RemoveSupervisedUsersOnStartup", base::FEATURE_DISABLED_BY_DEFAULT};
 #endif
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 const base::Feature kRequestDesktopSiteForTablets{
     "RequestDesktopSiteForTablets", base::FEATURE_DISABLED_BY_DEFAULT};
 #endif
@@ -914,14 +921,14 @@
                                             base::FEATURE_DISABLED_BY_DEFAULT};
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 const base::Feature kScrollCapture{"ScrollCapture",
                                    base::FEATURE_ENABLED_BY_DEFAULT};
 #endif
 
 // Controls whether SCT audit reports are queued and the rate at which they
 // should be sampled. Default sampling rate is 1/10,000 certificates.
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 const base::Feature kSCTAuditing{"SCTAuditing",
                                  base::FEATURE_DISABLED_BY_DEFAULT};
 #else
@@ -948,19 +955,19 @@
     "SharesheetCopyToClipboard", base::FEATURE_ENABLED_BY_DEFAULT};
 #endif
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 const base::Feature kShareUsageRanking{"ShareUsageRanking",
                                        base::FEATURE_DISABLED_BY_DEFAULT};
 const base::Feature kShareUsageRankingFixedMore{
     "ShareUsageRankingFixedMore", base::FEATURE_ENABLED_BY_DEFAULT};
 #endif
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 // Enables the "this OS is obsolete" infobar on Mac 10.10.
 // TODO(ellyjones): Remove this after the last 10.10 release.
 const base::Feature kShow10_10ObsoleteInfobar{
     "Show1010ObsoleteInfobar", base::FEATURE_DISABLED_BY_DEFAULT};
-#endif  // defined(OS_MAC)
+#endif  // BUILDFLAG(IS_MAC)
 
 // Alternative to switches::kSitePerProcess, for turning on full site isolation.
 // Launch bug: https://crbug.com/810843.  This is a //chrome-layer feature to
@@ -971,7 +978,7 @@
 // browser_features, as they are only used on the browser side.
 const base::Feature kSitePerProcess {
   "SitePerProcess",
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
       base::FEATURE_DISABLED_BY_DEFAULT
 #else
       base::FEATURE_ENABLED_BY_DEFAULT
@@ -1003,13 +1010,13 @@
                                        base::FEATURE_ENABLED_BY_DEFAULT};
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 // Enables logging UKMs for background tab activity by TabActivityWatcher.
 const base::Feature kTabMetricsLogging{"TabMetricsLogging",
                                        base::FEATURE_ENABLED_BY_DEFAULT};
 #endif
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 // Enables the blocking of third-party modules. This feature requires Windows 8
 // or higher because it depends on the ProcessExtensionPointDisablePolicy
 // mitigation, which was not available on Windows 7.
@@ -1024,7 +1031,7 @@
 const base::Feature kTreatUnsafeDownloadsAsActive{
     "TreatUnsafeDownloadsAsActive", base::FEATURE_ENABLED_BY_DEFAULT};
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 // Enables surveying of users of Trust & Safety features with HaTS.
 const base::Feature kTrustSafetySentimentSurvey{
     "TrustSafetySentimentSurvey", base::FEATURE_DISABLED_BY_DEFAULT};
@@ -1099,10 +1106,10 @@
                                               base::FEATURE_ENABLED_BY_DEFAULT};
 #endif
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 const base::Feature kWebAppManifestIconUpdating{
     "WebAppManifestIconUpdating", base::FEATURE_DISABLED_BY_DEFAULT};
-#endif  // defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_ANDROID)
 
 const base::Feature kWebAppManifestPolicyAppIdentityUpdate{
     "WebAppManifestPolicyAppIdentityUpdate", base::FEATURE_ENABLED_BY_DEFAULT};
@@ -1122,7 +1129,7 @@
                                     base::FEATURE_DISABLED_BY_DEFAULT};
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 // Allow capturing of WebRTC event logs, and uploading of those logs to Crash.
 // Please note that a Chrome policy must also be set, for this to have effect.
 // Effectively, this is a kill-switch for the feature.
@@ -1134,12 +1141,12 @@
     "WebRtcRemoteEventLogGzipped", base::FEATURE_ENABLED_BY_DEFAULT};
 #endif
 
-#if defined(OS_WIN) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS)
 // Enables Web Share (navigator.share)
 const base::Feature kWebShare{"WebShare", base::FEATURE_ENABLED_BY_DEFAULT};
 #endif
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 // Enables Web Share (navigator.share) for macOS
 const base::Feature kWebShare{"WebShare", base::FEATURE_DISABLED_BY_DEFAULT};
 #endif
@@ -1155,12 +1162,12 @@
 // UIs implemented with web technologies.
 const base::Feature kWebUIDarkMode {
   "WebUIDarkMode",
-#if defined(OS_MAC) || defined(OS_WIN) || defined(OS_ANDROID) || \
+#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) || \
     BUILDFLAG(IS_CHROMEOS_ASH)
       base::FEATURE_ENABLED_BY_DEFAULT
 #else
       base::FEATURE_DISABLED_BY_DEFAULT
-#endif  // defined(OS_MAC) || defined(OS_WIN) || defined(OS_ANDROID) ||
+#endif  // BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) ||
         // BUILDFLAG(IS_CHROMEOS_ASH)
 };
 
@@ -1181,11 +1188,11 @@
     "UserTypeByDeviceTypeMetricsProvider", base::FEATURE_ENABLED_BY_DEFAULT};
 #endif
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 // Enables the accelerated default browser flow for Windows 10.
 const base::Feature kWin10AcceleratedDefaultBrowserFlow{
     "Win10AcceleratedDefaultBrowserFlow", base::FEATURE_ENABLED_BY_DEFAULT};
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 
 // Enables writing basic system profile to the persistent histograms files
 // earlier.
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h
index 9c4c4a81..abbe726 100644
--- a/chrome/common/chrome_features.h
+++ b/chrome/common/chrome_features.h
@@ -53,7 +53,7 @@
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kAlwaysReinstallSystemWebApps;
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kAnonymousUpdateChecks;
 #endif
@@ -73,29 +73,29 @@
 extern const base::Feature kAppManagementIntentSettings;
 #endif
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kAppServiceLoadIconWithoutMojom;
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kAppServiceExtension;
-#endif  // !defined(OS_ANDROID)
+#endif  // !BUILDFLAG(IS_ANDROID)
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kAppShimRemoteCocoa;
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kAppShimNewCloseBehavior;
-#endif  // defined(OS_MAC)
+#endif  // BUILDFLAG(IS_MAC)
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kArcPiGhostWindow;
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
 COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kAsyncDns;
 
-#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) || \
-    defined(OS_CHROMEOS) || defined(OS_FUCHSIA)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \
+    BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_FUCHSIA)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kAutofillAddressSurvey;
 COMPONENT_EXPORT(CHROME_FEATURES)
@@ -104,24 +104,24 @@
 extern const base::Feature kAutofillPasswordSurvey;
 #endif
 
-#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kBackgroundModeAllowRestart;
-#endif  // defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kBorealis;
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kBrowserAppInstanceTracking;
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kChangePictureVideoMode;
 
-#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kChromeAppsDeprecation;
 #endif
@@ -132,7 +132,7 @@
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kConsolidatedSiteStorageControls;
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kContinuousSearch;
 #endif
@@ -162,7 +162,7 @@
 extern const base::Feature kCryptohomeUserDataAuthKillswitch;
 #endif
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kDataLeakPreventionPolicy;
 
@@ -180,13 +180,13 @@
 extern const base::Feature kDMServerOAuthForChildUser;
 #endif
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kPreinstalledWebAppInstallation;
 #endif
 
-#if BUILDFLAG(IS_CHROMEOS_ASH) || defined(OS_MAC) || defined(OS_LINUX) || \
-    defined(OS_FUCHSIA)
+#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \
+    BUILDFLAG(IS_FUCHSIA)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kDesktopPWAsAppIconShortcutsMenuUI;
 #endif
@@ -243,17 +243,17 @@
 extern const base::Feature kDnsProxyEnableDOH;
 #endif
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kEarlyLibraryLoad;
 #endif
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kElidePrioritizationOfPreNativeBootstrapTasks;
 #endif
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kElideTabPreloadAtStartup;
 #endif
@@ -267,7 +267,7 @@
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kEnableAmbientAuthenticationInIncognito;
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kEnableIncognitoShortcutOnDesktop;
 #endif
@@ -278,6 +278,11 @@
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kEnableWebAppUninstallFromOsSettings;
 
+#if !defined(OS_ANDROID)
+COMPONENT_EXPORT(CHROME_FEATURES)
+extern const base::Feature kExtensionDeferredIndividualSettings;
+#endif
+
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kExtensionWorkflowJustification;
 
@@ -302,13 +307,13 @@
 
 COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kGeoLanguage;
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature
     kGiveJavaUiThreadDefaultTaskTraitsUserBlockingPriority;
 #endif
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kHappinessTrackingSurveysForDesktopDemo;
 
@@ -400,12 +405,12 @@
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kHttpsOnlyMode;
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kImmersiveFullscreen;
 #endif
 
-#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kImproveAccessibilityTreeUsingLocalML;
 #endif
@@ -415,13 +420,13 @@
 extern const base::Feature kInSessionPasswordChange;
 #endif
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 // Only has an effect in branded builds.
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kIncompatibleApplicationsWarning;
-#endif  // defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_ANDROID)
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kIncognitoBrandConsistencyForAndroid;
 #endif
@@ -429,8 +434,8 @@
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kIncognitoNtpRevamp;
 
-#if defined(OS_MAC) || defined(OS_WIN) || defined(OS_LINUX) || \
-    defined(OS_CHROMEOS) || defined(OS_FUCHSIA)
+#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || \
+    BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_FUCHSIA)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kIncognitoBrandConsistencyForDesktop;
 
@@ -441,10 +446,10 @@
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kUpdateHistoryEntryPointsInIncognito;
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kIntentPickerPWAPersistence;
-#endif  // !defined(OS_ANDROID)
+#endif  // !BUILDFLAG(IS_ANDROID)
 
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kInvalidatorUniqueOwnerName;
@@ -457,31 +462,31 @@
 extern const base::Feature kKernelnextVMs;
 #endif
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kLinkCapturingUiUpdate;
 #endif
 
-#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kLinuxLowMemoryMonitor;
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::FeatureParam<int> kLinuxLowMemoryMonitorModerateLevel;
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::FeatureParam<int> kLinuxLowMemoryMonitorCriticalLevel;
-#endif  // defined(OS_LINUX) && !defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS)
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kMacFullSizeContentView;
 #endif
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kMacMaterialDesignDownloadShelf;
 #endif
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kMacSystemScreenCapturePermissionCheck;
 #endif
@@ -493,7 +498,7 @@
 extern const base::Feature kShowHiddenNetworkToggle;
 #endif
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kMetricsSettingsAndroid;
 #endif
@@ -516,23 +521,23 @@
 extern const base::Feature kSystemNotifications;
 #endif
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kNewMacNotificationAPI;
 #endif
 
 COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kNoReferrers;
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kNotificationDurationLongForRequireInteraction;
 #endif
 
-#if defined(OS_POSIX)
+#if BUILDFLAG(IS_POSIX)
 COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kNtlmV2Enabled;
 #endif
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kOnConnectNative;
 #endif
 
@@ -542,7 +547,7 @@
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kOobeMarketingDoubleOptInCountriesSupported;
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kOomIntervention;
 #endif
 
@@ -608,7 +613,7 @@
 extern const base::Feature kRemoveSupervisedUsersOnStartup;
 #endif
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kRequestDesktopSiteForTablets;
 #endif
@@ -618,10 +623,10 @@
 extern const base::Feature kSchedulerConfiguration;
 #endif
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kScrollCapture;
-#endif  // defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_ANDROID)
 
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kSCTAuditing;
@@ -644,17 +649,17 @@
 extern const base::Feature kSharesheetCopyToClipboard;
 #endif
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kShareUsageRanking;
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kShareUsageRankingFixedMore;
 #endif
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kShow10_10ObsoleteInfobar;
-#endif  // defined(OS_MAC)
+#endif  // BUILDFLAG(IS_MAC)
 
 COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kSitePerProcess;
 
@@ -675,11 +680,11 @@
 COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kTPMFirmwareUpdate;
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kTabMetricsLogging;
 #endif
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 // Only has an effect in branded builds.
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kThirdPartyModulesBlocking;
@@ -747,7 +752,7 @@
 
 // Android expects this string from Java code, so it is always needed.
 // TODO(crbug.com/731802): Use #if BUILDFLAG(ENABLE_VR_BROWSING) instead.
-#if BUILDFLAG(ENABLE_VR) || defined(OS_ANDROID)
+#if BUILDFLAG(ENABLE_VR) || BUILDFLAG(IS_ANDROID)
 COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kVrBrowsing;
 #endif
 #if BUILDFLAG(ENABLE_VR)
@@ -757,10 +762,10 @@
 extern const base::Feature kVrBrowsingExperimentalRendering;
 #endif  // ENABLE_VR
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kWebAppManifestIconUpdating;
-#endif  // !defined(OS_ANDROID)
+#endif  // !BUILDFLAG(IS_ANDROID)
 
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kWebAppManifestPolicyAppIdentityUpdate;
@@ -773,14 +778,14 @@
 extern const base::Feature kWebKioskEnableLacros;
 #endif
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kWebRtcRemoteEventLog;
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kWebRtcRemoteEventLogGzipped;
 #endif
 
-#if defined(OS_WIN) || defined(OS_CHROMEOS) || defined(OS_MAC)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC)
 COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kWebShare;
 #endif
 
@@ -797,10 +802,10 @@
 COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kWilcoDtc;
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kWin10AcceleratedDefaultBrowserFlow;
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kWriteBasicSystemProfileToPersistentHistogramsFile;
diff --git a/chrome/common/chrome_isolated_world_ids.h b/chrome/common/chrome_isolated_world_ids.h
index 32f711e..33bb6eb 100644
--- a/chrome/common/chrome_isolated_world_ids.h
+++ b/chrome/common/chrome_isolated_world_ids.h
@@ -15,10 +15,10 @@
   // Isolated world ID for internal Chrome features.
   ISOLATED_WORLD_ID_CHROME_INTERNAL,
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   // Isolated world ID for AppleScript.
   ISOLATED_WORLD_ID_APPLESCRIPT,
-#endif  // defined(OS_MAC)
+#endif  // BUILDFLAG(IS_MAC)
 
   // Numbers for isolated worlds for extensions are set in
   // extensions/renderer/script_injection.cc, and are are greater than or equal
diff --git a/chrome/common/chrome_paths.cc b/chrome/common/chrome_paths.cc
index c5f2b6e..8e466ff 100644
--- a/chrome/common/chrome_paths.cc
+++ b/chrome/common/chrome_paths.cc
@@ -22,19 +22,19 @@
 #include "media/media_buildflags.h"
 #include "ppapi/buildflags/buildflags.h"
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 #include "base/android/path_utils.h"
 #include "base/base_paths_android.h"
 // ui/base must only be used on Android. See BUILD.gn for dependency info.
 #include "ui/base/ui_base_paths.h"  // nogncheck
 #endif
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #include "base/mac/bundle_locations.h"
 #include "base/mac/foundation_util.h"
 #endif
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 #include "base/win/registry.h"
 #endif
 
@@ -44,7 +44,7 @@
 
 namespace {
 
-#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
 // The path to the external extension <id>.json files.
 // /usr/share seems like a good choice, see: http://www.pathname.com/fhs/
 const base::FilePath::CharType kFilepathSinglePrefExtensions[] =
@@ -54,7 +54,7 @@
     FILE_PATH_LITERAL("/usr/share/chromium/extensions");
 #endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING)
 
-#endif  // defined(OS_LINUX) || defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
 
 #if BUILDFLAG(ENABLE_WIDEVINE)
 // The name of the hint file that tells the latest component updated Widevine
@@ -79,7 +79,7 @@
 // Gets the path for internal plugins.
 bool GetInternalPluginsDirectory(base::FilePath* result) {
 #if BUILDFLAG(ENABLE_PLUGINS)
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   // If called from Chrome, get internal plugins from a subdirectory of the
   // framework.
   if (base::mac::AmIBundled()) {
@@ -89,7 +89,7 @@
     return true;
   }
   // In tests, just look in the module directory (below).
-#endif  //  defined(OS_MAC)
+#endif  //  BUILDFLAG(IS_MAC)
 
   // The rest of the world expects plugins in the module directory.
   return base::PathService::Get(base::DIR_MODULE, result);
@@ -103,11 +103,11 @@
 // implementations should not be used if higher-versioned component-updated
 // implementations are available in DIR_USER_DATA.
 bool GetComponentDirectory(base::FilePath* result) {
-#if defined(OS_FUCHSIA)
+#if BUILDFLAG(IS_FUCHSIA)
   // TODO(crbug.com/1241871): Support bundled components.
   return false;
 #else
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   // If called from Chrome, return the framework's Libraries directory.
   if (base::mac::AmIBundled()) {
     *result = chrome::GetFrameworkBundlePath();
@@ -137,12 +137,12 @@
 #else
       // Debug builds write next to the binary (in the build tree)
       // TODO(crbug.com/1262330): implement workable solution for Fuchsia.
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
       // Apps may not write into their own bundle.
       if (base::mac::AmIBundled()) {
         return base::PathService::Get(chrome::DIR_USER_DATA, result);
       }
-#endif  // defined(OS_MAC)
+#endif  // BUILDFLAG(IS_MAC)
       return base::PathService::Get(base::DIR_EXE, result);
 #endif  // NDEBUG
   }
@@ -178,7 +178,7 @@
         return false;
       break;
     case chrome::DIR_DEFAULT_DOWNLOADS_SAFE:
-#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
       if (!GetUserDownloadsDirectorySafe(&cur))
         return false;
       break;
@@ -186,7 +186,7 @@
       // Fall through for all other platforms.
 #endif
     case chrome::DIR_DEFAULT_DOWNLOADS:
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
       if (!base::android::GetDownloadsDirectory(&cur))
         return false;
 #else
@@ -200,7 +200,7 @@
 #if BUILDFLAG(IS_CHROMEOS_ASH)
       // ChromeOS uses a separate directory. See http://crosbug.com/25089
       cur = base::FilePath("/var/log/chrome");
-#elif defined(OS_ANDROID)
+#elif BUILDFLAG(IS_ANDROID)
       if (!base::android::GetCacheDirectory(&cur))
         return false;
 #else
@@ -213,14 +213,14 @@
       if (!GetDefaultUserDataDirectory(&cur))
         return false;
 #endif
-#if defined(OS_MAC) || defined(OS_WIN) || defined(OS_ANDROID)
+#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID)
       cur = cur.Append(FILE_PATH_LITERAL("Crashpad"));
 #else
       cur = cur.Append(FILE_PATH_LITERAL("Crash Reports"));
 #endif
       create_dir = true;
       break;
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
     case chrome::DIR_WATCHER_DATA:
       // The watcher data is always stored relative to the default user data
       // directory.  This allows the watcher to be initialized before
@@ -238,7 +238,7 @@
       break;
 #endif
     case chrome::DIR_RESOURCES:
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
       cur = base::mac::FrameworkBundlePath();
       cur = cur.Append(FILE_PATH_LITERAL("Resources"));
 #else
@@ -248,7 +248,7 @@
 #endif
       break;
     case chrome::DIR_APP_DICTIONARIES:
-#if defined(OS_POSIX)
+#if BUILDFLAG(IS_POSIX)
       // We can't write into the EXE dir on Linux, so keep dictionaries
       // alongside the safe browsing database in the user data dir.
       // And we don't want to write into the bundle on the Mac, so push
@@ -294,7 +294,7 @@
     // was shipped along with chrome.  The value can be overridden
     // if it is installed via component updater.
     case chrome::DIR_PNACL_COMPONENT:
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
       // PNaCl really belongs in the InternalPluginsDirectory but actually
       // copying it there would result in the files also being shipped, which
       // we don't want yet. So for now, just find them in the directory where
@@ -343,11 +343,11 @@
 
     case chrome::FILE_RESOURCES_PACK:  // Falls through.
     case chrome::FILE_DEV_UI_RESOURCES_PACK:
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
       cur = base::mac::FrameworkBundlePath();
       cur = cur.Append(FILE_PATH_LITERAL("Resources"))
                .Append(FILE_PATH_LITERAL("resources.pak"));
-#elif defined(OS_ANDROID)
+#elif BUILDFLAG(IS_ANDROID)
       if (!base::PathService::Get(ui::DIR_RESOURCE_PAKS_ANDROID, &cur))
         return false;
       if (key == chrome::FILE_DEV_UI_RESOURCES_PACK) {
@@ -411,7 +411,7 @@
       if (!base::PathExists(cur))  // We don't want to create this
         return false;
       break;
-#if defined(OS_POSIX) && !defined(OS_MAC) && !defined(OS_OPENBSD)
+#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC) && !BUILDFLAG(IS_OPENBSD)
     case chrome::DIR_POLICY_FILES: {
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
       cur = base::FilePath(FILE_PATH_LITERAL("/etc/opt/chrome/policies"));
@@ -423,10 +423,10 @@
 #endif
 // TODO(crbug.com/1052397): Revisit once build flag switch of lacros-chrome is
 // complete.
-#if BUILDFLAG(IS_CHROMEOS_ASH) ||                            \
-    ((defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) && \
-     BUILDFLAG(CHROMIUM_BRANDING)) ||                        \
-    defined(OS_MAC)
+#if BUILDFLAG(IS_CHROMEOS_ASH) ||                              \
+    ((BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) && \
+     BUILDFLAG(CHROMIUM_BRANDING)) ||                          \
+    BUILDFLAG(IS_MAC)
     case chrome::DIR_USER_EXTERNAL_EXTENSIONS: {
       if (!base::PathService::Get(chrome::DIR_USER_DATA, &cur))
         return false;
@@ -434,18 +434,18 @@
       break;
     }
 #endif
-#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
     case chrome::DIR_STANDALONE_EXTERNAL_EXTENSIONS: {
       cur = base::FilePath(kFilepathSinglePrefExtensions);
       break;
     }
 #endif
     case chrome::DIR_EXTERNAL_EXTENSIONS:
-#if defined(OS_FUCHSIA)
+#if BUILDFLAG(IS_FUCHSIA)
       // TODO(crbug.com/1241872): Support external extensions.
       return false;
 #else
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
       if (!chrome::GetGlobalApplicationSupportDirectory(&cur))
         return false;
 
@@ -464,11 +464,11 @@
 #endif
 
     case chrome::DIR_DEFAULT_APPS:
-#if defined(OS_FUCHSIA)
+#if BUILDFLAG(IS_FUCHSIA)
       // TODO(crbug.com/1241872): Support default-installed apps.
       return false;
 #else
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
       cur = base::mac::FrameworkBundlePath();
       cur = cur.Append(FILE_PATH_LITERAL("Default Apps"));
 #else
@@ -479,9 +479,9 @@
       break;
 #endif
 
-#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC)
     case chrome::DIR_NATIVE_MESSAGING:
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
       cur = base::FilePath(FILE_PATH_LITERAL(
            "/Library/Google/Chrome/NativeMessagingHosts"));
@@ -489,7 +489,7 @@
       cur = base::FilePath(FILE_PATH_LITERAL(
           "/Library/Application Support/Chromium/NativeMessagingHosts"));
 #endif
-#else  // defined(OS_MAC)
+#else  // BUILDFLAG(IS_MAC)
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
       cur = base::FilePath(FILE_PATH_LITERAL(
           "/etc/opt/chrome/native-messaging-hosts"));
@@ -497,7 +497,7 @@
       cur = base::FilePath(FILE_PATH_LITERAL(
           "/etc/chromium/native-messaging-hosts"));
 #endif
-#endif  // !defined(OS_MAC)
+#endif  // !BUILDFLAG(IS_MAC)
       break;
 
     case chrome::DIR_USER_NATIVE_MESSAGING:
@@ -505,14 +505,14 @@
         return false;
       cur = cur.Append(FILE_PATH_LITERAL("NativeMessagingHosts"));
       break;
-#endif  // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC)
-#if !defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC)
+#if !BUILDFLAG(IS_ANDROID)
     case chrome::DIR_GLOBAL_GCM_STORE:
       if (!base::PathService::Get(chrome::DIR_USER_DATA, &cur))
         return false;
       cur = cur.Append(kGCMStoreDirname);
       break;
-#endif  // !defined(OS_ANDROID)
+#endif  // !BUILDFLAG(IS_ANDROID)
 #if BUILDFLAG(IS_CHROMEOS_ASH)
     case chrome::FILE_CHROME_OS_TPM_FIRMWARE_UPDATE_LOCATION:
       cur = base::FilePath(kChromeOSTPMFirmwareUpdateLocation);
diff --git a/chrome/common/chrome_paths.h b/chrome/common/chrome_paths.h
index e76b30f..751f3a6 100644
--- a/chrome/common/chrome_paths.h
+++ b/chrome/common/chrome_paths.h
@@ -25,7 +25,7 @@
   DIR_LOGS = PATH_START,  // Directory where logs should be written.
   DIR_USER_DATA,          // Directory where user data can be written.
   DIR_CRASH_DUMPS,        // Directory where crash dumps are written.
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   DIR_WATCHER_DATA,       // Directory where the Chrome watcher stores
                           // data.
   DIR_ROAMING_USER_DATA,  // Directory where user data is stored that
@@ -45,7 +45,7 @@
   DIR_INTERNAL_PLUGINS,        // Directory where internal plugins reside.
   DIR_COMPONENTS,              // Directory where built-in implementations of
                                // component-updated libraries or data reside.
-#if defined(OS_POSIX) && !defined(OS_MAC)
+#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC)
   DIR_POLICY_FILES,  // Directory for system-wide read-only
                      // policy files that allow sys-admins
                      // to set policies for chrome. This directory
@@ -53,10 +53,10 @@
 #endif
 // TODO(crbug.com/1052397): Revisit once build flag switch of lacros-chrome is
 // complete.
-#if BUILDFLAG(IS_CHROMEOS_ASH) ||                            \
-    ((defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) && \
-     BUILDFLAG(CHROMIUM_BRANDING)) ||                        \
-    defined(OS_MAC)
+#if BUILDFLAG(IS_CHROMEOS_ASH) ||                              \
+    ((BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) && \
+     BUILDFLAG(CHROMIUM_BRANDING)) ||                          \
+    BUILDFLAG(IS_MAC)
   DIR_USER_EXTERNAL_EXTENSIONS,  // Directory for per-user external extensions
                                  // on Chrome Mac and Chromium Linux.
                                  // On Chrome OS, this path is used for OEM
@@ -64,7 +64,7 @@
                                  // create it.
 #endif
 
-#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
   DIR_STANDALONE_EXTERNAL_EXTENSIONS,  // Directory for 'per-extension'
                                        // definition manifest files that
                                        // describe extensions which are to be
@@ -105,13 +105,13 @@
   DIR_CHROMEOS_CUSTOM_WALLPAPERS,     // Directory where custom wallpapers
                                       // reside.
 #endif
-#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC)
   DIR_NATIVE_MESSAGING,       // System directory where native messaging host
                               // manifest files are stored.
   DIR_USER_NATIVE_MESSAGING,  // Directory with Native Messaging Hosts
                               // installed per-user.
 #endif
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
   DIR_GLOBAL_GCM_STORE,  // Directory where the global GCM instance
                          // stores its data.
 #endif
diff --git a/chrome/common/chrome_paths_internal.h b/chrome/common/chrome_paths_internal.h
index c23b3bb..23dfe33 100644
--- a/chrome/common/chrome_paths_internal.h
+++ b/chrome/common/chrome_paths_internal.h
@@ -9,7 +9,7 @@
 
 #include "build/build_config.h"
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #if defined(__OBJC__)
 @class NSBundle;
 #else
@@ -27,7 +27,7 @@
 // DIR_USER_DATA has been overridden by a command-line option.
 bool GetDefaultUserDataDirectory(base::FilePath* result);
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 // Get the path to the roaming user's data directory, regardless of whether
 // DIR_ROAMING_USER_DATA has been overridden by a command-line option.
 bool GetDefaultRoamingUserDataDirectory(base::FilePath* result);
@@ -45,7 +45,7 @@
 // Get the path to the user's documents directory.
 bool GetUserDocumentsDirectory(base::FilePath* result);
 
-#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
 // Gets the path to a safe default download directory for a user.
 bool GetUserDownloadsDirectorySafe(base::FilePath* result);
 #endif
@@ -62,7 +62,7 @@
 // Gets the path to the user's videos directory.
 bool GetUserVideosDirectory(base::FilePath* result);
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 // Most of the application is further contained within the framework, which
 // resides in the Frameworks directory of the top-level Contents folder. The
 // framework is versioned with the full product version. This function returns
@@ -89,7 +89,7 @@
 bool GetUserDataDirectoryForBrowserBundle(NSBundle* bundle,
                                           base::FilePath* result);
 
-#endif  // OS_MAC
+#endif  // BUILDFLAG(IS_MAC)
 // Checks if the |process_type| has the rights to access the profile.
 bool ProcessNeedsProfileDir(const std::string& process_type);
 
diff --git a/chrome/common/chrome_paths_unittest.cc b/chrome/common/chrome_paths_unittest.cc
index 80169759..fd901f6a 100644
--- a/chrome/common/chrome_paths_unittest.cc
+++ b/chrome/common/chrome_paths_unittest.cc
@@ -17,7 +17,7 @@
 #include "chrome/common/chrome_constants.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-#if defined(OS_FUCHSIA)
+#if BUILDFLAG(IS_FUCHSIA)
 #include "base/fuchsia/file_utils.h"
 #endif
 
@@ -29,27 +29,27 @@
   base::FilePath test_profile_dir;  // Platform-specific profile directory path.
   base::FilePath expected_cache_dir;
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   test_profile_dir = base::FilePath(FILE_PATH_LITERAL("C:\\Users\\Foo\\Bar"));
   expected_cache_dir = base::FilePath(FILE_PATH_LITERAL("C:\\Users\\Foo\\Bar"));
-#elif defined(OS_FUCHSIA)
+#elif BUILDFLAG(IS_FUCHSIA)
   // Fuchsia uses the Component's cache directory as the base.
   expected_cache_dir = base::FilePath(base::kPersistedCacheDirectoryPath);
   // TODO(crbug.com/1263566): Support profile-specific cache and uncomment this.
   // test_profile_dir =
   //     base::FilePath(base::kPersistedDataDirectoryPath).Append("foobar");
   // expected_cache_dir = expected_cache_dir.Append("foobar");
-#elif defined(OS_MAC)
+#elif BUILDFLAG(IS_MAC)
   ASSERT_TRUE(base::PathService::Get(base::DIR_APP_DATA, &test_profile_dir));
   test_profile_dir = test_profile_dir.Append("foobar");
   ASSERT_TRUE(base::PathService::Get(base::DIR_CACHE, &expected_cache_dir));
   expected_cache_dir = expected_cache_dir.Append("foobar");
-#elif defined(OS_ANDROID)
+#elif BUILDFLAG(IS_ANDROID)
   // No matter what the test_profile_dir is, Android always uses the
   // application's cache directory since multiple profiles are not supported.
   test_profile_dir = base::FilePath("\\Not a valid path");
   ASSERT_TRUE(base::PathService::Get(base::DIR_CACHE, &expected_cache_dir));
-#elif defined(OS_POSIX)
+#elif BUILDFLAG(IS_POSIX)
   base::FilePath homedir;
   base::PathService::Get(base::DIR_HOME, &homedir);
   // Note: we assume XDG_CACHE_HOME/XDG_CONFIG_HOME are at their
@@ -63,7 +63,7 @@
 #endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
 #else
 #error Unsupported platform
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 
   // Verify the expectations above for the platform-specific profile directory.
   // On Linux and Mac the platform-specific profile directory is in a special
@@ -78,10 +78,10 @@
   base::FilePath non_special_profile_dir =
       base::FilePath(FILE_PATH_LITERAL("/some/other/path"));
   GetUserCacheDirectory(non_special_profile_dir, &cache_dir);
-#if defined(OS_FUCHSIA) || defined(OS_ANDROID)
+#if BUILDFLAG(IS_FUCHSIA) || BUILDFLAG(IS_ANDROID)
   // Fuchsia always uses the same base cache directory.
   EXPECT_EQ(expected_cache_dir.value(), cache_dir.value());
-#elif defined(OS_ANDROID)
+#elif BUILDFLAG(IS_ANDROID)
   // Android always uses the same application cache directory.
   EXPECT_EQ(expected_cache_dir.value(), cache_dir.value());
 #else
@@ -90,7 +90,7 @@
 }
 
 // Chrome OS doesn't use any of the desktop linux configuration.
-#if defined(OS_LINUX) && !BUILDFLAG(IS_CHROMEOS_LACROS) && \
+#if BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS_LACROS) && \
     !BUILDFLAG(IS_CHROMEOS_ASH)
 TEST(ChromePaths, DefaultUserDataDir) {
   std::unique_ptr<base::Environment> env(base::Environment::Create());
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index 80cb346..2eac5f7 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -597,7 +597,7 @@
 // resulted in a browser startup.
 const char kWinJumplistAction[]             = "win-jumplist-action";
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 // Android authentication account type for SPNEGO authentication
 const char kAuthAndroidNegotiateAccountType[] = "auth-spnego-account-type";
 
@@ -633,7 +633,7 @@
 
 // Sets the market URL for Chrome for use in testing.
 const char kMarketUrlForTesting[] = "market-url-for-testing";
-#endif  // defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_ANDROID)
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 // Custom crosh command.
@@ -660,7 +660,7 @@
 const char kSchedulerConfigurationDefault[] = "scheduler-configuration-default";
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
-#if defined(OS_POSIX) && !defined(OS_MAC) && !BUILDFLAG(IS_CHROMEOS_ASH)
+#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC) && !BUILDFLAG(IS_CHROMEOS_ASH)
 // These flags show the man page on Linux. They are equivalent to each
 // other.
 const char kHelp[]                          = "help";
@@ -685,7 +685,7 @@
 const char kWmClass[]                       = "class";
 #endif
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 // Prevents Chrome from quitting when Chrome Apps are open.
 const char kAppsKeepChromeAliveInTests[]    = "apps-keep-chrome-alive-in-tests";
 
@@ -710,9 +710,9 @@
 // Indicates whether Chrome should be set as the default browser during
 // installation.
 const char kMakeChromeDefault[] = "make-chrome-default";
-#endif  // defined(OS_MAC)
+#endif  // BUILDFLAG(IS_MAC)
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 // Disables custom-drawing the window titlebar on Windows 10.
 const char kDisableWindows10CustomTitlebar[] =
     "disable-windows10-custom-titlebar";
@@ -768,7 +768,7 @@
 // method, as older PWA launchers still using this switch will rely on Chrome to
 // update them to use the new method.
 const char kPwaLauncherVersion[] = "pwa-launcher-version";
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 
 #if BUILDFLAG(ENABLE_PRINT_PREVIEW) && !defined(OFFICIAL_BUILD)
 // Enables support to debug printing subsystem.
@@ -789,15 +789,15 @@
 const char kAllowNaClSocketAPI[]            = "allow-nacl-socket-api";
 #endif
 
-#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC) || \
-    defined(OS_WIN) || defined(OS_FUCHSIA)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC) || \
+    BUILDFLAG(IS_WIN) || BUILDFLAG(IS_FUCHSIA)
 const char kEnableNewAppMenuIcon[] = "enable-new-app-menu-icon";
 
 // Causes the browser to launch directly in guest mode.
 const char kGuest[] = "guest";
 #endif
 
-#if defined(OS_LINUX) || defined(OS_MAC) || defined(OS_WIN)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
 // Writes open and installed web apps for each profile to the specified file
 // without launching a new browser window or tab. Pass a absolute file path to
 // specify where to output the information. Can be used together with optional
@@ -809,12 +809,12 @@
 const char kProfileBaseName[] = "profile-base-name";
 #endif
 
-#if BUILDFLAG(IS_CHROMEOS_ASH) || defined(OS_ANDROID)
+#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_ANDROID)
 // Custom WebAPK server URL for the sake of testing.
 const char kWebApkServerUrl[] = "webapk-server-url";
 #endif
 
-#if !BUILDFLAG(IS_CHROMEOS_ASH) && !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_ANDROID)
 // Uses the system default printer as the initially selected destination in
 // print preview, instead of the most recently used destination.
 const char kUseSystemDefaultPrinter[] = "use-system-default-printer";
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index bf0219e6..bb1953d 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -179,7 +179,7 @@
 extern const char kWinHttpProxyResolver[];
 extern const char kWinJumplistAction[];
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 extern const char kAuthAndroidNegotiateAccountType[];
 extern const char kEnableAccessibilityTabSwitcher[];
 extern const char kEnableHungRendererInfoBar[];
@@ -191,7 +191,7 @@
 extern const char kForceDisableSigninFRE[];
 extern const char kForceUpdateMenuType[];
 extern const char kMarketUrlForTesting[];
-#endif  // defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_ANDROID)
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 extern const char kCroshCommand[];
@@ -204,7 +204,7 @@
 extern const char kSchedulerConfigurationDefault[];
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
-#if defined(OS_POSIX) && !defined(OS_MAC) && !BUILDFLAG(IS_CHROMEOS_ASH)
+#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC) && !BUILDFLAG(IS_CHROMEOS_ASH)
 extern const char kHelp[];
 extern const char kHelpShort[];
 extern const char kPasswordStore[];
@@ -212,16 +212,16 @@
 extern const char kWmClass[];
 #endif
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 extern const char kAppsKeepChromeAliveInTests[];
 extern const char kEnableUserMetrics[];
 extern const char kMetricsClientID[];
 extern const char kRelauncherProcess[];
 extern const char kRelauncherProcessDMGDevice[];
 extern const char kMakeChromeDefault[];
-#endif  // defined(OS_MAC)
+#endif  // BUILDFLAG(IS_MAC)
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 extern const char kDisableWindows10CustomTitlebar[];
 extern const char kEnableProfileShortcutManager[];
 extern const char kFromInstaller[];
@@ -234,7 +234,7 @@
 extern const char kShowIcons[];
 extern const char kUninstall[];
 extern const char kUninstallAppId[];
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 
 #if BUILDFLAG(ENABLE_PRINT_PREVIEW) && !defined(OFFICIAL_BUILD)
 extern const char kDebugPrint[];
@@ -246,22 +246,22 @@
 extern const char kAllowNaClSocketAPI[];
 #endif
 
-#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC) || \
-    defined(OS_WIN) || defined(OS_FUCHSIA)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC) || \
+    BUILDFLAG(IS_WIN) || BUILDFLAG(IS_FUCHSIA)
 extern const char kEnableNewAppMenuIcon[];
 extern const char kGuest[];
 #endif
 
-#if defined(OS_LINUX) || defined(OS_MAC) || defined(OS_WIN)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
 extern const char kListApps[];
 extern const char kProfileBaseName[];
 #endif
 
-#if BUILDFLAG(IS_CHROMEOS_ASH) || defined(OS_ANDROID)
+#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_ANDROID)
 extern const char kWebApkServerUrl[];
 #endif
 
-#if !BUILDFLAG(IS_CHROMEOS_ASH) && !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_ANDROID)
 extern const char kUseSystemDefaultPrinter[];
 #endif
 
diff --git a/chrome/common/crash_keys.cc b/chrome/common/crash_keys.cc
index 68ddd33..f6850e85 100644
--- a/chrome/common/crash_keys.cc
+++ b/chrome/common/crash_keys.cc
@@ -28,7 +28,7 @@
 namespace crash_keys {
 namespace {
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 // ChromeOS uses --enable-features and --disable-features more heavily than
 // most platforms, and the results don't fit into the default 64 bytes. So they
 // are listed in special, larger CrashKeys and excluded from the default
@@ -60,11 +60,11 @@
     // anyways. Should be switches::kGpuPreferences but we run into linking
     // errors on Windows if we try to use that directly.
     "gpu-preferences",
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
     switches::kEnableFeatures,
     switches::kDisableFeatures,
 #endif
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
     switches::kMetricsClientID,
 #elif BUILDFLAG(IS_CHROMEOS_ASH)
     // --crash-loop-before is a "boring" switch because it is redundant;
@@ -90,7 +90,7 @@
 #endif
   };
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   // Just about everything has this, don't bother.
   if (base::StartsWith(flag, "/prefetch:", base::CompareCase::SENSITIVE))
     return true;
@@ -110,7 +110,7 @@
 }  // namespace
 
 void SetCrashKeysFromCommandLine(const base::CommandLine& command_line) {
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   HandleEnableDisableFeatures(command_line);
 #endif
   SetSwitchesFromCommandLine(command_line, &IsBoringSwitch);
diff --git a/chrome/common/crash_keys_unittest.cc b/chrome/common/crash_keys_unittest.cc
index 3db1bff..c0182c6 100644
--- a/chrome/common/crash_keys_unittest.cc
+++ b/chrome/common/crash_keys_unittest.cc
@@ -124,7 +124,7 @@
   EXPECT_TRUE(GetCrashKeyValue("switch-5").empty());
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 TEST_F(CrashKeysTest, EnabledDisabledFeaturesFlags) {
   base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
   command_line.InitFromArgv(
@@ -201,4 +201,4 @@
   }
 }
 
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
diff --git a/chrome/common/extensions/api/accessibility_private.json b/chrome/common/extensions/api/accessibility_private.json
index e407365..be0dfbe 100644
--- a/chrome/common/extensions/api/accessibility_private.json
+++ b/chrome/common/extensions/api/accessibility_private.json
@@ -248,6 +248,31 @@
         "type": "string",
         "enum": [ "success", "talkbackNotInstalled", "windowNotFound", "failure" ],
         "description": "Response code for onNativeChromeVoxArcSupportResult"
+      },
+      {
+        "id": "DictationBubbleIconType",
+        "type": "string",
+        "enum": [ "hidden", "standby", "macroSuccess", "macroFail" ],
+        "description": "The icon shown in the Dictation bubble UI"
+      },
+      {
+        "id": "DictationBubbleProperties",
+        "type": "object",
+        "properties": {
+          "visible": {
+            "type": "boolean",
+            "description": "Whether or not the UI should be visible."
+          },
+          "icon": {
+            "$ref": "DictationBubbleIconType",
+            "description": "The icon to show in the Dictation bubble UI."
+          },
+          "text": {
+            "type": "string",
+            "description": "The text to be displayed in the bubble UI. If `text` is undefined, the bubble will clear its current text.",
+            "optional": true
+          }
+        }
       }
     ],
     "properties": {
@@ -669,15 +694,9 @@
         "description": "Updates Dictation's bubble UI.",
         "parameters": [
           {
-            "name": "visible",
-            "type": "boolean",
-            "description": "Whether or not the UI should be visible."
-          },
-          {
-            "name": "text",
-            "type": "string",
-            "description": "The text to be displayed in the bubble UI. If `text` is undefined, the bubble will clear its current text.",
-            "optional": true
+            "name": "properties",
+            "$ref": "DictationBubbleProperties",
+            "description": "Properties for the updated Dictation bubble UI."
           }
         ]
       }
diff --git a/chrome/common/extensions/api/commands/commands_manifest_unittest.cc b/chrome/common/extensions/api/commands/commands_manifest_unittest.cc
index ebbe6d9f..562e90f0 100644
--- a/chrome/common/extensions/api/commands/commands_manifest_unittest.cc
+++ b/chrome/common/extensions/api/commands/commands_manifest_unittest.cc
@@ -22,7 +22,7 @@
 };
 
 TEST_F(CommandsManifestTest, CommandManifestSimple) {
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   int ctrl = ui::EF_COMMAND_DOWN;
 #else
   int ctrl = ui::EF_CONTROL_DOWN;
diff --git a/chrome/common/extensions/command.cc b/chrome/common/extensions/command.cc
index 40ee888..88bf394 100644
--- a/chrome/common/extensions/command.cc
+++ b/chrome/common/extensions/command.cc
@@ -104,7 +104,7 @@
         // Mac the developer has to specify MacCtrl). Therefore we treat this
         // as Command.
         modifiers |= ui::EF_COMMAND_DOWN;
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
       } else if (platform_key == values::kKeybindingPlatformDefault) {
         // If we see "Command+foo" in the Default section it can mean two
         // things, depending on the platform:
@@ -249,7 +249,7 @@
   if (platform == values::kKeybindingPlatformMac) {
     normalize = true;
   } else if (platform == values::kKeybindingPlatformDefault) {
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
     normalize = true;
 #endif
   }
@@ -288,13 +288,13 @@
 
 // static
 std::string Command::CommandPlatform() {
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   return values::kKeybindingPlatformWin;
-#elif defined(OS_MAC)
+#elif BUILDFLAG(IS_MAC)
   return values::kKeybindingPlatformMac;
 #elif BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
   return values::kKeybindingPlatformChromeOs;
-#elif defined(OS_LINUX)
+#elif BUILDFLAG(IS_LINUX)
   return values::kKeybindingPlatformLinux;
 #else
   return "";
diff --git a/chrome/common/extensions/command_unittest.cc b/chrome/common/extensions/command_unittest.cc
index 43d129ef..ce3b6b2 100644
--- a/chrome/common/extensions/command_unittest.cc
+++ b/chrome/common/extensions/command_unittest.cc
@@ -98,7 +98,7 @@
   const ui::Accelerator none = ui::Accelerator();
   const ui::Accelerator shift_f = ui::Accelerator(ui::VKEY_F,
                                                   ui::EF_SHIFT_DOWN);
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   int ctrl = ui::EF_COMMAND_DOWN;
 #else
   int ctrl = ui::EF_CONTROL_DOWN;
@@ -225,16 +225,16 @@
                base::UTF16ToASCII(command.description()).c_str());
   EXPECT_STREQ(command_name.c_str(), command.command_name().c_str());
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   ui::Accelerator accelerator(ui::VKEY_W,
                               ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN);
-#elif defined(OS_MAC)
+#elif BUILDFLAG(IS_MAC)
   ui::Accelerator accelerator(ui::VKEY_M,
                               ui::EF_SHIFT_DOWN | ui::EF_COMMAND_DOWN);
 #elif BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
   ui::Accelerator accelerator(ui::VKEY_C,
                               ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN);
-#elif defined(OS_LINUX)
+#elif BUILDFLAG(IS_LINUX)
   ui::Accelerator accelerator(ui::VKEY_L,
                               ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN);
 #else
@@ -272,7 +272,7 @@
 
   // Now add only a valid platform that we are not running on to make sure devs
   // are notified of errors on other platforms.
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   key_dict->SetStringKey("mac", "Ctrl+Shift+M");
 #else
   key_dict->SetStringKey("windows", "Ctrl+Shift+W");
@@ -280,7 +280,7 @@
   EXPECT_FALSE(command.Parse(input.get(), command_name, 0, &error));
 
   // Make sure Mac specific keys are not processed on other platforms.
-#if !defined(OS_MAC)
+#if !BUILDFLAG(IS_MAC)
   key_dict->SetStringKey("windows", "Command+Shift+M");
   EXPECT_FALSE(command.Parse(input.get(), command_name, 0, &error));
 #endif
diff --git a/chrome/common/extensions/extension_constants.cc b/chrome/common/extensions/extension_constants.cc
index fded91c..bb06c7b 100644
--- a/chrome/common/extensions/extension_constants.cc
+++ b/chrome/common/extensions/extension_constants.cc
@@ -57,7 +57,7 @@
     kIdentityApiUiAppId,
     kTextEditorAppId,
     kInAppPaymentsSupportAppId,
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
     kAssessmentAssistantExtensionId,
 #endif
 #if BUILDFLAG(IS_CHROMEOS_ASH)
@@ -73,7 +73,7 @@
     nullptr,  // Null-terminated array.
 };
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 const char kAssessmentAssistantExtensionId[] =
     "gndmhdcefbhlchkhipcnnbkcmicncehk";
 const char kGnubbyAppId[] = "beknehfpfkghjoafdifaflglpjkojoco";
diff --git a/chrome/common/extensions/extension_constants.h b/chrome/common/extensions/extension_constants.h
index fff878bd..592168c 100644
--- a/chrome/common/extensions/extension_constants.h
+++ b/chrome/common/extensions/extension_constants.h
@@ -160,7 +160,7 @@
   APP_LAUNCH_BUCKET_INVALID
 };
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 // The extension id of the Assessment Assistant extension.
 extern const char kAssessmentAssistantExtensionId[];
 // The extension id of the Gnubby chrome app.
diff --git a/chrome/common/extensions/extension_unittest.cc b/chrome/common/extensions/extension_unittest.cc
index 4037baa..1433d3a6 100644
--- a/chrome/common/extensions/extension_unittest.cc
+++ b/chrome/common/extensions/extension_unittest.cc
@@ -187,13 +187,13 @@
   run_rtl_test(L"google\x202e.com", L"google\x202e.com\x202c");
 
   run_rtl_test(L"كبير Google التطبيق",
-#if !defined(OS_WIN)
+#if !BUILDFLAG(IS_WIN)
                L"\x200e\x202bكبير Google التطبيق\x202c\x200e");
 #else
                // On Windows for an LTR locale, no changes to the string are
                // made.
                L"كبير Google التطبيق");
-#endif  // !OS_WIN
+#endif  // !BUILDFLAG(IS_WIN)
 }
 
 TEST(ExtensionTest, GetResourceURLAndPath) {
diff --git a/chrome/common/extensions/manifest_handlers/settings_overrides_handler_unittest.cc b/chrome/common/extensions/manifest_handlers/settings_overrides_handler_unittest.cc
index 8bff7ca..12f8bae 100644
--- a/chrome/common/extensions/manifest_handlers/settings_overrides_handler_unittest.cc
+++ b/chrome/common/extensions/manifest_handlers/settings_overrides_handler_unittest.cc
@@ -155,7 +155,7 @@
   std::string error;
   scoped_refptr<Extension> extension = CreateExtension(kManifest, &error);
   ASSERT_TRUE(extension.get());
-#if defined(OS_WIN) || defined(OS_MAC)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
   ASSERT_TRUE(
       extension->manifest()->FindPath(manifest_keys::kSettingsOverride));
 
@@ -190,7 +190,7 @@
   scoped_refptr<Extension> extension =
       CreateExtension(kPrepopulatedManifest, &error);
   ASSERT_TRUE(extension.get());
-#if defined(OS_WIN) || defined(OS_MAC)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
   ASSERT_TRUE(
       extension->manifest()->FindPath(manifest_keys::kSettingsOverride));
 
@@ -215,7 +215,7 @@
   scoped_refptr<Extension> extension =
       CreateExtension(kManifestBrokenHomepageButCorrectStartupPages, &error);
   ASSERT_TRUE(extension.get());
-#if defined(OS_WIN) || defined(OS_MAC)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
   ASSERT_TRUE(
       extension->manifest()->FindPath(manifest_keys::kSettingsOverride));
 
@@ -235,7 +235,7 @@
   scoped_refptr<Extension> extension =
       CreateExtension(kManifestBrokenStartupPagesButCorrectHomepage, &error);
   ASSERT_TRUE(extension.get());
-#if defined(OS_WIN) || defined(OS_MAC)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
   ASSERT_TRUE(
       extension->manifest()->FindPath(manifest_keys::kSettingsOverride));
   SettingsOverrides* settings_override = static_cast<SettingsOverrides*>(
@@ -253,7 +253,7 @@
   std::string error;
   scoped_refptr<Extension> extension =
       CreateExtension(kBrokenManifestEmpty, &error);
-#if defined(OS_WIN) || defined(OS_MAC)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
   EXPECT_FALSE(extension.get());
   EXPECT_EQ(
       extensions::ErrorUtils::FormatErrorMessage(
@@ -271,7 +271,7 @@
   std::string error;
   scoped_refptr<Extension> extension =
       CreateExtension(kBrokenManifestHomepage, &error);
-#if defined(OS_WIN) || defined(OS_MAC)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
   EXPECT_FALSE(extension.get());
   EXPECT_EQ(extensions::ErrorUtils::FormatErrorMessage(
                 extensions::manifest_errors::kInvalidHomepageOverrideURL,
@@ -288,7 +288,7 @@
   std::string error;
   scoped_refptr<Extension> extension =
       CreateExtension(kBrokenManifestStartupPages, &error);
-#if defined(OS_WIN) || defined(OS_MAC)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
   EXPECT_FALSE(extension.get());
   EXPECT_EQ(
       extensions::ErrorUtils::FormatErrorMessage(
@@ -333,7 +333,7 @@
     std::string error;
     scoped_refptr<Extension> extension = CreateExtensionWithSearchProvider(
         std::move(provider_with_missing_key), &error);
-#if defined(OS_WIN) || defined(OS_MAC)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
     EXPECT_FALSE(extension.get());
     EXPECT_EQ(extensions::ErrorUtils::FormatErrorMessage(
                   extensions::manifest_errors::kInvalidSearchEngineMissingKeys,
diff --git a/chrome/common/extensions/permissions/settings_override_permission_unittest.cc b/chrome/common/extensions/permissions/settings_override_permission_unittest.cc
index 5cb5351..1445795 100644
--- a/chrome/common/extensions/permissions/settings_override_permission_unittest.cc
+++ b/chrome/common/extensions/permissions/settings_override_permission_unittest.cc
@@ -31,7 +31,7 @@
 class SettingsOverridePermissionTest : public ChromeManifestTest {
  protected:
   SettingsOverridePermissionTest()
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
       : scoped_channel_(version_info::Channel::UNKNOWN)
 #endif
   {
@@ -77,10 +77,10 @@
     return LoadAndExpectSuccess(manifest);
   }
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   // On Mac, this API is limited to trunk.
   extensions::ScopedCurrentChannel scoped_channel_;
-#endif  // OS_MAC
+#endif  // BUILDFLAG(IS_MAC)
 };
 
 TEST_F(SettingsOverridePermissionTest, HomePage) {
@@ -88,7 +88,7 @@
   const PermissionSet& permission_set =
       extension->permissions_data()->active_permissions();
 
-#if defined(OS_WIN) || defined(OS_MAC)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
   EXPECT_TRUE(permission_set.HasAPIPermission(APIPermissionID::kHomepage));
   VerifyOnePermissionMessage(extension->permissions_data(),
                              "Change your home page to: google.com");
@@ -106,7 +106,7 @@
   const PermissionSet& permission_set =
       extension->permissions_data()->active_permissions();
 
-#if defined(OS_WIN) || defined(OS_MAC)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
   EXPECT_TRUE(permission_set.HasAPIPermission(APIPermissionID::kStartupPages));
   VerifyOnePermissionMessage(extension->permissions_data(),
                              "Change your start page to: startup.com");
@@ -124,7 +124,7 @@
   const PermissionSet& permission_set =
       extension->permissions_data()->active_permissions();
 
-#if defined(OS_WIN) || defined(OS_MAC)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
   EXPECT_TRUE(
       permission_set.HasAPIPermission(APIPermissionID::kSearchProvider));
   VerifyOnePermissionMessage(extension->permissions_data(),
@@ -144,7 +144,7 @@
   const PermissionSet& permission_set =
       extension->permissions_data()->active_permissions();
 
-#if defined(OS_WIN) || defined(OS_MAC)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
   EXPECT_TRUE(permission_set.HasAPIPermission(APIPermissionID::kHomepage));
   EXPECT_TRUE(permission_set.HasAPIPermission(APIPermissionID::kStartupPages));
   EXPECT_TRUE(
@@ -163,7 +163,7 @@
   const PermissionSet& permission_set =
       extension->permissions_data()->active_permissions();
 
-#if defined(OS_WIN) || defined(OS_MAC)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
   EXPECT_TRUE(permission_set.HasAPIPermission(APIPermissionID::kHomepage));
   EXPECT_TRUE(
       permission_set.HasAPIPermission(APIPermissionID::kSearchProvider));
diff --git a/chrome/common/google_url_loader_throttle.cc b/chrome/common/google_url_loader_throttle.cc
index 8c25470..8b72897 100644
--- a/chrome/common/google_url_loader_throttle.cc
+++ b/chrome/common/google_url_loader_throttle.cc
@@ -15,7 +15,7 @@
 #include "services/network/public/mojom/url_response_head.mojom.h"
 #include "services/network/public/mojom/x_frame_options.mojom.h"
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 #include "ui/base/device_form_factor.h"
 #endif
 
@@ -25,7 +25,7 @@
 
 namespace {
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 const char kCCTClientDataHeader[] = "X-CCT-Client-Data";
 const char kRequestDesktopDataHeader[] = "X-Eligible-Tablet";
 #endif
@@ -39,19 +39,19 @@
       safe_search_util::kGoogleAppsAllowedDomains);
   params->cors_exempt_header_list.push_back(
       safe_search_util::kYouTubeRestrictHeaderName);
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   params->cors_exempt_header_list.push_back(kCCTClientDataHeader);
 #endif
 }
 
 GoogleURLLoaderThrottle::GoogleURLLoaderThrottle(
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
     const std::string& client_data_header,
     bool is_tab_large_enough,
 #endif
     chrome::mojom::DynamicParams dynamic_params)
     :
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
       client_data_header_(client_data_header),
       is_tab_large_enough_(is_tab_large_enough),
 #endif
@@ -91,7 +91,7 @@
         dynamic_params_.allowed_domains_for_apps);
   }
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   if (!client_data_header_.empty() &&
       google_util::IsGoogleAssociatedDomainUrl(request->url)) {
     request->cors_exempt_headers.SetHeader(kCCTClientDataHeader,
@@ -145,7 +145,7 @@
         dynamic_params_.allowed_domains_for_apps);
   }
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   if (!client_data_header_.empty() &&
       !google_util::IsGoogleAssociatedDomainUrl(redirect_info->new_url)) {
     to_be_removed_headers->push_back(kCCTClientDataHeader);
diff --git a/chrome/common/google_url_loader_throttle.h b/chrome/common/google_url_loader_throttle.h
index b5294a5e..7a88759 100644
--- a/chrome/common/google_url_loader_throttle.h
+++ b/chrome/common/google_url_loader_throttle.h
@@ -18,7 +18,7 @@
     : public blink::URLLoaderThrottle,
       public base::SupportsWeakPtr<GoogleURLLoaderThrottle> {
  public:
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   GoogleURLLoaderThrottle(const std::string& client_data_header,
                           bool is_tab_large_enough,
                           chrome::mojom::DynamicParams dynamic_params);
@@ -49,7 +49,7 @@
 #endif
 
  private:
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   std::string client_data_header_;
   bool is_tab_large_enough_;
 #endif
diff --git a/chrome/common/google_url_loader_throttle_unittest.cc b/chrome/common/google_url_loader_throttle_unittest.cc
index 83876e4..ce859f3 100644
--- a/chrome/common/google_url_loader_throttle_unittest.cc
+++ b/chrome/common/google_url_loader_throttle_unittest.cc
@@ -11,7 +11,7 @@
 #include "services/network/public/cpp/resource_request.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 #include "ui/base/device_form_factor.h"
 #endif
 
@@ -32,7 +32,7 @@
   base::test::ScopedFeatureList scoped_feature_list_;
 };
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 
 TEST_F(GoogleURLLoaderThrottleTest, RequestDesktopHeaderForLargeScreen) {
   scoped_feature_list().Reset();
diff --git a/chrome/common/importer/firefox_importer_utils.cc b/chrome/common/importer/firefox_importer_utils.cc
index 264b79a..7f1e3bd 100644
--- a/chrome/common/importer/firefox_importer_utils.cc
+++ b/chrome/common/importer/firefox_importer_utils.cc
@@ -35,7 +35,7 @@
       !root.GetString(profile_name + ".Path", &path16))
     return base::FilePath();
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   base::ReplaceSubstringsAfterOffset(&path16, 0, u"/", u"\\");
 #endif
   base::FilePath path = base::FilePath::FromUTF16Unsafe(path16);
@@ -100,7 +100,7 @@
   return profile_details;
 }
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 // Find the "*.app" component of the path and build up from there.
 // The resulting path will be .../Firefox.app/Contents/MacOS.
 // We do this because we don't trust LastAppDir to always be
@@ -133,7 +133,7 @@
              << "installation path: missing /*.app/ directory.";
   return false;
 }
-#endif  // OS_MAC
+#endif  // BUILDFLAG(IS_MAC)
 
 bool GetFirefoxVersionAndPathFromProfile(const base::FilePath& profile_path,
                                          int* version,
@@ -160,15 +160,15 @@
         // UTF-8, what does Firefox do?  If it puts raw bytes in the
         // file, we could go straight from bytes -> filepath;
         // otherwise, we're out of luck here.
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
         // Extract path from "LastAppDir=/actual/path"
         size_t separator_pos = line.find_first_of('=');
         const std::string& path_from_ini = line.substr(separator_pos + 1);
         if (!ComposeMacAppPath(path_from_ini, app_path))
           return false;
-#else  // !OS_MAC
+#else   // BUILDFLAG(IS_MAC)
         *app_path = base::FilePath::FromUTF8Unsafe(line.substr(equal + 1));
-#endif  // OS_MAC
+#endif  // BUILDFLAG(IS_MAC)
       }
     }
   }
diff --git a/chrome/common/importer/firefox_importer_utils.h b/chrome/common/importer/firefox_importer_utils.h
index 548e8b1..32143ee 100644
--- a/chrome/common/importer/firefox_importer_utils.h
+++ b/chrome/common/importer/firefox_importer_utils.h
@@ -18,7 +18,7 @@
 class FilePath;
 }
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 // Detects which version of Firefox is installed from registry. Returns its
 // major version, and drops the minor version. Returns 0 if failed. If there are
 // indicators of both Firefox 2 and Firefox 3 it is biased to return the biggest
@@ -28,7 +28,7 @@
 // Detects where Firefox lives. Returns an empty path if Firefox is not
 // installed.
 base::FilePath GetFirefoxInstallPathFromRegistry();
-#endif  // OS_WIN
+#endif  // BUILDFLAG(IS_WIN)
 
 struct FirefoxDetail {
   // |path| represents the Path field in Profiles.ini.
diff --git a/chrome/common/importer/importer_type.h b/chrome/common/importer/importer_type.h
index bfd2490..783aeeb8 100644
--- a/chrome/common/importer/importer_type.h
+++ b/chrome/common/importer/importer_type.h
@@ -15,17 +15,17 @@
 // across IPC.
 enum ImporterType {
   TYPE_UNKNOWN = -1,
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   TYPE_IE = 0,
 #endif
   // Value 1 was the (now deleted) Firefox 2 profile importer.
   TYPE_FIREFOX = 2,
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   TYPE_SAFARI = 3,
 #endif
   // Value 4 was the (now deleted) Google Toolbar importer.
   TYPE_BOOKMARKS_FILE = 5,  // Identifies a 'bookmarks.html' file.
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   TYPE_EDGE = 6,
 #endif
 };
diff --git a/chrome/common/importer/profile_import_process_param_traits_macros.h b/chrome/common/importer/profile_import_process_param_traits_macros.h
index 5278624a..81d070e7 100644
--- a/chrome/common/importer/profile_import_process_param_traits_macros.h
+++ b/chrome/common/importer/profile_import_process_param_traits_macros.h
@@ -17,7 +17,7 @@
 #include "content/public/common/common_param_traits.h"
 #include "ipc/ipc_message_macros.h"
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 IPC_ENUM_TRAITS_MIN_MAX_VALUE(importer::ImporterType,
                               importer::TYPE_UNKNOWN,
                               importer::TYPE_EDGE)
diff --git a/chrome/common/logging_chrome.cc b/chrome/common/logging_chrome.cc
index 4e35d60..7bf3952 100644
--- a/chrome/common/logging_chrome.cc
+++ b/chrome/common/logging_chrome.cc
@@ -14,7 +14,7 @@
 // logger in this file.  (We implement about:ipc on Mac but implement
 // the loggers here anyway).  We need to do this real early to be sure
 // IPC_MESSAGE_MACROS_LOG_ENABLED doesn't get undefined.
-#if defined(OS_POSIX) && BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
+#if BUILDFLAG(IS_POSIX) && BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
 #define IPC_MESSAGE_MACROS_LOG_ENABLED
 #include "content/public/common/content_ipc_logging.h"
 #define IPC_LOG_TABLE_ADD_ENTRY(msg_id, logger) \
@@ -22,7 +22,7 @@
 #include "chrome/common/all_messages.h"
 #endif
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 #include <windows.h>
 #endif
 
@@ -59,7 +59,7 @@
 #include "ash/constants/ash_switches.h"
 #endif
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 #include <initguid.h>
 #include "base/logging_win.h"
 #include "base/syslog_logging.h"
@@ -85,7 +85,7 @@
 // InitChromeLogging() and the beginning of CleanupChromeLogging().
 bool chrome_logging_redirected_ = false;
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 // {7FE69228-633E-4f06-80C1-527FEA23E3A7}
 const GUID kChromeTraceProviderName = {
     0x7fe69228, 0x633e, 0x4f06,
@@ -111,7 +111,7 @@
   assert_handler_ = new ScopedLogAssertHandler(
       base::BindRepeating(SilentRuntimeAssertHandler));
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   UINT new_flags = SEM_FAILCRITICALERRORS |
                    SEM_NOGPFAULTERRORBOX |
                    SEM_NOOPENFILEERRORBOX;
@@ -372,7 +372,7 @@
     }
   }
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
   // Enable trace control and transport through event tracing for Windows.
   LogEventProvider::Initialize(kChromeTraceProviderName);
 
diff --git a/chrome/common/media/cdm_host_file_path.cc b/chrome/common/media/cdm_host_file_path.cc
index d2b48c5..fe95403 100644
--- a/chrome/common/media/cdm_host_file_path.cc
+++ b/chrome/common/media/cdm_host_file_path.cc
@@ -16,7 +16,7 @@
 #include "chrome/common/chrome_constants.h"
 #include "chrome/common/chrome_version.h"
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #include "base/mac/bundle_locations.h"
 #endif
 
@@ -43,7 +43,7 @@
   DCHECK(cdm_host_file_paths);
   DCHECK(cdm_host_file_paths->empty());
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 
   static const base::FilePath::CharType* const kUnversionedFiles[] = {
       chrome::kBrowserProcessExecutableName};
@@ -78,7 +78,7 @@
     cdm_host_file_paths->emplace_back(file_path, GetSigFilePath(file_path));
   }
 
-#elif defined(OS_MAC)
+#elif BUILDFLAG(IS_MAC)
 
   base::FilePath framework_dir = base::mac::FrameworkBundlePath();
   base::FilePath chrome_framework_path =
@@ -95,7 +95,7 @@
   cdm_host_file_paths->emplace_back(chrome_framework_path,
                                     chrome_framework_sig_path);
 
-#elif defined(OS_LINUX) || defined(OS_CHROMEOS)
+#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
 
   base::FilePath chrome_exe_dir;
   if (!base::PathService::Get(base::DIR_EXE, &chrome_exe_dir))
@@ -106,7 +106,7 @@
   DVLOG(2) << __func__ << ": chrome_path=" << chrome_path.value();
   cdm_host_file_paths->emplace_back(chrome_path, GetSigFilePath(chrome_path));
 
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 }
 
 #else  // BUILDFLAG(GOOGLE_CHROME_BRANDING)
diff --git a/chrome/common/media/cdm_registration.cc b/chrome/common/media/cdm_registration.cc
index 2edc662..64ddcc6 100644
--- a/chrome/common/media/cdm_registration.cc
+++ b/chrome/common/media/cdm_registration.cc
@@ -24,11 +24,11 @@
 
 #if BUILDFLAG(ENABLE_WIDEVINE)
 #include "third_party/widevine/cdm/widevine_cdm_common.h"  // nogncheck
-#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_WIN)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_WIN)
 #include "base/native_library.h"
 #include "chrome/common/chrome_paths.h"
-#endif  // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_WIN)
-#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_WIN)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
 #include "base/no_destructor.h"
 #include "components/cdm/common/cdm_manifest.h"
 #include "media/cdm/supported_audio_codecs.h"
@@ -39,7 +39,7 @@
 #if !BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/common/media/component_widevine_cdm_hint_file_linux.h"
 #endif  // !BUILDFLAG(IS_CHROMEOS_ASH)
-#endif  // defined(OS_LINUX) || defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
 #endif  // BUILDFLAG(ENABLE_WIDEVINE)
 
 namespace {
@@ -49,7 +49,7 @@
 #if BUILDFLAG(ENABLE_WIDEVINE)
 #if (BUILDFLAG(BUNDLE_WIDEVINE_CDM) ||            \
      BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT)) && \
-    (defined(OS_LINUX) || defined(OS_CHROMEOS))
+    (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS))
 // Create a CdmInfo for a Widevine CDM, using |version|, |cdm_library_path|, and
 // |capability|.
 std::unique_ptr<content::CdmInfo> CreateWidevineCdmInfo(
@@ -88,11 +88,11 @@
 }
 #endif  // !BUILDFLAG(IS_CHROMEOS_ASH)
 #endif  // (BUILDFLAG(BUNDLE_WIDEVINE_CDM) ||
-        // BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT)) && (defined(OS_LINUX) ||
-        // defined(OS_CHROMEOS))
+        // BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT)) && (BUILDFLAG(IS_LINUX) ||
+        // BUILDFLAG(IS_CHROMEOS))
 
 #if BUILDFLAG(BUNDLE_WIDEVINE_CDM) && \
-    (defined(OS_LINUX) || defined(OS_CHROMEOS))
+    (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS))
 // On Linux/ChromeOS we have to preload the CDM since it uses the zygote
 // sandbox. On Windows and Mac, the bundled CDM is handled by the component
 // updater.
@@ -168,11 +168,11 @@
       }());
   return s_cdm_info->get();
 }
-#endif  // BUILDFLAG(BUNDLE_WIDEVINE_CDM) && (defined(OS_LINUX) ||
-        // defined(OS_CHROMEOS))
+#endif  // BUILDFLAG(BUNDLE_WIDEVINE_CDM) && (BUILDFLAG(IS_LINUX) ||
+        // BUILDFLAG(IS_CHROMEOS))
 
 #if BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT) && \
-    (defined(OS_LINUX) || defined(OS_CHROMEOS))
+    (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS))
 // This code checks to see if a component updated Widevine CDM can be found. If
 // there is one and it looks valid, return the CdmInfo for that CDM. Otherwise
 // return nullptr.
@@ -191,11 +191,11 @@
       }());
   return s_cdm_info->get();
 }
-#endif  // BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT) && (defined(OS_LINUX) ||
-        // defined(OS_CHROMEOS))
+#endif  // BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT) && (BUILDFLAG(IS_LINUX) ||
+        // BUILDFLAG(IS_CHROMEOS))
 
 void AddSoftwareSecureWidevine(std::vector<content::CdmInfo>* cdms) {
-#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
   // The Widevine CDM on Linux needs to be registered (and loaded) before the
   // zygote is locked down. The CDM can be found from the version bundled with
   // Chrome (if BUNDLE_WIDEVINE_CDM = true) and/or the version downloaded by
@@ -233,7 +233,7 @@
   } else {
     VLOG(1) << "Widevine enabled but no library found";
   }
-#endif  // defined(OS_LINUX) || defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
 }
 
 void AddHardwareSecureWidevine(std::vector<content::CdmInfo>* cdms) {
diff --git a/chrome/common/media/component_widevine_cdm_hint_file_linux.h b/chrome/common/media/component_widevine_cdm_hint_file_linux.h
index 328ec6d..3b67a16 100644
--- a/chrome/common/media/component_widevine_cdm_hint_file_linux.h
+++ b/chrome/common/media/component_widevine_cdm_hint_file_linux.h
@@ -15,7 +15,7 @@
 
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
-#if !(defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
+#if !(BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
 #error "This file only applies to desktop Linux."
 #endif
 
diff --git a/chrome/common/media/media_resource_provider.cc b/chrome/common/media/media_resource_provider.cc
index cb6ec96..bbb6dc91 100644
--- a/chrome/common/media/media_resource_provider.cc
+++ b/chrome/common/media/media_resource_provider.cc
@@ -14,7 +14,7 @@
   switch (message_id) {
     case media::DEFAULT_AUDIO_DEVICE_NAME:
       return IDS_DEFAULT_AUDIO_DEVICE_NAME;
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
     case media::COMMUNICATIONS_AUDIO_DEVICE_NAME:
       return IDS_COMMUNICATIONS_AUDIO_DEVICE_NAME;
 #endif
diff --git a/chrome/common/multi_process_lock_unittest.cc b/chrome/common/multi_process_lock_unittest.cc
index d299e23..b297243 100644
--- a/chrome/common/multi_process_lock_unittest.cc
+++ b/chrome/common/multi_process_lock_unittest.cc
@@ -72,15 +72,15 @@
   // Mac OS X: BOOTSTRAP_MAX_NAME_LEN
   // Windows: MAX_PATH
   LOG(INFO) << "Following error log due to long name is expected";
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   std::string name("This is a name that is longer than one hundred and "
       "twenty-eight characters to make sure that we fail appropriately on "
       "Mac OS X when we have a path that is too long for Mac OS X to handle");
-#elif defined(OS_POSIX)
+#elif BUILDFLAG(IS_POSIX)
   std::string name("This is a name that is longer than one hundred and eight "
       "characters to make sure that we fail appropriately on POSIX systems "
       "when we have a path that is too long for the system to handle");
-#elif defined(OS_WIN)
+#elif BUILDFLAG(IS_WIN)
   std::string name("This is a name that is longer than two hundred and sixty "
       "characters to make sure that we fail appropriately on Windows when we "
       "have a path that is too long for Windows to handle "
@@ -135,14 +135,14 @@
   std::unique_ptr<base::Environment> environment(base::Environment::Create());
   EXPECT_TRUE(environment->GetVar(MultiProcessLockTest::kLockEnvironmentVarName,
                                   &name));
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   // OS X sends out a log if a lock fails.
   // Hopefully this will keep people from panicking about it when they
   // are perusing the build logs.
   LOG(INFO) << "Following error log "
             << "\"CFMessagePort: bootstrap_register(): failed 1100 (0x44c) "
             << "'Permission denied'\" is expected";
-#endif  // defined(OS_MAC)
+#endif  // BUILDFLAG(IS_MAC)
   std::unique_ptr<MultiProcessLock> test_lock = MultiProcessLock::Create(name);
 
   // Expect locking to fail because it is claimed by another process.
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index ef3e7f9c..5df863c4 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -68,7 +68,7 @@
 // This is the profile creation time.
 const char kProfileCreationTime[] = "profile.creation_time";
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 // This is a timestamp of the last time this profile was reset by a third party
 // tool. On Windows, a third party tool may set a registry value that will be
 // compared to this value and if different will result in a profile reset
@@ -115,14 +115,14 @@
 // Boolean that is true when user feedback to Google is allowed.
 const char kUserFeedbackAllowed[] = "feedback_allowed";
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 // Replaced by kManagedSerialAllowAllPortsForUrls in M-93.
 const char kManagedProfileSerialAllowAllPortsForUrlsDeprecated[] =
     "profile.managed.serial_allow_all_ports_for_urls";
 // Replaced by kManagedSerialAllowUsbDevicesForUrls in M-93.
 const char kManagedProfileSerialAllowUsbDevicesForUrlsDeprecated[] =
     "profile.managed.serial_allow_usb_devices_for_urls";
-#endif  // !defined(OS_ANDROID)
+#endif  // !BUILDFLAG(IS_ANDROID)
 
 #if BUILDFLAG(ENABLE_SUPERVISED_USERS) && BUILDFLAG(ENABLE_EXTENSIONS)
 // DictionaryValue that maps extension ids to the approved version of this
@@ -275,13 +275,13 @@
 const char kWebKitFantasyFontFamilyMap[] = WEBKIT_WEBPREFS_FONTS_FANTASY;
 const char kWebKitStandardFontFamilyArabic[] =
     "webkit.webprefs.fonts.standard.Arab";
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 const char kWebKitFixedFontFamilyArabic[] = "webkit.webprefs.fonts.fixed.Arab";
 #endif
 const char kWebKitSerifFontFamilyArabic[] = "webkit.webprefs.fonts.serif.Arab";
 const char kWebKitSansSerifFontFamilyArabic[] =
     "webkit.webprefs.fonts.sansserif.Arab";
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 const char kWebKitStandardFontFamilyCyrillic[] =
     "webkit.webprefs.fonts.standard.Cyrl";
 const char kWebKitFixedFontFamilyCyrillic[] =
@@ -311,7 +311,7 @@
 const char kWebKitSerifFontFamilyKorean[] = "webkit.webprefs.fonts.serif.Hang";
 const char kWebKitSansSerifFontFamilyKorean[] =
     "webkit.webprefs.fonts.sansserif.Hang";
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 const char kWebKitCursiveFontFamilyKorean[] =
     "webkit.webprefs.fonts.cursive.Hang";
 #endif
@@ -331,7 +331,7 @@
     "webkit.webprefs.fonts.serif.Hant";
 const char kWebKitSansSerifFontFamilyTraditionalHan[] =
     "webkit.webprefs.fonts.sansserif.Hant";
-#if defined(OS_WIN) || defined(OS_MAC)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
 const char kWebKitCursiveFontFamilySimplifiedHan[] =
     "webkit.webprefs.fonts.cursive.Hans";
 const char kWebKitCursiveFontFamilyTraditionalHan[] =
@@ -348,7 +348,7 @@
 const char kWebkitTabsToLinks[] = "webkit.webprefs.tabs_to_links";
 const char kWebKitAllowRunningInsecureContent[] =
     "webkit.webprefs.allow_running_insecure_content";
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 const char kWebKitFontScaleFactor[] = "webkit.webprefs.font_scale_factor";
 const char kWebKitForceEnableZoom[] = "webkit.webprefs.force_enable_zoom";
 const char kWebKitPasswordEchoEnabled[] =
@@ -394,7 +394,7 @@
 // Boolean that is true when Suggest support is enabled.
 const char kSearchSuggestEnabled[] = "search.suggest_enabled";
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 // String indicating the Contextual Search enabled state.
 // "false" - opt-out (disabled)
 // "" (empty string) - undecided
@@ -412,9 +412,9 @@
 // Search.
 const char kContextualSearchWasFullyPrivacyEnabled[] =
     "search.contextual_search_fully_opted_in";
-#endif  // defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_ANDROID)
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 // Boolean that indicates whether the browser should put up a confirmation
 // window when the user is attempting to quit. Only on Mac.
 const char kConfirmToQuitEnabled[] = "browser.confirm_to_quit";
@@ -443,7 +443,7 @@
 // Pref storing the user's network easter egg game high score.
 const char kNetworkEasterEggHighScore[] = "net.easter_egg_high_score";
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 // Last time that a check for cloud policy management was done. This time is
 // recorded on Android so that retries aren't attempted on every startup.
 // Instead the cloud policy registration is retried at least 1 or 3 days later.
@@ -469,7 +469,7 @@
 // from the New Tab Page and app launcher.
 const char kHideWebStoreIcon[] = "hide_web_store_icon";
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 // The list of extensions allowed to use the platformKeys API for remote
 // attestation.
 const char kAttestationExtensionAllowlist[] = "attestation.extension_allowlist";
@@ -1135,7 +1135,7 @@
     "restricted_managed_guest_session_extension_cleanup_exempt_list";
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 // A pref holding the value of the policy used to disable mounting of external
 // storage for the user.
 const char kExternalStorageDisabled[] = "hardware.external_storage_disabled";
@@ -1159,7 +1159,7 @@
 // There is code migrating from the legacy Local State pref to the Profile pref
 // in policy_cert_service_factory_ash.cc::MigrateLocalPrefIntoProfilePref .
 const char kUsedPolicyCertificates[] = "policy.used_policy_certificates";
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
 // A boolean pref set to true if a Home button to open the Home pages should be
 // visible on the toolbar.
@@ -1194,7 +1194,7 @@
 
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
-#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
 // Linux specific preference on whether we should match the system theme.
 const char kUsesSystemTheme[] = "extensions.theme.use_system";
 #endif
@@ -1269,7 +1269,7 @@
 const char kAccessibilityImageLabelsOptInAccepted[] =
     "settings.a11y.enable_accessibility_image_labels_opt_in_accepted";
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 // Whether the "Get Image Descriptions from Google" feature is enabled on
 // Android. We expose this only to mobile Android.
 const char kAccessibilityImageLabelsEnabledAndroid[] =
@@ -1287,7 +1287,7 @@
     "settings.a11y.focus_highlight";
 #endif
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 // Boolean that indicates whether the application should show the info bar
 // asking the user to set up automatic updates when Keystone promotion is
 // required.
@@ -1297,7 +1297,7 @@
 
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
-#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
 // Boolean that is false if we should show window manager decorations.  If
 // true, we draw a custom chrome frame (thicker title bar and blue border).
 const char kUseCustomChromeFrame[] = "browser.custom_chrome_frame";
@@ -1316,9 +1316,9 @@
 // be displayed at the default zoom level.
 const char kPartitionPerHostZoomLevels[] = "partition.per_host_zoom_levels";
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 const char kPinnedTabs[] = "pinned_tabs";
-#endif  // !defined(OS_ANDROID)
+#endif  // !BUILDFLAG(IS_ANDROID)
 
 // Preference to disable 3D APIs (WebGL, Pepper 3D).
 const char kDisable3DAPIs[] = "disable_3d_apis";
@@ -1424,7 +1424,7 @@
 const char kPrintPreviewDefaultDestinationSelectionRules[] =
     "printing.default_destination_selection_rules";
 
-#if defined(OS_WIN) || defined(OS_MAC)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
 // Boolean controlling whether the "Print as image" option should be available
 // in Print Preview when printing a PDF.
 const char kPrintPdfAsImageAvailability[] =
@@ -1441,7 +1441,7 @@
 const char kPrintPdfAsImageDefault[] = "printing.print_pdf_as_image_default";
 #endif
 
-#if defined(OS_WIN) && BUILDFLAG(ENABLE_PRINTING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(ENABLE_PRINTING)
 // An integer pref that holds the PostScript mode to use when printing.
 const char kPrintPostScriptMode[] = "printing.postscript_mode";
 
@@ -1449,7 +1449,7 @@
 const char kPrintRasterizationMode[] = "printing.rasterization_mode";
 #endif
 
-#if !BUILDFLAG(IS_CHROMEOS_ASH) && !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_ANDROID)
 // A pref that sets the default destination in Print Preview to always be the
 // OS default printer instead of the most recently used destination.
 const char kPrintPreviewUseSystemDefaultPrinter[] =
@@ -1461,7 +1461,7 @@
 // case of a later emergency version rollback.
 const char kUserDataSnapshotRetentionLimit[] =
     "downgrade.snapshot_retention_limit";
-#endif  // !OS_CHROMEOS && !OS_ANDROID
+#endif  // !BUILDFLAG(IS_CHROMEOS) && !BUILDFLAG(IS_ANDROID)
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 // List of print servers ids that are allowed in the user policy. List of
@@ -1558,7 +1558,7 @@
 // platforms.
 const char kFullscreenAllowed[] = "fullscreen.allowed";
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 // Boolean pref indicating whether notification permissions were migrated to
 // notification channels (on Android O+ we use channels to store notification
 // permission, so any existing permissions must be migrated).
@@ -1574,7 +1574,7 @@
 // Usage stats reporting opt-in.
 const char kUsageStatsEnabled[] = "usage_stats_reporting.enabled";
 
-#endif  // defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_ANDROID)
 
 // Maps from app ids to origin + Service Worker registration ID.
 const char kPushMessagingAppIdentifierMap[] =
@@ -1615,7 +1615,7 @@
 const char kWebRTCAllowLegacyTLSProtocols[] =
     "webrtc.allow_legacy_tls_protocols";
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 // Whether or not this profile has been shown the Welcome page.
 const char kHasSeenWelcomePage[] = "browser.has_seen_welcome_page";
 
@@ -1632,12 +1632,12 @@
     "profile.managed_accounts.restriction.all_managed_accounts";
 #endif
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 // Put the user into an onboarding group that's decided when they go through
 // the first run onboarding experience. Only users in a group will have their
 // finch group pinged to keep track of them for the experiment.
 const char kNaviOnboardGroup[] = "browser.navi_onboard_group";
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 
 // Boolean indicating whether, as part of the adaptive activation quiet UI dry
 // run experiment, the user has accumulated three notification permission
@@ -1670,7 +1670,7 @@
 // *************** LOCAL STATE ***************
 // These are attached to the machine/installation
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 // Used to store the value of the SerialAllowAllPortsForUrls policy.
 const char kManagedSerialAllowAllPortsForUrls[] =
     "managed.serial_allow_all_ports_for_urls";
@@ -1678,7 +1678,7 @@
 // Used to store the value of the SerialAllowUsbDevicesForUrls policy.
 const char kManagedSerialAllowUsbDevicesForUrls[] =
     "managed.serial_allow_usb_devices_for_urls";
-#endif  // !defined(OS_ANDROID)
+#endif  // !BUILDFLAG(IS_ANDROID)
 
 // Directory of the last profile used.
 const char kProfileLastUsed[] = "profile.last_used";
@@ -1770,13 +1770,13 @@
 // upgrade a unsafe location to a safe location.
 const char kDownloadDirUpgraded[] = "download.directory_upgrade";
 
-#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS) || \
-    defined(OS_MAC)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \
+    BUILDFLAG(IS_MAC)
 const char kOpenPdfDownloadInSystemReader[] =
     "download.open_pdf_in_system_reader";
 #endif
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 // Int (as defined by DownloadPromptStatus) which specifies whether we should
 // ask the user where they want to download the file (only for Android).
 const char kPromptForDownloadAndroid[] = "download.prompt_for_download_android";
@@ -1866,7 +1866,7 @@
 // before shutting everything down.
 const char kRestartLastSessionOnShutdown[] = "restart.last.session.on.shutdown";
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 #if !BUILDFLAG(IS_CHROMEOS_ASH)
 // Boolean that specifies whether or not to show security warnings for some
 // potentially bad command-line flags. True by default. Controlled by the
@@ -1887,7 +1887,7 @@
 
 // Set before autorestarting Chrome, cleared on clean exit.
 const char kWasRestarted[] = "was.restarted";
-#endif  // !defined(OS_ANDROID)
+#endif  // !BUILDFLAG(IS_ANDROID)
 
 // Whether Extensions are enabled.
 const char kDisableExtensions[] = "extensions.disabled";
@@ -1898,7 +1898,7 @@
 // Keeps track of which sessions are collapsed in the Other Devices menu.
 const char kNtpCollapsedForeignSessions[] = "ntp.collapsed_foreign_sessions";
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 // Keeps track of recently closed tabs collapsed state in the Other Devices
 // menu.
 const char kNtpCollapsedRecentlyClosedTabs[] =
@@ -1922,7 +1922,9 @@
 const char kNtpModulesVisible[] = "NewTabPage.ModulesVisible";
 // List of promos that the user has dismissed while on the NTP.
 const char kNtpPromoBlocklist[] = "ntp.promo_blocklist";
-#endif  // defined(OS_ANDROID)
+// Whether the promo is visible.
+const char kNtpPromoVisible[] = "ntp.promo_visible";
+#endif  // BUILDFLAG(IS_ANDROID)
 
 // Which page should be visible on the new tab page v4
 const char kNtpShownPage[] = "ntp.shown_page";
@@ -1990,7 +1992,7 @@
 const char kDevToolsSyncedPreferencesSyncDisabled[] =
     "devtools.synced_preferences_sync_disabled";
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 // Tracks the number of times the dice signin promo has been shown in the user
 // menu.
 const char kDiceSigninUserMenuPromoCount[] = "sync_promo.user_menu_show_count";
@@ -2058,8 +2060,8 @@
 // its isolation requirements.
 const char kWebAppsIsolationState[] = "web_apps.isolation_state";
 
-#if defined(OS_WIN) || defined(OS_MAC) || \
-    (defined(OS_LINUX) && !BUILDFLAG(IS_CHROMEOS_LACROS))
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || \
+    (BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS_LACROS))
 // Dictionary that maps origins to web apps that can act as URL handlers.
 const char kWebAppsUrlHandlerInfo[] = "web_apps.url_handler_info";
 #endif
@@ -2111,7 +2113,7 @@
 // the content.
 const char kMediaStorageIdSalt[] = "media.storage_id_salt";
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 // Mapping of origin to their origin id (UnguessableToken). Origin IDs are only
 // stored for origins using MediaFoundation-based CDMs.
 const char kMediaCdmOriginData[] = "media.cdm.origin_data";
@@ -2120,7 +2122,7 @@
 // sandboxed.
 const char kNetworkServiceSandboxEnabled[] = "net.network_service_sandbox";
 
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 
 // The last used printer and its settings.
 const char kPrintPreviewStickySettings[] =
@@ -2186,17 +2188,17 @@
 // requests.
 const char kBasicAuthOverHttpEnabled[] = "auth.basic_over_http_enabled";
 
-#if defined(OS_LINUX) || defined(OS_MAC) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_CHROMEOS)
 // Boolean that specifies whether OK-AS-DELEGATE flag from KDC is respected
 // along with kAuthNegotiateDelegateAllowlist.
 const char kAuthNegotiateDelegateByKdcPolicy[] =
     "auth.negotiate_delegate_by_kdc_policy";
-#endif  // defined(OS_LINUX) || defined(OS_MAC) || defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_CHROMEOS)
 
-#if defined(OS_POSIX) || defined(OS_FUCHSIA)
+#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
 // Boolean that specifies whether NTLMv2 is enabled.
 const char kNtlmV2Enabled[] = "auth.ntlm_v2_enabled";
-#endif  // defined(OS_POSIX) || defined(OS_FUCHSIA)
+#endif  // BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 // Boolean whether Kerberos functionality is enabled.
@@ -2592,13 +2594,13 @@
 
 // Pref name for the policy controlling whether to enable Media Router.
 const char kEnableMediaRouter[] = "media_router.enable_media_router";
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 // Pref name for the policy controlling whether to force the Cast icon to be
 // shown in the toolbar/overflow menu.
 const char kShowCastIconInToolbar[] = "media_router.show_cast_icon_in_toolbar";
-#endif  // !defined(OS_ANDROID)
+#endif  // !BUILDFLAG(IS_ANDROID)
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 // Pref name for the policy controlling the way in which users are notified of
 // the need to relaunch the browser for a pending update.
 const char kRelaunchNotification[] = "browser.relaunch_notification";
@@ -2610,7 +2612,7 @@
 // Pref name for the policy controlling the time interval within which the
 // relaunch should take place.
 const char kRelaunchWindow[] = "browser.relaunch_window";
-#endif  // !defined(OS_ANDROID)
+#endif  // !BUILDFLAG(IS_ANDROID)
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 // Pref name for the policy controlling the time period between the first user
@@ -2619,12 +2621,12 @@
 const char kRelaunchHeadsUpPeriod[] = "browser.relaunch_heads_up_period";
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 // Counts how many times prominent call-to-actions have occurred as part of the
 // Mac restore permissions experiment. https://crbug.com/1211052
 const char kMacRestoreLocationPermissionsExperimentCount[] =
     "mac_restore_location_permissions_experiment_count";
-#endif  // defined(OS_MAC)
+#endif  // BUILDFLAG(IS_MAC)
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 // Boolean indicating whether the Enrollment ID (EID) has already been uploaded
@@ -2679,7 +2681,7 @@
 // Preference to store proxy settings.
 const char kMaxConnectionsPerProxy[] = "net.max_connections_per_proxy";
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 // Set to true if the user removed our login item so we should not create a new
 // one when uninstalling background apps.
 const char kUserRemovedLoginItem[] = "background_mode.user_removed_login_item";
@@ -2716,7 +2718,7 @@
 // by the cloud policy subsystem.
 const char kDevicePolicyRefreshRate[] = "policy.device_refresh_rate";
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 // A boolean where true means that the browser has previously attempted to
 // enable autoupdate and failed, so the next out-of-date browser start should
 // not prompt the user to enable autoupdate, it should offer to reinstall Chrome
@@ -2731,7 +2733,7 @@
 // gallery.
 const char kMediaGalleriesRememberedGalleries[] =
     "media_galleries.remembered_galleries";
-#endif  // !defined(OS_ANDROID)
+#endif  // !BUILDFLAG(IS_ANDROID)
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 const char kPolicyPinnedLauncherApps[] = "policy_pinned_launcher_apps";
@@ -2743,7 +2745,7 @@
     "shelf_default_pin_layout_rolls_for_tablet_form_factor";
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 // Counts how many more times the 'profile on a network share' warning should be
 // shown to the user before the next silence period.
 const char kNetworkProfileWarningsLeft[] = "network_profile.warnings_left";
@@ -2755,7 +2757,7 @@
 // The last Chrome version at which
 // shell_integration::win::MigrateTaskbarPins() completed.
 const char kShortcutMigrationVersion[] = "browser.shortcut_migration_version";
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 // The RLZ brand code, if enabled.
@@ -2789,14 +2791,14 @@
 const char kWatchdogExtensionActive[] =
     "profile.extensions.activity_log.num_consumers_active";
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 // A list of partner bookmark rename/remove mappings.
 // Each list item is a dictionary containing a "url", a "provider_title" and
 // "mapped_title" entries, detailing the bookmark target URL (if any), the title
 // given by the PartnerBookmarksProvider and either the user-visible renamed
 // title or an empty string if the bookmark node was removed.
 const char kPartnerBookmarkMappings[] = "partnerbookmarks.mappings";
-#endif  // defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_ANDROID)
 
 // Whether DNS Quick Check is disabled in proxy resolution.
 //
@@ -2844,13 +2846,13 @@
 // Boolean which indicate if signin interception is enabled.
 const char kSigninInterceptionEnabled[] = "signin.interception_enabled";
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 // Boolean pref indicating whether the user is allowed to create secondary
 // profiles in Lacros browser. This is set by a policy, and the default value
 // for managed users is false.
 const char kLacrosSecondaryProfilesAllowed[] =
     "lacros_secondary_profiles_allowed";
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
 // Device identifier used by CryptAuth stored in local state. This ID is
 // combined with a user ID before being registered with the CryptAuth server,
@@ -2883,7 +2885,7 @@
 const char kRecoveryComponentNeedsElevation[] =
     "recovery_component.needs_elevation";
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 // Boolean that indicates whether Chrome enterprise extension request is enabled
 // or not.
 const char kCloudExtensionRequestEnabled[] =
@@ -2911,7 +2913,7 @@
 
 const char kAllowDinosaurEasterEgg[] = "allow_dinosaur_easter_egg";
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 // Whether the update menu item was clicked. Used to facilitate logging whether
 // Chrome was updated after the menu item is clicked.
 const char kClickedUpdateMenuItem[] = "omaha.clicked_update_menu_item";
@@ -2921,7 +2923,7 @@
     "omaha.latest_version_when_clicked_upate_menu_item";
 #endif
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 // The serialized timestamps of latest shown merchant viewer messages.
 const char kCommerceMerchantViewerMessagesShownTime[] =
     "commerce_merchant_viewer_messages_shown_time";
@@ -2946,7 +2948,7 @@
 // value.
 const char kWebShareVisitedTargets[] = "profile.web_share.visited_targets";
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 // Acts as a cache to remember incompatible applications through restarts. Used
 // for the Incompatible Applications Warning feature.
 const char kIncompatibleApplications[] = "incompatible_applications";
@@ -2959,9 +2961,9 @@
 // A boolean value, controlling whether third party software is allowed to
 // inject into Chrome's processes.
 const char kThirdPartyBlockingEnabled[] = "third_party_blocking_enabled";
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 // A boolean value, controlling whether Chrome renderer processes have the CIG
 // mitigation enabled.
 const char kRendererCodeIntegrityEnabled[] = "renderer_code_integrity_enabled";
@@ -2970,7 +2972,7 @@
 // ProcessExtensionPointDisablePolicy enabled.
 const char kBlockBrowserLegacyExtensionPoints[] =
     "block_browser_legacy_extension_points";
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 
 // An integer that keeps track of prompt waves for the settings reset
 // prompt. Users will be prompted to reset settings at most once per prompt wave
@@ -2997,7 +2999,7 @@
 const char kSettingsResetPromptLastTriggeredForHomepage[] =
     "settings_reset_prompt.last_triggered_for_homepage";
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 // Timestamp of the clipboard's last modified time, stored in base::Time's
 // internal format (int64) in local store.  (I.e., this is not a per-profile
 // pref.)
@@ -3093,7 +3095,7 @@
 extern const char kDisplayCapturePermissionsPolicyEnabled[] =
     "display_capture_permissions_policy_enabled";
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 // Boolean to allow SharedArrayBuffer in non-crossOriginIsolated contexts.
 // TODO(crbug.com/1144104) Remove when migration to COOP+COEP is complete.
 const char kSharedArrayBufferUnrestrictedAccessAllowed[] =
@@ -3107,14 +3109,14 @@
 
 // Boolean that specifies whether autoplay blocking is enabled.
 const char kBlockAutoplayEnabled[] = "media.block_autoplay";
-#endif  // !defined(OS_ANDROID)
+#endif  // !BUILDFLAG(IS_ANDROID)
 
 // Boolean allowing Chrome to block external protocol navigation in sandboxed
 // iframes.
 const char kSandboxExternalProtocolBlocked[] =
     "profile.sandbox_external_protocol_blocked";
 
-#if defined(OS_LINUX)
+#if BUILDFLAG(IS_LINUX)
 // Boolean that indicates if native notifications are allowed to be used in
 // place of Chrome notifications. Will be replaced by kAllowSystemNotifications.
 const char kAllowNativeNotifications[] = "native_notifications.allowed";
@@ -3122,7 +3124,7 @@
 // Boolean that indicates if system notifications are allowed to be used in
 // place of Chrome notifications.
 const char kAllowSystemNotifications[] = "system_notifications.allowed";
-#endif  // defined(OS_LINUX)
+#endif  // BUILDFLAG(IS_LINUX)
 
 // Integer that holds the value of the next persistent notification ID to be
 // used.
@@ -3148,7 +3150,7 @@
 // TODO(https://crbug.com/1003101): Remove this in Chrome 88.
 const char kAllowSyncXHRInPageDismissal[] = "allow_sync_xhr_in_page_dismissal";
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 // Enum that specifies client certificate management permissions for user. It
 // can have one of the following values.
 // 0: Users can manage all certificates.
@@ -3180,10 +3182,10 @@
 const char kSharingFCMRegistration[] = "sharing.fcm_registration";
 const char kSharingLocalSharingInfo[] = "sharing.local_sharing_info";
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 // Dictionary that contains all of the Hats Survey Metadata.
 const char kHatsSurveyMetadata[] = "hats.survey_metadata";
-#endif  // !defined(OS_ANDROID)
+#endif  // !BUILDFLAG(IS_ANDROID)
 
 const char kExternalProtocolDialogShowAlwaysOpenCheckbox[] =
     "external_protocol_dialog.show_always_open_checkbox";
@@ -3199,7 +3201,7 @@
 // This pref enables the ScrollToTextFragment feature.
 const char kScrollToTextFragmentEnabled[] = "scroll_to_text_fragment_enabled";
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 // Last time the known interception disclosure message was dismissed. Used to
 // ensure a cooldown period passes before the disclosure message is displayed
 // again.
@@ -3251,7 +3253,7 @@
     "adb_sideloading_powerwash_on_next_reboot_notification_shown";
 #endif
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 // Boolean pref that indicates whether caret browsing is currently enabled.
 const char kCaretBrowsingEnabled[] = "settings.a11y.caretbrowsing.enabled";
 
@@ -3298,7 +3300,7 @@
     "security_token_session_notification_scheduled";
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 // Boolean pref indicating whether user has hidden the cart module on NTP.
 const char kCartModuleHidden[] = "cart_module_hidden";
 // An integer that keeps track of how many times welcome surface has shown in
@@ -3318,13 +3320,13 @@
 const char kCartDiscountLastFetchedTime[] = "cart_discount_last_fetched_time";
 #endif
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 // Boolean pref controlling whether immersive AR sessions are enabled
 // in WebXR Device API.
 const char kWebXRImmersiveArEnabled[] = "webxr.immersive_ar_enabled";
 #endif
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 // The duration for keepalive requests on browser shutdown.
 const char kFetchKeepaliveDurationOnShutdown[] =
     "fetch_keepalive_duration_on_shutdown";
@@ -3341,21 +3343,21 @@
 const char kExplicitlyAllowedNetworkPorts[] =
     "net.explicitly_allowed_network_ports";
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 // Pref name for whether force-installed web apps (origins) are able to query
 // device attributes.
 const char kDeviceAttributesAllowedForOrigins[] =
     "policy.device_attributes_allowed_for_origins";
 #endif
 
-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
+#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS)
 // A boolean indicating whether the desktop sharing hub is enabled by enterprise
 // policy.
 const char kDesktopSharingHubEnabled[] =
     "sharing_hub.desktop_sharing_hub_enabled";
 #endif
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 // Pref name for the last major version where the What's New page was
 // successfully shown.
 const char kLastWhatsNewVersion[] = "browser.last_whats_new_version";
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index a50c00a..f5fbd851 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -34,7 +34,7 @@
 extern const char kHttpsOnlyModeEnabled[];
 extern const char kImportantSitesDialogHistory[];
 extern const char kProfileCreationTime[];
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 extern const char kLastProfileResetTimestamp[];
 extern const char kChromeCleanerResetPending[];
 extern const char kChromeCleanerScanCompletionTime[];
@@ -43,10 +43,10 @@
 extern const char kProfileIconVersion[];
 extern const char kRestoreOnStartup[];
 extern const char kSessionExitType[];
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 extern const char kManagedProfileSerialAllowAllPortsForUrlsDeprecated[];
 extern const char kManagedProfileSerialAllowUsbDevicesForUrlsDeprecated[];
-#endif  // !defined(OS_ANDROID)
+#endif  // !BUILDFLAG(IS_ANDROID)
 #if BUILDFLAG(ENABLE_SUPERVISED_USERS) && BUILDFLAG(ENABLE_EXTENSIONS)
 extern const char kSupervisedUserApprovedExtensions[];
 #endif  // BUILDFLAG(ENABLE_SUPERVISED_USERS) && BUILDFLAG(ENABLE_EXTENSIONS)
@@ -108,12 +108,12 @@
 // Per-script font prefs that have defaults, for easy reference when registering
 // the defaults.
 extern const char kWebKitStandardFontFamilyArabic[];
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 extern const char kWebKitFixedFontFamilyArabic[];
 #endif
 extern const char kWebKitSerifFontFamilyArabic[];
 extern const char kWebKitSansSerifFontFamilyArabic[];
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 extern const char kWebKitStandardFontFamilyCyrillic[];
 extern const char kWebKitFixedFontFamilyCyrillic[];
 extern const char kWebKitSerifFontFamilyCyrillic[];
@@ -131,7 +131,7 @@
 extern const char kWebKitFixedFontFamilyKorean[];
 extern const char kWebKitSerifFontFamilyKorean[];
 extern const char kWebKitSansSerifFontFamilyKorean[];
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 extern const char kWebKitCursiveFontFamilyKorean[];
 #endif
 extern const char kWebKitStandardFontFamilySimplifiedHan[];
@@ -142,7 +142,7 @@
 extern const char kWebKitFixedFontFamilyTraditionalHan[];
 extern const char kWebKitSerifFontFamilyTraditionalHan[];
 extern const char kWebKitSansSerifFontFamilyTraditionalHan[];
-#if defined(OS_WIN) || defined(OS_MAC)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
 extern const char kWebKitCursiveFontFamilySimplifiedHan[];
 extern const char kWebKitCursiveFontFamilyTraditionalHan[];
 #endif
@@ -161,7 +161,7 @@
 extern const char kWebkitTabsToLinks[];
 extern const char kWebKitAllowRunningInsecureContent[];
 extern const char kWebKitForceDarkModeEnabled[];
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 extern const char kWebKitFontScaleFactor[];
 extern const char kWebKitForceEnableZoom[];
 extern const char kWebKitPasswordEchoEnabled[];
@@ -170,28 +170,28 @@
 extern const char kSSLErrorOverrideAllowedForOrigins[];
 extern const char kIncognitoModeAvailability[];
 extern const char kSearchSuggestEnabled[];
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 extern const char kContextualSearchEnabled[];
 extern const char kContextualSearchDisabledValue[];
 extern const char kContextualSearchEnabledValue[];
 extern const char kContextualSearchPromoCardShownCount[];
 extern const char kContextualSearchWasFullyPrivacyEnabled[];
-#endif  // defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_ANDROID)
 extern const char kShowInternalAccessibilityTree[];
 extern const char kAccessibilityImageLabelsEnabled[];
 extern const char kAccessibilityImageLabelsOptInAccepted[];
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 extern const char kAccessibilityImageLabelsEnabledAndroid[];
 extern const char kAccessibilityImageLabelsOnlyOnWifi[];
 #endif
 #if !BUILDFLAG(IS_CHROMEOS_ASH)
 extern const char kAccessibilityFocusHighlightEnabled[];
 #endif
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 extern const char kLiveCaptionEnabled[];
 extern const char kLiveCaptionLanguageCode[];
 #endif
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 extern const char kConfirmToQuitEnabled[];
 extern const char kShowFullscreenToolbar[];
 extern const char kAllowJavascriptAppleEvents[];
@@ -200,13 +200,13 @@
 extern const char kQuicAllowed[];
 extern const char kNetworkQualities[];
 extern const char kNetworkEasterEggHighScore[];
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 extern const char kLastPolicyCheckTime[];
 #endif
 extern const char kNetworkPredictionOptions[];
 extern const char kPreinstalledAppsInstallState[];
 extern const char kHideWebStoreIcon[];
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 extern const char kAttestationExtensionAllowlist[];
 extern const char kPrintingAPIExtensionsAllowlist[];
 #endif
@@ -358,12 +358,12 @@
 extern const char kEduCoexistenceArcMigrationCompleted[];
 extern const char kRestrictedManagedGuestSessionExtensionCleanupExemptList[];
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 extern const char kExternalStorageDisabled[];
 extern const char kExternalStorageReadOnly[];
 extern const char kSettingsShowOSBanner[];
 extern const char kUsedPolicyCertificates[];
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 extern const char kShowHomeButton[];
 extern const char kSpeechRecognitionFilterProfanities[];
 extern const char kAllowDeletingBrowserHistory[];
@@ -375,7 +375,7 @@
 #endif  //  BUILDFLAG(IS_CHROMEOS_LACROS)
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
-#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
 extern const char kUsesSystemTheme[];
 #endif
 extern const char kCurrentThemePackFilename[];
@@ -399,12 +399,12 @@
 extern const char kDefaultBrowserLastDeclined[];
 extern const char kResetCheckDefaultBrowser[];
 extern const char kDefaultBrowserSettingEnabled[];
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 extern const char kShowUpdatePromotionInfoBar[];
 #endif
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
-#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
 extern const char kUseCustomChromeFrame[];
 #endif
 #if BUILDFLAG(ENABLE_PLUGINS)
@@ -413,9 +413,9 @@
 extern const char kPartitionDefaultZoomLevel[];
 extern const char kPartitionPerHostZoomLevels[];
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 extern const char kPinnedTabs[];
-#endif  // !defined(OS_ANDROID)
+#endif  // !BUILDFLAG(IS_ANDROID)
 
 extern const char kDisable3DAPIs[];
 extern const char kEnableHyperlinkAuditing[];
@@ -456,7 +456,7 @@
 extern const char kPrintPreviewDisabled[];
 extern const char kPrintPreviewDefaultDestinationSelectionRules[];
 
-#if defined(OS_WIN) || defined(OS_MAC)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
 extern const char kPrintPdfAsImageAvailability[];
 #endif
 
@@ -465,12 +465,12 @@
 extern const char kPrintPdfAsImageDefault[];
 #endif
 
-#if defined(OS_WIN) && BUILDFLAG(ENABLE_PRINTING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(ENABLE_PRINTING)
 extern const char kPrintPostScriptMode[];
 extern const char kPrintRasterizationMode[];
 #endif
 
-#if !BUILDFLAG(IS_CHROMEOS_ASH) && !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_ANDROID)
 extern const char kPrintPreviewUseSystemDefaultPrinter[];
 extern const char kUserDataSnapshotRetentionLimit[];
 #endif
@@ -504,7 +504,7 @@
 
 extern const char kFullscreenAllowed[];
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 extern const char kMigratedToSiteNotificationChannels[];
 extern const char kClearedBlockedSiteNotificationChannels[];
 extern const char kUsageStatsEnabled[];
@@ -530,34 +530,34 @@
 extern const char kWebRtcLocalIpsAllowedUrls[];
 extern const char kWebRTCAllowLegacyTLSProtocols[];
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 extern const char kHasSeenWelcomePage[];
 extern const char kManagedAccountsSigninRestriction[];
 extern const char kManagedAccountsSigninRestrictionScopeMachine[];
 #endif
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 // Only used in branded builds.
 extern const char kNaviOnboardGroup[];
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 
 extern const char kQuietNotificationPermissionShouldShowPromo[];
 extern const char kQuietNotificationPermissionPromoWasShown[];
 extern const char kNotificationPermissionActions[];
 extern const char kHadThreeConsecutiveNotificationPermissionDenies[];
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 extern const char kManagedSerialAllowAllPortsForUrls[];
 extern const char kManagedSerialAllowUsbDevicesForUrls[];
-#endif  // !defined(OS_ANDROID)
+#endif  // !BUILDFLAG(IS_ANDROID)
 
 extern const char kProfileLastUsed[];
 extern const char kProfilesLastActive[];
 extern const char kProfilesNumCreated[];
 extern const char kProfileAttributes[];
-#if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
+#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
 extern const char kLegacyProfileNamesMigrated[];
-#endif  // !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
+#endif  // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
 extern const char kProfileCreatedByVersion[];
 extern const char kProfilesDeleted[];
 
@@ -586,11 +586,11 @@
 extern const char kDownloadExtensionsToOpenByPolicy[];
 extern const char kDownloadAllowedURLsForOpenByPolicy[];
 extern const char kDownloadDirUpgraded[];
-#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS) || \
-    defined(OS_MAC)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \
+    BUILDFLAG(IS_MAC)
 extern const char kOpenPdfDownloadInSystemReader[];
 #endif
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 extern const char kPromptForDownloadAndroid[];
 extern const char kDownloadLaterPromptStatus[];
 extern const char kShowMissingSdCardErrorAndroid[];
@@ -623,20 +623,20 @@
 extern const char kShutdownNumProcessesSlow[];
 
 extern const char kRestartLastSessionOnShutdown[];
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 #if !BUILDFLAG(IS_CHROMEOS_ASH)
 extern const char kCommandLineFlagSecurityWarningsEnabled[];
 #endif
 extern const char kPromotionalTabsEnabled[];
 extern const char kSuppressUnsupportedOSWarning[];
 extern const char kWasRestarted[];
-#endif  // !defined(OS_ANDROID)
+#endif  // !BUILDFLAG(IS_ANDROID)
 
 extern const char kDisableExtensions[];
 
 extern const char kNtpAppPageNames[];
 extern const char kNtpCollapsedForeignSessions[];
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 extern const char kNtpCollapsedRecentlyClosedTabs[];
 extern const char kNtpCollapsedSnapshotDocument[];
 extern const char kNtpCollapsedSyncPromo[];
@@ -647,10 +647,11 @@
 extern const char kNtpModulesOrder[];
 extern const char kNtpModulesVisible[];
 extern const char kNtpPromoBlocklist[];
+extern const char kNtpPromoVisible[];
 extern const char kNtpSearchSuggestionsBlocklist[];
 extern const char kNtpSearchSuggestionsImpressions[];
 extern const char kNtpSearchSuggestionsOptOut[];
-#endif  // defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_ANDROID)
 extern const char kNtpShownPage[];
 
 extern const char kDevToolsAdbKey[];
@@ -670,7 +671,7 @@
 extern const char kDevToolsDiscoverTCPTargetsEnabled[];
 extern const char kDevToolsTCPDiscoveryConfig[];
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 extern const char kDiceSigninUserMenuPromoCount[];
 #endif
 
@@ -693,8 +694,8 @@
 extern const char kWebAppsPreferences[];
 extern const char kWebAppsIsolationState[];
 
-#if defined(OS_WIN) || defined(OS_MAC) || \
-    (defined(OS_LINUX) && !BUILDFLAG(IS_CHROMEOS_LACROS))
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || \
+    (BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS_LACROS))
 extern const char kWebAppsUrlHandlerInfo[];
 #endif
 
@@ -710,10 +711,10 @@
 extern const char kDefaultVideoCaptureDevice[];
 extern const char kMediaDeviceIdSalt[];
 extern const char kMediaStorageIdSalt[];
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 extern const char kMediaCdmOriginData[];
 extern const char kNetworkServiceSandboxEnabled[];
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 
 extern const char kPrintPreviewStickySettings[];
 extern const char kCloudPrintRoot[];
@@ -833,13 +834,13 @@
 extern const char kAmbientAuthenticationInPrivateModesEnabled[];
 extern const char kBasicAuthOverHttpEnabled[];
 
-#if defined(OS_LINUX) || defined(OS_MAC) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_CHROMEOS)
 extern const char kAuthNegotiateDelegateByKdcPolicy[];
-#endif  // defined(OS_LINUX) || defined(OS_MAC) || defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_CHROMEOS)
 
-#if defined(OS_POSIX) || defined(OS_FUCHSIA)
+#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
 extern const char kNtlmV2Enabled[];
-#endif  // defined(OS_POSIX) || defined(OS_FUCHSIA)
+#endif  // BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 extern const char kKerberosEnabled[];
@@ -859,7 +860,7 @@
 extern const char kDnsOverHttpsTemplates[];
 extern const char kAdditionalDnsQueryTypesEnabled[];
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 extern const char kUserRemovedLoginItem[];
 extern const char kChromeCreatedLoginItem[];
 extern const char kMigratedLoginItemPref[];
@@ -885,35 +886,35 @@
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 extern const char kEnableMediaRouter[];
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 extern const char kShowCastIconInToolbar[];
-#endif  // !defined(OS_ANDROID)
+#endif  // !BUILDFLAG(IS_ANDROID)
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 extern const char kRelaunchNotification[];
 extern const char kRelaunchNotificationPeriod[];
 extern const char kRelaunchWindow[];
-#endif  // !defined(OS_ANDROID)
+#endif  // !BUILDFLAG(IS_ANDROID)
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 extern const char kRelaunchHeadsUpPeriod[];
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 extern const char kMacRestoreLocationPermissionsExperimentCount[];
-#endif  // defined(OS_MAC)
+#endif  // BUILDFLAG(IS_MAC)
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 extern const char kEnrollmentIdUploadedOnChromad[];
 extern const char kLastChromadMigrationAttemptTime[];
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 extern const char kAttemptedToEnableAutoupdate[];
 
 extern const char kMediaGalleriesUniqueId[];
 extern const char kMediaGalleriesRememberedGalleries[];
-#endif  // !defined(OS_ANDROID)
+#endif  // !BUILDFLAG(IS_ANDROID)
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 extern const char kPolicyPinnedLauncherApps[];
@@ -921,7 +922,7 @@
 extern const char kShelfDefaultPinLayoutRollsForTabletFormFactor[];
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 extern const char kNetworkProfileWarningsLeft[];
 extern const char kNetworkProfileLastWarningTime[];
 extern const char kShortcutMigrationVersion[];
@@ -941,9 +942,9 @@
 
 extern const char kWatchdogExtensionActive[];
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 extern const char kPartnerBookmarkMappings[];
-#endif  // defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_ANDROID)
 
 extern const char kQuickCheckEnabled[];
 extern const char kBrowserGuestModeEnabled[];
@@ -955,9 +956,9 @@
 extern const char kBrowserShowProfilePickerOnStartup[];
 extern const char kSigninAllowedOnNextStartup[];
 extern const char kSigninInterceptionEnabled[];
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 extern const char kLacrosSecondaryProfilesAllowed[];
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
 extern const char kCryptAuthDeviceId[];
 extern const char kCryptAuthInstanceId[];
@@ -968,7 +969,7 @@
 
 extern const char kRecoveryComponentNeedsElevation[];
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 extern const char kCloudExtensionRequestEnabled[];
 extern const char kCloudExtensionRequestIds[];
 #endif
@@ -987,12 +988,12 @@
 
 extern const char kAllowDinosaurEasterEgg[];
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 extern const char kClickedUpdateMenuItem[];
 extern const char kLatestVersionWhenClickedUpdateMenuItem[];
 #endif
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 extern const char kCommerceMerchantViewerMessagesShownTime[];
 #endif
 
@@ -1003,25 +1004,25 @@
 
 extern const char kWebShareVisitedTargets[];
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 // Only used in branded builds.
 extern const char kIncompatibleApplications[];
 extern const char kModuleBlocklistCacheMD5Digest[];
 extern const char kThirdPartyBlockingEnabled[];
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 
 // Windows mitigation policies.
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 extern const char kRendererCodeIntegrityEnabled[];
 extern const char kBlockBrowserLegacyExtensionPoints[];
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 
 extern const char kSettingsResetPromptPromptWave[];
 extern const char kSettingsResetPromptLastTriggeredForDefaultSearch[];
 extern const char kSettingsResetPromptLastTriggeredForStartupUrls[];
 extern const char kSettingsResetPromptLastTriggeredForHomepage[];
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 extern const char kClipboardLastModifiedTime[];
 #endif
 
@@ -1061,7 +1062,7 @@
 
 extern const char kDisplayCapturePermissionsPolicyEnabled[];
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 extern const char kSharedArrayBufferUnrestrictedAccessAllowed[];
 extern const char kAutoplayAllowed[];
 extern const char kAutoplayAllowlist[];
@@ -1069,7 +1070,7 @@
 #endif
 extern const char kSandboxExternalProtocolBlocked[];
 
-#if defined(OS_LINUX)
+#if BUILDFLAG(IS_LINUX)
 extern const char kAllowNativeNotifications[];
 extern const char kAllowSystemNotifications[];
 #endif
@@ -1085,11 +1086,11 @@
 
 extern const char kAllowSyncXHRInPageDismissal[];
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 extern const char kUsageStatsEnabled[];
 #endif
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 extern const char kClientCertificateManagementAllowed[];
 extern const char kCACertificateManagementAllowed[];
 #endif
@@ -1102,9 +1103,9 @@
 extern const char kSharingFCMRegistration[];
 extern const char kSharingLocalSharingInfo[];
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 extern const char kHatsSurveyMetadata[];
-#endif  // !defined(OS_ANDROID)
+#endif  // !BUILDFLAG(IS_ANDROID)
 
 extern const char kExternalProtocolDialogShowAlwaysOpenCheckbox[];
 
@@ -1112,7 +1113,7 @@
 
 extern const char kScrollToTextFragmentEnabled[];
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 extern const char kKnownInterceptionDisclosureInfobarLastShown[];
 #endif
 
@@ -1134,7 +1135,7 @@
 extern const char kAdbSideloadingPowerwashOnNextRebootNotificationShown[];
 #endif
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 extern const char kCaretBrowsingEnabled[];
 extern const char kShowCaretBrowsingDialog[];
 #endif
@@ -1150,7 +1151,7 @@
 extern const char kSecurityTokenSessionNotificationScheduledDomain[];
 #endif
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 extern const char kCartModuleHidden[];
 extern const char kCartModuleWelcomeSurfaceShownTimes[];
 extern const char kCartDiscountAcknowledged[];
@@ -1159,11 +1160,11 @@
 extern const char kCartDiscountLastFetchedTime[];
 #endif
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 extern const char kWebXRImmersiveArEnabled[];
 #endif
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 extern const char kFetchKeepaliveDurationOnShutdown[];
 #endif
 
@@ -1177,19 +1178,19 @@
 
 extern const char kExplicitlyAllowedNetworkPorts[];
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 extern const char kDeviceAttributesAllowedForOrigins[];
 #endif
 
-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
+#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS)
 extern const char kDesktopSharingHubEnabled[];
 #endif
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 extern const char kLastWhatsNewVersion[];
 #endif
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 extern const char kLensRegionSearchEnabled[];
 #endif
 
diff --git a/chrome/common/printing/printer_capabilities.cc b/chrome/common/printing/printer_capabilities.cc
index c5c088f..5df02fd0 100644
--- a/chrome/common/printing/printer_capabilities.cc
+++ b/chrome/common/printing/printer_capabilities.cc
@@ -27,25 +27,25 @@
 #include "printing/mojom/print.mojom.h"
 #include "printing/print_job_constants.h"
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "components/strings/grit/components_strings.h"
 #include "ui/base/l10n/l10n_util.h"
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 #include "chrome/common/printing/ipp_l10n.h"
 #include "components/strings/grit/components_strings.h"
 #include "ui/base/l10n/l10n_util.h"
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
 #if BUILDFLAG(PRINT_MEDIA_L10N_ENABLED)
 #include "chrome/common/printing/print_media_l10n.h"
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #include "printing/printing_features.h"
-#endif  // defined(OS_MAC)
+#endif  // BUILDFLAG(IS_MAC)
 #endif  // BUILDFLAG(PRINT_MEDIA_L10N_ENABLED)
 
 namespace printing {
@@ -75,7 +75,7 @@
 }
 #endif  // BUILDFLAG(PRINT_MEDIA_L10N_ENABLED)
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 void PopulateAdvancedCapsLocalization(
     std::vector<AdvancedCapability>* advanced_capabilities) {
   auto& l10n_map = CapabilityLocalizationMap();
@@ -91,7 +91,7 @@
     }
   }
 }
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
 // Returns a dictionary representing printer capabilities as CDD, or
 // a Value of type NONE if no capabilities are provided.
@@ -106,7 +106,7 @@
 
 #if BUILDFLAG(PRINT_MEDIA_L10N_ENABLED)
   bool populate_paper_display_names = true;
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   // Paper display name localization requires standardized vendor ID names
   // populated by CUPS IPP. If the CUPS IPP backend is not enabled, localization
   // will not properly occur.
@@ -119,19 +119,19 @@
 
   caps->user_defined_papers = std::move(user_defined_papers);
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   if (!has_secure_protocol)
     caps->pin_supported = false;
 
   PopulateAdvancedCapsLocalization(&caps->advanced_capabilities);
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
   return cloud_print::PrinterSemanticCapsAndDefaultsToCdd(*caps);
 }
 
 }  // namespace
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 std::string GetUserFriendlyName(const std::string& printer_name) {
   // `printer_name` may be a UNC path like \\printserver\printername.
   if (!base::StartsWith(printer_name, "\\\\",
@@ -167,12 +167,12 @@
 
   base::Value options(base::Value::Type::DICTIONARY);
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
   printer_info.SetKey(
       kCUPSEnterprisePrinter,
       base::Value(base::Contains(basic_info.options, kCUPSEnterprisePrinter) &&
                   basic_info.options.at(kCUPSEnterprisePrinter) == kValueTrue));
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
   printer_info.SetKey(kSettingPrinterOptions, std::move(options));
 
diff --git a/chrome/common/printing/printer_capabilities.h b/chrome/common/printing/printer_capabilities.h
index 37bf466f2..820965a 100644
--- a/chrome/common/printing/printer_capabilities.h
+++ b/chrome/common/printing/printer_capabilities.h
@@ -19,7 +19,7 @@
 
 extern const char kPrinter[];
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 std::string GetUserFriendlyName(const std::string& printer_name);
 #endif
 
diff --git a/chrome/common/profiler/thread_profiler.cc b/chrome/common/profiler/thread_profiler.cc
index e5a2d82..d9934fc0 100644
--- a/chrome/common/profiler/thread_profiler.cc
+++ b/chrome/common/profiler/thread_profiler.cc
@@ -30,7 +30,7 @@
 #include "content/public/common/content_switches.h"
 #include "sandbox/policy/sandbox.h"
 
-#if defined(OS_ANDROID) && BUILDFLAG(ENABLE_ARM_CFI_TABLE)
+#if BUILDFLAG(IS_ANDROID) && BUILDFLAG(ENABLE_ARM_CFI_TABLE)
 #include "base/android/apk_assets.h"
 #include "base/files/memory_mapped_file.h"
 #include "base/profiler/arm_cfi_table.h"
@@ -42,7 +42,7 @@
 // shared library.
 extern char __executable_start;
 }
-#endif  // defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_ANDROID) && BUILDFLAG(ENABLE_ARM_CFI_TABLE)
 
 using CallStackProfileBuilder = metrics::CallStackProfileBuilder;
 using CallStackProfileParams = metrics::CallStackProfileParams;
@@ -59,7 +59,7 @@
 constexpr double kFractionOfExecutionTimeToSample = 0.02;
 
 bool IsCurrentProcessBackgrounded() {
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   // Port provider that returns the calling process's task port, ignoring its
   // argument.
   class SelfPortProvider : public base::PortProvider {
@@ -69,12 +69,12 @@
   };
   SelfPortProvider provider;
   return base::Process::Current().IsProcessBackgrounded(&provider);
-#else   // defined(OS_MAC)
+#else   // BUILDFLAG(IS_MAC)
   return base::Process::Current().IsProcessBackgrounded();
-#endif  // defined(OS_MAC)
+#endif  // BUILDFLAG(IS_MAC)
 }
 
-#if defined(OS_ANDROID) && BUILDFLAG(ENABLE_ARM_CFI_TABLE)
+#if BUILDFLAG(IS_ANDROID) && BUILDFLAG(ENABLE_ARM_CFI_TABLE)
 // Encapsulates the setup required to create the Chrome unwinder on Android.
 class ChromeUnwinderCreator {
  public:
@@ -141,10 +141,10 @@
   unwinders.push_back(chrome_unwinder_creator->Create());
   return unwinders;
 }
-#endif  // defined(OS_ANDROID) && BUILDFLAG(ENABLE_ARM_CFI_TABLE)
+#endif  // BUILDFLAG(IS_ANDROID) && BUILDFLAG(ENABLE_ARM_CFI_TABLE)
 
 base::StackSamplingProfiler::UnwindersFactory CreateCoreUnwindersFactory() {
-#if defined(OS_ANDROID) && BUILDFLAG(ENABLE_ARM_CFI_TABLE)
+#if BUILDFLAG(IS_ANDROID) && BUILDFLAG(ENABLE_ARM_CFI_TABLE)
   // The module is loadable if the profiler is enabled for the current
   // process.
   CHECK(
diff --git a/chrome/common/profiler/thread_profiler_browsertest.cc b/chrome/common/profiler/thread_profiler_browsertest.cc
index a2859861..3c42126 100644
--- a/chrome/common/profiler/thread_profiler_browsertest.cc
+++ b/chrome/common/profiler/thread_profiler_browsertest.cc
@@ -20,13 +20,13 @@
 #include "content/public/test/browser_test.h"
 #include "third_party/metrics_proto/sampled_profile.pb.h"
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 #include "chrome/test/base/android/android_browser_test.h"
 #else
 #include "chrome/test/base/in_process_browser_test.h"
 #endif
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #include "base/mac/mac_util.h"
 #endif
 
@@ -126,7 +126,7 @@
 };
 
 bool ShouldSkipTestForMacOS11() {
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   // Sampling profiler does not work and is disabled on macOS 11.
   // See https://crbug.com/1101399 and https://crbug.com/1098119.
   // DCHECK that that remains the case so these tests are re-enabled when the
@@ -231,7 +231,7 @@
 }
 
 // Android doesn't have a network service process.
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 #define MAYBE_NetworkServiceProcessIOThread \
   DISABLED_NetworkServiceProcessIOThread
 #else
diff --git a/chrome/common/profiler/thread_profiler_platform_configuration.cc b/chrome/common/profiler/thread_profiler_platform_configuration.cc
index 29e31273..704b9bd8 100644
--- a/chrome/common/profiler/thread_profiler_platform_configuration.cc
+++ b/chrome/common/profiler/thread_profiler_platform_configuration.cc
@@ -10,7 +10,7 @@
 #include "build/build_config.h"
 #include "chrome/common/profiler/process_type.h"
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 #include "chrome/android/modules/stack_unwinder/public/module.h"
 #endif
 
@@ -112,7 +112,7 @@
          *release_channel == version_info::Channel::DEV;
 }
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 // The configuration to use for the Android platform. Applies to ARM32 which is
 // the only Android architecture currently supported by StackSamplingProfiler.
 // Defined in terms of DefaultPlatformConfiguration where Android does not
@@ -236,14 +236,14 @@
   // TODO(https://crbug.com/1004855): Enable across all browser tests.
   return browser_test_mode_enabled();
 }
-#endif  // defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_ANDROID)
 
 }  // namespace
 
 // static
 std::unique_ptr<ThreadProfilerPlatformConfiguration>
 ThreadProfilerPlatformConfiguration::Create(bool browser_test_mode_enabled) {
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   using PlatformConfiguration = AndroidPlatformConfiguration;
 #else
   using PlatformConfiguration = DefaultPlatformConfiguration;
diff --git a/chrome/common/profiler/thread_profiler_platform_configuration_unittest.cc b/chrome/common/profiler/thread_profiler_platform_configuration_unittest.cc
index 442eb89..df7abdf 100644
--- a/chrome/common/profiler/thread_profiler_platform_configuration_unittest.cc
+++ b/chrome/common/profiler/thread_profiler_platform_configuration_unittest.cc
@@ -12,13 +12,13 @@
 #include "components/version_info/version_info.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #include "base/mac/mac_util.h"
 #endif
 
-#if (defined(OS_WIN) && defined(ARCH_CPU_X86_64)) || \
-    (defined(OS_MAC) && defined(ARCH_CPU_X86_64)) || \
-    (defined(OS_ANDROID) && BUILDFLAG(ENABLE_ARM_CFI_TABLE))
+#if (BUILDFLAG(IS_WIN) && defined(ARCH_CPU_X86_64)) || \
+    (BUILDFLAG(IS_MAC) && defined(ARCH_CPU_X86_64)) || \
+    (BUILDFLAG(IS_ANDROID) && BUILDFLAG(ENABLE_ARM_CFI_TABLE))
 #define THREAD_PROFILER_SUPPORTED_ON_PLATFORM true
 #else
 #define THREAD_PROFILER_SUPPORTED_ON_PLATFORM false
@@ -74,7 +74,7 @@
   EXPECT_FALSE(config()->IsSupported(version_info::Channel::STABLE));
 
   EXPECT_FALSE(config()->IsSupported(absl::nullopt));
-#elif defined(OS_ANDROID)
+#elif BUILDFLAG(IS_ANDROID)
   EXPECT_FALSE(config()->IsSupported(version_info::Channel::UNKNOWN));
   EXPECT_TRUE(config()->IsSupported(version_info::Channel::CANARY));
   EXPECT_FALSE(config()->IsSupported(version_info::Channel::DEV));
@@ -83,7 +83,7 @@
 
   EXPECT_FALSE(config()->IsSupported(absl::nullopt));
 #else
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   // Sampling profiler does not work on macOS 11.0 yet:
   // https://crbug.com/1101399
   const bool on_canary = base::mac::IsAtMostOS10_15();
@@ -108,7 +108,7 @@
                              GetRuntimeModuleState) {
   using RuntimeModuleState =
       ThreadProfilerPlatformConfiguration::RuntimeModuleState;
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   EXPECT_EQ(RuntimeModuleState::kModuleNotAvailable,
             config()->GetRuntimeModuleState(version_info::Channel::UNKNOWN));
   EXPECT_EQ(RuntimeModuleState::kModuleAbsentButAvailable,
@@ -143,7 +143,7 @@
                              GetEnableRates) {
   using RelativePopulations =
       ThreadProfilerPlatformConfiguration::RelativePopulations;
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   EXPECT_EQ((RelativePopulations{0, 50}),
             config()->GetEnableRates(version_info::Channel::CANARY));
   // Note: death tests aren't supported on Android. Otherwise this test would
@@ -164,7 +164,7 @@
 
 MAYBE_PLATFORM_CONFIG_TEST_F(ThreadProfilerPlatformConfigurationTest,
                              GetChildProcessEnableFraction) {
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   EXPECT_EQ(0.0, config()->GetChildProcessEnableFraction(
                      metrics::CallStackProfileParams::Process::kGpu));
   EXPECT_EQ(0.4, config()->GetChildProcessEnableFraction(
@@ -193,7 +193,7 @@
 
 MAYBE_PLATFORM_CONFIG_TEST_F(ThreadProfilerPlatformConfigurationTest,
                              IsEnabledForThread) {
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   EXPECT_FALSE(config()->IsEnabledForThread(
       metrics::CallStackProfileParams::Process::kBrowser,
       metrics::CallStackProfileParams::Thread::kMain));
diff --git a/chrome/common/safe_browsing/archive_analyzer_results.cc b/chrome/common/safe_browsing/archive_analyzer_results.cc
index bbede8b..abd2ae9 100644
--- a/chrome/common/safe_browsing/archive_analyzer_results.cc
+++ b/chrome/common/safe_browsing/archive_analyzer_results.cc
@@ -21,13 +21,13 @@
 #include "crypto/secure_hash.h"
 #include "crypto/sha2.h"
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 #include <mach-o/fat.h>
 #include <mach-o/loader.h>
 #include "base/containers/span.h"
 #include "chrome/common/safe_browsing/disk_image_type_sniffer_mac.h"
 #include "chrome/common/safe_browsing/mach_o_image_reader_mac.h"
-#endif  // OS_MAC
+#endif  // BUILDFLAG(IS_MAC)
 
 namespace safe_browsing {
 
@@ -109,7 +109,7 @@
       new BinaryFeatureExtractor());
   bool current_entry_is_executable;
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   uint32_t magic;
   file->Read(0, reinterpret_cast<char*>(&magic), sizeof(uint32_t));
 
@@ -142,7 +142,7 @@
 #else
   current_entry_is_executable =
       FileTypePolicies::GetInstance()->IsCheckedBinaryFile(path);
-#endif  // OS_MAC
+#endif  // BUILDFLAG(IS_MAC)
 
   if (FileTypePolicies::GetInstance()->IsArchiveFile(path)) {
     DVLOG(2) << "Downloaded a zipped archive: " << path.value();
@@ -156,14 +156,14 @@
     SetLengthAndDigestForContainedFile(path, file, file_length,
                                        archived_archive);
   } else {
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
     // This check prevents running analysis on .app files since they are
     // really just directories and will cause binary feature extraction
     // to fail.
     if (path.Extension().compare(".app") == 0) {
       DVLOG(2) << "Downloaded a zipped .app directory: " << path.value();
     } else {
-#endif  // OS_MAC
+#endif  // BUILDFLAG(IS_MAC)
       DVLOG(2) << "Downloaded a zipped executable: " << path.value();
       results->has_executable |= current_entry_is_executable;
       ClientDownloadRequest::ArchivedBinary* archived_binary =
@@ -177,9 +177,9 @@
       if (current_entry_is_executable) {
         AnalyzeContainedBinary(binary_feature_extractor, file, archived_binary);
       }
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
     }
-#endif  // OS_MAC
+#endif  // BUILDFLAG(IS_MAC)
   }
 }
 
diff --git a/chrome/common/safe_browsing/archive_analyzer_results.h b/chrome/common/safe_browsing/archive_analyzer_results.h
index ddd69f7..6fa66b81 100644
--- a/chrome/common/safe_browsing/archive_analyzer_results.h
+++ b/chrome/common/safe_browsing/archive_analyzer_results.h
@@ -27,12 +27,12 @@
   google::protobuf::RepeatedPtrField<ClientDownloadRequest_ArchivedBinary>
       archived_binary;
   std::vector<base::FilePath> archived_archive_filenames;
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   std::vector<uint8_t> signature_blob;
   google::protobuf::RepeatedPtrField<
       ClientDownloadRequest_DetachedCodeSignature>
       detached_code_signatures;
-#endif  // OS_MAC
+#endif  // BUILDFLAG(IS_MAC)
   int file_count;
   int directory_count;
   ArchiveAnalyzerResults();
diff --git a/chrome/common/safe_browsing/binary_feature_extractor_posix.cc b/chrome/common/safe_browsing/binary_feature_extractor_posix.cc
index 31e9f47..5ab5b50 100644
--- a/chrome/common/safe_browsing/binary_feature_extractor_posix.cc
+++ b/chrome/common/safe_browsing/binary_feature_extractor_posix.cc
@@ -17,7 +17,7 @@
     const base::FilePath& file_path,
     ClientDownloadRequest_SignatureInfo* signature_info) {}
 
-#if !defined(OS_MAC)
+#if !BUILDFLAG(IS_MAC)
 bool BinaryFeatureExtractor::ExtractImageFeaturesFromData(
     const uint8_t* data, size_t data_size,
     ExtractHeadersOption options,
diff --git a/chrome/common/url_constants.cc b/chrome/common/url_constants.cc
index 1e305b5..ecc7f55 100644
--- a/chrome/common/url_constants.cc
+++ b/chrome/common/url_constants.cc
@@ -5,9 +5,9 @@
 #include "chrome/common/url_constants.h"
 
 #include "build/branding_buildflags.h"
-#include "chrome/common/webui_url_constants.h"
-
+#include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
+#include "chrome/common/webui_url_constants.h"
 
 namespace chrome {
 
@@ -103,11 +103,11 @@
 const char kCloudPrintCertificateErrorLearnMoreURL[] =
 #if BUILDFLAG(IS_CHROMEOS_ASH)
     "https://support.google.com/chromebook?p=cloudprint_error_troubleshoot";
-#elif defined(OS_MAC)
+#elif BUILDFLAG(IS_MAC)
     "https://support.google.com/cloudprint?p=cloudprint_error_offline_mac";
-#elif defined(OS_WIN)
-        "https://support.google.com/"
-        "cloudprint?p=cloudprint_error_offline_windows";
+#elif BUILDFLAG(IS_WIN)
+    "https://support.google.com/"
+    "cloudprint?p=cloudprint_error_offline_windows";
 #else
         "https://support.google.com/"
         "cloudprint?p=cloudprint_error_offline_linux";
@@ -286,7 +286,7 @@
 const char kSyncLearnMoreURL[] =
     "https://support.google.com/chrome/?p=settings_sign_in";
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 const char kSyncTrustedVaultOptInURL[] =
     "https://passwords.google.com/encryption/enroll?"
     "utm_source=chrome&utm_medium=desktop&utm_campaign=encryption_enroll";
@@ -305,12 +305,12 @@
 const char kCwsEnhancedSafeBrowsingLearnMoreURL[] =
     "https://support.google.com/chrome?p=cws_enhanced_safe_browsing";
 
-#if BUILDFLAG(IS_CHROMEOS_ASH) || defined(OS_ANDROID)
+#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_ANDROID)
 const char kEnhancedPlaybackNotificationLearnMoreURL[] =
 #endif
 #if BUILDFLAG(IS_CHROMEOS_ASH)
     "https://support.google.com/chromebook/?p=enhanced_playback";
-#elif defined(OS_ANDROID)
+#elif BUILDFLAG(IS_ANDROID)
 // Keep in sync with chrome/browser/ui/android/strings/android_chrome_strings.grd
     "https://support.google.com/chrome/?p=mobile_protected_content";
 #endif
@@ -458,7 +458,7 @@
 
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 const char kChromeEnterpriseSignInLearnMoreURL[] =
     "https://support.google.com/chromebook/answer/1331549";
 
@@ -466,7 +466,7 @@
     "https://support.google.com/chrome/?p=unsupported_mac";
 #endif
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 const char kChromeCleanerLearnMoreURL[] =
     "https://support.google.com/chrome/?p=chrome_cleanup_tool";
 
diff --git a/chrome/common/url_constants.h b/chrome/common/url_constants.h
index 6b4df77..4c58afe 100644
--- a/chrome/common/url_constants.h
+++ b/chrome/common/url_constants.h
@@ -251,7 +251,7 @@
 // The URL for the "Learn more" page for sync setup on the personal stuff page.
 extern const char kSyncLearnMoreURL[];
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 // The URL for the trusted vault sync passphrase opt in.
 extern const char kSyncTrustedVaultOptInURL[];
 #endif
@@ -270,7 +270,7 @@
 // The URL for the "Learn more" link about CWS Enhanced Safe Browsing.
 extern const char kCwsEnhancedSafeBrowsingLearnMoreURL[];
 
-#if defined(OS_ANDROID) || BUILDFLAG(IS_CHROMEOS_ASH)
+#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS_ASH)
 // "Learn more" URL for the enhanced playback notification dialog.
 extern const char kEnhancedPlaybackNotificationLearnMoreURL[];
 #endif
@@ -421,7 +421,7 @@
 extern const char kFingerprintLearnMoreURL[];
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 // "Learn more" URL for the enterprise sign-in confirmation dialog.
 extern const char kChromeEnterpriseSignInLearnMoreURL[];
 
@@ -429,7 +429,7 @@
 extern const char kMac10_10_ObsoleteURL[];
 #endif
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 // The URL for the Learn More link in the Chrome Cleanup settings card.
 extern const char kChromeCleanerLearnMoreURL[];
 
diff --git a/chrome/common/webui_url_constants.cc b/chrome/common/webui_url_constants.cc
index 3ad355f3..90ced52 100644
--- a/chrome/common/webui_url_constants.cc
+++ b/chrome/common/webui_url_constants.cc
@@ -6,6 +6,7 @@
 
 #include "base/cxx17_backports.h"
 #include "base/strings/string_piece.h"
+#include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "components/nacl/common/buildflags.h"
 #include "components/safe_browsing/core/common/web_ui_constants.h"
@@ -139,7 +140,7 @@
 const char kChromeUINewTabURL[] = "chrome://newtab/";
 const char kChromeUIOmniboxHost[] = "omnibox";
 const char kChromeUIOmniboxURL[] = "chrome://omnibox/";
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 const char kChromeUIAppDisabledURL[] = "chrome://app-disabled";
 const char kChromeUIOsFlagsAppURL[] = "chrome://flags/";
 const char kChromeUIOsUrlAppURL[] = "chrome://internal/";
@@ -211,12 +212,12 @@
 const char kChromeUIWhatsNewHost[] = "whats-new";
 const char kChromeUIWhatsNewURL[] = "chrome://whats-new/";
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 // TODO(crbug.com/1003960): Remove when issue is resolved.
 const char kChromeUIWelcomeWin10Host[] = "welcome-win10";
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 const char kChromeUIExploreSitesInternalsHost[] = "explore-sites-internals";
 const char kChromeUIJavaCrashURL[] = "chrome://java-crash/";
 const char kChromeUINativeBookmarksURL[] = "chrome-native://bookmarks/";
@@ -242,7 +243,7 @@
 const char kCfmNetworkSettingsURL[] = "chrome://cfm-network-settings";
 #endif  // BUILDFLAG(PLATFORM_CFM)
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 const char kChromeUIGpuURL[] = "chrome://gpu";
 const char kChromeUIHistogramsURL[] = "chrome://histograms";
 #endif
@@ -427,40 +428,40 @@
 const char kOsUIVersionURL[] = "os://version";
 #endif
 
-#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
 const char kChromeUIWebUIJsErrorHost[] = "webuijserror";
 const char kChromeUIWebUIJsErrorURL[] = "chrome://webuijserror/";
 #endif
 
-#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) || \
-    defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \
+    BUILDFLAG(IS_CHROMEOS)
 const char kChromeUIConnectorsInternalsHost[] = "connectors-internals";
 #endif
 
-#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) || \
-    defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \
+    BUILDFLAG(IS_CHROMEOS)
 const char kChromeUIDiscardsHost[] = "discards";
 const char kChromeUIDiscardsURL[] = "chrome://discards/";
 #endif
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 const char kChromeUINearbyShareHost[] = "nearby";
 const char kChromeUINearbyShareURL[] = "chrome://nearby/";
-#endif  // !defined(OS_ANDROID)
+#endif  // !BUILDFLAG(IS_ANDROID)
 
-#if defined(OS_POSIX) && !defined(OS_MAC) && !defined(OS_ANDROID)
+#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC) && !BUILDFLAG(IS_ANDROID)
 const char kChromeUILinuxProxyConfigHost[] = "linux-proxy-config";
 #endif
 
-#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS) || \
-    defined(OS_ANDROID)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \
+    BUILDFLAG(IS_ANDROID)
 const char kChromeUISandboxHost[] = "sandbox";
 #endif
 
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
-#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_FUCHSIA) || \
-    (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_FUCHSIA) || \
+    (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
 const char kChromeUIBrowserSwitchHost[] = "browser-switch";
 const char kChromeUIBrowserSwitchURL[] = "chrome://browser-switch/";
 const char kChromeUIEnterpriseProfileWelcomeHost[] =
@@ -475,7 +476,8 @@
 const char kChromeUIProfilePickerStartupQuery[] = "startup";
 #endif
 
-#if ((defined(OS_LINUX) || defined(OS_CHROMEOS)) && defined(TOOLKIT_VIEWS)) || \
+#if ((BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)) && \
+     defined(TOOLKIT_VIEWS)) ||                         \
     defined(USE_AURA)
 const char kChromeUITabModalConfirmDialogHost[] = "tab-modal-confirm-dialog";
 #endif
@@ -489,7 +491,7 @@
 const char kChromeUITabStripURL[] = "chrome://tab-strip.top-chrome";
 #endif
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 const char kChromeUICommanderHost[] = "commander";
 const char kChromeUICommanderURL[] = "chrome://commander";
 const char kChromeUIDownloadShelfHost[] = "download-shelf.top-chrome";
@@ -540,15 +542,15 @@
 const char kManageProfileSubPage[] = "manageProfile";
 const char kPeopleSubPage[] = "people";
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 const char kPrivacySandboxSubPagePath[] = "/privacySandbox";
 #endif
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 const char kCleanupSubPage[] = "cleanup";
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 
-#if !defined(OS_ANDROID) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if !BUILDFLAG(IS_ANDROID) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 const char kChromeUICastFeedbackHost[] = "cast-feedback";
 #endif
 
@@ -560,7 +562,7 @@
 const char* const kChromeHostURLs[] = {
     kChromeUIAboutHost,
     kChromeUIAccessibilityHost,
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
     kChromeUIAppServiceInternalsHost,
 #endif
     kChromeUIAutofillInternalsHost,
@@ -584,7 +586,7 @@
     kChromeUIInterstitialHost,
     kChromeUIInvalidationsHost,
     kChromeUILocalStateHost,
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
     kChromeUIManagementHost,
 #endif
     kChromeUIMediaEngagementHost,
@@ -604,14 +606,14 @@
     kChromeUINTPTilesInternalsHost,
     safe_browsing::kChromeUISafeBrowsingHost,
     kChromeUISyncInternalsHost,
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
     kChromeUITermsHost,
 #endif
     kChromeUITranslateInternalsHost,
     kChromeUIUsbInternalsHost,
     kChromeUIUserActionsHost,
     kChromeUIVersionHost,
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
     kChromeUIWebAppInternalsHost,
 #endif
     content::kChromeUIAttributionInternalsHost,
@@ -624,12 +626,12 @@
     content::kChromeUINetworkErrorsListingHost,
     content::kChromeUIProcessInternalsHost,
     content::kChromeUIServiceWorkerInternalsHost,
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
     content::kChromeUITracingHost,
 #endif
     content::kChromeUIUkmHost,
     content::kChromeUIWebRTCInternalsHost,
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 #if !BUILDFLAG(IS_CHROMEOS_ASH)
     kChromeUIAppLauncherPageHost,
 #endif
@@ -643,7 +645,7 @@
     kChromeUISystemInfoHost,
     kChromeUIWhatsNewHost,
 #endif
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
     kChromeUIExploreSitesInternalsHost,
     kChromeUIOfflineInternalsHost,
     kChromeUISnippetsInternalsHost,
@@ -665,22 +667,22 @@
     kChromeUIInternetDetailDialogHost,
     kChromeUIAssistantOptInHost,
 #endif
-#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) || \
-    defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \
+    BUILDFLAG(IS_CHROMEOS)
     kChromeUIConnectorsInternalsHost,
 #endif
-#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) || \
-    defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \
+    BUILDFLAG(IS_CHROMEOS)
     kChromeUIDiscardsHost,
 #endif
-#if defined(OS_POSIX) && !defined(OS_MAC) && !defined(OS_ANDROID)
+#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC) && !BUILDFLAG(IS_ANDROID)
     kChromeUILinuxProxyConfigHost,
 #endif
-#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS) || \
-    defined(OS_ANDROID)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \
+    BUILDFLAG(IS_ANDROID)
     kChromeUISandboxHost,
 #endif
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
     kChromeUIConflictsHost,
 #endif
 #if BUILDFLAG(ENABLE_NACL)
@@ -702,9 +704,9 @@
 // Add chrome://internals/* subpages here to be included in chrome://chrome-urls
 // (about:about).
 const char* const kChromeInternalsPathURLs[] = {
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
     kChromeUIInternalsQueryTilesPath,
-#endif  // defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_ANDROID)
 #if BUILDFLAG(ENABLE_SESSION_SERVICE)
     kChromeUISessionServiceInternalsPath,
 #endif
@@ -726,15 +728,15 @@
     blink::kChromeUIMemoryExhaustURL,
     blink::kChromeUIMemoryPressureCriticalURL,
     blink::kChromeUIMemoryPressureModerateURL,
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
     blink::kChromeUIBrowserHeapCorruptionURL,
     blink::kChromeUIHeapCorruptionCrashURL,
 #endif
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
     blink::kChromeUIGpuJavaCrashURL,
     kChromeUIJavaCrashURL,
 #endif
-#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
     kChromeUIWebUIJsErrorURL,
 #endif
     kChromeUIQuitURL,
diff --git a/chrome/common/webui_url_constants.h b/chrome/common/webui_url_constants.h
index 6a6c86fa..a85c6125 100644
--- a/chrome/common/webui_url_constants.h
+++ b/chrome/common/webui_url_constants.h
@@ -141,7 +141,7 @@
 extern const char kChromeUIOfflineInternalsHost[];
 extern const char kChromeUIOmniboxHost[];
 extern const char kChromeUIOmniboxURL[];
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 extern const char kChromeUIAppDisabledURL[];
 extern const char kChromeUIOsFlagsAppURL[];
 extern const char kChromeUIOsUrlAppURL[];
@@ -208,12 +208,12 @@
 extern const char kChromeUIWhatsNewHost[];
 extern const char kChromeUIWhatsNewURL[];
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 // TODO(crbug.com/1003960): Remove when issue is resolved.
 extern const char kChromeUIWelcomeWin10Host[];
-#endif  // defined(OS_WIN)
+#endif  // BUILDFLAG(IS_WIN)
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 extern const char kChromeUIExploreSitesInternalsHost[];
 extern const char kChromeUIJavaCrashURL[];
 extern const char kChromeUINativeBookmarksURL[];
@@ -230,9 +230,9 @@
 extern const char kChromeUIReadLaterHost[];
 extern const char kChromeUIReadLaterURL[];
 extern const char kChromeUIWebAppInternalsHost[];
-#endif  // defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_ANDROID)
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS)
 extern const char kChromeUIGpuURL[];
 extern const char kChromeUIHistogramsURL[];
 #endif
@@ -371,40 +371,40 @@
 extern const char kOsUIVersionURL[];
 #endif
 
-#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
 extern const char kChromeUIWebUIJsErrorHost[];
 extern const char kChromeUIWebUIJsErrorURL[];
 #endif
 
-#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) || \
-    defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \
+    BUILDFLAG(IS_CHROMEOS)
 extern const char kChromeUIConnectorsInternalsHost[];
 #endif
 
-#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) || \
-    defined(OS_CHROMEOS) || defined(OS_FUCHSIA)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \
+    BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_FUCHSIA)
 extern const char kChromeUIDiscardsHost[];
 extern const char kChromeUIDiscardsURL[];
 #endif
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 extern const char kChromeUINearbyShareHost[];
 extern const char kChromeUINearbyShareURL[];
-#endif  // !BUILDFLAG(IS_CHROMEOS_ASH)
+#endif
 
-#if defined(OS_POSIX) && !defined(OS_MAC) && !defined(OS_ANDROID)
+#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC) && !BUILDFLAG(IS_ANDROID)
 extern const char kChromeUILinuxProxyConfigHost[];
 #endif
 
-#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS) || \
-    defined(OS_ANDROID)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \
+    BUILDFLAG(IS_ANDROID)
 extern const char kChromeUISandboxHost[];
 #endif
 
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
-#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_FUCHSIA) || \
-    (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_FUCHSIA) || \
+    (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
 extern const char kChromeUIBrowserSwitchHost[];
 extern const char kChromeUIBrowserSwitchURL[];
 extern const char kChromeUIEnterpriseProfileWelcomeHost[];
@@ -416,7 +416,8 @@
 extern const char kChromeUIProfilePickerStartupQuery[];
 #endif
 
-#if ((defined(OS_LINUX) || defined(OS_CHROMEOS)) && defined(TOOLKIT_VIEWS)) || \
+#if ((BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)) && \
+     defined(TOOLKIT_VIEWS)) ||                         \
     defined(USE_AURA)
 extern const char kChromeUITabModalConfirmDialogHost[];
 #endif
@@ -430,7 +431,7 @@
 extern const char kChromeUITabStripURL[];
 #endif
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 extern const char kChromeUICommanderHost[];
 extern const char kChromeUICommanderURL[];
 extern const char kChromeUIDownloadShelfHost[];
@@ -480,15 +481,15 @@
 extern const char kSyncSetupSubPage[];
 extern const char kTriggeredResetProfileSettingsSubPage[];
 
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
 extern const char kPrivacySandboxSubPagePath[];
 #endif
 
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
 extern const char kCleanupSubPage[];
 #endif
 
-#if !defined(OS_ANDROID) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if !BUILDFLAG(IS_ANDROID) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 extern const char kChromeUICastFeedbackHost[];
 #endif
 
diff --git a/chrome/services/file_util/xz_file_extractor.cc b/chrome/services/file_util/xz_file_extractor.cc
index 175ccbc..9d0995d 100644
--- a/chrome/services/file_util/xz_file_extractor.cc
+++ b/chrome/services/file_util/xz_file_extractor.cc
@@ -13,7 +13,6 @@
 #include <utility>
 
 #include "base/bind.h"
-#include "base/compiler_specific.h"
 #include "third_party/lzma_sdk/7zCrc.h"
 #include "third_party/lzma_sdk/Xz.h"
 #include "third_party/lzma_sdk/XzCrc64.h"
@@ -145,12 +144,11 @@
 }  // namespace
 
 XzFileExtractor::XzFileExtractor() {
-  static const bool initialized = []() {
+  [[maybe_unused]] static const bool initialized = []() {
     CrcGenerateTable();
     Crc64GenerateTable();
     return true;
   }();
-  ANALYZER_ALLOW_UNUSED(initialized);
 }
 
 XzFileExtractor::~XzFileExtractor() = default;
diff --git a/chrome/services/sharing/nearby/platform/BUILD.gn b/chrome/services/sharing/nearby/platform/BUILD.gn
index 7912373..21b4e04 100644
--- a/chrome/services/sharing/nearby/platform/BUILD.gn
+++ b/chrome/services/sharing/nearby/platform/BUILD.gn
@@ -99,12 +99,6 @@
     "condition_variable_unittest.cc",
     "count_down_latch_unittest.cc",
     "crypto_unittest.cc",
-    "fake_tcp_connected_socket.cc",
-    "fake_tcp_connected_socket.h",
-    "fake_tcp_server_socket.cc",
-    "fake_tcp_server_socket.h",
-    "fake_tcp_socket_factory.cc",
-    "fake_tcp_socket_factory.h",
     "input_file_unittest.cc",
     "input_stream_impl_unittest.cc",
     "multi_thread_executor_unittest.cc",
@@ -122,6 +116,7 @@
   deps = [
     ":platform",
     "//ash/services/nearby/public/cpp:tcp_server_socket_port",
+    "//ash/services/nearby/public/cpp:test_support",
     "//ash/services/nearby/public/mojom",
     "//base/test:test_support",
     "//chrome/services/sharing/nearby/test_support",
diff --git a/chrome/services/sharing/nearby/platform/wifi_lan_medium_unittest.cc b/chrome/services/sharing/nearby/platform/wifi_lan_medium_unittest.cc
index e573f93..4feb322f 100644
--- a/chrome/services/sharing/nearby/platform/wifi_lan_medium_unittest.cc
+++ b/chrome/services/sharing/nearby/platform/wifi_lan_medium_unittest.cc
@@ -6,11 +6,13 @@
 
 #include <memory>
 
+#include "ash/services/nearby/public/cpp/fake_firewall_hole.h"
+#include "ash/services/nearby/public/cpp/fake_firewall_hole_factory.h"
+#include "ash/services/nearby/public/cpp/fake_tcp_socket_factory.h"
 #include "ash/services/nearby/public/cpp/tcp_server_socket_port.h"
 #include "ash/services/nearby/public/mojom/firewall_hole.mojom.h"
 #include "base/task/thread_pool.h"
 #include "base/test/task_environment.h"
-#include "chrome/services/sharing/nearby/platform/fake_tcp_socket_factory.h"
 #include "chrome/services/sharing/nearby/platform/wifi_lan_server_socket.h"
 #include "chromeos/login/login_state/login_state.h"
 #include "chromeos/network/managed_network_configuration_handler.h"
@@ -54,35 +56,6 @@
 const char kWifiServiceName[] = "wifi_service_name";
 const char kWifiServicePath[] = "/service/wifi0";
 
-class FakeFirewallHole : public sharing::mojom::FirewallHole {
- public:
-  FakeFirewallHole() = default;
-  ~FakeFirewallHole() override = default;
-};
-
-class FakeFirewallHoleFactory : public sharing::mojom::FirewallHoleFactory {
- public:
-  FakeFirewallHoleFactory() = default;
-  ~FakeFirewallHoleFactory() override = default;
-
-  // Immediately invokes |callback| with a fake firewall hole if
-  // |should_succeed_| is true and NullRemote if false.
-  void OpenFirewallHole(const ash::nearby::TcpServerSocketPort& port,
-                        OpenFirewallHoleCallback callback) override {
-    if (should_succeed_) {
-      mojo::PendingRemote<sharing::mojom::FirewallHole> firewall_hole;
-      mojo::MakeSelfOwnedReceiver(
-          std::make_unique<FakeFirewallHole>(),
-          firewall_hole.InitWithNewPipeAndPassReceiver());
-      std::move(callback).Run(std::move(firewall_hole));
-    } else {
-      std::move(callback).Run(/*firewall_hole=*/mojo::NullRemote());
-    }
-  }
-
-  bool should_succeed_ = true;
-};
-
 }  // namespace
 
 class WifiLanMediumTest : public ::testing::Test {
@@ -114,8 +87,9 @@
 
   void Initialize(WifiInitState state) {
     // Set up TCP socket factory mojo service.
-    auto fake_socket_factory = std::make_unique<FakeTcpSocketFactory>(
-        /*default_local_addr=*/kLocalAddress);
+    auto fake_socket_factory =
+        std::make_unique<ash::nearby::FakeTcpSocketFactory>(
+            /*default_local_addr=*/kLocalAddress);
     fake_socket_factory_ = fake_socket_factory.get();
     mojo::MakeSelfOwnedReceiver(
         std::move(fake_socket_factory),
@@ -150,7 +124,7 @@
 
     // Set up firewall hole factory mojo service.
     auto fake_firewall_hole_factory =
-        std::make_unique<FakeFirewallHoleFactory>();
+        std::make_unique<ash::nearby::FakeFirewallHoleFactory>();
     fake_firewall_hole_factory_ = fake_firewall_hole_factory.get();
     mojo::MakeSelfOwnedReceiver(
         std::move(fake_firewall_hole_factory),
@@ -330,7 +304,7 @@
   base::OnceClosure on_listen_calls_finished_;
 
   // TCP socket factory:
-  FakeTcpSocketFactory* fake_socket_factory_;
+  ash::nearby::FakeTcpSocketFactory* fake_socket_factory_;
   mojo::SharedRemote<sharing::mojom::TcpSocketFactory>
       socket_factory_shared_remote_;
 
@@ -349,7 +323,7 @@
       cros_network_config_;
 
   // Firewall hole factory:
-  FakeFirewallHoleFactory* fake_firewall_hole_factory_;
+  ash::nearby::FakeFirewallHoleFactory* fake_firewall_hole_factory_;
   mojo::SharedRemote<sharing::mojom::FirewallHoleFactory>
       firewall_hole_factory_shared_remote_;
 
diff --git a/chrome/services/sharing/nearby/platform/wifi_lan_server_socket_unittest.cc b/chrome/services/sharing/nearby/platform/wifi_lan_server_socket_unittest.cc
index ef339c7..1e75e4b 100644
--- a/chrome/services/sharing/nearby/platform/wifi_lan_server_socket_unittest.cc
+++ b/chrome/services/sharing/nearby/platform/wifi_lan_server_socket_unittest.cc
@@ -6,14 +6,15 @@
 
 #include <memory>
 
+#include "ash/services/nearby/public/cpp/fake_firewall_hole.h"
+#include "ash/services/nearby/public/cpp/fake_tcp_connected_socket.h"
+#include "ash/services/nearby/public/cpp/fake_tcp_server_socket.h"
 #include "ash/services/nearby/public/mojom/firewall_hole.mojom.h"
 #include "base/run_loop.h"
 #include "base/task/thread_pool.h"
 #include "base/test/bind.h"
 #include "base/test/task_environment.h"
 #include "base/threading/thread_restrictions.h"
-#include "chrome/services/sharing/nearby/platform/fake_tcp_connected_socket.h"
-#include "chrome/services/sharing/nearby/platform/fake_tcp_server_socket.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/self_owned_receiver.h"
 #include "mojo/public/cpp/system/data_pipe.h"
@@ -35,12 +36,6 @@
 
 const net::IPEndPoint kRemoteAddress(net::IPAddress(192, 168, 86, 62), 33333);
 
-class FakeFirewallHole : public sharing::mojom::FirewallHole {
- public:
-  FakeFirewallHole() = default;
-  ~FakeFirewallHole() override = default;
-};
-
 }  // namespace
 
 class WifiLanServerSocketTest : public testing::Test {
@@ -51,7 +46,8 @@
   WifiLanServerSocketTest& operator=(const WifiLanServerSocketTest&) = delete;
 
   void SetUp() override {
-    auto fake_tcp_server_socket = std::make_unique<FakeTcpServerSocket>();
+    auto fake_tcp_server_socket =
+        std::make_unique<ash::nearby::FakeTcpServerSocket>();
     fake_tcp_server_socket_ = fake_tcp_server_socket.get();
     mojo::PendingRemote<network::mojom::TCPServerSocket> tcp_server_socket;
     tcp_server_socket_self_owned_receiver_ref_ = mojo::MakeSelfOwnedReceiver(
@@ -60,7 +56,7 @@
 
     mojo::PendingRemote<sharing::mojom::FirewallHole> firewall_hole;
     firewall_hole_self_owned_receiver_ref_ = mojo::MakeSelfOwnedReceiver(
-        std::make_unique<FakeFirewallHole>(),
+        std::make_unique<ash::nearby::FakeFirewallHole>(),
         firewall_hole.InitWithNewPipeAndPassReceiver());
 
     wifi_lan_server_socket_ = std::make_unique<WifiLanServerSocket>(
@@ -115,7 +111,7 @@
   base::test::TaskEnvironment task_environment_;
   size_t num_running_accept_calls_ = 0;
   base::OnceClosure on_accept_calls_finished_;
-  FakeTcpServerSocket* fake_tcp_server_socket_;
+  ash::nearby::FakeTcpServerSocket* fake_tcp_server_socket_;
   mojo::SelfOwnedReceiverRef<network::mojom::TCPServerSocket>
       tcp_server_socket_self_owned_receiver_ref_;
   mojo::SelfOwnedReceiverRef<sharing::mojom::FirewallHole>
diff --git a/chrome/services/sharing/nearby/platform/wifi_lan_socket_unittest.cc b/chrome/services/sharing/nearby/platform/wifi_lan_socket_unittest.cc
index 19a94e8..486584d5 100644
--- a/chrome/services/sharing/nearby/platform/wifi_lan_socket_unittest.cc
+++ b/chrome/services/sharing/nearby/platform/wifi_lan_socket_unittest.cc
@@ -4,11 +4,11 @@
 
 #include "chrome/services/sharing/nearby/platform/wifi_lan_socket.h"
 
+#include "ash/services/nearby/public/cpp/fake_tcp_connected_socket.h"
 #include "base/run_loop.h"
 #include "base/task/thread_pool.h"
 #include "base/test/bind.h"
 #include "base/test/task_environment.h"
-#include "chrome/services/sharing/nearby/platform/fake_tcp_connected_socket.h"
 #include "mojo/public/cpp/bindings/self_owned_receiver.h"
 #include "mojo/public/cpp/system/data_pipe.h"
 #include "services/network/public/mojom/tcp_socket.mojom.h"
@@ -44,9 +44,10 @@
                                                    send_pipe_producer_handle,
                                                    send_pipe_consumer_handle));
 
-    auto fake_tcp_connected_socket = std::make_unique<FakeTcpConnectedSocket>(
-        std::move(receive_pipe_producer_handle),
-        std::move(send_pipe_consumer_handle));
+    auto fake_tcp_connected_socket =
+        std::make_unique<ash::nearby::FakeTcpConnectedSocket>(
+            std::move(receive_pipe_producer_handle),
+            std::move(send_pipe_consumer_handle));
     fake_tcp_connected_socket_ = fake_tcp_connected_socket.get();
     mojo::PendingRemote<network::mojom::TCPConnectedSocket>
         tcp_connected_socket;
@@ -66,7 +67,7 @@
   base::test::TaskEnvironment task_environment_;
   mojo::ScopedDataPipeProducerHandle receive_stream_;
   mojo::ScopedDataPipeConsumerHandle send_stream_;
-  FakeTcpConnectedSocket* fake_tcp_connected_socket_;
+  ash::nearby::FakeTcpConnectedSocket* fake_tcp_connected_socket_;
   mojo::SelfOwnedReceiverRef<network::mojom::TCPConnectedSocket>
       tcp_connected_socket_self_owned_receiver_ref_;
   std::unique_ptr<WifiLanSocket> wifi_lan_socket_;
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 6a85ac0..ecf223b6 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -1589,7 +1589,6 @@
       "../browser/file_system_access/chrome_file_system_access_permission_context_browsertest.cc",
       "../browser/file_system_access/file_system_access_tab_helper_browsertest.cc",
       "../browser/first_run/first_run_browsertest.cc",
-      "../browser/font_access/font_access_context_browsertest.cc",
       "../browser/geolocation/geolocation_browsertest.cc",
       "../browser/guest_view/mime_handler_view/chrome_mime_handler_view_browsertest.cc",
       "../browser/headless/headless_mode_browsertest.cc",
@@ -6075,7 +6074,6 @@
       "../browser/ui/extensions/extension_settings_overridden_dialog_unittest.cc",
       "../browser/ui/extensions/settings_api_bubble_helpers_unittest.cc",
       "../browser/ui/extensions/settings_overridden_params_providers_unittest.cc",
-      "../browser/ui/font_access/font_access_chooser_controller_unittest.cc",
       "../browser/ui/global_error/global_error_service_unittest.cc",
       "../browser/ui/global_media_controls/cast_media_notification_item_unittest.cc",
       "../browser/ui/global_media_controls/cast_media_notification_producer_unittest.cc",
diff --git a/chrome/test/data/extensions/api_test/accessibility_private/background.js b/chrome/test/data/extensions/api_test/accessibility_private/background.js
index 0355d9e..1c412f48 100644
--- a/chrome/test/data/extensions/api_test/accessibility_private/background.js
+++ b/chrome/test/data/extensions/api_test/accessibility_private/background.js
@@ -105,17 +105,33 @@
   },
 
   function testUpdateDictationBubble() {
-    chrome.accessibilityPrivate.updateDictationBubble(
-        /*visible=*/ true, /*text=*/ 'Hello');
-    chrome.test.sendMessage('Show', (proceed) => {
-      chrome.accessibilityPrivate.updateDictationBubble(
-          /*visible=*/ true, /*text=*/ 'Hello world');
-      chrome.test.sendMessage('Update', (proceed) => {
-        chrome.accessibilityPrivate.updateDictationBubble(/*visible=*/ false);
-        chrome.test.sendMessage('Hide');
-        chrome.test.succeed();
+    const update = chrome.accessibilityPrivate.updateDictationBubble;
+    const IconType = chrome.accessibilityPrivate.DictationBubbleIconType;
+
+    // The typical flow for this API is as follows:
+    // 1. Show the UI with the standby icon.
+    // 2. Update the UI with some speech results and hide all icons.
+    // 3. If the speech results match a Dictation macro (and the macro ran
+    // successfully), then show the macro succeeded icon along with the
+    // recognized text.
+    // 4. Reset the UI and show the standby icon.
+    // 5. Hide the UI.
+    update({visible: true, icon: IconType.STANDBY});
+    chrome.test.sendMessage('Standby', (proceed) => {
+      update({visible: true, icon: IconType.HIDDEN, text: 'Hello'});
+      chrome.test.sendMessage('Show text', (proceed) => {
+        update({visible: true, icon: IconType.MACRO_SUCCESS, text: 'Hello'});
+        chrome.test.sendMessage('Show macro success', (proceed) => {
+          update({visible: true, icon: IconType.STANDBY});
+          chrome.test.sendMessage('Reset', (proceed) => {
+            update({visible: false, icon: IconType.HIDDEN});
+            chrome.test.sendMessage('Hide');
+            chrome.test.succeed();
+          });
+        });
       });
     });
+
     chrome.test.notifyPass();
   },
 
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json
index 83715238..375ec6e 100644
--- a/chrome/test/data/policy/policy_test_cases.json
+++ b/chrome/test/data/policy/policy_test_cases.json
@@ -7308,6 +7308,37 @@
       }
     ]
   },
+  "NTPMiddleSlotAnnouncementVisible": {
+    "os": [
+      "win",
+      "linux",
+      "mac",
+      "chromeos_ash",
+      "chromeos_lacros"
+    ],
+    "policy_pref_mapping_tests": [
+      {
+        "policies": {
+          "NTPMiddleSlotAnnouncementVisible": true
+        },
+        "prefs": {
+          "ntp.promo_visible": {
+            "value": true
+          }
+        }
+      },
+      {
+        "policies": {
+          "NTPMiddleSlotAnnouncementVisible": false
+        },
+        "prefs": {
+          "ntp.promo_visible": {
+            "value": false
+          }
+        }
+      }
+    ]
+  },
   "WebRtcUdpPortRange": {
     "os": [
       "win",
diff --git a/chrome/test/data/printing/lazy-loaded-image-offscreen.html b/chrome/test/data/printing/lazy-loaded-image-offscreen.html
new file mode 100644
index 0000000..813a2ec
--- /dev/null
+++ b/chrome/test/data/printing/lazy-loaded-image-offscreen.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<img id=target loading=lazy src="test1.png"
+  style="margin-top: 40000px">
diff --git a/chrome/test/data/webui/chromeos/diagnostics/diagnostics_browsertest.js b/chrome/test/data/webui/chromeos/diagnostics/diagnostics_browsertest.js
index 870e4716..60784901 100644
--- a/chrome/test/data/webui/chromeos/diagnostics/diagnostics_browsertest.js
+++ b/chrome/test/data/webui/chromeos/diagnostics/diagnostics_browsertest.js
@@ -124,7 +124,13 @@
   mocha.run();
 });
 
-TEST_F('DiagnosticsAppWithNetwork', 'BrowserTest', function() {
+// TODO(crbug.com/1288529): Flaky on ChromeOS.
+GEN('#if defined(OS_CHROMEOS)');
+GEN('# define MAYBE_BrowserTest DISABLED_BrowserTest');
+GEN('#else');
+GEN('# define MAYBE_BrowserTest BrowserTest');
+GEN('#endif');
+TEST_F('DiagnosticsAppWithNetwork', 'MAYBE_BrowserTest', function() {
   mocha.run();
 });
 
diff --git a/chrome/test/data/webui/extensions/BUILD.gn b/chrome/test/data/webui/extensions/BUILD.gn
index 96cc330..9083ac2 100644
--- a/chrome/test/data/webui/extensions/BUILD.gn
+++ b/chrome/test/data/webui/extensions/BUILD.gn
@@ -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/chromeos/ui_mode.gni")
 import("//extensions/buildflags/buildflags.gni")
 import("//tools/typescript/ts_library.gni")
 import("//ui/webui/resources/tools/generate_grd.gni")
@@ -44,8 +45,6 @@
     "item_list_test.js",
     "item_test.js",
     "keyboard_shortcuts_test.js",
-    "kiosk_mode_manager_unit_test.js",
-    "kiosk_mode_test.js",
     "load_error_test.js",
     "manager_test.js",
     "manager_test_with_activity_log_flag.js",
@@ -59,12 +58,20 @@
     "runtime_hosts_dialog_test.js",
     "shortcut_input_test.js",
     "sidebar_test.js",
-    "test_kiosk_browser_proxy.js",
-    "test_service.js",
-    "test_util.js",
-    "toggle_row_test.js",
+    "test_service.ts",
+    "test_util.ts",
+    "toggle_row_test.ts",
     "toolbar_test.js",
   ]
+
+  if (is_chromeos_ash) {
+    in_files += [
+      "kiosk_mode_manager_unit_test.js",
+      "kiosk_mode_test.js",
+      "test_kiosk_browser_proxy.ts",
+    ]
+  }
+
   deps = [ "//chrome/browser/resources/extensions:build_ts" ]
   definitions = [
     "//tools/typescript/definitions/developer_private.d.ts",
diff --git a/chrome/test/data/webui/extensions/test_kiosk_browser_proxy.js b/chrome/test/data/webui/extensions/test_kiosk_browser_proxy.ts
similarity index 68%
rename from chrome/test/data/webui/extensions/test_kiosk_browser_proxy.js
rename to chrome/test/data/webui/extensions/test_kiosk_browser_proxy.ts
index 865a702..a70d688 100644
--- a/chrome/test/data/webui/extensions/test_kiosk_browser_proxy.js
+++ b/chrome/test/data/webui/extensions/test_kiosk_browser_proxy.ts
@@ -2,10 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import {KioskAppSettings, KioskBrowserProxy, KioskSettings} from 'chrome://extensions/extensions.js';
+
 import {TestBrowserProxy} from '../test_browser_proxy.js';
 
-/** @implements {KioskBrowserProxy} */
-export class TestKioskBrowserProxy extends TestBrowserProxy {
+export class TestKioskBrowserProxy extends TestBrowserProxy implements
+    KioskBrowserProxy {
+  private initialSettings_: KioskSettings;
+  private appSettings_: KioskAppSettings;
+
   constructor() {
     super([
       'initializeKioskAppSettings',
@@ -17,13 +22,11 @@
       'setDisableBailoutShortcut',
     ]);
 
-    /** @private {!KioskSettings} */
     this.initialSettings_ = {
       kioskEnabled: true,
       autoLaunchEnabled: false,
     };
 
-    /** @private {!KioskAppSettings} */
     this.appSettings_ = {
       apps: [],
       disableBailout: false,
@@ -31,50 +34,41 @@
     };
   }
 
-  /** @param {!KioskAppSettings} */
-  setAppSettings(settings) {
+  setAppSettings(settings: KioskAppSettings) {
     this.appSettings_ = settings;
   }
 
-  /** @param {!KioskSettings} */
-  setInitialSettings(settings) {
+  setInitialSettings(settings: KioskSettings) {
     this.initialSettings_ = settings;
   }
 
-  /** @override */
   initializeKioskAppSettings() {
     this.methodCalled('initializeKioskAppSettings');
     return Promise.resolve(this.initialSettings_);
   }
 
-  /** @override */
   getKioskAppSettings() {
     this.methodCalled('getKioskAppSettings');
     return Promise.resolve(this.appSettings_);
   }
 
-  /** @override */
-  addKioskApp(appId) {
+  addKioskApp(appId: string) {
     this.methodCalled('addKioskApp', appId);
   }
 
-  /** @override */
-  disableKioskAutoLaunch(appId) {
+  disableKioskAutoLaunch(appId: string) {
     this.methodCalled('disableKioskAutoLaunch', appId);
   }
 
-  /** @override */
-  enableKioskAutoLaunch(appId) {
+  enableKioskAutoLaunch(appId: string) {
     this.methodCalled('enableKioskAutoLaunch', appId);
   }
 
-  /** @override */
-  removeKioskApp(appId) {
+  removeKioskApp(appId: string) {
     this.methodCalled('removeKioskApp', appId);
   }
 
-  /** @override */
-  setDisableBailoutShortcut(disableBailout) {
+  setDisableBailoutShortcut(disableBailout: boolean) {
     this.methodCalled('setDisableBailoutShortcut', disableBailout);
   }
 }
diff --git a/chrome/test/data/webui/extensions/test_service.js b/chrome/test/data/webui/extensions/test_service.js
deleted file mode 100644
index b6a81c08..0000000
--- a/chrome/test/data/webui/extensions/test_service.js
+++ /dev/null
@@ -1,237 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import {FakeChromeEvent} from 'chrome://webui-test/fake_chrome_event.js';
-import {TestBrowserProxy} from 'chrome://webui-test/test_browser_proxy.js';
-
-/** An extensions.Service implementation to be used in tests. */
-export class TestService extends TestBrowserProxy {
-  constructor() {
-    super([
-      'addRuntimeHostPermission',
-      'deleteActivitiesById',
-      'deleteActivitiesFromExtension',
-      'downloadActivities',
-      'getExtensionActivityLog',
-      'getExtensionsInfo',
-      'getExtensionSize',
-      'getFilteredExtensionActivityLog',
-      'getProfileConfiguration',
-      'loadUnpacked',
-      'recordUserAction',
-      'retryLoadUnpacked',
-      'reloadItem',
-      'removeRuntimeHostPermission',
-      'setItemHostAccess',
-      'setProfileInDevMode',
-      'setShortcutHandlingSuspended',
-      'shouldIgnoreUpdate',
-      'updateAllExtensions',
-      'updateExtensionCommandKeybinding',
-      'updateExtensionCommandScope',
-    ]);
-
-    this.itemStateChangedTarget = new FakeChromeEvent();
-    this.profileStateChangedTarget = new FakeChromeEvent();
-    this.extensionActivityTarget = new FakeChromeEvent();
-
-    /** @type {boolean} */
-    this.acceptRuntimeHostPermission = true;
-
-    /** @private {!chrome.developerPrivate.LoadError} */
-    this.retryLoadUnpackedError_;
-
-    /** @type {boolean} */
-    this.forceReloadItemError_ = false;
-
-    /** @type {!chrome.activityLogPrivate.ActivityResultSet|undefined} */
-    this.testActivities;
-
-    /** @type {boolean} */
-    this.loadUnpackedSuccess_ = true;
-  }
-
-  /**
-   * @param {!chrome.developerPrivate.LoadError} error
-   */
-  setRetryLoadUnpackedError(error) {
-    this.retryLoadUnpackedError_ = error;
-  }
-
-  /**
-   * @param {boolean} force
-   */
-  setForceReloadItemError(force) {
-    this.forceReloadItemError_ = force;
-  }
-
-  /**
-   * @param {boolean} success
-   */
-  setLoadUnpackedSuccess(success) {
-    this.loadUnpackedSuccess_ = success;
-  }
-
-  /** @override */
-  addRuntimeHostPermission(id, site) {
-    this.methodCalled('addRuntimeHostPermission', [id, site]);
-    return this.acceptRuntimeHostPermission ? Promise.resolve() :
-                                              Promise.reject();
-  }
-
-  /** @override */
-  getProfileConfiguration() {
-    this.methodCalled('getProfileConfiguration');
-    return Promise.resolve({inDeveloperMode: false});
-  }
-
-  /** @override */
-  getItemStateChangedTarget() {
-    return this.itemStateChangedTarget;
-  }
-
-  /** @override */
-  getProfileStateChangedTarget() {
-    return this.profileStateChangedTarget;
-  }
-
-  /** @override */
-  getExtensionsInfo() {
-    this.methodCalled('getExtensionsInfo');
-    return Promise.resolve([]);
-  }
-
-  /** @override */
-  getExtensionSize() {
-    this.methodCalled('getExtensionSize');
-    return Promise.resolve('20 MB');
-  }
-
-  /** @override */
-  removeRuntimeHostPermission(id, site) {
-    this.methodCalled('removeRuntimeHostPermission', [id, site]);
-    return Promise.resolve();
-  }
-
-  /** @override */
-  setItemHostAccess(id, access) {
-    this.methodCalled('setItemHostAccess', [id, access]);
-  }
-
-  /** @override */
-  setShortcutHandlingSuspended(enable) {
-    this.methodCalled('setShortcutHandlingSuspended', enable);
-  }
-
-  /** @override */
-  shouldIgnoreUpdate(extensionId, eventType) {
-    this.methodCalled('shouldIgnoreUpdate', [extensionId, eventType]);
-  }
-
-  /** @override */
-  updateExtensionCommandKeybinding(item, commandName, keybinding) {
-    this.methodCalled(
-        'updateExtensionCommandKeybinding', [item, commandName, keybinding]);
-  }
-
-  /** @override */
-  updateExtensionCommandScope(item, commandName, scope) {
-    this.methodCalled(
-        'updateExtensionCommandScope', [item, commandName, scope]);
-  }
-
-  /** @override */
-  loadUnpacked() {
-    this.methodCalled('loadUnpacked');
-    return Promise.resolve(this.loadUnpackedSuccess_);
-  }
-
-  /** @override */
-  reloadItem(id) {
-    this.methodCalled('reloadItem', id);
-    return this.forceReloadItemError_ ? Promise.reject() : Promise.resolve();
-  }
-
-  /** @override */
-  retryLoadUnpacked(guid) {
-    this.methodCalled('retryLoadUnpacked', guid);
-    return (this.retryLoadUnpackedError_ !== undefined) ?
-        Promise.reject(this.retryLoadUnpackedError_) :
-        Promise.resolve();
-  }
-
-  /** @override */
-  setProfileInDevMode(inDevMode) {
-    this.methodCalled('setProfileInDevMode', inDevMode);
-  }
-
-  /** @override */
-  updateAllExtensions(extensions) {
-    this.methodCalled('updateAllExtensions');
-    return this.forceReloadItemError_ ? Promise.reject() : Promise.resolve();
-  }
-
-  /** @override */
-  getExtensionActivityLog(id) {
-    this.methodCalled('getExtensionActivityLog', id);
-    return Promise.resolve(this.testActivities);
-  }
-
-  /** @override */
-  getFilteredExtensionActivityLog(id, searchTerm) {
-    // This is functionally identical to getFilteredExtensionActivityLog in
-    // service.js but we do the filtering here instead of making API calls
-    // with filter objects.
-    this.methodCalled('getFilteredExtensionActivityLog', id, searchTerm);
-
-    // Convert everything to lowercase as searching is not case sensitive.
-    const lowerCaseSearchTerm = searchTerm.toLowerCase();
-
-    const activities = this.testActivities.activities;
-    const apiCallMatches = activities.filter(
-        activity =>
-            activity.apiCall.toLowerCase().includes(lowerCaseSearchTerm));
-    const pageUrlMatches = activities.filter(
-        activity => activity.pageUrl &&
-            activity.pageUrl.toLowerCase().includes(lowerCaseSearchTerm));
-    const argUrlMatches = activities.filter(
-        activity => activity.argUrl &&
-            activity.argUrl.toLowerCase().includes(lowerCaseSearchTerm));
-
-    return Promise.resolve(
-        {activities: [...apiCallMatches, ...pageUrlMatches, ...argUrlMatches]});
-  }
-
-  /** @override */
-  deleteActivitiesById(activityIds) {
-    // Pretend to delete all activities specified by activityIds.
-    const newActivities = this.testActivities.activities.filter(
-        activity => !activityIds.includes(activity.activityId));
-    this.testActivities = {activities: newActivities};
-
-    this.methodCalled('deleteActivitiesById', activityIds);
-    return Promise.resolve();
-  }
-
-  /** @override */
-  deleteActivitiesFromExtension(extensionId) {
-    this.methodCalled('deleteActivitiesFromExtension', extensionId);
-    return Promise.resolve();
-  }
-
-  /** @override */
-  getOnExtensionActivity() {
-    return this.extensionActivityTarget;
-  }
-
-  /** @override */
-  downloadActivities(rawActivityData, fileName) {
-    this.methodCalled('downloadActivities', [rawActivityData, fileName]);
-  }
-
-  /** @override */
-  recordUserAction(metricName) {
-    this.methodCalled('recordUserAction', metricName);
-  }
-}
diff --git a/chrome/test/data/webui/extensions/test_service.ts b/chrome/test/data/webui/extensions/test_service.ts
new file mode 100644
index 0000000..c68bb5d
--- /dev/null
+++ b/chrome/test/data/webui/extensions/test_service.ts
@@ -0,0 +1,291 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import {ServiceInterface} from 'chrome://extensions/extensions.js';
+import {FakeChromeEvent} from 'chrome://webui-test/fake_chrome_event.js';
+import {TestBrowserProxy} from 'chrome://webui-test/test_browser_proxy.js';
+
+// An Service implementation to be used in tests.
+export class TestService extends TestBrowserProxy implements ServiceInterface {
+  itemStateChangedTarget: FakeChromeEvent = new FakeChromeEvent();
+  profileStateChangedTarget: FakeChromeEvent = new FakeChromeEvent();
+  extensionActivityTarget: FakeChromeEvent = new FakeChromeEvent();
+  acceptRuntimeHostPermission: boolean = true;
+  testActivities?: chrome.activityLogPrivate.ActivityResultSet|undefined;
+
+  private retryLoadUnpackedError_?: chrome.developerPrivate.LoadError;
+  private forceReloadItemError_: boolean = false;
+  private loadUnpackedSuccess_: boolean = true;
+
+  constructor() {
+    super([
+      'addRuntimeHostPermission',
+      'choosePackRootDirectory',
+      'choosePrivateKeyPath',
+      'deleteActivitiesById',
+      'deleteActivitiesFromExtension',
+      'deleteErrors',
+      'deleteItem',
+      'downloadActivities',
+      'getExtensionActivityLog',
+      'getExtensionsInfo',
+      'getExtensionSize',
+      'getFilteredExtensionActivityLog',
+      'getProfileConfiguration',
+      'inspectItemView',
+      'loadUnpacked',
+      'openUrl',
+      'packExtension',
+      'recordUserAction',
+      'reloadItem',
+      'removeRuntimeHostPermission',
+      'repairItem',
+      'requestFileSource',
+      'retryLoadUnpacked',
+      'setItemAllowedIncognito',
+      'setItemAllowedOnFileUrls',
+      'setItemCollectsErrors',
+      'setItemEnabled',
+      'setItemHostAccess',
+      'setProfileInDevMode',
+      'setShortcutHandlingSuspended',
+      'shouldIgnoreUpdate',
+      'showInFolder',
+      'showItemOptionsPage',
+      'updateAllExtensions',
+      'updateExtensionCommandKeybinding',
+      'updateExtensionCommandScope',
+    ]);
+  }
+
+  setRetryLoadUnpackedError(error: chrome.developerPrivate.LoadError) {
+    this.retryLoadUnpackedError_ = error;
+  }
+
+  setForceReloadItemError(force: boolean) {
+    this.forceReloadItemError_ = force;
+  }
+
+  setLoadUnpackedSuccess(success: boolean) {
+    this.loadUnpackedSuccess_ = success;
+  }
+
+  addRuntimeHostPermission(id: string, host: string) {
+    this.methodCalled('addRuntimeHostPermission', [id, host]);
+    return this.acceptRuntimeHostPermission ? Promise.resolve() :
+                                              Promise.reject();
+  }
+
+  choosePackRootDirectory() {
+    this.methodCalled('choosePackRootDirectory');
+    return Promise.resolve('');
+  }
+
+  choosePrivateKeyPath() {
+    this.methodCalled('choosePrivateKeyPath');
+    return Promise.resolve('');
+  }
+
+  getProfileConfiguration() {
+    this.methodCalled('getProfileConfiguration');
+    return Promise.resolve({inDeveloperMode: false});
+  }
+
+  getItemStateChangedTarget() {
+    return this.itemStateChangedTarget;
+  }
+
+  getProfileStateChangedTarget() {
+    return this.profileStateChangedTarget;
+  }
+
+  getExtensionsInfo() {
+    this.methodCalled('getExtensionsInfo');
+    return Promise.resolve([]);
+  }
+
+  getExtensionSize() {
+    this.methodCalled('getExtensionSize');
+    return Promise.resolve('20 MB');
+  }
+
+  inspectItemView(id: string, view: chrome.developerPrivate.ExtensionView) {
+    this.methodCalled('inspectItemView', [id, view]);
+  }
+
+  removeRuntimeHostPermission(id: string, host: string) {
+    this.methodCalled('removeRuntimeHostPermission', [id, host]);
+    return Promise.resolve();
+  }
+
+  setItemAllowedIncognito(id: string, isAllowedIncognito: boolean) {
+    this.methodCalled('setItemAllowedIncognito', [id, isAllowedIncognito]);
+  }
+
+  setItemAllowedOnFileUrls(id: string, isAllowedOnFileUrls: boolean) {
+    this.methodCalled('setItemAllowedOnFileUrls', [id, isAllowedOnFileUrls]);
+  }
+
+  setItemEnabled(id: string, isEnabled: boolean) {
+    this.methodCalled('setItemEnabled', [id, isEnabled]);
+  }
+
+  setItemCollectsErrors(id: string, collectsErrors: boolean) {
+    this.methodCalled('setItemCollectsErrors', [id, collectsErrors]);
+  }
+
+  setItemHostAccess(id: string, access: chrome.developerPrivate.HostAccess) {
+    this.methodCalled('setItemHostAccess', [id, access]);
+  }
+
+  setShortcutHandlingSuspended(enable: boolean) {
+    this.methodCalled('setShortcutHandlingSuspended', enable);
+  }
+
+  shouldIgnoreUpdate(
+      extensionId: string, eventType: chrome.developerPrivate.EventType) {
+    this.methodCalled('shouldIgnoreUpdate', [extensionId, eventType]);
+  }
+
+  updateExtensionCommandKeybinding(
+      extensionId: string, commandName: string, keybinding: string) {
+    this.methodCalled(
+        'updateExtensionCommandKeybinding',
+        [extensionId, commandName, keybinding]);
+  }
+
+  updateExtensionCommandScope(
+      extensionId: string, commandName: string,
+      scope: chrome.developerPrivate.CommandScope): void {
+    this.methodCalled(
+        'updateExtensionCommandScope', [extensionId, commandName, scope]);
+  }
+
+  loadUnpacked() {
+    this.methodCalled('loadUnpacked');
+    return Promise.resolve(this.loadUnpackedSuccess_);
+  }
+
+  reloadItem(id: string) {
+    this.methodCalled('reloadItem', id);
+    return this.forceReloadItemError_ ? Promise.reject() : Promise.resolve();
+  }
+
+  retryLoadUnpacked(guid: string) {
+    this.methodCalled('retryLoadUnpacked', guid);
+    return (this.retryLoadUnpackedError_ !== undefined) ?
+        Promise.reject(this.retryLoadUnpackedError_) :
+        Promise.resolve(true);
+  }
+
+  requestFileSource(args: chrome.developerPrivate.RequestFileSourceProperties) {
+    this.methodCalled('requestFileSource', args);
+    return Promise.resolve({
+      highlight: '',
+      beforeHighlight: '',
+      afterHighlight: '',
+      title: '',
+      message: '',
+    });
+  }
+
+  openUrl(url: string) {
+    this.methodCalled('openUrl', url);
+  }
+
+  packExtension(
+      rootPath: string, keyPath: string, flag?: number,
+      _callback?:
+          (response: chrome.developerPrivate.PackDirectoryResponse) => void):
+      void {
+    this.methodCalled('packExtension', [rootPath, keyPath, flag]);
+  }
+
+  repairItem(id: string): void {
+    this.methodCalled('repairItem', id);
+  }
+
+  setProfileInDevMode(inDevMode: boolean) {
+    this.methodCalled('setProfileInDevMode', inDevMode);
+  }
+
+  showInFolder(id: string) {
+    this.methodCalled('showInFolder', id);
+  }
+
+  showItemOptionsPage(extension: chrome.developerPrivate.ExtensionInfo) {
+    this.methodCalled('showItemOptionsPage', extension);
+  }
+
+  updateAllExtensions(_extensions: chrome.developerPrivate.ExtensionInfo[]) {
+    this.methodCalled('updateAllExtensions');
+    return this.forceReloadItemError_ ? Promise.reject() : Promise.resolve();
+  }
+
+  getExtensionActivityLog(id: string) {
+    this.methodCalled('getExtensionActivityLog', id);
+    return Promise.resolve(this.testActivities!);
+  }
+
+  getFilteredExtensionActivityLog(id: string, searchTerm: string) {
+    // This is functionally identical to getFilteredExtensionActivityLog in
+    // service.js but we do the filtering here instead of making API calls
+    // with filter objects.
+    this.methodCalled('getFilteredExtensionActivityLog', id, searchTerm);
+
+    // Convert everything to lowercase as searching is not case sensitive.
+    const lowerCaseSearchTerm = searchTerm.toLowerCase();
+
+    const activities = this.testActivities!.activities;
+    const apiCallMatches = activities.filter(
+        activity =>
+            activity.apiCall!.toLowerCase().includes(lowerCaseSearchTerm));
+    const pageUrlMatches = activities.filter(
+        activity => activity.pageUrl &&
+            activity.pageUrl.toLowerCase().includes(lowerCaseSearchTerm));
+    const argUrlMatches = activities.filter(
+        activity => activity.argUrl &&
+            activity.argUrl.toLowerCase().includes(lowerCaseSearchTerm));
+
+    return Promise.resolve(
+        {activities: [...apiCallMatches, ...pageUrlMatches, ...argUrlMatches]});
+  }
+
+  deleteActivitiesById(activityIds: string[]) {
+    // Pretend to delete all activities specified by activityIds.
+    const newActivities = this.testActivities!.activities.filter(
+        activity => !activityIds.includes(activity.activityId!));
+    this.testActivities = {activities: newActivities};
+
+    this.methodCalled('deleteActivitiesById', activityIds);
+    return Promise.resolve();
+  }
+
+  deleteActivitiesFromExtension(extensionId: string) {
+    this.methodCalled('deleteActivitiesFromExtension', extensionId);
+    return Promise.resolve();
+  }
+
+  deleteErrors(
+      extensionId: string, _errorIds?: number[],
+      _type?: chrome.developerPrivate.ErrorType) {
+    this.methodCalled('deleteErrors', extensionId);
+  }
+
+  deleteItem(id: string) {
+    this.methodCalled('deleteItem', id);
+  }
+
+  getOnExtensionActivity() {
+    return this.extensionActivityTarget;
+  }
+
+  downloadActivities(rawActivityData: string, fileName: string) {
+    this.methodCalled('downloadActivities', [rawActivityData, fileName]);
+  }
+
+  recordUserAction(metricName: string) {
+    this.methodCalled('recordUserAction', metricName);
+  }
+}
diff --git a/chrome/test/data/webui/extensions/test_util.js b/chrome/test/data/webui/extensions/test_util.js
deleted file mode 100644
index f5d11302..0000000
--- a/chrome/test/data/webui/extensions/test_util.js
+++ /dev/null
@@ -1,252 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/** @fileoverview Common utilities for extension ui tests. */
-import {MockController, MockMethod} from 'chrome://webui-test/mock_controller.js';
-import {isChildVisible} from 'chrome://webui-test/test_util.js';
-
-import {TestKioskBrowserProxy} from './test_kiosk_browser_proxy.js';
-
-/** A mock to test that clicking on an element calls a specific method. */
-export class ClickMock {
-  /**
-   * Tests clicking on an element and expecting a call.
-   * @param {HTMLElement} element The element to click on.
-   * @param {string} callName The function expected to be called.
-   * @param {Array<*>=} opt_expectedArgs The arguments the function is
-   *     expected to be called with.
-   * @param {*=} opt_returnValue The value to return from the function call.
-   */
-  testClickingCalls(element, callName, opt_expectedArgs, opt_returnValue) {
-    const mock = new MockController();
-    const mockMethod = mock.createFunctionMock(this, callName);
-    mockMethod.returnValue = opt_returnValue;
-    MockMethod.prototype.addExpectation.apply(mockMethod, opt_expectedArgs);
-    element.click();
-    mock.verifyMocks();
-  }
-}
-
-/**
- * A mock to test receiving expected events and verify that they were called
- * with the proper detail values.
- */
-export class ListenerMock {
-  constructor() {
-    /** @private {Object<{satisfied: boolean, args: !Object}>} */
-    this.listeners_ = {};
-  }
-
-  /**
-   * @param {string} eventName
-   * @param {Event} e
-   */
-  onEvent_(eventName, e) {
-    assert(this.listeners_.hasOwnProperty(eventName));
-    if (this.listeners_[eventName].satisfied) {
-      // Event was already called and checked. We could always make this
-      // more intelligent by allowing for subsequent calls, removing the
-      // listener, etc, but there's no need right now.
-      return;
-    }
-    const expected = this.listeners_[eventName].args || {};
-    expectDeepEquals(e.detail, expected);
-    this.listeners_[eventName].satisfied = true;
-  }
-
-  /**
-   * Adds an expected event.
-   * @param {!EventTarget} target
-   * @param {string} eventName
-   * @param {Object=} opt_eventArgs If omitted, will check that the details
-   *     are empty (i.e., {}).
-   */
-  addListener(target, eventName, opt_eventArgs) {
-    assert(!this.listeners_.hasOwnProperty(eventName));
-    this.listeners_[eventName] = {args: opt_eventArgs || {}, satisfied: false};
-    target.addEventListener(eventName, this.onEvent_.bind(this, eventName));
-  }
-
-  /** Verifies the expectations set. */
-  verify() {
-    const missingEvents = [];
-    for (const key in this.listeners_) {
-      if (!this.listeners_[key].satisfied) {
-        missingEvents.push(key);
-      }
-    }
-    expectEquals(0, missingEvents.length, JSON.stringify(missingEvents));
-  }
-}
-
-/**
- * A mock delegate for the item, capable of testing functionality.
- * @implements {extensions.ItemDelegate}
- */
-export class MockItemDelegate extends ClickMock {
-  constructor() {
-    super();
-  }
-
-  /** @override */
-  deleteItem(id) {}
-
-  /** @override */
-  setItemEnabled(id, enabled) {}
-
-  /** @override */
-  showItemDetails(id) {}
-
-  /** @override */
-  setItemAllowedIncognito(id, enabled) {}
-
-  /** @override */
-  setItemAllowedOnFileUrls(id, enabled) {}
-
-  /** @override */
-  setItemHostAccess(id, hostAccess) {}
-
-  /** @override */
-  setItemCollectsErrors(id, enabled) {}
-
-  /** @override */
-  inspectItemView(id, view) {}
-
-  /** @override */
-  reloadItem(id) {}
-
-  /** @override */
-  repairItem(id) {}
-
-  /** @override */
-  showItemOptionsPage(id) {}
-
-  /** @override */
-  showInFolder(id) {}
-
-  /** @override */
-  getExtensionSize(id) {
-    return Promise.resolve('10 MB');
-  }
-}
-
-/**
- * A mock to intercept User Action logging calls and verify how many times they
- * were called.
- */
-export class MetricsPrivateMock {
-  constructor() {
-    this.userActionMap = new Map();
-  }
-
-  getUserActionCount(metricName) {
-    return this.userActionMap.get(metricName) || 0;
-  }
-
-  recordUserAction(metricName) {
-    this.userActionMap.set(metricName, this.getUserActionCount(metricName) + 1);
-  }
-}
-
-/**
- * @param {!HTMLElement} element
- * @return {boolean} whether or not the element passed in is visible
- */
-export function isElementVisible(element) {
-  const rect = element.getBoundingClientRect();
-  return rect.width * rect.height > 0;  // Width and height is never negative.
-}
-
-/**
- * Tests that the element's visibility matches |expectedVisible| and,
- * optionally, has specific content if it is visible.
- * @param {!HTMLElement} parentEl The parent element to query for the element.
- * @param {string} selector The selector to find the element.
- * @param {boolean} expectedVisible Whether the element should be
- *     visible.
- * @param {string=} opt_expectedText The expected textContent value.
- */
-export function testVisible(
-    parentEl, selector, expectedVisible, opt_expectedText) {
-  const visible = isChildVisible(parentEl, selector);
-  expectEquals(expectedVisible, visible, selector);
-  if (expectedVisible && visible && opt_expectedText) {
-    const element = parentEl.shadowRoot.querySelector(selector);
-    expectEquals(opt_expectedText, element.textContent.trim(), selector);
-  }
-}
-
-/**
- * Creates an ExtensionInfo object.
- * @param {Object=} opt_properties A set of properties that will be used on
- *     the resulting ExtensionInfo (otherwise defaults will be used).
- * @return {chrome.developerPrivate.ExtensionInfo}
- */
-export function createExtensionInfo(opt_properties) {
-  const id = opt_properties && opt_properties.hasOwnProperty('id') ?
-      opt_properties['id'] :
-      'a'.repeat(32);
-  const baseUrl = 'chrome-extension://' + id + '/';
-  return Object.assign(
-      {
-        commands: [],
-        dependentExtensions: [],
-        description: 'This is an extension',
-        disableReasons: {
-          suspiciousInstall: false,
-          corruptInstall: false,
-          updateRequired: false,
-          blockedByPolicy: false,
-          custodianApprovalRequired: false,
-          parentDisabledPermissions: false,
-          reloading: false,
-        },
-        homePage: {specified: false, url: ''},
-        iconUrl: 'chrome://extension-icon/' + id + '/24/0',
-        id: id,
-        incognitoAccess: {isEnabled: true, isActive: false},
-        location: 'FROM_STORE',
-        manifestErrors: [],
-        name: 'Wonderful Extension',
-        runtimeErrors: [],
-        runtimeWarnings: [],
-        permissions: {simplePermissions: []},
-        state: 'ENABLED',
-        type: 'EXTENSION',
-        userMayModify: true,
-        version: '2.0',
-        views: [{url: baseUrl + 'foo.html'}, {url: baseUrl + 'bar.html'}],
-      },
-      opt_properties);
-}
-
-/**
- * Finds all nodes matching |query| under |root|, within self and children's
- * Shadow DOM.
- * @param {!Node} root
- * @param {string} query The CSS query
- * @return {!Array<!HTMLElement>}
- */
-export function findMatches(root, query) {
-  let elements = new Set();
-  function doSearch(node) {
-    if (node.nodeType === Node.ELEMENT_NODE) {
-      const matches = node.querySelectorAll(query);
-      for (let match of matches) {
-        elements.add(match);
-      }
-    }
-    let child = node.firstChild;
-    while (child !== null) {
-      doSearch(child);
-      child = child.nextSibling;
-    }
-    const shadowRoot = node.shadowRoot;
-    if (shadowRoot) {
-      doSearch(shadowRoot);
-    }
-  }
-  doSearch(root);
-  return Array.from(elements);
-}
diff --git a/chrome/test/data/webui/extensions/test_util.ts b/chrome/test/data/webui/extensions/test_util.ts
new file mode 100644
index 0000000..79c5159
--- /dev/null
+++ b/chrome/test/data/webui/extensions/test_util.ts
@@ -0,0 +1,244 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/** @fileoverview Common utilities for extension ui tests. */
+import {ItemDelegate} from 'chrome://extensions/extensions.js';
+import {assertDeepEquals, assertEquals, assertTrue} from 'chrome://webui-test/chai_assert.js';
+import {MockController, MockMethod} from 'chrome://webui-test/mock_controller.js';
+import {isChildVisible} from 'chrome://webui-test/test_util.js';
+
+/** A mock to test that clicking on an element calls a specific method. */
+export class ClickMock {
+  /**
+   * Tests clicking on an element and expecting a call.
+   * @param element The element to click on.
+   * @param callName The function expected to be called.
+   * @param opt_expectedArgs The arguments the function is
+   *     expected to be called with.
+   * @param opt_returnValue The value to return from the function call.
+   */
+  testClickingCalls(
+      element: HTMLElement, callName: string, opt_expectedArgs: any[],
+      opt_returnValue: any) {
+    const mock = new MockController();
+    const mockMethod = mock.createFunctionMock(this, callName);
+    mockMethod.returnValue = opt_returnValue;
+    MockMethod.prototype.addExpectation.apply(mockMethod, opt_expectedArgs);
+    element.click();
+    mock.verifyMocks();
+  }
+}
+
+type ListenerInfo = {
+  satisfied: boolean,
+  args: any,
+};
+
+/**
+ * A mock to test receiving expected events and verify that they were called
+ * with the proper detail values.
+ */
+export class ListenerMock {
+  private listeners_: {[eventName: string]: ListenerInfo} = {};
+
+  private onEvent_(eventName: string, e: Event) {
+    assertTrue(this.listeners_.hasOwnProperty(eventName));
+    if (this.listeners_[eventName]!.satisfied) {
+      // Event was already called and checked. We could always make this
+      // more intelligent by allowing for subsequent calls, removing the
+      // listener, etc, but there's no need right now.
+      return;
+    }
+    const expected = this.listeners_[eventName]!.args || {};
+    assertDeepEquals((e as CustomEvent).detail, expected);
+    this.listeners_[eventName]!.satisfied = true;
+  }
+
+  /**
+   * Adds an expected event.
+   * @param opt_eventArgs If omitted, will check that the details
+   *     are empty (i.e., {}).
+   */
+  addListener(target: EventTarget, eventName: string, opt_eventArgs: any) {
+    assertTrue(!this.listeners_.hasOwnProperty(eventName));
+    this.listeners_[eventName] = {args: opt_eventArgs || {}, satisfied: false};
+    target.addEventListener(eventName, this.onEvent_.bind(this, eventName));
+  }
+
+  /** Verifies the expectations set. */
+  verify() {
+    const missingEvents = [];
+    for (const key in this.listeners_) {
+      if (!this.listeners_[key]!.satisfied) {
+        missingEvents.push(key);
+      }
+    }
+    assertEquals(0, missingEvents.length, JSON.stringify(missingEvents));
+  }
+}
+
+/**
+ * A mock delegate for the item, capable of testing functionality.
+ */
+export class MockItemDelegate extends ClickMock implements ItemDelegate {
+  deleteItem(_id: string) {}
+  setItemEnabled(_id: string, _isEnabled: boolean) {}
+  setItemAllowedIncognito(_id: string, _isAllowedIncognito: boolean) {}
+  setItemAllowedOnFileUrls(_id: string, _isAllowedOnFileUrls: boolean) {}
+  setItemHostAccess(
+      _id: string, _hostAccess: chrome.developerPrivate.HostAccess) {}
+  setItemCollectsErrors(_id: string, _collectsErrors: boolean) {}
+  inspectItemView(_id: string, _view: chrome.developerPrivate.ExtensionView) {}
+  openUrl(_url: string) {}
+
+
+  reloadItem(_id: string) {
+    return Promise.resolve();
+  }
+
+  repairItem(_id: string) {}
+  showItemOptionsPage(_extension: chrome.developerPrivate.ExtensionInfo) {}
+  showInFolder(_id: string) {}
+
+  getExtensionSize(_id: string) {
+    return Promise.resolve('10 MB');
+  }
+
+  addRuntimeHostPermission(_id: string, _host: string) {
+    return Promise.resolve();
+  }
+
+  removeRuntimeHostPermission(_id: string, _host: string) {
+    return Promise.resolve();
+  }
+
+  recordUserAction(_metricName: string) {}
+}
+
+/**
+ * A mock to intercept User Action logging calls and verify how many times they
+ * were called.
+ */
+export class MetricsPrivateMock {
+  userActionMap: Map<string, number> = new Map();
+
+  getUserActionCount(metricName: string): number {
+    return this.userActionMap.get(metricName) || 0;
+  }
+
+  recordUserAction(metricName: string) {
+    this.userActionMap.set(metricName, this.getUserActionCount(metricName) + 1);
+  }
+}
+
+export function isElementVisible(element: HTMLElement): boolean {
+  const rect = element.getBoundingClientRect();
+  return rect.width * rect.height > 0;  // Width and height is never negative.
+}
+
+/**
+ * Tests that the element's visibility matches |expectedVisible| and,
+ * optionally, has specific content if it is visible.
+ * @param parentEl The parent element to query for the element.
+ * @param selector The selector to find the element.
+ * @param expectedVisible Whether the element should be visible.
+ * @param opt_expectedText The expected textContent value.
+ */
+export function testVisible(
+    parentEl: HTMLElement, selector: string, expectedVisible: boolean,
+    opt_expectedText?: string) {
+  const visible = isChildVisible(parentEl, selector);
+  assertEquals(expectedVisible, visible, selector);
+  if (expectedVisible && visible && opt_expectedText) {
+    const element = parentEl.shadowRoot!.querySelector(selector)!;
+    assertEquals(opt_expectedText, element.textContent!.trim(), selector);
+  }
+}
+
+/**
+ * Creates an ExtensionInfo object.
+ * @param opt_properties A set of properties that will be used on the resulting
+ *     ExtensionInfo (otherwise defaults will be used).
+ */
+export function createExtensionInfo(
+    opt_properties: Partial<chrome.developerPrivate.ExtensionInfo>):
+    chrome.developerPrivate.ExtensionInfo {
+  const id = opt_properties && opt_properties.hasOwnProperty('id') ?
+      opt_properties['id']! :
+      'a'.repeat(32);
+  const baseUrl = 'chrome-extension://' + id + '/';
+  return Object.assign(
+      {
+        commands: [],
+        errorCollection: {
+          isEnabled: false,
+          isActive: false,
+        },
+        dependentExtensions: [],
+        description: 'This is an extension',
+        disableReasons: {
+          suspiciousInstall: false,
+          corruptInstall: false,
+          updateRequired: false,
+          blockedByPolicy: false,
+          custodianApprovalRequired: false,
+          parentDisabledPermissions: false,
+          reloading: false,
+        },
+        fileAccess: {
+          isEnabled: false,
+          isActive: false,
+        },
+        homePage: {specified: false, url: ''},
+        iconUrl: 'chrome://extension-icon/' + id + '/24/0',
+        id: id,
+        incognitoAccess: {isEnabled: true, isActive: false},
+        installWarnings: [],
+        location: 'FROM_STORE',
+        manifestErrors: [],
+        manifestHomePageUrl: '',
+        mustRemainInstalled: false,
+        name: 'Wonderful Extension',
+        offlineEnabled: false,
+        runtimeErrors: [],
+        runtimeWarnings: [],
+        permissions: {simplePermissions: []},
+        state: 'ENABLED',
+        type: 'EXTENSION',
+        updateUrl: '',
+        userMayModify: true,
+        version: '2.0',
+        views: [{url: baseUrl + 'foo.html'}, {url: baseUrl + 'bar.html'}],
+        webStoreUrl: '',
+        showSafeBrowsingAllowlistWarning: false,
+      },
+      opt_properties);
+}
+
+/**
+ * Finds all nodes matching |query| under |root|, within self and children's
+ * Shadow DOM.
+ */
+export function findMatches(root: HTMLElement, query: string): HTMLElement[] {
+  let elements = new Set<HTMLElement>();
+  function doSearch(node: Node) {
+    if (node.nodeType === Node.ELEMENT_NODE) {
+      const matches = (node as Element).querySelectorAll<HTMLElement>(query);
+      for (let match of matches) {
+        elements.add(match);
+      }
+    }
+    let child = node.firstChild;
+    while (child !== null) {
+      doSearch(child);
+      child = child.nextSibling;
+    }
+    const shadowRoot = (node as HTMLElement).shadowRoot;
+    if (shadowRoot) {
+      doSearch(shadowRoot);
+    }
+  }
+  doSearch(root);
+  return Array.from(elements);
+}
diff --git a/chrome/test/data/webui/extensions/toggle_row_test.js b/chrome/test/data/webui/extensions/toggle_row_test.ts
similarity index 80%
rename from chrome/test/data/webui/extensions/toggle_row_test.js
rename to chrome/test/data/webui/extensions/toggle_row_test.ts
index 5750ee2e..f68e844 100644
--- a/chrome/test/data/webui/extensions/toggle_row_test.js
+++ b/chrome/test/data/webui/extensions/toggle_row_test.ts
@@ -4,10 +4,12 @@
 
 import 'chrome://extensions/extensions.js';
 
+import {ExtensionsToggleRowElement} from 'chrome://extensions/extensions.js';
+import {assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
 import {eventToPromise} from 'chrome://webui-test/test_util.js';
 
 suite('extensions-toggle-row', function() {
-  let row;
+  let row: ExtensionsToggleRowElement;
 
   setup(function() {
     document.body.innerHTML = `
@@ -16,7 +18,7 @@
       </extensions-toggle-row>
     `;
 
-    row = document.getElementById('row');
+    row = document.querySelector('extensions-toggle-row')!;
     assertFalse(row.checked);
   });
 
diff --git a/chrome/test/data/webui/read_later/side_panel/bookmarks_list_test.ts b/chrome/test/data/webui/read_later/side_panel/bookmarks_list_test.ts
index 4e0cfea..cb45384 100644
--- a/chrome/test/data/webui/read_later/side_panel/bookmarks_list_test.ts
+++ b/chrome/test/data/webui/read_later/side_panel/bookmarks_list_test.ts
@@ -284,6 +284,7 @@
   test('CutsCopyPastesBookmark', async () => {
     const folderElement = getFolderElements(bookmarksList)[0]!;
     const bookmarkElement = getBookmarkElements(folderElement)[0]!;
+    bookmarkElement.focus();
 
     bookmarkElement.dispatchEvent(new KeyboardEvent(
         'keydown', {key: 'x', ctrlKey: true, bubbles: true, composed: true}));
diff --git a/chrome/test/data/webui/settings/chromeos/app_management/supported_links_item_test.js b/chrome/test/data/webui/settings/chromeos/app_management/supported_links_item_test.js
index cb6a101..5a3fdc04 100644
--- a/chrome/test/data/webui/settings/chromeos/app_management/supported_links_item_test.js
+++ b/chrome/test/data/webui/settings/chromeos/app_management/supported_links_item_test.js
@@ -162,13 +162,15 @@
     await fakeHandler.flushPipesForTesting();
     await test_util.flushTasks();
 
-    assertTrue(
-        !!supportedLinksItem.shadowRoot.querySelector('#explanation-text'));
+    assertTrue(!!supportedLinksItem.shadowRoot.querySelector(
+        '#disabled-explanation-text'));
     assertTrue(
         !!supportedLinksItem.shadowRoot.querySelector('#radio-group').disabled);
   });
 
-  test('can open and close supported link list dialog', async function() {
+  // TODO(crbug/1253891): Race condition when closing the dialog makes this test
+  // flaky.
+  test.skip('can open and close supported link list dialog', async function() {
     const supportedLink = 'google.com';
     const pwaOptions = {
       type: apps.mojom.AppType.kWeb,
@@ -221,7 +223,9 @@
                     .open);
   });
 
-  test('overlap dialog is shown and cancelled', async function() {
+  // TODO(crbug/1253891): Race condition when closing the dialog makes this test
+  // flaky.
+  test.skip('overlap dialog is shown and cancelled', async function() {
     const pwaOptions = {
       type: apps.mojom.AppType.kWeb,
       isPreferredApp: false,
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 ef6ddc85..c68ed98 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
@@ -281,8 +281,7 @@
  ['AppManagementPwaDetailView', 'pwa_detail_view_test.m.js'],
  ['AppManagementReducers', 'reducers_test.m.js'],
  ['AppManagementResizeLockItem', 'resize_lock_item_test.m.js'],
- // TODO(crbug/1253891): Re-enable once flakiness is fixed.
- // ['AppManagementSupportedLinksItem', 'supported_links_item_test.m.js'],
+ ['AppManagementSupportedLinksItem', 'supported_links_item_test.m.js'],
  ['AppManagementToggleRow', 'toggle_row_test.m.js'],
  ['AppManagementUninstallButton', 'uninstall_button_test.m.js'],
  ['BluetoothPage', 'bluetooth_page_tests.m.js'],
diff --git a/chrome/test/pixel/demo/skia_gold_demo_pixeltest.cc b/chrome/test/pixel/demo/skia_gold_demo_pixeltest.cc
index 966d9647..aaa4cdf 100644
--- a/chrome/test/pixel/demo/skia_gold_demo_pixeltest.cc
+++ b/chrome/test/pixel/demo/skia_gold_demo_pixeltest.cc
@@ -46,7 +46,7 @@
   ui::ScopedAnimationDurationScaleMode disable_animation(
       ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
   GURL url("chrome://bookmarks");
-  AddTabAtIndex(0, url, ui::PageTransition::PAGE_TRANSITION_FIRST);
+  ASSERT_TRUE(AddTabAtIndex(0, url, ui::PageTransition::PAGE_TRANSITION_FIRST));
   auto* const browser_view = static_cast<BrowserView*>(browser()->window());
   bool ret = GetPixelDiff().CompareScreenshot("omnibox",
       browser_view->GetLocationBarView());
diff --git a/chrome/updater/app/app_install.cc b/chrome/updater/app/app_install.cc
index c5b66a9..d91047a3 100644
--- a/chrome/updater/app/app_install.cc
+++ b/chrome/updater/app/app_install.cc
@@ -171,15 +171,22 @@
   scoped_refptr<UpdateService> update_service =
       CreateUpdateServiceProxy(updater_scope());
   update_service->RegisterApp(
-      request, base::BindOnce(
-                   [](scoped_refptr<UpdateService> /*update_service*/,
-                      scoped_refptr<AppInstall> app_install,
-                      const RegistrationResponse& registration_response) {
-                     VLOG(2) << "Updater registration complete: "
-                             << registration_response.status_code;
-                     app_install->MaybeInstallApp();
-                   },
-                   update_service, base::WrapRefCounted(this)));
+      request,
+      base::BindOnce(
+          [](scoped_refptr<UpdateService> /*update_service*/,
+             scoped_refptr<AppInstall> app_install,
+             const RegistrationResponse& registration_response) {
+            if (registration_response.status_code != kRegistrationSuccess &&
+                registration_response.status_code !=
+                    kRegistrationAlreadyRegistered) {
+              VLOG(2) << "Updater registration failed: "
+                      << registration_response.status_code;
+              app_install->Shutdown(kErrorRegistrationFailed);
+              return;
+            }
+            app_install->MaybeInstallApp();
+          },
+          update_service, base::WrapRefCounted(this)));
 }
 
 void AppInstall::MaybeInstallApp() {
diff --git a/chrome/updater/constants.h b/chrome/updater/constants.h
index 3c1d52b..61a9c51 100644
--- a/chrome/updater/constants.h
+++ b/chrome/updater/constants.h
@@ -200,6 +200,9 @@
 // The server candidate failed to promote itself to active.
 constexpr int kErrorFailedToSwap = 2;
 
+// Client Errors.
+constexpr int kErrorRegistrationFailed = 1;
+
 // Policy Management constants.
 // The maximum value allowed for policy AutoUpdateCheckPeriodMinutes.
 constexpr int kMaxAutoUpdateCheckPeriodMinutes = 43200;
diff --git a/chrome/updater/mac/BUILD.gn b/chrome/updater/mac/BUILD.gn
index f6395606..be429c8 100644
--- a/chrome/updater/mac/BUILD.gn
+++ b/chrome/updater/mac/BUILD.gn
@@ -231,7 +231,7 @@
   sources =
       [ "$root_out_dir/${keystone_app_name}Agent.app/Contents/Info.plist" ]
 
-  outputs = [ "{{bundle_contents_dir}}/Helpers/$keystone_app_name.bundle/Contents/Resources/${keystone_app_name}Agent.app/Contents/MacOS/{{source_file_part}}" ]
+  outputs = [ "{{bundle_contents_dir}}/Helpers/$keystone_app_name.bundle/Contents/Resources/${keystone_app_name}Agent.app/Contents/{{source_file_part}}" ]
   public_deps = [ ":keystone_agent_bundle" ]
 }
 
diff --git a/chromecast/browser/cast_content_browser_client.cc b/chromecast/browser/cast_content_browser_client.cc
index 5098a506..f435de4 100644
--- a/chromecast/browser/cast_content_browser_client.cc
+++ b/chromecast/browser/cast_content_browser_client.cc
@@ -726,6 +726,10 @@
   }
 }
 
+bool CastContentBrowserClient::IsBufferingEnabled() {
+  return true;
+}
+
 absl::optional<service_manager::Manifest>
 CastContentBrowserClient::GetServiceManifestOverlay(
     base::StringPiece service_name) {
@@ -998,7 +1002,7 @@
           GetCmaBackendFactory(), std::move(media_task_runner),
           GetVideoModeSwitcher(), GetVideoResolutionPolicy(),
           base::UnguessableToken::Create(), nullptr /* frame_interfaces */,
-          browser_main_parts()->connector()),
+          browser_main_parts()->connector(), true /* is_buffering_enabled */),
       std::move(receiver));
 }
 
diff --git a/chromecast/browser/cast_content_browser_client.h b/chromecast/browser/cast_content_browser_client.h
index f4bf309..5e7469c 100644
--- a/chromecast/browser/cast_content_browser_client.h
+++ b/chromecast/browser/cast_content_browser_client.h
@@ -306,6 +306,10 @@
                                bool* mixer_audio_enabled,
                                content::RenderFrameHost* render_frame_host);
 
+  // Returns whether buffering should be used for the CMA Pipeline created for
+  // this runtime instance. May be called from any thread.
+  virtual bool IsBufferingEnabled();
+
  private:
   // Create device cert/key
   virtual scoped_refptr<net::X509Certificate> DeviceCert();
diff --git a/chromecast/browser/cast_content_browser_client_receiver_bindings.cc b/chromecast/browser/cast_content_browser_client_receiver_bindings.cc
index 276ef5b..25837f4 100644
--- a/chromecast/browser/cast_content_browser_client_receiver_bindings.cc
+++ b/chromecast/browser/cast_content_browser_client_receiver_bindings.cc
@@ -169,12 +169,17 @@
   if (!video_geometry_setter_service_) {
     CreateVideoGeometrySetterServiceOnMediaThread();
   }
+
+  // Using base::Unretained is safe here because this class will persist for
+  // the duration of the browser process' lifetime.
   auto mojo_media_client = std::make_unique<media::CastMojoMediaClient>(
       GetCmaBackendFactory(),
       base::BindRepeating(&CastContentBrowserClient::CreateCdmFactory,
                           base::Unretained(this)),
       GetVideoModeSwitcher(), GetVideoResolutionPolicy(),
-      browser_main_parts()->media_connector());
+      browser_main_parts()->media_connector(),
+      base::BindRepeating(&CastContentBrowserClient::IsBufferingEnabled,
+                          base::Unretained(this)));
   mojo_media_client->SetVideoGeometrySetterService(
       video_geometry_setter_service_.get());
 
diff --git a/chromecast/cast_core/runtime/browser/BUILD.gn b/chromecast/cast_core/runtime/browser/BUILD.gn
index a185e89..ff48340 100644
--- a/chromecast/cast_core/runtime/browser/BUILD.gn
+++ b/chromecast/cast_core/runtime/browser/BUILD.gn
@@ -171,6 +171,13 @@
   ]
 }
 
+cast_source_set("runtime_application_watcher") {
+  sources = [
+    "runtime_application_watcher.cc",
+    "runtime_application_watcher.h",
+  ]
+}
+
 cast_source_set("runtime_application_dispatcher") {
   sources = [
     "runtime_application_base.cc",
@@ -188,6 +195,7 @@
     ":grpc_webui",
     ":metrics_recorder",
     ":runtime_application",
+    ":runtime_application_watcher",
     "//base",
     "//chromecast/browser:browser_base",
     "//chromecast/cast_core/runtime/browser/grpc",
@@ -243,6 +251,7 @@
 
   deps = [
     ":cast_runtime_service",
+    ":runtime_application_watcher",
     "//base",
     "//chromecast/cast_core/runtime/common:cors_exempt_headers",
     "//components/url_rewrite/browser",
diff --git a/chromecast/cast_core/runtime/browser/cast_runtime_content_browser_client.cc b/chromecast/cast_core/runtime/browser/cast_runtime_content_browser_client.cc
index c034c1a..dd585d7 100644
--- a/chromecast/cast_core/runtime/browser/cast_runtime_content_browser_client.cc
+++ b/chromecast/cast_core/runtime/browser/cast_runtime_content_browser_client.cc
@@ -46,7 +46,8 @@
       },
       this);
   auto cast_runtime_service = std::make_unique<CastRuntimeService>(
-      web_service, std::move(network_context_getter), video_plane_controller);
+      web_service, std::move(network_context_getter), video_plane_controller,
+      this);
   cast_runtime_service_ = cast_runtime_service.get();
   return cast_runtime_service;
 }
@@ -111,14 +112,10 @@
 std::unique_ptr<blink::URLLoaderThrottle>
 CastRuntimeContentBrowserClient::CreateUrlRewriteRulesThrottle(
     content::WebContents* web_contents) {
-  CastRuntimeService* cast_runtime_service = GetCastRuntimeService();
-  DCHECK(cast_runtime_service);
-
-  RuntimeApplication* app = cast_runtime_service->GetRuntimeApplication();
-  DCHECK(app);
+  DCHECK(runtime_application_);
 
   url_rewrite::UrlRequestRewriteRulesManager* url_rewrite_rules_manager =
-      app->GetUrlRewriteRulesManager();
+      runtime_application_->GetUrlRewriteRulesManager();
   DCHECK(url_rewrite_rules_manager);
 
   const auto& rules = url_rewrite_rules_manager->GetCachedRules();
@@ -131,4 +128,15 @@
       rules, base::BindRepeating(&IsHeaderCorsExempt));
 }
 
+bool CastRuntimeContentBrowserClient::IsBufferingEnabled() {
+  return !is_runtime_application_for_streaming_.load();
+}
+
+void CastRuntimeContentBrowserClient::OnRuntimeApplicationChanged(
+    RuntimeApplication* application) {
+  runtime_application_ = application;
+  is_runtime_application_for_streaming_.store(
+      runtime_application_ && runtime_application_->IsStreamingApplication());
+}
+
 }  // namespace chromecast
diff --git a/chromecast/cast_core/runtime/browser/cast_runtime_content_browser_client.h b/chromecast/cast_core/runtime/browser/cast_runtime_content_browser_client.h
index d966d4c..a285ec7 100644
--- a/chromecast/cast_core/runtime/browser/cast_runtime_content_browser_client.h
+++ b/chromecast/cast_core/runtime/browser/cast_runtime_content_browser_client.h
@@ -5,14 +5,19 @@
 #ifndef CHROMECAST_CAST_CORE_RUNTIME_BROWSER_CAST_RUNTIME_CONTENT_BROWSER_CLIENT_H_
 #define CHROMECAST_CAST_CORE_RUNTIME_BROWSER_CAST_RUNTIME_CONTENT_BROWSER_CLIENT_H_
 
+#include <atomic>
+
 #include "chromecast/browser/cast_content_browser_client.h"
+#include "chromecast/cast_core/runtime/browser/runtime_application_watcher.h"
 
 namespace chromecast {
 
 class CastRuntimeService;
 class CastFeatureListCreator;
+class RuntimeApplication;
 
-class CastRuntimeContentBrowserClient : public shell::CastContentBrowserClient {
+class CastRuntimeContentBrowserClient : public shell::CastContentBrowserClient,
+                                        public RuntimeApplicationWatcher {
  public:
   static std::unique_ptr<CastRuntimeContentBrowserClient> Create(
       CastFeatureListCreator* feature_list_creator);
@@ -49,11 +54,23 @@
       const base::RepeatingCallback<content::WebContents*()>& wc_getter,
       content::NavigationUIData* navigation_ui_data,
       int frame_tree_node_id) override;
+  bool IsBufferingEnabled() override;
 
  private:
+  // RuntimeApplicationWatcher overrides:
+  void OnRuntimeApplicationChanged(RuntimeApplication* application) override;
+
   std::unique_ptr<blink::URLLoaderThrottle> CreateUrlRewriteRulesThrottle(
       content::WebContents* web_contents);
 
+  // The current application running in this runtime, or nullptr if no such app
+  // exists
+  RuntimeApplication* runtime_application_ = nullptr;
+
+  // Tracks whether the current application is a streaming application, for the
+  // purposes of disabling buffering.
+  std::atomic_bool is_runtime_application_for_streaming_{false};
+
   // An instance of |CastRuntimeService| created once during the lifetime of the
   // runtime.
   CastRuntimeService* cast_runtime_service_ = nullptr;
diff --git a/chromecast/cast_core/runtime/browser/cast_runtime_service.cc b/chromecast/cast_core/runtime/browser/cast_runtime_service.cc
index c15972fe..abb6aa5 100644
--- a/chromecast/cast_core/runtime/browser/cast_runtime_service.cc
+++ b/chromecast/cast_core/runtime/browser/cast_runtime_service.cc
@@ -20,12 +20,14 @@
 CastRuntimeService::CastRuntimeService(
     CastWebService* web_service,
     NetworkContextGetter network_context_getter,
-    media::VideoPlaneController* video_plane_controller)
+    media::VideoPlaneController* video_plane_controller,
+    RuntimeApplicationWatcher* application_watcher)
     : video_plane_controller_(video_plane_controller),
       app_dispatcher_(web_service,
                       this,
                       std::move(network_context_getter),
-                      video_plane_controller_) {
+                      video_plane_controller_,
+                      application_watcher) {
   DCHECK(video_plane_controller_);
 }
 
@@ -66,8 +68,4 @@
   return nullptr;
 }
 
-RuntimeApplication* CastRuntimeService::GetRuntimeApplication() {
-  return app_dispatcher_.GetRuntimeApplication();
-}
-
 }  // namespace chromecast
diff --git a/chromecast/cast_core/runtime/browser/cast_runtime_service.h b/chromecast/cast_core/runtime/browser/cast_runtime_service.h
index e16257d..7b7f1bb 100644
--- a/chromecast/cast_core/runtime/browser/cast_runtime_service.h
+++ b/chromecast/cast_core/runtime/browser/cast_runtime_service.h
@@ -24,7 +24,7 @@
 
 class CastWebService;
 class WebCryptoServer;
-class RuntimeApplication;
+class RuntimeApplicationWatcher;
 
 namespace receiver {
 class MediaManager;
@@ -47,7 +47,8 @@
 
   CastRuntimeService(CastWebService* web_service,
                      NetworkContextGetter network_context_getter,
-                     media::VideoPlaneController* video_plane_controller);
+                     media::VideoPlaneController* video_plane_controller,
+                     RuntimeApplicationWatcher* application_watcher);
   ~CastRuntimeService() override;
 
   // Returns WebCryptoServer.
@@ -56,9 +57,6 @@
   // Returns MediaManager.
   virtual receiver::MediaManager* GetMediaManager();
 
-  // Returns a pointer to RuntimeApplication.
-  virtual RuntimeApplication* GetRuntimeApplication();
-
  protected:
   // CastService implementation:
   void InitializeInternal() override;
diff --git a/chromecast/cast_core/runtime/browser/runtime_application.h b/chromecast/cast_core/runtime/browser/runtime_application.h
index 6193e73..f032bf65e 100644
--- a/chromecast/cast_core/runtime/browser/runtime_application.h
+++ b/chromecast/cast_core/runtime/browser/runtime_application.h
@@ -59,6 +59,9 @@
   virtual bool Launch(
       const cast::runtime::LaunchApplicationRequest& request) = 0;
 
+  // Returns whether this instance is associated with cast streaming.
+  virtual bool IsStreamingApplication() const = 0;
+
  protected:
   void set_application_config(cast::common::ApplicationConfig app_config) {
     app_config_ = std::move(app_config);
diff --git a/chromecast/cast_core/runtime/browser/runtime_application_base.cc b/chromecast/cast_core/runtime/browser/runtime_application_base.cc
index 0e79ac90..11a8530 100644
--- a/chromecast/cast_core/runtime/browser/runtime_application_base.cc
+++ b/chromecast/cast_core/runtime/browser/runtime_application_base.cc
@@ -16,6 +16,7 @@
 namespace chromecast {
 
 RuntimeApplicationBase::RuntimeApplicationBase(
+    cast::common::ApplicationConfig app_config,
     mojom::RendererType renderer_type_used,
     CastWebService* web_service,
     scoped_refptr<base::SequencedTaskRunner> task_runner)
@@ -25,6 +26,8 @@
       renderer_type_(renderer_type_used) {
   DCHECK(web_service_);
   DCHECK(task_runner_);
+
+  set_application_config(std::move(app_config));
 }
 
 RuntimeApplicationBase::~RuntimeApplicationBase() {
diff --git a/chromecast/cast_core/runtime/browser/runtime_application_base.h b/chromecast/cast_core/runtime/browser/runtime_application_base.h
index 6687ca1c..60607d4b 100644
--- a/chromecast/cast_core/runtime/browser/runtime_application_base.h
+++ b/chromecast/cast_core/runtime/browser/runtime_application_base.h
@@ -36,7 +36,8 @@
   using CoreApplicationServiceGrpc = cast::v2::CoreApplicationService::Stub;
 
   // |web_service| is expected to exist for the lifetime of this instance.
-  RuntimeApplicationBase(mojom::RendererType renderer_type_used,
+  RuntimeApplicationBase(cast::common::ApplicationConfig app_config,
+                         mojom::RendererType renderer_type_used,
                          CastWebService* web_service,
                          scoped_refptr<base::SequencedTaskRunner> task_runner);
 
diff --git a/chromecast/cast_core/runtime/browser/runtime_application_dispatcher.cc b/chromecast/cast_core/runtime/browser/runtime_application_dispatcher.cc
index 79e4ace..ac0b90a 100644
--- a/chromecast/cast_core/runtime/browser/runtime_application_dispatcher.cc
+++ b/chromecast/cast_core/runtime/browser/runtime_application_dispatcher.cc
@@ -9,6 +9,7 @@
 #include "base/time/time.h"
 #include "chromecast/browser/cast_content_window.h"
 #include "chromecast/browser/cast_web_service.h"
+#include "chromecast/cast_core/runtime/browser/runtime_application_watcher.h"
 #include "chromecast/cast_core/runtime/browser/streaming_runtime_application.h"
 #include "chromecast/cast_core/runtime/browser/web_runtime_application.h"
 #include "third_party/cast_core/public/src/proto/common/application_config.pb.h"
@@ -51,12 +52,14 @@
     CastWebService* web_service,
     CastRuntimeMetricsRecorder::EventBuilderFactory* event_builder_factory,
     cast_streaming::NetworkContextGetter network_context_getter,
-    media::VideoPlaneController* video_plane_controller)
+    media::VideoPlaneController* video_plane_controller,
+    RuntimeApplicationWatcher* application_watcher)
     : GrpcServer(base::SequencedTaskRunnerHandle::Get()),
       web_service_(web_service),
       network_context_getter_(std::move(network_context_getter)),
       metrics_recorder_(event_builder_factory),
-      video_plane_controller_(video_plane_controller) {
+      video_plane_controller_(video_plane_controller),
+      application_watcher_(application_watcher) {
   DCHECK(web_service_);
   DCHECK(video_plane_controller_);
 }
@@ -90,7 +93,7 @@
 }
 
 void RuntimeApplicationDispatcher::Stop() {
-  app_.reset();
+  ResetApp();
 
   if (heartbeat_) {
     heartbeat_->Finish(grpc::Status::CANCELLED);
@@ -118,26 +121,11 @@
     const cast::runtime::LoadApplicationRequest& request,
     cast::runtime::LoadApplicationResponse* response,
     GrpcMethod* callback) {
-  const std::string& app_id = request.application_config().app_id();
-
-  if (openscreen::cast::IsCastStreamingReceiverAppId(app_id)) {
-    // Deliberately copy |network_context_getter_|.
-    app_ = std::make_unique<StreamingRuntimeApplication>(
-        web_service_, task_runner_, network_context_getter_,
-        video_plane_controller_);
-  } else {
-    app_ = std::make_unique<WebRuntimeApplication>(web_service_, task_runner_);
-  }
-  if (!app_->Load(request)) {
-    app_.reset();
+  if (!request.has_application_config()) {
     std::stringstream err_stream;
     err_stream
-        << "failed to load RuntimeApplication (session id: "
-        << request.cast_session_id() << ", app id: "
-        << (request.has_application_config()
-                ? request.application_config().app_id()
-                : "NONE")
-        << ", grpc endpoint: "
+        << "Invalid LoadApplication call (session id: "
+        << request.cast_session_id() << ", grpc endpoint: "
         << (request.has_runtime_application_service_info()
                 ? request.runtime_application_service_info().grpc_endpoint()
                 : "NONE")
@@ -145,6 +133,36 @@
     callback->StepGRPC(grpc::Status(grpc::INTERNAL, err_stream.str()));
     return;
   }
+
+  const std::string& app_id = request.application_config().app_id();
+  if (openscreen::cast::IsCastStreamingReceiverAppId(app_id)) {
+    // Deliberately copy |network_context_getter_|.
+    app_ = std::make_unique<StreamingRuntimeApplication>(
+        request.application_config(), web_service_, task_runner_,
+        network_context_getter_, video_plane_controller_);
+  } else {
+    app_ = std::make_unique<WebRuntimeApplication>(request.application_config(),
+                                                   web_service_, task_runner_);
+  }
+
+  if (application_watcher_) {
+    application_watcher_->OnRuntimeApplicationChanged(app_.get());
+  }
+
+  if (!app_->Load(request)) {
+    std::stringstream err_stream;
+    err_stream
+        << "failed to load RuntimeApplication (session id: "
+        << request.cast_session_id()
+        << ", app id: " << app_->app_config().app_id() << ", grpc endpoint: "
+        << (request.has_runtime_application_service_info()
+                ? request.runtime_application_service_info().grpc_endpoint()
+                : "NONE")
+        << ")";
+    ResetApp();
+    callback->StepGRPC(grpc::Status(grpc::INTERNAL, err_stream.str()));
+    return;
+  }
   cast::runtime::MessagePortInfo info;
   *response->mutable_message_port_info() = info;
   DCHECK(response->has_message_port_info());
@@ -165,7 +183,7 @@
                        ? request.cast_media_service_info().grpc_endpoint()
                        : "NONE")
                << ")";
-    app_.reset();
+    ResetApp();
     callback->StepGRPC(grpc::Status(grpc::INTERNAL, err_stream.str()));
     return;
   }
@@ -178,7 +196,7 @@
     GrpcMethod* callback) {
   response->set_app_id(app_->app_config().app_id());
   response->set_cast_session_id(app_->cast_session_id());
-  app_.reset();
+  ResetApp();
   callback->StepGRPC(grpc::Status::OK);
 }
 
@@ -258,6 +276,13 @@
   callback->StepGRPC(grpc::Status::OK);
 }
 
+void RuntimeApplicationDispatcher::ResetApp() {
+  app_.reset();
+  if (application_watcher_) {
+    application_watcher_->OnRuntimeApplicationChanged(nullptr);
+  }
+}
+
 const std::string&
 RuntimeApplicationDispatcher::GetCastMediaServiceGrpcEndpoint() const {
   return app_->cast_media_service_grpc_endpoint();
diff --git a/chromecast/cast_core/runtime/browser/runtime_application_dispatcher.h b/chromecast/cast_core/runtime/browser/runtime_application_dispatcher.h
index 2b6c228a..2069588 100644
--- a/chromecast/cast_core/runtime/browser/runtime_application_dispatcher.h
+++ b/chromecast/cast_core/runtime/browser/runtime_application_dispatcher.h
@@ -27,6 +27,7 @@
 
 class CastWebService;
 class RuntimeApplication;
+class RuntimeApplicationWatcher;
 
 class RuntimeApplicationDispatcher final : public GrpcServer,
                                            public RuntimeServiceDelegate,
@@ -36,7 +37,8 @@
       CastWebService* web_service,
       CastRuntimeMetricsRecorder::EventBuilderFactory* event_builder_factory,
       cast_streaming::NetworkContextGetter network_context_getter,
-      media::VideoPlaneController* video_plane_controller);
+      media::VideoPlaneController* video_plane_controller,
+      RuntimeApplicationWatcher* application_watcher);
   ~RuntimeApplicationDispatcher() override;
 
   // Starts and stops the runtime service, including the gRPC completion queue.
@@ -97,6 +99,7 @@
   void SendHeartbeat();
   void OnRecordComplete();
   void OnMetricsRecorderServiceStopped(GrpcMethod* callback);
+  void ResetApp();
 
   // MetricsRecorderGrpc implementation:
   void Record(const cast::metrics::RecordRequest& request) override;
@@ -125,6 +128,7 @@
   std::unique_ptr<CastRuntimeMetricsRecorderService> metrics_recorder_service_;
 
   media::VideoPlaneController* video_plane_controller_;
+  RuntimeApplicationWatcher* application_watcher_;
 
   base::WeakPtrFactory<RuntimeApplicationDispatcher> weak_factory_{this};
 };
diff --git a/chromecast/cast_core/runtime/browser/runtime_application_watcher.cc b/chromecast/cast_core/runtime/browser/runtime_application_watcher.cc
new file mode 100644
index 0000000..ef01faf
--- /dev/null
+++ b/chromecast/cast_core/runtime/browser/runtime_application_watcher.cc
@@ -0,0 +1,11 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromecast/cast_core/runtime/browser/runtime_application_watcher.h"
+
+namespace chromecast {
+
+RuntimeApplicationWatcher::~RuntimeApplicationWatcher() = default;
+
+}  // namespace chromecast
diff --git a/chromecast/cast_core/runtime/browser/runtime_application_watcher.h b/chromecast/cast_core/runtime/browser/runtime_application_watcher.h
new file mode 100644
index 0000000..6dd2319
--- /dev/null
+++ b/chromecast/cast_core/runtime/browser/runtime_application_watcher.h
@@ -0,0 +1,25 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMECAST_CAST_CORE_RUNTIME_BROWSER_RUNTIME_APPLICATION_WATCHER_H_
+#define CHROMECAST_CAST_CORE_RUNTIME_BROWSER_RUNTIME_APPLICATION_WATCHER_H_
+
+namespace chromecast {
+
+class RuntimeApplication;
+
+// This class is responsible for providing a callback when the current runtime
+// application changes.
+class RuntimeApplicationWatcher {
+ public:
+  virtual ~RuntimeApplicationWatcher();
+
+  // Called when the current runtime application changes, with |application|
+  // being a pointer to this instance or nullptr if no such instance exists.
+  virtual void OnRuntimeApplicationChanged(RuntimeApplication* application) = 0;
+};
+
+}  // namespace chromecast
+
+#endif  // CHROMECAST_CAST_CORE_RUNTIME_BROWSER_RUNTIME_APPLICATION_WATCHER_H_
diff --git a/chromecast/cast_core/runtime/browser/streaming_runtime_application.cc b/chromecast/cast_core/runtime/browser/streaming_runtime_application.cc
index 7cb67ec..9870f19 100644
--- a/chromecast/cast_core/runtime/browser/streaming_runtime_application.cc
+++ b/chromecast/cast_core/runtime/browser/streaming_runtime_application.cc
@@ -32,11 +32,13 @@
 }  // namespace
 
 StreamingRuntimeApplication::StreamingRuntimeApplication(
+    cast::common::ApplicationConfig app_config,
     CastWebService* web_service,
     scoped_refptr<base::SequencedTaskRunner> task_runner,
     cast_streaming::NetworkContextGetter network_context_getter,
     media::VideoPlaneController* video_plane_controller)
-    : RuntimeApplicationBase(mojom::RendererType::MOJO_RENDERER,
+    : RuntimeApplicationBase(std::move(app_config),
+                             mojom::RendererType::MOJO_RENDERER,
                              web_service,
                              std::move(task_runner)),
       video_plane_controller_(video_plane_controller),
@@ -126,6 +128,10 @@
   message_port_service_.reset();
 }
 
+bool StreamingRuntimeApplication::IsStreamingApplication() const {
+  return true;
+}
+
 void StreamingRuntimeApplication::MainFrameReadyToCommitNavigation(
     content::NavigationHandle* navigation_handle) {
   DLOG(INFO)
diff --git a/chromecast/cast_core/runtime/browser/streaming_runtime_application.h b/chromecast/cast_core/runtime/browser/streaming_runtime_application.h
index 6150cd7..3fffdbb1 100644
--- a/chromecast/cast_core/runtime/browser/streaming_runtime_application.h
+++ b/chromecast/cast_core/runtime/browser/streaming_runtime_application.h
@@ -29,6 +29,7 @@
  public:
   // |web_service| is expected to exist for the lifetime of this instance.
   StreamingRuntimeApplication(
+      cast::common::ApplicationConfig app_config,
       CastWebService* web_service,
       scoped_refptr<base::SequencedTaskRunner> task_runner,
       cast_streaming::NetworkContextGetter network_context_getter,
@@ -42,6 +43,7 @@
   void InitializeApplication(CoreApplicationServiceGrpc* grpc_stub,
                              CastWebContents* cast_web_contents) override;
   void StopApplication() override;
+  bool IsStreamingApplication() const override;
 
   // StreamingReceiverSessionClient::Handler implementation:
   void OnStreamingSessionStarted() override;
diff --git a/chromecast/cast_core/runtime/browser/web_runtime_application.cc b/chromecast/cast_core/runtime/browser/web_runtime_application.cc
index 4dac76b..07d33a1 100644
--- a/chromecast/cast_core/runtime/browser/web_runtime_application.cc
+++ b/chromecast/cast_core/runtime/browser/web_runtime_application.cc
@@ -15,9 +15,11 @@
 namespace chromecast {
 
 WebRuntimeApplication::WebRuntimeApplication(
+    cast::common::ApplicationConfig app_config,
     CastWebService* web_service,
     scoped_refptr<base::SequencedTaskRunner> task_runner)
-    : RuntimeApplicationBase(mojom::RendererType::MOJO_RENDERER,
+    : RuntimeApplicationBase(std::move(app_config),
+                             mojom::RendererType::MOJO_RENDERER,
                              web_service,
                              std::move(task_runner)) {}
 
@@ -65,6 +67,10 @@
   SetApplicationStarted();
 }
 
+bool WebRuntimeApplication::IsStreamingApplication() const {
+  return true;
+}
+
 void WebRuntimeApplication::InnerContentsCreated(
     CastWebContents* inner_contents,
     CastWebContents* outer_contents) {
diff --git a/chromecast/cast_core/runtime/browser/web_runtime_application.h b/chromecast/cast_core/runtime/browser/web_runtime_application.h
index 06ebc61..c331816 100644
--- a/chromecast/cast_core/runtime/browser/web_runtime_application.h
+++ b/chromecast/cast_core/runtime/browser/web_runtime_application.h
@@ -17,7 +17,8 @@
                                     public CastWebContents::Observer {
  public:
   // |web_service| is expected to exist for the lifetime of this instance.
-  WebRuntimeApplication(CastWebService* web_service,
+  WebRuntimeApplication(cast::common::ApplicationConfig app_config,
+                        CastWebService* web_service,
                         scoped_refptr<base::SequencedTaskRunner> task_runner);
   ~WebRuntimeApplication() override;
 
@@ -27,6 +28,7 @@
                      cast::web::MessagePortStatus* response) override;
   void InitializeApplication(CoreApplicationServiceGrpc* grpc_stub,
                              CastWebContents* cast_web_contents) override;
+  bool IsStreamingApplication() const override;
 
   // CastWebContents::Observer implementation:
   void InnerContentsCreated(CastWebContents* inner_contents,
diff --git a/chromecast/media/cma/pipeline/audio_video_pipeline_impl_unittest.cc b/chromecast/media/cma/pipeline/audio_video_pipeline_impl_unittest.cc
index 2c9600ea..b741d65 100644
--- a/chromecast/media/cma/pipeline/audio_video_pipeline_impl_unittest.cc
+++ b/chromecast/media/cma/pipeline/audio_video_pipeline_impl_unittest.cc
@@ -132,7 +132,8 @@
                                   &last_push_pts_[STREAM_VIDEO]));
 
     media_pipeline_ = std::make_unique<MediaPipelineImpl>();
-    media_pipeline_->Initialize(kLoadTypeURL, std::move(backend));
+    media_pipeline_->Initialize(kLoadTypeURL, std::move(backend),
+                                /* is_buffering_enabled */ true);
 
     if (have_audio_) {
       ::media::AudioDecoderConfig audio_config(
diff --git a/chromecast/media/cma/pipeline/media_pipeline_impl.cc b/chromecast/media/cma/pipeline/media_pipeline_impl.cc
index a7b83c37a..8f45099 100644
--- a/chromecast/media/cma/pipeline/media_pipeline_impl.cc
+++ b/chromecast/media/cma/pipeline/media_pipeline_impl.cc
@@ -112,12 +112,14 @@
 
 void MediaPipelineImpl::Initialize(
     LoadType load_type,
-    std::unique_ptr<CmaBackend> media_pipeline_backend) {
+    std::unique_ptr<CmaBackend> media_pipeline_backend,
+    bool is_buffering_enabled) {
   LOG(INFO) << __FUNCTION__;
   DCHECK(thread_checker_.CalledOnValidThread());
   media_pipeline_backend_ = std::move(media_pipeline_backend);
 
-  if (load_type == kLoadTypeURL || load_type == kLoadTypeMediaSource) {
+  if ((load_type == kLoadTypeURL || load_type == kLoadTypeMediaSource) &&
+      is_buffering_enabled) {
     base::TimeDelta low_threshold(kLowBufferThresholdURL);
     base::TimeDelta high_threshold(kHighBufferThresholdURL);
     if (load_type == kLoadTypeMediaSource) {
diff --git a/chromecast/media/cma/pipeline/media_pipeline_impl.h b/chromecast/media/cma/pipeline/media_pipeline_impl.h
index 15f3a04..98263d2 100644
--- a/chromecast/media/cma/pipeline/media_pipeline_impl.h
+++ b/chromecast/media/cma/pipeline/media_pipeline_impl.h
@@ -45,7 +45,8 @@
   // Initialize the media pipeline: the pipeline is configured based on
   // |load_type|.
   void Initialize(LoadType load_type,
-                  std::unique_ptr<CmaBackend> media_pipeline_backend);
+                  std::unique_ptr<CmaBackend> media_pipeline_backend,
+                  bool is_buffering_enabled);
 
   void SetClient(MediaPipelineClient client);
   void SetCdm(const base::UnguessableToken* cdm_id);
diff --git a/chromecast/media/service/cast_mojo_media_client.cc b/chromecast/media/service/cast_mojo_media_client.cc
index a8419e41..e5c2d3e2 100644
--- a/chromecast/media/service/cast_mojo_media_client.cc
+++ b/chromecast/media/service/cast_mojo_media_client.cc
@@ -4,6 +4,8 @@
 
 #include "chromecast/media/service/cast_mojo_media_client.h"
 
+#include <utility>
+
 #include "chromecast/media/api/cma_backend_factory.h"
 #include "chromecast/media/service/cast_renderer.h"
 #include "chromecast/public/media/media_pipeline_backend.h"
@@ -19,12 +21,14 @@
     const CreateCdmFactoryCB& create_cdm_factory_cb,
     VideoModeSwitcher* video_mode_switcher,
     VideoResolutionPolicy* video_resolution_policy,
-    external_service_support::ExternalConnector* connector)
+    external_service_support::ExternalConnector* connector,
+    CastMojoMediaClient::EnableBufferingCB enable_buffering_cb)
     : backend_factory_(backend_factory),
       create_cdm_factory_cb_(create_cdm_factory_cb),
       video_mode_switcher_(video_mode_switcher),
       video_resolution_policy_(video_resolution_policy),
-      connector_(connector) {
+      connector_(connector),
+      enable_buffering_cb_(std::move(enable_buffering_cb)) {
   DCHECK(backend_factory_);
   DCHECK(connector_);
 }
@@ -45,7 +49,8 @@
   DCHECK(video_geometry_setter_);
   auto cast_renderer = std::make_unique<CastRenderer>(
       backend_factory_, task_runner, video_mode_switcher_,
-      video_resolution_policy_, overlay_plane_id, frame_interfaces, connector_);
+      video_resolution_policy_, overlay_plane_id, frame_interfaces, connector_,
+      enable_buffering_cb_.Run());
   cast_renderer->SetVideoGeometrySetterService(video_geometry_setter_);
   return cast_renderer;
 }
diff --git a/chromecast/media/service/cast_mojo_media_client.h b/chromecast/media/service/cast_mojo_media_client.h
index b98de47b..b1c5186 100644
--- a/chromecast/media/service/cast_mojo_media_client.h
+++ b/chromecast/media/service/cast_mojo_media_client.h
@@ -26,12 +26,14 @@
   using CreateCdmFactoryCB =
       base::RepeatingCallback<std::unique_ptr<::media::CdmFactory>(
           ::media::mojom::FrameInterfaceFactory*)>;
+  using EnableBufferingCB = base::RepeatingCallback<bool()>;
 
   CastMojoMediaClient(CmaBackendFactory* backend_factory,
                       const CreateCdmFactoryCB& create_cdm_factory_cb,
                       VideoModeSwitcher* video_mode_switcher,
                       VideoResolutionPolicy* video_resolution_policy,
-                      external_service_support::ExternalConnector* connector);
+                      external_service_support::ExternalConnector* connector,
+                      EnableBufferingCB enable_buffering_cb);
 
   CastMojoMediaClient(const CastMojoMediaClient&) = delete;
   CastMojoMediaClient& operator=(const CastMojoMediaClient&) = delete;
@@ -65,6 +67,7 @@
   VideoModeSwitcher* video_mode_switcher_;
   VideoResolutionPolicy* video_resolution_policy_;
   external_service_support::ExternalConnector* const connector_;
+  const EnableBufferingCB enable_buffering_cb_;
 
 #if BUILDFLAG(ENABLE_CAST_RENDERER)
   VideoGeometrySetterService* video_geometry_setter_;
diff --git a/chromecast/media/service/cast_renderer.cc b/chromecast/media/service/cast_renderer.cc
index b58e6ff..087c471 100644
--- a/chromecast/media/service/cast_renderer.cc
+++ b/chromecast/media/service/cast_renderer.cc
@@ -61,7 +61,8 @@
     VideoResolutionPolicy* video_resolution_policy,
     const base::UnguessableToken& overlay_plane_id,
     ::media::mojom::FrameInterfaceFactory* frame_interfaces,
-    external_service_support::ExternalConnector* connector)
+    external_service_support::ExternalConnector* connector,
+    bool is_buffering_enabled)
     : backend_factory_(backend_factory),
       task_runner_(task_runner),
       video_mode_switcher_(video_mode_switcher),
@@ -74,6 +75,7 @@
       media_task_runner_factory_(
           new BalancedMediaTaskRunnerFactory(kMaxDeltaFetcher)),
       video_geometry_setter_service_(nullptr),
+      is_buffering_enabled_(is_buffering_enabled),
       weak_factory_(this) {
   DCHECK(backend_factory_);
   LOG(INFO) << __FUNCTION__ << ": " << this;
@@ -223,7 +225,7 @@
       &CastRenderer::OnBufferingStateChange, weak_factory_.GetWeakPtr());
   pipeline_.reset(new MediaPipelineImpl());
   pipeline_->SetClient(std::move(pipeline_client));
-  pipeline_->Initialize(load_type, std::move(backend));
+  pipeline_->Initialize(load_type, std::move(backend), is_buffering_enabled_);
 
   // TODO(servolk): Implement support for multiple streams. For now use the
   // first enabled audio and video streams to preserve the existing behavior.
diff --git a/chromecast/media/service/cast_renderer.h b/chromecast/media/service/cast_renderer.h
index b505ea2..a201388 100644
--- a/chromecast/media/service/cast_renderer.h
+++ b/chromecast/media/service/cast_renderer.h
@@ -51,7 +51,8 @@
                VideoResolutionPolicy* video_resolution_policy,
                const base::UnguessableToken& overlay_plane_id,
                ::media::mojom::FrameInterfaceFactory* frame_interfaces,
-               external_service_support::ExternalConnector* connector);
+               external_service_support::ExternalConnector* connector,
+               bool is_buffering_enabled);
 
   CastRenderer(const CastRenderer&) = delete;
   CastRenderer& operator=(const CastRenderer&) = delete;
@@ -150,6 +151,8 @@
 
   absl::optional<float> pending_volume_;
 
+  const bool is_buffering_enabled_;
+
   base::WeakPtrFactory<CastRenderer> weak_factory_;
 };
 
diff --git a/chromeos/dbus/cryptohome/BUILD.gn b/chromeos/dbus/cryptohome/BUILD.gn
index afa7d79..019e3ff 100644
--- a/chromeos/dbus/cryptohome/BUILD.gn
+++ b/chromeos/dbus/cryptohome/BUILD.gn
@@ -41,10 +41,3 @@
 
   proto_out_dir = "chromeos/dbus/cryptohome"
 }
-
-proto_library("cryptohome_signkey_proto") {
-  sources =
-      [ "//third_party/cros_system_api/dbus/cryptohome/signed_secret.proto" ]
-
-  proto_out_dir = "chromeos/dbus/cryptohome"
-}
diff --git a/chromeos/profiles/atom.afdo.newest.txt b/chromeos/profiles/atom.afdo.newest.txt
index 0c78f62..8a1af8d8 100644
--- a/chromeos/profiles/atom.afdo.newest.txt
+++ b/chromeos/profiles/atom.afdo.newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-atom-99-4815.0-1642417637-benchmark-99.0.4835.0-r1-redacted.afdo.xz
+chromeos-chrome-amd64-atom-99-4815.0-1642417637-benchmark-99.0.4837.0-r1-redacted.afdo.xz
diff --git a/chromeos/profiles/bigcore.afdo.newest.txt b/chromeos/profiles/bigcore.afdo.newest.txt
index 3a3c771..f397e67 100644
--- a/chromeos/profiles/bigcore.afdo.newest.txt
+++ b/chromeos/profiles/bigcore.afdo.newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-bigcore-99-4815.0-1642415760-benchmark-99.0.4835.0-r1-redacted.afdo.xz
+chromeos-chrome-amd64-bigcore-99-4815.0-1642415760-benchmark-99.0.4837.0-r1-redacted.afdo.xz
diff --git a/chromeos/services/bluetooth_config/bluetooth_power_controller_impl.cc b/chromeos/services/bluetooth_config/bluetooth_power_controller_impl.cc
index caf92bed..b4b384c 100644
--- a/chromeos/services/bluetooth_config/bluetooth_power_controller_impl.cc
+++ b/chromeos/services/bluetooth_config/bluetooth_power_controller_impl.cc
@@ -123,13 +123,12 @@
 void BluetoothPowerControllerImpl::ApplyBluetoothLocalStatePref() {
   if (local_state_->FindPreference(prefs::kSystemBluetoothAdapterEnabled)
           ->IsDefaultValue()) {
-    // If the device has not had the local state Bluetooth pref, set the pref
-    // according to whatever the current Bluetooth power is.
-    BLUETOOTH_LOG(EVENT) << "Saving current power state of "
-                         << adapter_state_controller_->GetAdapterState()
-                         << " to local state.";
-    SaveCurrentPowerStateToPrefs(local_state_,
-                                 prefs::kSystemBluetoothAdapterEnabled);
+    // If the device has not had the local state Bluetooth pref set, this is a
+    // fresh install. On fresh installs, the Bluetooth adapter defaults to
+    // powered on. Save this state to prefs.
+    BLUETOOTH_LOG(EVENT) << "No local state pref has been set, saving"
+                         << "Bluetooth power state of enabled to local state";
+    local_state_->SetBoolean(ash::prefs::kSystemBluetoothAdapterEnabled, true);
     return;
   }
 
diff --git a/chromeos/services/bluetooth_config/bluetooth_power_controller_impl_unittest.cc b/chromeos/services/bluetooth_config/bluetooth_power_controller_impl_unittest.cc
index f5a079f..90937f8 100644
--- a/chromeos/services/bluetooth_config/bluetooth_power_controller_impl_unittest.cc
+++ b/chromeos/services/bluetooth_config/bluetooth_power_controller_impl_unittest.cc
@@ -118,40 +118,40 @@
 
 // Tests toggling Bluetooth setting on and off.
 TEST_F(BluetoothPowerControllerImplTest, ToggleBluetoothEnabled) {
-  // Makes sure we start with Bluetooth power off.
-  SetBluetoothSystemState(mojom::BluetoothSystemState::kDisabled);
+  // Makes sure we start with Bluetooth power on.
+  SetBluetoothSystemState(mojom::BluetoothSystemState::kEnabled);
 
   Init();
 
-  EXPECT_FALSE(
-      local_state()->GetBoolean(prefs::kSystemBluetoothAdapterEnabled));
-  EXPECT_EQ(GetAdapterState(), mojom::BluetoothSystemState::kDisabled);
-
-  // Toggling Bluetooth on/off when there is no user session should affect
-  // local state prefs.
-  SetBluetoothEnabledState(true);
+  // By default, the local state gets set to enabled.
   EXPECT_TRUE(local_state()->GetBoolean(prefs::kSystemBluetoothAdapterEnabled));
+  EXPECT_EQ(GetAdapterState(), mojom::BluetoothSystemState::kEnabled);
+
+  // Toggling Bluetooth off/on when there is no user session should affect
+  // local state prefs.
   SetBluetoothEnabledState(false);
   EXPECT_FALSE(
       local_state()->GetBoolean(prefs::kSystemBluetoothAdapterEnabled));
+  SetBluetoothEnabledState(true);
+  EXPECT_TRUE(local_state()->GetBoolean(prefs::kSystemBluetoothAdapterEnabled));
 
-  // Toggling Bluetooth on/off when there is user session should affect
+  // Toggling Bluetooth off/on when there is user session should affect
   // user prefs.
   AddUserSession(kUser1Email);
+  EXPECT_TRUE(
+      active_user_prefs()->GetBoolean(prefs::kUserBluetoothAdapterEnabled));
+
+  SetBluetoothEnabledState(false);
   EXPECT_FALSE(
       active_user_prefs()->GetBoolean(prefs::kUserBluetoothAdapterEnabled));
 
+  // Local state prefs should remain unchanged.
+  EXPECT_TRUE(local_state()->GetBoolean(prefs::kSystemBluetoothAdapterEnabled));
+
   SetBluetoothEnabledState(true);
   EXPECT_TRUE(
       active_user_prefs()->GetBoolean(prefs::kUserBluetoothAdapterEnabled));
-
-  // Local state prefs should remain unchanged.
-  EXPECT_FALSE(
-      local_state()->GetBoolean(prefs::kSystemBluetoothAdapterEnabled));
-
-  SetBluetoothEnabledState(false);
-  EXPECT_FALSE(
-      active_user_prefs()->GetBoolean(prefs::kUserBluetoothAdapterEnabled));
+  EXPECT_TRUE(local_state()->GetBoolean(prefs::kSystemBluetoothAdapterEnabled));
 }
 
 // Tests how BluetoothPowerController applies the local state pref when
@@ -163,10 +163,6 @@
                   ->FindPreference(prefs::kSystemBluetoothAdapterEnabled)
                   ->IsDefaultValue());
 
-  // Start with Bluetooth power on.
-  SetBluetoothSystemState(mojom::BluetoothSystemState::kEnabled);
-  EXPECT_EQ(GetAdapterState(), mojom::BluetoothSystemState::kEnabled);
-
   Init();
 
   // Pref should now contain the current Bluetooth adapter state (on).
diff --git a/components/app_restore/app_restore_utils.cc b/components/app_restore/app_restore_utils.cc
index c471141..c5b6ccf 100644
--- a/components/app_restore/app_restore_utils.cc
+++ b/components/app_restore/app_restore_utils.cc
@@ -194,6 +194,13 @@
   return app_name.substr(prefix.length());
 }
 
+const std::string GetLacrosWindowId(aura::Window* window) {
+  const std::string* lacros_window_id =
+      window->GetProperty(app_restore::kLacrosWindowId);
+  DCHECK(lacros_window_id);
+  return *lacros_window_id;
+}
+
 void OnLacrosWindowAdded(aura::Window* const window,
                          uint32_t browser_session_id,
                          uint32_t restored_browser_session_id) {
diff --git a/components/app_restore/app_restore_utils.h b/components/app_restore/app_restore_utils.h
index e935a3e..1797870 100644
--- a/components/app_restore/app_restore_utils.h
+++ b/components/app_restore/app_restore_utils.h
@@ -64,6 +64,9 @@
 COMPONENT_EXPORT(APP_RESTORE)
 std::string GetAppIdFromAppName(const std::string& app_name);
 
+// Returns the Lacros window id for `window`.
+const std::string GetLacrosWindowId(aura::Window* window);
+
 // Invoked when Lacros window is created. `browser_session_id` is the
 // current browser session id. `restored_browser_session_id` is the restored
 // browser session id.
diff --git a/components/app_restore/arc_read_handler.cc b/components/app_restore/arc_read_handler.cc
index c8fa7f4..276f450a 100644
--- a/components/app_restore/arc_read_handler.cc
+++ b/components/app_restore/arc_read_handler.cc
@@ -215,7 +215,7 @@
   // Remove the window from the hidden container.
   if ((*window_it)->GetProperty(kParentToHiddenContainerKey)) {
     full_restore::FullRestoreInfo::GetInstance()
-        ->OnARCTaskReadyForUnparentedWindow(*window_it);
+        ->OnParentWindowToValidContainer(*window_it);
   }
 
   arc_window_candidates_.erase(*window_it);
diff --git a/components/app_restore/full_restore_info.cc b/components/app_restore/full_restore_info.cc
index ce2c5e4..0a449a57 100644
--- a/components/app_restore/full_restore_info.cc
+++ b/components/app_restore/full_restore_info.cc
@@ -79,9 +79,9 @@
     observer.OnWidgetInitialized(widget);
 }
 
-void FullRestoreInfo::OnARCTaskReadyForUnparentedWindow(aura::Window* window) {
+void FullRestoreInfo::OnParentWindowToValidContainer(aura::Window* window) {
   for (auto& observer : observers_)
-    observer.OnARCTaskReadyForUnparentedWindow(window);
+    observer.OnParentWindowToValidContainer(window);
 }
 
 }  // namespace full_restore
diff --git a/components/app_restore/full_restore_info.h b/components/app_restore/full_restore_info.h
index d53f0d9..051fccd 100644
--- a/components/app_restore/full_restore_info.h
+++ b/components/app_restore/full_restore_info.h
@@ -64,10 +64,14 @@
     // ARC task also may not be created yet at this point.
     virtual void OnWidgetInitialized(views::Widget* widget) {}
 
-    // Called once a window which was created without an associated task is now
-    // associated with a ARC task. Will not be called for non-ARC windows, or
-    // ARC windows created with an associated task.
-    virtual void OnARCTaskReadyForUnparentedWindow(aura::Window* window) {}
+    // Called when `window` is ready to be parented to a valid desk container.
+    //
+    // For Lacros windows, called when `window` is associated with a Lacros
+    // window id.
+    //
+    // For ARC app windows, called once a window which was created without an
+    // associated task is now associated with a ARC task.
+    virtual void OnParentWindowToValidContainer(aura::Window* window) {}
 
    protected:
     ~Observer() override = default;
@@ -112,9 +116,9 @@
   // Notifies observers that |widget| has been initialized.
   void OnWidgetInitialized(views::Widget* widget);
 
-  // Notifies observers that `window`, which previously had no associated task,
-  // now has one.
-  void OnARCTaskReadyForUnparentedWindow(aura::Window* window);
+  // Notifies observers that `window` is ready to be parented to a valid desk
+  // container..
+  void OnParentWindowToValidContainer(aura::Window* window);
 
  private:
   base::ObserverList<Observer> observers_;
diff --git a/components/app_restore/lacros_save_handler.cc b/components/app_restore/lacros_save_handler.cc
index d5e8abe..c58750903 100644
--- a/components/app_restore/lacros_save_handler.cc
+++ b/components/app_restore/lacros_save_handler.cc
@@ -5,32 +5,21 @@
 #include "components/app_restore/lacros_save_handler.h"
 
 #include "components/app_restore/app_launch_info.h"
+#include "components/app_restore/app_restore_utils.h"
 #include "components/app_restore/full_restore_save_handler.h"
 #include "components/app_restore/window_info.h"
-#include "components/app_restore/window_properties.h"
 #include "extensions/common/constants.h"
 #include "ui/aura/window.h"
 
 namespace full_restore {
 
-namespace {
-
-const std::string GetLacrosWindowId(aura::Window* window) {
-  const std::string* lacros_window_id =
-      window->GetProperty(app_restore::kLacrosWindowId);
-  DCHECK(lacros_window_id);
-  return *lacros_window_id;
-}
-
-}  // namespace
-
 LacrosSaveHandler::LacrosSaveHandler(const base::FilePath& profile_path)
     : profile_path_(profile_path) {}
 
 LacrosSaveHandler::~LacrosSaveHandler() = default;
 
 void LacrosSaveHandler::OnWindowInitialized(aura::Window* window) {
-  const std::string lacros_window_id = GetLacrosWindowId(window);
+  const std::string lacros_window_id = app_restore::GetLacrosWindowId(window);
 
   // If `window` has been saved by OnBrowserWindowAdded, we don't need to save
   // again.
@@ -63,7 +52,7 @@
 }
 
 void LacrosSaveHandler::OnWindowDestroyed(aura::Window* window) {
-  const std::string lacros_window_id = GetLacrosWindowId(window);
+  const std::string lacros_window_id = app_restore::GetLacrosWindowId(window);
   lacros_window_id_to_app_id_.erase(lacros_window_id);
 
   auto it = window_candidates_.find(lacros_window_id);
@@ -78,7 +67,7 @@
 
 void LacrosSaveHandler::OnBrowserWindowAdded(aura::Window* const window,
                                              uint32_t browser_session_id) {
-  const std::string lacros_window_id = GetLacrosWindowId(window);
+  const std::string lacros_window_id = app_restore::GetLacrosWindowId(window);
   std::unique_ptr<app_restore::WindowInfo> window_info;
   auto* save_handler = FullRestoreSaveHandler::GetInstance();
   DCHECK(save_handler);
@@ -149,7 +138,8 @@
 
 void LacrosSaveHandler::ModifyWindowInfo(
     const app_restore::WindowInfo& window_info) {
-  auto it = window_candidates_.find(GetLacrosWindowId(window_info.window));
+  auto it = window_candidates_.find(
+      app_restore::GetLacrosWindowId(window_info.window));
   if (it != window_candidates_.end()) {
     FullRestoreSaveHandler::GetInstance()->ModifyWindowInfo(
         profile_path_, it->second.app_id, it->second.window_id, window_info);
@@ -157,7 +147,7 @@
 }
 
 std::string LacrosSaveHandler::GetAppId(aura::Window* window) {
-  auto it = window_candidates_.find(GetLacrosWindowId(window));
+  auto it = window_candidates_.find(app_restore::GetLacrosWindowId(window));
   return it != window_candidates_.end() ? it->second.app_id : std::string();
 }
 
diff --git a/components/certificate_transparency/chrome_ct_policy_enforcer.cc b/components/certificate_transparency/chrome_ct_policy_enforcer.cc
index e8e0ccff..de649f7 100644
--- a/components/certificate_transparency/chrome_ct_policy_enforcer.cc
+++ b/components/certificate_transparency/chrome_ct_policy_enforcer.cc
@@ -173,6 +173,9 @@
     return false;
   }
   *disqualification_date = base::Time::UnixEpoch() + p->second;
+  if (base::Time::Now() < *disqualification_date) {
+    return false;
+  }
   return true;
 }
 
diff --git a/components/certificate_transparency/chrome_ct_policy_enforcer.h b/components/certificate_transparency/chrome_ct_policy_enforcer.h
index 90e66dc..2a5ded6 100644
--- a/components/certificate_transparency/chrome_ct_policy_enforcer.h
+++ b/components/certificate_transparency/chrome_ct_policy_enforcer.h
@@ -11,6 +11,7 @@
 #include <vector>
 
 #include "base/component_export.h"
+#include "base/gtest_prod_util.h"
 #include "base/memory/raw_ptr.h"
 #include "base/time/clock.h"
 #include "base/time/time.h"
@@ -95,6 +96,10 @@
   }
 
  private:
+  FRIEND_TEST_ALL_PREFIXES(ChromeCTPolicyEnforcerTest,
+                           IsLogDisqualifiedTimestamp);
+  FRIEND_TEST_ALL_PREFIXES(ChromeCTPolicyEnforcerTest,
+                           IsLogDisqualifiedReturnsFalseOnUnknownLog);
   // Returns true if the log identified by |log_id| (the SHA-256 hash of the
   // log's DER-encoded SPKI) has been disqualified, and sets
   // |*disqualification_date| to the date of disqualification. Any SCTs that
diff --git a/components/certificate_transparency/chrome_ct_policy_enforcer_unittest.cc b/components/certificate_transparency/chrome_ct_policy_enforcer_unittest.cc
index 94bd7060..96a5560a 100644
--- a/components/certificate_transparency/chrome_ct_policy_enforcer_unittest.cc
+++ b/components/certificate_transparency/chrome_ct_policy_enforcer_unittest.cc
@@ -45,6 +45,8 @@
 static_assert(base::size(kGoogleAviatorLogID) - 1 == crypto::kSHA256Length,
               "Incorrect log ID length.");
 
+}  // namespace
+
 class ChromeCTPolicyEnforcerTest : public ::testing::Test {
  public:
   void SetUp() override {
@@ -540,6 +542,135 @@
                                                     NetLogWithSource()));
 }
 
+TEST_F(ChromeCTPolicyEnforcerTest, IsLogDisqualifiedTimestamp) {
+  ChromeCTPolicyEnforcer* chrome_policy_enforcer =
+      static_cast<ChromeCTPolicyEnforcer*>(policy_enforcer_.get());
+
+  // Clear the log list and add 2 disqualified logs, one with a disqualification
+  // date in the past and one in the future.
+  // The actual logs are irrelevant for this test, so we use Aviator for the one
+  // disqualified in the past, and a modified version of it for disqualified in
+  // the future.
+  const char kModifiedGoogleAviatorLogID[] =
+      "\x68\xf6\x98\xf8\x1f\x64\x82\xbe\x3a\x8c\xee\xb9\x28\x1d\x4c\xfc\x71\x51"
+      "\x5d\x67\x93\xd4\x44\xd1\x0a\x67\xac\xbb\x4f\x4f\x4f\xf4";
+  std::vector<std::pair<std::string, base::TimeDelta>> disqualified_logs;
+  std::vector<std::string> operated_by_google_logs;
+  std::map<std::string, OperatorHistoryEntry> log_operator_history;
+  base::Time past_disqualification = base::Time::Now() - base::Hours(1);
+  base::Time future_disqualification = base::Time::Now() + base::Hours(1);
+  disqualified_logs.emplace_back(
+      kModifiedGoogleAviatorLogID,
+      future_disqualification - base::Time::UnixEpoch());
+  disqualified_logs.emplace_back(
+      kGoogleAviatorLogID, past_disqualification - base::Time::UnixEpoch());
+  chrome_policy_enforcer->UpdateCTLogList(base::Time::Now(), disqualified_logs,
+                                          operated_by_google_logs,
+                                          log_operator_history);
+
+  base::Time disqualification_time;
+  EXPECT_TRUE(chrome_policy_enforcer->IsLogDisqualified(
+      kGoogleAviatorLogID, &disqualification_time));
+  EXPECT_EQ(disqualification_time, past_disqualification);
+  EXPECT_FALSE(chrome_policy_enforcer->IsLogDisqualified(
+      kModifiedGoogleAviatorLogID, &disqualification_time));
+  EXPECT_EQ(disqualification_time, future_disqualification);
+}
+
+TEST_F(ChromeCTPolicyEnforcerTest, IsLogDisqualifiedReturnsFalseOnUnknownLog) {
+  ChromeCTPolicyEnforcer* chrome_policy_enforcer =
+      static_cast<ChromeCTPolicyEnforcer*>(policy_enforcer_.get());
+
+  // Clear the log list and add a single disqualified log, with a
+  // disqualification date in the past;
+  const char kModifiedGoogleAviatorLogID[] =
+      "\x68\xf6\x98\xf8\x1f\x64\x82\xbe\x3a\x8c\xee\xb9\x28\x1d\x4c\xfc\x71\x51"
+      "\x5d\x67\x93\xd4\x44\xd1\x0a\x67\xac\xbb\x4f\x4f\x4f\xf4";
+  std::vector<std::pair<std::string, base::TimeDelta>> disqualified_logs;
+  std::vector<std::string> operated_by_google_logs;
+  std::map<std::string, OperatorHistoryEntry> log_operator_history;
+  disqualified_logs.emplace_back(
+      kModifiedGoogleAviatorLogID,
+      base::Time::Now() - base::Days(1) - base::Time::UnixEpoch());
+  chrome_policy_enforcer->UpdateCTLogList(base::Time::Now(), disqualified_logs,
+                                          operated_by_google_logs,
+                                          log_operator_history);
+
+  base::Time unused;
+  // IsLogDisqualified should return false for a log that is not in the
+  // disqualified list.
+  EXPECT_FALSE(
+      chrome_policy_enforcer->IsLogDisqualified(kGoogleAviatorLogID, &unused));
+}
+
+TEST_F(ChromeCTPolicyEnforcerTest,
+       ConformsWithCTPolicyFutureRetirementDateLogs) {
+  ChromeCTPolicyEnforcer* chrome_policy_enforcer =
+      static_cast<ChromeCTPolicyEnforcer*>(policy_enforcer_.get());
+  SCTList scts;
+  FillListWithSCTsOfOrigin(SignedCertificateTimestamp::SCT_EMBEDDED, 5, &scts);
+
+  std::vector<std::pair<std::string, base::TimeDelta>> disqualified_logs;
+  std::vector<std::string> operated_by_google_logs = {google_log_id_};
+  std::map<std::string, OperatorHistoryEntry> log_operator_history;
+
+  // Set all the log operators for these SCTs as disqualiied, with a timestamp
+  // one hour from now.
+  base::TimeDelta retirement_time =
+      base::Time::Now() + base::Hours(1) - base::Time::UnixEpoch();
+  // This mirrors how FillListWithSCTsOfOrigin generates log ids.
+  disqualified_logs.emplace_back(google_log_id_, retirement_time);
+  for (size_t i = 1; i < 5; ++i) {
+    disqualified_logs.emplace_back(
+        std::string(crypto::kSHA256Length, static_cast<char>(i)),
+        retirement_time);
+  }
+  std::sort(std::begin(disqualified_logs), std::end(disqualified_logs));
+
+  chrome_policy_enforcer->UpdateCTLogList(base::Time::Now(), disqualified_logs,
+                                          operated_by_google_logs,
+                                          log_operator_history);
+
+  // SCTs should comply since retirement date is in the future.
+  EXPECT_EQ(CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS,
+            policy_enforcer_->CheckCompliance(chain_.get(), scts,
+                                              NetLogWithSource()));
+}
+
+TEST_F(ChromeCTPolicyEnforcerTest,
+       DoesNotConformWithCTPolicyPastRetirementDateLogs) {
+  ChromeCTPolicyEnforcer* chrome_policy_enforcer =
+      static_cast<ChromeCTPolicyEnforcer*>(policy_enforcer_.get());
+  SCTList scts;
+  FillListWithSCTsOfOrigin(SignedCertificateTimestamp::SCT_EMBEDDED, 5, &scts);
+
+  std::vector<std::pair<std::string, base::TimeDelta>> disqualified_logs;
+  std::vector<std::string> operated_by_google_logs = {google_log_id_};
+  std::map<std::string, OperatorHistoryEntry> log_operator_history;
+
+  // Set all the log operators for these SCTs as disqualiied, with a timestamp
+  // one hour ago.
+  base::TimeDelta retirement_time =
+      base::Time::Now() - base::Hours(1) - base::Time::UnixEpoch();
+  // This mirrors how FillListWithSCTsOfOrigin generates log ids.
+  disqualified_logs.emplace_back(google_log_id_, retirement_time);
+  for (size_t i = 1; i < 5; ++i) {
+    disqualified_logs.emplace_back(
+        std::string(crypto::kSHA256Length, static_cast<char>(i)),
+        retirement_time);
+  }
+  std::sort(std::begin(disqualified_logs), std::end(disqualified_logs));
+
+  chrome_policy_enforcer->UpdateCTLogList(base::Time::Now(), disqualified_logs,
+                                          operated_by_google_logs,
+                                          log_operator_history);
+
+  // SCTs should not comply since retirement date is in the past.
+  EXPECT_EQ(CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS,
+            policy_enforcer_->CheckCompliance(chain_.get(), scts,
+                                              NetLogWithSource()));
+}
+
 class ChromeCTPolicyEnforcerTest2022Policy : public ChromeCTPolicyEnforcerTest {
  public:
   void SetUp() override {
@@ -845,6 +976,4 @@
                                               NetLogWithSource()));
 }
 
-}  // namespace
-
 }  // namespace certificate_transparency
diff --git a/components/exo/client_controlled_shell_surface_unittest.cc b/components/exo/client_controlled_shell_surface_unittest.cc
index 2d599db..555ec873 100644
--- a/components/exo/client_controlled_shell_surface_unittest.cc
+++ b/components/exo/client_controlled_shell_surface_unittest.cc
@@ -2837,8 +2837,7 @@
 
   // Call the WindowRestoreController, simulating the ARC task becoming ready.
   // The surface should be reparented and the WideFrameView should follow it.
-  ash::WindowRestoreController::Get()->OnARCTaskReadyForUnparentedWindow(
-      window);
+  ash::WindowRestoreController::Get()->OnParentWindowToValidContainer(window);
   EXPECT_NE(hidden_container_parent, window->parent());
   wide_frame = shell_surface->wide_frame_for_test();
   EXPECT_TRUE(wide_frame);
diff --git a/components/exo/wayland/zcr_remote_shell_impl_unittest.cc b/components/exo/wayland/zcr_remote_shell_impl_unittest.cc
index 1b7c188..35ecd34 100644
--- a/components/exo/wayland/zcr_remote_shell_impl_unittest.cc
+++ b/components/exo/wayland/zcr_remote_shell_impl_unittest.cc
@@ -61,8 +61,11 @@
 
     wl_display_.reset(wl_display_create());
     wl_client_.reset(wl_client_create(wl_display_.get(), reader_.release()));
-    wl_shell_resource_.reset(wl_resource_create(
-        wl_client_.get(), &zcr_remote_shell_v2_interface, 1, 1));
+    // Use 0 as the id here to avoid the id conflict (i.e. let wayland library
+    // choose the id from available ids.) Otherwise that will cause memory leak.
+    wl_shell_resource_.reset(wl_resource_create(wl_client_.get(),
+                                                &zcr_remote_shell_v2_interface,
+                                                /*version=*/1, /*id=*/0));
 
     display_ = std::make_unique<Display>();
     shell_ = std::make_unique<WaylandRemoteShell>(
@@ -191,8 +194,8 @@
   auto shell_surface =
       exo_test_helper()->CreateClientControlledShellSurface(surface.get());
 
-  ScopedWlResource wl_res(
-      wl_resource_create(wl_client(), &zcr_remote_surface_v2_interface, 1, 1));
+  ScopedWlResource wl_res(wl_resource_create(
+      wl_client(), &zcr_remote_surface_v2_interface, /*version=*/1, /*id=*/0));
   shell_surface->set_delegate(
       shell()->CreateShellSurfaceDelegate(wl_res.get()));
 
@@ -229,8 +232,8 @@
   auto shell_surface =
       exo_test_helper()->CreateClientControlledShellSurface(surface.get());
 
-  ScopedWlResource wl_res(
-      wl_resource_create(wl_client(), &zcr_remote_surface_v2_interface, 1, 1));
+  ScopedWlResource wl_res(wl_resource_create(
+      wl_client(), &zcr_remote_surface_v2_interface, /*version=*/1, /*id=*/0));
   shell_surface->set_delegate(
       shell()->CreateShellSurfaceDelegate(wl_res.get()));
   SetSurfaceResource(surface.get(), wl_res.get());
diff --git a/components/language/content/browser/ulp_language_code_locator/ulp_language_code_locator.cc b/components/language/content/browser/ulp_language_code_locator/ulp_language_code_locator.cc
index b0ed1b6..d6bf5b3 100644
--- a/components/language/content/browser/ulp_language_code_locator/ulp_language_code_locator.cc
+++ b/components/language/content/browser/ulp_language_code_locator/ulp_language_code_locator.cc
@@ -54,8 +54,8 @@
   S2CellId cell(S2LatLng::FromDegrees(latitude, longitude));
   std::vector<std::string> languages;
 
-  ListPrefUpdateDeprecated update(prefs_, kCachedGeoLanguagesPref);
-  base::ListValue* celllangs_cached = update.Get();
+  ListPrefUpdate update(prefs_, kCachedGeoLanguagesPref);
+  base::Value* celllangs_cached = update.Get();
   for (size_t index = 0; index < serialized_langtrees_.size(); index++) {
     std::string language;
 
diff --git a/components/language/core/browser/url_language_histogram.cc b/components/language/core/browser/url_language_histogram.cc
index ad732b1..7663776 100644
--- a/components/language/core/browser/url_language_histogram.cc
+++ b/components/language/core/browser/url_language_histogram.cc
@@ -117,8 +117,7 @@
 }
 
 void UrlLanguageHistogram::OnPageVisited(const std::string& language_code) {
-  DictionaryPrefUpdateDeprecated update(pref_service_,
-                                        kUrlLanguageHistogramCounters);
+  DictionaryPrefUpdate update(pref_service_, kUrlLanguageHistogramCounters);
   base::Value* dict = update.Get();
   // If the key |language_code| does not exist, |counter_value| stays 0.
   int counter_value = dict->FindIntKey(language_code).value_or(0);
diff --git a/components/omnibox/bug-triage.md b/components/omnibox/bug-triage.md
index de02dfb..44d3685 100644
--- a/components/omnibox/bug-triage.md
+++ b/components/omnibox/bug-triage.md
@@ -175,10 +175,10 @@
 | --- | --- |
 | UI>Browser>Omnibox>AiS | Answers in Suggest. |
 | UI>Browser>Omnibox>DocumentSuggest | Documents provided by Google Drive |
+| UI>Browser>Omnibox>NTPRealbox | Suggestions displayed in the searchbox on the New Tab Page. |
 | UI>Browser>Omnibox>SecurityIndicators | Secure/insecure icons; triaged by another team. |
 | UI>Browser>Omnibox>TabToSearch | Custom search engines, omnibox extensions, etc. (including adding, triggering, ranking, etc. for them). |
 | UI>Browser>Omnibox>ZeroSuggest | Suggestions displayed on omnibox focus (both contextual and non-contextual). |
-| UI>Browser>Omnibox>NTPRealbox | Suggestions displayed in the searchbox on the New Tab Page. |
 
 If the bug is extremely low priority, set the **NextAction field** to
 **01/07/2021** and mention that we will "reassess" the bug next year.  This
diff --git a/components/page_load_metrics/browser/observers/core/largest_contentful_paint_handler.cc b/components/page_load_metrics/browser/observers/core/largest_contentful_paint_handler.cc
index fdf2a15..78c9d3e 100644
--- a/components/page_load_metrics/browser/observers/core/largest_contentful_paint_handler.cc
+++ b/components/page_load_metrics/browser/observers/core/largest_contentful_paint_handler.cc
@@ -51,11 +51,12 @@
   DCHECK(inout_timing);
   const ContentfulPaintTimingInfo new_candidate(
       candidate_new_time, candidate_new_size, inout_timing->TextOrImage(),
-      inout_timing->InMainFrame(), inout_timing->Type());
+      inout_timing->InMainFrame(), inout_timing->Type(),
+      inout_timing->ImageBPP());
   const ContentfulPaintTimingInfo& merged_candidate =
       MergeTimingsBySizeAndTime(new_candidate, *inout_timing);
   inout_timing->Reset(merged_candidate.Time(), merged_candidate.Size(),
-                      merged_candidate.Type());
+                      merged_candidate.Type(), merged_candidate.ImageBPP());
 }
 
 bool IsSubframe(content::RenderFrameHost* subframe_rfh) {
@@ -63,7 +64,7 @@
 }
 
 void Reset(ContentfulPaintTimingInfo& timing) {
-  timing.Reset(absl::nullopt, 0u, 0 /*type*/);
+  timing.Reset(absl::nullopt, 0u, /*type=*/0, /*image_bpp=*/0.0);
 }
 
 bool IsSameSite(const GURL& url1, const GURL& url2) {
@@ -90,12 +91,14 @@
     const absl::optional<base::TimeDelta>& time,
     const uint64_t& size,
     const LargestContentTextOrImage text_or_image,
+    double image_bpp,
     bool in_main_frame,
     uint32_t type)
     : time_(time),
       size_(size),
       text_or_image_(text_or_image),
       type_(type),
+      image_bpp_(image_bpp),
       in_main_frame_(in_main_frame) {}
 
 ContentfulPaintTimingInfo::ContentfulPaintTimingInfo(
@@ -135,10 +138,12 @@
 void ContentfulPaintTimingInfo::Reset(
     const absl::optional<base::TimeDelta>& time,
     const uint64_t& size,
-    uint32_t type) {
+    uint32_t type,
+    double image_bpp) {
   size_ = size;
   time_ = time;
   type_ = type;
+  image_bpp_ = image_bpp;
 }
 ContentfulPaint::ContentfulPaint(bool in_main_frame, uint32_t type)
     : text_(ContentfulPaintTimingInfo::LargestContentTextOrImage::kText,
@@ -281,13 +286,14 @@
   if (IsValid(largest_contentful_paint.largest_text_paint)) {
     main_frame_contentful_paint_.Text().Reset(
         largest_contentful_paint.largest_text_paint,
-        largest_contentful_paint.largest_text_paint_size, 0 /*type*/);
+        largest_contentful_paint.largest_text_paint_size, /*type=*/0,
+        /*image_bpp=*/0.0);
   }
   if (IsValid(largest_contentful_paint.largest_image_paint)) {
     main_frame_contentful_paint_.Image().Reset(
         largest_contentful_paint.largest_image_paint,
         largest_contentful_paint.largest_image_paint_size,
-        largest_contentful_paint.type);
+        largest_contentful_paint.type, largest_contentful_paint.image_bpp);
   }
 }
 
diff --git a/components/page_load_metrics/browser/observers/core/largest_contentful_paint_handler.h b/components/page_load_metrics/browser/observers/core/largest_contentful_paint_handler.h
index a6481cc0..9d47a27c 100644
--- a/components/page_load_metrics/browser/observers/core/largest_contentful_paint_handler.h
+++ b/components/page_load_metrics/browser/observers/core/largest_contentful_paint_handler.h
@@ -32,25 +32,27 @@
     kMaxValue = kText,
   };
 
-  explicit ContentfulPaintTimingInfo(
-      LargestContentTextOrImage largest_content_type,
-      bool in_main_frame,
-      blink::LargestContentfulPaintTypeMask type);
-  explicit ContentfulPaintTimingInfo(
+  ContentfulPaintTimingInfo(LargestContentTextOrImage largest_content_type,
+                            bool in_main_frame,
+                            blink::LargestContentfulPaintTypeMask type);
+  ContentfulPaintTimingInfo(
       const absl::optional<base::TimeDelta>&,
       const uint64_t& size,
       const LargestContentTextOrImage largest_content_type,
+      double image_bpp,
       bool in_main_frame,
       blink::LargestContentfulPaintTypeMask type);
   ContentfulPaintTimingInfo(const ContentfulPaintTimingInfo& other);
   void Reset(const absl::optional<base::TimeDelta>&,
              const uint64_t& size,
-             blink::LargestContentfulPaintTypeMask type);
+             blink::LargestContentfulPaintTypeMask type,
+             double image_bpp);
   absl::optional<base::TimeDelta> Time() const { return time_; }
   bool InMainFrame() const { return in_main_frame_; }
   blink::LargestContentfulPaintTypeMask Type() const { return type_; }
   uint64_t Size() const { return size_; }
   LargestContentTextOrImage TextOrImage() const { return text_or_image_; }
+  double ImageBPP() const { return image_bpp_; }
 
   // Returns true iff this object does not represent any paint.
   bool Empty() const {
@@ -75,6 +77,7 @@
   uint64_t size_;
   LargestContentTextOrImage text_or_image_;
   blink::LargestContentfulPaintTypeMask type_ = 0;
+  double image_bpp_ = 0.0;
   bool in_main_frame_;
 };
 
diff --git a/components/page_load_metrics/common/page_load_metrics.mojom b/components/page_load_metrics/common/page_load_metrics.mojom
index dc5f7e3..d51657a 100644
--- a/components/page_load_metrics/common/page_load_metrics.mojom
+++ b/components/page_load_metrics/common/page_load_metrics.mojom
@@ -40,6 +40,10 @@
   // These are packed blink::LargestContentfulPaintType enums, indicating
   // the largest LCP candidate's type characteristics.
   uint32 type;
+
+  // Computed entropy of the page's largest image, calculated as the image file
+  // size, in bits, divided by the image's rendered size, in pixels.
+  double image_bpp;
 };
 
 // TimeDeltas below relative to navigation start.
diff --git a/components/page_load_metrics/renderer/metrics_render_frame_observer.cc b/components/page_load_metrics/renderer/metrics_render_frame_observer.cc
index 1e67661..048e4de 100644
--- a/components/page_load_metrics/renderer/metrics_render_frame_observer.cc
+++ b/components/page_load_metrics/renderer/metrics_render_frame_observer.cc
@@ -594,6 +594,8 @@
             : ClampDelta(perf.LargestImagePaint(), start);
     timing->paint_timing->largest_contentful_paint->type =
         perf.LargestContentfulPaintType();
+    timing->paint_timing->largest_contentful_paint->image_bpp =
+        perf.LargestContentfulPaintImageBPP();
   }
   if (perf.LargestTextPaintSize() > 0) {
     // LargestTextPaint and LargestTextPaintSize should be available at the
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json
index 39c9048..169b606 100644
--- a/components/policy/resources/policy_templates.json
+++ b/components/policy/resources/policy_templates.json
@@ -17403,6 +17403,39 @@
       ''',
     },
     {
+      'name': 'NTPMiddleSlotAnnouncementVisible',
+      'owners': ['danpeng@google.com', 'tiborg@chromium.org', 'chrome-desktop-ntp@google.com'],
+      'type': 'main',
+      'schema': { 'type': 'boolean' },
+      'supported_on': ['chrome.*:99-', 'chrome_os:99-'],
+      'features': {
+        'dynamic_refresh': True,
+        'per_profile': True,
+      },
+      'items': [
+        {
+          'value': True,
+          'caption': 'New Tab Page will show the middle slot announcement if it is available',
+        },
+        {
+          'value': False,
+          'caption': 'New Tab Page will not show the middle slot announcement even if it is available',
+        },
+      ],
+      'example_value': True,
+      'default': True,
+      'id': 941,
+      'caption': '''Show the middle slot announcement on the New Tab Page''',
+      'tags': [],
+      'desc':
+      '''This policy controls the visibility of the middle slot announcement on the New Tab Page.
+
+      If the policy is set to Enabled, the New Tab Page will show the middle slot announcement if it is available.
+
+      If the policy is set to Disabled, the New Tab Page will not show the middle slot announcement even if it is available.
+      ''',
+    },
+    {
       'name': 'WebRtcUdpPortRange',
       'owners': ['guidou@chromium.org'],
       'type': 'string',
@@ -30307,6 +30340,6 @@
   'placeholders': [],
   'deleted_policy_ids': [114, 115, 204, 205, 206, 341, 412, 476, 544, 546, 562, 569, 578, 583, 585, 586, 587, 588, 589, 590, 591, 600, 668, 669, 872],
   'deleted_atomic_policy_group_ids': [19],
-  'highest_id_currently_used': 940,
+  'highest_id_currently_used': 941,
   'highest_atomic_group_id_currently_used': 41
 }
diff --git a/components/policy/test_support/BUILD.gn b/components/policy/test_support/BUILD.gn
index c353f460..e56e307 100644
--- a/components/policy/test_support/BUILD.gn
+++ b/components/policy/test_support/BUILD.gn
@@ -20,6 +20,8 @@
     "request_handler_for_api_authorization.h",
     "request_handler_for_auto_enrollment.cc",
     "request_handler_for_auto_enrollment.h",
+    "request_handler_for_check_android_management.cc",
+    "request_handler_for_check_android_management.h",
     "request_handler_for_chrome_desktop_report.cc",
     "request_handler_for_chrome_desktop_report.h",
     "request_handler_for_device_attribute_update.cc",
@@ -83,6 +85,7 @@
     "policy_storage_unittest.cc",
     "request_handler_for_api_authorization_unittest.cc",
     "request_handler_for_auto_enrollment_unittest.cc",
+    "request_handler_for_check_android_management_unittest.cc",
     "request_handler_for_chrome_desktop_report_unittest.cc",
     "request_handler_for_device_attribute_update_permission_unittest.cc",
     "request_handler_for_device_attribute_update_unittest.cc",
diff --git a/components/policy/test_support/embedded_policy_test_server.cc b/components/policy/test_support/embedded_policy_test_server.cc
index 51f39bc..52fe8c1 100644
--- a/components/policy/test_support/embedded_policy_test_server.cc
+++ b/components/policy/test_support/embedded_policy_test_server.cc
@@ -10,11 +10,15 @@
 #include "base/bind.h"
 #include "base/logging.h"
 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
+#if !BUILDFLAG(IS_ANDROID)
+#include "components/policy/proto/chrome_extension_policy.pb.h"
+#endif  // !BUILDFLAG(IS_ANDROID)
 #include "components/policy/test_support/client_storage.h"
 #include "components/policy/test_support/failing_request_handler.h"
 #include "components/policy/test_support/policy_storage.h"
 #include "components/policy/test_support/request_handler_for_api_authorization.h"
 #include "components/policy/test_support/request_handler_for_auto_enrollment.h"
+#include "components/policy/test_support/request_handler_for_check_android_management.h"
 #include "components/policy/test_support/request_handler_for_chrome_desktop_report.h"
 #include "components/policy/test_support/request_handler_for_device_attribute_update.h"
 #include "components/policy/test_support/request_handler_for_device_attribute_update_permission.h"
@@ -28,6 +32,7 @@
 #include "components/policy/test_support/request_handler_for_remote_commands.h"
 #include "components/policy/test_support/request_handler_for_status_upload.h"
 #include "components/policy/test_support/test_server_helpers.h"
+#include "crypto/sha2.h"
 #include "net/base/url_util.h"
 #include "net/http/http_status_code.h"
 #include "net/test/embedded_test_server/http_request.h"
@@ -82,6 +87,8 @@
       client_storage_.get(), policy_storage_.get()));
   RegisterHandler(std::make_unique<RequestHandlerForAutoEnrollment>(
       client_storage_.get(), policy_storage_.get()));
+  RegisterHandler(std::make_unique<RequestHandlerForCheckAndroidManagement>(
+      client_storage_.get(), policy_storage_.get()));
   RegisterHandler(std::make_unique<RequestHandlerForChromeDesktopReport>(
       client_storage_.get(), policy_storage_.get()));
   RegisterHandler(std::make_unique<RequestHandlerForDeviceAttributeUpdate>(
@@ -136,16 +143,28 @@
       client_storage_.get(), policy_storage_.get(), request_type, error_code));
 }
 
-GURL EmbeddedPolicyTestServer::GetExternalPolicyDataURL(
-    const std::string& policy_type,
-    const std::string& entity_id) const {
-  GURL url = http_server_.GetURL(kExternalPolicyDataPath);
-  url = net::AppendOrReplaceQueryParameter(url, kExternalPolicyTypeParam,
-                                           policy_type);
-  url = net::AppendOrReplaceQueryParameter(url, kExternalEntityIdParam,
-                                           entity_id);
-  return url;
+#if !BUILDFLAG(IS_ANDROID)
+void EmbeddedPolicyTestServer::UpdateExternalPolicy(
+    const std::string& type,
+    const std::string& entity_id,
+    const std::string& raw_policy) {
+  // Register raw policy to be served by external endpoint.
+  policy_storage()->SetExternalPolicyPayload(type, entity_id, raw_policy);
+
+  // Register proto policy with details on how to fetch the raw policy.
+  GURL external_policy_url = http_server_.GetURL(kExternalPolicyDataPath);
+  external_policy_url = net::AppendOrReplaceQueryParameter(
+      external_policy_url, kExternalPolicyTypeParam, type);
+  external_policy_url = net::AppendOrReplaceQueryParameter(
+      external_policy_url, kExternalEntityIdParam, entity_id);
+
+  enterprise_management::ExternalPolicyData external_policy_data;
+  external_policy_data.set_download_url(external_policy_url.spec());
+  external_policy_data.set_secure_hash(crypto::SHA256HashString(raw_policy));
+  policy_storage()->SetPolicyPayload(type, entity_id,
+                                     external_policy_data.SerializeAsString());
 }
+#endif  // !BUILDFLAG(IS_ANDROID)
 
 std::unique_ptr<HttpResponse> EmbeddedPolicyTestServer::HandleRequest(
     const HttpRequest& request) {
diff --git a/components/policy/test_support/embedded_policy_test_server.h b/components/policy/test_support/embedded_policy_test_server.h
index a19ef43..736b7cb7 100644
--- a/components/policy/test_support/embedded_policy_test_server.h
+++ b/components/policy/test_support/embedded_policy_test_server.h
@@ -84,8 +84,15 @@
   void ConfigureRequestError(const std::string& request_type,
                              net::HttpStatusCode error_code);
 
-  GURL GetExternalPolicyDataURL(const std::string& policy_type,
-                                const std::string& entity_id) const;
+#if !BUILDFLAG(IS_ANDROID)
+  // Updates policy selected by |type| and optional |entity_id|. The
+  // |raw_policy| is served via an external endpoint. This does not trigger
+  // policy invalidation, hence test authors must manually trigger a policy
+  // fetch.
+  void UpdateExternalPolicy(const std::string& type,
+                            const std::string& entity_id,
+                            const std::string& raw_policy);
+#endif  // !BUILDFLAG(IS_ANDROID)
 
  private:
   // Default request handler.
diff --git a/components/policy/test_support/embedded_policy_test_server_test_base.cc b/components/policy/test_support/embedded_policy_test_server_test_base.cc
index 1a4c28dd..6d1582f 100644
--- a/components/policy/test_support/embedded_policy_test_server_test_base.cc
+++ b/components/policy/test_support/embedded_policy_test_server_test_base.cc
@@ -71,6 +71,11 @@
   AddQueryParam(dm_protocol::kParamDeviceType, device_type);
 }
 
+void EmbeddedPolicyTestServerTestBase::SetOAuthToken(
+    const std::string& oauth_token) {
+  AddQueryParam(dm_protocol::kParamOAuthToken, oauth_token);
+}
+
 void EmbeddedPolicyTestServerTestBase::SetRequestTypeParam(
     const std::string& request_type) {
   AddQueryParam(dm_protocol::kParamRequest, request_type);
diff --git a/components/policy/test_support/embedded_policy_test_server_test_base.h b/components/policy/test_support/embedded_policy_test_server_test_base.h
index 87ba0af..6e90eac 100644
--- a/components/policy/test_support/embedded_policy_test_server_test_base.h
+++ b/components/policy/test_support/embedded_policy_test_server_test_base.h
@@ -43,6 +43,7 @@
   void SetAppType(const std::string& app_type);
   void SetDeviceIdParam(const std::string& device_id);
   void SetDeviceType(const std::string& device_type);
+  void SetOAuthToken(const std::string& oauth_token);
   void SetRequestTypeParam(const std::string& request_type);
   void SetEnrollmentTokenHeader(const std::string& enrollment_token);
   void SetDeviceTokenHeader(const std::string& device_token);
diff --git a/components/policy/test_support/embedded_policy_test_server_unittest.cc b/components/policy/test_support/embedded_policy_test_server_unittest.cc
index ebc97d6..63da4dad 100644
--- a/components/policy/test_support/embedded_policy_test_server_unittest.cc
+++ b/components/policy/test_support/embedded_policy_test_server_unittest.cc
@@ -5,6 +5,9 @@
 #include "components/policy/test_support/embedded_policy_test_server.h"
 
 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
+#if !BUILDFLAG(IS_ANDROID)
+#include "components/policy/proto/chrome_extension_policy.pb.h"
+#endif  // !BUILDFLAG(IS_ANDROID)
 #include "components/policy/test_support/embedded_policy_test_server.h"
 #include "components/policy/test_support/embedded_policy_test_server_test_base.h"
 #include "components/policy/test_support/policy_storage.h"
@@ -21,11 +24,17 @@
 namespace {
 
 constexpr char kFakeDeviceId[] = "fake_device_id";
-constexpr char kFakeExtensionId[] = "fake_extension_id";
 constexpr char kFakeRequestType[] = "fake_request_type";
 constexpr char kInvalidRequestType[] = "invalid_request_type";
 constexpr char kResponseBodyYay[] = "Yay!!!";
+#if !BUILDFLAG(IS_ANDROID)
+constexpr char kFakeExtensionId[] = "fake_extension_id";
 constexpr char kRawPolicyPayload[] = R"({"foo": "bar"})";
+constexpr base::StringPiece kSHA256HashForRawPolicyPayload(
+    "\x42\x6f\xc0\x4f\x04\xbf\x8f\xdb\x58\x31\xdc\x37\xbb\xb6\xdc\xf7\x0f\x63"
+    "\xa3\x7e\x05\xa6\x8c\x6e\xa5\xf6\x3e\x85\xae\x57\x93\x76",
+    32);
+#endif  // !BUILDFLAG(IS_ANDROID)
 
 class FakeRequestHandler : public EmbeddedPolicyTestServer::RequestHandler {
  public:
@@ -105,13 +114,21 @@
   EXPECT_EQ(GetResponseCode(), net::HTTP_BAD_REQUEST);
 }
 
-TEST_F(EmbeddedPolicyTestServerTest, HandleRequest_ExternalPolicyData_Success) {
-  test_server()->policy_storage()->SetExternalPolicyPayload(
-      dm_protocol::kChromeExtensionPolicyType, kFakeExtensionId,
-      kRawPolicyPayload);
+#if !BUILDFLAG(IS_ANDROID)
+TEST_F(EmbeddedPolicyTestServerTest, HandleRequest_PolicyViaExternalEndpoint) {
+  test_server()->UpdateExternalPolicy(dm_protocol::kChromeExtensionPolicyType,
+                                      kFakeExtensionId, kRawPolicyPayload);
+
+  std::string policy_data = test_server()->policy_storage()->GetPolicyPayload(
+      dm_protocol::kChromeExtensionPolicyType, kFakeExtensionId);
+  ASSERT_FALSE(policy_data.empty());
+  enterprise_management::ExternalPolicyData data;
+  ASSERT_TRUE(data.ParseFromString(policy_data));
+  EXPECT_EQ(data.secure_hash(), kSHA256HashForRawPolicyPayload);
+  ASSERT_TRUE(data.has_download_url());
+
   SetMethod(net::HttpRequestHeaders::kGetMethod);
-  SetURL(test_server()->GetExternalPolicyDataURL(
-      dm_protocol::kChromeExtensionPolicyType, kFakeExtensionId));
+  SetURL(GURL(data.download_url()));
 
   StartRequestAndWait();
 
@@ -119,16 +136,6 @@
   ASSERT_TRUE(HasResponseBody());
   EXPECT_EQ(GetResponseBody(), kRawPolicyPayload);
 }
-
-TEST_F(EmbeddedPolicyTestServerTest,
-       HandleRequest_ExternalPolicyData_NoPayload) {
-  SetMethod(net::HttpRequestHeaders::kGetMethod);
-  SetURL(test_server()->GetExternalPolicyDataURL(
-      dm_protocol::kChromeExtensionPolicyType, kFakeExtensionId));
-
-  StartRequestAndWait();
-
-  EXPECT_EQ(GetResponseCode(), net::HTTP_NOT_FOUND);
-}
+#endif  // !BUILDFLAG(IS_ANDROID)
 
 }  // namespace policy
diff --git a/components/policy/test_support/request_handler_for_check_android_management.cc b/components/policy/test_support/request_handler_for_check_android_management.cc
new file mode 100644
index 0000000..45eb5a1
--- /dev/null
+++ b/components/policy/test_support/request_handler_for_check_android_management.cc
@@ -0,0 +1,56 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/policy/test_support/request_handler_for_check_android_management.h"
+
+#include "components/policy/core/common/cloud/cloud_policy_constants.h"
+#include "components/policy/proto/device_management_backend.pb.h"
+#include "components/policy/test_support/client_storage.h"
+#include "components/policy/test_support/policy_storage.h"
+#include "components/policy/test_support/test_server_helpers.h"
+#include "net/base/url_util.h"
+#include "net/http/http_status_code.h"
+#include "net/test/embedded_test_server/http_request.h"
+#include "net/test/embedded_test_server/http_response.h"
+
+using net::test_server::HttpRequest;
+using net::test_server::HttpResponse;
+
+namespace em = enterprise_management;
+
+namespace policy {
+
+const char kManagedAuthToken[] = "managed-auth-token";
+const char kUnmanagedAuthToken[] = "unmanaged-auth-token";
+
+RequestHandlerForCheckAndroidManagement::
+    RequestHandlerForCheckAndroidManagement(ClientStorage* client_storage,
+                                            PolicyStorage* policy_storage)
+    : EmbeddedPolicyTestServer::RequestHandler(client_storage, policy_storage) {
+}
+
+RequestHandlerForCheckAndroidManagement::
+    ~RequestHandlerForCheckAndroidManagement() = default;
+
+std::string RequestHandlerForCheckAndroidManagement::RequestType() {
+  return dm_protocol::kValueRequestCheckAndroidManagement;
+}
+
+std::unique_ptr<HttpResponse>
+RequestHandlerForCheckAndroidManagement::HandleRequest(
+    const HttpRequest& request) {
+  std::string oauth_token;
+  net::GetValueForKeyInQuery(request.GetURL(), dm_protocol::kParamOAuthToken,
+                             &oauth_token);
+
+  em::DeviceManagementResponse response;
+  response.mutable_check_android_management_response();
+  if (oauth_token == kManagedAuthToken)
+    return CreateHttpResponse(net::HTTP_CONFLICT, response.SerializeAsString());
+  if (oauth_token == kUnmanagedAuthToken)
+    return CreateHttpResponse(net::HTTP_OK, response.SerializeAsString());
+  return CreateHttpResponse(net::HTTP_FORBIDDEN, "Invalid OAuth token");
+}
+
+}  // namespace policy
diff --git a/components/policy/test_support/request_handler_for_check_android_management.h b/components/policy/test_support/request_handler_for_check_android_management.h
new file mode 100644
index 0000000..c7343d62
--- /dev/null
+++ b/components/policy/test_support/request_handler_for_check_android_management.h
@@ -0,0 +1,37 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_POLICY_TEST_SUPPORT_REQUEST_HANDLER_FOR_CHECK_ANDROID_MANAGEMENT_H_
+#define COMPONENTS_POLICY_TEST_SUPPORT_REQUEST_HANDLER_FOR_CHECK_ANDROID_MANAGEMENT_H_
+
+#include "components/policy/test_support/embedded_policy_test_server.h"
+
+namespace policy {
+
+// Auth token for Android managed accounts.
+extern const char kManagedAuthToken[];
+// Auth token for other Android unmanaged accounts.
+extern const char kUnmanagedAuthToken[];
+
+// Handler for request type `check_android_management`.
+class RequestHandlerForCheckAndroidManagement
+    : public EmbeddedPolicyTestServer::RequestHandler {
+ public:
+  RequestHandlerForCheckAndroidManagement(ClientStorage* client_storage,
+                                          PolicyStorage* policy_storage);
+  RequestHandlerForCheckAndroidManagement(
+      RequestHandlerForCheckAndroidManagement&& handler) = delete;
+  RequestHandlerForCheckAndroidManagement& operator=(
+      RequestHandlerForCheckAndroidManagement&& handler) = delete;
+  ~RequestHandlerForCheckAndroidManagement() override;
+
+  // EmbeddedPolicyTestServer::RequestHandler:
+  std::string RequestType() override;
+  std::unique_ptr<net::test_server::HttpResponse> HandleRequest(
+      const net::test_server::HttpRequest& request) override;
+};
+
+}  // namespace policy
+
+#endif  // COMPONENTS_POLICY_TEST_SUPPORT_REQUEST_HANDLER_FOR_CHECK_ANDROID_MANAGEMENT_H_
diff --git a/components/policy/test_support/request_handler_for_check_android_management_unittest.cc b/components/policy/test_support/request_handler_for_check_android_management_unittest.cc
new file mode 100644
index 0000000..185867f
--- /dev/null
+++ b/components/policy/test_support/request_handler_for_check_android_management_unittest.cc
@@ -0,0 +1,66 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/policy/test_support/request_handler_for_check_android_management.h"
+
+#include <utility>
+
+#include "components/policy/core/common/cloud/cloud_policy_constants.h"
+#include "components/policy/test_support/embedded_policy_test_server_test_base.h"
+#include "components/policy/test_support/policy_storage.h"
+#include "net/http/http_status_code.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace policy {
+
+namespace {
+
+constexpr char kDeviceId[] = "fake_device_id";
+
+}  // namespace
+
+class RequestHandlerForCheckAndroidManagementTest
+    : public EmbeddedPolicyTestServerTestBase {
+ public:
+  RequestHandlerForCheckAndroidManagementTest() = default;
+  ~RequestHandlerForCheckAndroidManagementTest() override = default;
+
+  void SetUp() override {
+    EmbeddedPolicyTestServerTestBase::SetUp();
+
+    SetRequestTypeParam(dm_protocol::kValueRequestCheckAndroidManagement);
+    SetAppType(dm_protocol::kValueAppType);
+    SetDeviceIdParam(kDeviceId);
+    SetDeviceType(dm_protocol::kValueDeviceType);
+  }
+};
+
+TEST_F(RequestHandlerForCheckAndroidManagementTest, HandleRequest_Success) {
+  SetOAuthToken(kUnmanagedAuthToken);
+
+  StartRequestAndWait();
+
+  EXPECT_EQ(GetResponseCode(), net::HTTP_OK);
+  ASSERT_TRUE(HasResponseBody());
+  auto response = GetDeviceManagementResponse();
+  EXPECT_TRUE(response.has_check_android_management_response());
+}
+
+TEST_F(RequestHandlerForCheckAndroidManagementTest, HandleRequest_Conflict) {
+  SetOAuthToken(kManagedAuthToken);
+
+  StartRequestAndWait();
+
+  EXPECT_EQ(GetResponseCode(), net::HTTP_CONFLICT);
+}
+
+TEST_F(RequestHandlerForCheckAndroidManagementTest, HandleRequest_Forbidden) {
+  SetOAuthToken("invalid-auth-token");
+
+  StartRequestAndWait();
+
+  EXPECT_EQ(GetResponseCode(), net::HTTP_FORBIDDEN);
+}
+
+}  // namespace policy
diff --git a/components/printing/renderer/print_render_frame_helper.cc b/components/printing/renderer/print_render_frame_helper.cc
index 23437494..d046a79 100644
--- a/components/printing/renderer/print_render_frame_helper.cc
+++ b/components/printing/renderer/print_render_frame_helper.cc
@@ -1223,6 +1223,10 @@
     std::move(on_stop_loading_closure_).Run();
 }
 
+void PrintRenderFrameHelper::DidFinishLoadForPrinting() {
+  DidFinishLoad();
+}
+
 void PrintRenderFrameHelper::ScriptedPrint(bool user_initiated) {
   blink::WebLocalFrame* web_frame = render_frame()->GetWebFrame();
   if (!IsScriptInitiatedPrintAllowed(web_frame, user_initiated))
@@ -1243,7 +1247,8 @@
   if (g_is_preview_enabled) {
 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
     print_preview_context_.InitWithFrame(web_frame);
-    RequestPrintPreview(PRINT_PREVIEW_SCRIPTED);
+    RequestPrintPreview(PRINT_PREVIEW_SCRIPTED,
+                        /*already_notified_frame=*/false);
 #endif
   } else {
     web_frame->DispatchBeforePrintEvent(/*print_client=*/nullptr);
@@ -1364,9 +1369,9 @@
     return;
   }
   print_preview_context_.InitWithFrame(frame);
-  RequestPrintPreview(has_selection
-                          ? PRINT_PREVIEW_USER_INITIATED_SELECTION
-                          : PRINT_PREVIEW_USER_INITIATED_ENTIRE_FRAME);
+  RequestPrintPreview(has_selection ? PRINT_PREVIEW_USER_INITIATED_SELECTION
+                                    : PRINT_PREVIEW_USER_INITIATED_ENTIRE_FRAME,
+                      /*already_notified_frame=*/false);
 }
 
 void PrintRenderFrameHelper::PrintPreview(base::Value settings) {
@@ -1893,7 +1898,8 @@
   if (g_is_preview_enabled) {
 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
     print_preview_context_.InitWithNode(node);
-    RequestPrintPreview(PRINT_PREVIEW_USER_INITIATED_CONTEXT_NODE);
+    RequestPrintPreview(PRINT_PREVIEW_USER_INITIATED_CONTEXT_NODE,
+                        /*already_notified_frame=*/false);
 #endif
   } else {
     // Make a copy of the node, in case RenderView::OnContextMenuClosed() resets
@@ -2494,12 +2500,39 @@
   }
 }
 
-void PrintRenderFrameHelper::RequestPrintPreview(PrintPreviewRequestType type) {
+void PrintRenderFrameHelper::WaitForLoad(PrintPreviewRequestType type) {
+  static constexpr base::TimeDelta kLoadEventTimeout = base::Seconds(2);
+
+  if (type == PRINT_PREVIEW_SCRIPTED) {
+    on_stop_loading_closure_ =
+        base::BindOnce(&PrintRenderFrameHelper::ShowScriptedPrintPreview,
+                       weak_ptr_factory_.GetWeakPtr());
+  } else {
+    on_stop_loading_closure_ =
+        base::BindOnce(&PrintRenderFrameHelper::RequestPrintPreview,
+                       weak_ptr_factory_.GetWeakPtr(), type, true);
+    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+        FROM_HERE,
+        base::BindOnce(&PrintRenderFrameHelper::DidFinishLoadForPrinting,
+                       weak_ptr_factory_.GetWeakPtr()),
+        kLoadEventTimeout);
+  }
+}
+
+void PrintRenderFrameHelper::RequestPrintPreview(PrintPreviewRequestType type,
+                                                 bool already_notified_frame) {
   auto weak_this = weak_ptr_factory_.GetWeakPtr();
-  print_preview_context_.DispatchBeforePrintEvent(weak_this);
+  if (!already_notified_frame) {
+    print_preview_context_.DispatchBeforePrintEvent(weak_this);
+  }
   if (!weak_this)
     return;
 
+  // TODO(chrishtr): make async work for scripted print.
+  if (type != PRINT_PREVIEW_SCRIPTED && !already_notified_frame) {
+    is_loading_ = print_preview_context_.source_frame()->WillPrintSoon();
+  }
+
   const bool is_from_arc = print_preview_context_.IsForArc();
   const bool is_modifiable = print_preview_context_.IsModifiable();
   const bool has_selection = print_preview_context_.HasSelection();
@@ -2523,13 +2556,14 @@
       // 2. ShowScriptedPrintPreview() shows preview once the document has been
       //    loaded.
       is_scripted_preview_delayed_ = true;
-      if (is_loading_ && print_preview_context_.IsPlugin()) {
-        // Wait for DidStopLoading. Plugins may not know the correct
-        // |is_modifiable| value until they are fully loaded, which occurs when
-        // DidStopLoading() is called. Defer showing the preview until then.
-        on_stop_loading_closure_ =
-            base::BindOnce(&PrintRenderFrameHelper::ShowScriptedPrintPreview,
-                           weak_ptr_factory_.GetWeakPtr());
+      if (is_loading_) {
+        // Wait for DidStopLoading, for two reasons:
+        // * To give the document time to finish loading any pending resources
+        ///  that are desired for printing.
+        // * Plugins may not know the correct|is_modifiable| value until they
+        //   are fully loaded, which occurs when DidStopLoading() is called.
+        //   Defer showing the preview until then.
+        WaitForLoad(type);
       } else {
         base::ThreadTaskRunnerHandle::Get()->PostTask(
             FROM_HERE,
@@ -2560,13 +2594,9 @@
       return;
     }
     case PRINT_PREVIEW_USER_INITIATED_ENTIRE_FRAME: {
-      // Wait for DidStopLoading. Continuing with this function while
-      // |is_loading_| is true will cause print preview to hang when try to
-      // print a PDF document.
-      if (is_loading_ && print_preview_context_.IsPlugin()) {
-        on_stop_loading_closure_ =
-            base::BindOnce(&PrintRenderFrameHelper::RequestPrintPreview,
-                           weak_ptr_factory_.GetWeakPtr(), type);
+      // See comment under PRINT_PREVIEW_SCRIPTED.
+      if (is_loading_) {
+        WaitForLoad(type);
         return;
       }
 
@@ -2579,10 +2609,9 @@
       break;
     }
     case PRINT_PREVIEW_USER_INITIATED_CONTEXT_NODE: {
-      if (is_loading_ && print_preview_context_.IsPlugin()) {
-        on_stop_loading_closure_ =
-            base::BindOnce(&PrintRenderFrameHelper::RequestPrintPreview,
-                           weak_ptr_factory_.GetWeakPtr(), type);
+      // See comment under PRINT_PREVIEW_SCRIPTED.
+      if (is_loading_) {
+        WaitForLoad(type);
         return;
       }
 
diff --git a/components/printing/renderer/print_render_frame_helper.h b/components/printing/renderer/print_render_frame_helper.h
index fee6bb8c..2b70311 100644
--- a/components/printing/renderer/print_render_frame_helper.h
+++ b/components/printing/renderer/print_render_frame_helper.h
@@ -247,6 +247,7 @@
       absl::optional<blink::WebNavigationType> navigation_type) override;
   void DidFailProvisionalLoad() override;
   void DidFinishLoad() override;
+  void DidFinishLoadForPrinting() override;
   void ScriptedPrint(bool user_initiated) override;
 
   void BindPrintRenderFrameReceiver(
@@ -436,7 +437,8 @@
 
   // WARNING: |this| may be gone after this method returns when |type| is
   // PRINT_PREVIEW_SCRIPTED.
-  void RequestPrintPreview(PrintPreviewRequestType type);
+  void RequestPrintPreview(PrintPreviewRequestType type,
+                           bool already_notified_frame);
 
   // Checks whether print preview should continue or not.
   // Returns true if canceling, false if continuing.
@@ -655,6 +657,8 @@
     int count_ = 0;
   };
 
+  void WaitForLoad(PrintPreviewRequestType type);
+
   ScriptingThrottler scripting_throttler_;
 
   bool print_node_in_progress_ = false;
@@ -673,10 +677,13 @@
   // is enabled.
   std::unique_ptr<content::AXTreeSnapshotter> snapshotter_;
 
-  // Used to fix a race condition where the source is a PDF and print preview
-  // hangs because RequestPrintPreview is called before DidStopLoading() is
-  // called. This is a store for the RequestPrintPreview() call and its
-  // parameters so that it can be invoked after DidStopLoading.
+  // Used for two reasons:
+  // * To give the document time to finish loading any pending resources that
+  //   are desired for printing.
+  // * To fix a race condition where the source is a PDF and print preview
+  //   hangs because RequestPrintPreview is called before DidStopLoading() is
+  //   called. This is a store for the RequestPrintPreview() call and its
+  //   parameters so that it can be invoked after DidStopLoading.
   base::OnceClosure on_stop_loading_closure_;
 
   // Stores the quit closures of Mojo responses.
diff --git a/components/safe_browsing/content/browser/base_ui_manager.cc b/components/safe_browsing/content/browser/base_ui_manager.cc
index ab07df4..0b97163 100644
--- a/components/safe_browsing/content/browser/base_ui_manager.cc
+++ b/components/safe_browsing/content/browser/base_ui_manager.cc
@@ -11,7 +11,6 @@
 #include "base/feature_list.h"
 #include "base/i18n/rtl.h"
 #include "base/memory/ptr_util.h"
-#include "base/supports_user_data.h"
 #include "components/safe_browsing/content/browser/base_blocking_page.h"
 #include "components/safe_browsing/core/common/features.h"
 #include "components/security_interstitials/content/security_interstitial_tab_helper.h"
@@ -21,6 +20,7 @@
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_contents_user_data.h"
 
 using content::BrowserThread;
 using content::NavigationEntry;
@@ -30,18 +30,15 @@
 
 namespace {
 
-const void* const kAllowlistKey = &kAllowlistKey;
-
 // A AllowlistUrlSet holds the set of URLs that have been allowlisted
 // for a specific WebContents, along with pending entries that are still
 // undecided. Each URL is associated with the first SBThreatType that
 // was seen for that URL. The URLs in this set should come from
 // GetAllowlistUrl() or GetMainFrameAllowlistUrlForResource() (in
 // SafeBrowsingUIManager)
-class AllowlistUrlSet : public base::SupportsUserData::Data {
+class AllowlistUrlSet : public content::WebContentsUserData<AllowlistUrlSet> {
  public:
-  AllowlistUrlSet() {}
-
+  ~AllowlistUrlSet() override = default;
   AllowlistUrlSet(const AllowlistUrlSet&) = delete;
   AllowlistUrlSet& operator=(const AllowlistUrlSet&) = delete;
 
@@ -82,12 +79,17 @@
     pending_[url] = {threat_type, 1};
   }
 
- protected:
+ private:
+  friend class content::WebContentsUserData<AllowlistUrlSet>;
+  WEB_CONTENTS_USER_DATA_KEY_DECL();
+
+  explicit AllowlistUrlSet(content::WebContents* web_contents)
+      : content::WebContentsUserData<AllowlistUrlSet>(*web_contents) {}
+
   // Method to remove all the instances of a website in the pending list
   // disregarding the count. Used when adding a site to the permanent list.
   void RemoveAllPending(const GURL& url) { pending_.erase(url); }
 
- private:
   std::map<GURL, SBThreatType> map_;
   // Keep a count of how many times a site has been added to the pending list
   // in order to solve a problem where upon reloading an interstitial, a site
@@ -95,6 +97,8 @@
   std::map<GURL, std::pair<SBThreatType, int>> pending_;
 };
 
+WEB_CONTENTS_USER_DATA_KEY_IMPL(AllowlistUrlSet);
+
 // Returns the URL that should be used in a AllowlistUrlSet for the
 // resource loaded from |url| on a navigation |entry|.
 GURL GetAllowlistUrl(const GURL& url,
@@ -108,23 +112,13 @@
   return url.GetWithEmptyPath();
 }
 
-AllowlistUrlSet* GetOrCreateAllowlist(WebContents* web_contents) {
-  AllowlistUrlSet* site_list =
-      static_cast<AllowlistUrlSet*>(web_contents->GetUserData(kAllowlistKey));
-  if (!site_list) {
-    site_list = new AllowlistUrlSet;
-    web_contents->SetUserData(kAllowlistKey, base::WrapUnique(site_list));
-  }
-  return site_list;
-}
-
 }  // namespace
 
 namespace safe_browsing {
 
-BaseUIManager::BaseUIManager() {}
+BaseUIManager::BaseUIManager() = default;
 
-BaseUIManager::~BaseUIManager() {}
+BaseUIManager::~BaseUIManager() = default;
 
 bool BaseUIManager::IsAllowlisted(const UnsafeResource& resource) {
   NavigationEntry* entry = nullptr;
@@ -159,8 +153,7 @@
   if (lookup_url.is_empty())
     return false;
 
-  AllowlistUrlSet* site_list =
-      static_cast<AllowlistUrlSet*>(web_contents->GetUserData(kAllowlistKey));
+  AllowlistUrlSet* site_list = AllowlistUrlSet::FromWebContents(web_contents);
   if (!site_list)
     return false;
 
@@ -335,7 +328,7 @@
 }
 
 void BaseUIManager::EnsureAllowlistCreated(WebContents* web_contents) {
-  GetOrCreateAllowlist(web_contents);
+  AllowlistUrlSet::CreateForWebContents(web_contents);
 }
 
 void BaseUIManager::CreateAndSendHitReport(const UnsafeResource& resource) {}
@@ -384,7 +377,8 @@
   if (!web_contents)
     return;
 
-  AllowlistUrlSet* site_list = GetOrCreateAllowlist(web_contents);
+  AllowlistUrlSet::CreateForWebContents(web_contents);
+  AllowlistUrlSet* site_list = AllowlistUrlSet::FromWebContents(web_contents);
 
   if (allowlist_url.is_empty())
     return;
@@ -445,8 +439,7 @@
   // here. By this point, a "Back" navigation could have already been
   // committed, so the page loading |resource| might be gone and
   // |web_contents_getter| may no longer be valid.
-  AllowlistUrlSet* site_list =
-      static_cast<AllowlistUrlSet*>(web_contents->GetUserData(kAllowlistKey));
+  AllowlistUrlSet* site_list = AllowlistUrlSet::FromWebContents(web_contents);
 
   if (allowlist_url.is_empty())
     return;
diff --git a/components/test/data/payments/email.js b/components/test/data/payments/email.js
index b3ba207..780cb6d2 100644
--- a/components/test/data/payments/email.js
+++ b/components/test/data/payments/email.js
@@ -10,15 +10,24 @@
  * Launches the PaymentRequest UI that requests email address.
  */
 function buy() { // eslint-disable-line no-unused-vars
+  buyWithMethods([
+    {supportedMethods: 'https://bobpay.com'},
+    {
+      supportedMethods: 'basic-card',
+      data: {supportedNetworks: ['visa']},
+    },
+  ]);
+}
+
+/**
+ * Launches the PaymentRequest UI that requests email address.
+ * @param {sequence<PaymentMethodData>} methodData An array of payment method
+ *        objects.
+ */
+function buyWithMethods(methodData) {
   try {
     new PaymentRequest(
-        [
-          {supportedMethods: 'https://bobpay.com'},
-          {
-            supportedMethods: 'basic-card',
-            data: {supportedNetworks: ['visa']},
-          },
-        ],
+        methodData,
         {total: {label: 'Total', amount: {currency: 'USD', value: '5.00'}}},
         {requestPayerEmail: true})
         .show()
diff --git a/components/ui_devtools/views/BUILD.gn b/components/ui_devtools/views/BUILD.gn
index 0a5864c1..6b20f6e 100644
--- a/components/ui_devtools/views/BUILD.gn
+++ b/components/ui_devtools/views/BUILD.gn
@@ -28,7 +28,6 @@
 
   deps = [
     "//components/ui_devtools",
-    "//extensions/common",
     "//skia",
     "//ui/views",
   ]
diff --git a/components/user_manager/known_user.cc b/components/user_manager/known_user.cc
index ffa6b22..ecebb018 100644
--- a/components/user_manager/known_user.cc
+++ b/components/user_manager/known_user.cc
@@ -146,8 +146,7 @@
 }
 
 // Checks if values in |dict| correspond with |account_id| identity.
-bool UserMatches(const AccountId& account_id,
-                 const base::DictionaryValue& dict) {
+bool UserMatches(const AccountId& account_id, const base::Value& dict) {
   const std::string* account_type = dict.FindStringKey(kAccountTypeKey);
   if (account_id.GetAccountType() != AccountType::UNKNOWN && account_type &&
       account_id.GetAccountType() !=
@@ -214,37 +213,31 @@
 
 KnownUser::~KnownUser() = default;
 
-bool KnownUser::FindPrefs(const AccountId& account_id,
-                          const base::DictionaryValue** out_value) {
+const base::Value* KnownUser::FindPrefs(const AccountId& account_id) {
   // UserManager is usually NULL in unit tests.
   if (account_id.GetAccountType() != AccountType::ACTIVE_DIRECTORY &&
       UserManager::IsInitialized() &&
       UserManager::Get()->IsUserNonCryptohomeDataEphemeral(account_id)) {
-    return false;
+    return nullptr;
   }
 
   if (!account_id.is_valid())
-    return false;
+    return nullptr;
 
   const base::Value* known_users = local_state_->GetList(kKnownUsers);
   for (const base::Value& element_value : known_users->GetList()) {
     if (element_value.is_dict()) {
-      const base::DictionaryValue& element =
-          base::Value::AsDictionaryValue(element_value);
-      if (UserMatches(account_id, element)) {
-        if (out_value)
-          *out_value = &element;
-
-        return true;
+      if (UserMatches(account_id, element_value)) {
+        return &element_value;
       }
     }
   }
-  return false;
+  return nullptr;
 }
 
-void KnownUser::UpdatePrefs(const AccountId& account_id,
-                            const base::DictionaryValue& values,
-                            bool clear) {
+void KnownUser::SetPath(const AccountId& account_id,
+                        const std::string& path,
+                        absl::optional<base::Value> opt_value) {
   // UserManager is usually NULL in unit tests.
   if (account_id.GetAccountType() != AccountType::ACTIVE_DIRECTORY &&
       UserManager::IsInitialized() &&
@@ -258,28 +251,31 @@
   ListPrefUpdate update(local_state_, kKnownUsers);
   for (base::Value& element_value : update->GetList()) {
     if (element_value.is_dict()) {
-      base::DictionaryValue* element =
-          static_cast<base::DictionaryValue*>(&element_value);
-      if (UserMatches(account_id, *element)) {
-        if (clear)
-          element->DictClear();
-        element->MergeDictionary(&values);
-        UpdateIdentity(account_id, *element);
+      if (UserMatches(account_id, element_value)) {
+        if (opt_value.has_value())
+          element_value.SetPath(path, std::move(opt_value).value());
+        else
+          element_value.RemovePath(path);
+
+        UpdateIdentity(account_id, element_value);
         return;
       }
     }
   }
-  base::Value new_value(base::Value::Type::DICTIONARY);
-  new_value.MergeDictionary(&values);
-  UpdateIdentity(account_id, new_value);
-  update->Append(std::move(new_value));
+  if (!opt_value.has_value())
+    return;
+
+  base::Value new_dict(base::Value::Type::DICTIONARY);
+  new_dict.SetPath(path, std::move(opt_value).value());
+  UpdateIdentity(account_id, new_dict);
+  update->Append(std::move(new_dict));
 }
 
 bool KnownUser::GetStringPref(const AccountId& account_id,
                               const std::string& path,
                               std::string* out_value) {
-  const base::DictionaryValue* user_pref_dict = nullptr;
-  if (!FindPrefs(account_id, &user_pref_dict))
+  const base::Value* user_pref_dict = FindPrefs(account_id);
+  if (!user_pref_dict)
     return false;
 
   const std::string* pref = user_pref_dict->FindStringPath(path);
@@ -291,16 +287,14 @@
 void KnownUser::SetStringPref(const AccountId& account_id,
                               const std::string& path,
                               const std::string& in_value) {
-  base::DictionaryValue dict;
-  dict.SetString(path, in_value);
-  UpdatePrefs(account_id, dict, false);
+  SetPath(account_id, path, base::Value(in_value));
 }
 
 bool KnownUser::GetBooleanPref(const AccountId& account_id,
                                const std::string& path,
                                bool* out_value) {
-  const base::DictionaryValue* user_pref_dict = nullptr;
-  if (!FindPrefs(account_id, &user_pref_dict))
+  const base::Value* user_pref_dict = FindPrefs(account_id);
+  if (!user_pref_dict)
     return false;
 
   absl::optional<bool> ret_value = user_pref_dict->FindBoolPath(path);
@@ -314,54 +308,47 @@
 void KnownUser::SetBooleanPref(const AccountId& account_id,
                                const std::string& path,
                                const bool in_value) {
-  base::DictionaryValue dict;
-  dict.SetBoolean(path, in_value);
-  UpdatePrefs(account_id, dict, false);
+  SetPath(account_id, path, base::Value(in_value));
 }
 
 bool KnownUser::GetIntegerPref(const AccountId& account_id,
                                const std::string& path,
                                int* out_value) {
-  const base::DictionaryValue* user_pref_dict = nullptr;
-  if (!FindPrefs(account_id, &user_pref_dict))
+  const base::Value* user_pref_dict = FindPrefs(account_id);
+  if (!user_pref_dict)
     return false;
-  return user_pref_dict->GetInteger(path, out_value);
+  absl::optional<int> optional_value = user_pref_dict->FindIntPath(path);
+
+  if (out_value && optional_value.has_value())
+    *out_value = optional_value.value();
+
+  return optional_value.has_value();
 }
 
 void KnownUser::SetIntegerPref(const AccountId& account_id,
                                const std::string& path,
                                const int in_value) {
-  base::DictionaryValue dict;
-  dict.SetInteger(path, in_value);
-  UpdatePrefs(account_id, dict, false);
+  SetPath(account_id, path, base::Value(in_value));
 }
 
 bool KnownUser::GetPref(const AccountId& account_id,
                         const std::string& path,
                         const base::Value** out_value) {
-  const base::DictionaryValue* user_pref_dict = nullptr;
-  if (!FindPrefs(account_id, &user_pref_dict))
+  const base::Value* user_pref_dict = FindPrefs(account_id);
+  if (!user_pref_dict)
     return false;
 
   *out_value = user_pref_dict->FindPath(path);
   return *out_value != nullptr;
 }
 
-void KnownUser::SetPref(const AccountId& account_id,
-                        const std::string& path,
-                        base::Value in_value) {
-  base::DictionaryValue dict;
-  dict.SetPath(path, std::move(in_value));
-  UpdatePrefs(account_id, dict, false);
-}
-
 void KnownUser::RemovePref(const AccountId& account_id,
                            const std::string& path) {
   // Prevent removing keys that are used internally.
   for (const std::string& key : kReservedKeys)
     CHECK_NE(path, key);
 
-  ClearPref(account_id, path);
+  SetPath(account_id, path, absl::nullopt);
 }
 
 AccountId KnownUser::GetAccountId(const std::string& user_email,
@@ -443,14 +430,12 @@
   const base::Value* known_users = local_state_->GetList(kKnownUsers);
   for (const base::Value& element_value : known_users->GetList()) {
     if (element_value.is_dict()) {
-      const base::DictionaryValue& element =
-          base::Value::AsDictionaryValue(element_value);
-      const std::string* email = element.FindStringKey(kCanonicalEmail);
-      const std::string* gaia_id = element.FindStringKey(kGAIAIdKey);
-      const std::string* obj_guid = element.FindStringKey(kObjGuidKey);
+      const std::string* email = element_value.FindStringKey(kCanonicalEmail);
+      const std::string* gaia_id = element_value.FindStringKey(kGAIAIdKey);
+      const std::string* obj_guid = element_value.FindStringKey(kObjGuidKey);
       AccountType account_type = AccountType::GOOGLE;
       if (const std::string* account_type_string =
-              element.FindStringKey(kAccountTypeKey)) {
+              element_value.FindStringKey(kAccountTypeKey)) {
         account_type = AccountId::StringToAccountType(*account_type_string);
       }
       switch (account_type) {
@@ -590,7 +575,7 @@
 }
 
 void KnownUser::ClearProfileRequiresPolicy(const AccountId& account_id) {
-  ClearPref(account_id, kProfileRequiresPolicy);
+  SetPath(account_id, kProfileRequiresPolicy, absl::nullopt);
 }
 
 void KnownUser::UpdateReauthReason(const AccountId& account_id,
@@ -605,7 +590,7 @@
 void KnownUser::SetChallengeResponseKeys(const AccountId& account_id,
                                          base::Value value) {
   DCHECK(value.is_list());
-  SetPref(account_id, kChallengeResponseKeys, std::move(value));
+  SetPath(account_id, kChallengeResponseKeys, std::move(value));
 }
 
 base::Value KnownUser::GetChallengeResponseKeys(const AccountId& account_id) {
@@ -617,7 +602,7 @@
 
 void KnownUser::SetLastOnlineSignin(const AccountId& account_id,
                                     base::Time time) {
-  SetPref(account_id, kLastOnlineSignin, base::TimeToValue(time));
+  SetPath(account_id, kLastOnlineSignin, base::TimeToValue(time));
 }
 
 base::Time KnownUser::GetLastOnlineSignin(const AccountId& account_id) {
@@ -634,9 +619,9 @@
     const AccountId& account_id,
     absl::optional<base::TimeDelta> time_delta) {
   if (!time_delta) {
-    ClearPref(account_id, kOfflineSigninLimit);
+    SetPath(account_id, kOfflineSigninLimit, absl::nullopt);
   } else {
-    SetPref(account_id, kOfflineSigninLimit,
+    SetPath(account_id, kOfflineSigninLimit,
             base::TimeDeltaToValue(time_delta.value()));
   }
 }
@@ -729,7 +714,7 @@
     const AccountId& account_id,
     const absl::optional<base::Version> version) {
   if (!version) {
-    ClearPref(account_id, kOnboardingCompletedVersion);
+    SetPath(account_id, kOnboardingCompletedVersion, absl::nullopt);
   } else {
     SetStringPref(account_id, kOnboardingCompletedVersion,
                   version.value().GetString());
@@ -750,7 +735,7 @@
 
 void KnownUser::RemoveOnboardingCompletedVersionForTests(
     const AccountId& account_id) {
-  ClearPref(account_id, kOnboardingCompletedVersion);
+  SetPath(account_id, kOnboardingCompletedVersion, absl::nullopt);
 }
 
 void KnownUser::SetPendingOnboardingScreen(const AccountId& account_id,
@@ -759,7 +744,7 @@
 }
 
 void KnownUser::RemovePendingOnboardingScreen(const AccountId& account_id) {
-  ClearPref(account_id, kPendingOnboardingScreen);
+  SetPath(account_id, kPendingOnboardingScreen, absl::nullopt);
 }
 
 std::string KnownUser::GetPendingOnboardingScreen(const AccountId& account_id) {
@@ -770,18 +755,8 @@
   return std::string();
 }
 
-void KnownUser::ClearPref(const AccountId& account_id,
-                          const std::string& path) {
-  const base::DictionaryValue* user_pref_dict = nullptr;
-  if (!FindPrefs(account_id, &user_pref_dict))
-    return;
-
-  base::Value updated_user_pref = user_pref_dict->Clone();
-  base::DictionaryValue* updated_user_pref_dict;
-  updated_user_pref.GetAsDictionary(&updated_user_pref_dict);
-
-  updated_user_pref_dict->RemovePath(path);
-  UpdatePrefs(account_id, *updated_user_pref_dict, true);
+bool KnownUser::UserExists(const AccountId& account_id) {
+  return FindPrefs(account_id);
 }
 
 void KnownUser::RemovePrefs(const AccountId& account_id) {
@@ -791,12 +766,9 @@
   ListPrefUpdate update(local_state_, kKnownUsers);
   base::Value::ListView update_view = update->GetList();
   for (auto it = update_view.begin(); it != update_view.end(); ++it) {
-    base::DictionaryValue* element = nullptr;
-    if (it->GetAsDictionary(&element)) {
-      if (UserMatches(account_id, *element)) {
-        update->EraseListIter(it);
-        break;
-      }
+    if (UserMatches(account_id, *it)) {
+      update->EraseListIter(it);
+      break;
     }
   }
 }
@@ -830,25 +802,6 @@
 // --- Legacy interface ---
 namespace known_user {
 
-bool FindPrefs(const AccountId& account_id,
-               const base::DictionaryValue** out_value) {
-  PrefService* local_state = GetLocalStateLegacy();
-  // Local State may not be initialized in tests.
-  if (!local_state)
-    return false;
-  return KnownUser(local_state).FindPrefs(account_id, out_value);
-}
-
-void UpdatePrefs(const AccountId& account_id,
-                 const base::DictionaryValue& values,
-                 bool clear) {
-  PrefService* local_state = GetLocalStateLegacy();
-  // Local State may not be initialized in tests.
-  if (!local_state)
-    return;
-  return KnownUser(local_state).UpdatePrefs(account_id, values, clear);
-}
-
 bool GetStringPref(const AccountId& account_id,
                    const std::string& path,
                    std::string* out_value) {
@@ -919,16 +872,6 @@
   return KnownUser(local_state).GetPref(account_id, path, out_value);
 }
 
-void SetPref(const AccountId& account_id,
-             const std::string& path,
-             base::Value in_value) {
-  PrefService* local_state = GetLocalStateLegacy();
-  // Local State may not be initialized in tests.
-  if (!local_state)
-    return;
-  return KnownUser(local_state).SetPref(account_id, path, std::move(in_value));
-}
-
 void RemovePref(const AccountId& account_id, const std::string& path) {
   PrefService* local_state = GetLocalStateLegacy();
   // Local State may not be initialized in tests.
diff --git a/components/user_manager/known_user.h b/components/user_manager/known_user.h
index 245a4a3..4abcd14 100644
--- a/components/user_manager/known_user.h
+++ b/components/user_manager/known_user.h
@@ -20,7 +20,6 @@
 class PrefService;
 
 namespace base {
-class DictionaryValue;
 class Value;
 }
 
@@ -50,18 +49,12 @@
   KnownUser(const KnownUser& other) = delete;
   KnownUser& operator=(const KnownUser& other) = delete;
 
-  // Performs a lookup of properties associated with |account_id|. If found,
-  // returns |true| and fills |out_value|. |out_value| can be NULL, if
-  // only existence check is required.
-  bool FindPrefs(const AccountId& account_id,
-                 const base::DictionaryValue** out_value);
-
-  // Updates (or creates) properties associated with |account_id| based
-  // on |values|. |clear| defines if existing properties are cleared (|true|)
-  // or if it is just a incremental update (|false|).
-  void UpdatePrefs(const AccountId& account_id,
-                   const base::DictionaryValue& values,
-                   bool clear);
+  // Updates (or creates) properties associated with |account_id|. Updates
+  // value found by |path| with |opt_value|. If |opt_value| has no value it
+  // clears the |path| in properties.
+  void SetPath(const AccountId& account_id,
+               const std::string& path,
+               absl::optional<base::Value> opt_value);
 
   // Returns true if |account_id| preference by |path| does exist,
   // fills in |out_value|. Otherwise returns false.
@@ -102,11 +95,6 @@
                const std::string& path,
                const base::Value** out_value);
 
-  // Updates user's identified by |account_id| value preference |path|.
-  void SetPref(const AccountId& account_id,
-               const std::string& path,
-               base::Value in_value);
-
   // Removes user's identified by |account_id| preference |path|.
   void RemovePref(const AccountId& account_id, const std::string& path);
 
@@ -255,10 +243,13 @@
 
   std::string GetPendingOnboardingScreen(const AccountId& account_id);
 
+  bool UserExists(const AccountId& account_id);
+
   // Register known user prefs.
   static void RegisterPrefs(PrefRegistrySimple* registry);
 
  private:
+  friend class KnownUserTest;
   friend class UserManagerBase;
 
   FRIEND_TEST_ALL_PREFIXES(KnownUserTest,
@@ -266,8 +257,9 @@
   FRIEND_TEST_ALL_PREFIXES(KnownUserTest, CleanObsoletePrefs);
   FRIEND_TEST_ALL_PREFIXES(KnownUserTest, MigrateOfflineSigninLimit);
 
-  // Removes |path| from account_id's known user dictionary.
-  void ClearPref(const AccountId& account_id, const std::string& path);
+  // Performs a lookup of properties associated with |account_id|. Returns
+  // nullptr if not found.
+  const base::Value* FindPrefs(const AccountId& account_id);
 
   // Removes all user preferences associated with |account_id|.
   // Not exported as code should not be calling this outside this component
@@ -290,22 +282,6 @@
 namespace known_user {
 // Methods for storage/retrieval of per-user properties in Local State.
 
-// Performs a lookup of properties associated with |account_id|. If found,
-// returns |true| and fills |out_value|. |out_value| can be NULL, if
-// only existence check is required.
-// TODO(https://crbug.com/1150434): Deprecated, use KnownUser::FindPrefs
-// instead.
-bool USER_MANAGER_EXPORT FindPrefs(const AccountId& account_id,
-                                   const base::DictionaryValue** out_value);
-
-// Updates (or creates) properties associated with |account_id| based
-// on |values|. |clear| defines if existing properties are cleared (|true|)
-// or if it is just a incremental update (|false|).
-// TODO(https://crbug.com/1150434): Deprecated, use KnownUser:: instead.
-void USER_MANAGER_EXPORT UpdatePrefs(const AccountId& account_id,
-                                     const base::DictionaryValue& values,
-                                     bool clear);
-
 // Returns true if |account_id| preference by |path| does exist,
 // fills in |out_value|. Otherwise returns false.
 // TODO(https://crbug.com/1150434): Deprecated, use KnownUser::GetStringPref
@@ -358,12 +334,6 @@
                                  const std::string& path,
                                  const base::Value** out_value);
 
-// Updates user's identified by |account_id| value preference |path|.
-// TODO(https://crbug.com/1150434): Deprecated, use KnownUser::SetPref instead.
-void USER_MANAGER_EXPORT SetPref(const AccountId& account_id,
-                                 const std::string& path,
-                                 base::Value in_value);
-
 // Removes user's identified by |account_id| preference |path|.
 // TODO(https://crbug.com/1150434): Deprecated, use KnownUser::RemovePref
 // instead.
diff --git a/components/user_manager/known_user_unittest.cc b/components/user_manager/known_user_unittest.cc
index bdf30fd..8417289 100644
--- a/components/user_manager/known_user_unittest.cc
+++ b/components/user_manager/known_user_unittest.cc
@@ -59,6 +59,10 @@
 
   PrefService* local_state() { return &local_state_; }
 
+  const base::Value* FindPrefs(const AccountId& account_id) {
+    return KnownUser(local_state()).FindPrefs(account_id);
+  }
+
  private:
   base::test::TaskEnvironment task_environment_{
       base::test::TaskEnvironment::MainThreadType::UI};
@@ -70,11 +74,7 @@
 };
 
 TEST_F(KnownUserTest, FindPrefsNonExisting) {
-  KnownUser known_user(local_state());
-  const base::DictionaryValue* value = nullptr;
-  bool read_success = known_user.FindPrefs(kDefaultAccountId, &value);
-  EXPECT_FALSE(read_success);
-  EXPECT_FALSE(value);
+  EXPECT_FALSE(FindPrefs(kDefaultAccountId));
 }
 
 TEST_F(KnownUserTest, FindPrefsExisting) {
@@ -82,9 +82,7 @@
   const std::string kCustomPrefName = "custom_pref";
   known_user.SetStringPref(kDefaultAccountId, kCustomPrefName, "value");
 
-  const base::DictionaryValue* value = nullptr;
-  bool read_success = known_user.FindPrefs(kDefaultAccountId, &value);
-  EXPECT_TRUE(read_success);
+  const base::Value* value = FindPrefs(kDefaultAccountId);
   ASSERT_TRUE(value);
 
   const std::string* pref_value = value->FindStringKey(kCustomPrefName);
@@ -107,19 +105,9 @@
   known_user.SetStringPref(kAccountIdEphemeralGaia, kCustomPrefName, "value");
   known_user.SetStringPref(kAccountIdEphemeralAd, kCustomPrefName, "value");
 
-  {
-    const base::DictionaryValue* value = nullptr;
-    bool read_success = known_user.FindPrefs(kAccountIdEphemeralGaia, &value);
-    EXPECT_FALSE(read_success);
-    EXPECT_FALSE(value);
-  }
+  EXPECT_FALSE(FindPrefs(kAccountIdEphemeralGaia));
 
-  {
-    const base::DictionaryValue* value = nullptr;
-    bool read_success = known_user.FindPrefs(kAccountIdEphemeralAd, &value);
-    EXPECT_TRUE(read_success);
-    EXPECT_TRUE(value);
-  }
+  EXPECT_TRUE(FindPrefs(kAccountIdEphemeralAd));
 }
 
 TEST_F(KnownUserTest, FindPrefsMatchForUnknownAccountType) {
@@ -134,12 +122,9 @@
 
   known_user.SetStringPref(kAccountIdUnknown, "some_pref", "some_value");
 
-  // Looking it up by AccountId always succeeds, no matter which AccountType is
-  // used for the lookup.
-  const base::DictionaryValue* value = nullptr;
-  EXPECT_TRUE(known_user.FindPrefs(kAccountIdUnknown, &value));
-  EXPECT_TRUE(known_user.FindPrefs(kAccountIdGaia, &value));
-  EXPECT_TRUE(known_user.FindPrefs(kAccountIdAd, &value));
+  EXPECT_TRUE(FindPrefs(kAccountIdUnknown));
+  EXPECT_TRUE(FindPrefs(kAccountIdGaia));
+  EXPECT_TRUE(FindPrefs(kAccountIdAd));
 }
 
 TEST_F(KnownUserTest, FindPrefsMatchForGaiaAccountWithEmail) {
@@ -151,35 +136,28 @@
 
   known_user.SaveKnownUser(AccountId::FromUserEmailGaiaId(kEmailA, kGaiaIdA));
 
-  const base::DictionaryValue* value = nullptr;
-
   // Finding by itself should work
-  EXPECT_TRUE(known_user.FindPrefs(
-      AccountId::FromUserEmailGaiaId(kEmailA, kGaiaIdA), &value));
+  EXPECT_TRUE(FindPrefs(AccountId::FromUserEmailGaiaId(kEmailA, kGaiaIdA)));
   // Finding by gaia id should also work even if the e-mail doesn't match.
-  EXPECT_TRUE(known_user.FindPrefs(
-      AccountId::FromUserEmailGaiaId(kEmailB, kGaiaIdA), &value));
+  EXPECT_TRUE(FindPrefs(AccountId::FromUserEmailGaiaId(kEmailB, kGaiaIdA)));
   // Finding by e-mail should also work even if the gaia id doesn't match.
   // TODO(https://crbug.com/1190902): This should likely be EXPECT_FALSE going
   // forward.
-  EXPECT_TRUE(known_user.FindPrefs(
-      AccountId::FromUserEmailGaiaId(kEmailA, kGaiaIdB), &value));
+  EXPECT_TRUE(FindPrefs(AccountId::FromUserEmailGaiaId(kEmailA, kGaiaIdB)));
   // Finding by just gaia id without any e-mail doesn't work (because the
   // resulting AccountId is not considered valid).
-  EXPECT_FALSE(known_user.FindPrefs(AccountId::FromGaiaId(kGaiaIdA), &value));
+  EXPECT_FALSE(FindPrefs(AccountId::FromGaiaId(kGaiaIdA)));
 
   // An unrelated gaia AccountId with the same Account Type doesn't find
   // anything.
-  EXPECT_FALSE(known_user.FindPrefs(
-      AccountId::FromUserEmailGaiaId(kEmailB, kGaiaIdB), &value));
+  EXPECT_FALSE(FindPrefs(AccountId::FromUserEmailGaiaId(kEmailB, kGaiaIdB)));
 
   // Looking up an AccountId stored as gaia by an unknown-type AccountId with
   // the same e-mail address succeeds.
-  EXPECT_TRUE(known_user.FindPrefs(AccountId::FromUserEmail(kEmailA), &value));
+  EXPECT_TRUE(FindPrefs(AccountId::FromUserEmail(kEmailA)));
 
   // Looking up an AccountId stored as gaia by an AccountId with type Ad fails.
-  EXPECT_FALSE(known_user.FindPrefs(
-      AccountId::AdFromUserEmailObjGuid(kEmailA, "guid"), &value));
+  EXPECT_FALSE(FindPrefs(AccountId::AdFromUserEmailObjGuid(kEmailA, "guid")));
 }
 
 TEST_F(KnownUserTest, FindPrefsMatchForAdAccountWithEmail) {
@@ -189,33 +167,26 @@
 
   known_user.SaveKnownUser(AccountId::AdFromUserEmailObjGuid(kEmailA, "a"));
 
-  const base::DictionaryValue* value = nullptr;
-
   // Finding by itself should work
-  EXPECT_TRUE(known_user.FindPrefs(
-      AccountId::AdFromUserEmailObjGuid(kEmailA, "a"), &value));
+  EXPECT_TRUE(FindPrefs(AccountId::AdFromUserEmailObjGuid(kEmailA, "a")));
   // Finding by guid should also work even if the e-mail doesn't match.
-  EXPECT_TRUE(known_user.FindPrefs(
-      AccountId::AdFromUserEmailObjGuid(kEmailB, "a"), &value));
+  EXPECT_TRUE(FindPrefs(AccountId::AdFromUserEmailObjGuid(kEmailB, "a")));
   // Finding by e-mail should also work even if the guid doesn't match.
-  EXPECT_TRUE(known_user.FindPrefs(
-      AccountId::AdFromUserEmailObjGuid(kEmailA, "b"), &value));
+  EXPECT_TRUE(FindPrefs(AccountId::AdFromUserEmailObjGuid(kEmailA, "b")));
   // Finding by just AD guid  without any e-mail doesn't work (because the
   // resulting AccountId is not considered valid).
-  EXPECT_FALSE(known_user.FindPrefs(AccountId::AdFromObjGuid("a"), &value));
+  EXPECT_FALSE(FindPrefs(AccountId::AdFromObjGuid("a")));
 
   // An unrelated AD AccountId with the same Account Type doesn't find
   // anything.
-  EXPECT_FALSE(known_user.FindPrefs(
-      AccountId::AdFromUserEmailObjGuid(kEmailB, "b"), &value));
+  EXPECT_FALSE(FindPrefs(AccountId::AdFromUserEmailObjGuid(kEmailB, "b")));
 
   // Looking up an AccountId stored as AD by an unknown-type AccountId with
   // the same e-mail address succeeds.
-  EXPECT_TRUE(known_user.FindPrefs(AccountId::FromUserEmail(kEmailA), &value));
+  EXPECT_TRUE(FindPrefs(AccountId::FromUserEmail(kEmailA)));
 
   // Looking up an AccountId stored as AD by an AccountId with type gaia fails.
-  EXPECT_FALSE(known_user.FindPrefs(
-      AccountId::FromUserEmailGaiaId(kEmailA, "gaia_id"), &value));
+  EXPECT_FALSE(FindPrefs(AccountId::FromUserEmailGaiaId(kEmailA, "gaia_id")));
 }
 
 TEST_F(KnownUserTest, UpdatePrefsWithoutClear) {
@@ -223,23 +194,14 @@
   constexpr char kPrefName1[] = "pref1";
   constexpr char kPrefName2[] = "pref2";
 
-  {
-    base::DictionaryValue update;
-    update.SetKey(kPrefName1, base::Value("pref1_value1"));
-    known_user.UpdatePrefs(kDefaultAccountId, update, /*clear=*/false);
-  }
+  known_user.SetPath(kDefaultAccountId, kPrefName1,
+                     base::Value("pref1_value1"));
 
-  {
-    base::DictionaryValue update;
-    update.SetKey(kPrefName1, base::Value("pref1_value2"));
-    known_user.UpdatePrefs(kDefaultAccountId, update, /*clear=*/false);
-  }
+  known_user.SetPath(kDefaultAccountId, kPrefName1,
+                     base::Value("pref1_value2"));
 
-  {
-    base::DictionaryValue update;
-    update.SetKey(kPrefName2, base::Value("pref2_value1"));
-    known_user.UpdatePrefs(kDefaultAccountId, update, /*clear=*/false);
-  }
+  known_user.SetPath(kDefaultAccountId, kPrefName2,
+                     base::Value("pref2_value1"));
 
   EXPECT_EQ(absl::make_optional(std::string("pref1_value2")),
             GetStringPrefValue(&known_user, kDefaultAccountId, kPrefName1));
@@ -252,17 +214,13 @@
   constexpr char kPrefName1[] = "pref1";
   constexpr char kPrefName2[] = "pref2";
 
-  {
-    base::DictionaryValue update;
-    update.SetKey(kPrefName1, base::Value("pref1_value1"));
-    known_user.UpdatePrefs(kDefaultAccountId, update, /*clear=*/false);
-  }
+  known_user.SetPath(kDefaultAccountId, kPrefName1,
+                     base::Value("pref1_value1"));
 
-  {
-    base::DictionaryValue update;
-    update.SetKey(kPrefName2, base::Value("pref2_value1"));
-    known_user.UpdatePrefs(kDefaultAccountId, update, /*clear=*/true);
-  }
+  known_user.SetPath(kDefaultAccountId, kPrefName2,
+                     base::Value("pref2_value1"));
+
+  known_user.SetPath(kDefaultAccountId, kPrefName1, absl::nullopt);
 
   EXPECT_EQ(absl::nullopt,
             GetStringPrefValue(&known_user, kDefaultAccountId, kPrefName1));
@@ -710,7 +668,7 @@
   using PrefType = base::Value;
   using PrefTypeForReading = const base::Value*;
 
-  static constexpr auto SetFunc = &KnownUser::SetPref;
+  static constexpr auto SetFunc = &KnownUser::SetPath;
   static constexpr auto GetFunc = &KnownUser::GetPref;
 
   static PrefType CreatePrefValue() { return base::Value("test"); }
diff --git a/components/viz/service/display/surface_aggregator.cc b/components/viz/service/display/surface_aggregator.cc
index 10f2342..c4749bd 100644
--- a/components/viz/service/display/surface_aggregator.cc
+++ b/components/viz/service/display/surface_aggregator.cc
@@ -15,7 +15,6 @@
 #include "base/check_op.h"
 #include "base/containers/adapters.h"
 #include "base/containers/cxx20_erase.h"
-#include "base/debug/alias.h"
 #include "base/logging.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/numerics/ranges.h"
@@ -438,32 +437,6 @@
           dest_pass->transform_to_root_target, dest_root_target_clip_rect);
 
   surface_damage_rect_list_->push_back(damage_rect_in_root_target_space);
-
-  // TODO(crbug.com/1257765): CHECK is temporary and is for validating the
-  // fixes for integer overflows on surface damage rects.
-  // Remove this CHECK before the next branch M99 scheduled on 01/20/2022.
-  if (!damage_rect_in_root_target_space.size().GetCheckedArea().IsValid()) {
-    const gfx::Rect default_damage_rect0 = default_damage_rect;
-    const gfx::Rect damage_rect0 = damage_rect;
-    const gfx::Rect damage_rect_in_root_target_space0 =
-        damage_rect_in_root_target_space;
-
-    const gfx::Transform dest_pass_transform_to_root_target0 =
-        dest_pass->transform_to_root_target;
-    const gfx::Transform parent_target_transform0 = parent_target_transform;
-
-    const gfx::Rect dest_root_target_clip_rect0 =
-        dest_root_target_clip_rect.value_or(gfx::Rect());
-
-    base::debug::Alias(&default_damage_rect0);
-    base::debug::Alias(&damage_rect0);
-    base::debug::Alias(&damage_rect_in_root_target_space0);
-    base::debug::Alias(&dest_pass_transform_to_root_target0);
-    base::debug::Alias(&parent_target_transform0);
-    base::debug::Alias(&dest_root_target_clip_rect0);
-
-    CHECK(false);
-  }
 }
 
 // This function returns the overlay candidate quad ptr which has an
diff --git a/components/webapps/services/web_app_origin_association/public/mojom/web_app_origin_association_parser.mojom b/components/webapps/services/web_app_origin_association/public/mojom/web_app_origin_association_parser.mojom
index 816d299..05712ee 100644
--- a/components/webapps/services/web_app_origin_association/public/mojom/web_app_origin_association_parser.mojom
+++ b/components/webapps/services/web_app_origin_association/public/mojom/web_app_origin_association_parser.mojom
@@ -9,7 +9,7 @@
 
 // The WebAppOriginAssociation structure is an internal representation of the
 // web app origin association file described in the "PWAs as URL Handlers"
-// explainer: https://github.com/WICG/pwa-url-handler/blob/master/explainer.md
+// explainer: https://github.com/WICG/pwa-url-handler/blob/main/explainer.md
 struct WebAppOriginAssociation {
   array<AssociatedWebApp> apps;
 };
diff --git a/components/webapps/services/web_app_origin_association/web_app_origin_association_parser.h b/components/webapps/services/web_app_origin_association/web_app_origin_association_parser.h
index 76e7b9a..161ce96 100644
--- a/components/webapps/services/web_app_origin_association/web_app_origin_association_parser.h
+++ b/components/webapps/services/web_app_origin_association/web_app_origin_association_parser.h
@@ -19,7 +19,7 @@
 
 // Handles the logic of parsing the web app origin association file from a
 // string as described in the "PWAs as URL Handlers" explainer:
-// https://github.com/WICG/pwa-url-handler/blob/master/explainer.md
+// https://github.com/WICG/pwa-url-handler/blob/main/explainer.md
 class WebAppOriginAssociationParser {
  public:
   WebAppOriginAssociationParser();
diff --git a/content/app/content_main_runner_impl.cc b/content/app/content_main_runner_impl.cc
index 27f444b1..5a36593 100644
--- a/content/app/content_main_runner_impl.cc
+++ b/content/app/content_main_runner_impl.cc
@@ -20,7 +20,6 @@
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/command_line.h"
-#include "base/compiler_specific.h"
 #include "base/debug/debugger.h"
 #include "base/debug/leak_annotations.h"
 #include "base/debug/stack_trace.h"
@@ -721,8 +720,8 @@
 
 #if !BUILDFLAG(IS_WIN)
 
-  base::GlobalDescriptors* g_fds = base::GlobalDescriptors::GetInstance();
-  ALLOW_UNUSED_LOCAL(g_fds);
+  [[maybe_unused]] base::GlobalDescriptors* g_fds =
+      base::GlobalDescriptors::GetInstance();
 
 // On Android, the ipc_fd is passed through the Java service.
 #if !BUILDFLAG(IS_ANDROID)
diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
index 0b0acf8..14290f3 100644
--- a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
+++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -943,12 +943,9 @@
   RunAriaTest(FILE_PATH_LITERAL("aria-insertion-deletion.html"));
 }
 
-#if !defined(OS_CHROMEOS)
-// TODO(accessibility) Reennable. See crrev.com/c//3396516.
 IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, AccessibilityAriaInvalid) {
   RunAriaTest(FILE_PATH_LITERAL("aria-invalid.html"));
 }
-#endif  // defined(OS_CHROMEOS)
 
 IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest,
                        AccessibilityAriaKeyShortcuts) {
diff --git a/content/browser/compositor/viz_process_transport_factory.cc b/content/browser/compositor/viz_process_transport_factory.cc
index ba0d6ca..a9655d5 100644
--- a/content/browser/compositor/viz_process_transport_factory.cc
+++ b/content/browser/compositor/viz_process_transport_factory.cc
@@ -103,9 +103,7 @@
 class HostDisplayClient : public viz::HostDisplayClient {
  public:
   explicit HostDisplayClient(ui::Compositor* compositor)
-      : viz::HostDisplayClient(compositor->widget()), compositor_(compositor) {
-    ANALYZER_ALLOW_UNUSED(compositor_);
-  }
+      : viz::HostDisplayClient(compositor->widget()), compositor_(compositor) {}
   ~HostDisplayClient() override = default;
   HostDisplayClient(const HostDisplayClient&) = delete;
   HostDisplayClient& operator=(const HostDisplayClient&) = delete;
@@ -120,7 +118,7 @@
 #endif
 
  private:
-  const raw_ptr<ui::Compositor> compositor_;
+  [[maybe_unused]] const raw_ptr<ui::Compositor> compositor_;
 };
 
 }  // namespace
@@ -271,7 +269,6 @@
 void VizProcessTransportFactory::DisableGpuCompositing(
     ui::Compositor* guilty_compositor) {
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-  ALLOW_UNUSED_LOCAL(compositing_mode_reporter_);
   // A fatal error has occurred and we can't fall back to software compositing
   // on CrOS. These can be unrecoverable hardware errors, or bugs that should
   // not happen. Crash the browser process to reset everything.
diff --git a/content/browser/compositor/viz_process_transport_factory.h b/content/browser/compositor/viz_process_transport_factory.h
index de03be97..4473da8 100644
--- a/content/browser/compositor/viz_process_transport_factory.h
+++ b/content/browser/compositor/viz_process_transport_factory.h
@@ -128,7 +128,8 @@
 
   // Controls the compositing mode based on what mode the display compositors
   // are using.
-  const raw_ptr<viz::CompositingModeReporterImpl> compositing_mode_reporter_;
+  [[maybe_unused]] const raw_ptr<viz::CompositingModeReporterImpl>
+      compositing_mode_reporter_;
 
   // ContextProvider used on worker threads for rasterization.
   scoped_refptr<viz::RasterContextProvider> worker_context_provider_;
diff --git a/content/browser/font_access/font_access_manager_impl.cc b/content/browser/font_access/font_access_manager_impl.cc
index e8e05af..14d3326 100644
--- a/content/browser/font_access/font_access_manager_impl.cc
+++ b/content/browser/font_access/font_access_manager_impl.cc
@@ -21,7 +21,6 @@
 #include "content/browser/renderer_host/render_frame_host_impl.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
-#include "content/public/browser/font_access_delegate.h"
 #include "content/public/browser/global_routing_id.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/common/content_client.h"
@@ -135,70 +134,6 @@
 #endif
 }
 
-void FontAccessManagerImpl::ChooseLocalFonts(
-    const std::vector<std::string>& selection,
-    ChooseLocalFontsCallback callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-#if !defined(PLATFORM_HAS_LOCAL_FONT_ENUMERATION_IMPL)
-  std::move(callback).Run(blink::mojom::FontEnumerationStatus::kUnimplemented,
-                          {});
-#else
-  const BindingContext& context = receivers_.current_context();
-
-  RenderFrameHostImpl* rfh = RenderFrameHostImpl::FromID(context.frame_id);
-  if (rfh == nullptr) {
-    std::move(callback).Run(
-        blink::mojom::FontEnumerationStatus::kUnexpectedError, {});
-    return;
-  }
-
-  // Page Visibility is required for the API to function at all.
-  if (rfh->visibility() == blink::mojom::FrameVisibility::kNotRendered) {
-    std::move(callback).Run(blink::mojom::FontEnumerationStatus::kNotVisible,
-                            {});
-    return;
-  }
-
-  // Transient User Activation required before showing the chooser.
-  // This action will consume it.
-  if (!rfh->HasTransientUserActivation()) {
-    std::move(callback).Run(
-        blink::mojom::FontEnumerationStatus::kNeedsUserActivation, {});
-    return;
-  }
-  rfh->frame_tree_node()->UpdateUserActivationState(
-      blink::mojom::UserActivationUpdateType::kConsumeTransientActivation,
-      blink::mojom::UserActivationNotificationType::kNone);
-
-  FontAccessDelegate* delegate =
-      GetContentClient()->browser()->GetFontAccessDelegate();
-  // TODO(pwnall): It may be possible to replace the WeakPtr below with
-  //               base::Unretained(), if the FontAccessChooser guarantees that
-  //               the callback isn't run after the chooser is destroyed.
-  choosers_[context.frame_id] = delegate->RunChooser(
-      rfh, selection,
-      base::BindOnce(&FontAccessManagerImpl::DidChooseLocalFonts,
-                     weak_ptr_factory_.GetWeakPtr(), context.frame_id,
-                     std::move(callback)));
-#endif
-}
-
-void FontAccessManagerImpl::FindAllFonts(FindAllFontsCallback callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-#if !defined(PLATFORM_HAS_LOCAL_FONT_ENUMERATION_IMPL)
-  std::move(callback).Run(blink::mojom::FontEnumerationStatus::kUnimplemented,
-                          {});
-#else
-  font_enumeration_cache_
-      .AsyncCall(&FontEnumerationCache::GetFontEnumerationData)
-      .Then(base::BindOnce(&FontAccessManagerImpl::DidFindAllFonts,
-                           weak_ptr_factory_.GetWeakPtr(),
-                           std::move(callback)));
-#endif
-}
-
 void FontAccessManagerImpl::DidRequestPermission(
     EnumerateLocalFontsCallback callback,
     blink::mojom::PermissionStatus status) {
@@ -228,46 +163,4 @@
 #endif
 }
 
-void FontAccessManagerImpl::DidFindAllFonts(FindAllFontsCallback callback,
-                                            FontEnumerationData data) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-  if (data.status != blink::mojom::FontEnumerationStatus::kOk) {
-    std::move(callback).Run(data.status, {});
-    return;
-  }
-
-  const base::ReadOnlySharedMemoryMapping mapping = data.font_data.Map();
-  if (mapping.size() > std::numeric_limits<int>::max()) {
-    std::move(callback).Run(
-        blink::mojom::FontEnumerationStatus::kUnexpectedError, {});
-    return;
-  }
-
-  blink::FontEnumerationTable table;
-  table.ParseFromArray(mapping.memory(), static_cast<int>(mapping.size()));
-
-  std::vector<blink::mojom::FontMetadata> font_data;
-  for (const auto& element : table.fonts()) {
-    font_data.emplace_back(element.postscript_name(), element.full_name(),
-                           element.family(), element.style());
-  }
-
-  std::move(callback).Run(data.status, std::move(font_data));
-}
-
-void FontAccessManagerImpl::DidChooseLocalFonts(
-    GlobalRenderFrameHostId frame_id,
-    ChooseLocalFontsCallback callback,
-    blink::mojom::FontEnumerationStatus status,
-    std::vector<blink::mojom::FontMetadataPtr> fonts) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-  // The chooser has fulfilled its purpose. It's safe to dispose of it.
-  size_t erased = choosers_.erase(frame_id);
-  DCHECK_EQ(erased, 1u);
-
-  std::move(callback).Run(std::move(status), std::move(fonts));
-}
-
 }  // namespace content
diff --git a/content/browser/font_access/font_access_manager_impl.h b/content/browser/font_access/font_access_manager_impl.h
index d932262..84bf3203 100644
--- a/content/browser/font_access/font_access_manager_impl.h
+++ b/content/browser/font_access/font_access_manager_impl.h
@@ -16,8 +16,6 @@
 #include "base/threading/sequence_bound.h"
 #include "base/types/pass_key.h"
 #include "content/common/content_export.h"
-#include "content/public/browser/font_access_chooser.h"
-#include "content/public/browser/font_access_context.h"
 #include "content/public/browser/global_routing_id.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/receiver_set.h"
@@ -27,17 +25,14 @@
 namespace content {
 
 class FontEnumerationCache;
-struct FontEnumerationData;
 
 // The ownership hierarchy for this class is:
 //
 // StoragePartitionImpl (1) <- (1) FontAccessManagerImpl
 //
 // FontAccessManagerImpl (1) <- (*) BindingContext
-// FontAccessManagerImpl (1) <- (*) FontAccessChooser
 //
 // BindingContext (1) <- (1) GlobalRenderFrameHostId
-// GlobalRenderFrameHostId (1) <-- (1) FontAccessChooser
 //
 // Legend:
 //
@@ -53,8 +48,7 @@
 // GlobalRenderFrameHostId,
 //   obtained from a corresponding BindingContext
 class CONTENT_EXPORT FontAccessManagerImpl
-    : public blink::mojom::FontAccessManager,
-      public FontAccessContext {
+    : public blink::mojom::FontAccessManager {
  public:
   // Factory method for production instances.
   static std::unique_ptr<FontAccessManagerImpl> Create();
@@ -83,11 +77,6 @@
 
   // blink::mojom::FontAccessManager:
   void EnumerateLocalFonts(EnumerateLocalFontsCallback callback) override;
-  void ChooseLocalFonts(const std::vector<std::string>& selection,
-                        ChooseLocalFontsCallback callback) override;
-
-  // content::FontAccessContext:
-  void FindAllFonts(FindAllFontsCallback callback) override;
 
   void SkipPrivacyChecksForTesting(bool skip) {
     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -102,11 +91,6 @@
 
   void DidRequestPermission(EnumerateLocalFontsCallback callback,
                             blink::mojom::PermissionStatus status);
-  void DidFindAllFonts(FindAllFontsCallback callback, FontEnumerationData data);
-  void DidChooseLocalFonts(GlobalRenderFrameHostId frame_id,
-                           ChooseLocalFontsCallback callback,
-                           blink::mojom::FontEnumerationStatus status,
-                           std::vector<blink::mojom::FontMetadataPtr> fonts);
 
   SEQUENCE_CHECKER(sequence_checker_);
 
@@ -122,10 +106,6 @@
   bool skip_privacy_checks_for_testing_ GUARDED_BY_CONTEXT(sequence_checker_) =
       false;
 
-  // Here to keep the choosers alive for the user to interact with.
-  std::map<GlobalRenderFrameHostId, std::unique_ptr<FontAccessChooser>>
-      choosers_ GUARDED_BY_CONTEXT(sequence_checker_);
-
   base::WeakPtrFactory<FontAccessManagerImpl> weak_ptr_factory_
       GUARDED_BY_CONTEXT(sequence_checker_){this};
 };
diff --git a/content/browser/font_access/font_access_manager_impl_browsertest.cc b/content/browser/font_access/font_access_manager_impl_browsertest.cc
index 7afae23..aef2663 100644
--- a/content/browser/font_access/font_access_manager_impl_browsertest.cc
+++ b/content/browser/font_access/font_access_manager_impl_browsertest.cc
@@ -87,7 +87,6 @@
   FontAccessManagerImplBrowserTest() {
     std::vector<base::Feature> enabled_features({
         blink::features::kFontAccess,
-        blink::features::kFontAccessPersistent,
     });
     scoped_feature_list_->InitWithFeatures(std::move(enabled_features),
                                            /*disabled_features=*/{});
@@ -144,8 +143,7 @@
       EvalJs(shell(),
              "(async () => {"
              "  let fullName = '';"
-             "  const fonts = await navigator.fonts.query({persistentAccess: "
-             "true});"
+             "  const fonts = await navigator.fonts.query();"
              "  for (const item of fonts) {"
              "    if (item.postscriptName == 'MicrosoftYaHei') {"
              "      fullName = item.fullName;"
@@ -169,8 +167,7 @@
       EvalJs(shell(),
              "(async () => {"
              "  let family = '';"
-             "  const fonts = await navigator.fonts.query({persistentAccess: "
-             "true});"
+             "  const fonts = await navigator.fonts.query();"
              "  for (const item of fonts) {"
              "    if (item.postscriptName == 'MicrosoftYaHei') {"
              "      family = item.family;"
diff --git a/content/browser/font_access/font_access_manager_impl_unittest.cc b/content/browser/font_access/font_access_manager_impl_unittest.cc
index 35fed63..3bc33c88 100644
--- a/content/browser/font_access/font_access_manager_impl_unittest.cc
+++ b/content/browser/font_access/font_access_manager_impl_unittest.cc
@@ -65,26 +65,6 @@
     return result;
   }
 
-  std::pair<FontEnumerationStatus, std::vector<blink::mojom::FontMetadataPtr>>
-  ChooseLocalFonts(const std::vector<std::string>& selection) {
-    std::pair<FontEnumerationStatus, std::vector<blink::mojom::FontMetadataPtr>>
-        result;
-
-    base::RunLoop run_loop;
-    manager_->ChooseLocalFonts(
-        selection,
-        base::BindLambdaForTesting(
-            [&](FontEnumerationStatus status,
-                std::vector<blink::mojom::FontMetadataPtr> font_metadata) {
-              result.first = status;
-              result.second = std::move(font_metadata);
-              run_loop.Quit();
-            }));
-    run_loop.Run();
-
-    return result;
-  }
-
  private:
   const raw_ptr<blink::mojom::FontAccessManager> manager_;
 };
@@ -299,28 +279,6 @@
   EXPECT_EQ(status, FontEnumerationStatus::kPermissionDenied);
 }
 
-TEST_F(FontAccessManagerImplTest, FontAccessContextFindAllFontsTest) {
-  FontAccessContext* font_access_context =
-      static_cast<FontAccessContext*>(manager_impl_.get());
-
-  FontEnumerationStatus status;
-  std::vector<blink::mojom::FontMetadata> fonts;
-
-  base::RunLoop run_loop;
-  font_access_context->FindAllFonts(base::BindLambdaForTesting(
-      [&](FontEnumerationStatus find_status,
-          std::vector<blink::mojom::FontMetadata> find_fonts) {
-        status = find_status;
-        fonts = std::move(find_fonts);
-        run_loop.Quit();
-      }));
-  run_loop.Run();
-
-  EXPECT_EQ(status, FontEnumerationStatus::kOk);
-  EXPECT_GT(fonts.size(), 0u)
-      << "Enumeration expected to yield at least 1 font";
-}
-
 #endif
 
 }  // namespace
diff --git a/content/browser/gpu/gpu_data_manager_impl_private.cc b/content/browser/gpu/gpu_data_manager_impl_private.cc
index 70249be..6d086646 100644
--- a/content/browser/gpu/gpu_data_manager_impl_private.cc
+++ b/content/browser/gpu/gpu_data_manager_impl_private.cc
@@ -409,7 +409,7 @@
 }
 
 // Determines if Vulkan is available for the GPU process.
-bool ALLOW_UNUSED_TYPE VulkanAllowed() {
+[[maybe_unused]] bool VulkanAllowed() {
 #if BUILDFLAG(ENABLE_VULKAN)
   // Vulkan will be enabled if certain flags are present.
   // --enable-features=Vulkan will cause Vulkan to be used for compositing and
@@ -426,7 +426,7 @@
 }
 
 // Determines if Metal is available for the GPU process.
-bool ALLOW_UNUSED_TYPE MetalAllowed() {
+[[maybe_unused]] bool MetalAllowed() {
 #if BUILDFLAG(IS_MAC)
   return base::FeatureList::IsEnabled(features::kMetal);
 #else
diff --git a/content/browser/gpu/gpu_data_manager_impl_private_unittest.cc b/content/browser/gpu/gpu_data_manager_impl_private_unittest.cc
index 84e8802e..761e6be 100644
--- a/content/browser/gpu/gpu_data_manager_impl_private_unittest.cc
+++ b/content/browser/gpu/gpu_data_manager_impl_private_unittest.cc
@@ -65,8 +65,8 @@
   return GURL("http://bar.com/");
 }
 
-gpu::GpuFeatureInfo ALLOW_UNUSED_TYPE
-GetGpuFeatureInfoWithOneDisabled(gpu::GpuFeatureType disabled_feature) {
+[[maybe_unused]] gpu::GpuFeatureInfo GetGpuFeatureInfoWithOneDisabled(
+    gpu::GpuFeatureType disabled_feature) {
   gpu::GpuFeatureInfo gpu_feature_info;
   for (auto& status : gpu_feature_info.status_values)
     status = gpu::GpuFeatureStatus::kGpuFeatureStatusEnabled;
diff --git a/content/browser/locks/lock_manager_browsertest.cc b/content/browser/locks/lock_manager_browsertest.cc
index eac1a325..fe1a8f6 100644
--- a/content/browser/locks/lock_manager_browsertest.cc
+++ b/content/browser/locks/lock_manager_browsertest.cc
@@ -228,8 +228,8 @@
 
 // Verify that content::FeatureObserver is notified that a frame stopped holding
 // locks when it is navigated away.
-// TODO(crbug.com/1286329): Flakes on Linux and Chrome OS.
-#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+// TODO(crbug.com/1286329): Flakes on Linux, Chrome OS, and Mac.
+#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC)
 #define MAYBE_ObserverNavigate DISABLED_ObserverNavigate
 #else
 #define MAYBE_ObserverNavigate ObserverNavigate
diff --git a/content/browser/media/key_system_support_impl_unittest.cc b/content/browser/media/key_system_support_impl_unittest.cc
index 7b151ae..dc71090b 100644
--- a/content/browser/media/key_system_support_impl_unittest.cc
+++ b/content/browser/media/key_system_support_impl_unittest.cc
@@ -143,8 +143,8 @@
     return is_supported;
   }
 
-  gpu::GpuFeatureInfo ALLOW_UNUSED_TYPE
-  GetGpuFeatureInfoWithOneDisabled(gpu::GpuFeatureType disabled_feature) {
+  [[maybe_unused]] gpu::GpuFeatureInfo GetGpuFeatureInfoWithOneDisabled(
+      gpu::GpuFeatureType disabled_feature) {
     gpu::GpuFeatureInfo gpu_feature_info;
     for (auto& status : gpu_feature_info.status_values)
       status = gpu::GpuFeatureStatus::kGpuFeatureStatusEnabled;
diff --git a/content/browser/plugin_private_storage_helper.cc b/content/browser/plugin_private_storage_helper.cc
index 90afa06c..99fc364 100644
--- a/content/browser/plugin_private_storage_helper.cc
+++ b/content/browser/plugin_private_storage_helper.cc
@@ -13,7 +13,6 @@
 #include <vector>
 
 #include "base/bind.h"
-#include "base/compiler_specific.h"
 #include "base/containers/contains.h"
 #include "base/files/file.h"
 #include "base/files/file_enumerator.h"
@@ -393,11 +392,11 @@
     storage::FileSystemQuotaUtil* quota_util = backend->GetQuotaUtil();
     // TODO(https://crbug.com/1231162): determine whether EME/CDM/plugin private
     // file system will be partitioned and use the appropriate StorageKey.
-    base::File::Error result = quota_util->DeleteStorageKeyDataOnFileTaskRunner(
-        filesystem_context_.get(), nullptr,
-        blink::StorageKey(url::Origin::Create(origin)),
-        storage::kFileSystemTypePluginPrivate);
-    ALLOW_UNUSED_LOCAL(result);
+    [[maybe_unused]] base::File::Error result =
+        quota_util->DeleteStorageKeyDataOnFileTaskRunner(
+            filesystem_context_.get(), nullptr,
+            blink::StorageKey(url::Origin::Create(origin)),
+            storage::kFileSystemTypePluginPrivate);
     DLOG_IF(ERROR, result != base::File::FILE_OK)
         << "Unable to delete the plugin data for " << origin;
   }
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc
index cbc416b..22c448ad 100644
--- a/content/browser/storage_partition_impl.cc
+++ b/content/browser/storage_partition_impl.cc
@@ -1467,11 +1467,6 @@
   return filesystem_context_.get();
 }
 
-FontAccessContext* StoragePartitionImpl::GetFontAccessContext() {
-  DCHECK(initialized_);
-  return font_access_manager_.get();
-}
-
 storage::DatabaseTracker* StoragePartitionImpl::GetDatabaseTracker() {
   DCHECK(initialized_);
   return database_tracker_.get();
diff --git a/content/browser/storage_partition_impl.h b/content/browser/storage_partition_impl.h
index 4f3ba3c..4356c6e3 100644
--- a/content/browser/storage_partition_impl.h
+++ b/content/browser/storage_partition_impl.h
@@ -68,7 +68,6 @@
 class CookieStoreManager;
 class FileSystemAccessEntryFactory;
 class FileSystemAccessManagerImpl;
-class FontAccessContext;
 class FontAccessManagerImpl;
 class GeneratedCodeCacheContext;
 class HostZoomLevelContext;
@@ -155,7 +154,6 @@
   storage::QuotaManager* GetQuotaManager() override;
   BackgroundSyncContextImpl* GetBackgroundSyncContext() override;
   storage::FileSystemContext* GetFileSystemContext() override;
-  FontAccessContext* GetFontAccessContext() override;
   storage::DatabaseTracker* GetDatabaseTracker() override;
   DOMStorageContextWrapper* GetDOMStorageContext() override;
   storage::mojom::LocalStorageControl* GetLocalStorageControl() override;
@@ -235,11 +233,11 @@
   AttributionManagerImpl* GetAttributionManager();
   void SetFontAccessManagerForTesting(
       std::unique_ptr<FontAccessManagerImpl> font_access_manager);
-  FontAccessManagerImpl* GetFontAccessManager();
   InterestGroupManager* GetInterestGroupManager();
   ComputePressureManager* GetComputePressureManager();
   std::string GetPartitionDomain();
   AggregationServiceImpl* GetAggregationService();
+  FontAccessManagerImpl* GetFontAccessManager();
 
   // blink::mojom::DomStorage interface.
   void OpenLocalStorage(
diff --git a/content/browser/web_contents/web_contents_observer_browsertest.cc b/content/browser/web_contents/web_contents_observer_browsertest.cc
index b396a23..54cc67e 100644
--- a/content/browser/web_contents/web_contents_observer_browsertest.cc
+++ b/content/browser/web_contents/web_contents_observer_browsertest.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include "base/test/scoped_feature_list.h"
+#include "build/build_config.h"
 #include "content/browser/renderer_host/render_frame_host_impl.h"
 #include "content/browser/service_worker/embedded_worker_instance.h"
 #include "content/browser/service_worker/embedded_worker_status.h"
@@ -475,8 +476,14 @@
   cookie_tracker.cookie_accesses().clear();
 }
 
+// TODO(https://crbug.com/1288573): Flaky on Mac.
+#if defined(OS_MAC)
+#define MAYBE_CookieCallbacks_Subframe DISABLED_CookieCallbacks_Subframe
+#else
+#define MAYBE_CookieCallbacks_Subframe CookieCallbacks_Subframe
+#endif
 IN_PROC_BROWSER_TEST_F(WebContentsObserverBrowserTest,
-                       CookieCallbacks_Subframe) {
+                       MAYBE_CookieCallbacks_Subframe) {
   CookieTracker cookie_tracker(web_contents());
 
   GURL first_party_url("http://a.com/");
diff --git a/content/browser/webauth/authenticator_common.cc b/content/browser/webauth/authenticator_common.cc
index 201b324..3cf1c07 100644
--- a/content/browser/webauth/authenticator_common.cc
+++ b/content/browser/webauth/authenticator_common.cc
@@ -1562,19 +1562,21 @@
     blink::mojom::AuthenticatorStatus status) {
   error_awaiting_user_acknowledgement_ = status;
 
-  if (!request_delegate_->DoesBlockRequestOnFailure(reason)) {
-    // Resolve the failed request right away.
-    CancelWithStatus(error_awaiting_user_acknowledgement_);
-    return;
-  }
-
-  // The UI blocks resolution of the failed request until it receives user
-  // acknowledgement. Tell the active FidoRequestHandler to stop processing in
-  // the meantime.
+  // The UI may decide to end the request immediately, or after user
+  // confirmation. Either way stop discoveries and authenticators now.
   if (request_handler_) {
     request_handler_->StopDiscoveries();
     request_handler_->CancelActiveAuthenticators();
   }
+
+  if (request_delegate_->DoesBlockRequestOnFailure(reason)) {
+    // The UI may have decided to start the request over. Thus do not assume
+    // anything about the state here.
+    return;
+  }
+
+  // The UI wishes the end the request immediately.
+  CancelWithStatus(error_awaiting_user_acknowledgement_);
 }
 
 void AuthenticatorCommon::BeginRequestTimeout(
diff --git a/content/browser/webauth/authenticator_impl_unittest.cc b/content/browser/webauth/authenticator_impl_unittest.cc
index 7810d82..45e23ed 100644
--- a/content/browser/webauth/authenticator_impl_unittest.cc
+++ b/content/browser/webauth/authenticator_impl_unittest.cc
@@ -1863,7 +1863,8 @@
       : action_callbacks_registered_callback_(
             std::move(action_callbacks_registered_callback)),
         attestation_consent_(attestation_consent),
-        started_over_callback_(std::move(started_over_callback)) {}
+        started_over_callback_(std::move(started_over_callback)),
+        does_block_request_on_failure_(!started_over_callback_.is_null()) {}
 
   TestAuthenticatorRequestDelegate(const TestAuthenticatorRequestDelegate&) =
       delete;
@@ -1886,8 +1887,7 @@
     std::move(action_callbacks_registered_callback_).Run();
     if (started_over_callback_) {
       action_callbacks_registered_callback_ = std::move(started_over_callback_);
-      base::SequencedTaskRunnerHandle::Get()->PostTask(
-          FROM_HERE, base::BindOnce(std::move(start_over_callback)));
+      start_over_callback_ = start_over_callback;
     }
   }
 
@@ -1932,10 +1932,22 @@
     }
   }
 
+  bool DoesBlockRequestOnFailure(InterestingFailureReason reason) override {
+    if (!does_block_request_on_failure_) {
+      return false;
+    }
+
+    std::move(start_over_callback_).Run();
+    does_block_request_on_failure_ = false;
+    return true;
+  }
+
   base::OnceClosure action_callbacks_registered_callback_;
   absl::optional<base::OnceClosure> cancel_callback_;
   const AttestationConsent attestation_consent_;
   base::OnceClosure started_over_callback_;
+  base::OnceClosure start_over_callback_;
+  bool does_block_request_on_failure_ = false;
   bool attestation_consent_queried_ = false;
 };
 
@@ -1982,7 +1994,8 @@
   // be restarted after action callbacks are registered, and
   // |started_over_callback| will replace
   // |action_callbacks_registered_callback|. This should then be called the
-  // second time action callbacks are registered.
+  // second time action callbacks are registered. It also causes
+  // DoesBlockRequestOnFailure to return true, once.
   base::OnceClosure started_over_callback_;
 };
 
@@ -3094,6 +3107,9 @@
 
   PublicKeyCredentialCreationOptionsPtr options =
       GetTestPublicKeyCredentialCreationOptions();
+  // Make the request fail so that it's started over.
+  options->authenticator_selection->user_verification_requirement =
+      device::UserVerificationRequirement::kRequired;
 
   TestRequestStartedCallback request_started;
   test_client_.action_callbacks_registered_callback =
@@ -3104,6 +3120,13 @@
   authenticator->MakeCredential(std::move(options), base::DoNothing());
   request_started.WaitForCallback();
   request_restarted.WaitForCallback();
+
+  const auto& discoveries_trace = virtual_device_factory_->trace()->discoveries;
+  ASSERT_EQ(discoveries_trace.size(), 2u);
+  EXPECT_TRUE(discoveries_trace[0].is_stopped);
+  EXPECT_TRUE(discoveries_trace[0].is_destroyed);
+  EXPECT_FALSE(discoveries_trace[1].is_stopped);
+  EXPECT_FALSE(discoveries_trace[1].is_destroyed);
 }
 
 TEST_F(AuthenticatorContentBrowserClientTest, GetAssertionStartOver) {
@@ -3123,6 +3146,13 @@
   authenticator->GetAssertion(std::move(options), base::DoNothing());
   request_started.WaitForCallback();
   request_restarted.WaitForCallback();
+
+  const auto& discoveries_trace = virtual_device_factory_->trace()->discoveries;
+  ASSERT_EQ(discoveries_trace.size(), 2u);
+  EXPECT_TRUE(discoveries_trace[0].is_stopped);
+  EXPECT_TRUE(discoveries_trace[0].is_destroyed);
+  EXPECT_FALSE(discoveries_trace[1].is_stopped);
+  EXPECT_FALSE(discoveries_trace[1].is_destroyed);
 }
 
 TEST_F(AuthenticatorContentBrowserClientTest, Unfocused) {
diff --git a/content/child/child_thread_impl.cc b/content/child/child_thread_impl.cc
index ca6d759..c446a31 100644
--- a/content/child/child_thread_impl.cc
+++ b/content/child/child_thread_impl.cc
@@ -15,7 +15,6 @@
 #include "base/bind.h"
 #include "base/clang_profiling_buildflags.h"
 #include "base/command_line.h"
-#include "base/compiler_specific.h"
 #include "base/debug/alias.h"
 #include "base/debug/leak_annotations.h"
 #include "base/debug/profiler.h"
@@ -756,8 +755,7 @@
     auto leaked_remote =
         std::make_unique<mojo::SharedRemote<mojom::ChildProcessHost>>(
             std::move(child_process_host_));
-    auto* leaked_remote_ptr = leaked_remote.release();
-    ALLOW_UNUSED_LOCAL(leaked_remote_ptr);
+    [[maybe_unused]] auto* leaked_remote_ptr = leaked_remote.release();
     ANNOTATE_LEAKING_OBJECT_PTR(leaked_remote_ptr);
   }
 
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc
index aa3c3af..1008af73 100644
--- a/content/child/runtime_features.cc
+++ b/content/child/runtime_features.cc
@@ -360,7 +360,6 @@
           {"FileHandling", blink::features::kFileHandlingAPI},
           {"Fledge", blink::features::kFledge},
           {"FontAccess", blink::features::kFontAccess},
-          {"FontAccessPersistent", blink::features::kFontAccessPersistent},
           {"FontSrcLocalMatching", features::kFontSrcLocalMatching},
           {"ForceSynchronousHTMLParsing",
            blink::features::kForceSynchronousHTMLParsing},
diff --git a/content/common/partition_alloc_support.cc b/content/common/partition_alloc_support.cc
index 8b2d79a1..d753f79 100644
--- a/content/common/partition_alloc_support.cc
+++ b/content/common/partition_alloc_support.cc
@@ -216,10 +216,8 @@
   CHECK(base::FeatureList::GetInstance());
 
   bool enable_brp = false;
-  bool split_main_partition = false;
-  ALLOW_UNUSED_LOCAL(split_main_partition);
-  bool use_dedicated_aligned_partition = false;
-  ALLOW_UNUSED_LOCAL(use_dedicated_aligned_partition);
+  [[maybe_unused]] bool split_main_partition = false;
+  [[maybe_unused]] bool use_dedicated_aligned_partition = false;
 #if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
 #if BUILDFLAG(USE_BACKUP_REF_PTR)
   bool process_affected_by_brp_flag = false;
diff --git a/content/public/android/java/src/org/chromium/content/browser/ChildProcessRanking.java b/content/public/android/java/src/org/chromium/content/browser/ChildProcessRanking.java
index 83d4e99b..ebc9504 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ChildProcessRanking.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ChildProcessRanking.java
@@ -300,6 +300,7 @@
             return;
         }
 
+        assert right >= left;
         final int gap = right - left;
 
         // If there is a large enough gap, place connection close to the end. This is a heuristic
@@ -368,7 +369,8 @@
                     throw new RuntimeException("Not in low rank group " + connection);
                 }
                 if (connection.connection.getImportanceInGroup() <= importance) {
-                    throw new RuntimeException("Wrong group importance order " + connection);
+                    throw new RuntimeException("Wrong group importance order " + connection + " "
+                            + connection.connection.getImportanceInGroup() + " " + importance);
                 }
                 importance = connection.connection.getImportanceInGroup();
             } else {
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityEventsTest.java b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityEventsTest.java
index b3596f01..f7c7e78 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityEventsTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityEventsTest.java
@@ -699,6 +699,24 @@
 
     @Test
     @SmallTest
+    public void test_inputCombobox() {
+        performTest("input-combobox.html", "input-combobox-expected-android.txt");
+    }
+
+    @Test
+    @SmallTest
+    public void test_inputComboboxAria1() {
+        performTest("input-combobox-aria1.html", "input-combobox-aria1-expected-android.txt");
+    }
+
+    @Test
+    @SmallTest
+    public void test_inputComboboxDialog() {
+        performTest("input-combobox-dialog.html", "input-combobox-dialog-expected-android.txt");
+    }
+
+    @Test
+    @SmallTest
     public void test_inputTypeTextValueChanged() {
         performTest("input-type-text-value-changed.html", EMPTY_EXPECTATIONS_FILE);
     }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTest.java b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTest.java
index cf09483f..cf73676 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTest.java
@@ -20,7 +20,6 @@
 import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_COPY;
 import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_CUT;
 import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_FOCUS;
-import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_LONG_CLICK;
 import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_NEXT_AT_MOVEMENT_GRANULARITY;
 import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_NEXT_HTML_ELEMENT;
 import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_PAGE_UP;
@@ -44,7 +43,6 @@
 import static org.chromium.content.browser.accessibility.AccessibilityContentShellTestUtils.sInputTypeMatcher;
 import static org.chromium.content.browser.accessibility.AccessibilityContentShellTestUtils.sRangeInfoMatcher;
 import static org.chromium.content.browser.accessibility.AccessibilityContentShellTestUtils.sTextMatcher;
-import static org.chromium.content.browser.accessibility.AccessibilityContentShellTestUtils.sTextOrContentDescriptionMatcher;
 import static org.chromium.content.browser.accessibility.AccessibilityContentShellTestUtils.sViewIdResourceNameMatcher;
 import static org.chromium.content.browser.accessibility.WebContentsAccessibilityImpl.EVENTS_DROPPED_HISTOGRAM;
 import static org.chromium.content.browser.accessibility.WebContentsAccessibilityImpl.EXTRAS_DATA_REQUEST_IMAGE_DATA_KEY;
@@ -60,7 +58,6 @@
 import static org.chromium.content.browser.accessibility.WebContentsAccessibilityImpl.PERCENTAGE_DROPPED_HISTOGRAM;
 
 import android.annotation.SuppressLint;
-import android.annotation.TargetApi;
 import android.content.ClipData;
 import android.content.ClipboardManager;
 import android.graphics.Rect;
@@ -104,33 +101,20 @@
  * implements the interface.
  */
 @RunWith(ContentJUnit4ClassRunner.class)
-@MinAndroidSdkLevel(Build.VERSION_CODES.LOLLIPOP)
-@TargetApi(Build.VERSION_CODES.LOLLIPOP)
 @SuppressLint("VisibleForTests")
 public class WebContentsAccessibilityTest {
     // Test output error messages
-    private static final String COMBOBOX_ERROR = "expanded combobox announcement was incorrect.";
     private static final String DISABLED_COMBOBOX_ERROR =
             "disabled combobox child elements should not be clickable";
-    private static final String LONG_CLICK_ERROR =
-            "node should not have the ACTION_LONG_CLICK action as an available action";
-    private static final String ACTION_SET_ERROR =
-            "node should have the ACTION_SET_TEXT action as an available action";
     private static final String THRESHOLD_ERROR =
             "Too many TYPE_WINDOW_CONTENT_CHANGED events received in an atomic update.";
     private static final String THRESHOLD_LOW_EVENT_COUNT_ERROR =
             "Expected more TYPE_WINDOW_CONTENT_CHANGED events"
             + "in an atomic update, is throttling still necessary?";
-    private static final String ARIA_INVALID_ERROR =
-            "Error message for aria-invalid node has not been set correctly.";
-    private static final String CONTENTEDITABLE_ERROR =
-            "contenteditable node is not being identified and/or received incorrect class name";
     private static final String SPELLING_ERROR =
             "node should have a Spannable with spelling correction for given text.";
     private static final String INPUT_RANGE_VALUE_MISMATCH =
             "Value for <input type='range'> is incorrect, did you honor 'step' value?";
-    private static final String INPUT_RANGE_VALUETEXT_MISMATCH =
-            "Value for <input type='range'> text is incorrect, did you honor aria-valuetext?";
     private static final String INPUT_RANGE_EVENT_ERROR =
             "TYPE_VIEW_SCROLLED event not received before timeout.";
     private static final String CACHING_ERROR = "AccessibilityNodeInfo cache has stale data";
@@ -262,7 +246,6 @@
      */
     @Test
     @SmallTest
-    @MinAndroidSdkLevel(Build.VERSION_CODES.O)
     public void testAccessibilityNodeInfo_inputTypeRange() throws Throwable {
         // Create a basic input range, and find the associated |AccessibilityNodeInfo| object.
         setupTestWithHTML("<input type='range' min='0' max='40'>");
@@ -316,7 +299,6 @@
      */
     @Test
     @SmallTest
-    @MinAndroidSdkLevel(Build.VERSION_CODES.O)
     public void testAccessibilityNodeInfo_inputTypeRange_withStepValue() throws Throwable {
         // Create a basic input range, and find the associated |AccessibilityNodeInfo| object.
         setupTestWithHTML("<input type='range' min='0' max='144' step='12'>");
@@ -372,7 +354,6 @@
      */
     @Test
     @SmallTest
-    @MinAndroidSdkLevel(Build.VERSION_CODES.O)
     public void testAccessibilityNodeInfo_inputTypeRange_withRequiredMin() throws Throwable {
         // Create a basic input range, and find the associated |AccessibilityNodeInfo| object.
         setupTestWithHTML("<input type='range' min='0' max='1000' step='1'>");
@@ -422,39 +403,6 @@
     }
 
     /**
-     * Test <input type="range"> nodes are properly populated when aria-valuetext is set.
-     */
-    @Test
-    @SmallTest
-    public void testAccessibilityNodeInfo_inputTypeRange_withAriaValueText() {
-        // Build a simple web page with input nodes that have aria-valuetext.
-        setupTestWithHTML(
-                "<input id='in1' type='range' value='1' min='0' max='2' aria-valuetext='medium'>"
-                + "<label for='in2'>This is a test label"
-                + "  <input id='in2' type='range' value='0' min='0' max='2' aria-valuetext='small'>"
-                + "</label>");
-
-        int vvIdInput1 = waitForNodeMatching(sViewIdResourceNameMatcher, "in1");
-        int vvIdInput2 = waitForNodeMatching(sViewIdResourceNameMatcher, "in2");
-        AccessibilityNodeInfoCompat mNodeInfo1 = createAccessibilityNodeInfo(vvIdInput1);
-        AccessibilityNodeInfoCompat mNodeInfo2 = createAccessibilityNodeInfo(vvIdInput2);
-        Assert.assertNotNull(NODE_TIMEOUT_ERROR, mNodeInfo1);
-        Assert.assertNotNull(NODE_TIMEOUT_ERROR, mNodeInfo2);
-
-        mActivityTestRule.sendEndOfTestSignal();
-
-        // Check the text of each element, and that RangeInfo has not been set.
-        mNodeInfo1 = createAccessibilityNodeInfo(vvIdInput1);
-        mNodeInfo2 = createAccessibilityNodeInfo(vvIdInput2);
-        Assert.assertEquals(
-                INPUT_RANGE_VALUETEXT_MISMATCH, "medium", mNodeInfo1.getText().toString());
-        Assert.assertEquals(INPUT_RANGE_VALUETEXT_MISMATCH, "small, This is a test label",
-                mNodeInfo2.getText().toString());
-        Assert.assertNull(INPUT_RANGE_VALUETEXT_MISMATCH, mNodeInfo1.getRangeInfo());
-        Assert.assertNull(INPUT_RANGE_VALUETEXT_MISMATCH, mNodeInfo2.getRangeInfo());
-    }
-
-    /**
      * Ensure we throttle TYPE_WINDOW_CONTENT_CHANGED events for large tree updates.
      */
     @Test
@@ -527,90 +475,6 @@
     }
 
     /**
-     * Ensure we send an announcement on combobox expansion.
-     */
-    @Test
-    @SmallTest
-    public void testEventText_Combobox() throws Throwable {
-        // Build a simple web page with a combobox, and focus the input field.
-        setupTestFromFile("content/test/data/android/input/input_combobox.html");
-
-        // Find a node in the accessibility tree of the correct class.
-        int comboBoxVirtualViewId =
-                waitForNodeMatching(sClassNameMatcher, "android.widget.EditText");
-        mNodeInfo = createAccessibilityNodeInfo(comboBoxVirtualViewId);
-        Assert.assertNotNull(NODE_TIMEOUT_ERROR, mNodeInfo);
-
-        focusNode(comboBoxVirtualViewId);
-
-        // Run JS code to expand the combobox
-        executeJS("expandCombobox()");
-
-        // Signal end of test
-        mActivityTestRule.sendEndOfTestSignal();
-
-        // We should have received a TYPE_ANNOUNCEMENT event, check announcement text.
-        Assert.assertEquals(COMBOBOX_ERROR, "expanded, 3 autocomplete options available.",
-                mTestData.getAnnouncementText());
-    }
-
-    /**
-     * Ensure we send an announcement on combobox expansion that opens a dialog.
-     */
-    @Test
-    @SmallTest
-    public void testEventText_Combobox_dialog() throws Throwable {
-        // Build a simple web page with a combobox, and focus the input field.
-        setupTestFromFile("content/test/data/android/input/input_combobox_dialog.html");
-
-        // Find a node in the accessibility tree of the correct class.
-        int comboBoxVirtualViewId =
-                waitForNodeMatching(sClassNameMatcher, "android.widget.EditText");
-        mNodeInfo = createAccessibilityNodeInfo(comboBoxVirtualViewId);
-        Assert.assertNotNull(NODE_TIMEOUT_ERROR, mNodeInfo);
-
-        focusNode(comboBoxVirtualViewId);
-
-        // Run JS code to expand the combobox
-        executeJS("expandCombobox()");
-
-        // Signal end of test
-        mActivityTestRule.sendEndOfTestSignal();
-
-        // We should have received a TYPE_ANNOUNCEMENT event, check announcement text.
-        Assert.assertEquals(
-                COMBOBOX_ERROR, "expanded, dialog opened.", mTestData.getAnnouncementText());
-    }
-
-    /**
-     * Ensure we send an announcement on combobox expansion with aria-1.0 spec.
-     */
-    @Test
-    @SmallTest
-    public void testEventText_Combobox_ariaOne() throws Throwable {
-        // Build a simple web page with a combobox, and focus the input field.
-        setupTestFromFile("content/test/data/android/input/input_combobox_aria1.0.html");
-
-        // Find a node in the accessibility tree of the correct class.
-        int comboBoxVirtualViewId =
-                waitForNodeMatching(sClassNameMatcher, "android.widget.EditText");
-        mNodeInfo = createAccessibilityNodeInfo(comboBoxVirtualViewId);
-        Assert.assertNotNull(NODE_TIMEOUT_ERROR, mNodeInfo);
-
-        focusNode(comboBoxVirtualViewId);
-
-        // Run JS code to expand the combobox
-        executeJS("expandCombobox()");
-
-        // Signal end of test
-        mActivityTestRule.sendEndOfTestSignal();
-
-        // We should have received a TYPE_ANNOUNCEMENT event, check announcement text.
-        Assert.assertEquals(COMBOBOX_ERROR, "expanded, 3 autocomplete options available.",
-                mTestData.getAnnouncementText());
-    }
-
-    /**
      * Ensure that disabled comboboxes and children are not shadow clickable.
      */
     @Test
@@ -979,95 +843,6 @@
     }
 
     /**
-     * Test |AccessibilityNodeInfo| object for contenteditable node.
-     */
-    @Test
-    @SmallTest
-    public void testNodeInfo_className_contenteditable() {
-        setupTestWithHTML("<div contenteditable>Edit This</div>");
-
-        int textNodeVirtualViewId =
-                waitForNodeMatching(sClassNameMatcher, "android.widget.EditText");
-        mNodeInfo = createAccessibilityNodeInfo(textNodeVirtualViewId);
-
-        Assert.assertNotNull(NODE_TIMEOUT_ERROR, mNodeInfo);
-        Assert.assertTrue(CONTENTEDITABLE_ERROR, mNodeInfo.isEditable());
-        Assert.assertEquals(CONTENTEDITABLE_ERROR, "Edit This", mNodeInfo.getText().toString());
-    }
-
-    /**
-     * Test |AccessibilityNodeInfo| object for node with aria-invalid="true".
-     */
-    @Test
-    @SmallTest
-    public void testNodeInfo_errorMessage_true() {
-        setupTestWithHTML("<input type='text' aria-invalid='true' value='123456789'>");
-
-        int textNodeVirtualViewId =
-                waitForNodeMatching(sClassNameMatcher, "android.widget.EditText");
-        mNodeInfo = createAccessibilityNodeInfo(textNodeVirtualViewId);
-
-        Assert.assertNotNull(NODE_TIMEOUT_ERROR, mNodeInfo);
-        Assert.assertTrue(ARIA_INVALID_ERROR, mNodeInfo.isContentInvalid());
-        Assert.assertEquals(ARIA_INVALID_ERROR, "Invalid entry", mNodeInfo.getError());
-    }
-
-    /**
-     * Test |AccessibilityNodeInfo| object for node with aria-invalid="spelling".
-     */
-    @Test
-    @SmallTest
-    public void testNodeInfo_errorMessage_spelling() {
-        setupTestWithHTML("<input type='text' aria-invalid='spelling' value='123456789'>");
-
-        int textNodeVirtualViewId =
-                waitForNodeMatching(sClassNameMatcher, "android.widget.EditText");
-        mNodeInfo = createAccessibilityNodeInfo(textNodeVirtualViewId);
-
-        Assert.assertNotNull(NODE_TIMEOUT_ERROR, mNodeInfo);
-        Assert.assertTrue(ARIA_INVALID_ERROR, mNodeInfo.isContentInvalid());
-        // Spelling and Grammar errors via aria-invalid label on the whole text field are reported
-        // as general errors.
-        Assert.assertEquals(ARIA_INVALID_ERROR, "Invalid entry", mNodeInfo.getError());
-    }
-
-    /**
-     * Test |AccessibilityNodeInfo| object for node with aria-invalid="grammar".
-     */
-    @Test
-    @SmallTest
-    public void testNodeInfo_errorMessage_grammar() {
-        setupTestWithHTML("<input type='text' aria-invalid='grammar' value='123456789'>");
-
-        int textNodeVirtualViewId =
-                waitForNodeMatching(sClassNameMatcher, "android.widget.EditText");
-        mNodeInfo = createAccessibilityNodeInfo(textNodeVirtualViewId);
-
-        Assert.assertNotNull(NODE_TIMEOUT_ERROR, mNodeInfo);
-        Assert.assertTrue(ARIA_INVALID_ERROR, mNodeInfo.isContentInvalid());
-        // Spelling and Grammar errors via aria-invalid label on the whole text field are reported
-        // as general errors.
-        Assert.assertEquals(ARIA_INVALID_ERROR, "Invalid entry", mNodeInfo.getError());
-    }
-
-    /**
-     * Test |AccessibilityNodeInfo| object for node with no aria-invalid.
-     */
-    @Test
-    @SmallTest
-    public void testNodeInfo_errorMessage_none() {
-        setupTestWithHTML("<input type='text'>");
-
-        int textNodeVirtualViewId =
-                waitForNodeMatching(sClassNameMatcher, "android.widget.EditText");
-        mNodeInfo = createAccessibilityNodeInfo(textNodeVirtualViewId);
-
-        Assert.assertNotNull(NODE_TIMEOUT_ERROR, mNodeInfo);
-        Assert.assertFalse(ARIA_INVALID_ERROR, mNodeInfo.isContentInvalid());
-        Assert.assertNull(ARIA_INVALID_ERROR, mNodeInfo.getError());
-    }
-
-    /**
      * Test |AccessibilityNodeInfo| object for node with spelling error, and ensure the
      * spelling error is encoded as a Spannable.
      **/
@@ -1104,8 +879,6 @@
      */
     @Test
     @SmallTest
-    @MinAndroidSdkLevel(Build.VERSION_CODES.O)
-    @TargetApi(Build.VERSION_CODES.O)
     public void testNodeInfo_extraDataAdded_characterLocations() {
         setupTestWithHTML("<h1>Simple test page</h1><section><p>Text</p></section>");
 
@@ -1190,8 +963,6 @@
      */
     @Test
     @SmallTest
-    @MinAndroidSdkLevel(Build.VERSION_CODES.O)
-    @TargetApi(Build.VERSION_CODES.O)
     public void testNodeInfo_extraDataAdded_imageData() {
         // Setup test page with example image (20px red square).
         setupTestWithHTML("<img id='id1' src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEU"
@@ -1265,50 +1036,11 @@
     }
 
     /**
-     * Test |AccessibilityNodeInfo| object actions to ensure we are not adding ACTION_LONG_CLICK
-     * to nodes due to verbose utterances issue.
-     */
-    @Test
-    @SmallTest
-    @MinAndroidSdkLevel(Build.VERSION_CODES.M)
-    public void testNodeInfo_noLongClickAction() {
-        // Build a simple web page with a node.
-        setupTestWithHTML("<p>Example paragraph</p>");
-
-        int textViewId = waitForNodeMatching(sTextOrContentDescriptionMatcher, "Example paragraph");
-        mNodeInfo = createAccessibilityNodeInfo(textViewId);
-        Assert.assertNotNull(NODE_TIMEOUT_ERROR, mNodeInfo);
-
-        // Confirm the ACTION_LONG_CLICK action has not been added to the node.
-        Assert.assertFalse(LONG_CLICK_ERROR, mNodeInfo.getActionList().contains(ACTION_LONG_CLICK));
-    }
-
-    /**
-     * Test |AccessibilityNodeInfo| object actions for text node.
-     */
-    @Test
-    @SmallTest
-    @MinAndroidSdkLevel(Build.VERSION_CODES.M)
-    public void testNodeInfo_Actions_SetText() {
-        // Load a web page with a text field.
-        setupTestWithHTML("<input type='text'>");
-
-        int textNodeVirtualViewId =
-                waitForNodeMatching(sClassNameMatcher, "android.widget.EditText");
-        mNodeInfo = createAccessibilityNodeInfo(textNodeVirtualViewId);
-        Assert.assertNotNull(NODE_TIMEOUT_ERROR, mNodeInfo);
-
-        // Confirm the ACTION_SET_TEXT action has been added to the node.
-        Assert.assertTrue(ACTION_SET_ERROR, mNodeInfo.getActionList().contains(ACTION_SET_TEXT));
-    }
-
-    /**
      * Test |AccessibilityNodeInfo| object actions for node is specifically user scrollable,
      * and not just programmatically scrollable.
      */
     @Test
     @SmallTest
-    @MinAndroidSdkLevel(Build.VERSION_CODES.M)
     public void testNodeInfo_Actions_OverflowHidden() throws Throwable {
         // Build a simple web page with a div and overflow:hidden
         setupTestWithHTML("<div title='1234' style='overflow:hidden; width: 200px; height:50px'>\n"
@@ -1354,7 +1086,6 @@
      */
     @Test
     @SmallTest
-    @MinAndroidSdkLevel(Build.VERSION_CODES.M)
     public void testNodeInfo_Actions_OverflowScroll() throws Throwable {
         // Build a simple web page with a div and overflow:scroll
         setupTestWithHTML("<div title='1234' style='overflow:scroll; width: 200px; height:50px'>\n"
@@ -1403,7 +1134,6 @@
      */
     @Test
     @SmallTest
-    @MinAndroidSdkLevel(Build.VERSION_CODES.M)
     public void testNodeInfoCache_AccessibilityFocusAndActions() throws Throwable {
         // Build a simple web page with two paragraphs that can be focused.
         setupTestWithHTML("<div>\n"
@@ -1866,7 +1596,6 @@
      */
     @Test
     @SmallTest
-    @MinAndroidSdkLevel(Build.VERSION_CODES.M)
     public void testPerformAction_paste() throws Throwable {
         // Build a simple web page with an input field.
         setupTestWithHTML("<input type='text'>");
@@ -2191,7 +1920,6 @@
         Assert.assertFalse(PERFORM_ACTION_ERROR, mNodeInfo2.isFocused());
     }
 
-    @MinAndroidSdkLevel(Build.VERSION_CODES.M)
     private void assertActionsContainNoScrolls(AccessibilityNodeInfoCompat nodeInfo) {
         Assert.assertFalse(nodeInfo.getActionList().contains(ACTION_SCROLL_FORWARD));
         Assert.assertFalse(nodeInfo.getActionList().contains(ACTION_SCROLL_BACKWARD));
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTreeTest.java b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTreeTest.java
index 5b7f1c3..1fc8d03 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTreeTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTreeTest.java
@@ -1803,6 +1803,12 @@
 
     @Test
     @SmallTest
+    public void test_inputTextRange() {
+        performHtmlTest("input-text-range.html");
+    }
+
+    @Test
+    @SmallTest
     public void test_inputTextReadOnly() {
         performHtmlTest("input-text-read-only.html");
     }
diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn
index ad9774a2..048ec33 100644
--- a/content/public/browser/BUILD.gn
+++ b/content/public/browser/BUILD.gn
@@ -171,9 +171,6 @@
     "file_system_access_write_item.h",
     "file_url_loader.h",
     "focused_node_details.h",
-    "font_access_chooser.h",
-    "font_access_context.h",
-    "font_access_delegate.h",
     "font_list_async.h",
     "frame_accept_header.cc",
     "frame_accept_header.h",
diff --git a/content/public/browser/font_access_chooser.h b/content/public/browser/font_access_chooser.h
deleted file mode 100644
index 8e77f3e..0000000
--- a/content/public/browser/font_access_chooser.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_PUBLIC_BROWSER_FONT_ACCESS_CHOOSER_H_
-#define CONTENT_PUBLIC_BROWSER_FONT_ACCESS_CHOOSER_H_
-
-#include "base/callback_forward.h"
-#include "content/common/content_export.h"
-#include "content/public/browser/render_frame_host.h"
-#include "third_party/blink/public/mojom/font_access/font_access.mojom.h"
-
-namespace content {
-
-class CONTENT_EXPORT FontAccessChooser {
- public:
-  using Callback =
-      base::OnceCallback<void(blink::mojom::FontEnumerationStatus,
-                              std::vector<blink::mojom::FontMetadataPtr>)>;
-  FontAccessChooser() = default;
-  virtual ~FontAccessChooser() = default;
-
-  FontAccessChooser(const FontAccessChooser&) = delete;
-  FontAccessChooser operator=(const FontAccessChooser&) = delete;
-};
-
-}  // namespace content
-
-#endif  // CONTENT_PUBLIC_BROWSER_FONT_ACCESS_CHOOSER_H_
diff --git a/content/public/browser/font_access_context.h b/content/public/browser/font_access_context.h
deleted file mode 100644
index 2d8ea84..0000000
--- a/content/public/browser/font_access_context.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_PUBLIC_BROWSER_FONT_ACCESS_CONTEXT_H_
-#define CONTENT_PUBLIC_BROWSER_FONT_ACCESS_CONTEXT_H_
-
-#include "base/callback_forward.h"
-#include "build/build_config.h"
-#include "content/common/content_export.h"
-#include "third_party/blink/public/mojom/font_access/font_access.mojom.h"
-
-#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \
-    BUILDFLAG(IS_MAC) || BUILDFLAG(IS_FUCHSIA)
-#define PLATFORM_HAS_LOCAL_FONT_ENUMERATION_IMPL 1
-#endif
-
-namespace content {
-
-class CONTENT_EXPORT FontAccessContext {
- public:
-  using FindAllFontsCallback =
-      base::OnceCallback<void(blink::mojom::FontEnumerationStatus,
-                              std::vector<blink::mojom::FontMetadata>)>;
-  virtual void FindAllFonts(FindAllFontsCallback callback) = 0;
-};
-
-}  // namespace content
-
-#endif  // CONTENT_PUBLIC_BROWSER_FONT_ACCESS_CONTEXT_H_
diff --git a/content/public/browser/font_access_delegate.h b/content/public/browser/font_access_delegate.h
deleted file mode 100644
index c8055c3..0000000
--- a/content/public/browser/font_access_delegate.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_PUBLIC_BROWSER_FONT_ACCESS_DELEGATE_H_
-#define CONTENT_PUBLIC_BROWSER_FONT_ACCESS_DELEGATE_H_
-
-#include "content/common/content_export.h"
-#include "content/public/browser/font_access_chooser.h"
-
-namespace content {
-
-class RenderFrameHost;
-
-class CONTENT_EXPORT FontAccessDelegate {
- public:
-  virtual ~FontAccessDelegate() = default;
-
-  virtual std::unique_ptr<FontAccessChooser> RunChooser(
-      RenderFrameHost* frame,
-      const std::vector<std::string>& selection,
-      FontAccessChooser::Callback callback) = 0;
-};
-
-}  // namespace content
-
-#endif  // CONTENT_PUBLIC_BROWSER_FONT_ACCESS_DELEGATE_H_
diff --git a/content/public/browser/storage_partition.h b/content/public/browser/storage_partition.h
index f85916b..2388801 100644
--- a/content/public/browser/storage_partition.h
+++ b/content/public/browser/storage_partition.h
@@ -67,7 +67,6 @@
 class DevToolsBackgroundServicesContext;
 class DOMStorageContext;
 class FileSystemAccessEntryFactory;
-class FontAccessContext;
 class GeneratedCodeCacheContext;
 class HostZoomLevelContext;
 class HostZoomMap;
@@ -135,7 +134,6 @@
   virtual storage::QuotaManager* GetQuotaManager() = 0;
   virtual BackgroundSyncContext* GetBackgroundSyncContext() = 0;
   virtual storage::FileSystemContext* GetFileSystemContext() = 0;
-  virtual FontAccessContext* GetFontAccessContext() = 0;
   virtual storage::DatabaseTracker* GetDatabaseTracker() = 0;
   virtual DOMStorageContext* GetDOMStorageContext() = 0;
   virtual storage::mojom::LocalStorageControl* GetLocalStorageControl() = 0;
diff --git a/content/public/renderer/render_frame_observer.h b/content/public/renderer/render_frame_observer.h
index 1282c25..28e22ce 100644
--- a/content/public/renderer/render_frame_observer.h
+++ b/content/public/renderer/render_frame_observer.h
@@ -124,6 +124,7 @@
   virtual void DidCommitProvisionalLoad(ui::PageTransition transition) {}
   virtual void DidFailProvisionalLoad() {}
   virtual void DidFinishLoad() {}
+  virtual void DidFinishLoadForPrinting() {}
   virtual void DidDispatchDOMContentLoadedEvent() {}
   virtual void DidHandleOnloadEvents() {}
   virtual void DidCreateScriptContext(v8::Local<v8::Context> context,
diff --git a/content/public/test/test_storage_partition.cc b/content/public/test/test_storage_partition.cc
index 2e8e73f..6a065aa6 100644
--- a/content/public/test/test_storage_partition.cc
+++ b/content/public/test/test_storage_partition.cc
@@ -107,10 +107,6 @@
   return nullptr;
 }
 
-FontAccessContext* TestStoragePartition::GetFontAccessContext() {
-  return nullptr;
-}
-
 ServiceWorkerContext* TestStoragePartition::GetServiceWorkerContext() {
   return service_worker_context_;
 }
diff --git a/content/public/test/test_storage_partition.h b/content/public/test/test_storage_partition.h
index dcd8c21..b30962e6 100644
--- a/content/public/test/test_storage_partition.h
+++ b/content/public/test/test_storage_partition.h
@@ -94,8 +94,6 @@
   }
   storage::FileSystemContext* GetFileSystemContext() override;
 
-  FontAccessContext* GetFontAccessContext() override;
-
   void set_background_sync_context(BackgroundSyncContext* context) {
     background_sync_context_ = context;
   }
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 8302cd97..1fd6d17 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -4058,6 +4058,11 @@
                                       ".MainFrameDidFinishLoad");
 }
 
+void RenderFrameImpl::DidFinishLoadForPrinting() {
+  for (auto& observer : observers_)
+    observer.DidFinishLoadForPrinting();
+}
+
 void RenderFrameImpl::DidFinishSameDocumentNavigation(
     blink::WebHistoryCommitType commit_type,
     bool is_synchronously_committed,
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index 760c40de..57caa4c 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -553,6 +553,7 @@
   void RunScriptsAtDocumentIdle() override;
   void DidHandleOnloadEvents() override;
   void DidFinishLoad() override;
+  void DidFinishLoadForPrinting() override;
   void DidFinishSameDocumentNavigation(
       blink::WebHistoryCommitType commit_type,
       bool is_synchronously_committed,
diff --git a/content/services/isolated_xr_device/xr_runtime_provider.cc b/content/services/isolated_xr_device/xr_runtime_provider.cc
index 1626107..aa77848 100644
--- a/content/services/isolated_xr_device/xr_runtime_provider.cc
+++ b/content/services/isolated_xr_device/xr_runtime_provider.cc
@@ -6,7 +6,6 @@
 
 #include "base/bind.h"
 #include "base/command_line.h"
-#include "base/compiler_specific.h"
 #include "base/trace_event/trace_event.h"
 #include "content/public/common/content_switches.h"
 #include "device/base/features.h"
@@ -74,9 +73,9 @@
 
 // If none of the runtimes are enabled, this function will be unused.
 // This is a bit more scalable than wrapping it in all the typedefs
-bool ALLOW_UNUSED_TYPE IsEnabled(const base::CommandLine* command_line,
-                                 const base::Feature& feature,
-                                 const std::string& name) {
+[[maybe_unused]] bool IsEnabled(const base::CommandLine* command_line,
+                                const base::Feature& feature,
+                                const std::string& name) {
   if (!command_line->HasSwitch(switches::kWebXrForceRuntime))
     return base::FeatureList::IsEnabled(feature);
 
@@ -92,11 +91,9 @@
 // runtime) should be enabled at once, so this chooses the most preferred among
 // available options.
 void IsolatedXRRuntimeProvider::PollForDeviceChanges() {
-  bool preferred_device_enabled = false;
-
-  // If none of the following runtimes are enabled,
-  // we'll get an error for 'preferred_device_enabled' being unused.
-  ALLOW_UNUSED_LOCAL(preferred_device_enabled);
+  // If none of the following runtimes are enabled, we'll get an error for
+  // 'preferred_device_enabled' being unused, thus [[maybe_unused]].
+  [[maybe_unused]] bool preferred_device_enabled = false;
 
 #if BUILDFLAG(ENABLE_OPENXR)
   if (!preferred_device_enabled && IsOpenXrHardwareAvailable()) {
@@ -117,11 +114,10 @@
 
 void IsolatedXRRuntimeProvider::SetupPollingForDeviceChanges() {
   bool any_runtimes_available = false;
-  const base::CommandLine* command_line =
+  [[maybe_unused]] const base::CommandLine* command_line =
       base::CommandLine::ForCurrentProcess();
-  // If none of the following runtimes are enabled,
-  // we'll get an error for 'command_line' being unused.
-  ALLOW_UNUSED_LOCAL(command_line);
+  // If none of the following runtimes are enabled, we'll get an error for
+  // 'command_line' being unused, thus [[maybe_unused]].
 
 #if BUILDFLAG(ENABLE_OPENXR)
   if (IsEnabled(command_line, device::features::kOpenXR,
@@ -215,4 +211,4 @@
     : device_service_host_(std::move(device_service_host)),
       io_task_runner_(std::move(io_task_runner)) {}
 
-IsolatedXRRuntimeProvider::~IsolatedXRRuntimeProvider() = default;
\ No newline at end of file
+IsolatedXRRuntimeProvider::~IsolatedXRRuntimeProvider() = default;
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index 59daf7b3..2a1ed0d 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -2497,7 +2497,6 @@
     "//gpu/ipc/host",
     "//gpu/ipc/service",
     "//ipc:test_support",
-    "//jingle:jingle_glue",
     "//media:test_support",
     "//media/capture",
     "//media/midi:midi",
diff --git a/content/test/data/accessibility/PRESUBMIT.py b/content/test/data/accessibility/PRESUBMIT.py
deleted file mode 100644
index 701b570b..0000000
--- a/content/test/data/accessibility/PRESUBMIT.py
+++ /dev/null
@@ -1,60 +0,0 @@
-# Copyright 2021 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Presubmit script for content/test/data/accessibility*"""
-
-PRESUBMIT_VERSION = '2.0.0'
-
-USE_PYTHON3 = True
-
-_ACCESSIBILITY_EVENTS_TEST_PATH = (
-    r"^content[\\/]test[\\/]data[\\/]accessibility[\\/]event[\\/].*\.html",
-)
-
-_ACCESSIBILITY_ANDROID_EVENTS_TEST_PATH = (
-    r"^.*[\\/]WebContentsAccessibilityEventsTest\.java",
-)
-
-def CheckAccessibilityEventsTestIncludesAndroid(input_api, output_api):
-  """Checks that commits that include a newly added, renamed/moved, or deleted
-  test in the DumpAccessibilityEventsTest suite also includes a corresponding
-  change to the Android test."""
-  def FilePathFilter(affected_file):
-    paths = _ACCESSIBILITY_EVENTS_TEST_PATH
-    return input_api.FilterSourceFile(affected_file, files_to_check=paths)
-
-  def AndroidFilePathFilter(affected_file):
-    paths = _ACCESSIBILITY_ANDROID_EVENTS_TEST_PATH
-    return input_api.FilterSourceFile(affected_file, files_to_check=paths)
-
-  # Only consider changes in the events test data path with html type.
-  if not any(input_api.AffectedFiles(include_deletes=True,
-                                     file_filter=FilePathFilter)):
-    return []
-
-  # If the commit contains any change to the Android test file, ignore.
-  if any(input_api.AffectedFiles(include_deletes=True,
-                                 file_filter=AndroidFilePathFilter)):
-    return []
-
-  # Only consider changes that are adding/renaming or deleting a file
-  message = []
-  for f in input_api.AffectedFiles(include_deletes=True,
-                                   file_filter=FilePathFilter):
-    if f.Action()=='A' or f.Action()=='D':
-      message = ("It appears that you are adding, renaming or deleting"
-                 "\na dump_accessibility_events* test, but have not included"
-                 "\na corresponding change for Android."
-                 "\nPlease include (or remove) the test from:"
-                 "\n    content/public/android/javatests/src/org/chromium/"
-                 "content/browser/accessibility/"
-                 "WebContentsAccessibilityEventsTest.java"
-                 "\nIf this message is confusing or annoying, please contact"
-                 "\nmembers of ui/accessibility/OWNERS.")
-
-  # If no message was set, return empty.
-  if not len(message):
-    return []
-
-  return [output_api.PresubmitPromptWarning(message)]
diff --git a/content/test/data/accessibility/PRESUBMIT_test.py b/content/test/data/accessibility/PRESUBMIT_test.py
deleted file mode 100755
index 6dc43c2b6..0000000
--- a/content/test/data/accessibility/PRESUBMIT_test.py
+++ /dev/null
@@ -1,122 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2021 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import sys
-import unittest
-
-import PRESUBMIT
-
-sys.path.append(
-    os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '..',
-      '..', '..'))
-from PRESUBMIT_test_mocks import (MockInputApi, MockOutputApi, MockAffectedFile)
-
-class AccessibilityEventsTestIncludesAndroidTest(unittest.TestCase):
-  # Test that no warning is raised when the Android file is also modified.
-  def testAndroidChangeIncluded(self):
-    mock_input_api = MockInputApi()
-
-    mock_input_api.files = [
-        MockAffectedFile('content/test/data/accessibility/event/foo.html',
-          [''], action='A'),
-        MockAffectedFile(
-          'accessibility/WebContentsAccessibilityEventsTest.java',
-          [''], action='M')
-    ]
-
-    msgs = PRESUBMIT.CheckAccessibilityEventsTestIncludesAndroid(
-        mock_input_api, MockOutputApi())
-    self.assertEqual(0, len(msgs),
-                     'Expected %d messages, found %d: %s'
-                     % (0, len(msgs), msgs))
-
-  # Test that a warning is raised when the Android file is not modified.
-  def testAndroidChangeMissing(self):
-    mock_input_api = MockInputApi()
-
-    mock_input_api.files = [
-        MockAffectedFile('content/test/data/accessibility/event/foo.html',
-          [''], action='A'),
-    ]
-
-    msgs = PRESUBMIT.CheckAccessibilityEventsTestIncludesAndroid(
-        mock_input_api, MockOutputApi())
-    self.assertEqual(1, len(msgs),
-                     'Expected %d messages, found %d: %s'
-                     % (1, len(msgs), msgs))
-
-  # Test that Android change is not required when no html file is added/removed.
-  def testIgnoreNonHtmlFiles(self):
-    mock_input_api = MockInputApi()
-
-    mock_input_api.files = [
-        MockAffectedFile('content/test/data/accessibility/event/foo.txt',
-          [''], action='A'),
-        MockAffectedFile('content/test/data/accessibility/event/foo.cc',
-          [''], action='A'),
-        MockAffectedFile('content/test/data/accessibility/event/foo.h',
-          [''], action='A'),
-        MockAffectedFile('content/test/data/accessibility/event/foo.py',
-          [''], action='A')
-    ]
-
-    msgs = PRESUBMIT.CheckAccessibilityEventsTestIncludesAndroid(
-        mock_input_api, MockOutputApi())
-    self.assertEqual(0, len(msgs),
-                     'Expected %d messages, found %d: %s'
-                     % (0, len(msgs), msgs))
-
-  # Test that Android change is not required for unrelated html files.
-  def testIgnoreNonRelatedHtmlFiles(self):
-    mock_input_api = MockInputApi()
-
-    mock_input_api.files = [
-        MockAffectedFile('content/test/data/accessibility/aria/foo.html',
-          [''], action='A'),
-        MockAffectedFile('content/test/data/accessibility/html/foo.html',
-          [''], action='A'),
-        MockAffectedFile('chrome/tests/data/accessibility/foo.html',
-          [''], action='A')
-    ]
-
-    msgs = PRESUBMIT.CheckAccessibilityEventsTestIncludesAndroid(
-        mock_input_api, MockOutputApi())
-    self.assertEqual(0, len(msgs),
-                     'Expected %d messages, found %d: %s'
-                     % (0, len(msgs), msgs))
-
-  # Test that only modifying an html file will not trigger the warning.
-  def testIgnoreModifiedFiles(self):
-    mock_input_api = MockInputApi()
-
-    mock_input_api.files = [
-        MockAffectedFile('content/test/data/accessibility/event/foo.html',
-          [''], action='M')
-    ]
-
-    msgs = PRESUBMIT.CheckAccessibilityEventsTestIncludesAndroid(
-        mock_input_api, MockOutputApi())
-    self.assertEqual(0, len(msgs),
-                     'Expected %d messages, found %d: %s'
-                     % (0, len(msgs), msgs))
-
-  # Test that deleting an html file will trigger the warning.
-  def testAndroidChangeMissingOnDeletedFile(self):
-    mock_input_api = MockInputApi()
-
-    mock_input_api.files = [
-        MockAffectedFile('content/test/data/accessibility/event/foo.html',
-          [], action='D')
-    ]
-
-    msgs = PRESUBMIT.CheckAccessibilityEventsTestIncludesAndroid(
-        mock_input_api, MockOutputApi())
-    self.assertEqual(1, len(msgs),
-                     'Expected %d messages, found %d: %s'
-                     % (1, len(msgs), msgs))
-
-if __name__ == '__main__':
-  unittest.main()
\ No newline at end of file
diff --git a/content/test/data/accessibility/event/input-combobox-aria1-expected-android.txt b/content/test/data/accessibility/event/input-combobox-aria1-expected-android.txt
new file mode 100644
index 0000000..e7fe3b4
--- /dev/null
+++ b/content/test/data/accessibility/event/input-combobox-aria1-expected-android.txt
@@ -0,0 +1,2 @@
+TYPE_VIEW_TEXT_SELECTION_CHANGED - [0, 0]
+TYPE_ANNOUNCEMENT - [expanded, 3 autocomplete options available.]
\ No newline at end of file
diff --git a/content/test/data/android/input/input_combobox_aria1.0.html b/content/test/data/accessibility/event/input-combobox-aria1.html
similarity index 88%
rename from content/test/data/android/input/input_combobox_aria1.0.html
rename to content/test/data/accessibility/event/input-combobox-aria1.html
index 19a59cd..50d6c67 100644
--- a/content/test/data/android/input/input_combobox_aria1.0.html
+++ b/content/test/data/accessibility/event/input-combobox-aria1.html
@@ -2,7 +2,8 @@
 <html>
   <head>
     <script>
-      function expandCombobox() {
+      function go() {
+        document.getElementById('test-input').focus();
         document.getElementById('test-input').setAttribute('aria-expanded', 'true');
         document.getElementById('test-listbox').removeAttribute('hidden');
         document.getElementById('test-input').setAttribute('aria-controls', 'test-listbox');
diff --git a/content/test/data/accessibility/event/input-combobox-dialog-expected-android.txt b/content/test/data/accessibility/event/input-combobox-dialog-expected-android.txt
new file mode 100644
index 0000000..133f41f
--- /dev/null
+++ b/content/test/data/accessibility/event/input-combobox-dialog-expected-android.txt
@@ -0,0 +1,3 @@
+TYPE_VIEW_TEXT_SELECTION_CHANGED - [0, 0]
+TYPE_ANNOUNCEMENT - [expanded, dialog opened.]
+TYPE_WINDOW_STATE_CHANGED - [contentTypes=16]
\ No newline at end of file
diff --git a/content/test/data/android/input/input_combobox_dialog.html b/content/test/data/accessibility/event/input-combobox-dialog.html
similarity index 88%
rename from content/test/data/android/input/input_combobox_dialog.html
rename to content/test/data/accessibility/event/input-combobox-dialog.html
index 911065b..bfc30b1 100644
--- a/content/test/data/android/input/input_combobox_dialog.html
+++ b/content/test/data/accessibility/event/input-combobox-dialog.html
@@ -2,7 +2,8 @@
 <html>
   <head>
     <script>
-      function expandCombobox() {
+      function go() {
+        document.getElementById('test-input').focus();
         document.getElementById('test-combobox').setAttribute('aria-expanded', 'true');
         document.getElementById('test-dialog').removeAttribute('hidden');
         document.getElementById('test-input').setAttribute('aria-controls', 'test-dialog');
diff --git a/content/test/data/accessibility/event/input-combobox-expected-android.txt b/content/test/data/accessibility/event/input-combobox-expected-android.txt
new file mode 100644
index 0000000..e7fe3b4
--- /dev/null
+++ b/content/test/data/accessibility/event/input-combobox-expected-android.txt
@@ -0,0 +1,2 @@
+TYPE_VIEW_TEXT_SELECTION_CHANGED - [0, 0]
+TYPE_ANNOUNCEMENT - [expanded, 3 autocomplete options available.]
\ No newline at end of file
diff --git a/content/test/data/android/input/input_combobox.html b/content/test/data/accessibility/event/input-combobox.html
similarity index 89%
rename from content/test/data/android/input/input_combobox.html
rename to content/test/data/accessibility/event/input-combobox.html
index 841de50..7835271 100644
--- a/content/test/data/android/input/input_combobox.html
+++ b/content/test/data/accessibility/event/input-combobox.html
@@ -2,7 +2,8 @@
 <html>
   <head>
     <script>
-      function expandCombobox() {
+      function go() {
+        document.getElementById('test-input').focus();
         document.getElementById('test-combobox').setAttribute('aria-expanded', 'true');
         document.getElementById('test-listbox').removeAttribute('hidden');
         document.getElementById('test-input').setAttribute('aria-controls', 'test-listbox');
diff --git a/content/test/data/accessibility/html/input-text-range-expected-android-external.txt b/content/test/data/accessibility/html/input-text-range-expected-android-external.txt
new file mode 100644
index 0000000..a513c7a
--- /dev/null
+++ b/content/test/data/accessibility/html/input-text-range-expected-android-external.txt
@@ -0,0 +1,6 @@
+WebView focusable focused scrollable actions:[CLEAR_FOCUS, AX_FOCUS] bundle:[chromeRole="rootWebArea"]
+++View actions:[AX_FOCUS] bundle:[chromeRole="genericContainer"]
+++++SeekBar text:"medium" clickable focusable actions:[FOCUS, CLICK, AX_FOCUS, NEXT, PREVIOUS, SCROLL_FORWARD, SCROLL_BACKWARD, SET_PROGRESS] bundle:[chromeRole="slider", roleDescription="slider"]
+++++View actions:[AX_FOCUS] bundle:[chromeRole="labelText"]
+++++++TextView text:"This is a test label " actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="staticText"]
+++++++SeekBar text:"small" clickable focusable actions:[FOCUS, CLICK, AX_FOCUS, NEXT, PREVIOUS, SCROLL_FORWARD, SET_PROGRESS] bundle:[chromeRole="slider", roleDescription="slider"]
\ No newline at end of file
diff --git a/content/test/data/accessibility/html/input-text-range.html b/content/test/data/accessibility/html/input-text-range.html
new file mode 100644
index 0000000..f76e4f0
--- /dev/null
+++ b/content/test/data/accessibility/html/input-text-range.html
@@ -0,0 +1,8 @@
+<html>
+  <body>
+    <input type='range' value='1' min='0' max='2' aria-valuetext='medium'>
+    <label for='in2'>This is a test label
+      <input type='range' value='0' min='0' max='2' aria-valuetext='small'>
+    </label>
+  </body>
+</html>
\ No newline at end of file
diff --git a/content/test/data/accessibility/html/selectmenu-open-expected-fuchsia.txt b/content/test/data/accessibility/html/selectmenu-open-expected-fuchsia.txt
index a7a9a8b2..ffb07a9 100644
--- a/content/test/data/accessibility/html/selectmenu-open-expected-fuchsia.txt
+++ b/content/test/data/accessibility/html/selectmenu-open-expected-fuchsia.txt
@@ -3,11 +3,11 @@
 ++++UNKNOWN
 ++++++UNKNOWN
 ++++++++UNKNOWN hidden
-++++++++++UNKNOWN label='Custom selectmenu button' actions='{DEFAULT}'
+++++++++++UNKNOWN actions='{DEFAULT}' value='Custom selectmenu button'
 ++++++++++++STATIC_TEXT label='Custom selectmenu button'
 ++++++++++++++UNKNOWN label='Custom selectmenu button'
 ++++++++UNKNOWN hidden
 ++++++++++UNKNOWN actions='{DEFAULT}'
 ++++++++++++UNKNOWN focusable selected label='Option 1' actions='{DEFAULT}'
 ++++++++++++UNKNOWN focusable label='Option 2' actions='{DEFAULT}'
-++++++++++++UNKNOWN focusable label='Option 3' actions='{DEFAULT}'
\ No newline at end of file
+++++++++++++UNKNOWN focusable label='Option 3' actions='{DEFAULT}'
diff --git a/device/fido/multiple_virtual_fido_device_factory.cc b/device/fido/multiple_virtual_fido_device_factory.cc
index afa723b0..b6cf8e3 100644
--- a/device/fido/multiple_virtual_fido_device_factory.cc
+++ b/device/fido/multiple_virtual_fido_device_factory.cc
@@ -31,9 +31,11 @@
     if (device.transport != transport) {
       continue;
     }
+    const size_t trace_index = trace_->discoveries.size();
+    trace_->discoveries.emplace_back();
     discoveries.push_back(std::make_unique<VirtualFidoDeviceDiscovery>(
-        device.transport, device.state, device.protocol, device.config,
-        std::move(device.disconnect_events)));
+        trace_, trace_index, device.transport, device.state, device.protocol,
+        device.config, std::move(device.disconnect_events)));
   }
   return discoveries;
 }
diff --git a/device/fido/multiple_virtual_fido_device_factory.h b/device/fido/multiple_virtual_fido_device_factory.h
index 4a995511..da1a537 100644
--- a/device/fido/multiple_virtual_fido_device_factory.h
+++ b/device/fido/multiple_virtual_fido_device_factory.h
@@ -14,6 +14,7 @@
 #include "device/fido/fido_types.h"
 #include "device/fido/virtual_ctap2_device.h"
 #include "device/fido/virtual_fido_device.h"
+#include "device/fido/virtual_fido_device_discovery.h"
 
 namespace device {
 namespace test {
@@ -60,6 +61,8 @@
 
  private:
   std::vector<DeviceDetails> devices_;
+  scoped_refptr<VirtualFidoDeviceDiscovery::Trace> trace_ =
+      new VirtualFidoDeviceDiscovery::Trace;
 };
 
 }  // namespace test
diff --git a/device/fido/virtual_fido_device_discovery.cc b/device/fido/virtual_fido_device_discovery.cc
index a3bd983..76fd3ff5 100644
--- a/device/fido/virtual_fido_device_discovery.cc
+++ b/device/fido/virtual_fido_device_discovery.cc
@@ -14,18 +14,28 @@
 namespace device {
 namespace test {
 
+VirtualFidoDeviceDiscovery::Trace::Trace() = default;
+VirtualFidoDeviceDiscovery::Trace::~Trace() = default;
+
 VirtualFidoDeviceDiscovery::VirtualFidoDeviceDiscovery(
+    scoped_refptr<Trace> trace,
+    size_t trace_index,
     FidoTransportProtocol transport,
     scoped_refptr<VirtualFidoDevice::State> state,
     ProtocolVersion supported_protocol,
     const VirtualCtap2Device::Config& ctap2_config,
     std::unique_ptr<FidoDeviceDiscovery::EventStream<bool>> disconnect_events)
     : FidoDeviceDiscovery(transport),
+      trace_(std::move(trace)),
+      trace_index_(trace_index),
       state_(std::move(state)),
       supported_protocol_(supported_protocol),
       ctap2_config_(ctap2_config),
       disconnect_events_(std::move(disconnect_events)) {}
-VirtualFidoDeviceDiscovery::~VirtualFidoDeviceDiscovery() = default;
+
+VirtualFidoDeviceDiscovery::~VirtualFidoDeviceDiscovery() {
+  trace_->discoveries[trace_index_].is_destroyed = true;
+}
 
 void VirtualFidoDeviceDiscovery::StartInternal() {
   std::unique_ptr<FidoDevice> device;
@@ -56,5 +66,10 @@
   RemoveDevice(id_);
 }
 
+bool VirtualFidoDeviceDiscovery::MaybeStop() {
+  trace_->discoveries[trace_index_].is_stopped = true;
+  return FidoDeviceDiscovery::MaybeStop();
+}
+
 }  // namespace test
 }  // namespace device
diff --git a/device/fido/virtual_fido_device_discovery.h b/device/fido/virtual_fido_device_discovery.h
index bf46e18..9897422 100644
--- a/device/fido/virtual_fido_device_discovery.h
+++ b/device/fido/virtual_fido_device_discovery.h
@@ -18,7 +18,28 @@
     : public FidoDeviceDiscovery,
       public base::SupportsWeakPtr<VirtualFidoDeviceDiscovery> {
  public:
+  // Trace contains a history of the discovery objects that have been created by
+  // a given factory. VirtualFidoDeviceDiscovery gets a reference to this object
+  // and keeps its information up to date.
+  struct Trace : public base::RefCounted<Trace> {
+    Trace();
+    Trace(const Trace&) = delete;
+    Trace& operator=(const Trace&) = delete;
+
+    struct Discovery {
+      bool is_stopped = false;
+      bool is_destroyed = false;
+    };
+    std::vector<Discovery> discoveries;
+
+   private:
+    friend class base::RefCounted<Trace>;
+    ~Trace();
+  };
+
   VirtualFidoDeviceDiscovery(
+      scoped_refptr<Trace> trace,
+      size_t trace_index,
       FidoTransportProtocol transport,
       scoped_refptr<VirtualFidoDevice::State> state,
       ProtocolVersion supported_protocol,
@@ -31,10 +52,13 @@
 
  protected:
   void StartInternal() override;
+  bool MaybeStop() override;
 
  private:
   void Disconnect(bool _);
 
+  scoped_refptr<Trace> trace_;
+  const size_t trace_index_;
   scoped_refptr<VirtualFidoDevice::State> state_;
   const ProtocolVersion supported_protocol_;
   const VirtualCtap2Device::Config ctap2_config_;
diff --git a/device/fido/virtual_fido_device_factory.cc b/device/fido/virtual_fido_device_factory.cc
index 2c903840..2cd611c5 100644
--- a/device/fido/virtual_fido_device_factory.cc
+++ b/device/fido/virtual_fido_device_factory.cc
@@ -32,14 +32,21 @@
   return state_.get();
 }
 
+scoped_refptr<VirtualFidoDeviceDiscovery::Trace>
+VirtualFidoDeviceFactory::trace() {
+  return trace_;
+}
+
 std::vector<std::unique_ptr<FidoDiscoveryBase>>
 VirtualFidoDeviceFactory::Create(FidoTransportProtocol transport) {
   if (transport != transport_) {
     return {};
   }
+  const size_t trace_index = trace_->discoveries.size();
+  trace_->discoveries.emplace_back();
   return SingleDiscovery(std::make_unique<VirtualFidoDeviceDiscovery>(
-      transport_, state_, supported_protocol_, ctap2_config_,
-      /*disconnect_events=*/nullptr));
+      trace_, trace_index, transport_, state_, supported_protocol_,
+      ctap2_config_, /*disconnect_events=*/nullptr));
 }
 
 bool VirtualFidoDeviceFactory::IsTestOverride() {
diff --git a/device/fido/virtual_fido_device_factory.h b/device/fido/virtual_fido_device_factory.h
index 25ead64..8accb43a 100644
--- a/device/fido/virtual_fido_device_factory.h
+++ b/device/fido/virtual_fido_device_factory.h
@@ -6,12 +6,16 @@
 #define DEVICE_FIDO_VIRTUAL_FIDO_DEVICE_FACTORY_H_
 
 #include <memory>
+#include <utility>
+#include <vector>
 
+#include "base/memory/scoped_refptr.h"
 #include "device/fido/fido_constants.h"
 #include "device/fido/fido_discovery_factory.h"
 #include "device/fido/fido_transport_protocol.h"
 #include "device/fido/virtual_ctap2_device.h"
 #include "device/fido/virtual_fido_device.h"
+#include "device/fido/virtual_fido_device_discovery.h"
 
 namespace device {
 namespace test {
@@ -39,6 +43,7 @@
   // the supported protocol to CTAP2.
   void SetCtap2Config(const VirtualCtap2Device::Config& config);
   VirtualFidoDevice::State* mutable_state();
+  scoped_refptr<VirtualFidoDeviceDiscovery::Trace> trace();
 
  protected:
   // device::FidoDiscoveryFactory:
@@ -52,6 +57,8 @@
       FidoTransportProtocol::kUsbHumanInterfaceDevice;
   VirtualCtap2Device::Config ctap2_config_;
   scoped_refptr<VirtualFidoDevice::State> state_ = new VirtualFidoDevice::State;
+  scoped_refptr<VirtualFidoDeviceDiscovery::Trace> trace_ =
+      new VirtualFidoDeviceDiscovery::Trace;
 };
 
 }  // namespace test
diff --git a/device/vr/openxr/openxr_controller.cc b/device/vr/openxr/openxr_controller.cc
index 2f4fae6..76a52d7 100644
--- a/device/vr/openxr/openxr_controller.cc
+++ b/device/vr/openxr/openxr_controller.cc
@@ -214,6 +214,7 @@
   RETURN_IF_XR_FAILED(CreateActionsForButton(OpenXrButtonType::kButton1));
   RETURN_IF_XR_FAILED(CreateActionsForButton(OpenXrButtonType::kButton2));
   RETURN_IF_XR_FAILED(CreateActionsForButton(OpenXrButtonType::kGrasp));
+  RETURN_IF_XR_FAILED(CreateActionsForButton(OpenXrButtonType::kShoulder));
 
   const std::string type_string = GetStringFromType(type_);
   const std::string name_prefix = type_string + "_controller_";
@@ -592,6 +593,9 @@
     case OpenXrButtonType::kGrasp:
       name_prefix += "grasp_";
       break;
+    case OpenXrButtonType::kShoulder:
+      name_prefix += "shoulder_";
+      break;
   }
 
   std::unordered_map<OpenXrButtonActionType, XrAction>& cur_button =
diff --git a/device/vr/openxr/openxr_defs.h b/device/vr/openxr/openxr_defs.h
index 9afb0473..ffdd9cb 100644
--- a/device/vr/openxr/openxr_defs.h
+++ b/device/vr/openxr/openxr_defs.h
@@ -28,6 +28,8 @@
     "/interaction_profiles/hp/mixed_reality_controller";
 constexpr char kHandSelectGraspInteractionProfilePath[] =
     "/interaction_profiles/microsoft/hand_interaction";
+constexpr char kHTCViveCosmosInteractionProfilePath[] =
+    "/interaction_profiles/htc/vive_cosmos_controller";
 
 }  // namespace device
 
diff --git a/device/vr/openxr/openxr_input_helper.cc b/device/vr/openxr/openxr_input_helper.cc
index 9560460..830ddc2 100644
--- a/device/vr/openxr/openxr_input_helper.cc
+++ b/device/vr/openxr/openxr_input_helper.cc
@@ -93,6 +93,11 @@
   if (grasp_button)
     builder.AddOptionalButtonData(grasp_button.value());
 
+  absl::optional<GamepadButton> shoulder_button =
+      controller.GetButton(OpenXrButtonType::kShoulder);
+  if (shoulder_button)
+    builder.AddOptionalButtonData(shoulder_button.value());
+
   return builder.GetGamepad();
 }
 
diff --git a/device/vr/openxr/openxr_interaction_profile_type.h b/device/vr/openxr/openxr_interaction_profile_type.h
index 5c522bb..bb85dc4 100644
--- a/device/vr/openxr/openxr_interaction_profile_type.h
+++ b/device/vr/openxr/openxr_interaction_profile_type.h
@@ -15,6 +15,7 @@
   kSamsungOdyssey = 5,
   kHPReverbG2 = 6,
   kHandSelectGrasp = 7,
+  kViveCosmos = 8,
   kCount,
 };
 }
diff --git a/device/vr/openxr/openxr_interaction_profiles.cc b/device/vr/openxr/openxr_interaction_profiles.cc
index 17d8784..c1712d5 100644
--- a/device/vr/openxr/openxr_interaction_profiles.cc
+++ b/device/vr/openxr/openxr_interaction_profiles.cc
@@ -110,6 +110,11 @@
           // Microsoft Hand Interaction
           {OpenXrInteractionProfileType::kHandSelectGrasp,
            {{"", {"generic-hand-select-grasp", "generic-hand-select"}}}},
+
+          // Vive Cosmos
+          {OpenXrInteractionProfileType::kViveCosmos,
+           {{"",
+             {"htc-vive-cosmos", "generic-trigger-squeeze-thumbstick"}}}},
       });
   return *kInputProfilesMap;
 }
@@ -397,8 +402,62 @@
            },
            /*left_button_maps=*/{},
            /*right_button_maps=*/{},
-           /*axis_maps=*/{}}
+           /*axis_maps=*/{}},
           // Microsoft Hands Profile
+
+          // Vive Cosmos
+          {OpenXrInteractionProfileType::kViveCosmos,
+           kHTCViveCosmosInteractionProfilePath,
+           /*required_extension=*/XR_HTC_VIVE_COSMOS_CONTROLLER_INTERACTION_EXTENSION_NAME,
+           GamepadMapping::kXrStandard,
+           /*common_button_maps=*/
+           {
+               {OpenXrButtonType::kTrigger,
+                {
+                    {OpenXrButtonActionType::kPress, "/input/trigger/value"},
+                    {OpenXrButtonActionType::kValue, "/input/trigger/value"},
+                }},
+               {OpenXrButtonType::kSqueeze,
+                {
+                    {OpenXrButtonActionType::kPress, "/input/squeeze/click"},
+                }},
+               {OpenXrButtonType::kThumbstick,
+                {
+                    {OpenXrButtonActionType::kPress, "/input/thumbstick/click"},
+                    {OpenXrButtonActionType::kTouch, "/input/thumbstick/touch"},
+                }},
+               {OpenXrButtonType::kShoulder,
+                {
+                    {OpenXrButtonActionType::kPress, "/input/shoulder/click"},
+                }},
+           },
+           /*left_button_maps=*/
+           {
+               {OpenXrButtonType::kButton1,
+                {
+                    {OpenXrButtonActionType::kPress, "/input/x/click"},
+                }},
+               {OpenXrButtonType::kButton2,
+                {
+                    {OpenXrButtonActionType::kPress, "/input/y/click"},
+                }},
+           },
+           /*right_button_maps=*/
+           {
+               {OpenXrButtonType::kButton1,
+                {
+                    {OpenXrButtonActionType::kPress, "/input/a/click"},
+                }},
+               {OpenXrButtonType::kButton2,
+                {
+                    {OpenXrButtonActionType::kPress, "/input/b/click"},
+                }},
+           },
+           /*axis_maps=*/
+           {
+               {OpenXrAxisType::kThumbstick, "/input/thumbstick"},
+           }},
+          // Vive Cosmos
       });
   return *kOpenXrControllerInteractionProfiles;
 }
diff --git a/device/vr/openxr/openxr_interaction_profiles.h b/device/vr/openxr/openxr_interaction_profiles.h
index 6f8bf04..01591603 100644
--- a/device/vr/openxr/openxr_interaction_profiles.h
+++ b/device/vr/openxr/openxr_interaction_profiles.h
@@ -29,7 +29,8 @@
   kButton1 = 5,
   kButton2 = 6,
   kGrasp = 7,
-  kMaxValue = 7,
+  kShoulder = 8,
+  kMaxValue = 8,
 };
 
 enum class OpenXrAxisType {
diff --git a/device/vr/openxr/openxr_util.cc b/device/vr/openxr/openxr_util.cc
index c5ba8f96..fb9215a3e 100644
--- a/device/vr/openxr/openxr_util.cc
+++ b/device/vr/openxr/openxr_util.cc
@@ -152,6 +152,7 @@
   EnableExtensionIfSupported(kExtSamsungOdysseyControllerExtensionName);
   EnableExtensionIfSupported(kExtHPMixedRealityControllerExtensionName);
   EnableExtensionIfSupported(kMSFTHandInteractionExtensionName);
+  EnableExtensionIfSupported(XR_HTC_VIVE_COSMOS_CONTROLLER_INTERACTION_EXTENSION_NAME);
 
   EnableExtensionIfSupported(XR_EXT_HAND_TRACKING_EXTENSION_NAME);
   EnableExtensionIfSupported(XR_MSFT_SPATIAL_ANCHOR_EXTENSION_NAME);
diff --git a/device/vr/openxr/test/openxr_test_helper.cc b/device/vr/openxr/test/openxr_test_helper.cc
index d6492946..7967ce6 100644
--- a/device/vr/openxr/test/openxr_test_helper.cc
+++ b/device/vr/openxr/test/openxr_test_helper.cc
@@ -767,6 +767,8 @@
         button_id = device::kX;
       } else if (PathContainsString(path_string, "/y/")) {
         button_id = device::kY;
+      } else if (PathContainsString(path_string, "/shoulder/")) {
+        button_id = device::kShoulder;
       } else {
         NOTREACHED() << "Unrecognized boolean button: " << path_string;
       }
@@ -977,6 +979,9 @@
     case device_test::mojom::InteractionProfileType::kHandSelectGrasp:
       interaction_profile_ = device::kHandSelectGraspInteractionProfilePath;
       break;
+    case device_test::mojom::InteractionProfileType::kViveCosmos:
+      interaction_profile_ = device::kHTCViveCosmosInteractionProfilePath;
+      break;
     case device_test::mojom::InteractionProfileType::kInvalid:
       NOTREACHED() << "Invalid EventData interaction_profile type";
       break;
diff --git a/device/vr/openxr/test/openxr_test_helper.h b/device/vr/openxr/test/openxr_test_helper.h
index 6576512..884df27 100644
--- a/device/vr/openxr/test/openxr_test_helper.h
+++ b/device/vr/openxr/test/openxr_test_helper.h
@@ -146,6 +146,7 @@
       device::kExtSamsungOdysseyControllerExtensionName,
       device::kExtHPMixedRealityControllerExtensionName,
       device::kMSFTHandInteractionExtensionName,
+      XR_HTC_VIVE_COSMOS_CONTROLLER_INTERACTION_EXTENSION_NAME,
       XR_MSFT_SECONDARY_VIEW_CONFIGURATION_EXTENSION_NAME,
   };
 
diff --git a/device/vr/public/mojom/browser_test_interfaces.mojom b/device/vr/public/mojom/browser_test_interfaces.mojom
index 29e51b0..cc2a3c8 100644
--- a/device/vr/public/mojom/browser_test_interfaces.mojom
+++ b/device/vr/public/mojom/browser_test_interfaces.mojom
@@ -100,6 +100,7 @@
   kSamsungOdyssey,
   kHPReverbG2,
   kHandSelectGrasp,
+  kViveCosmos,
   kInvalid,
 };
 
diff --git a/device/vr/test/test_hook.h b/device/vr/test/test_hook.h
index 94bc2854..3739247 100644
--- a/device/vr/test/test_hook.h
+++ b/device/vr/test/test_hook.h
@@ -33,6 +33,7 @@
   kX = 9,
   kY = 10,
   kThumbRest = 11,
+  kShoulder = 12,
   kProximitySensor = 31,
   kAxisTrackpad = 32,
   kAxisTrigger = 33,
diff --git a/docs/accessibility/os/espeak.md b/docs/accessibility/os/espeak.md
index a121ccbe..b1b10e35 100644
--- a/docs/accessibility/os/espeak.md
+++ b/docs/accessibility/os/espeak.md
@@ -45,10 +45,26 @@
 
   https://chromium.googlesource.com/chromiumos/third_party/espeak-ng
 
-All of the Chrome-specific changes are in the "chrome" branch. Clone
-the repository, switch to the "chrome" branch, and check out
+All of the Chrome-specific changes are in the "chrome" branch. 
+
+To get the source code locally:
+
+1. Clone the repository
+```
+git clone https://chromium.googlesource.com/chromiumos/third_party/espeak-ng
+```
+2. Enter the espeak-ng directory
+```
+cd espeak-ng/
+```
+3. Switch to the "chrome" branch
+```
+git checkout chrome
+```
+
+From there,
 [README.chrome](https://chromium.googlesource.com/chromiumos/third_party/espeak-ng/+/chrome/README.chrome)
-for build instructions.
+has instructions on building eSpeak.
 
 ## Releasing a new version of eSpeak for Chrome OS
 
diff --git a/docs/security/rule-of-2.md b/docs/security/rule-of-2.md
index 0f6de09..6d5676a 100644
--- a/docs/security/rule-of-2.md
+++ b/docs/security/rule-of-2.md
@@ -142,7 +142,8 @@
 return a well-formed response back to the caller in an IPC message. See [Safe
 Browsing's ZIP
 analyzer](https://cs.chromium.org/chromium/src/chrome/common/safe_browsing/zip_analyzer.h)
-for an example.
+for an example. The [Data Decoder Service](https://source.chromium.org/chromium/chromium/src/+/main:services/data_decoder/public/cpp/data_decoder.h)
+facilitates this safe decoding process for several common data formats.
 
 ### Verifying The Trustworthiness Of A Source
 
diff --git a/docs/testing/web_platform_tests.md b/docs/testing/web_platform_tests.md
index 760ef86e..822e76f26 100644
--- a/docs/testing/web_platform_tests.md
+++ b/docs/testing/web_platform_tests.md
@@ -442,3 +442,9 @@
 ```bash
 curl -v http://localhost:8081/wpt_internal/fake/foobar.html |& less
 ```
+
+#### Debugging with a debugger
+
+You are able to debug the inside of Chromium with a debugger for particular
+WPT tests. Refer to [Running web tests using the content shell](https://chromium.googlesource.com/chromium/src/+/refs/heads/main/docs/testing/web_tests_in_content_shell.md)
+for details.
diff --git a/docs/testing/web_tests_in_content_shell.md b/docs/testing/web_tests_in_content_shell.md
index c9b4b5b..ebf30bf 100644
--- a/docs/testing/web_tests_in_content_shell.md
+++ b/docs/testing/web_tests_in_content_shell.md
@@ -153,6 +153,20 @@
 out/Default/content_shell --enable-experimental-web-platform-features --ignore-certificate-errors --host-resolver-rules="MAP nonexistent.*.test ~NOTFOUND, MAP *.test. 127.0.0.1, MAP *.test 127.0.0.1"
 ```
 
+You are also able to debug the inside of Chromium with a debugger for
+particular WPT tests. After starting the WPT server, run particular tests via
+Content Shell from the debugger with the following command.
+(Refer to your debugger's manual for how to start a program from your debugger.)
+
+```bash
+out/Default/content_shell --run-web-tests http://localhost:8001/<test>
+```
+
+Chromium adopts multi-process architecture. If you want to debug the child
+renderer processes, use `--single-process` Content Shell option, or
+`--renderer-startup-dialog` option and attach the debugger to the renderer
+processes after starting the tests. Refer to the Debugging section below for details.
+
 ## Debugging
 
 ### `--single-process`
diff --git a/extensions/BUILD.gn b/extensions/BUILD.gn
index 0a884d1..53ddd25 100644
--- a/extensions/BUILD.gn
+++ b/extensions/BUILD.gn
@@ -9,391 +9,414 @@
 import("//tools/grit/repack.gni")
 import("//ui/base/ui_features.gni")
 
-assert(enable_extensions)
 assert(
     !(enable_autofill_assistant_api && is_official_build),
     "The AutofillAssistant Extension API must be disabled in official builds.")
 
-group("extensions_resources") {
-  public_deps = [
-    ":extensions_browser_resources",
-    ":extensions_renderer_resources",
-    ":extensions_resources_grd",
-  ]
-}
-
-grit("extensions_resources_grd") {
-  source = "extensions_resources.grd"
-  outputs = [
-    "grit/extensions_resources.h",
-    "extensions_resources.pak",
-  ]
-}
-
-grit("extensions_browser_resources") {
-  source = "browser/resources/extensions_browser_resources.grd"
-  outputs = [
-    "grit/extensions_browser_resources.h",
-    "grit/extensions_browser_resources_map.cc",
-    "grit/extensions_browser_resources_map.h",
-    "extensions_browser_resources_100_percent.pak",
-    "extensions_browser_resources_200_percent.pak",
-  ]
-}
-
-grit("extensions_renderer_resources") {
-  source = "renderer/resources/extensions_renderer_resources.grd"
-  defines = [ "is_chromecast=$is_chromecast" ]
-  outputs = [
-    "grit/extensions_renderer_resources.h",
-    "extensions_renderer_resources.pak",
-  ]
-  grit_flags = [
-    "-E",
-    "mojom_root=" + rebase_path(root_gen_dir, root_build_dir),
-  ]
-
-  deps = [
-    "//extensions/common:mojom_js",
-    "//extensions/common/api:mojom_js",
-    "//services/device/public/mojom:mojom_js",
-  ]
-}
-
-static_library("test_support") {
-  testonly = true
-  sources = [
-    "browser/api/declarative/test_rules_registry.cc",
-    "browser/api/declarative/test_rules_registry.h",
-    "browser/api/storage/settings_test_util.cc",
-    "browser/api/storage/settings_test_util.h",
-    "browser/api_test_utils.cc",
-    "browser/api_test_utils.h",
-    "browser/api_unittest.cc",
-    "browser/api_unittest.h",
-    "browser/app_window/test_app_window_contents.cc",
-    "browser/app_window/test_app_window_contents.h",
-    "browser/content_verifier/test_utils.cc",
-    "browser/content_verifier/test_utils.h",
-    "browser/extension_error_test_util.cc",
-    "browser/extension_error_test_util.h",
-    "browser/extensions_test.cc",
-    "browser/extensions_test.h",
-    "browser/guest_view/mime_handler_view/test_mime_handler_view_guest.cc",
-    "browser/guest_view/mime_handler_view/test_mime_handler_view_guest.h",
-    "browser/mock_extension_system.cc",
-    "browser/mock_extension_system.h",
-    "browser/mock_external_provider.cc",
-    "browser/mock_external_provider.h",
-    "browser/scoped_ignore_content_verifier_for_test.cc",
-    "browser/scoped_ignore_content_verifier_for_test.h",
-    "browser/test_event_router.cc",
-    "browser/test_event_router.h",
-    "browser/test_extension_registry_observer.cc",
-    "browser/test_extension_registry_observer.h",
-    "browser/test_extensions_browser_client.cc",
-    "browser/test_extensions_browser_client.h",
-    "browser/test_image_loader.cc",
-    "browser/test_image_loader.h",
-    "browser/test_management_policy.cc",
-    "browser/test_management_policy.h",
-    "browser/test_runtime_api_delegate.cc",
-    "browser/test_runtime_api_delegate.h",
-    "common/extension_builder.cc",
-    "common/extension_builder.h",
-    "common/manifest_test.cc",
-    "common/manifest_test.h",
-    "common/permissions/mock_manifest_permission.cc",
-    "common/permissions/mock_manifest_permission.h",
-    "common/permissions/permission_message_test_util.cc",
-    "common/permissions/permission_message_test_util.h",
-    "common/scoped_testing_manifest_handler_registry.cc",
-    "common/scoped_testing_manifest_handler_registry.h",
-    "renderer/test_extensions_renderer_client.cc",
-    "renderer/test_extensions_renderer_client.h",
-    "test/extension_background_page_waiter.cc",
-    "test/extension_background_page_waiter.h",
-    "test/extension_state_tester.cc",
-    "test/extension_state_tester.h",
-    "test/extension_test_message_listener.cc",
-    "test/extension_test_message_listener.h",
-    "test/extension_test_notification_observer.cc",
-    "test/extension_test_notification_observer.h",
-    "test/logging_timer.cc",
-    "test/logging_timer.h",
-    "test/result_catcher.cc",
-    "test/result_catcher.h",
-    "test/test_content_script_load_waiter.cc",
-    "test/test_content_script_load_waiter.h",
-    "test/test_content_utility_client.cc",
-    "test/test_content_utility_client.h",
-    "test/test_extension_dir.cc",
-    "test/test_extension_dir.h",
-    "test/test_extensions_client.cc",
-    "test/test_extensions_client.h",
-    "test/test_permission_message_provider.cc",
-    "test/test_permission_message_provider.h",
-  ]
-
-  deps = [
-    ":extensions_resources",
-    "//base",
-    "//build:chromeos_buildflags",
-    "//chrome/common:buildflags",
-    "//components/crx_file",
-    "//components/guest_view/browser:test_support",
-    "//components/keyed_service/content",
-    "//components/pref_registry",
-    "//components/prefs:test_support",
-    "//components/sync_preferences:test_support",
-    "//components/update_client",
-    "//components/user_prefs",
-    "//content/public/common",
-    "//content/test:test_support",
-    "//extensions/browser",
-    "//extensions/browser:test_support",
-    "//extensions/browser/api",
-    "//extensions/browser/updater",
-    "//extensions/common",
-    "//extensions/common:core_api_provider",
-    "//extensions/common/api",
-    "//extensions/common/api:extensions_features",
-    "//extensions/renderer",
-    "//net:test_support",
-    "//services/network/public/mojom",
-    "//testing/gmock",
-    "//testing/gtest",
-    "//third_party/cld_3/src/src:cld_3",
-    "//third_party/zlib/google:zip",
-  ]
-
-  # Generally, //extensions should not depend on //chromeos. However, a number
-  # of the APIs and the extensions shell already do. We should try to avoid
-  # expanding these dependencies.
-  if (is_chromeos_ash) {
-    deps += [ "//chromeos/login/login_state" ]
-  }
-
-  if (is_chromeos_lacros) {
-    deps += [ "//chromeos/lacros:test_support" ]
-  }
-
-  public_deps = [ "//content/public/browser" ]
-}
-
-repack("shell_and_test_pak") {
-  testonly = true
-
-  sources = [
-    "$root_gen_dir/content/browser/devtools/devtools_resources.pak",
-    "$root_gen_dir/content/content_resources.pak",
-    "$root_gen_dir/content/dev_ui_content_resources.pak",
-    "$root_gen_dir/content/shell/shell_resources.pak",
-    "$root_gen_dir/device/bluetooth/strings/bluetooth_strings_en-US.pak",
-    "$root_gen_dir/extensions/extensions_browser_resources_100_percent.pak",
-    "$root_gen_dir/extensions/extensions_renderer_resources.pak",
-    "$root_gen_dir/extensions/extensions_resources.pak",
-    "$root_gen_dir/extensions/shell/app_shell_resources.pak",
-    "$root_gen_dir/extensions/strings/extensions_strings_en-US.pak",
-    "$root_gen_dir/mojo/public/js/mojo_bindings_resources.pak",
-    "$root_gen_dir/third_party/blink/public/resources/blink_resources.pak",
-    "$root_gen_dir/third_party/blink/public/resources/blink_scaled_resources_100_percent.pak",
-    "$root_gen_dir/third_party/blink/public/strings/blink_strings_en-US.pak",
-    "$root_gen_dir/ui/resources/ui_resources_100_percent.pak",
-    "$root_gen_dir/ui/strings/app_locale_settings_en-US.pak",
-    "$root_gen_dir/ui/strings/ax_strings_en-US.pak",
-    "$root_gen_dir/ui/strings/ui_strings_en-US.pak",
-  ]
-
-  output = "$root_out_dir/extensions_shell_and_test.pak"
-
-  deps = [
-    ":extensions_resources",
-    "//content:content_resources",
-    "//content:dev_ui_content_resources",
-    "//content/browser/devtools:devtools_resources",
-    "//content/shell:resources",
-    "//device/bluetooth/strings",
-    "//extensions/shell:resources",
-    "//extensions/strings",
-    "//mojo/public/js:resources",
-    "//third_party/blink/public:resources",
-    "//third_party/blink/public:scaled_resources_100_percent",
-    "//third_party/blink/public/strings",
-    "//ui/resources",
-    "//ui/strings",
-  ]
-}
-
-test("extensions_unittests") {
-  use_xvfb = use_xvfb_in_this_config
-
-  sources = [
-    "test/extensions_unittests_main.cc",
-    "test/logging_timer_unittest.cc",
-  ]
-
-  data = [
-    "test/data/",
-    "//chrome/test/data/extensions/",
-    "//components/test/data/cast_certificate/",
-    "$root_out_dir/content_shell.pak",
-    "$root_out_dir/extensions_shell_and_test.pak",
-  ]
-
-  deps = [
-    ":extensions_resources",
-    ":shell_and_test_pak",
-    ":test_support",
-    "//base/test:test_support",
-    "//content/public/common",
-    "//content/test:test_support",
-    "//extensions/browser:unit_tests",
-    "//extensions/common",
-    "//extensions/common:unit_tests",
-    "//extensions/renderer:unit_tests",
-    "//extensions/shell:unit_tests",
-    "//services/data_decoder:lib",
-    "//services/service_manager/public/cpp/test:test_support",
-    "//ui/gl:test_support",
-  ]
-
-  data_deps = [ "//third_party/mesa_headers" ]
-
-  if (is_fuchsia) {
-    additional_manifest_fragments = [
-      "//build/config/fuchsia/test/jit_capabilities.test-cmx",
-      "//build/config/fuchsia/test/network_capabilities.test-cmx",
+if (is_component_build) {
+  component("extensions") {
+    visibility = [
+      "//extensions/common:common_constants",
+      "//extensions/common:export",
+    ]
+    public_deps = [
+      "//extensions/common:constants_impl",
+      "//extensions/common:export_impl",
     ]
   }
 }
 
-test("extensions_browsertests") {
-  use_xvfb = use_xvfb_in_this_config
-
-  data = [
-    "//extensions/test/data/",
-    "//net/tools/testserver/",
-    "//third_party/pywebsocket3/src/mod_pywebsocket/",
-    "$root_out_dir/extensions_shell_and_test.pak",
-  ]
-
-  deps = [
-    "//extensions/browser:browser_tests",
-    "//extensions/shell:browser_tests",
-  ]
-
-  data_deps = [ "//third_party/mesa_headers" ]
+# Used by targets that compile into the implementation.
+config("component_implementation") {
+  defines = [ "EXTENSIONS_COMPONENT_IMPLEMENTATION" ]
 }
 
-# TODO(rockot) bug 505926: These should be moved to extensions_browsertests but have
-# old dependencies on chrome files. The chrome dependencies should be removed
-# and these moved to the extensions_browsertests target. Currently, we solve
-# the problem by making this a source set and linking it into
-# //chrome/test:browser_tests.
-source_set("chrome_extensions_browsertests") {
-  testonly = true
-  sources = [
-    "browser/api/app_window/app_window_apitest.cc",
-    "browser/api/bluetooth/bluetooth_apitest.cc",
-    "browser/api/bluetooth/bluetooth_private_apitest.cc",
-    "browser/api/serial/serial_apitest.cc",
-    "browser/api/usb/usb_manual_apitest.cc",
-    "browser/app_window/app_window_browsertest.cc",
-    "browser/guest_view/mime_handler_view/mime_handler_view_browsertest.cc",
-    "renderer/script_context_browsertest.cc",
-  ]
-
-  defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ]
-
-  # These are the deps from browser_tests minus some internal Chrome ones that
-  # aren't allowed to be included here and that aren't needed.
-  deps = [
-    "//base",
-    "//base:i18n",
-    "//base/test:test_support",
-    "//build:chromeos_buildflags",
-    "//chrome/browser",
-    "//chrome/common/extensions/api",
-    "//chrome/renderer",
-    "//chrome/test:test_support",
-    "//components/autofill/content/browser:risk_proto",
-    "//components/autofill/content/renderer:test_support",
-    "//components/captive_portal/core:test_support",
-    "//components/dom_distiller/content/browser",
-    "//components/dom_distiller/core:test_support",
-    "//components/guest_view/browser:test_support",
-    "//components/javascript_dialogs",
-    "//components/resources",
-    "//components/strings",
-    "//components/sync",
-    "//components/sync:test_support_model",
-    "//components/translate/core/common",
-    "//crypto:platform",
-    "//crypto:test_support",
-    "//device/bluetooth:mocks",
-    "//extensions/browser/api/bluetooth",
-    "//extensions/common/api",
-    "//extensions/renderer",
-    "//google_apis:test_support",
-    "//media:test_support",
-    "//net",
-    "//net:test_support",
-    "//skia",
-    "//testing/gmock",
-    "//testing/gtest",
-    "//testing/perf",
-    "//third_party/blink/public:blink",
-    "//third_party/icu",
-    "//third_party/leveldatabase",
-    "//third_party/libaddressinput",
-    "//third_party/webrtc_overrides:webrtc_component",
-    "//third_party/widevine/cdm:headers",
-    "//ui/accessibility:test_support",
-    "//ui/base:test_support",
-    "//ui/compositor:test_support",
-    "//ui/resources",
-    "//ui/web_dialogs:test_support",
-    "//v8",
-  ]
-
-  if (is_chromeos_ash) {
-    deps += [ "//components/user_manager:test_support" ]
+# TODO(crbug.com/731689): Assert that extensions are enabled.
+# We can't do this here directly because some platforms where extensions aren't
+# enabled depend on //extensions/common:common_constants, which in turn depends
+# on the //extensions component target in component builds.
+if (enable_extensions) {
+  group("extensions_resources") {
+    public_deps = [
+      ":extensions_browser_resources",
+      ":extensions_renderer_resources",
+      ":extensions_resources_grd",
+    ]
   }
-}
 
-# TODO(rockot) bug 505926: This should be deleted for the same reason as
-# chrome_extensions_browsertests.
-source_set("chrome_extensions_interactive_uitests") {
-  testonly = true
-  sources = [ "browser/guest_view/mime_handler_view/mime_handler_view_interactive_uitest.cc" ]
+  grit("extensions_resources_grd") {
+    source = "extensions_resources.grd"
+    outputs = [
+      "grit/extensions_resources.h",
+      "extensions_resources.pak",
+    ]
+  }
 
-  defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ]
+  grit("extensions_browser_resources") {
+    source = "browser/resources/extensions_browser_resources.grd"
+    outputs = [
+      "grit/extensions_browser_resources.h",
+      "grit/extensions_browser_resources_map.cc",
+      "grit/extensions_browser_resources_map.h",
+      "extensions_browser_resources_100_percent.pak",
+      "extensions_browser_resources_200_percent.pak",
+    ]
+  }
 
-  # These are the deps from interactive_uitests minus some internal Chrome
-  # ones that aren't allowed to be included here and that aren't needed.
-  deps = [
-    "//chrome/browser",
-    "//chrome/browser/devtools",
-    "//chrome/renderer",
-    "//chrome/test:test_support",
-    "//components/sync",
-    "//content/app/resources",
-    "//crypto:platform",
-    "//crypto:test_support",
-    "//google_apis:test_support",
-    "//net",
-    "//net:net_resources",
-    "//net:test_support",
-    "//skia",
-    "//testing/gmock",
-    "//testing/gtest",
-    "//third_party/hunspell",
-    "//third_party/icu",
-    "//third_party/libpng",
-    "//third_party/zlib",
-    "//ui/base:test_support",
-    "//ui/resources:ui_test_pak",
-    "//ui/web_dialogs:test_support",
-  ]
+  grit("extensions_renderer_resources") {
+    source = "renderer/resources/extensions_renderer_resources.grd"
+    defines = [ "is_chromecast=$is_chromecast" ]
+    outputs = [
+      "grit/extensions_renderer_resources.h",
+      "extensions_renderer_resources.pak",
+    ]
+    grit_flags = [
+      "-E",
+      "mojom_root=" + rebase_path(root_gen_dir, root_build_dir),
+    ]
+
+    deps = [
+      "//extensions/common:mojom_js",
+      "//extensions/common/api:mojom_js",
+      "//services/device/public/mojom:mojom_js",
+    ]
+  }
+
+  static_library("test_support") {
+    testonly = true
+    sources = [
+      "browser/api/declarative/test_rules_registry.cc",
+      "browser/api/declarative/test_rules_registry.h",
+      "browser/api/storage/settings_test_util.cc",
+      "browser/api/storage/settings_test_util.h",
+      "browser/api_test_utils.cc",
+      "browser/api_test_utils.h",
+      "browser/api_unittest.cc",
+      "browser/api_unittest.h",
+      "browser/app_window/test_app_window_contents.cc",
+      "browser/app_window/test_app_window_contents.h",
+      "browser/content_verifier/test_utils.cc",
+      "browser/content_verifier/test_utils.h",
+      "browser/extension_error_test_util.cc",
+      "browser/extension_error_test_util.h",
+      "browser/extensions_test.cc",
+      "browser/extensions_test.h",
+      "browser/guest_view/mime_handler_view/test_mime_handler_view_guest.cc",
+      "browser/guest_view/mime_handler_view/test_mime_handler_view_guest.h",
+      "browser/mock_extension_system.cc",
+      "browser/mock_extension_system.h",
+      "browser/mock_external_provider.cc",
+      "browser/mock_external_provider.h",
+      "browser/scoped_ignore_content_verifier_for_test.cc",
+      "browser/scoped_ignore_content_verifier_for_test.h",
+      "browser/test_event_router.cc",
+      "browser/test_event_router.h",
+      "browser/test_extension_registry_observer.cc",
+      "browser/test_extension_registry_observer.h",
+      "browser/test_extensions_browser_client.cc",
+      "browser/test_extensions_browser_client.h",
+      "browser/test_image_loader.cc",
+      "browser/test_image_loader.h",
+      "browser/test_management_policy.cc",
+      "browser/test_management_policy.h",
+      "browser/test_runtime_api_delegate.cc",
+      "browser/test_runtime_api_delegate.h",
+      "common/extension_builder.cc",
+      "common/extension_builder.h",
+      "common/manifest_test.cc",
+      "common/manifest_test.h",
+      "common/permissions/mock_manifest_permission.cc",
+      "common/permissions/mock_manifest_permission.h",
+      "common/permissions/permission_message_test_util.cc",
+      "common/permissions/permission_message_test_util.h",
+      "common/scoped_testing_manifest_handler_registry.cc",
+      "common/scoped_testing_manifest_handler_registry.h",
+      "renderer/test_extensions_renderer_client.cc",
+      "renderer/test_extensions_renderer_client.h",
+      "test/extension_background_page_waiter.cc",
+      "test/extension_background_page_waiter.h",
+      "test/extension_state_tester.cc",
+      "test/extension_state_tester.h",
+      "test/extension_test_message_listener.cc",
+      "test/extension_test_message_listener.h",
+      "test/extension_test_notification_observer.cc",
+      "test/extension_test_notification_observer.h",
+      "test/logging_timer.cc",
+      "test/logging_timer.h",
+      "test/result_catcher.cc",
+      "test/result_catcher.h",
+      "test/test_content_script_load_waiter.cc",
+      "test/test_content_script_load_waiter.h",
+      "test/test_content_utility_client.cc",
+      "test/test_content_utility_client.h",
+      "test/test_extension_dir.cc",
+      "test/test_extension_dir.h",
+      "test/test_extensions_client.cc",
+      "test/test_extensions_client.h",
+      "test/test_permission_message_provider.cc",
+      "test/test_permission_message_provider.h",
+    ]
+
+    deps = [
+      ":extensions_resources",
+      "//base",
+      "//build:chromeos_buildflags",
+      "//chrome/common:buildflags",
+      "//components/crx_file",
+      "//components/guest_view/browser:test_support",
+      "//components/keyed_service/content",
+      "//components/pref_registry",
+      "//components/prefs:test_support",
+      "//components/sync_preferences:test_support",
+      "//components/update_client",
+      "//components/user_prefs",
+      "//content/public/common",
+      "//content/test:test_support",
+      "//extensions/browser",
+      "//extensions/browser:test_support",
+      "//extensions/browser/api",
+      "//extensions/browser/updater",
+      "//extensions/common",
+      "//extensions/common:core_api_provider",
+      "//extensions/common/api",
+      "//extensions/common/api:extensions_features",
+      "//extensions/renderer",
+      "//net:test_support",
+      "//services/network/public/mojom",
+      "//testing/gmock",
+      "//testing/gtest",
+      "//third_party/cld_3/src/src:cld_3",
+      "//third_party/zlib/google:zip",
+    ]
+
+    # Generally, //extensions should not depend on //chromeos. However, a number
+    # of the APIs and the extensions shell already do. We should try to avoid
+    # expanding these dependencies.
+    if (is_chromeos_ash) {
+      deps += [ "//chromeos/login/login_state" ]
+    }
+
+    if (is_chromeos_lacros) {
+      deps += [ "//chromeos/lacros:test_support" ]
+    }
+
+    public_deps = [ "//content/public/browser" ]
+  }
+
+  repack("shell_and_test_pak") {
+    testonly = true
+
+    sources = [
+      "$root_gen_dir/content/browser/devtools/devtools_resources.pak",
+      "$root_gen_dir/content/content_resources.pak",
+      "$root_gen_dir/content/dev_ui_content_resources.pak",
+      "$root_gen_dir/content/shell/shell_resources.pak",
+      "$root_gen_dir/device/bluetooth/strings/bluetooth_strings_en-US.pak",
+      "$root_gen_dir/extensions/extensions_browser_resources_100_percent.pak",
+      "$root_gen_dir/extensions/extensions_renderer_resources.pak",
+      "$root_gen_dir/extensions/extensions_resources.pak",
+      "$root_gen_dir/extensions/shell/app_shell_resources.pak",
+      "$root_gen_dir/extensions/strings/extensions_strings_en-US.pak",
+      "$root_gen_dir/mojo/public/js/mojo_bindings_resources.pak",
+      "$root_gen_dir/third_party/blink/public/resources/blink_resources.pak",
+      "$root_gen_dir/third_party/blink/public/resources/blink_scaled_resources_100_percent.pak",
+      "$root_gen_dir/third_party/blink/public/strings/blink_strings_en-US.pak",
+      "$root_gen_dir/ui/resources/ui_resources_100_percent.pak",
+      "$root_gen_dir/ui/strings/app_locale_settings_en-US.pak",
+      "$root_gen_dir/ui/strings/ax_strings_en-US.pak",
+      "$root_gen_dir/ui/strings/ui_strings_en-US.pak",
+    ]
+
+    output = "$root_out_dir/extensions_shell_and_test.pak"
+
+    deps = [
+      ":extensions_resources",
+      "//content:content_resources",
+      "//content:dev_ui_content_resources",
+      "//content/browser/devtools:devtools_resources",
+      "//content/shell:resources",
+      "//device/bluetooth/strings",
+      "//extensions/shell:resources",
+      "//extensions/strings",
+      "//mojo/public/js:resources",
+      "//third_party/blink/public:resources",
+      "//third_party/blink/public:scaled_resources_100_percent",
+      "//third_party/blink/public/strings",
+      "//ui/resources",
+      "//ui/strings",
+    ]
+  }
+
+  test("extensions_unittests") {
+    use_xvfb = use_xvfb_in_this_config
+
+    sources = [
+      "test/extensions_unittests_main.cc",
+      "test/logging_timer_unittest.cc",
+    ]
+
+    data = [
+      "test/data/",
+      "//chrome/test/data/extensions/",
+      "//components/test/data/cast_certificate/",
+      "$root_out_dir/content_shell.pak",
+      "$root_out_dir/extensions_shell_and_test.pak",
+    ]
+
+    deps = [
+      ":extensions_resources",
+      ":shell_and_test_pak",
+      ":test_support",
+      "//base/test:test_support",
+      "//content/public/common",
+      "//content/test:test_support",
+      "//extensions/browser:unit_tests",
+      "//extensions/common",
+      "//extensions/common:unit_tests",
+      "//extensions/renderer:unit_tests",
+      "//extensions/shell:unit_tests",
+      "//services/data_decoder:lib",
+      "//services/service_manager/public/cpp/test:test_support",
+      "//ui/gl:test_support",
+    ]
+
+    data_deps = [ "//third_party/mesa_headers" ]
+
+    if (is_fuchsia) {
+      additional_manifest_fragments = [
+        "//build/config/fuchsia/test/jit_capabilities.test-cmx",
+        "//build/config/fuchsia/test/network_capabilities.test-cmx",
+      ]
+    }
+  }
+
+  test("extensions_browsertests") {
+    use_xvfb = use_xvfb_in_this_config
+
+    data = [
+      "//extensions/test/data/",
+      "//net/tools/testserver/",
+      "//third_party/pywebsocket3/src/mod_pywebsocket/",
+      "$root_out_dir/extensions_shell_and_test.pak",
+    ]
+
+    deps = [
+      "//extensions/browser:browser_tests",
+      "//extensions/shell:browser_tests",
+    ]
+
+    data_deps = [ "//third_party/mesa_headers" ]
+  }
+
+  # TODO(rockot) bug 505926: These should be moved to extensions_browsertests but have
+  # old dependencies on chrome files. The chrome dependencies should be removed
+  # and these moved to the extensions_browsertests target. Currently, we solve
+  # the problem by making this a source set and linking it into
+  # //chrome/test:browser_tests.
+  source_set("chrome_extensions_browsertests") {
+    testonly = true
+    sources = [
+      "browser/api/app_window/app_window_apitest.cc",
+      "browser/api/bluetooth/bluetooth_apitest.cc",
+      "browser/api/bluetooth/bluetooth_private_apitest.cc",
+      "browser/api/serial/serial_apitest.cc",
+      "browser/api/usb/usb_manual_apitest.cc",
+      "browser/app_window/app_window_browsertest.cc",
+      "browser/guest_view/mime_handler_view/mime_handler_view_browsertest.cc",
+      "renderer/script_context_browsertest.cc",
+    ]
+
+    defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ]
+
+    # These are the deps from browser_tests minus some internal Chrome ones that
+    # aren't allowed to be included here and that aren't needed.
+    deps = [
+      "//base",
+      "//base:i18n",
+      "//base/test:test_support",
+      "//build:chromeos_buildflags",
+      "//chrome/browser",
+      "//chrome/common/extensions/api",
+      "//chrome/renderer",
+      "//chrome/test:test_support",
+      "//components/autofill/content/browser:risk_proto",
+      "//components/autofill/content/renderer:test_support",
+      "//components/captive_portal/core:test_support",
+      "//components/dom_distiller/content/browser",
+      "//components/dom_distiller/core:test_support",
+      "//components/guest_view/browser:test_support",
+      "//components/javascript_dialogs",
+      "//components/resources",
+      "//components/strings",
+      "//components/sync",
+      "//components/sync:test_support_model",
+      "//components/translate/core/common",
+      "//crypto:platform",
+      "//crypto:test_support",
+      "//device/bluetooth:mocks",
+      "//extensions/browser/api/bluetooth",
+      "//extensions/common/api",
+      "//extensions/renderer",
+      "//google_apis:test_support",
+      "//media:test_support",
+      "//net",
+      "//net:test_support",
+      "//skia",
+      "//testing/gmock",
+      "//testing/gtest",
+      "//testing/perf",
+      "//third_party/blink/public:blink",
+      "//third_party/icu",
+      "//third_party/leveldatabase",
+      "//third_party/libaddressinput",
+      "//third_party/webrtc_overrides:webrtc_component",
+      "//third_party/widevine/cdm:headers",
+      "//ui/accessibility:test_support",
+      "//ui/base:test_support",
+      "//ui/compositor:test_support",
+      "//ui/resources",
+      "//ui/web_dialogs:test_support",
+      "//v8",
+    ]
+
+    if (is_chromeos_ash) {
+      deps += [ "//components/user_manager:test_support" ]
+    }
+  }
+
+  # TODO(rockot) bug 505926: This should be deleted for the same reason as
+  # chrome_extensions_browsertests.
+  source_set("chrome_extensions_interactive_uitests") {
+    testonly = true
+    sources = [ "browser/guest_view/mime_handler_view/mime_handler_view_interactive_uitest.cc" ]
+
+    defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ]
+
+    # These are the deps from interactive_uitests minus some internal Chrome
+    # ones that aren't allowed to be included here and that aren't needed.
+    deps = [
+      "//chrome/browser",
+      "//chrome/browser/devtools",
+      "//chrome/renderer",
+      "//chrome/test:test_support",
+      "//components/sync",
+      "//content/app/resources",
+      "//crypto:platform",
+      "//crypto:test_support",
+      "//google_apis:test_support",
+      "//net",
+      "//net:net_resources",
+      "//net:test_support",
+      "//skia",
+      "//testing/gmock",
+      "//testing/gtest",
+      "//third_party/hunspell",
+      "//third_party/icu",
+      "//third_party/libpng",
+      "//third_party/zlib",
+      "//ui/base:test_support",
+      "//ui/resources:ui_test_pak",
+      "//ui/web_dialogs:test_support",
+    ]
+  }
 }
diff --git a/extensions/common/BUILD.gn b/extensions/common/BUILD.gn
index c7e95be..ecca9989 100644
--- a/extensions/common/BUILD.gn
+++ b/extensions/common/BUILD.gn
@@ -11,7 +11,41 @@
 
 # TODO(crbug.com/731689): Assert that extensions are enabled.
 
-source_set("common_constants") {
+group("common_constants") {
+  if (is_component_build) {
+    public_deps = [ "//extensions" ]
+  } else {
+    public_deps = [ ":constants_impl" ]
+  }
+}
+
+group("export") {
+  if (is_component_build) {
+    public_deps = [ "//extensions" ]
+  } else {
+    public_deps = [ ":export_impl" ]
+  }
+}
+
+source_set("export_impl") {
+  visibility = [
+    "//extensions",
+    "//extensions/common:*",
+  ]
+
+  configs += [ "//extensions:component_implementation" ]
+
+  sources = [ "extensions_export.h" ]
+}
+
+source_set("constants_impl") {
+  visibility = [
+    "//extensions",
+    "//extensions/common:common_constants",
+  ]
+
+  configs += [ "//extensions:component_implementation" ]
+
   sources = [
     "constants.cc",
     "constants.h",
@@ -22,6 +56,7 @@
     "//base",
     "//build:chromeos_buildflags",
     "//components/services/app_service/public/mojom",
+    "//extensions/common:export_impl",
   ]
 
   deps = [ "//build:chromecast_buildflags" ]
diff --git a/extensions/common/constants.cc b/extensions/common/constants.cc
index 306ae76..f6e8647f 100644
--- a/extensions/common/constants.cc
+++ b/extensions/common/constants.cc
@@ -118,6 +118,10 @@
 
 namespace extension_misc {
 
+const int kUnknownTabId = -1;
+const int kUnknownWindowId = -1;
+const int kCurrentWindowId = -2;
+
 #if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_CHROMECAST)
 // The extension id for the built-in component extension.
 const char kChromeVoxExtensionId[] = "mndnfokpggljbaajbnioimlmbfngpief";
diff --git a/extensions/common/constants.h b/extensions/common/constants.h
index 862266b..dd15849 100644
--- a/extensions/common/constants.h
+++ b/extensions/common/constants.h
@@ -8,134 +8,148 @@
 #include "base/files/file_path.h"
 #include "base/strings/string_piece_forward.h"
 #include "build/chromeos_buildflags.h"
+#include "extensions/common/extensions_export.h"
 
 namespace extensions {
 
 // Scheme we serve extension content from.
-extern const char kExtensionScheme[];
+EXTENSIONS_EXPORT extern const char kExtensionScheme[];
 
 // The name of the manifest inside an extension.
-extern const base::FilePath::CharType kManifestFilename[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType kManifestFilename[];
 
 // The name of the differential fingerprint file inside an extension.
-extern const base::FilePath::CharType kDifferentialFingerprintFilename[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType
+    kDifferentialFingerprintFilename[];
 
 // The name of locale folder inside an extension.
-extern const base::FilePath::CharType kLocaleFolder[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType kLocaleFolder[];
 
 // The name of the messages file inside an extension.
-extern const base::FilePath::CharType kMessagesFilename[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType kMessagesFilename[];
 
 // The name of the gzipped messages file inside an extension.
-extern const base::FilePath::CharType kGzippedMessagesFilename[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType
+    kGzippedMessagesFilename[];
 
 // The base directory for subdirectories with platform-specific code.
-extern const base::FilePath::CharType kPlatformSpecificFolder[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType
+    kPlatformSpecificFolder[];
 
 // A directory reserved for metadata, generated either by the webstore
 // or chrome.
-extern const base::FilePath::CharType kMetadataFolder[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType kMetadataFolder[];
 
 // Name of the verified contents file within the metadata folder.
-extern const base::FilePath::CharType kVerifiedContentsFilename[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType
+    kVerifiedContentsFilename[];
 
 // Name of the computed hashes file within the metadata folder.
-extern const base::FilePath::CharType kComputedHashesFilename[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType
+    kComputedHashesFilename[];
 
 // Name of the indexed ruleset directory for the Declarative Net Request API.
-extern const base::FilePath::CharType kIndexedRulesetDirectory[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType
+    kIndexedRulesetDirectory[];
 
 // The name of the directory inside the profile where extensions are
 // installed to.
-extern const char kInstallDirectoryName[];
+EXTENSIONS_EXPORT extern const char kInstallDirectoryName[];
 
 // The name of a temporary directory to install an extension into for
 // validation before finalizing install.
-extern const char kTempExtensionName[];
+EXTENSIONS_EXPORT extern const char kTempExtensionName[];
 
 // The file to write our decoded message catalogs to, relative to the
 // extension_path.
-extern const char kDecodedMessageCatalogsFilename[];
+EXTENSIONS_EXPORT extern const char kDecodedMessageCatalogsFilename[];
 
 // The filename to use for a background page generated from
 // background.scripts.
-extern const char kGeneratedBackgroundPageFilename[];
+EXTENSIONS_EXPORT extern const char kGeneratedBackgroundPageFilename[];
 
 // Path to imported modules.
-extern const char kModulesDir[];
+EXTENSIONS_EXPORT extern const char kModulesDir[];
 
 // The file extension (.crx) for extensions.
-extern const base::FilePath::CharType kExtensionFileExtension[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType
+    kExtensionFileExtension[];
 
 // The file extension (.pem) for private key files.
-extern const base::FilePath::CharType kExtensionKeyFileExtension[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType
+    kExtensionKeyFileExtension[];
 
 // Default frequency for auto updates, if turned on.
-extern const int kDefaultUpdateFrequencySeconds;
+EXTENSIONS_EXPORT extern const int kDefaultUpdateFrequencySeconds;
 
 // The name of the directory inside the profile where per-app local settings
 // are stored.
-extern const base::FilePath::CharType kLocalAppSettingsDirectoryName[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType
+    kLocalAppSettingsDirectoryName[];
 
 // The name of the directory inside the profile where per-extension local
 // settings are stored.
-extern const base::FilePath::CharType kLocalExtensionSettingsDirectoryName[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType
+    kLocalExtensionSettingsDirectoryName[];
 
 // The name of the directory inside the profile where per-app synced settings
 // are stored.
-extern const base::FilePath::CharType kSyncAppSettingsDirectoryName[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType
+    kSyncAppSettingsDirectoryName[];
 
 // The name of the directory inside the profile where per-extension synced
 // settings are stored.
-extern const base::FilePath::CharType kSyncExtensionSettingsDirectoryName[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType
+    kSyncExtensionSettingsDirectoryName[];
 
 // The name of the directory inside the profile where per-extension persistent
 // managed settings are stored.
-extern const base::FilePath::CharType kManagedSettingsDirectoryName[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType
+    kManagedSettingsDirectoryName[];
 
 // The name of the database inside the profile where chrome-internal
 // extension state resides.
-extern const base::FilePath::CharType kStateStoreName[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType kStateStoreName[];
 
 // The name of the database inside the profile where declarative extension
 // rules are stored.
-extern const base::FilePath::CharType kRulesStoreName[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType kRulesStoreName[];
 
 // The name of the database inside the profile where persistent dynamic user
 // script metadata is stored.
-extern const base::FilePath::CharType kScriptsStoreName[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType kScriptsStoreName[];
 
 // Statistics are logged to UMA with these strings as part of histogram name.
 // They can all be found under Extensions.Database.Open.<client>. Changing this
 // needs to synchronize with histograms.xml, AND will also become incompatible
 // with older browsers still reporting the previous values.
-extern const char kSettingsDatabaseUMAClientName[];
-extern const char kRulesDatabaseUMAClientName[];
-extern const char kStateDatabaseUMAClientName[];
-extern const char kScriptsDatabaseUMAClientName[];
+EXTENSIONS_EXPORT extern const char kSettingsDatabaseUMAClientName[];
+EXTENSIONS_EXPORT extern const char kRulesDatabaseUMAClientName[];
+EXTENSIONS_EXPORT extern const char kStateDatabaseUMAClientName[];
+EXTENSIONS_EXPORT extern const char kScriptsDatabaseUMAClientName[];
 
 // The URL query parameter key corresponding to multi-login user index.
-extern const char kAuthUserQueryKey[];
+EXTENSIONS_EXPORT extern const char kAuthUserQueryKey[];
 
 // Mime type strings
-extern const char kMimeTypeJpeg[];
-extern const char kMimeTypePng[];
+EXTENSIONS_EXPORT extern const char kMimeTypeJpeg[];
+EXTENSIONS_EXPORT extern const char kMimeTypePng[];
 
 // The extension id of the Web Store component application.
-extern const char kWebStoreAppId[];
+EXTENSIONS_EXPORT extern const char kWebStoreAppId[];
 
 // The key used for signing some pieces of data from the webstore.
-extern const uint8_t kWebstoreSignaturesPublicKey[];
-extern const size_t kWebstoreSignaturesPublicKeySize;
+EXTENSIONS_EXPORT extern const uint8_t kWebstoreSignaturesPublicKey[];
+EXTENSIONS_EXPORT extern const size_t kWebstoreSignaturesPublicKeySize;
 
 // A preference for storing the extension's update URL data.
-extern const char kUpdateURLData[];
+EXTENSIONS_EXPORT extern const char kUpdateURLData[];
 
 // Thread identifier for the main renderer thread (as opposed to a service
 // worker thread).
 // This is the default thread id used for extension event listeners registered
 // from a non-service worker context
-extern const int kMainThreadId;
+EXTENSIONS_EXPORT extern const int kMainThreadId;
 
 // Enumeration of possible app launch sources.
 // This should be kept in sync with LaunchSource in
@@ -201,13 +215,13 @@
 namespace extension_misc {
 
 // Matches chrome.tabs.TAB_ID_NONE.
-const int kUnknownTabId = -1;
+EXTENSIONS_EXPORT extern const int kUnknownTabId;
 
 // Matches chrome.windows.WINDOW_ID_NONE.
-const int kUnknownWindowId = -1;
+EXTENSIONS_EXPORT extern const int kUnknownWindowId;
 
 // Matches chrome.windows.WINDOW_ID_CURRENT.
-const int kCurrentWindowId = -2;
+EXTENSIONS_EXPORT extern const int kCurrentWindowId;
 
 enum ExtensionIcons {
   EXTENSION_ICON_GIGANTOR = 512,
@@ -221,125 +235,125 @@
 };
 
 // The extension id of the ChromeVox extension.
-extern const char kChromeVoxExtensionId[];
+EXTENSIONS_EXPORT extern const char kChromeVoxExtensionId[];
 
 // The extension id of the feedback component extension.
-extern const char kFeedbackExtensionId[];
+EXTENSIONS_EXPORT extern const char kFeedbackExtensionId[];
 
 // The extension id of the PDF extension.
-extern const char kPdfExtensionId[];
+EXTENSIONS_EXPORT extern const char kPdfExtensionId[];
 
 // The extension id of the Office Viewer component extension.
-extern const char kQuickOfficeComponentExtensionId[];
+EXTENSIONS_EXPORT extern const char kQuickOfficeComponentExtensionId[];
 
 // The extension id of the Office Viewer extension on the internal webstore.
-extern const char kQuickOfficeInternalExtensionId[];
+EXTENSIONS_EXPORT extern const char kQuickOfficeInternalExtensionId[];
 
 // The extension id of the Office Viewer extension.
-extern const char kQuickOfficeExtensionId[];
+EXTENSIONS_EXPORT extern const char kQuickOfficeExtensionId[];
 
 // The extension id used for testing mimeHandlerPrivate.
-extern const char kMimeHandlerPrivateTestExtensionId[];
+EXTENSIONS_EXPORT extern const char kMimeHandlerPrivateTestExtensionId[];
 
 // The extension id of the Chrome component application.
-extern const char kChromeAppId[];
+EXTENSIONS_EXPORT extern const char kChromeAppId[];
 
 // Fake extension ID for the Lacros chrome browser application.
-extern const char kLacrosAppId[];
+EXTENSIONS_EXPORT extern const char kLacrosAppId[];
 
 // The extension id of the Files Manager application.
-extern const char kFilesManagerAppId[];
+EXTENSIONS_EXPORT extern const char kFilesManagerAppId[];
 
 // The extension id of the Calculator application.
-extern const char kCalculatorAppId[];
+EXTENSIONS_EXPORT extern const char kCalculatorAppId[];
 
 // The extension id of the demo Calendar application.
-extern const char kCalendarDemoAppId[];
+EXTENSIONS_EXPORT extern const char kCalendarDemoAppId[];
 
 // The extension id of the GMail application.
-extern const char kGmailAppId[];
+EXTENSIONS_EXPORT extern const char kGmailAppId[];
 
 // The extension id of the demo Google Docs application.
-extern const char kGoogleDocsDemoAppId[];
+EXTENSIONS_EXPORT extern const char kGoogleDocsDemoAppId[];
 
 // The extension id of the Google Docs PWA.
-extern const char kGoogleDocsPwaAppId[];
+EXTENSIONS_EXPORT extern const char kGoogleDocsPwaAppId[];
 
 // The extension id of the Google Drive application.
-extern const char kGoogleDriveAppId[];
+EXTENSIONS_EXPORT extern const char kGoogleDriveAppId[];
 
 // The extension id of the Google Meet PWA.
-extern const char kGoogleMeetPwaAppId[];
+EXTENSIONS_EXPORT extern const char kGoogleMeetPwaAppId[];
 
 // The extension id of the demo Google Sheets application.
-extern const char kGoogleSheetsDemoAppId[];
+EXTENSIONS_EXPORT extern const char kGoogleSheetsDemoAppId[];
 
 // The extension id of the Google Sheets PWA.
-extern const char kGoogleSheetsPwaAppId[];
+EXTENSIONS_EXPORT extern const char kGoogleSheetsPwaAppId[];
 
 // The extension id of the demo Google Slides application.
-extern const char kGoogleSlidesDemoAppId[];
+EXTENSIONS_EXPORT extern const char kGoogleSlidesDemoAppId[];
 
 // The extension id of the Google Keep application.
-extern const char kGoogleKeepAppId[];
+EXTENSIONS_EXPORT extern const char kGoogleKeepAppId[];
 
 // The extension id of the Youtube application.
-extern const char kYoutubeAppId[];
+EXTENSIONS_EXPORT extern const char kYoutubeAppId[];
 
 // The extension id of the Youtube PWA.
-extern const char kYoutubePwaAppId[];
+EXTENSIONS_EXPORT extern const char kYoutubePwaAppId[];
 
 // The extension id of the Spotify PWA.
-extern const char kSpotifyAppId[];
+EXTENSIONS_EXPORT extern const char kSpotifyAppId[];
 
 // The extension id of the BeFunky PWA.
-extern const char kBeFunkyAppId[];
+EXTENSIONS_EXPORT extern const char kBeFunkyAppId[];
 
 // The extension id of the Clipchamp PWA.
-extern const char kClipchampAppId[];
+EXTENSIONS_EXPORT extern const char kClipchampAppId[];
 
 // The extension id of the GeForce NOW PWA.
-extern const char kGeForceNowAppId[];
+EXTENSIONS_EXPORT extern const char kGeForceNowAppId[];
 
 // The extension id of the Zoom PWA.
-extern const char kZoomAppId[];
+EXTENSIONS_EXPORT extern const char kZoomAppId[];
 
 // The extension id of the Google Docs application.
-extern const char kGoogleDocsAppId[];
+EXTENSIONS_EXPORT extern const char kGoogleDocsAppId[];
 
 // The extension id of the Google Sheets application.
-extern const char kGoogleSheetsAppId[];
+EXTENSIONS_EXPORT extern const char kGoogleSheetsAppId[];
 
 // The extension id of the Google Slides application.
-extern const char kGoogleSlidesAppId[];
+EXTENSIONS_EXPORT extern const char kGoogleSlidesAppId[];
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 // The extension id of the default Demo Mode Highlights app.
-extern const char kHighlightsAppId[];
+EXTENSIONS_EXPORT extern const char kHighlightsAppId[];
 
 // The extension id of the atlas Demo Mode Highlights app.
-extern const char kHighlightsAtlasAppId[];
+EXTENSIONS_EXPORT extern const char kHighlightsAtlasAppId[];
 
 // The extension id of the default Demo Mode screensaver app.
-extern const char kScreensaverAppId[];
+EXTENSIONS_EXPORT extern const char kScreensaverAppId[];
 
 // The extension id of the atlas Demo Mode screensaver app.
-extern const char kScreensaverAtlasAppId[];
+EXTENSIONS_EXPORT extern const char kScreensaverAtlasAppId[];
 
 // The extension id of the krane Demo Mode screensaver app. That app is only
 // run on KRANE-ZDKS devices.
-extern const char kScreensaverKraneZdksAppId[];
+EXTENSIONS_EXPORT extern const char kScreensaverKraneZdksAppId[];
 
 // The id of the testing extension allowed in the signin profile.
-extern const char kSigninProfileTestExtensionId[];
+EXTENSIONS_EXPORT extern const char kSigninProfileTestExtensionId[];
 
 // The id of the testing extension allowed in guest mode.
-extern const char kGuestModeTestExtensionId[];
+EXTENSIONS_EXPORT extern const char kGuestModeTestExtensionId[];
 
 // Returns true if this app is part of the "system UI". Generally this is UI
 // that that on other operating systems would be considered part of the OS,
 // for example the file manager.
-bool IsSystemUIApp(base::StringPiece extension_id);
+EXTENSIONS_EXPORT bool IsSystemUIApp(base::StringPiece extension_id);
 #endif
 
 // Returns if the app is managed by extension default apps. This is a hardcoded
@@ -348,29 +362,29 @@
 // TODO(https://crbug.com/1257275): remove after deault app migration is done.
 // This function is copied from
 // chrome/browser/web_applications/extension_status_utils.h.
-bool IsPreinstalledAppId(const std::string& app_id);
+EXTENSIONS_EXPORT bool IsPreinstalledAppId(const std::string& app_id);
 
 // The extension id for the production version of Hangouts.
-extern const char kProdHangoutsExtensionId[];
+EXTENSIONS_EXPORT extern const char kProdHangoutsExtensionId[];
 
 // Extension ids used by Hangouts.
-extern const char* const kHangoutsExtensionIds[6];
+EXTENSIONS_EXPORT extern const char* const kHangoutsExtensionIds[6];
 
 // Error message when enterprise policy blocks scripting of webpage.
-extern const char kPolicyBlockedScripting[];
+EXTENSIONS_EXPORT extern const char kPolicyBlockedScripting[];
 
 // The default block size for hashing used in content verification.
-extern const int kContentVerificationDefaultBlockSize;
+EXTENSIONS_EXPORT extern const int kContentVerificationDefaultBlockSize;
 
 // The origin of the CryptoToken component extension, which implements the
 // deprecated U2F Security Key API.
 // TODO(1224886): Delete together with CryptoToken code.
-extern const char kCryptotokenExtensionId[];
+EXTENSIONS_EXPORT extern const char kCryptotokenExtensionId[];
 
 // The name of the CryptoToken component extension deprecation trial, which
 // allows making requests to the extension after it has been default disabled.
 // TODO(1224886): Delete together with CryptoToken code.
-extern const char kCryptotokenDeprecationTrialName[];
+EXTENSIONS_EXPORT extern const char kCryptotokenDeprecationTrialName[];
 
 }  // namespace extension_misc
 
diff --git a/extensions/common/extensions_export.h b/extensions/common/extensions_export.h
new file mode 100644
index 0000000..b6ff78f
--- /dev/null
+++ b/extensions/common/extensions_export.h
@@ -0,0 +1,30 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef EXTENSIONS_COMMON_EXTENSIONS_EXPORT_H_
+#define EXTENSIONS_COMMON_EXTENSIONS_EXPORT_H_
+
+#if defined(COMPONENT_BUILD)
+
+#if defined(WIN32)
+
+#if defined(EXTENSIONS_COMPONENT_IMPLEMENTATION)
+#define EXTENSIONS_EXPORT __declspec(dllexport)
+#else
+#define EXTENSIONS_EXPORT __declspec(dllimport)
+#endif  // defined(EXTENSIONS_COMPONENT_IMPLEMENTATION)
+
+#else  // defined(WIN32)
+#if defined(EXTENSIONS_COMPONENT_IMPLEMENTATION)
+#define EXTENSIONS_EXPORT __attribute__((visibility("default")))
+#else
+#define EXTENSIONS_EXPORT
+#endif
+#endif
+
+#else  // defined(COMPONENT_BUILD)
+#define EXTENSIONS_EXPORT
+#endif
+
+#endif  // EXTENSIONS_COMMON_EXTENSIONS_EXPORT_H_
diff --git a/extensions/common/manifest_handlers/mime_types_handler.cc b/extensions/common/manifest_handlers/mime_types_handler.cc
index bb86605..a74df21 100644
--- a/extensions/common/manifest_handlers/mime_types_handler.cc
+++ b/extensions/common/manifest_handlers/mime_types_handler.cc
@@ -26,7 +26,7 @@
 // This has to by in sync with MimeHandlerType enum.
 // Note that if multiple versions of quickoffice are installed, the
 // higher-indexed entry will clobber earlier entries.
-constexpr const char* const kMIMETypeHandlersAllowlist[] = {
+const char* kMIMETypeHandlersAllowlist[] = {
     extension_misc::kPdfExtensionId,
     extension_misc::kQuickOfficeComponentExtensionId,
     extension_misc::kQuickOfficeInternalExtensionId,
diff --git a/gpu/command_buffer/service/raster_decoder.cc b/gpu/command_buffer/service/raster_decoder.cc
index 986d90fa..d6593a76 100644
--- a/gpu/command_buffer/service/raster_decoder.cc
+++ b/gpu/command_buffer/service/raster_decoder.cc
@@ -61,6 +61,7 @@
 #include "gpu/command_buffer/service/shared_image_representation.h"
 #include "gpu/command_buffer/service/skia_utils.h"
 #include "gpu/command_buffer/service/wrapped_sk_image.h"
+#include "gpu/config/gpu_finch_features.h"
 #include "gpu/vulkan/buildflags.h"
 #include "skia/ext/legacy_display_globals.h"
 #include "skia/ext/rgba_to_yuva.h"
@@ -821,12 +822,22 @@
     bool sync_cpu = gpu::ShouldVulkanSyncCpuForSkiaSubmit(
         shared_context_state_->vk_context_provider());
     if (signal_semaphores.empty()) {
-      if (surface)
+      if (surface) {
         surface->flush();
-      else
+      } else {
         gr_context()->flush();
-      if (sync_cpu)
+      }
+
+      // If DrDc is enabled, submit the gr_context() to ensure correct ordering
+      // of vulkan commands between raster and display compositor.
+      // TODO(vikassoni): This submit could be happening more often than
+      // intended resulting in perf penalty. Explore ways to reduce it by
+      // trying to issue submit only once per draw call for both gpu main and
+      // drdc thread gr_context. Also add metric to see how often submits are
+      // happening per frame.
+      if (sync_cpu || is_drdc_enabled_) {
         gr_context()->submit(sync_cpu);
+      }
       return;
     }
 
@@ -985,6 +996,8 @@
 
   const bool is_raw_draw_enabled_;
 
+  const bool is_drdc_enabled_;
+
   raw_ptr<gl::GLApi> api_ = nullptr;
 
   base::WeakPtrFactory<DecoderContext> weak_ptr_factory_{this};
@@ -1101,7 +1114,8 @@
           this,
           gpu_preferences_.disable_oopr_debug_crash_dump)),
       is_privileged_(is_privileged),
-      is_raw_draw_enabled_(features::IsUsingRawDraw()) {
+      is_raw_draw_enabled_(features::IsUsingRawDraw()),
+      is_drdc_enabled_(features::IsDrDcEnabled()) {
   DCHECK(shared_context_state_);
   shared_context_state_->AddContextLostObserver(this);
 }
diff --git a/gpu/command_buffer/service/wrapped_sk_image.cc b/gpu/command_buffer/service/wrapped_sk_image.cc
index ec7dd03a..389dd03 100644
--- a/gpu/command_buffer/service/wrapped_sk_image.cc
+++ b/gpu/command_buffer/service/wrapped_sk_image.cc
@@ -9,6 +9,9 @@
 #include "base/memory/raw_ptr.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/strings/stringprintf.h"
+#include "base/task/bind_post_task.h"
+#include "base/task/single_thread_task_runner.h"
+#include "base/threading/thread_task_runner_handle.h"
 #include "base/trace_event/memory_dump_manager.h"
 #include "base/trace_event/process_memory_dump.h"
 #include "base/trace_event/trace_event.h"
@@ -26,6 +29,7 @@
 #include "gpu/command_buffer/service/shared_image_representation.h"
 #include "gpu/command_buffer/service/shared_memory_region_wrapper.h"
 #include "gpu/command_buffer/service/skia_utils.h"
+#include "gpu/config/gpu_finch_features.h"
 #include "skia/buildflags.h"
 #include "third_party/skia/include/core/SkCanvas.h"
 #include "third_party/skia/include/core/SkPromiseImageTexture.h"
@@ -112,7 +116,8 @@
                  SkAlphaType alpha_type,
                  uint32_t usage,
                  size_t estimated_size,
-                 scoped_refptr<SharedContextState> context_state)
+                 scoped_refptr<SharedContextState> context_state,
+                 const bool thread_safe)
       : ClearTrackingSharedImageBacking(mailbox,
                                         format,
                                         size,
@@ -121,24 +126,60 @@
                                         alpha_type,
                                         usage,
                                         estimated_size,
-                                        false /* is_thread_safe */),
+                                        thread_safe),
         context_state_(std::move(context_state)) {
     DCHECK(!!context_state_);
+
+    // If the backing is meant to be thread safe, then grab the task runner to
+    // destroy the object later on same thread on which it was created on. Note
+    // that SkSurface and GrBackendTexture are not thread safe and hence should
+    // be destroyed on same thread on which it was created on.
+    if (is_thread_safe()) {
+      // If backing is thread safe, then ensure that we have a task runner to
+      // destroy backing on correct thread. Webview doesn't have a task runner
+      // but it uses and shares this backing on a single thread (on render
+      // passes for display compositor) and DrDc is disabled on webview. Hence
+      // using is_thread_safe() to grab task_runner is enough to ensure
+      // correctness.
+      DCHECK(base::ThreadTaskRunnerHandle::IsSet());
+      task_runner_ = base::ThreadTaskRunnerHandle::Get();
+    }
   }
 
   WrappedSkImage(const WrappedSkImage&) = delete;
   WrappedSkImage& operator=(const WrappedSkImage&) = delete;
 
   ~WrappedSkImage() override {
-    context_state_->MakeCurrent(nullptr);
-    promise_texture_.reset();
-    context_state_->EraseCachedSkSurface(this);
+    auto destroy_resources = [](scoped_refptr<SharedContextState> context_state,
+                                sk_sp<SkPromiseImageTexture> promise_texture,
+                                GrBackendTexture backend_texture) {
+      DCHECK(promise_texture);
+      context_state->MakeCurrent(nullptr);
+      context_state->EraseCachedSkSurface(promise_texture.get());
+      promise_texture.reset();
 
-    if (backend_texture_.isValid())
-      DeleteGrBackendTexture(context_state_.get(), &backend_texture_);
+      if (backend_texture.isValid())
+        DeleteGrBackendTexture(context_state.get(), &backend_texture);
 
-    if (!context_state_->context_lost())
-      context_state_->set_need_context_state_reset(true);
+      if (!context_state->context_lost())
+        context_state->set_need_context_state_reset(true);
+    };
+
+    // Since the representation from this backing can be created on either gpu
+    // main or drdc thread, the last representation ref and hence the backing
+    // could be destroyed in any thread irrespective of the thread it was
+    // created on. Hence we need to ensure that the resources are destroyed on
+    // the thread they were created on.
+    if (task_runner_ && !task_runner_->BelongsToCurrentThread()) {
+      auto destruction_cb =
+          base::BindPostTask(task_runner_, base::BindOnce(destroy_resources));
+      std::move(destruction_cb)
+          .Run(std::move(context_state_), std::move(promise_texture_),
+               std::move(backend_texture_));
+    } else {
+      destroy_resources(std::move(context_state_), std::move(promise_texture_),
+                        std::move(backend_texture_));
+    }
   }
 
   // SharedImageBacking implementation.
@@ -194,13 +235,23 @@
         /*gpu_compositing=*/true, format());
   }
 
-  sk_sp<SkSurface> GetSkSurface(int final_msaa_count,
-                                const SkSurfaceProps& surface_props) {
+  sk_sp<SkSurface> GetSkSurface(
+      int final_msaa_count,
+      const SkSurfaceProps& surface_props,
+      scoped_refptr<SharedContextState> context_state) {
+    // This method should only be called on the same thread on which this
+    // backing is created on. Hence adding a dcheck on context_state to ensure
+    // this.
+    DCHECK_EQ(context_state_, context_state);
     if (context_state_->context_lost())
       return nullptr;
     DCHECK(context_state_->IsCurrent(nullptr));
 
-    auto surface = context_state_->GetCachedSkSurface(this);
+    // Note that we are using |promise_texture_| as a key to the cache below
+    // since it is safe to do so. |promise_texture_| is not destroyed until we
+    // remove the entry from the cache.
+    DCHECK(promise_texture_);
+    auto surface = context_state_->GetCachedSkSurface(promise_texture_.get());
     if (!surface || final_msaa_count != surface_msaa_count_ ||
         surface_props != surface->props()) {
       surface = SkSurface::MakeFromBackendTexture(
@@ -209,17 +260,22 @@
           &surface_props);
       if (!surface) {
         LOG(ERROR) << "MakeFromBackendTexture() failed.";
-        context_state_->EraseCachedSkSurface(this);
+        context_state_->EraseCachedSkSurface(promise_texture_.get());
         return nullptr;
       }
       surface_msaa_count_ = final_msaa_count;
-      context_state_->CacheSkSurface(this, surface);
+      context_state_->CacheSkSurface(promise_texture_.get(), surface);
     }
     return surface;
   }
 
-  bool SkSurfaceUnique() {
-    return context_state_->CachedSkSurfaceIsUnique(this);
+  bool SkSurfaceUnique(scoped_refptr<SharedContextState> context_state) {
+    // This method should only be called on the same thread on which this
+    // backing is created on. Hence adding a dcheck on context_state to ensure
+    // this.
+    DCHECK_EQ(context_state_, context_state);
+    DCHECK(promise_texture_);
+    return context_state_->CachedSkSurfaceIsUnique(promise_texture_.get());
   }
 
   sk_sp<SkPromiseImageTexture> promise_texture() { return promise_texture_; }
@@ -337,6 +393,7 @@
   SharedMemoryRegionWrapper shared_memory_wrapper_;
 
   uint64_t tracing_id_ = 0;
+  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
 };
 
 class WrappedSkImage::RepresentationSkia
@@ -344,8 +401,10 @@
  public:
   RepresentationSkia(SharedImageManager* manager,
                      SharedImageBacking* backing,
-                     MemoryTypeTracker* tracker)
-      : SharedImageRepresentationSkia(manager, backing, tracker) {}
+                     MemoryTypeTracker* tracker,
+                     scoped_refptr<SharedContextState> context_state)
+      : SharedImageRepresentationSkia(manager, backing, tracker),
+        context_state_(std::move(context_state)) {}
 
   ~RepresentationSkia() override { DCHECK(!write_surface_); }
 
@@ -354,8 +413,8 @@
       const SkSurfaceProps& surface_props,
       std::vector<GrBackendSemaphore>* begin_semaphores,
       std::vector<GrBackendSemaphore>* end_semaphores) override {
-    auto surface =
-        wrapped_sk_image()->GetSkSurface(final_msaa_count, surface_props);
+    auto surface = wrapped_sk_image()->GetSkSurface(
+        final_msaa_count, surface_props, context_state_);
     if (!surface)
       return nullptr;
     int save_count = surface->getCanvas()->save();
@@ -379,7 +438,7 @@
       surface.reset();
       write_surface_ = nullptr;
 
-      DCHECK(wrapped_sk_image()->SkSurfaceUnique());
+      DCHECK(wrapped_sk_image()->SkSurfaceUnique(context_state_));
     }
   }
 
@@ -403,6 +462,7 @@
   }
 
   raw_ptr<SkSurface> write_surface_ = nullptr;
+  scoped_refptr<SharedContextState> context_state_;
 };
 
 class WrappedSkImage::RepresentationMemory
@@ -432,7 +492,8 @@
 
 WrappedSkImageFactory::WrappedSkImageFactory(
     scoped_refptr<SharedContextState> context_state)
-    : context_state_(std::move(context_state)) {}
+    : context_state_(std::move(context_state)),
+      is_drdc_enabled_(features::IsDrDcEnabled()) {}
 
 WrappedSkImageFactory::~WrappedSkImageFactory() = default;
 
@@ -446,12 +507,22 @@
     SkAlphaType alpha_type,
     uint32_t usage,
     bool is_thread_safe) {
-  DCHECK(!is_thread_safe);
+  // Ensure that the backing is treated as thread safe only when DrDc is enabled
+  // for vulkan context.
+  // TODO(vikassoni): Wire |is_thread_safe| flag in remaining
+  // CreateSharedImage() factory methods also. Without this flag, backing will
+  // always be considered as thread safe when DrDc is enabled for vulkan mode
+  // even though it might be used on a single thread (RenderPass for example).
+  // That should be fine for now since we do not have/use any locks in backing.
+  DCHECK(!is_thread_safe ||
+         (context_state_->GrContextIsVulkan() && is_drdc_enabled_));
   size_t estimated_size = EstimatedSize(format, size);
   auto texture = std::make_unique<WrappedSkImage>(
       base::PassKey<WrappedSkImageFactory>(), mailbox, format, size,
       color_space, surface_origin, alpha_type, usage, estimated_size,
-      context_state_);
+      context_state_,
+      /*is_thread_safe=*/is_thread_safe &&
+          context_state_->GrContextIsVulkan() && is_drdc_enabled_);
   if (!texture->Initialize())
     return nullptr;
   return texture;
@@ -470,7 +541,8 @@
   auto texture = std::make_unique<WrappedSkImage>(
       base::PassKey<WrappedSkImageFactory>(), mailbox, format, size,
       color_space, surface_origin, alpha_type, usage, estimated_size,
-      context_state_);
+      context_state_, /*is_thread_safe=*/context_state_->GrContextIsVulkan() &&
+                          is_drdc_enabled_);
   if (!texture->InitializeWithData(data, /*stride=*/0))
     return nullptr;
   return texture;
@@ -518,7 +590,8 @@
   auto texture = std::make_unique<WrappedSkImage>(
       base::PassKey<WrappedSkImageFactory>(), mailbox, format, size,
       color_space, surface_origin, alpha_type, usage, info.computeMinByteSize(),
-      context_state_);
+      context_state_, /*is_thread_safe=*/context_state_->GrContextIsVulkan() &&
+                          is_drdc_enabled_);
   if (!texture->InitializeWithGMB(std::move(shm_wrapper)))
     return nullptr;
 
@@ -558,7 +631,20 @@
                                         GrContextType gr_context_type,
                                         bool* allow_legacy_mailbox,
                                         bool is_pixel_used) {
-  if (!CanUseWrappedSkImage(usage, gr_context_type) || thread_safe) {
+  // Note that this backing support thread safety only for vulkan mode because
+  // the underlying vulkan resources like vulkan images can be shared across
+  // multiple vulkan queues. Also note that this backing currently only supports
+  // thread safety for DrDc mode where both gpu main and drdc thread uses/shared
+  // a single vulkan queue to submit work and hence do not need to synchronize
+  // the reads/writes using semaphores. For this backing to support thread
+  // safety across multiple queues, we need to synchronize the reads/writes via
+  // semaphores.
+  if (thread_safe &&
+      (!is_drdc_enabled_ || gr_context_type != GrContextType::kVulkan)) {
+    return false;
+  }
+
+  if (!CanUseWrappedSkImage(usage, gr_context_type)) {
     return false;
   }
   if (gmb_type != gfx::EMPTY_BUFFER && !CanImportGpuMemoryBuffer(gmb_type)) {
@@ -576,8 +662,8 @@
   if (context_state_->context_lost())
     return nullptr;
 
-  DCHECK_EQ(context_state_, context_state.get());
-  return std::make_unique<RepresentationSkia>(manager, this, tracker);
+  return std::make_unique<RepresentationSkia>(manager, this, tracker,
+                                              std::move(context_state));
 }
 
 std::unique_ptr<SharedImageRepresentationMemory> WrappedSkImage::ProduceMemory(
diff --git a/gpu/command_buffer/service/wrapped_sk_image.h b/gpu/command_buffer/service/wrapped_sk_image.h
index a09a662..cb790862 100644
--- a/gpu/command_buffer/service/wrapped_sk_image.h
+++ b/gpu/command_buffer/service/wrapped_sk_image.h
@@ -77,6 +77,7 @@
                             GrContextType gr_context_type) const;
 
   scoped_refptr<SharedContextState> context_state_;
+  const bool is_drdc_enabled_;
 };
 
 }  // namespace raster
diff --git a/gpu/ipc/service/gpu_watchdog_thread_unittest.cc b/gpu/ipc/service/gpu_watchdog_thread_unittest.cc
index d7d7581c7..e12e09d6 100644
--- a/gpu/ipc/service/gpu_watchdog_thread_unittest.cc
+++ b/gpu/ipc/service/gpu_watchdog_thread_unittest.cc
@@ -17,33 +17,19 @@
 namespace gpu {
 
 namespace {
-constexpr auto kGpuWatchdogTimeoutForTesting = base::Milliseconds(5);
+constexpr auto kGpuWatchdogTimeoutForTesting = base::Milliseconds(1000);
 
 // This is the extra time the gpu main/test thread spends after
 // GpuWatchdogTimeout. Theoretically, any extra time such as 1 ms should be
-// enough to trigger the watchdog kill. However, it can cause test flakiness
-// when the time is too short.
-#if BUILDFLAG(IS_WIN)
-constexpr auto kExtraGPUJobTimeForTesting = base::Milliseconds(20);
-#else
-constexpr auto kExtraGPUJobTimeForTesting = base::Milliseconds(15);
-#endif
+// enough to trigger the watchdog kill. However, more time is added to fix the
+// flakiness in CQ.
+base::TimeDelta ExtraGPUJobTimeMSForTesting(int milliseconds) {
+  return base::Milliseconds(milliseconds);
+}
 
-// On Windows, the gpu watchdog check if the main thread has used the full
-// thread time. We want to detect the case in which the main thread is swapped
-// out by the OS scheduler. The task on windows is simiulated by reading
-// TimeTicks instead of Sleep().
-void SimpleTask(base::TimeDelta duration, base::TimeDelta extra_time) {
-#if BUILDFLAG(IS_WIN)
-  auto start_timetick = base::TimeTicks::Now();
-  do {
-  } while ((base::TimeTicks::Now() - start_timetick) < duration);
-
-  base::PlatformThread::Sleep(extra_time);
-
-#else
-  base::PlatformThread::Sleep(duration + extra_time);
-#endif
+// This task will run for duration_ms milliseconds.
+void SimpleTask(base::TimeDelta duration) {
+  base::PlatformThread::Sleep(duration);
 }
 }  // namespace
 
@@ -54,12 +40,9 @@
   void LongTaskWithReportProgress(base::TimeDelta duration,
                                   base::TimeDelta report_delta);
 
-#if BUILDFLAG(IS_ANDROID)
   void LongTaskFromBackgroundToForeground(
       base::TimeDelta duration,
-      base::TimeDelta extra_time,
       base::TimeDelta time_to_switch_to_foreground);
-#endif
 
   // Implements testing::Test
   void SetUp() override;
@@ -69,7 +52,6 @@
   base::test::SingleThreadTaskEnvironment task_environment_;
   base::RunLoop run_loop;
   std::unique_ptr<gpu::GpuWatchdogThread> watchdog_thread_;
-  base::TimeDelta full_thread_time_on_windows_ = base::TimeDelta();
 };
 
 class GpuWatchdogPowerTest : public GpuWatchdogTest {
@@ -77,7 +59,6 @@
   GpuWatchdogPowerTest() {}
 
   void LongTaskOnResume(base::TimeDelta duration,
-                        base::TimeDelta extra_time,
                         base::TimeDelta time_to_power_resume);
 
   // Implements testing::Test
@@ -100,11 +81,6 @@
       /*init_factor=*/kInitFactor,
       /*restart_factor=*/kRestartFactor,
       /*test_mode=*/true, /*thread_name=*/"GpuWatchdog");
-
-#if BUILDFLAG(IS_WIN)
-  full_thread_time_on_windows_ =
-      kGpuWatchdogTimeoutForTesting * kMaxCountOfMoreGpuThreadTimeAllowed;
-#endif
 }
 
 void GpuWatchdogPowerTest::SetUp() {
@@ -127,93 +103,77 @@
   base::TimeTicks end;
 
   do {
-    SimpleTask(report_delta, /*extra_time=*/base::TimeDelta());
+    base::PlatformThread::Sleep(report_delta);
     watchdog_thread_->ReportProgress();
     end = base::TimeTicks::Now();
   } while (end - start <= duration);
 }
 
-#if BUILDFLAG(IS_ANDROID)
 void GpuWatchdogTest::LongTaskFromBackgroundToForeground(
     base::TimeDelta duration,
-    base::TimeDelta extra_time,
     base::TimeDelta time_to_switch_to_foreground) {
   // Chrome is running in the background first.
   watchdog_thread_->OnBackgrounded();
-  SimpleTask(time_to_switch_to_foreground, /*extra_time=*/base::TimeDelta());
+  base::PlatformThread::Sleep(time_to_switch_to_foreground);
   // Now switch Chrome to the foreground after the specified time
   watchdog_thread_->OnForegrounded();
-  SimpleTask(duration, extra_time);
+  base::PlatformThread::Sleep(duration);
 }
-#endif
 
 void GpuWatchdogPowerTest::LongTaskOnResume(
     base::TimeDelta duration,
-    base::TimeDelta extra_time,
     base::TimeDelta time_to_power_resume) {
   // Stay in power suspension mode first.
   power_monitor_source_.GenerateSuspendEvent();
 
-  SimpleTask(time_to_power_resume, /*extra_time=*/base::TimeDelta());
+  base::PlatformThread::Sleep(time_to_power_resume);
 
   // Now wake up on power resume.
   power_monitor_source_.GenerateResumeEvent();
   // Continue the GPU task for the remaining time.
-  SimpleTask(duration, extra_time);
-}
-
-// Normal GPU Initialization and Running Task
-TEST_F(GpuWatchdogTest, GpuInitializationComplete) {
-  // Assume GPU initialization takes quarter of WatchdogTimeout time.
-  auto normal_task_time = kGpuWatchdogTimeoutForTesting / 4;
-
-  SimpleTask(normal_task_time, /*extra_time=*/base::TimeDelta());
-  watchdog_thread_->OnInitComplete();
-
-  bool result = watchdog_thread_->IsGpuHangDetectedForTesting();
-  EXPECT_FALSE(result);
+  base::PlatformThread::Sleep(duration);
 }
 
 // GPU Hang In Initialization
 TEST_F(GpuWatchdogTest, GpuInitializationHang) {
-  auto allowed_time = kGpuWatchdogTimeoutForTesting * (kInitFactor + 1) +
-                      full_thread_time_on_windows_;
-
   // GPU init takes longer than timeout.
-  SimpleTask(allowed_time, /*extra_time=*/kExtraGPUJobTimeForTesting);
+#if BUILDFLAG(IS_WIN)
+  SimpleTask(kGpuWatchdogTimeoutForTesting * kInitFactor +
+             kGpuWatchdogTimeoutForTesting *
+                 kMaxCountOfMoreGpuThreadTimeAllowed +
+             ExtraGPUJobTimeMSForTesting(3000));
+#else
+  SimpleTask(kGpuWatchdogTimeoutForTesting * kInitFactor +
+             ExtraGPUJobTimeMSForTesting(3000));
+#endif
 
   // Gpu hangs. OnInitComplete() is not called
+
   bool result = watchdog_thread_->IsGpuHangDetectedForTesting();
   EXPECT_TRUE(result);
-  // retry on failure.
 }
 
 // Normal GPU Initialization and Running Task
 TEST_F(GpuWatchdogTest, GpuInitializationAndRunningTasks) {
-  // Assume GPU initialization takes quarter of WatchdogTimeout time.
-  auto normal_task_time = kGpuWatchdogTimeoutForTesting / 4;
-  SimpleTask(normal_task_time, /*extra_time=*/base::TimeDelta());
+  // Assume GPU initialization takes 300 milliseconds.
+  SimpleTask(base::Milliseconds(300));
   watchdog_thread_->OnInitComplete();
 
   // Start running GPU tasks. Watchdog function WillProcessTask(),
   // DidProcessTask() and ReportProgress() are tested.
   task_environment_.GetMainThreadTaskRunner()->PostTask(
-      FROM_HERE, base::BindOnce(&SimpleTask, normal_task_time,
-                                /*extra_time=*/base::TimeDelta()));
+      FROM_HERE, base::BindOnce(&SimpleTask, base::Milliseconds(500)));
   task_environment_.GetMainThreadTaskRunner()->PostTask(
-      FROM_HERE, base::BindOnce(&SimpleTask, normal_task_time,
-                                /*extra_time=*/base::TimeDelta()));
+      FROM_HERE, base::BindOnce(&SimpleTask, base::Milliseconds(500)));
 
-  // This long task takes 6X timeout to finish, longer than timeout.
-  // But it reports progress every quarter of kGpuWatchdogTimeoutForTesting
-  // time, so this is an expected normal behavior.
-  auto normal_long_task_time = kGpuWatchdogTimeoutForTesting * 6;
+  // This long task takes 3000 milliseconds to finish, longer than timeout.
+  // But it reports progress every 500 milliseconds
   task_environment_.GetMainThreadTaskRunner()->PostTask(
       FROM_HERE,
-      base::BindOnce(
-          &GpuWatchdogTest::LongTaskWithReportProgress, base::Unretained(this),
-          normal_long_task_time,
-          /*report_progress_time*/ kGpuWatchdogTimeoutForTesting / 4));
+      base::BindOnce(&GpuWatchdogTest::LongTaskWithReportProgress,
+                     base::Unretained(this),
+                     kGpuWatchdogTimeoutForTesting + base::Milliseconds(2000),
+                     base::Milliseconds(500)));
 
   task_environment_.GetMainThreadTaskRunner()->PostTask(FROM_HERE,
                                                         run_loop.QuitClosure());
@@ -230,12 +190,19 @@
   watchdog_thread_->OnInitComplete();
 
   // Start running a GPU task.
-  auto allowed_time =
-      kGpuWatchdogTimeoutForTesting * 2 + full_thread_time_on_windows_;
-
+#if BUILDFLAG(IS_WIN)
   task_environment_.GetMainThreadTaskRunner()->PostTask(
       FROM_HERE,
-      base::BindOnce(&SimpleTask, allowed_time, kExtraGPUJobTimeForTesting));
+      base::BindOnce(&SimpleTask, kGpuWatchdogTimeoutForTesting * 2 +
+                                      kGpuWatchdogTimeoutForTesting *
+                                          kMaxCountOfMoreGpuThreadTimeAllowed +
+                                      ExtraGPUJobTimeMSForTesting(4000)));
+#else
+  task_environment_.GetMainThreadTaskRunner()->PostTask(
+      FROM_HERE,
+      base::BindOnce(&SimpleTask, kGpuWatchdogTimeoutForTesting * 2 +
+                                      ExtraGPUJobTimeMSForTesting(4000)));
+#endif
 
   task_environment_.GetMainThreadTaskRunner()->PostTask(FROM_HERE,
                                                         run_loop.QuitClosure());
@@ -246,24 +213,22 @@
   EXPECT_TRUE(result);
 }
 
-#if BUILDFLAG(IS_ANDROID)
 TEST_F(GpuWatchdogTest, ChromeInBackground) {
   // Chrome starts in the background.
   watchdog_thread_->OnBackgrounded();
 
-  // Gpu init takes longer than 6x kGpuWatchdogTimeoutForTesting. This is normal
-  // since Chrome is running in the background.
-  auto normal_long_task_time = kGpuWatchdogTimeoutForTesting * 6;
-  SimpleTask(normal_long_task_time, /*extra_time=*/base::TimeDelta());
+  // Gpu init (3000 ms) takes longer than timeout (2000 ms).
+  SimpleTask(kGpuWatchdogTimeoutForTesting * kInitFactor +
+             ExtraGPUJobTimeMSForTesting(1000));
 
   // Report GPU init complete.
   watchdog_thread_->OnInitComplete();
 
-  // Run a task that takes 6x kGpuWatchdogTimeoutForTesting longer.This is
-  // normal since Chrome is running in the background.
+  // Run a task that takes longer (3000 milliseconds) than timeout.
   task_environment_.GetMainThreadTaskRunner()->PostTask(
-      FROM_HERE, base::BindOnce(&SimpleTask, normal_long_task_time,
-                                /*extra_time=*/base::TimeDelta()));
+      FROM_HERE,
+      base::BindOnce(&SimpleTask, kGpuWatchdogTimeoutForTesting * 2 +
+                                      ExtraGPUJobTimeMSForTesting(1000)));
   task_environment_.GetMainThreadTaskRunner()->PostTask(FROM_HERE,
                                                         run_loop.QuitClosure());
   run_loop.Run();
@@ -277,17 +242,29 @@
   // Report GPU init complete.
   watchdog_thread_->OnInitComplete();
 
-  // A task stays in the background for kGpuWatchdogTimeoutForTesting/4, and
-  // then switches to the foreground and runs longer than the first-time
-  // foreground watchdog timeout allowed.
-  auto allowed_time = kGpuWatchdogTimeoutForTesting * (kRestartFactor + 1);
+  // A task stays in the background for 200 milliseconds, and then
+  // switches to the foreground and runs for 6000 milliseconds. This is longer
+  // than the first-time foreground watchdog timeout (2000 ms).
+#if BUILDFLAG(IS_WIN)
   task_environment_.GetMainThreadTaskRunner()->PostTask(
       FROM_HERE,
-      base::BindOnce(
-          &GpuWatchdogTest::LongTaskFromBackgroundToForeground,
-          base::Unretained(this), /*duration*/ allowed_time,
-          /*extra_time=*/kExtraGPUJobTimeForTesting,
-          /*time_to_switch_to_foreground*/ kGpuWatchdogTimeoutForTesting / 4));
+      base::BindOnce(&GpuWatchdogTest::LongTaskFromBackgroundToForeground,
+                     base::Unretained(this),
+                     /*duration*/ kGpuWatchdogTimeoutForTesting * 2 +
+                         kGpuWatchdogTimeoutForTesting *
+                             kMaxCountOfMoreGpuThreadTimeAllowed +
+                         ExtraGPUJobTimeMSForTesting(4000),
+                     /*time_to_switch_to_foreground*/
+                     base::Milliseconds(200)));
+#else
+  task_environment_.GetMainThreadTaskRunner()->PostTask(
+      FROM_HERE,
+      base::BindOnce(&GpuWatchdogTest::LongTaskFromBackgroundToForeground,
+                     base::Unretained(this),
+                     /*duration*/ kGpuWatchdogTimeoutForTesting * 2 +
+                         ExtraGPUJobTimeMSForTesting(4000),
+                     /*time_to_switch_to_foreground*/ base::Milliseconds(200)));
+#endif
 
   task_environment_.GetMainThreadTaskRunner()->PostTask(FROM_HERE,
                                                         run_loop.QuitClosure());
@@ -298,18 +275,15 @@
   bool result = watchdog_thread_->IsGpuHangDetectedForTesting();
   EXPECT_TRUE(result);
 }
-#endif
 
 TEST_F(GpuWatchdogTest, GpuInitializationPause) {
-  // Running for kGpuWatchdogTimeoutForTesting/4 in the beginning of GPU init.
-  SimpleTask(kGpuWatchdogTimeoutForTesting / 4,
-             /*extra_time=*/base::TimeDelta());
+  // Running for 100 ms in the beginning of GPU init.
+  SimpleTask(base::Milliseconds(100));
   watchdog_thread_->PauseWatchdog();
 
-  // The Gpu init continues for another 6x kGpuWatchdogTimeoutForTesting after
-  // the pause. This is normal since watchdog is paused.
-  auto normal_long_task_time = kGpuWatchdogTimeoutForTesting * 6;
-  SimpleTask(normal_long_task_time, /*extra_time=*/base::TimeDelta());
+  // The Gpu init continues for another (init timeout + 1000) ms after the pause
+  SimpleTask(kGpuWatchdogTimeoutForTesting * kInitFactor +
+             ExtraGPUJobTimeMSForTesting(1000));
 
   // No GPU hang is detected when the watchdog is paused.
   bool result = watchdog_thread_->IsGpuHangDetectedForTesting();
@@ -317,12 +291,16 @@
 
   // Continue the watchdog now.
   watchdog_thread_->ResumeWatchdog();
-
-  // The Gpu init continues for longer than allowed init time.
-  auto allowed_time = kGpuWatchdogTimeoutForTesting * (kInitFactor + 1) +
-                      full_thread_time_on_windows_;
-
-  SimpleTask(allowed_time, /*extra_time=*/kExtraGPUJobTimeForTesting);
+  // The Gpu init continues for (init timeout + 4000) ms.
+#if BUILDFLAG(IS_WIN)
+  SimpleTask(kGpuWatchdogTimeoutForTesting * kInitFactor +
+             kGpuWatchdogTimeoutForTesting *
+                 kMaxCountOfMoreGpuThreadTimeAllowed +
+             ExtraGPUJobTimeMSForTesting(4000));
+#else
+  SimpleTask(kGpuWatchdogTimeoutForTesting * kInitFactor +
+             ExtraGPUJobTimeMSForTesting(4000));
+#endif
 
   // A GPU hang should be detected.
   result = watchdog_thread_->IsGpuHangDetectedForTesting();
@@ -335,11 +313,11 @@
   // Enter power suspension mode.
   power_monitor_source_.GenerateSuspendEvent();
 
-  // Run a task that takes 6x kGpuWatchdogTimeoutForTesting.
-  auto normal_long_task_time = kGpuWatchdogTimeoutForTesting * 6;
+  // Run a task that takes longer (5000 milliseconds) than timeout.
   task_environment_.GetMainThreadTaskRunner()->PostTask(
-      FROM_HERE, base::BindOnce(&SimpleTask, normal_long_task_time,
-                                /*extra_time=*/base::TimeDelta()));
+      FROM_HERE,
+      base::BindOnce(&SimpleTask, kGpuWatchdogTimeoutForTesting * 2 +
+                                      ExtraGPUJobTimeMSForTesting(3000)));
   task_environment_.GetMainThreadTaskRunner()->PostTask(FROM_HERE,
                                                         run_loop.QuitClosure());
   run_loop.Run();
@@ -353,18 +331,30 @@
 TEST_F(GpuWatchdogPowerTest, GpuOnResumeHang) {
   // watchdog_thread_->OnInitComplete() is called in SetUp
 
-  // This task stays in the suspension mode for kGpuWatchdogTimeoutForTesting/4,
-  // and it wakes up on power resume and then runs a job that is longer than the
-  // watchdog resume restart timeout.
-  auto allowed_time = kGpuWatchdogTimeoutForTesting * (kRestartFactor + 1) +
-                      full_thread_time_on_windows_;
-
+  // This task stays in the suspension mode for 200 milliseconds, and it
+  // wakes up on power resume and then runs for 6000 milliseconds. This is
+  // longer than the watchdog resume timeout (2000 ms).
+#if BUILDFLAG(IS_WIN)
   task_environment_.GetMainThreadTaskRunner()->PostTask(
       FROM_HERE,
       base::BindOnce(
           &GpuWatchdogPowerTest::LongTaskOnResume, base::Unretained(this),
-          /*duration*/ allowed_time, /*extra_time=*/kExtraGPUJobTimeForTesting,
-          /*time_to_power_resume*/ kGpuWatchdogTimeoutForTesting / 4));
+          /*duration*/ kGpuWatchdogTimeoutForTesting * kRestartFactor +
+              kGpuWatchdogTimeoutForTesting *
+                  kMaxCountOfMoreGpuThreadTimeAllowed +
+              ExtraGPUJobTimeMSForTesting(4000),
+          /*time_to_power_resume*/
+          base::Milliseconds(200)));
+#else
+  task_environment_.GetMainThreadTaskRunner()->PostTask(
+      FROM_HERE,
+      base::BindOnce(
+          &GpuWatchdogPowerTest::LongTaskOnResume, base::Unretained(this),
+          /*duration*/ kGpuWatchdogTimeoutForTesting * kRestartFactor +
+              ExtraGPUJobTimeMSForTesting(4000),
+          /*time_to_power_resume*/
+          base::Milliseconds(200)));
+#endif
 
   task_environment_.GetMainThreadTaskRunner()->PostTask(FROM_HERE,
                                                         run_loop.QuitClosure());
diff --git a/headless/BUILD.gn b/headless/BUILD.gn
index 5921e4c..b80712c 100644
--- a/headless/BUILD.gn
+++ b/headless/BUILD.gn
@@ -171,18 +171,21 @@
   "tracing",
 ]
 
-generated_devtools_api = []
+generated_devtools_api_sources = []
+generated_devtools_api_headers = []
 foreach(domain, devtools_domains) {
-  generated_devtools_api += [
-    "$target_gen_dir/public/devtools/domains/" + domain + ".cc",
+  generated_devtools_api_headers += [
     "$target_gen_dir/public/devtools/domains/" + domain + ".h",
     "$target_gen_dir/public/devtools/domains/types_" + domain + ".h",
-    "$target_gen_dir/public/devtools/domains/types_" + domain + ".cc",
     "$target_gen_dir/public/devtools/internal/type_conversions_" + domain +
         ".h",
     "$target_gen_dir/public/devtools/internal/" +
         "types_forward_declarations_" + domain + ".h",
   ]
+  generated_devtools_api_sources += [
+    "$target_gen_dir/public/devtools/domains/" + domain + ".cc",
+    "$target_gen_dir/public/devtools/domains/types_" + domain + ".cc",
+  ]
 }
 
 action("gen_devtools_client_api") {
@@ -195,7 +198,7 @@
     "$root_gen_dir/third_party/blink/public/devtools_protocol/protocol.json",
   ]
 
-  outputs = generated_devtools_api
+  outputs = generated_devtools_api_headers + generated_devtools_api_sources
   sources = [
     "lib/browser/devtools_api/domain_cc.template",
     "lib/browser/devtools_api/domain_h.template",
@@ -308,7 +311,7 @@
     "public/util/user_agent.h",
   ]
 
-  sources += generated_devtools_api
+  sources += generated_devtools_api_headers + generated_devtools_api_sources
 
   if (!is_fuchsia) {
     sources += [
@@ -690,10 +693,20 @@
   sources = [
     "public/domains/types_unittest.cc",
     "public/util/error_reporter_unittest.cc",
+
+    # Headers for code under test that aren't normally exposed.
+    "public/headless_export.h",
+    "public/util/error_reporter.h",
   ]
+
+  # Headers for generated API code under test.
+  sources += generated_devtools_api_headers
+
   defines = []
 
   deps = [
+    ":gen_devtools_client_api",
+    ":headless_non_renderer",
     ":headless_shell_lib",
     "//base/test:run_all_unittests",
     "//base/test:test_support",
diff --git a/infra/config/generated/builders/ci/ios-catalyst/properties.textpb b/infra/config/generated/builders/ci/ios-catalyst/properties.textpb
index 9015f79..6d2a595 100644
--- a/infra/config/generated/builders/ci/ios-catalyst/properties.textpb
+++ b/infra/config/generated/builders/ci/ios-catalyst/properties.textpb
@@ -11,7 +11,11 @@
       "v.test_suite"
     ]
   },
-  "builder_group": "chromium.fyi",
+  "builder_group": "chromium.mac",
   "recipe": "chromium",
+  "sheriff_rotations": [
+    "chromium",
+    "ios"
+  ],
   "xcode_build_version": "13a233"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/linux-annotator-rel/properties.textpb b/infra/config/generated/builders/ci/linux-annotator-rel/properties.textpb
index fc3bce3..342b501 100644
--- a/infra/config/generated/builders/ci/linux-annotator-rel/properties.textpb
+++ b/infra/config/generated/builders/ci/linux-annotator-rel/properties.textpb
@@ -1,9 +1,8 @@
 {
-  "$build/goma": {
-    "enable_ats": true,
-    "rpc_extra_params": "?prod",
-    "server_host": "goma.chromium.org",
-    "use_luci_auth": true
+  "$build/reclient": {
+    "instance": "rbe-chromium-trusted",
+    "jobs": 500,
+    "metrics_project": "chromium-reclient-metrics"
   },
   "$recipe_engine/resultdb/test_presentation": {
     "column_keys": [],
diff --git a/infra/config/generated/builders/ci/linux-blink-heap-verification/properties.textpb b/infra/config/generated/builders/ci/linux-blink-heap-verification/properties.textpb
index fc3bce3..342b501 100644
--- a/infra/config/generated/builders/ci/linux-blink-heap-verification/properties.textpb
+++ b/infra/config/generated/builders/ci/linux-blink-heap-verification/properties.textpb
@@ -1,9 +1,8 @@
 {
-  "$build/goma": {
-    "enable_ats": true,
-    "rpc_extra_params": "?prod",
-    "server_host": "goma.chromium.org",
-    "use_luci_auth": true
+  "$build/reclient": {
+    "instance": "rbe-chromium-trusted",
+    "jobs": 500,
+    "metrics_project": "chromium-reclient-metrics"
   },
   "$recipe_engine/resultdb/test_presentation": {
     "column_keys": [],
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg
index be51f97..f67e841 100644
--- a/infra/config/generated/luci/cr-buildbucket.cfg
+++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -25959,6 +25959,10 @@
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
+        key: "luci.recipes.use_python3"
+        value: 100
+      }
+      experiments {
         key: "luci.use_realms"
         value: 100
       }
@@ -31013,11 +31017,15 @@
         '      }'
         '    }'
         '  },'
-        '  "builder_group": "chromium.fyi",'
+        '  "builder_group": "chromium.mac",'
         '  "led_builder_is_bootstrapped": true,'
-        '  "recipe": "chromium"'
+        '  "recipe": "chromium",'
+        '  "sheriff_rotations": ['
+        '    "chromium",'
+        '    "ios"'
+        '  ]'
         '}'
-      execution_timeout_secs: 36000
+      execution_timeout_secs: 10800
       caches {
         name: "xcode_ios_13a233"
         path: "xcode_ios_13a233.app"
@@ -56473,7 +56481,7 @@
       }
       experiments {
         key: "luci.recipes.use_python3"
-        value: 1
+        value: 5
       }
       experiments {
         key: "luci.use_realms"
diff --git a/infra/config/generated/luci/luci-milo.cfg b/infra/config/generated/luci/luci-milo.cfg
index da3534b..ef60001 100644
--- a/infra/config/generated/luci/luci-milo.cfg
+++ b/infra/config/generated/luci/luci-milo.cfg
@@ -246,6 +246,11 @@
     short_name: "sim"
   }
   builders {
+    name: "buildbucket/luci.chromium.ci/ios-catalyst"
+    category: "chromium.mac|ios|default"
+    short_name: "ctl"
+  }
+  builders {
     name: "buildbucket/luci.chromium.ci/ios-simulator-full-configs"
     category: "chromium.mac|ios|default"
     short_name: "ful"
@@ -2068,6 +2073,11 @@
     short_name: "sim"
   }
   builders {
+    name: "buildbucket/luci.chromium.ci/ios-catalyst"
+    category: "chromium.mac"
+    short_name: "ctl"
+  }
+  builders {
     name: "buildbucket/luci.chromium.ci/ios-simulator-full-configs"
     category: "chromium.mac"
     short_name: "ful"
@@ -6306,11 +6316,6 @@
     short_name: "asan"
   }
   builders {
-    name: "buildbucket/luci.chromium.ci/ios-catalyst"
-    category: "iOS"
-    short_name: "ctl"
-  }
-  builders {
     name: "buildbucket/luci.chromium.ci/ios-simulator-multi-window"
     category: "iOS"
     short_name: "mwd"
@@ -9127,6 +9132,11 @@
     short_name: "sim"
   }
   builders {
+    name: "buildbucket/luci.chromium.ci/ios-catalyst"
+    category: "ios|default"
+    short_name: "ctl"
+  }
+  builders {
     name: "buildbucket/luci.chromium.ci/ios-simulator-full-configs"
     category: "ios|default"
     short_name: "ful"
diff --git a/infra/config/generated/luci/luci-notify.cfg b/infra/config/generated/luci/luci-notify.cfg
index aaeadaf..c33c58b 100644
--- a/infra/config/generated/luci/luci-notify.cfg
+++ b/infra/config/generated/luci/luci-notify.cfg
@@ -2934,6 +2934,25 @@
   }
   builders {
     bucket: "ci"
+    name: "ios-catalyst"
+    repository: "https://chromium.googlesource.com/chromium/src"
+  }
+  tree_closers {
+    tree_status_host: "chromium-status.appspot.com"
+    failed_step_regexp: "\\b(bot_update|compile|gclient runhooks|runhooks|update|\\w*nocompile_test)\\b"
+  }
+}
+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"
+  }
+  builders {
+    bucket: "ci"
     name: "ios-device"
     repository: "https://chromium.googlesource.com/chromium/src"
   }
diff --git a/infra/config/recipes.star b/infra/config/recipes.star
index 1b127f3..00e0643 100644
--- a/infra/config/recipes.star
+++ b/infra/config/recipes.star
@@ -205,6 +205,7 @@
 
 build_recipe(
     name = "recipe:cronet",
+    use_python3 = True,
 )
 
 build_recipe(
@@ -221,7 +222,7 @@
 build_recipe(
     name = "recipe:presubmit",
     experiments = {
-        "luci.recipes.use_python3": 1,
+        "luci.recipes.use_python3": 5,
     },
 )
 
diff --git a/infra/config/subprojects/chromium/ci/chromium.fyi.star b/infra/config/subprojects/chromium/ci/chromium.fyi.star
index 961cc5a..e5c3a171 100644
--- a/infra/config/subprojects/chromium/ci/chromium.fyi.star
+++ b/infra/config/subprojects/chromium/ci/chromium.fyi.star
@@ -277,6 +277,9 @@
     ),
     notifies = ["annotator-rel"],
     os = os.LINUX_BIONIC_SWITCH_TO_DEFAULT,
+    goma_backend = None,
+    reclient_jobs = rbe_jobs.HIGH_JOBS_FOR_CI,
+    reclient_instance = rbe_instance.DEFAULT,
 )
 
 ci.builder(
@@ -353,6 +356,9 @@
     ),
     notifies = ["linux-blink-fyi-bots"],
     os = os.LINUX_BIONIC_SWITCH_TO_DEFAULT,
+    goma_backend = None,
+    reclient_jobs = rbe_jobs.HIGH_JOBS_FOR_CI,
+    reclient_instance = rbe_instance.DEFAULT,
 )
 
 ci.builder(
@@ -983,16 +989,6 @@
     ),
 )
 fyi_ios_builder(
-    name = "ios-catalyst",
-    console_view_entry = [
-        consoles.console_view_entry(
-            category = "iOS",
-            short_name = "ctl",
-        ),
-    ],
-    os = os.MAC_11,
-)
-fyi_ios_builder(
     name = "ios-reclient",
     console_view_entry = consoles.console_view_entry(
         category = "iOS",
diff --git a/infra/config/subprojects/chromium/ci/chromium.mac.star b/infra/config/subprojects/chromium/ci/chromium.mac.star
index 13b7c85..df7cdcf 100644
--- a/infra/config/subprojects/chromium/ci/chromium.mac.star
+++ b/infra/config/subprojects/chromium/ci/chromium.mac.star
@@ -182,6 +182,24 @@
 )
 
 ios_builder(
+    # We don't have necessary capacity to run this configuration in CQ, but it
+    # is part of the main waterfall
+    name = "ios-catalyst",
+    console_view_entry = [
+        consoles.console_view_entry(
+            category = "ios|default",
+            short_name = "ctl",
+        ),
+        consoles.console_view_entry(
+            branch_selector = branches.MAIN,
+            console_view = "sheriff.ios",
+            category = "chromium.mac",
+            short_name = "ctl",
+        ),
+    ],
+)
+
+ios_builder(
     name = "ios-device",
     console_view_entry = [
         consoles.console_view_entry(
diff --git a/ios/chrome/browser/ssl/BUILD.gn b/ios/chrome/browser/ssl/BUILD.gn
index 9692f3d..1bd1fa9 100644
--- a/ios/chrome/browser/ssl/BUILD.gn
+++ b/ios/chrome/browser/ssl/BUILD.gn
@@ -5,6 +5,7 @@
 source_set("ssl") {
   configs += [ "//build/config/compiler:enable_arc" ]
   sources = [
+    "captive_portal_metrics.cc",
     "captive_portal_metrics.h",
     "captive_portal_tab_helper.h",
     "captive_portal_tab_helper.mm",
diff --git a/ios/chrome/browser/ssl/captive_portal_metrics.cc b/ios/chrome/browser/ssl/captive_portal_metrics.cc
new file mode 100644
index 0000000..30203f0
--- /dev/null
+++ b/ios/chrome/browser/ssl/captive_portal_metrics.cc
@@ -0,0 +1,28 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ios/chrome/browser/ssl/captive_portal_metrics.h"
+
+#include "base/notreached.h"
+
+CaptivePortalStatus CaptivePortalStatusFromDetectionResult(
+    captive_portal::CaptivePortalResult result) {
+  CaptivePortalStatus status;
+  switch (result) {
+    case captive_portal::RESULT_INTERNET_CONNECTED:
+      status = CaptivePortalStatus::ONLINE;
+      break;
+    case captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL:
+      status = CaptivePortalStatus::PORTAL;
+      break;
+    case captive_portal::RESULT_NO_RESPONSE:
+      status = CaptivePortalStatus::UNKNOWN;
+      break;
+    case captive_portal::RESULT_COUNT:
+      NOTREACHED();
+      status = CaptivePortalStatus::UNKNOWN;
+      break;
+  }
+  return status;
+}
diff --git a/ios/chrome/browser/ssl/captive_portal_metrics.h b/ios/chrome/browser/ssl/captive_portal_metrics.h
index 0265e6d..ba62a44 100644
--- a/ios/chrome/browser/ssl/captive_portal_metrics.h
+++ b/ios/chrome/browser/ssl/captive_portal_metrics.h
@@ -5,6 +5,8 @@
 #ifndef IOS_CHROME_BROWSER_SSL_CAPTIVE_PORTAL_METRICS_H_
 #define IOS_CHROME_BROWSER_SSL_CAPTIVE_PORTAL_METRICS_H_
 
+#include "components/captive_portal/core/captive_portal_types.h"
+
 // Enum used to record the captive portal detection result.
 enum class CaptivePortalStatus {
   UNKNOWN = 0,
@@ -15,4 +17,9 @@
   COUNT
 };
 
+// Returns the associated CaptivePortalStatus value for logging to UMA metrics
+// based on detection |result|.
+CaptivePortalStatus CaptivePortalStatusFromDetectionResult(
+    captive_portal::CaptivePortalResult result);
+
 #endif  // IOS_CHROME_BROWSER_SSL_CAPTIVE_PORTAL_METRICS_H_
diff --git a/ios/chrome/browser/ssl/ios_ssl_error_handler.mm b/ios/chrome/browser/ssl/ios_ssl_error_handler.mm
index 7104eeb3..d9862ae 100644
--- a/ios/chrome/browser/ssl/ios_ssl_error_handler.mm
+++ b/ios/chrome/browser/ssl/ios_ssl_error_handler.mm
@@ -29,15 +29,17 @@
 #error "This file requires ARC support."
 #endif
 
-const char kSessionDetectionResultHistogram[] =
-    "CaptivePortal.Session.DetectionResult";
-
 const int64_t kSSLInterstitialDelayInSeconds = 3;
 
 using captive_portal::CaptivePortalDetector;
 using security_interstitials::IOSBlockingPageTabHelper;
 
 namespace {
+// Result of captive portal network check after a request fails with
+// NSURLErrorSecureConnectionFailed.
+const char kCaptivePortalSecureConnectionFailedHistogram[] =
+    "IOS.CaptivePortal.SecureConnectionFailed";
+
 std::unique_ptr<security_interstitials::IOSBlockingPageMetricsHelper>
 CreateMetricsHelper(web::WebState* web_state,
                     const GURL& request_url,
@@ -188,19 +190,8 @@
 // static
 void IOSSSLErrorHandler::LogCaptivePortalResult(
     captive_portal::CaptivePortalResult result) {
-  CaptivePortalStatus status;
-  switch (result) {
-    case captive_portal::RESULT_INTERNET_CONNECTED:
-      status = CaptivePortalStatus::ONLINE;
-      break;
-    case captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL:
-      status = CaptivePortalStatus::PORTAL;
-      break;
-    default:
-      status = CaptivePortalStatus::UNKNOWN;
-      break;
-  }
-  UMA_HISTOGRAM_ENUMERATION(kSessionDetectionResultHistogram,
+  CaptivePortalStatus status = CaptivePortalStatusFromDetectionResult(result);
+  UMA_HISTOGRAM_ENUMERATION(kCaptivePortalSecureConnectionFailedHistogram,
                             static_cast<int>(status),
                             static_cast<int>(CaptivePortalStatus::COUNT));
 }
diff --git a/ios/chrome/browser/tabs_search/BUILD.gn b/ios/chrome/browser/tabs_search/BUILD.gn
index c1f7a8fe..aca4c85d 100644
--- a/ios/chrome/browser/tabs_search/BUILD.gn
+++ b/ios/chrome/browser/tabs_search/BUILD.gn
@@ -18,6 +18,7 @@
     "//components/sync_sessions",
     "//ios/chrome/browser/history",
     "//ios/chrome/browser/main:public",
+    "//ios/chrome/browser/sessions",
     "//ios/chrome/browser/signin",
     "//ios/chrome/browser/sync",
     "//ios/chrome/browser/tabs",
@@ -54,7 +55,10 @@
     "//ios/chrome/browser/browser_state:test_support",
     "//ios/chrome/browser/main:public",
     "//ios/chrome/browser/main:test_support",
+    "//ios/chrome/browser/sessions",
+    "//ios/chrome/browser/tabs",
     "//ios/chrome/browser/web_state_list",
+    "//ios/chrome/test:test_support",
     "//ios/web/public/test",
     "//ios/web/public/test/fakes",
     "//testing/gtest",
diff --git a/ios/chrome/browser/tabs_search/tabs_search_service.h b/ios/chrome/browser/tabs_search/tabs_search_service.h
index d6378560..3c4f1c9 100644
--- a/ios/chrome/browser/tabs_search/tabs_search_service.h
+++ b/ios/chrome/browser/tabs_search/tabs_search_service.h
@@ -18,6 +18,10 @@
 class BrowserList;
 class ChromeBrowserState;
 
+namespace sessions {
+class SerializedNavigationEntry;
+}  // namespace sessions
+
 namespace synced_sessions {
 struct DistantTab;
 }  // namespace synced_sessions
@@ -47,6 +51,13 @@
       const std::u16string& term,
       base::OnceCallback<void(std::vector<web::WebState*>)> completion);
 
+  // Searches through recently closed tabs within |browser_state| in the same
+  // manner as |Search|.
+  void SearchRecentlyClosed(
+      const std::u16string& term,
+      base::OnceCallback<void(
+          std::vector<const sessions::SerializedNavigationEntry>)> completion);
+
   // Searches through Remote Tabs for tabs matching |term|.
   void SearchRemoteTabs(
       const std::u16string& term,
diff --git a/ios/chrome/browser/tabs_search/tabs_search_service.mm b/ios/chrome/browser/tabs_search/tabs_search_service.mm
index 4b0083e..9b6507c 100644
--- a/ios/chrome/browser/tabs_search/tabs_search_service.mm
+++ b/ios/chrome/browser/tabs_search/tabs_search_service.mm
@@ -11,6 +11,7 @@
 #import "base/strings/sys_string_conversions.h"
 #import "base/strings/utf_string_conversions.h"
 #include "components/keyed_service/core/service_access_type.h"
+#include "components/sessions/core/tab_restore_service.h"
 #include "components/signin/public/base/consent_level.h"
 #include "components/signin/public/identity_manager/identity_manager.h"
 #include "components/sync_sessions/session_sync_service.h"
@@ -19,6 +20,7 @@
 #include "ios/chrome/browser/history/web_history_service_factory.h"
 #import "ios/chrome/browser/main/browser.h"
 #import "ios/chrome/browser/main/browser_list.h"
+#include "ios/chrome/browser/sessions/ios_chrome_tab_restore_service_factory.h"
 #include "ios/chrome/browser/signin/identity_manager_factory.h"
 #include "ios/chrome/browser/sync/session_sync_service_factory.h"
 #include "ios/chrome/browser/sync/sync_service_factory.h"
@@ -56,6 +58,37 @@
                        std::move(completion));
 }
 
+void TabsSearchService::SearchRecentlyClosed(
+    const std::u16string& term,
+    base::OnceCallback<void(
+        std::vector<const sessions::SerializedNavigationEntry>)> completion) {
+  FixedPatternStringSearchIgnoringCaseAndAccents query_search(term);
+
+  std::vector<const sessions::SerializedNavigationEntry> results;
+  sessions::TabRestoreService* restore_service =
+      IOSChromeTabRestoreServiceFactory::GetForBrowserState(browser_state_);
+  for (auto iter = restore_service->entries().begin();
+       iter != restore_service->entries().end(); ++iter) {
+    const sessions::TabRestoreService::Entry* entry = iter->get();
+    DCHECK(entry);
+    DCHECK_EQ(sessions::TabRestoreService::TAB, entry->type);
+    const sessions::TabRestoreService::Tab* tab =
+        static_cast<const sessions::TabRestoreService::Tab*>(entry);
+    const sessions::SerializedNavigationEntry& navigationEntry =
+        tab->navigations[tab->current_navigation_index];
+
+    if (query_search.Search(navigationEntry.title(), /*match_index=*/nullptr,
+                            /*match_length=*/nullptr) ||
+        query_search.Search(
+            base::UTF8ToUTF16(navigationEntry.virtual_url().spec()),
+            /*match_index=*/nullptr, nullptr)) {
+      results.push_back(navigationEntry);
+    }
+  }
+
+  std::move(completion).Run(results);
+}
+
 void TabsSearchService::SearchRemoteTabs(
     const std::u16string& term,
     base::OnceCallback<void(std::vector<synced_sessions::DistantTab*>)>
diff --git a/ios/chrome/browser/tabs_search/tabs_search_service_unittest.mm b/ios/chrome/browser/tabs_search/tabs_search_service_unittest.mm
index 5a9c76b..432280f4a 100644
--- a/ios/chrome/browser/tabs_search/tabs_search_service_unittest.mm
+++ b/ios/chrome/browser/tabs_search/tabs_search_service_unittest.mm
@@ -4,17 +4,25 @@
 
 #import "ios/chrome/browser/tabs_search/tabs_search_service.h"
 
+#include <memory>
 #include <vector>
 
 #include "base/i18n/case_conversion.h"
 #include "base/strings/utf_string_conversions.h"
+#include "components/sessions/core/tab_restore_service_impl.h"
 #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
+#include "ios/chrome/browser/browser_state/test_chrome_browser_state_manager.h"
 #import "ios/chrome/browser/main/browser_list.h"
 #import "ios/chrome/browser/main/browser_list_factory.h"
 #include "ios/chrome/browser/main/test_browser.h"
+#include "ios/chrome/browser/sessions/ios_chrome_tab_restore_service_client.h"
+#include "ios/chrome/browser/sessions/ios_chrome_tab_restore_service_factory.h"
+#import "ios/chrome/browser/tabs/closing_web_state_observer_browser_agent.h"
 #import "ios/chrome/browser/tabs_search/tabs_search_service_factory.h"
 #import "ios/chrome/browser/web_state_list/web_state_list.h"
 #import "ios/chrome/browser/web_state_list/web_state_opener.h"
+#include "ios/chrome/test/ios_chrome_scoped_testing_chrome_browser_state_manager.h"
+#import "ios/web/public/test/fakes/fake_navigation_manager.h"
 #import "ios/web/public/test/fakes/fake_web_state.h"
 #include "ios/web/public/test/web_task_environment.h"
 #include "testing/platform_test.h"
@@ -44,18 +52,35 @@
 const char kWebState2Url[] = "http://www.url2.com/";
 // Title for a second sample WebState.
 const char16_t kWebState2Title[] = u"Web State 2";
+
+std::unique_ptr<KeyedService> BuildTabRestoreService(
+    web::BrowserState* context) {
+  ChromeBrowserState* browser_state =
+      ChromeBrowserState::FromBrowserState(context);
+  return std::make_unique<sessions::TabRestoreServiceImpl>(
+      base::WrapUnique(new IOSChromeTabRestoreServiceClient(browser_state)),
+      browser_state->GetPrefs(), nullptr);
+}
 }  // namespace
 
 // Test fixture to test the search service.
 class TabsSearchServiceTest : public PlatformTest {
  public:
-  TabsSearchServiceTest() {
+  TabsSearchServiceTest()
+      : scoped_browser_state_manager_(
+            std::make_unique<TestChromeBrowserStateManager>(base::FilePath())) {
     TestChromeBrowserState::Builder test_browser_state_builder;
     chrome_browser_state_ = test_browser_state_builder.Build();
+    IOSChromeTabRestoreServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+        chrome_browser_state_.get(),
+        base::BindRepeating(&BuildTabRestoreService));
+
     browser_list_ =
         BrowserListFactory::GetForBrowserState(chrome_browser_state_.get());
 
     browser_ = std::make_unique<TestBrowser>(chrome_browser_state_.get());
+    ClosingWebStateObserverBrowserAgent::CreateForBrowser(browser_.get());
+
     browser_list_->AddBrowser(browser_.get());
 
     other_browser_ = std::make_unique<TestBrowser>(chrome_browser_state_.get());
@@ -79,6 +104,14 @@
     fake_web_state->SetVisibleURL(url);
     fake_web_state->SetTitle(title);
 
+    auto navigation_manager = std::make_unique<web::FakeNavigationManager>();
+
+    navigation_manager->AddItem(url, ui::PAGE_TRANSITION_LINK);
+    int item_index = navigation_manager->GetLastCommittedItemIndex();
+    navigation_manager->GetItemAtIndex(item_index)->SetTitle(title);
+
+    fake_web_state->SetNavigationManager(std::move(navigation_manager));
+
     web::FakeWebState* inserted_web_state = fake_web_state.get();
     browser->GetWebStateList()->InsertWebState(
         WebStateList::kInvalidIndex, std::move(fake_web_state),
@@ -93,6 +126,7 @@
   }
 
   web::WebTaskEnvironment task_environment_;
+  IOSChromeScopedTestingChromeBrowserStateManager scoped_browser_state_manager_;
   std::unique_ptr<TestChromeBrowserState> chrome_browser_state_;
   std::unique_ptr<Browser> browser_;
   std::unique_ptr<Browser> other_browser_;
@@ -352,3 +386,109 @@
 
   ASSERT_TRUE(results_received);
 }
+
+// Tests that no recently closed tabs are returned before any tabs are closed.
+TEST_F(TabsSearchServiceTest, RecentlyClosedNoResults) {
+  AppendNewWebState(browser_.get(), kWebState1Title, GURL(kWebState1Url));
+
+  __block bool results_received = false;
+  search_service()->SearchRecentlyClosed(
+      kWebState1Title,
+      base::BindOnce(
+          ^(std::vector<const sessions::SerializedNavigationEntry> results) {
+            ASSERT_EQ(0ul, results.size());
+            results_received = true;
+          }));
+
+  ASSERT_TRUE(results_received);
+}
+
+// Tests that no recently closed tabs are returned when the search term doesn't
+// match the recently closed tabs.
+TEST_F(TabsSearchServiceTest, RecentlyClosedNoMatch) {
+  AppendNewWebState(browser_.get(), kWebState1Title, GURL(kWebState1Url));
+
+  browser_->GetWebStateList()->CloseWebStateAt(/*index=*/0,
+                                               WebStateList::CLOSE_NO_FLAGS);
+
+  __block bool results_received = false;
+  search_service()->SearchRecentlyClosed(
+      kSearchQueryMatchesNone,
+      base::BindOnce(
+          ^(std::vector<const sessions::SerializedNavigationEntry> results) {
+            ASSERT_EQ(0ul, results.size());
+            results_received = true;
+          }));
+
+  ASSERT_TRUE(results_received);
+}
+
+// Tests that a recently closed tab is matched based on a title string match.
+TEST_F(TabsSearchServiceTest, RecentlyClosedMatchTitle) {
+  AppendNewWebState(browser_.get(), kWebState1Title, GURL(kWebState1Url));
+  AppendNewWebState(browser_.get(), kWebState2Title, GURL(kWebState2Url));
+
+  browser_->GetWebStateList()->CloseWebStateAt(/*index=*/0,
+                                               WebStateList::CLOSE_NO_FLAGS);
+
+  __block bool results_received = false;
+  search_service()->SearchRecentlyClosed(
+      kWebState1Title,
+      base::BindOnce(
+          ^(std::vector<const sessions::SerializedNavigationEntry> results) {
+            ASSERT_EQ(1ul, results.size());
+            EXPECT_EQ(kWebState1Url, results.front().virtual_url().spec());
+            EXPECT_EQ(kWebState1Title, results.front().title());
+            results_received = true;
+          }));
+
+  ASSERT_TRUE(results_received);
+}
+
+// Tests that a recently closed tab is matched based on a url match.
+TEST_F(TabsSearchServiceTest, RecentlyClosedMatchURL) {
+  AppendNewWebState(browser_.get(), kWebState1Title, GURL(kWebState1Url));
+  AppendNewWebState(browser_.get(), kWebState2Title, GURL(kWebState2Url));
+
+  browser_->GetWebStateList()->CloseWebStateAt(/*index=*/0,
+                                               WebStateList::CLOSE_NO_FLAGS);
+
+  __block bool results_received = false;
+  search_service()->SearchRecentlyClosed(
+      kWebState1ParamValue,
+      base::BindOnce(
+          ^(std::vector<const sessions::SerializedNavigationEntry> results) {
+            ASSERT_EQ(1ul, results.size());
+            EXPECT_EQ(kWebState1Url, results.front().virtual_url().spec());
+            EXPECT_EQ(kWebState1Title, results.front().title());
+
+            results_received = true;
+          }));
+
+  ASSERT_TRUE(results_received);
+}
+
+// Tests that a recently closed tab is matched based on a title string match.
+TEST_F(TabsSearchServiceTest, RecentlyClosedMatchTitleAllClosed) {
+  AppendNewWebState(browser_.get(), kWebState1Title, GURL(kWebState1Url));
+  AppendNewWebState(browser_.get(), kWebState2Title, GURL(kWebState2Url));
+  // Add a webstate which will not match |kSearchQueryMatchesAll|.
+  AppendNewWebState(browser_.get(), u"X", GURL("http://abc.xyz"));
+
+  browser_->GetWebStateList()->CloseAllWebStates(WebStateList::CLOSE_NO_FLAGS);
+
+  __block bool results_received = false;
+  search_service()->SearchRecentlyClosed(
+      kSearchQueryMatchesAll,
+      base::BindOnce(
+          ^(std::vector<const sessions::SerializedNavigationEntry> results) {
+            ASSERT_EQ(2ul, results.size());
+            EXPECT_EQ(kWebState1Url, results.front().virtual_url().spec());
+            EXPECT_EQ(kWebState1Title, results.front().title());
+            EXPECT_EQ(kWebState2Url, results.back().virtual_url().spec());
+            EXPECT_EQ(kWebState2Title, results.back().title());
+            results_received = true;
+          }));
+
+  ASSERT_TRUE(results_received);
+}
diff --git a/ios/chrome/credential_provider_extension/credential_provider_view_controller.mm b/ios/chrome/credential_provider_extension/credential_provider_view_controller.mm
index 6b213c6..a368c67 100644
--- a/ios/chrome/credential_provider_extension/credential_provider_view_controller.mm
+++ b/ios/chrome/credential_provider_extension/credential_provider_view_controller.mm
@@ -33,6 +33,14 @@
 #error "This file requires ARC support."
 #endif
 
+namespace {
+UIColor* BackgroundColor() {
+  return IsPasswordCreationEnabled()
+             ? [UIColor colorNamed:kGroupedPrimaryBackgroundColor]
+             : [UIColor colorNamed:kBackgroundColor];
+}
+}
+
 @interface CredentialProviderViewController () <ConfirmationAlertActionHandler,
                                                 SuccessfulReauthTimeAccessor>
 
@@ -68,6 +76,11 @@
 // Loading indicator used for user validation, which APIs can take a long time.
 @property(nonatomic, strong) UIActivityIndicatorView* activityIndicatorView;
 
+// Identfiers cached in |-prepareCredentialListForServiceIdentifiers:| to show
+// the next time this view appears.
+@property(nonatomic, strong)
+    NSArray<ASCredentialServiceIdentifier*>* serviceIdentifiers;
+
 @end
 
 @implementation CredentialProviderViewController
@@ -80,25 +93,46 @@
   }
 }
 
+- (void)viewDidLoad {
+  [super viewDidLoad];
+  self.view.backgroundColor = BackgroundColor();
+}
+
+- (void)viewWillAppear:(BOOL)animated {
+  [super viewWillAppear:animated];
+  // If identifiers were stored in
+  // |-prepareCredentialListForServiceIdentifiers:|, handle that now.
+  if (self.serviceIdentifiers) {
+    NSArray<ASCredentialServiceIdentifier*>* serviceIdentifiers =
+        self.serviceIdentifiers;
+    self.serviceIdentifiers = nil;
+    __weak __typeof__(self) weakSelf = self;
+    [self validateUserWithCompletion:^(BOOL userIsValid) {
+      if (!userIsValid) {
+        [weakSelf showStaleCredentials];
+        return;
+      }
+      [weakSelf reauthenticateIfNeededWithCompletionHandler:^(
+                    ReauthenticationResult result) {
+        if (result != ReauthenticationResult::kFailure) {
+          [weakSelf showCredentialListForServiceIdentifiers:serviceIdentifiers];
+        } else {
+          [weakSelf exitWithErrorCode:ASExtensionErrorCodeFailed];
+        }
+      }];
+    }];
+  }
+}
+
 #pragma mark - ASCredentialProviderViewController
 
 - (void)prepareCredentialListForServiceIdentifiers:
     (NSArray<ASCredentialServiceIdentifier*>*)serviceIdentifiers {
-  __weak __typeof__(self) weakSelf = self;
-  [self validateUserWithCompletion:^(BOOL userIsValid) {
-    if (!userIsValid) {
-      [weakSelf showStaleCredentials];
-      return;
-    }
-    [weakSelf reauthenticateIfNeededWithCompletionHandler:^(
-                  ReauthenticationResult result) {
-      if (result != ReauthenticationResult::kFailure) {
-        [weakSelf showCredentialListForServiceIdentifiers:serviceIdentifiers];
-      } else {
-        [weakSelf exitWithErrorCode:ASExtensionErrorCodeFailed];
-      }
-    }];
-  }];
+  // Sometimes, this method is called while the authentication framework thinks
+  // the app is not foregrounded, so authentication fails. Instead of directly
+  // authenticating and showing the credentials, store the list of
+  // identifiers and authenticate once the extension is visible.
+  self.serviceIdentifiers = serviceIdentifiers;
 }
 
 - (void)provideCredentialWithoutUserInteractionForIdentity:
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 70fd8fb..d8bd273 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 @@
-b62ac8aff4ba4db43c9558cb4c751353f3f13677
\ No newline at end of file
+98e34c9bd8467de54f31b6849216f915e5ce9b71
\ 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 992507d5..ce99124 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 @@
-ee634d67a5acefac26cacb525b64f8c97bc8b4b0
\ No newline at end of file
+8fc241e4d29caa8900339b2a449628d51b798f53
\ 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 f80304f..8017274 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 @@
-d816488d22dc91807907e825e6bcb54e1bcf765b
\ No newline at end of file
+dea257e2babf128def3a05899747f145ea5a6d9d
\ 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 cc853f6..036362be 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 @@
-0c1e1545567349a7babae19aa4e76de1b7058d1b
\ No newline at end of file
+81268634c9fa5bc11dae81d0f083b495257514df
\ 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 a49977a..231ba121 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 @@
-a6ca2a24d1cc5bf2dfd787ff5bbaa9adf7ec61d2
\ No newline at end of file
+bdf395fc2079d8834feed85c47610f7efc6bad38
\ 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 e7a3c90..c541eabd 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 @@
-f1a9cd8cb4d1c29bc1d501826c27401dcd51352c
\ No newline at end of file
+b8c410eec9723c1405d4aab2f5b342da3e0f4e2c
\ 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 d9ff06a..bff8575 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 @@
-d77f84ae4e1f0169f9183ce4a46a11a2c5a924e6
\ No newline at end of file
+ad335ce00ff3629f7f1fd8938b4406db40757341
\ 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 3e326b0..05151d63 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 @@
-14ba286386dad28bdd84b7fe57768a8a498a5107
\ No newline at end of file
+e50673e9c2e2fd52876d012d739fa2192ea1d8a6
\ 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 5f875e9..67a3300 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 @@
-59226878b7c5dd6cca3752f0b5646cdcf385e444
\ No newline at end of file
+199be598097f9edc9edbce67eeb1a34639ba75e4
\ 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 0352dbe..9c46015 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 @@
-c1cb5a9d85fcf5e1916e0931dfd868f7c06371ce
\ No newline at end of file
+d2745bb41de5904ec74b0099f13ded92a96b3c9c
\ No newline at end of file
diff --git a/jingle/BUILD.gn b/jingle/BUILD.gn
index 78bad2f..5aad94f 100644
--- a/jingle/BUILD.gn
+++ b/jingle/BUILD.gn
@@ -28,48 +28,10 @@
   ]
 }
 
-static_library("jingle_glue") {
-  visibility = [
-    ":*",
-    "//content/test:*",
-    "//remoting/protocol",
-    "//remoting/signaling",
-  ]
-  sources = [
-    "glue/network_service_async_socket.cc",
-    "glue/network_service_async_socket.h",
-    "glue/network_service_config.cc",
-    "glue/network_service_config.h",
-    "glue/task_pump.cc",
-    "glue/task_pump.h",
-  ]
-  public_deps = [ "//services/network/public/mojom" ]
-  deps = [
-    "//base",
-    "//net",
-    "//third_party/libjingle_xmpp:rtc_task_runner",
-    "//third_party/libjingle_xmpp:rtc_xmpp",
-  ]
-
-  if (is_nacl) {
-    sources -= [
-      "glue/network_service_async_socket.cc",
-      "glue/network_service_config.cc",
-    ]
-    public_deps -= [ "//services/network/public/mojom" ]
-  }
-}
-
 test("jingle_unittests") {
   sources = [
     "glue/fake_ssl_client_socket_unittest.cc",
-    "glue/jingle_glue_mock_objects.cc",
-    "glue/jingle_glue_mock_objects.h",
     "glue/logging_unittest.cc",
-    "glue/mock_task.cc",
-    "glue/mock_task.h",
-    "glue/network_service_async_socket_unittest.cc",
-    "glue/task_pump_unittest.cc",
     "glue/thread_wrapper_unittest.cc",
     "run_all_unittests.cc",
   ]
@@ -80,7 +42,6 @@
   }
 
   deps = [
-    ":jingle_glue",
     ":webrtc_glue",
     "//base",
     "//base/test:test_support",
diff --git a/jingle/glue/jingle_glue_mock_objects.cc b/jingle/glue/jingle_glue_mock_objects.cc
deleted file mode 100644
index 6cd48ce..0000000
--- a/jingle/glue/jingle_glue_mock_objects.cc
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "jingle/glue/jingle_glue_mock_objects.h"
-
-namespace jingle_glue {
-
-MockStream::MockStream() {}
-
-MockStream::~MockStream() {}
-
-}  // namespace jingle_glue
diff --git a/jingle/glue/jingle_glue_mock_objects.h b/jingle/glue/jingle_glue_mock_objects.h
deleted file mode 100644
index 9ed4b7e..0000000
--- a/jingle/glue/jingle_glue_mock_objects.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef JINGLE_GLUE_JINGLE_GLUE_MOCK_OBJECTS_H_
-#define JINGLE_GLUE_JINGLE_GLUE_MOCK_OBJECTS_H_
-
-#include <stddef.h>
-
-#include "testing/gmock/include/gmock/gmock.h"
-#include "third_party/webrtc/rtc_base/stream.h"
-
-namespace jingle_glue {
-
-class MockStream : public rtc::StreamInterface {
- public:
-  MockStream();
-  ~MockStream() override;
-
-  MOCK_CONST_METHOD0(GetState, rtc::StreamState());
-
-  MOCK_METHOD4(Read, rtc::StreamResult(void*, size_t, size_t*, int*));
-  MOCK_METHOD4(Write, rtc::StreamResult(const void*, size_t,
-                                              size_t*, int*));
-  MOCK_CONST_METHOD1(GetAvailable, bool(size_t*));
-  MOCK_METHOD0(Close, void());
-
-  MOCK_METHOD3(PostEvent, void(rtc::Thread*, int, int));
-  MOCK_METHOD2(PostEvent, void(int, int));
-};
-
-}  // namespace jingle_glue
-
-#endif  // JINGLE_GLUE_JINGLE_GLUE_MOCK_OBJECTS_H_
diff --git a/jingle/glue/mock_task.cc b/jingle/glue/mock_task.cc
deleted file mode 100644
index a187899c..0000000
--- a/jingle/glue/mock_task.cc
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "jingle/glue/mock_task.h"
-
-namespace jingle_glue {
-
-MockTask::MockTask(TaskParent* parent) : jingle_xmpp::Task(parent) {}
-
-MockTask::~MockTask() {}
-
-}  // namespace jingle_glue
diff --git a/jingle/glue/mock_task.h b/jingle/glue/mock_task.h
deleted file mode 100644
index e74f1f5..0000000
--- a/jingle/glue/mock_task.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// A mock of rtc::Task.
-
-#ifndef JINGLE_GLUE_MOCK_TASK_H_
-#define JINGLE_GLUE_MOCK_TASK_H_
-
-#include "testing/gmock/include/gmock/gmock.h"
-#include "third_party/libjingle_xmpp/task_runner/task.h"
-
-namespace jingle_glue {
-
-class MockTask : public jingle_xmpp::Task {
- public:
-  MockTask(TaskParent* parent);
-
-  ~MockTask() override;
-
-  MOCK_METHOD0(ProcessStart, int());
-};
-
-}  // namespace jingle_glue
-
-#endif  // JINGLE_GLUE_MOCK_TASK_H_
diff --git a/jingle/glue/network_service_async_socket.cc b/jingle/glue/network_service_async_socket.cc
deleted file mode 100644
index 066b34c..0000000
--- a/jingle/glue/network_service_async_socket.cc
+++ /dev/null
@@ -1,591 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "jingle/glue/network_service_async_socket.h"
-
-#include <stddef.h>
-#include <algorithm>
-#include <cstdlib>
-#include <cstring>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/compiler_specific.h"
-#include "base/logging.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "mojo/public/cpp/bindings/pending_remote.h"
-#include "net/base/host_port_pair.h"
-#include "net/base/io_buffer.h"
-#include "net/base/network_isolation_key.h"
-#include "url/gurl.h"
-#include "url/origin.h"
-
-namespace jingle_glue {
-
-NetworkServiceAsyncSocket::NetworkServiceAsyncSocket(
-    GetProxyResolvingSocketFactoryCallback get_socket_factory_callback,
-    bool use_fake_tls_handshake,
-    size_t read_buf_size,
-    size_t write_buf_size,
-    const net::NetworkTrafficAnnotationTag& traffic_annotation)
-    : get_socket_factory_callback_(get_socket_factory_callback),
-      use_fake_tls_handshake_(use_fake_tls_handshake),
-      state_(STATE_CLOSED),
-      error_(ERROR_NONE),
-      net_error_(net::OK),
-      read_state_(IDLE),
-      read_buf_(read_buf_size),
-      read_start_(0U),
-      read_end_(0U),
-      saw_error_on_read_pipe_(false),
-      saw_error_on_write_pipe_(false),
-      saw_read_error_on_socket_observer_pipe_(net::ERR_IO_PENDING),
-      saw_write_error_on_socket_observer_pipe_(net::ERR_IO_PENDING),
-      write_state_(IDLE),
-      write_buf_(write_buf_size),
-      write_end_(0U),
-      traffic_annotation_(traffic_annotation) {
-  DCHECK(get_socket_factory_callback_);
-  DCHECK_GT(read_buf_size, 0U);
-  DCHECK_GT(write_buf_size, 0U);
-}
-
-NetworkServiceAsyncSocket::~NetworkServiceAsyncSocket() {}
-
-NetworkServiceAsyncSocket::State NetworkServiceAsyncSocket::state() {
-  return state_;
-}
-
-NetworkServiceAsyncSocket::Error NetworkServiceAsyncSocket::error() {
-  return error_;
-}
-
-int NetworkServiceAsyncSocket::GetError() {
-  return net_error_;
-}
-
-bool NetworkServiceAsyncSocket::IsOpen() const {
-  return (state_ == STATE_OPEN) || (state_ == STATE_TLS_OPEN);
-}
-
-void NetworkServiceAsyncSocket::DoNonNetError(Error error) {
-  DCHECK_NE(error, ERROR_NONE);
-  DCHECK_NE(error, ERROR_WINSOCK);
-  error_ = error;
-  net_error_ = net::OK;
-}
-
-void NetworkServiceAsyncSocket::DoNetError(net::Error net_error) {
-  error_ = ERROR_WINSOCK;
-  net_error_ = net_error;
-}
-
-void NetworkServiceAsyncSocket::DoNetErrorFromStatus(int status) {
-  DCHECK_LT(status, net::OK);
-  DoNetError(static_cast<net::Error>(status));
-}
-
-void NetworkServiceAsyncSocket::ProcessSocketObserverError() {
-  if (saw_read_error_on_socket_observer_pipe_ == net::ERR_IO_PENDING &&
-      saw_write_error_on_socket_observer_pipe_ == net::ERR_IO_PENDING) {
-    // Haven't seen an error, and the socket observer pipe got broken.
-    // This shouldn't normally happen, but as the trust level of network service
-    // is lower than of browser process, it needs to be handled.
-    DoNetError(net::ERR_FAILED);
-    DoClose();
-  }
-  // In case an error came in on the socket observer pipe, it will
-  // get handled at time of read data pipe's closing.
-}
-
-void NetworkServiceAsyncSocket::OnReadError(int32_t net_error) {
-  // Ignore redundant error messages.
-  if (saw_read_error_on_socket_observer_pipe_ != net::ERR_IO_PENDING)
-    return;
-
-  // Sanitize any invalid error code,
-  if (net_error > 0 || net_error == net::ERR_IO_PENDING)
-    net_error = net::ERR_FAILED;
-  if (saw_error_on_read_pipe_) {
-    // Read pipe closure got delivered first, and so with the socket observer
-    // notification here, both pipes got fully handled.
-    ReportReadError(net_error);
-  } else {
-    // Read error notification on socket observer pipe got delivered first;
-    // save error code for read pipe closure to deliver.
-    saw_read_error_on_socket_observer_pipe_ = net_error;
-  }
-}
-
-void NetworkServiceAsyncSocket::OnWriteError(int32_t net_error) {
-  // Ignore redundant error messages.
-  if (saw_write_error_on_socket_observer_pipe_ != net::ERR_IO_PENDING)
-    return;
-
-  // Sanitize any invalid error code,
-  if (net_error >= 0 || net_error == net::ERR_IO_PENDING)
-    net_error = net::ERR_FAILED;
-  if (saw_error_on_write_pipe_) {
-    // Write pipe closure got delivered first, and so with the socket observer
-    // notification here, both pipes got fully handled.
-    DoNetErrorFromStatus(net_error);
-    DoClose();
-  } else {
-    // Write error notification on socket observer pipe got delivered first;
-    // save error code for write pipe closure to deliver.
-    saw_write_error_on_socket_observer_pipe_ = net_error;
-  }
-}
-
-// STATE_CLOSED -> STATE_CONNECTING
-
-bool NetworkServiceAsyncSocket::Connect(const net::HostPortPair& address) {
-  if (state_ != STATE_CLOSED) {
-    LOG(DFATAL) << "Connect() called on non-closed socket";
-    DoNonNetError(ERROR_WRONGSTATE);
-    return false;
-  }
-  if (address.host().empty() || address.port() == 0) {
-    DoNonNetError(ERROR_DNS);
-    return false;
-  }
-
-  DCHECK_EQ(state_, jingle_xmpp::AsyncSocket::STATE_CLOSED);
-  DCHECK_EQ(read_state_, IDLE);
-  DCHECK_EQ(write_state_, IDLE);
-
-  state_ = STATE_CONNECTING;
-
-  get_socket_factory_callback_.Run(
-      socket_factory_.BindNewPipeAndPassReceiver());
-
-  mojo::PendingRemote<network::mojom::SocketObserver> socket_observer;
-  auto socket_observer_receiver =
-      socket_observer.InitWithNewPipeAndPassReceiver();
-  network::mojom::ProxyResolvingSocketOptionsPtr options =
-      network::mojom::ProxyResolvingSocketOptions::New();
-  options->use_tls = false;
-  options->fake_tls_handshake = use_fake_tls_handshake_;
-  GURL url("https://" + address.ToString());
-  auto origin = url::Origin::Create(url);
-  socket_factory_->CreateProxyResolvingSocket(
-      url,
-      net::NetworkIsolationKey(origin /* top_frame_origin */,
-                               origin /* frame_origin */),
-      std::move(options),
-      net::MutableNetworkTrafficAnnotationTag(traffic_annotation_),
-      socket_.BindNewPipeAndPassReceiver(), std::move(socket_observer),
-      base::BindOnce(&NetworkServiceAsyncSocket::ProcessConnectDone,
-                     base::Unretained(this),
-                     std::move(socket_observer_receiver)));
-  return true;
-}
-
-// STATE_CONNECTING -> STATE_OPEN
-// read_state_ == IDLE -> read_state_ == WAITING (via WatchForReadReady())
-
-void NetworkServiceAsyncSocket::ProcessConnectDone(
-    mojo::PendingReceiver<network::mojom::SocketObserver>
-        socket_observer_receiver,
-    int status,
-    const absl::optional<net::IPEndPoint>& local_addr,
-    const absl::optional<net::IPEndPoint>& peer_addr,
-    mojo::ScopedDataPipeConsumerHandle receive_stream,
-    mojo::ScopedDataPipeProducerHandle send_stream) {
-  DCHECK_NE(status, net::ERR_IO_PENDING);
-  DCHECK_EQ(read_state_, IDLE);
-  DCHECK_EQ(write_state_, IDLE);
-  DCHECK_EQ(state_, STATE_CONNECTING);
-  if (status != net::OK) {
-    DoNetErrorFromStatus(status);
-    DoClose();
-    return;
-  }
-  state_ = STATE_OPEN;
-  ConnectPipes(std::move(receive_stream), std::move(send_stream));
-  BindSocketObserver(std::move(socket_observer_receiver));
-
-  WatchForReadReady();
-  // Write buffer should be empty.
-  DCHECK_EQ(write_end_, 0U);
-  SignalConnected();
-}
-
-// read_state_ == IDLE -> read_state_ == WAITING
-
-void NetworkServiceAsyncSocket::WatchForReadReady() {
-  // Note that this never transitions to ProcessReadReady immediately; which
-  // avoids potentially error-prone synchronous notifications from within
-  // methods like Connect() and Read().
-  DCHECK(IsOpen());
-  DCHECK_EQ(read_state_, IDLE);
-  DCHECK_EQ(read_start_, 0U);
-  DCHECK_EQ(read_end_, 0U);
-
-  // Once we call Read(), we cannot call StartTls() until the read
-  // finishes.  This is okay, as StartTls() is called only from a read
-  // handler (i.e., after a read finishes and before another read is
-  // done).
-  read_state_ = WAITING;
-  read_watcher_->ArmOrNotify();
-}
-
-// read_state_ == WAITING -> read_state_ == IDLE
-
-void NetworkServiceAsyncSocket::ProcessReadReady(
-    MojoResult result,
-    const mojo::HandleSignalsState& state) {
-  DCHECK(IsOpen());
-  DCHECK_EQ(read_state_, WAITING);
-  DCHECK_EQ(read_start_, 0U);
-  DCHECK_EQ(read_end_, 0U);
-  read_state_ = IDLE;
-
-  uint32_t num_bytes = read_buf_.size();
-  if (result == MOJO_RESULT_OK && !state.peer_closed()) {
-    result = read_pipe_->ReadData(read_buf_.data(), &num_bytes,
-                                  MOJO_READ_DATA_FLAG_NONE);
-    if (result == MOJO_RESULT_SHOULD_WAIT) {
-      WatchForReadReady();
-      return;
-    }
-  }
-
-  if (result != MOJO_RESULT_OK || !num_bytes || state.peer_closed()) {
-    // The pipe is closed on any error, or EOF.
-    if (saw_read_error_on_socket_observer_pipe_ != net::ERR_IO_PENDING) {
-      // Already saw socket observer's notification, report result.
-      ReportReadError(saw_read_error_on_socket_observer_pipe_);
-    } else {
-      // This got delivered before the error code from socket observer, let it
-      // know it's responsible for reporting the error/EOF.
-      saw_error_on_read_pipe_ = true;
-    }
-    return;
-  }
-
-  read_end_ = num_bytes;
-  SignalRead();
-}
-
-void NetworkServiceAsyncSocket::ReportReadError(int net_error) {
-  if (net_error == 0) {
-    // Other side closed the connection.
-    error_ = ERROR_NONE;
-    net_error_ = net::OK;
-  } else {
-    DoNetErrorFromStatus(net_error);
-  }
-  DoClose();
-}
-
-// (maybe) read_state_ == IDLE -> read_state_ == WAITING (via
-// WatchForReadReady())
-
-bool NetworkServiceAsyncSocket::Read(char* data, size_t len, size_t* len_read) {
-  if (!IsOpen() && (state_ != STATE_TLS_CONNECTING)) {
-    // Read() may be called on a closed socket if a previous read
-    // causes a socket close (e.g., client sends wrong password and
-    // server terminates connection).
-    //
-    // TODO(akalin): Fix handling of this on the libjingle side.
-    if (state_ != STATE_CLOSED) {
-      LOG(DFATAL) << "Read() called on non-open non-tls-connecting socket";
-    }
-    DoNonNetError(ERROR_WRONGSTATE);
-    return false;
-  }
-  DCHECK_LE(read_start_, read_end_);
-  if ((state_ == STATE_TLS_CONNECTING) || read_end_ == 0U) {
-    if (state_ == STATE_TLS_CONNECTING) {
-      DCHECK_EQ(read_state_, IDLE);
-      DCHECK_EQ(read_end_, 0U);
-    } else {
-      DCHECK_NE(read_state_, IDLE);
-    }
-    *len_read = 0;
-    return true;
-  }
-  DCHECK_EQ(read_state_, IDLE);
-  *len_read = std::min(len, read_end_ - read_start_);
-  DCHECK_GT(*len_read, 0U);
-  std::memcpy(data, read_buf_.data() + read_start_, *len_read);
-  read_start_ += *len_read;
-  if (read_start_ == read_end_) {
-    read_start_ = 0U;
-    read_end_ = 0U;
-    WatchForReadReady();
-  }
-  return true;
-}
-
-// (maybe) write_state_ == IDLE -> write_state_ == WAITING (via
-// WatchForWriteReady())
-
-bool NetworkServiceAsyncSocket::Write(const char* data, size_t len) {
-  if (!IsOpen() && (state_ != STATE_TLS_CONNECTING)) {
-    LOG(DFATAL) << "Write() called on non-open non-tls-connecting socket";
-    DoNonNetError(ERROR_WRONGSTATE);
-    return false;
-  }
-  // TODO(akalin): Avoid this check by modifying the interface to have
-  // a "ready for writing" signal.
-  if ((static_cast<size_t>(write_buf_.size()) - write_end_) < len) {
-    LOG(DFATAL) << "queueing " << len << " bytes would exceed the "
-                << "max write buffer size = " << write_buf_.size() << " by "
-                << (len - write_buf_.size()) << " bytes";
-    DoNetError(net::ERR_INSUFFICIENT_RESOURCES);
-    return false;
-  }
-  std::memcpy(write_buf_.data() + write_end_, data, len);
-  write_end_ += len;
-  // If we're TLS-connecting, the write buffer will get flushed once
-  // the TLS-connect finishes.  Otherwise, start writing if we're not
-  // already writing and we have something to write.
-  if ((state_ != STATE_TLS_CONNECTING) && (write_state_ == IDLE) &&
-      (write_end_ > 0U)) {
-    WatchForWriteReady();
-  }
-  return true;
-}
-
-// write_state_ == IDLE -> write_state_ == WAITING
-
-void NetworkServiceAsyncSocket::WatchForWriteReady() {
-  // Note that this never transitions to ProcessWriteReady immediately; which
-  // avoids potentially error-prone synchronous notifications from within
-  // methods like Write().
-  DCHECK(IsOpen());
-  DCHECK_EQ(write_state_, IDLE);
-  DCHECK_GT(write_end_, 0U);
-
-  // Once we call Write(), we cannot call StartTls() until the write
-  // finishes.  This is okay, as StartTls() is called only after we
-  // have received a reply to a message we sent to the server and
-  // before we send the next message.
-  write_state_ = WAITING;
-  write_watcher_->ArmOrNotify();
-}
-
-// write_state_ == WAITING -> write_state_ == IDLE or WAITING (the
-// latter via WatchForWriteReady())
-
-void NetworkServiceAsyncSocket::ProcessWriteReady(
-    MojoResult result,
-    const mojo::HandleSignalsState& state) {
-  DCHECK(IsOpen());
-  DCHECK_EQ(write_state_, WAITING);
-  DCHECK_GT(write_end_, 0U);
-  write_state_ = IDLE;
-
-  // Write errors are handled in ProcessWriteClosed.
-  uint32_t written = write_end_;
-  if (result == MOJO_RESULT_OK) {
-    result = write_pipe_->WriteData(write_buf_.data(), &written,
-                                    MOJO_WRITE_DATA_FLAG_NONE);
-  }
-
-  if (result == MOJO_RESULT_SHOULD_WAIT) {
-    WatchForWriteReady();
-    return;
-  }
-
-  if (result != MOJO_RESULT_OK) {
-    DCHECK(socket_observer_receiver_.is_bound());
-    // Unlike with reads, as the pipe close notifier for writes is independent
-    // and always armed, it can take care of all the errors.
-    return;
-  }
-
-  if (written > write_end_) {
-    LOG(DFATAL) << "bytes written = " << written
-                << " exceeds bytes requested = " << write_end_;
-    DoNetError(net::ERR_UNEXPECTED);
-    DoClose();
-    return;
-  }
-  // TODO(akalin): Figure out a better way to do this; perhaps a queue
-  // of DrainableIOBuffers.  This'll also allow us to not have an
-  // artificial buffer size limit.
-  std::memmove(write_buf_.data(), write_buf_.data() + written,
-               write_end_ - written);
-  write_end_ -= written;
-  if (write_end_ > 0U) {
-    WatchForWriteReady();
-  }
-}
-
-void NetworkServiceAsyncSocket::ProcessWriteClosed(
-    MojoResult result,
-    const mojo::HandleSignalsState& state) {
-  DCHECK(state.peer_closed());
-
-  // The pipe is closed on any error, or EOF.
-  if (saw_write_error_on_socket_observer_pipe_ != net::ERR_IO_PENDING) {
-    // Already saw socket observer's notification, report result.
-    DoNetErrorFromStatus(saw_write_error_on_socket_observer_pipe_);
-    DoClose();
-  } else {
-    // This got delivered before the error code from socket observer, let it
-    // know it's responsible for reporting the error/EOF.
-    saw_error_on_write_pipe_ = true;
-  }
-}
-
-// * -> STATE_CLOSED
-
-bool NetworkServiceAsyncSocket::Close() {
-  DoClose();
-  return true;
-}
-
-// (not STATE_CLOSED) -> STATE_CLOSED
-
-void NetworkServiceAsyncSocket::DoClose() {
-  // As this closes all the mojo pipes and destroys all the watchers it also
-  // cancels all pending async operations.
-  read_state_ = IDLE;
-  read_start_ = 0U;
-  read_end_ = 0U;
-  read_pipe_.reset();
-  read_watcher_.reset();
-  saw_error_on_read_pipe_ = false;
-  saw_error_on_write_pipe_ = false;
-  saw_read_error_on_socket_observer_pipe_ = net::ERR_IO_PENDING;
-  saw_write_error_on_socket_observer_pipe_ = net::ERR_IO_PENDING;
-  write_state_ = IDLE;
-  write_end_ = 0U;
-  write_pipe_.reset();
-  write_watcher_.reset();
-  write_close_watcher_.reset();
-
-  socket_.reset();
-  tls_socket_.reset();
-  socket_observer_receiver_.reset();
-  socket_factory_.reset();
-
-  if (state_ != STATE_CLOSED) {
-    state_ = STATE_CLOSED;
-    SignalClosed();
-  }
-  // Reset error variables after SignalClosed() so slots connected
-  // to it can read it.
-  error_ = ERROR_NONE;
-  net_error_ = net::OK;
-}
-
-// STATE_OPEN -> STATE_TLS_CONNECTING
-
-bool NetworkServiceAsyncSocket::StartTls(const std::string& domain_name) {
-  DCHECK_EQ(IDLE, write_state_);
-  if (state_ != STATE_OPEN) {
-    LOG(DFATAL) << "StartTls() called in wrong state";
-    DoNonNetError(ERROR_WRONGSTATE);
-    return false;
-  }
-
-  state_ = STATE_TLS_CONNECTING;
-  read_state_ = IDLE;
-  read_start_ = 0U;
-  read_end_ = 0U;
-  DCHECK_EQ(write_end_, 0U);
-
-  read_watcher_ = nullptr;
-  read_pipe_.reset();
-  write_watcher_ = nullptr;
-  write_close_watcher_ = nullptr;
-  write_pipe_.reset();
-  socket_observer_receiver_.reset();
-  mojo::PendingRemote<network::mojom::SocketObserver> socket_observer;
-  auto socket_observer_receiver =
-      socket_observer.InitWithNewPipeAndPassReceiver();
-
-  socket_->UpgradeToTLS(
-      net::HostPortPair(domain_name, 443),
-      net::MutableNetworkTrafficAnnotationTag(traffic_annotation_),
-      tls_socket_.BindNewPipeAndPassReceiver(), std::move(socket_observer),
-      base::BindOnce(&NetworkServiceAsyncSocket::ProcessSSLConnectDone,
-                     base::Unretained(this),
-                     std::move(socket_observer_receiver)));
-  return true;
-}
-
-// STATE_TLS_CONNECTING -> STATE_TLS_OPEN
-// read_state_ == IDLE -> read_state_ == WAITING (via WatchForReadReady())
-// (maybe) write_state_ == IDLE -> write_state_ == WAITING (via
-// WatchForWriteReady())
-
-void NetworkServiceAsyncSocket::ProcessSSLConnectDone(
-    mojo::PendingReceiver<network::mojom::SocketObserver>
-        socket_observer_receiver,
-    int status,
-    mojo::ScopedDataPipeConsumerHandle receive_stream,
-    mojo::ScopedDataPipeProducerHandle send_stream) {
-  DCHECK_NE(status, net::ERR_IO_PENDING);
-  DCHECK_EQ(state_, STATE_TLS_CONNECTING);
-  DCHECK_EQ(read_state_, IDLE);
-  DCHECK_EQ(read_start_, 0U);
-  DCHECK_EQ(read_end_, 0U);
-  DCHECK_EQ(write_state_, IDLE);
-  if (status != net::OK) {
-    DoNetErrorFromStatus(status);
-    DoClose();
-    return;
-  }
-  state_ = STATE_TLS_OPEN;
-  ConnectPipes(std::move(receive_stream), std::move(send_stream));
-  BindSocketObserver(std::move(socket_observer_receiver));
-
-  WatchForReadReady();
-  if (write_end_ > 0U) {
-    WatchForWriteReady();
-  }
-  SignalSSLConnected();
-}
-
-void NetworkServiceAsyncSocket::ConnectPipes(
-    mojo::ScopedDataPipeConsumerHandle receive_stream,
-    mojo::ScopedDataPipeProducerHandle send_stream) {
-  read_pipe_ = std::move(receive_stream);
-  read_watcher_ = std::make_unique<mojo::SimpleWatcher>(
-      FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL);
-  read_watcher_->Watch(
-      read_pipe_.get(),
-      MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
-      MOJO_TRIGGER_CONDITION_SIGNALS_SATISFIED,
-      base::BindRepeating(&NetworkServiceAsyncSocket::ProcessReadReady,
-                          base::Unretained(this)));
-
-  write_pipe_ = std::move(send_stream);
-  write_watcher_ = std::make_unique<mojo::SimpleWatcher>(
-      FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL);
-  write_watcher_->Watch(
-      write_pipe_.get(), MOJO_HANDLE_SIGNAL_WRITABLE,
-      MOJO_TRIGGER_CONDITION_SIGNALS_SATISFIED,
-      base::BindRepeating(&NetworkServiceAsyncSocket::ProcessWriteReady,
-                          base::Unretained(this)));
-
-  // Write pipe close gets a separate  watcher to look for signs of trouble
-  // even when no write is pending. (Read doesn't need one since reads are
-  // always watched for).
-  write_close_watcher_ = std::make_unique<mojo::SimpleWatcher>(
-      FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL);
-  write_close_watcher_->Watch(
-      write_pipe_.get(), MOJO_HANDLE_SIGNAL_PEER_CLOSED,
-      MOJO_TRIGGER_CONDITION_SIGNALS_SATISFIED,
-      base::BindRepeating(&NetworkServiceAsyncSocket::ProcessWriteClosed,
-                          base::Unretained(this)));
-  write_close_watcher_->ArmOrNotify();
-}
-
-void NetworkServiceAsyncSocket::BindSocketObserver(
-    mojo::PendingReceiver<network::mojom::SocketObserver>
-        socket_observer_receiver) {
-  socket_observer_receiver_.Bind(std::move(socket_observer_receiver));
-  socket_observer_receiver_.set_disconnect_handler(
-      base::BindOnce(&NetworkServiceAsyncSocket::ProcessSocketObserverError,
-                     base::Unretained(this)));
-}
-
-}  // namespace jingle_glue
diff --git a/jingle/glue/network_service_async_socket.h b/jingle/glue/network_service_async_socket.h
deleted file mode 100644
index 63f1f8f..0000000
--- a/jingle/glue/network_service_async_socket.h
+++ /dev/null
@@ -1,272 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// An implementation of jingle_xmpp::AsyncSocket that uses Chrome Network Service
-// sockets.
-
-#ifndef JINGLE_GLUE_NETWORK_SERVICE_ASYNC_SOCKET_H_
-#define JINGLE_GLUE_NETWORK_SERVICE_ASYNC_SOCKET_H_
-
-#include <stddef.h>
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
-#include "jingle/glue/network_service_config.h"
-#include "mojo/public/cpp/bindings/pending_receiver.h"
-#include "mojo/public/cpp/bindings/receiver.h"
-#include "mojo/public/cpp/bindings/remote.h"
-#include "mojo/public/cpp/system/data_pipe.h"
-#include "mojo/public/cpp/system/simple_watcher.h"
-#include "net/base/host_port_pair.h"
-#include "net/traffic_annotation/network_traffic_annotation.h"
-#include "services/network/public/mojom/proxy_resolving_socket.mojom.h"
-#include "services/network/public/mojom/tcp_socket.mojom.h"
-#include "services/network/public/mojom/tls_socket.mojom.h"
-#include "third_party/libjingle_xmpp/xmpp/asyncsocket.h"
-
-namespace jingle_glue {
-
-class NetworkServiceAsyncSocket : public jingle_xmpp::AsyncSocket,
-                                  public network::mojom::SocketObserver {
- public:
-  NetworkServiceAsyncSocket(
-      GetProxyResolvingSocketFactoryCallback get_socket_factory_callback,
-      bool use_fake_tls_handshake,
-      size_t read_buf_size,
-      size_t write_buf_size,
-      const net::NetworkTrafficAnnotationTag& traffic_annotation);
-
-  NetworkServiceAsyncSocket(const NetworkServiceAsyncSocket&) = delete;
-  NetworkServiceAsyncSocket& operator=(const NetworkServiceAsyncSocket&) =
-      delete;
-
-  // Does not raise any signals.
-  ~NetworkServiceAsyncSocket() override;
-
-  // jingle_xmpp::AsyncSocket implementation.
-
-  // The current state (see jingle_xmpp::AsyncSocket::State; all but
-  // STATE_CLOSING is used).
-  State state() override;
-
-  // The last generated error.  Errors are generated when the main
-  // functions below return false or when SignalClosed is raised due
-  // to an asynchronous error.
-  Error error() override;
-
-  // GetError() (which is of type net::Error) != net::OK only when
-  // error() == ERROR_WINSOCK.
-  int GetError() override;
-
-  // Tries to connect to the given address.
-  //
-  // If state() is not STATE_CLOSED, sets error to ERROR_WRONGSTATE
-  // and returns false.
-  //
-  // If |address| has an empty hostname or a zero port, sets error to
-  // ERROR_DNS and returns false.  (We don't use the IP address even
-  // if it's present, as DNS resolution is done by the network service).
-  // But it's perfectly fine if the hostname is a stringified IP address.)
-  //
-  // Otherwise, starts the connection process and returns true.
-  // SignalConnected will be raised when the connection is successful;
-  // otherwise, SignalClosed will be raised with a net error set.
-  bool Connect(const net::HostPortPair& address) override;
-
-  // Tries to read at most |len| bytes into |data|.
-  //
-  // If state() is not STATE_TLS_CONNECTING, STATE_OPEN, or
-  // STATE_TLS_OPEN, sets error to ERROR_WRONGSTATE and returns false.
-  //
-  // Otherwise, fills in |len_read| with the number of bytes read and
-  // returns true.  If this is called when state() is
-  // STATE_TLS_CONNECTING, reads 0 bytes.  (We have to handle this
-  // case because StartTls() is called during a slot connected to
-  // SignalRead after parsing the final non-TLS reply from the server
-  // [see XmppClient::Private::OnSocketRead()].)
-  bool Read(char* data, size_t len, size_t* len_read) override;
-
-  // Queues up |len| bytes of |data| for writing.
-  //
-  // If state() is not STATE_TLS_CONNECTING, STATE_OPEN, or
-  // STATE_TLS_OPEN, sets error to ERROR_WRONGSTATE and returns false.
-  //
-  // If the given data is too big for the internal write buffer, sets
-  // error to ERROR_WINSOCK/net::ERR_INSUFFICIENT_RESOURCES and
-  // returns false.
-  //
-  // Otherwise, queues up the data and returns true.  If this is
-  // called when state() == STATE_TLS_CONNECTING, the data is will be
-  // sent only after the TLS connection succeeds.  (See StartTls()
-  // below for why this happens.)
-  //
-  // Note that there's no guarantee that the data will actually be
-  // sent; however, it is guaranteed that the any data sent will be
-  // sent in FIFO order.
-  bool Write(const char* data, size_t len) override;
-
-  // If the socket is not already closed, closes the socket and raises
-  // SignalClosed.  Always returns true.
-  bool Close() override;
-
-  // Tries to change to a TLS connection with the given domain name.
-  //
-  // If state() is not STATE_OPEN or there are pending reads or
-  // writes, sets error to ERROR_WRONGSTATE and returns false.  (In
-  // practice, this means that StartTls() can only be called from a
-  // slot connected to SignalRead.)
-  //
-  // Otherwise, starts the TLS connection process and returns true.
-  // SignalSSLConnected will be raised when the connection is
-  // successful; otherwise, SignalClosed will be raised with a net
-  // error set.
-  bool StartTls(const std::string& domain_name) override;
-
-  // Signal behavior:
-  //
-  // SignalConnected: raised whenever the connect initiated by a call
-  // to Connect() is complete.
-  //
-  // SignalSSLConnected: raised whenever the connect initiated by a
-  // call to StartTls() is complete.  Not actually used by
-  // XmppClient. (It just assumes that if SignalRead is raised after a
-  // call to StartTls(), the connection has been successfully
-  // upgraded.)
-  //
-  // SignalClosed: raised whenever the socket is closed, either due to
-  // an asynchronous error, the other side closing the connection, or
-  // when Close() is called.
-  //
-  // SignalRead: raised whenever the next call to Read() will succeed
-  // with a non-zero |len_read| (assuming nothing else happens in the
-  // meantime).
-  //
-  // SignalError: not used.
-
- private:
-  enum AsyncIOState {
-    // An I/O op is not in progress or has been handed over to the network
-    // service.
-    IDLE,
-    // Waiting for network service to be ready to handle an operation.
-    WAITING,
-  };
-
-  bool IsOpen() const;
-
-  // Error functions.
-  void DoNonNetError(Error error);
-  void DoNetError(net::Error net_error);
-  void DoNetErrorFromStatus(int status);
-  void ProcessSocketObserverError();
-
-  // SocketObserver implementation
-  void OnReadError(int32_t net_error) override;
-  void OnWriteError(int32_t net_error) override;
-
-  // Connection functions.
-  void ProcessConnectDone(mojo::PendingReceiver<network::mojom::SocketObserver>
-                              socket_observer_receiver,
-                          int status,
-                          const absl::optional<net::IPEndPoint>& local_addr,
-                          const absl::optional<net::IPEndPoint>& peer_addr,
-                          mojo::ScopedDataPipeConsumerHandle receive_stream,
-                          mojo::ScopedDataPipeProducerHandle send_stream);
-
-  // Read loop functions.
-  void WatchForReadReady();
-  void ProcessReadReady(MojoResult result,
-                        const mojo::HandleSignalsState& state);
-  void ReportReadError(int net_error);
-
-  // Write loop functions.
-  void WatchForWriteReady();
-  void ProcessWriteReady(MojoResult result,
-                         const mojo::HandleSignalsState& state);
-  void ProcessWriteClosed(MojoResult result,
-                          const mojo::HandleSignalsState& state);
-
-  // SSL/TLS connection functions.
-  void ProcessSSLConnectDone(
-      mojo::PendingReceiver<network::mojom::SocketObserver>
-          socket_observer_receiver,
-      int status,
-      mojo::ScopedDataPipeConsumerHandle receive_stream,
-      mojo::ScopedDataPipeProducerHandle send_stream);
-
-  // Close functions.
-  void DoClose();
-
-  void ConnectPipes(mojo::ScopedDataPipeConsumerHandle receive_stream,
-                    mojo::ScopedDataPipeProducerHandle send_stream);
-  void BindSocketObserver(mojo::PendingReceiver<network::mojom::SocketObserver>
-                              socket_observer_receiver);
-
-  // |socket_factory_| is recreated every time via |get_socket_factory_callback|
-  // to handle network service restarts after crashes.
-  GetProxyResolvingSocketFactoryCallback get_socket_factory_callback_;
-  mojo::Remote<network::mojom::ProxyResolvingSocketFactory> socket_factory_;
-  // The handle to the proxy resolving socket for the current connection, if one
-  // exists.
-  mojo::Remote<network::mojom::ProxyResolvingSocket> socket_;
-  // TLS socket, if StartTls has been called.
-  mojo::Remote<network::mojom::TLSClientSocket> tls_socket_;
-
-  // Used to route error notifications here.
-  mojo::Receiver<network::mojom::SocketObserver> socket_observer_receiver_{
-      this};
-
-  bool use_fake_tls_handshake_;
-
-  // jingle_xmpp::AsyncSocket state.
-  jingle_xmpp::AsyncSocket::State state_;
-  jingle_xmpp::AsyncSocket::Error error_;
-  net::Error net_error_;
-
-  // State for the read loop.  |read_start_| <= |read_end_| <=
-  // |read_buf_->size()|.  There's a read in flight (i.e.,
-  // |read_state_| != IDLE) iff |read_end_| == 0.
-  AsyncIOState read_state_;
-  std::vector<char> read_buf_;
-  size_t read_start_, read_end_;
-  mojo::ScopedDataPipeConsumerHandle read_pipe_;
-  std::unique_ptr<mojo::SimpleWatcher> read_watcher_;
-
-  // Handling read errors is a bit tricky since the status is reported via
-  // |socket_observer_receiver_|, which is unordered compared to |read_pipe_|,
-  // so it's possible to see an end of file (or an error) there while there is
-  // still useful data pending.  As a result, the code waits to see both happen
-  // before reporting error statuses (including EOF). Likewise for write pipes.
-  //
-  bool saw_error_on_read_pipe_;
-  bool saw_error_on_write_pipe_;
-
-  // This is != net::ERR_IO_PENDING (including possibly net::OK for end-of-file)
-  // if a read error was reported via socket observer interface.
-  int saw_read_error_on_socket_observer_pipe_;
-  int saw_write_error_on_socket_observer_pipe_;
-
-  // State for the write loop.  |write_end_| <= |write_buf_->size()|.
-  // There's a write in flight (i.e., |write_state_| != IDLE) iff
-  // |write_end_| > 0.
-  AsyncIOState write_state_;
-  std::vector<char> write_buf_;
-  size_t write_end_;
-  mojo::ScopedDataPipeProducerHandle write_pipe_;
-  std::unique_ptr<mojo::SimpleWatcher> write_watcher_;
-  std::unique_ptr<mojo::SimpleWatcher> write_close_watcher_;
-
-  // Network traffic annotation for downstream socket write.
-  // NetworkServiceAsyncSocket is not reused, hence annotation can be added in
-  // constructor and used in all subsequent writes.
-  const net::NetworkTrafficAnnotationTag traffic_annotation_;
-};
-
-}  // namespace jingle_glue
-
-#endif  // JINGLE_GLUE_NETWORK_SERVICE_ASYNC_SOCKET_H_
diff --git a/jingle/glue/network_service_async_socket_unittest.cc b/jingle/glue/network_service_async_socket_unittest.cc
deleted file mode 100644
index 19bf076..0000000
--- a/jingle/glue/network_service_async_socket_unittest.cc
+++ /dev/null
@@ -1,1480 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "jingle/glue/network_service_async_socket.h"
-
-#include <stddef.h>
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/check_op.h"
-#include "base/containers/circular_deque.h"
-#include "base/cxx17_backports.h"
-#include "base/memory/ptr_util.h"
-#include "base/memory/raw_ptr.h"
-#include "base/message_loop/message_pump_default.h"
-#include "base/notreached.h"
-#include "base/run_loop.h"
-#include "base/strings/strcat.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/test/gtest_util.h"
-#include "base/test/task_environment.h"
-#include "mojo/public/cpp/bindings/pending_receiver.h"
-#include "mojo/public/cpp/bindings/pending_remote.h"
-#include "mojo/public/cpp/bindings/remote.h"
-#include "mojo/public/cpp/bindings/unique_receiver_set.h"
-#include "mojo/public/cpp/system/data_pipe_utils.h"
-#include "net/base/address_list.h"
-#include "net/base/host_port_pair.h"
-#include "net/base/ip_address.h"
-#include "net/base/net_errors.h"
-#include "net/base/network_isolation_key.h"
-#include "net/cert/mock_cert_verifier.h"
-#include "net/http/transport_security_state.h"
-#include "net/log/net_log_source.h"
-#include "net/socket/socket_test_util.h"
-#include "net/socket/ssl_client_socket.h"
-#include "net/ssl/ssl_config_service.h"
-#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
-#include "net/url_request/url_request_test_util.h"
-#include "services/network/proxy_resolving_socket_factory_mojo.h"
-#include "services/network/public/mojom/proxy_resolving_socket.mojom.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/webrtc/rtc_base/third_party/sigslot/sigslot.h"
-#include "url/origin.h"
-
-namespace jingle_glue {
-
-namespace {
-
-// Data provider that handles reads/writes for NetworkServiceAsyncSocket.
-class AsyncSocketDataProvider : public net::SocketDataProvider {
- public:
-  AsyncSocketDataProvider() : has_pending_read_(false) {}
-
-  AsyncSocketDataProvider(const AsyncSocketDataProvider&) = delete;
-  AsyncSocketDataProvider& operator=(const AsyncSocketDataProvider&) = delete;
-
-  ~AsyncSocketDataProvider() override {
-    EXPECT_TRUE(writes_.empty());
-    EXPECT_TRUE(reads_.empty());
-  }
-
-  // If there's no read, sets the "has pending read" flag.  Otherwise,
-  // pops the next read.
-  net::MockRead OnRead() override {
-    if (reads_.empty()) {
-      DCHECK(!has_pending_read_);
-      has_pending_read_ = true;
-      const net::MockRead pending_read(net::SYNCHRONOUS, net::ERR_IO_PENDING);
-      return pending_read;
-    }
-    net::MockRead mock_read = reads_.front();
-    reads_.pop_front();
-    return mock_read;
-  }
-
-  void CancelPendingRead() override {
-    DCHECK(has_pending_read_);
-    has_pending_read_ = false;
-  }
-
-  // Simply pops the next write and, if applicable, compares it to
-  // |data|.
-  net::MockWriteResult OnWrite(const std::string& data) override {
-    DCHECK(!writes_.empty());
-    net::MockWrite mock_write = writes_.front();
-    writes_.pop_front();
-    if (mock_write.result != net::OK) {
-      return net::MockWriteResult(mock_write.mode, mock_write.result);
-    }
-    std::string expected_data(mock_write.data, mock_write.data_len);
-    EXPECT_EQ(expected_data, data);
-    if (expected_data != data) {
-      return net::MockWriteResult(net::SYNCHRONOUS, net::ERR_UNEXPECTED);
-    }
-    return net::MockWriteResult(mock_write.mode, data.size());
-  }
-
-  // We ignore resets so we can pre-load the socket data provider with
-  // read/write events.
-  void Reset() override {}
-
-  // If there is a pending read, completes it with the given read.
-  // Otherwise, queues up the given read.
-  void AddRead(const net::MockRead& mock_read) {
-    DCHECK_NE(mock_read.result, net::ERR_IO_PENDING);
-    if (has_pending_read_) {
-      has_pending_read_ = false;
-      socket()->OnReadComplete(mock_read);
-      return;
-    }
-    reads_.push_back(mock_read);
-  }
-
-  // Simply queues up the given write.
-  void AddWrite(const net::MockWrite& mock_write) {
-    writes_.push_back(mock_write);
-  }
-
-  bool AllReadDataConsumed() const override { return reads_.empty(); }
-
-  bool AllWriteDataConsumed() const override { return writes_.empty(); }
-
- private:
-  base::circular_deque<net::MockRead> reads_;
-  bool has_pending_read_;
-
-  base::circular_deque<net::MockWrite> writes_;
-};
-
-class MockProxyResolvingSocket : public network::mojom::ProxyResolvingSocket {
- public:
-  enum Event {
-    // These names are from the perspective of the client, not the socket.
-    kRead,
-    kWrite,
-    kCloseReadPipe,
-    kCloseWritePipe,
-    kReadError,
-    kReadErrorInvalid,
-    kWriteError,
-    kWriteErrorInvalid,
-    kReadEofError,
-    kCloseObserverPipe,
-  };
-
-  MockProxyResolvingSocket() {}
-
-  MockProxyResolvingSocket(const MockProxyResolvingSocket&) = delete;
-  MockProxyResolvingSocket& operator=(const MockProxyResolvingSocket&) = delete;
-
-  ~MockProxyResolvingSocket() override {}
-
-  void Connect(mojo::PendingRemote<network::mojom::SocketObserver> observer,
-               network::mojom::ProxyResolvingSocketFactory::
-                   CreateProxyResolvingSocketCallback callback) {
-    mojo::ScopedDataPipeProducerHandle send_producer_handle;
-    ASSERT_EQ(
-        mojo::CreateDataPipe(nullptr, send_producer_handle, send_pipe_handle_),
-        MOJO_RESULT_OK);
-
-    mojo::ScopedDataPipeConsumerHandle receive_consumer_handle;
-    ASSERT_EQ(mojo::CreateDataPipe(nullptr, receive_pipe_handle_,
-                                   receive_consumer_handle),
-              MOJO_RESULT_OK);
-
-    observer_.Bind(std::move(observer));
-
-    std::move(callback).Run(net::OK, absl::nullopt, absl::nullopt,
-                            std::move(receive_consumer_handle),
-                            std::move(send_producer_handle));
-  }
-
-  void RunEvents(std::vector<Event>&& events);
-
-  // mojom::ProxyResolvingSocket implementation.
-  void UpgradeToTLS(
-      const net::HostPortPair& host_port_pair,
-      const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
-      mojo::PendingReceiver<network::mojom::TLSClientSocket> receiver,
-      mojo::PendingRemote<network::mojom::SocketObserver> observer,
-      network::mojom::ProxyResolvingSocket::UpgradeToTLSCallback callback)
-      override {
-    NOTREACHED();
-  }
-
- private:
-  mojo::Remote<network::mojom::SocketObserver> observer_;
-  mojo::ScopedDataPipeProducerHandle receive_pipe_handle_;
-  mojo::ScopedDataPipeConsumerHandle send_pipe_handle_;
-};
-
-class MockProxyResolvingSocketFactory
-    : public network::mojom::ProxyResolvingSocketFactory {
- public:
-  explicit MockProxyResolvingSocketFactory() : socket_raw_(nullptr) {}
-
-  MockProxyResolvingSocketFactory(const MockProxyResolvingSocketFactory&) =
-      delete;
-  MockProxyResolvingSocketFactory& operator=(
-      const MockProxyResolvingSocketFactory&) = delete;
-
-  ~MockProxyResolvingSocketFactory() override {}
-
-  // mojom::ProxyResolvingSocketFactory implementation.
-  void CreateProxyResolvingSocket(
-      const GURL& url,
-      const net::NetworkIsolationKey& network_isolation_key,
-      network::mojom::ProxyResolvingSocketOptionsPtr options,
-      const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
-      mojo::PendingReceiver<network::mojom::ProxyResolvingSocket> receiver,
-      mojo::PendingRemote<network::mojom::SocketObserver> observer,
-      CreateProxyResolvingSocketCallback callback) override {
-    url::Origin origin = url::Origin::Create(url);
-    EXPECT_EQ(net::NetworkIsolationKey(origin /* top_frame_origin */,
-                                       origin /* frame_origin */),
-              network_isolation_key);
-    auto socket = std::make_unique<MockProxyResolvingSocket>();
-    socket_raw_ = socket.get();
-    proxy_resolving_socket_receivers_.Add(std::move(socket),
-                                          std::move(receiver));
-    socket_raw_->Connect(std::move(observer), std::move(callback));
-  }
-
-  MockProxyResolvingSocket* socket() { return socket_raw_; }
-
- private:
-  mojo::UniqueReceiverSet<network::mojom::ProxyResolvingSocket>
-      proxy_resolving_socket_receivers_;
-
-  // Owned by |proxy_resolving_socket_receivers_|.
-  raw_ptr<MockProxyResolvingSocket> socket_raw_;
-};
-
-void MockProxyResolvingSocket::RunEvents(std::vector<Event>&& events) {
-  for (Event ev : events) {
-    switch (ev) {
-      case kRead:
-        mojo::BlockingCopyFromString("data", receive_pipe_handle_);
-        break;
-      case kWrite: {
-        std::string written;
-        while (true) {
-          char read_buffer[1024];
-          uint32_t read_size = sizeof(read_buffer);
-          MojoResult result = send_pipe_handle_->ReadData(
-              read_buffer, &read_size, MOJO_READ_DATA_FLAG_NONE);
-          if (result != MOJO_RESULT_OK)
-            break;
-          written.append(read_buffer, read_size);
-        }
-
-        EXPECT_EQ("atad", written);
-        break;
-      }
-      case kCloseReadPipe:
-        receive_pipe_handle_.reset();
-        break;
-      case kCloseWritePipe:
-        send_pipe_handle_.reset();
-        break;
-      case kReadError:
-        observer_->OnReadError(net::ERR_OUT_OF_MEMORY);
-        observer_.FlushForTesting();
-        break;
-      case kReadErrorInvalid:
-        observer_->OnReadError(42);
-        observer_.FlushForTesting();
-        break;
-      case kWriteError:
-        observer_->OnWriteError(net::ERR_ACCESS_DENIED);
-        observer_.FlushForTesting();
-        break;
-      case kWriteErrorInvalid:
-        observer_->OnWriteError(net::ERR_IO_PENDING);
-        observer_.FlushForTesting();
-        break;
-      case kReadEofError:
-        observer_->OnReadError(0);
-        observer_.FlushForTesting();
-        break;
-      case kCloseObserverPipe:
-        observer_.reset();
-        break;
-    }
-    // Make sure the event is actually delivered.
-    base::RunLoop().RunUntilIdle();
-  }
-}
-
-class NetworkServiceAsyncSocketTest : public testing::Test,
-                                      public sigslot::has_slots<> {
- protected:
-  explicit NetworkServiceAsyncSocketTest(bool use_mojo_level_mock = false)
-      : ssl_socket_data_provider_(net::ASYNC, net::OK),
-        use_mojo_level_mock_(use_mojo_level_mock),
-        mock_proxy_resolving_socket_factory_(nullptr),
-        addr_({"localhost", 35}) {
-    // GTest death tests by default execute in a fork()ed but not exec()ed
-    // process. On macOS, a CoreFoundation-backed MessageLoop will exit with a
-    // __THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTIONALITY___YOU_MUST_EXEC__
-    // when called. Use the threadsafe mode to avoid this problem.
-    testing::GTEST_FLAG(death_test_style) = "threadsafe";
-  }
-
-  NetworkServiceAsyncSocketTest(const NetworkServiceAsyncSocketTest&) = delete;
-  NetworkServiceAsyncSocketTest& operator=(
-      const NetworkServiceAsyncSocketTest&) = delete;
-
-  ~NetworkServiceAsyncSocketTest() override {}
-
-  void SetUp() override {
-    mock_client_socket_factory_ =
-        std::make_unique<net::MockClientSocketFactory>();
-    mock_client_socket_factory_->set_enable_read_if_ready(true);
-    mock_client_socket_factory_->AddSocketDataProvider(
-        &async_socket_data_provider_);
-    mock_client_socket_factory_->AddSSLSocketDataProvider(
-        &ssl_socket_data_provider_);
-
-    test_url_request_context_ =
-        std::make_unique<net::TestURLRequestContext>(true /* delay init */);
-    test_url_request_context_->set_client_socket_factory(
-        mock_client_socket_factory_.get());
-    test_url_request_context_->Init();
-
-    if (use_mojo_level_mock_) {
-      auto mock_proxy_resolving_socket_factory =
-          std::make_unique<MockProxyResolvingSocketFactory>();
-      mock_proxy_resolving_socket_factory_ =
-          mock_proxy_resolving_socket_factory.get();
-      proxy_resolving_socket_factory_ =
-          std::move(mock_proxy_resolving_socket_factory);
-    } else {
-      mock_proxy_resolving_socket_factory_ = nullptr;
-      proxy_resolving_socket_factory_ =
-          std::make_unique<network::ProxyResolvingSocketFactoryMojo>(
-              test_url_request_context_.get());
-    }
-
-    ns_async_socket_ = std::make_unique<NetworkServiceAsyncSocket>(
-        base::BindRepeating(
-            &NetworkServiceAsyncSocketTest::BindToProxyResolvingSocketFactory,
-            base::Unretained(this)),
-        false, /* use_fake_tls_handshake */
-        14, 20, TRAFFIC_ANNOTATION_FOR_TESTS);
-
-    ns_async_socket_->SignalConnected.connect(
-        this, &NetworkServiceAsyncSocketTest::OnConnect);
-    ns_async_socket_->SignalSSLConnected.connect(
-        this, &NetworkServiceAsyncSocketTest::OnSSLConnect);
-    ns_async_socket_->SignalClosed.connect(
-        this, &NetworkServiceAsyncSocketTest::OnClose);
-    ns_async_socket_->SignalRead.connect(
-        this, &NetworkServiceAsyncSocketTest::OnRead);
-    ns_async_socket_->SignalError.connect(
-        this, &NetworkServiceAsyncSocketTest::OnError);
-  }
-
-  void TearDown() override {
-    // Run any tasks that we forgot to pump.
-    base::RunLoop().RunUntilIdle();
-    ExpectClosed();
-    ExpectNoSignal();
-    ns_async_socket_.reset();
-  }
-
-  void BindToProxyResolvingSocketFactory(
-      mojo::PendingReceiver<network::mojom::ProxyResolvingSocketFactory>
-          receiver) {
-    proxy_resolving_socket_factory_receiver_ = std::make_unique<
-        mojo::Receiver<network::mojom::ProxyResolvingSocketFactory>>(
-        proxy_resolving_socket_factory_.get());
-    proxy_resolving_socket_factory_receiver_->Bind(std::move(receiver));
-  }
-
-  enum Signal {
-    SIGNAL_CONNECT,
-    SIGNAL_SSL_CONNECT,
-    SIGNAL_CLOSE,
-    SIGNAL_READ,
-    SIGNAL_ERROR,
-  };
-
-  // Helper struct that records the state at the time of a signal.
-
-  struct SignalSocketState {
-    SignalSocketState()
-        : signal(SIGNAL_ERROR),
-          state(NetworkServiceAsyncSocket::STATE_CLOSED),
-          error(NetworkServiceAsyncSocket::ERROR_NONE),
-          net_error(net::OK) {}
-
-    SignalSocketState(Signal signal,
-                      NetworkServiceAsyncSocket::State state,
-                      NetworkServiceAsyncSocket::Error error,
-                      net::Error net_error)
-        : signal(signal), state(state), error(error), net_error(net_error) {}
-
-    bool IsEqual(const SignalSocketState& other) const {
-      return (signal == other.signal) && (state == other.state) &&
-             (error == other.error) && (net_error == other.net_error);
-    }
-
-    static SignalSocketState FromAsyncSocket(Signal signal,
-                                             jingle_xmpp::AsyncSocket* async_socket) {
-      return SignalSocketState(
-          signal, async_socket->state(), async_socket->error(),
-          static_cast<net::Error>(async_socket->GetError()));
-    }
-
-    static SignalSocketState NoError(Signal signal,
-                                     jingle_xmpp::AsyncSocket::State state) {
-      return SignalSocketState(signal, state, jingle_xmpp::AsyncSocket::ERROR_NONE,
-                               net::OK);
-    }
-
-    std::string ToString() const {
-      return base::StrCat({"(", base::NumberToString(signal), ",",
-                           base::NumberToString(state), ",",
-                           base::NumberToString(error), ",",
-                           base::NumberToString(net_error), ")"});
-    }
-
-    Signal signal;
-    NetworkServiceAsyncSocket::State state;
-    NetworkServiceAsyncSocket::Error error;
-    net::Error net_error;
-  };
-
-  void CaptureSocketState(Signal signal) {
-    signal_socket_states_.push_back(
-        SignalSocketState::FromAsyncSocket(signal, ns_async_socket_.get()));
-  }
-
-  void OnConnect() { CaptureSocketState(SIGNAL_CONNECT); }
-
-  void OnSSLConnect() { CaptureSocketState(SIGNAL_SSL_CONNECT); }
-
-  void OnClose() { CaptureSocketState(SIGNAL_CLOSE); }
-
-  void OnRead() { CaptureSocketState(SIGNAL_READ); }
-
-  void OnError() { ADD_FAILURE(); }
-
-  // State expect functions.
-
-  void ExpectState(NetworkServiceAsyncSocket::State state,
-                   NetworkServiceAsyncSocket::Error error,
-                   net::Error net_error) {
-    EXPECT_EQ(state, ns_async_socket_->state());
-    EXPECT_EQ(error, ns_async_socket_->error());
-    EXPECT_EQ(net_error, ns_async_socket_->GetError());
-  }
-
-  void ExpectNonErrorState(NetworkServiceAsyncSocket::State state) {
-    ExpectState(state, NetworkServiceAsyncSocket::ERROR_NONE, net::OK);
-  }
-
-  void ExpectErrorState(NetworkServiceAsyncSocket::State state,
-                        NetworkServiceAsyncSocket::Error error) {
-    ExpectState(state, error, net::OK);
-  }
-
-  void ExpectClosed() {
-    ExpectNonErrorState(NetworkServiceAsyncSocket::STATE_CLOSED);
-  }
-
-  // Signal expect functions.
-
-  void ExpectNoSignal() {
-    if (!signal_socket_states_.empty()) {
-      ADD_FAILURE() << signal_socket_states_.front().signal;
-    }
-  }
-
-  void ExpectSignalSocketState(SignalSocketState expected_signal_socket_state) {
-    if (signal_socket_states_.empty()) {
-      ADD_FAILURE() << expected_signal_socket_state.signal;
-      return;
-    }
-    EXPECT_TRUE(
-        expected_signal_socket_state.IsEqual(signal_socket_states_.front()))
-        << "Expected signal:" << expected_signal_socket_state.ToString()
-        << " actual signal: " << signal_socket_states_.front().ToString();
-    signal_socket_states_.pop_front();
-  }
-
-  void ExpectReadSignal() {
-    ExpectSignalSocketState(SignalSocketState::NoError(
-        SIGNAL_READ, NetworkServiceAsyncSocket::STATE_OPEN));
-  }
-
-  void ExpectSSLConnectSignal() {
-    ExpectSignalSocketState(SignalSocketState::NoError(
-        SIGNAL_SSL_CONNECT, NetworkServiceAsyncSocket::STATE_TLS_OPEN));
-  }
-
-  void ExpectSSLReadSignal() {
-    ExpectSignalSocketState(SignalSocketState::NoError(
-        SIGNAL_READ, NetworkServiceAsyncSocket::STATE_TLS_OPEN));
-  }
-
-  // Open/close utility functions.
-
-  void DoOpenClosed() {
-    ExpectClosed();
-    async_socket_data_provider_.set_connect_data(
-        net::MockConnect(net::SYNCHRONOUS, net::OK));
-    EXPECT_TRUE(ns_async_socket_->Connect(addr_));
-    ExpectNonErrorState(NetworkServiceAsyncSocket::STATE_CONNECTING);
-
-    base::RunLoop().RunUntilIdle();
-    // We may not necessarily be open; may have been other events
-    // queued up.
-    ExpectSignalSocketState(SignalSocketState::NoError(
-        SIGNAL_CONNECT, NetworkServiceAsyncSocket::STATE_OPEN));
-  }
-
-  void DoCloseOpened(SignalSocketState expected_signal_socket_state) {
-    // We may be in an error state, so just compare state().
-    EXPECT_EQ(NetworkServiceAsyncSocket::STATE_OPEN, ns_async_socket_->state());
-    EXPECT_TRUE(ns_async_socket_->Close());
-    ExpectSignalSocketState(expected_signal_socket_state);
-    ExpectNonErrorState(NetworkServiceAsyncSocket::STATE_CLOSED);
-  }
-
-  void DoCloseOpenedNoError() {
-    DoCloseOpened(SignalSocketState::NoError(
-        SIGNAL_CLOSE, NetworkServiceAsyncSocket::STATE_CLOSED));
-  }
-
-  void DoSSLOpenClosed() {
-    const char kDummyData[] = "dummy_data";
-    async_socket_data_provider_.AddRead(net::MockRead(kDummyData));
-    DoOpenClosed();
-    ExpectReadSignal();
-    EXPECT_EQ(kDummyData, DrainRead(1));
-
-    EXPECT_TRUE(ns_async_socket_->StartTls("fakedomain.com"));
-    base::RunLoop().RunUntilIdle();
-    ExpectSSLConnectSignal();
-    ExpectNoSignal();
-    ExpectNonErrorState(NetworkServiceAsyncSocket::STATE_TLS_OPEN);
-  }
-
-  void DoSSLCloseOpened(SignalSocketState expected_signal_socket_state) {
-    // We may be in an error state, so just compare state().
-    EXPECT_EQ(NetworkServiceAsyncSocket::STATE_TLS_OPEN,
-              ns_async_socket_->state());
-    EXPECT_TRUE(ns_async_socket_->Close());
-    ExpectSignalSocketState(expected_signal_socket_state);
-    ExpectNonErrorState(NetworkServiceAsyncSocket::STATE_CLOSED);
-  }
-
-  void DoSSLCloseOpenedNoError() {
-    DoSSLCloseOpened(SignalSocketState::NoError(
-        SIGNAL_CLOSE, NetworkServiceAsyncSocket::STATE_CLOSED));
-  }
-
-  // Read utility functions.
-
-  std::string DrainRead(size_t buf_size) {
-    std::string read;
-    std::unique_ptr<char[]> buf(new char[buf_size]);
-    size_t len_read;
-    while (true) {
-      bool success = ns_async_socket_->Read(buf.get(), buf_size, &len_read);
-      if (!success) {
-        ADD_FAILURE();
-        break;
-      }
-      if (len_read == 0U) {
-        break;
-      }
-      read.append(buf.get(), len_read);
-    }
-    return read;
-  }
-
-  // Need a message loop for both the socket and Mojo.
-  base::test::SingleThreadTaskEnvironment task_environment_;
-
-  AsyncSocketDataProvider async_socket_data_provider_;
-  net::SSLSocketDataProvider ssl_socket_data_provider_;
-
-  bool use_mojo_level_mock_;
-
-  std::unique_ptr<net::MockClientSocketFactory> mock_client_socket_factory_;
-  std::unique_ptr<net::TestURLRequestContext> test_url_request_context_;
-  // Either null or owned by proxy_resolving_socket_factory_.
-  raw_ptr<MockProxyResolvingSocketFactory> mock_proxy_resolving_socket_factory_;
-  std::unique_ptr<network::mojom::ProxyResolvingSocketFactory>
-      proxy_resolving_socket_factory_;
-  std::unique_ptr<mojo::Receiver<network::mojom::ProxyResolvingSocketFactory>>
-      proxy_resolving_socket_factory_receiver_;
-
-  std::unique_ptr<NetworkServiceAsyncSocket> ns_async_socket_;
-  base::circular_deque<SignalSocketState> signal_socket_states_;
-  const net::HostPortPair addr_;
-};
-
-TEST_F(NetworkServiceAsyncSocketTest, InitialState) {
-  ExpectClosed();
-  ExpectNoSignal();
-}
-
-TEST_F(NetworkServiceAsyncSocketTest, EmptyClose) {
-  ExpectClosed();
-  EXPECT_TRUE(ns_async_socket_->Close());
-  ExpectClosed();
-}
-
-TEST_F(NetworkServiceAsyncSocketTest, ImmediateConnectAndClose) {
-  DoOpenClosed();
-
-  ExpectNonErrorState(NetworkServiceAsyncSocket::STATE_OPEN);
-
-  DoCloseOpenedNoError();
-}
-
-// After this, no need to test immediate successful connect and
-// Close() so thoroughly.
-
-TEST_F(NetworkServiceAsyncSocketTest, DoubleClose) {
-  DoOpenClosed();
-
-  EXPECT_TRUE(ns_async_socket_->Close());
-  ExpectClosed();
-  ExpectSignalSocketState(SignalSocketState::NoError(
-      SIGNAL_CLOSE, NetworkServiceAsyncSocket::STATE_CLOSED));
-
-  EXPECT_TRUE(ns_async_socket_->Close());
-  ExpectClosed();
-}
-
-TEST_F(NetworkServiceAsyncSocketTest, ZeroPortConnect) {
-  const net::HostPortPair zero_port_addr({addr_.host(), 0});
-  EXPECT_FALSE(ns_async_socket_->Connect(zero_port_addr));
-  ExpectErrorState(NetworkServiceAsyncSocket::STATE_CLOSED,
-                   NetworkServiceAsyncSocket::ERROR_DNS);
-
-  EXPECT_TRUE(ns_async_socket_->Close());
-  ExpectClosed();
-}
-
-TEST_F(NetworkServiceAsyncSocketTest, DoubleConnect) {
-  EXPECT_DCHECK_DEATH_WITH(
-      {
-        DoOpenClosed();
-
-        EXPECT_FALSE(ns_async_socket_->Connect(addr_));
-        ExpectErrorState(NetworkServiceAsyncSocket::STATE_OPEN,
-                         NetworkServiceAsyncSocket::ERROR_WRONGSTATE);
-
-        DoCloseOpened(SignalSocketState(
-            SIGNAL_CLOSE, NetworkServiceAsyncSocket::STATE_CLOSED,
-            NetworkServiceAsyncSocket::ERROR_WRONGSTATE, net::OK));
-      },
-      "non-closed socket");
-}
-
-TEST_F(NetworkServiceAsyncSocketTest, ImmediateConnectCloseBeforeRead) {
-  DoOpenClosed();
-
-  EXPECT_TRUE(ns_async_socket_->Close());
-  ExpectClosed();
-  ExpectSignalSocketState(SignalSocketState::NoError(
-      SIGNAL_CLOSE, NetworkServiceAsyncSocket::STATE_CLOSED));
-
-  base::RunLoop().RunUntilIdle();
-}
-
-TEST_F(NetworkServiceAsyncSocketTest, HangingConnect) {
-  EXPECT_TRUE(ns_async_socket_->Connect(addr_));
-  ExpectNonErrorState(NetworkServiceAsyncSocket::STATE_CONNECTING);
-  ExpectNoSignal();
-
-  EXPECT_TRUE(ns_async_socket_->Close());
-  ExpectClosed();
-  ExpectSignalSocketState(SignalSocketState::NoError(
-      SIGNAL_CLOSE, NetworkServiceAsyncSocket::STATE_CLOSED));
-}
-
-TEST_F(NetworkServiceAsyncSocketTest, PendingConnect) {
-  async_socket_data_provider_.set_connect_data(
-      net::MockConnect(net::ASYNC, net::OK));
-  EXPECT_TRUE(ns_async_socket_->Connect(addr_));
-  ExpectNonErrorState(NetworkServiceAsyncSocket::STATE_CONNECTING);
-  ExpectNoSignal();
-
-  base::RunLoop().RunUntilIdle();
-  ExpectNonErrorState(NetworkServiceAsyncSocket::STATE_OPEN);
-  ExpectSignalSocketState(SignalSocketState::NoError(
-      SIGNAL_CONNECT, NetworkServiceAsyncSocket::STATE_OPEN));
-  ExpectNoSignal();
-
-  base::RunLoop().RunUntilIdle();
-
-  DoCloseOpenedNoError();
-}
-
-// After this no need to test successful pending connect so
-// thoroughly.
-
-TEST_F(NetworkServiceAsyncSocketTest, PendingConnectCloseBeforeRead) {
-  async_socket_data_provider_.set_connect_data(
-      net::MockConnect(net::ASYNC, net::OK));
-  EXPECT_TRUE(ns_async_socket_->Connect(addr_));
-
-  base::RunLoop().RunUntilIdle();
-  ExpectSignalSocketState(SignalSocketState::NoError(
-      SIGNAL_CONNECT, NetworkServiceAsyncSocket::STATE_OPEN));
-
-  DoCloseOpenedNoError();
-
-  base::RunLoop().RunUntilIdle();
-}
-
-TEST_F(NetworkServiceAsyncSocketTest, PendingConnectError) {
-  async_socket_data_provider_.set_connect_data(
-      net::MockConnect(net::ASYNC, net::ERR_TIMED_OUT));
-  EXPECT_TRUE(ns_async_socket_->Connect(addr_));
-
-  base::RunLoop().RunUntilIdle();
-
-  ExpectSignalSocketState(SignalSocketState(
-      SIGNAL_CLOSE, NetworkServiceAsyncSocket::STATE_CLOSED,
-      NetworkServiceAsyncSocket::ERROR_WINSOCK, net::ERR_TIMED_OUT));
-}
-
-// After this we can assume Connect() and Close() work as expected.
-
-TEST_F(NetworkServiceAsyncSocketTest, EmptyRead) {
-  DoOpenClosed();
-
-  char buf[4096];
-  size_t len_read = 10000U;
-  EXPECT_TRUE(ns_async_socket_->Read(buf, sizeof(buf), &len_read));
-  EXPECT_EQ(0U, len_read);
-
-  DoCloseOpenedNoError();
-}
-
-TEST_F(NetworkServiceAsyncSocketTest, WrongRead) {
-  EXPECT_DCHECK_DEATH_WITH(
-      {
-        async_socket_data_provider_.set_connect_data(
-            net::MockConnect(net::ASYNC, net::OK));
-        EXPECT_TRUE(ns_async_socket_->Connect(addr_));
-        ExpectNonErrorState(NetworkServiceAsyncSocket::STATE_CONNECTING);
-        ExpectNoSignal();
-
-        char buf[4096];
-        size_t len_read;
-        EXPECT_FALSE(ns_async_socket_->Read(buf, sizeof(buf), &len_read));
-        ExpectErrorState(NetworkServiceAsyncSocket::STATE_CONNECTING,
-                         NetworkServiceAsyncSocket::ERROR_WRONGSTATE);
-        EXPECT_TRUE(ns_async_socket_->Close());
-        ExpectSignalSocketState(SignalSocketState(
-            SIGNAL_CLOSE, NetworkServiceAsyncSocket::STATE_CLOSED,
-            NetworkServiceAsyncSocket::ERROR_WRONGSTATE, net::OK));
-      },
-      "non-open");
-}
-
-TEST_F(NetworkServiceAsyncSocketTest, WrongReadClosed) {
-  char buf[4096];
-  size_t len_read;
-  EXPECT_FALSE(ns_async_socket_->Read(buf, sizeof(buf), &len_read));
-  ExpectErrorState(NetworkServiceAsyncSocket::STATE_CLOSED,
-                   NetworkServiceAsyncSocket::ERROR_WRONGSTATE);
-  EXPECT_TRUE(ns_async_socket_->Close());
-}
-
-const char kReadData[] = "mydatatoread";
-
-TEST_F(NetworkServiceAsyncSocketTest, Read) {
-  async_socket_data_provider_.AddRead(net::MockRead(kReadData));
-  DoOpenClosed();
-
-  ExpectReadSignal();
-  ExpectNoSignal();
-
-  EXPECT_EQ(kReadData, DrainRead(1));
-
-  base::RunLoop().RunUntilIdle();
-
-  DoCloseOpenedNoError();
-}
-
-TEST_F(NetworkServiceAsyncSocketTest, ReadTwice) {
-  async_socket_data_provider_.AddRead(net::MockRead(kReadData));
-  DoOpenClosed();
-
-  ExpectReadSignal();
-  ExpectNoSignal();
-
-  EXPECT_EQ(kReadData, DrainRead(1));
-
-  base::RunLoop().RunUntilIdle();
-
-  const char kReadData2[] = "mydatatoread2";
-  async_socket_data_provider_.AddRead(net::MockRead(kReadData2));
-  base::RunLoop().RunUntilIdle();
-
-  ExpectReadSignal();
-  ExpectNoSignal();
-
-  EXPECT_EQ(kReadData2, DrainRead(1));
-
-  DoCloseOpenedNoError();
-}
-
-TEST_F(NetworkServiceAsyncSocketTest, ReadError) {
-  async_socket_data_provider_.AddRead(net::MockRead(kReadData));
-  DoOpenClosed();
-
-  ExpectReadSignal();
-  ExpectNoSignal();
-
-  EXPECT_EQ(kReadData, DrainRead(1));
-
-  base::RunLoop().RunUntilIdle();
-
-  async_socket_data_provider_.AddRead(
-      net::MockRead(net::SYNCHRONOUS, net::ERR_TIMED_OUT));
-  base::RunLoop().RunUntilIdle();
-
-  ExpectSignalSocketState(SignalSocketState(
-      SIGNAL_CLOSE, NetworkServiceAsyncSocket::STATE_CLOSED,
-      NetworkServiceAsyncSocket::ERROR_WINSOCK, net::ERR_TIMED_OUT));
-}
-
-TEST_F(NetworkServiceAsyncSocketTest, ReadEOF) {
-  async_socket_data_provider_.AddRead(net::MockRead(kReadData));
-  DoOpenClosed();
-
-  ExpectReadSignal();
-  ExpectNoSignal();
-
-  EXPECT_EQ(kReadData, DrainRead(1));
-
-  base::RunLoop().RunUntilIdle();
-
-  async_socket_data_provider_.AddRead(net::MockRead(net::SYNCHRONOUS, net::OK));
-  base::RunLoop().RunUntilIdle();
-  ExpectSignalSocketState(SignalSocketState::NoError(
-      SIGNAL_CLOSE, NetworkServiceAsyncSocket::STATE_CLOSED));
-}
-
-TEST_F(NetworkServiceAsyncSocketTest, ReadEmpty) {
-  async_socket_data_provider_.AddRead(net::MockRead(""));
-  DoOpenClosed();
-
-  ExpectSignalSocketState(SignalSocketState::NoError(
-      SIGNAL_CLOSE, NetworkServiceAsyncSocket::STATE_CLOSED));
-}
-
-TEST_F(NetworkServiceAsyncSocketTest, PendingRead) {
-  DoOpenClosed();
-
-  ExpectNoSignal();
-
-  async_socket_data_provider_.AddRead(net::MockRead(kReadData));
-  base::RunLoop().RunUntilIdle();
-
-  ExpectSignalSocketState(SignalSocketState::NoError(
-      SIGNAL_READ, NetworkServiceAsyncSocket::STATE_OPEN));
-  ExpectNoSignal();
-
-  EXPECT_EQ(kReadData, DrainRead(1));
-
-  base::RunLoop().RunUntilIdle();
-
-  DoCloseOpenedNoError();
-}
-
-TEST_F(NetworkServiceAsyncSocketTest, PendingEmptyRead) {
-  DoOpenClosed();
-
-  ExpectNoSignal();
-
-  async_socket_data_provider_.AddRead(net::MockRead(""));
-  base::RunLoop().RunUntilIdle();
-
-  ExpectSignalSocketState(SignalSocketState::NoError(
-      SIGNAL_CLOSE, NetworkServiceAsyncSocket::STATE_CLOSED));
-}
-
-TEST_F(NetworkServiceAsyncSocketTest, PendingReadError) {
-  DoOpenClosed();
-
-  ExpectNoSignal();
-
-  async_socket_data_provider_.AddRead(
-      net::MockRead(net::ASYNC, net::ERR_TIMED_OUT));
-  base::RunLoop().RunUntilIdle();
-
-  ExpectSignalSocketState(SignalSocketState(
-      SIGNAL_CLOSE, NetworkServiceAsyncSocket::STATE_CLOSED,
-      NetworkServiceAsyncSocket::ERROR_WINSOCK, net::ERR_TIMED_OUT));
-}
-
-// After this we can assume non-SSL Read() works as expected.
-
-TEST_F(NetworkServiceAsyncSocketTest, WrongWrite) {
-  EXPECT_DCHECK_DEATH_WITH(
-      {
-        std::string data("foo");
-        EXPECT_FALSE(ns_async_socket_->Write(data.data(), data.size()));
-        ExpectErrorState(NetworkServiceAsyncSocket::STATE_CLOSED,
-                         NetworkServiceAsyncSocket::ERROR_WRONGSTATE);
-        EXPECT_TRUE(ns_async_socket_->Close());
-      },
-      "non-open");
-}
-
-const char kWriteData[] = "mydatatowrite";
-
-TEST_F(NetworkServiceAsyncSocketTest, SyncWrite) {
-  async_socket_data_provider_.AddWrite(
-      net::MockWrite(net::SYNCHRONOUS, kWriteData, 3));
-  async_socket_data_provider_.AddWrite(
-      net::MockWrite(net::SYNCHRONOUS, kWriteData + 3, 5));
-  async_socket_data_provider_.AddWrite(net::MockWrite(
-      net::SYNCHRONOUS, kWriteData + 8, base::size(kWriteData) - 8));
-  DoOpenClosed();
-
-  EXPECT_TRUE(ns_async_socket_->Write(kWriteData, 3));
-  base::RunLoop().RunUntilIdle();
-  EXPECT_TRUE(ns_async_socket_->Write(kWriteData + 3, 5));
-  base::RunLoop().RunUntilIdle();
-  EXPECT_TRUE(
-      ns_async_socket_->Write(kWriteData + 8, base::size(kWriteData) - 8));
-  base::RunLoop().RunUntilIdle();
-
-  ExpectNoSignal();
-
-  DoCloseOpenedNoError();
-}
-
-TEST_F(NetworkServiceAsyncSocketTest, AsyncWrite) {
-  DoOpenClosed();
-
-  async_socket_data_provider_.AddWrite(
-      net::MockWrite(net::ASYNC, kWriteData, 3));
-  async_socket_data_provider_.AddWrite(
-      net::MockWrite(net::ASYNC, kWriteData + 3, 5));
-  async_socket_data_provider_.AddWrite(
-      net::MockWrite(net::ASYNC, kWriteData + 8, base::size(kWriteData) - 8));
-
-  EXPECT_TRUE(ns_async_socket_->Write(kWriteData, 3));
-  base::RunLoop().RunUntilIdle();
-  EXPECT_TRUE(ns_async_socket_->Write(kWriteData + 3, 5));
-  base::RunLoop().RunUntilIdle();
-  EXPECT_TRUE(
-      ns_async_socket_->Write(kWriteData + 8, base::size(kWriteData) - 8));
-  base::RunLoop().RunUntilIdle();
-
-  ExpectNoSignal();
-
-  DoCloseOpenedNoError();
-}
-
-TEST_F(NetworkServiceAsyncSocketTest, AsyncWriteError) {
-  DoOpenClosed();
-
-  async_socket_data_provider_.AddWrite(
-      net::MockWrite(net::ASYNC, kWriteData, 3));
-  async_socket_data_provider_.AddWrite(
-      net::MockWrite(net::ASYNC, kWriteData + 3, 5));
-  async_socket_data_provider_.AddWrite(
-      net::MockWrite(net::ASYNC, net::ERR_TIMED_OUT));
-
-  EXPECT_TRUE(ns_async_socket_->Write(kWriteData, 3));
-  base::RunLoop().RunUntilIdle();
-  EXPECT_TRUE(ns_async_socket_->Write(kWriteData + 3, 5));
-  base::RunLoop().RunUntilIdle();
-  EXPECT_TRUE(
-      ns_async_socket_->Write(kWriteData + 8, base::size(kWriteData) - 8));
-  base::RunLoop().RunUntilIdle();
-
-  ExpectSignalSocketState(SignalSocketState(
-      SIGNAL_CLOSE, NetworkServiceAsyncSocket::STATE_CLOSED,
-      NetworkServiceAsyncSocket::ERROR_WINSOCK, net::ERR_TIMED_OUT));
-}
-
-TEST_F(NetworkServiceAsyncSocketTest, LargeWrite) {
-  EXPECT_DCHECK_DEATH_WITH(
-      {
-        DoOpenClosed();
-
-        std::string large_data(100, 'x');
-        EXPECT_FALSE(
-            ns_async_socket_->Write(large_data.data(), large_data.size()));
-        ExpectState(NetworkServiceAsyncSocket::STATE_OPEN,
-                    NetworkServiceAsyncSocket::ERROR_WINSOCK,
-                    net::ERR_INSUFFICIENT_RESOURCES);
-        DoCloseOpened(SignalSocketState(
-            SIGNAL_CLOSE, NetworkServiceAsyncSocket::STATE_CLOSED,
-            NetworkServiceAsyncSocket::ERROR_WINSOCK,
-            net::ERR_INSUFFICIENT_RESOURCES));
-      },
-      "exceed the max write buffer");
-}
-
-TEST_F(NetworkServiceAsyncSocketTest, LargeAccumulatedWrite) {
-  EXPECT_DCHECK_DEATH_WITH(
-      {
-        DoOpenClosed();
-
-        std::string data(15, 'x');
-        EXPECT_TRUE(ns_async_socket_->Write(data.data(), data.size()));
-        EXPECT_FALSE(ns_async_socket_->Write(data.data(), data.size()));
-        ExpectState(NetworkServiceAsyncSocket::STATE_OPEN,
-                    NetworkServiceAsyncSocket::ERROR_WINSOCK,
-                    net::ERR_INSUFFICIENT_RESOURCES);
-        DoCloseOpened(SignalSocketState(
-            SIGNAL_CLOSE, NetworkServiceAsyncSocket::STATE_CLOSED,
-            NetworkServiceAsyncSocket::ERROR_WINSOCK,
-            net::ERR_INSUFFICIENT_RESOURCES));
-      },
-      "exceed the max write buffer");
-}
-
-// After this we can assume non-SSL I/O works as expected.
-
-TEST_F(NetworkServiceAsyncSocketTest, HangingSSLConnect) {
-  async_socket_data_provider_.AddRead(net::MockRead(kReadData));
-  DoOpenClosed();
-  ExpectReadSignal();
-
-  EXPECT_TRUE(ns_async_socket_->StartTls("fakedomain.com"));
-  ExpectNoSignal();
-
-  ExpectNonErrorState(NetworkServiceAsyncSocket::STATE_TLS_CONNECTING);
-  EXPECT_TRUE(ns_async_socket_->Close());
-  ExpectSignalSocketState(SignalSocketState::NoError(
-      SIGNAL_CLOSE, NetworkServiceAsyncSocket::STATE_CLOSED));
-  ExpectNonErrorState(NetworkServiceAsyncSocket::STATE_CLOSED);
-}
-
-TEST_F(NetworkServiceAsyncSocketTest, ImmediateSSLConnect) {
-  async_socket_data_provider_.AddRead(net::MockRead(kReadData));
-  DoOpenClosed();
-  ExpectReadSignal();
-
-  EXPECT_TRUE(ns_async_socket_->StartTls("fakedomain.com"));
-  base::RunLoop().RunUntilIdle();
-  ExpectSSLConnectSignal();
-  ExpectNoSignal();
-  ExpectNonErrorState(NetworkServiceAsyncSocket::STATE_TLS_OPEN);
-
-  DoSSLCloseOpenedNoError();
-}
-
-TEST_F(NetworkServiceAsyncSocketTest, DoubleSSLConnect) {
-  EXPECT_DCHECK_DEATH_WITH(
-      {
-        async_socket_data_provider_.AddRead(net::MockRead(kReadData));
-        DoOpenClosed();
-        ExpectReadSignal();
-
-        EXPECT_TRUE(ns_async_socket_->StartTls("fakedomain.com"));
-        base::RunLoop().RunUntilIdle();
-        ExpectSSLConnectSignal();
-        ExpectNoSignal();
-        ExpectNonErrorState(NetworkServiceAsyncSocket::STATE_TLS_OPEN);
-
-        EXPECT_FALSE(ns_async_socket_->StartTls("fakedomain.com"));
-
-        DoSSLCloseOpened(SignalSocketState(
-            SIGNAL_CLOSE, NetworkServiceAsyncSocket::STATE_CLOSED,
-            NetworkServiceAsyncSocket::ERROR_WRONGSTATE, net::OK));
-      },
-      "wrong state");
-}
-
-TEST_F(NetworkServiceAsyncSocketTest, FailedSSLConnect) {
-  ssl_socket_data_provider_.connect =
-      net::MockConnect(net::ASYNC, net::ERR_CERT_COMMON_NAME_INVALID),
-
-  async_socket_data_provider_.AddRead(net::MockRead(kReadData));
-  DoOpenClosed();
-  ExpectReadSignal();
-
-  EXPECT_TRUE(ns_async_socket_->StartTls("fakedomain.com"));
-  base::RunLoop().RunUntilIdle();
-  ExpectSignalSocketState(
-      SignalSocketState(SIGNAL_CLOSE, NetworkServiceAsyncSocket::STATE_CLOSED,
-                        NetworkServiceAsyncSocket::ERROR_WINSOCK,
-                        net::ERR_CERT_COMMON_NAME_INVALID));
-
-  EXPECT_TRUE(ns_async_socket_->Close());
-  ExpectClosed();
-}
-
-TEST_F(NetworkServiceAsyncSocketTest, ReadDuringSSLConnecting) {
-  async_socket_data_provider_.AddRead(net::MockRead(kReadData));
-  DoOpenClosed();
-  ExpectReadSignal();
-  EXPECT_EQ(kReadData, DrainRead(1));
-
-  EXPECT_TRUE(ns_async_socket_->StartTls("fakedomain.com"));
-  ExpectNoSignal();
-
-  // Shouldn't do anything.
-  async_socket_data_provider_.AddRead(net::MockRead(kReadData));
-
-  char buf[4096];
-  size_t len_read = 10000U;
-  EXPECT_TRUE(ns_async_socket_->Read(buf, sizeof(buf), &len_read));
-  EXPECT_EQ(0U, len_read);
-
-  base::RunLoop().RunUntilIdle();
-  ExpectSSLConnectSignal();
-  ExpectSSLReadSignal();
-  ExpectNoSignal();
-  ExpectNonErrorState(NetworkServiceAsyncSocket::STATE_TLS_OPEN);
-
-  len_read = 10000U;
-  EXPECT_TRUE(ns_async_socket_->Read(buf, sizeof(buf), &len_read));
-  EXPECT_EQ(kReadData, std::string(buf, len_read));
-
-  DoSSLCloseOpenedNoError();
-}
-
-TEST_F(NetworkServiceAsyncSocketTest, WriteDuringSSLConnecting) {
-  async_socket_data_provider_.AddRead(net::MockRead(kReadData));
-  DoOpenClosed();
-  ExpectReadSignal();
-
-  EXPECT_TRUE(ns_async_socket_->StartTls("fakedomain.com"));
-  ExpectNoSignal();
-  ExpectNonErrorState(NetworkServiceAsyncSocket::STATE_TLS_CONNECTING);
-
-  async_socket_data_provider_.AddWrite(
-      net::MockWrite(net::ASYNC, kWriteData, 3));
-
-  // Shouldn't do anything.
-  EXPECT_TRUE(ns_async_socket_->Write(kWriteData, 3));
-
-  // TODO(akalin): Figure out how to test that the write happens
-  // *after* the SSL connect.
-
-  base::RunLoop().RunUntilIdle();
-  ExpectSSLConnectSignal();
-  ExpectNoSignal();
-
-  base::RunLoop().RunUntilIdle();
-
-  DoSSLCloseOpenedNoError();
-}
-
-// After this we can assume SSL connect works as expected.
-
-TEST_F(NetworkServiceAsyncSocketTest, SSLRead) {
-  DoSSLOpenClosed();
-  async_socket_data_provider_.AddRead(net::MockRead(kReadData));
-  base::RunLoop().RunUntilIdle();
-
-  ExpectSSLReadSignal();
-  ExpectNoSignal();
-
-  EXPECT_EQ(kReadData, DrainRead(1));
-
-  base::RunLoop().RunUntilIdle();
-
-  DoSSLCloseOpenedNoError();
-}
-
-TEST_F(NetworkServiceAsyncSocketTest, SSLSyncWrite) {
-  async_socket_data_provider_.AddWrite(
-      net::MockWrite(net::SYNCHRONOUS, kWriteData, 3));
-  async_socket_data_provider_.AddWrite(
-      net::MockWrite(net::SYNCHRONOUS, kWriteData + 3, 5));
-  async_socket_data_provider_.AddWrite(net::MockWrite(
-      net::SYNCHRONOUS, kWriteData + 8, base::size(kWriteData) - 8));
-  DoSSLOpenClosed();
-
-  EXPECT_TRUE(ns_async_socket_->Write(kWriteData, 3));
-  base::RunLoop().RunUntilIdle();
-  EXPECT_TRUE(ns_async_socket_->Write(kWriteData + 3, 5));
-  base::RunLoop().RunUntilIdle();
-  EXPECT_TRUE(
-      ns_async_socket_->Write(kWriteData + 8, base::size(kWriteData) - 8));
-  base::RunLoop().RunUntilIdle();
-
-  ExpectNoSignal();
-
-  DoSSLCloseOpenedNoError();
-}
-
-TEST_F(NetworkServiceAsyncSocketTest, SSLAsyncWrite) {
-  DoSSLOpenClosed();
-
-  async_socket_data_provider_.AddWrite(
-      net::MockWrite(net::ASYNC, kWriteData, 3));
-  async_socket_data_provider_.AddWrite(
-      net::MockWrite(net::ASYNC, kWriteData + 3, 5));
-  async_socket_data_provider_.AddWrite(
-      net::MockWrite(net::ASYNC, kWriteData + 8, base::size(kWriteData) - 8));
-
-  EXPECT_TRUE(ns_async_socket_->Write(kWriteData, 3));
-  base::RunLoop().RunUntilIdle();
-  EXPECT_TRUE(ns_async_socket_->Write(kWriteData + 3, 5));
-  base::RunLoop().RunUntilIdle();
-  EXPECT_TRUE(
-      ns_async_socket_->Write(kWriteData + 8, base::size(kWriteData) - 8));
-  base::RunLoop().RunUntilIdle();
-
-  ExpectNoSignal();
-
-  DoSSLCloseOpenedNoError();
-}
-
-class NetworkServiceAsyncSocketMojoTest : public NetworkServiceAsyncSocketTest {
- protected:
-  NetworkServiceAsyncSocketMojoTest()
-      : NetworkServiceAsyncSocketTest(true /* use_mojo_level_mock */) {}
-  ~NetworkServiceAsyncSocketMojoTest() override {}
-};
-
-TEST_F(NetworkServiceAsyncSocketMojoTest, ReadEOF1) {
-  DoOpenClosed();
-  mock_proxy_resolving_socket_factory_->socket()->RunEvents(
-      {MockProxyResolvingSocket::kRead,
-       MockProxyResolvingSocket::kCloseReadPipe,
-       MockProxyResolvingSocket::kReadEofError,
-       MockProxyResolvingSocket::kCloseObserverPipe});
-
-  ExpectReadSignal();
-  ExpectNoSignal();
-  EXPECT_EQ("data", DrainRead(1));
-
-  base::RunLoop().RunUntilIdle();
-  ExpectSignalSocketState(SignalSocketState::NoError(
-      SIGNAL_CLOSE, NetworkServiceAsyncSocket::STATE_CLOSED));
-  ExpectClosed();
-}
-
-TEST_F(NetworkServiceAsyncSocketMojoTest, ReadEOF2) {
-  DoOpenClosed();
-  mock_proxy_resolving_socket_factory_->socket()->RunEvents(
-      {MockProxyResolvingSocket::kReadEofError,
-       MockProxyResolvingSocket::kCloseObserverPipe,
-       MockProxyResolvingSocket::kRead,
-       MockProxyResolvingSocket::kCloseReadPipe});
-
-  ExpectReadSignal();
-  ExpectNoSignal();
-  EXPECT_EQ("data", DrainRead(1));
-
-  base::RunLoop().RunUntilIdle();
-  ExpectSignalSocketState(SignalSocketState::NoError(
-      SIGNAL_CLOSE, NetworkServiceAsyncSocket::STATE_CLOSED));
-  ExpectClosed();
-}
-
-TEST_F(NetworkServiceAsyncSocketMojoTest, ReadError1) {
-  DoOpenClosed();
-  mock_proxy_resolving_socket_factory_->socket()->RunEvents(
-      {MockProxyResolvingSocket::kRead,
-       MockProxyResolvingSocket::kCloseReadPipe,
-       MockProxyResolvingSocket::kReadError,
-       MockProxyResolvingSocket::kCloseObserverPipe});
-
-  ExpectReadSignal();
-  ExpectNoSignal();
-  EXPECT_EQ("data", DrainRead(1));
-
-  base::RunLoop().RunUntilIdle();
-  ExpectSignalSocketState(SignalSocketState(
-      SIGNAL_CLOSE, NetworkServiceAsyncSocket::STATE_CLOSED,
-      NetworkServiceAsyncSocket::ERROR_WINSOCK, net::ERR_OUT_OF_MEMORY));
-  ExpectClosed();
-}
-
-TEST_F(NetworkServiceAsyncSocketMojoTest, ReadError2) {
-  DoOpenClosed();
-  mock_proxy_resolving_socket_factory_->socket()->RunEvents(
-      {MockProxyResolvingSocket::kReadError,
-       MockProxyResolvingSocket::kCloseObserverPipe,
-       MockProxyResolvingSocket::kRead,
-       MockProxyResolvingSocket::kCloseReadPipe});
-
-  ExpectReadSignal();
-  ExpectNoSignal();
-  EXPECT_EQ("data", DrainRead(1));
-
-  base::RunLoop().RunUntilIdle();
-  ExpectSignalSocketState(SignalSocketState(
-      SIGNAL_CLOSE, NetworkServiceAsyncSocket::STATE_CLOSED,
-      NetworkServiceAsyncSocket::ERROR_WINSOCK, net::ERR_OUT_OF_MEMORY));
-  ExpectClosed();
-}
-
-TEST_F(NetworkServiceAsyncSocketMojoTest, ReadErrorDouble) {
-  DoOpenClosed();
-  mock_proxy_resolving_socket_factory_->socket()->RunEvents(
-      {MockProxyResolvingSocket::kReadError,
-       MockProxyResolvingSocket::kReadError,
-       MockProxyResolvingSocket::kCloseObserverPipe,
-       MockProxyResolvingSocket::kRead,
-       MockProxyResolvingSocket::kCloseReadPipe});
-
-  ExpectReadSignal();
-  ExpectNoSignal();
-  EXPECT_EQ("data", DrainRead(1));
-
-  base::RunLoop().RunUntilIdle();
-  ExpectSignalSocketState(SignalSocketState(
-      SIGNAL_CLOSE, NetworkServiceAsyncSocket::STATE_CLOSED,
-      NetworkServiceAsyncSocket::ERROR_WINSOCK, net::ERR_OUT_OF_MEMORY));
-  ExpectClosed();
-}
-
-TEST_F(NetworkServiceAsyncSocketMojoTest, ReadErrorDoubleInvalid) {
-  DoOpenClosed();
-  mock_proxy_resolving_socket_factory_->socket()->RunEvents(
-      {MockProxyResolvingSocket::kReadError,
-       MockProxyResolvingSocket::kReadErrorInvalid,
-       MockProxyResolvingSocket::kCloseObserverPipe,
-       MockProxyResolvingSocket::kRead,
-       MockProxyResolvingSocket::kCloseReadPipe});
-
-  ExpectReadSignal();
-  ExpectNoSignal();
-  EXPECT_EQ("data", DrainRead(1));
-
-  base::RunLoop().RunUntilIdle();
-  ExpectSignalSocketState(SignalSocketState(
-      SIGNAL_CLOSE, NetworkServiceAsyncSocket::STATE_CLOSED,
-      NetworkServiceAsyncSocket::ERROR_WINSOCK, net::ERR_OUT_OF_MEMORY));
-  ExpectClosed();
-}
-
-TEST_F(NetworkServiceAsyncSocketMojoTest, ReadErrorDoubleInvalid2) {
-  DoOpenClosed();
-  mock_proxy_resolving_socket_factory_->socket()->RunEvents(
-      {MockProxyResolvingSocket::kReadErrorInvalid,
-       MockProxyResolvingSocket::kReadError,
-       MockProxyResolvingSocket::kCloseObserverPipe,
-       MockProxyResolvingSocket::kRead,
-       MockProxyResolvingSocket::kCloseReadPipe});
-
-  ExpectReadSignal();
-  ExpectNoSignal();
-  EXPECT_EQ("data", DrainRead(1));
-
-  base::RunLoop().RunUntilIdle();
-  ExpectSignalSocketState(SignalSocketState(
-      SIGNAL_CLOSE, NetworkServiceAsyncSocket::STATE_CLOSED,
-      NetworkServiceAsyncSocket::ERROR_WINSOCK, net::ERR_FAILED));
-  ExpectClosed();
-}
-
-TEST_F(NetworkServiceAsyncSocketMojoTest, ReadErrorClosedObserverPipe) {
-  DoOpenClosed();
-  mock_proxy_resolving_socket_factory_->socket()->RunEvents(
-      {MockProxyResolvingSocket::kRead,
-       MockProxyResolvingSocket::kCloseObserverPipe});
-  // Can't run kCloseReadPipe since it'll already be closed.
-
-  ExpectReadSignal();
-  // Since this is a misbehaving network service process scenario, no attempt
-  // to recover the data is made.
-  ExpectSignalSocketState(SignalSocketState(
-      SIGNAL_CLOSE, NetworkServiceAsyncSocket::STATE_CLOSED,
-      NetworkServiceAsyncSocket::ERROR_WINSOCK, net::ERR_FAILED));
-  ExpectClosed();
-}
-
-TEST_F(NetworkServiceAsyncSocketMojoTest, WriteError1) {
-  DoOpenClosed();
-  ExpectNoSignal();
-  ns_async_socket_->Write("atad", 4);
-  base::RunLoop().RunUntilIdle();
-
-  mock_proxy_resolving_socket_factory_->socket()->RunEvents(
-      {MockProxyResolvingSocket::kWrite,
-       MockProxyResolvingSocket::kCloseWritePipe,
-       MockProxyResolvingSocket::kWriteError});
-  // Cannot close the observer pipe here at the end since the other size
-  // would have closed it already.
-
-  base::RunLoop().RunUntilIdle();
-  ExpectSignalSocketState(SignalSocketState(
-      SIGNAL_CLOSE, NetworkServiceAsyncSocket::STATE_CLOSED,
-      NetworkServiceAsyncSocket::ERROR_WINSOCK, net::ERR_ACCESS_DENIED));
-  ExpectClosed();
-}
-
-TEST_F(NetworkServiceAsyncSocketMojoTest, WriteError2) {
-  DoOpenClosed();
-  ExpectNoSignal();
-  ns_async_socket_->Write("atad", 4);
-  base::RunLoop().RunUntilIdle();
-
-  mock_proxy_resolving_socket_factory_->socket()->RunEvents(
-      {MockProxyResolvingSocket::kWriteError,
-       MockProxyResolvingSocket::kCloseObserverPipe,
-       MockProxyResolvingSocket::kWrite,
-       MockProxyResolvingSocket::kCloseWritePipe});
-
-  base::RunLoop().RunUntilIdle();
-  ExpectSignalSocketState(SignalSocketState(
-      SIGNAL_CLOSE, NetworkServiceAsyncSocket::STATE_CLOSED,
-      NetworkServiceAsyncSocket::ERROR_WINSOCK, net::ERR_ACCESS_DENIED));
-  ExpectClosed();
-}
-
-TEST_F(NetworkServiceAsyncSocketMojoTest, WriteErrorDouble) {
-  DoOpenClosed();
-  ExpectNoSignal();
-  ns_async_socket_->Write("atad", 4);
-  base::RunLoop().RunUntilIdle();
-
-  mock_proxy_resolving_socket_factory_->socket()->RunEvents(
-      {MockProxyResolvingSocket::kWriteError,
-       MockProxyResolvingSocket::kWriteError,
-       MockProxyResolvingSocket::kCloseObserverPipe,
-       MockProxyResolvingSocket::kWrite,
-       MockProxyResolvingSocket::kCloseWritePipe});
-
-  base::RunLoop().RunUntilIdle();
-  ExpectSignalSocketState(SignalSocketState(
-      SIGNAL_CLOSE, NetworkServiceAsyncSocket::STATE_CLOSED,
-      NetworkServiceAsyncSocket::ERROR_WINSOCK, net::ERR_ACCESS_DENIED));
-  ExpectClosed();
-}
-
-TEST_F(NetworkServiceAsyncSocketMojoTest, WriteErrorDoubleInvalid) {
-  DoOpenClosed();
-  ExpectNoSignal();
-  ns_async_socket_->Write("atad", 4);
-  base::RunLoop().RunUntilIdle();
-
-  mock_proxy_resolving_socket_factory_->socket()->RunEvents(
-      {MockProxyResolvingSocket::kWriteError,
-       MockProxyResolvingSocket::kWriteErrorInvalid,
-       MockProxyResolvingSocket::kCloseObserverPipe,
-       MockProxyResolvingSocket::kWrite,
-       MockProxyResolvingSocket::kCloseWritePipe});
-
-  base::RunLoop().RunUntilIdle();
-  ExpectSignalSocketState(SignalSocketState(
-      SIGNAL_CLOSE, NetworkServiceAsyncSocket::STATE_CLOSED,
-      NetworkServiceAsyncSocket::ERROR_WINSOCK, net::ERR_ACCESS_DENIED));
-  ExpectClosed();
-}
-
-TEST_F(NetworkServiceAsyncSocketMojoTest, WriteErrorDoubleInvalid2) {
-  DoOpenClosed();
-  ExpectNoSignal();
-  ns_async_socket_->Write("atad", 4);
-  base::RunLoop().RunUntilIdle();
-
-  mock_proxy_resolving_socket_factory_->socket()->RunEvents(
-      {MockProxyResolvingSocket::kWriteErrorInvalid,
-       MockProxyResolvingSocket::kWriteError,
-       MockProxyResolvingSocket::kCloseObserverPipe,
-       MockProxyResolvingSocket::kWrite,
-       MockProxyResolvingSocket::kCloseWritePipe});
-
-  base::RunLoop().RunUntilIdle();
-  ExpectSignalSocketState(SignalSocketState(
-      SIGNAL_CLOSE, NetworkServiceAsyncSocket::STATE_CLOSED,
-      NetworkServiceAsyncSocket::ERROR_WINSOCK, net::ERR_FAILED));
-  ExpectClosed();
-}
-
-}  // namespace
-
-}  // namespace jingle_glue
diff --git a/jingle/glue/network_service_config.cc b/jingle/glue/network_service_config.cc
deleted file mode 100644
index d619555..0000000
--- a/jingle/glue/network_service_config.cc
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// Configuration information for talking to the network service.
-
-#include "jingle/glue/network_service_config.h"
-
-namespace jingle_glue {
-
-NetworkServiceConfig::NetworkServiceConfig() = default;
-NetworkServiceConfig::NetworkServiceConfig(const NetworkServiceConfig& other) =
-    default;
-NetworkServiceConfig::~NetworkServiceConfig() = default;
-
-}  // namespace jingle_glue
diff --git a/jingle/glue/network_service_config.h b/jingle/glue/network_service_config.h
deleted file mode 100644
index c4c5000..0000000
--- a/jingle/glue/network_service_config.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// Configuration information for talking to the network service.
-
-#ifndef JINGLE_GLUE_NETWORK_SERVICE_CONFIG_H_
-#define JINGLE_GLUE_NETWORK_SERVICE_CONFIG_H_
-
-#include "base/callback.h"
-#include "base/task/single_thread_task_runner.h"
-#include "mojo/public/cpp/bindings/pending_receiver.h"
-#include "services/network/public/mojom/proxy_resolving_socket.mojom.h"
-
-namespace jingle_glue {
-
-using GetProxyResolvingSocketFactoryCallback = base::RepeatingCallback<void(
-    mojo::PendingReceiver<network::mojom::ProxyResolvingSocketFactory>)>;
-
-struct NetworkServiceConfig {
-  NetworkServiceConfig();
-  NetworkServiceConfig(const NetworkServiceConfig& other);
-  ~NetworkServiceConfig();
-
-  // This will be run on |task_runner|.
-  GetProxyResolvingSocketFactoryCallback
-      get_proxy_resolving_socket_factory_callback;
-  scoped_refptr<base::SingleThreadTaskRunner> task_runner;
-};
-
-}  // namespace jingle_glue
-
-#endif  // JINGLE_GLUE_NETWORK_SERVICE_CONFIG_H_
diff --git a/jingle/glue/task_pump.cc b/jingle/glue/task_pump.cc
deleted file mode 100644
index 74cdab7..0000000
--- a/jingle/glue/task_pump.cc
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <stdint.h>
-
-#include "base/bind.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "jingle/glue/task_pump.h"
-
-namespace jingle_glue {
-
-TaskPump::TaskPump() : posted_wake_(false), stopped_(false) {}
-
-TaskPump::~TaskPump() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-}
-
-void TaskPump::WakeTasks() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  if (!stopped_ && !posted_wake_) {
-    // Do the requested wake up.
-    base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::BindOnce(&TaskPump::CheckAndRunTasks,
-                                  weak_factory_.GetWeakPtr()));
-    posted_wake_ = true;
-  }
-}
-
-void TaskPump::Stop() {
-  stopped_ = true;
-}
-
-void TaskPump::CheckAndRunTasks() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  if (stopped_) {
-    return;
-  }
-  posted_wake_ = false;
-  // We shouldn't be using libjingle for timeout tasks, so we should
-  // have no timeout tasks at all.
-
-  // TODO(akalin): Add HasTimeoutTask() back in TaskRunner class and
-  // uncomment this check.
-  // DCHECK(!HasTimeoutTask())
-  RunTasks();
-}
-
-}  // namespace jingle_glue
diff --git a/jingle/glue/task_pump.h b/jingle/glue/task_pump.h
deleted file mode 100644
index 6848453..0000000
--- a/jingle/glue/task_pump.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef JINGLE_GLUE_TASK_PUMP_H_
-#define JINGLE_GLUE_TASK_PUMP_H_
-
-#include <stdint.h>
-
-#include "base/compiler_specific.h"
-#include "base/memory/weak_ptr.h"
-#include "base/sequence_checker.h"
-#include "third_party/libjingle_xmpp/task_runner/taskrunner.h"
-
-namespace jingle_glue {
-
-// rtc::TaskRunner implementation that works on chromium threads.
-class TaskPump : public jingle_xmpp::TaskRunner {
- public:
-  TaskPump();
-
-  TaskPump(const TaskPump&) = delete;
-  TaskPump& operator=(const TaskPump&) = delete;
-
-  ~TaskPump() override;
-
-  // rtc::TaskRunner implementation.
-  void WakeTasks() override;
-
-  // No tasks will be processed after this is called, even if
-  // WakeTasks() is called.
-  void Stop();
-
- private:
-  void CheckAndRunTasks();
-
-  bool posted_wake_;
-  bool stopped_;
-
-  SEQUENCE_CHECKER(sequence_checker_);
-
-  base::WeakPtrFactory<TaskPump> weak_factory_{this};
-};
-
-}  // namespace jingle_glue
-
-#endif  // JINGLE_GLUE_TASK_PUMP_H_
diff --git a/jingle/glue/task_pump_unittest.cc b/jingle/glue/task_pump_unittest.cc
deleted file mode 100644
index 696a9b9..0000000
--- a/jingle/glue/task_pump_unittest.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "jingle/glue/task_pump.h"
-
-#include "base/run_loop.h"
-#include "base/test/task_environment.h"
-#include "jingle/glue/mock_task.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace jingle_glue {
-
-namespace {
-
-using ::testing::Return;
-
-class TaskPumpTest : public testing::Test {
- private:
-  base::test::SingleThreadTaskEnvironment task_environment_;
-};
-
-TEST_F(TaskPumpTest, Basic) {
-  TaskPump task_pump;
-  MockTask* task = new MockTask(&task_pump);
-  // We have to do this since the state enum is protected in
-  // rtc::Task.
-  const int TASK_STATE_DONE = 2;
-  EXPECT_CALL(*task, ProcessStart()).WillOnce(Return(TASK_STATE_DONE));
-  task->Start();
-
-  base::RunLoop().RunUntilIdle();
-}
-
-TEST_F(TaskPumpTest, Stop) {
-  TaskPump task_pump;
-  MockTask* task = new MockTask(&task_pump);
-  // We have to do this since the state enum is protected in
-  // rtc::Task.
-  const int TASK_STATE_ERROR = 3;
-  ON_CALL(*task, ProcessStart()).WillByDefault(Return(TASK_STATE_ERROR));
-  EXPECT_CALL(*task, ProcessStart()).Times(0);
-  task->Start();
-
-  task_pump.Stop();
-  base::RunLoop().RunUntilIdle();
-}
-
-}  // namespace
-
-}  // namespace jingle_glue
diff --git a/net/cookies/cookie_store_unittest.h b/net/cookies/cookie_store_unittest.h
index 7e155f4..a754d3a 100644
--- a/net/cookies/cookie_store_unittest.h
+++ b/net/cookies/cookie_store_unittest.h
@@ -221,9 +221,14 @@
       absl::optional<base::Time> server_time = absl::nullopt,
       absl::optional<base::Time> system_time = absl::nullopt,
       absl::optional<CookiePartitionKey> cookie_partition_key = absl::nullopt) {
-    auto cookie = CanonicalCookie::Create(
-        url, cookie_line, system_time.value_or(base::Time::Now()), server_time,
-        cookie_partition_key);
+    // Ensure a different Creation date to guarantee sort order for testing
+    static base::Time last = base::Time::Min();
+    last = base::Time::Now() == last ? last + base::Microseconds(1)
+                                     : base::Time::Now();
+
+    auto cookie =
+        CanonicalCookie::Create(url, cookie_line, system_time.value_or(last),
+                                server_time, cookie_partition_key);
 
     if (!cookie)
       return false;
diff --git a/net/http/http_proxy_connect_job.cc b/net/http/http_proxy_connect_job.cc
index 9172681..aa92b63 100644
--- a/net/http/http_proxy_connect_job.cc
+++ b/net/http/http_proxy_connect_job.cc
@@ -211,8 +211,7 @@
 
 LoadState HttpProxyConnectJob::GetLoadState() const {
   switch (next_state_) {
-    case STATE_TCP_CONNECT_COMPLETE:
-    case STATE_SSL_CONNECT_COMPLETE:
+    case STATE_TRANSPORT_CONNECT_COMPLETE:
       return nested_connect_job_->GetLoadState();
     case STATE_HTTP_PROXY_CONNECT:
     case STATE_HTTP_PROXY_CONNECT_COMPLETE:
@@ -224,10 +223,10 @@
     case STATE_RESTART_WITH_AUTH:
     case STATE_RESTART_WITH_AUTH_COMPLETE:
       return LOAD_STATE_ESTABLISHING_PROXY_TUNNEL;
-    // These states shouldn't be possible to be called in.
-    case STATE_TCP_CONNECT:
-    case STATE_SSL_CONNECT:
-
+    // This state shouldn't be possible to be called in.
+    case STATE_TRANSPORT_CONNECT:
+      NOTREACHED();
+      [[fallthrough]];
     case STATE_BEGIN_CONNECT:
     case STATE_NONE:
       // May be possible for this method to be called after an error, shouldn't
@@ -263,8 +262,7 @@
 
 void HttpProxyConnectJob::OnConnectJobComplete(int result, ConnectJob* job) {
   DCHECK_EQ(nested_connect_job_.get(), job);
-  DCHECK(next_state_ == STATE_TCP_CONNECT_COMPLETE ||
-         next_state_ == STATE_SSL_CONNECT_COMPLETE);
+  DCHECK_EQ(next_state_, STATE_TRANSPORT_CONNECT_COMPLETE);
   OnIOComplete(result);
 }
 
@@ -326,10 +324,7 @@
 int HttpProxyConnectJob::ConnectInternal() {
   DCHECK_EQ(next_state_, STATE_NONE);
   next_state_ = STATE_BEGIN_CONNECT;
-  int result = DoLoop(OK);
-  if (result != ERR_IO_PENDING)
-    HandleConnectResult(result);
-  return result;
+  return DoLoop(OK);
 }
 
 ProxyServer::Scheme HttpProxyConnectJob::GetProxyServerScheme() const {
@@ -345,8 +340,6 @@
 void HttpProxyConnectJob::OnIOComplete(int result) {
   int rv = DoLoop(result);
   if (rv != ERR_IO_PENDING) {
-    HandleConnectResult(rv);
-
     // May delete |this|.
     NotifyDelegateOfCompletion(rv);
   }
@@ -375,20 +368,13 @@
         DCHECK_EQ(OK, rv);
         rv = DoBeginConnect();
         break;
-      case STATE_TCP_CONNECT:
+      case STATE_TRANSPORT_CONNECT:
         DCHECK_EQ(OK, rv);
         rv = DoTransportConnect();
         break;
-      case STATE_TCP_CONNECT_COMPLETE:
+      case STATE_TRANSPORT_CONNECT_COMPLETE:
         rv = DoTransportConnectComplete(rv);
         break;
-      case STATE_SSL_CONNECT:
-        DCHECK_EQ(OK, rv);
-        rv = DoSSLConnect();
-        break;
-      case STATE_SSL_CONNECT_COMPLETE:
-        rv = DoSSLConnectComplete(rv);
-        break;
       case STATE_HTTP_PROXY_CONNECT:
         DCHECK_EQ(OK, rv);
         rv = DoHttpProxyConnect();
@@ -444,10 +430,8 @@
       has_established_connection_ = true;
       break;
     case ProxyServer::SCHEME_HTTP:
-      next_state_ = STATE_TCP_CONNECT;
-      break;
     case ProxyServer::SCHEME_HTTPS:
-      next_state_ = STATE_SSL_CONNECT;
+      next_state_ = STATE_TRANSPORT_CONNECT;
       break;
     default:
       NOTREACHED();
@@ -456,79 +440,74 @@
 }
 
 int HttpProxyConnectJob::DoTransportConnect() {
-  next_state_ = STATE_TCP_CONNECT_COMPLETE;
-  nested_connect_job_ = TransportConnectJob::CreateTransportConnectJob(
-      params_->transport_params(), priority(), socket_tag(),
-      common_connect_job_params(), this, &net_log());
+  ProxyServer::Scheme scheme = GetProxyServerScheme();
+  if (scheme == ProxyServer::SCHEME_HTTP) {
+    nested_connect_job_ = TransportConnectJob::CreateTransportConnectJob(
+        params_->transport_params(), priority(), socket_tag(),
+        common_connect_job_params(), this, &net_log());
+  } else {
+    DCHECK_EQ(scheme, ProxyServer::SCHEME_HTTPS);
+    DCHECK(params_->ssl_params());
+    // Skip making a new connection if we have an existing HTTP/2 session.
+    if (params_->tunnel() &&
+        common_connect_job_params()->spdy_session_pool->FindAvailableSession(
+            CreateSpdySessionKey(), /*enable_ip_based_pooling=*/false,
+            /*is_websocket=*/false, net_log())) {
+      using_spdy_ = true;
+      next_state_ = STATE_SPDY_PROXY_CREATE_STREAM;
+      return OK;
+    }
+
+    nested_connect_job_ = std::make_unique<SSLConnectJob>(
+        priority(), socket_tag(), common_connect_job_params(),
+        params_->ssl_params(), this, &net_log());
+  }
+
+  next_state_ = STATE_TRANSPORT_CONNECT_COMPLETE;
   return nested_connect_job_->Connect();
 }
 
 int HttpProxyConnectJob::DoTransportConnectComplete(int result) {
   resolve_error_info_ = nested_connect_job_->GetResolveErrorInfo();
+  ProxyServer::Scheme scheme = GetProxyServerScheme();
   if (result != OK) {
-    UMA_HISTOGRAM_MEDIUM_TIMES("Net.HttpProxy.ConnectLatency.Insecure.Error",
-                               base::TimeTicks::Now() - connect_start_time_);
-    return ERR_PROXY_CONNECTION_FAILED;
-  }
+    base::UmaHistogramMediumTimes(
+        scheme == ProxyServer::SCHEME_HTTP
+            ? "Net.HttpProxy.ConnectLatency.Insecure.Error"
+            : "Net.HttpProxy.ConnectLatency.Secure.Error",
+        base::TimeTicks::Now() - connect_start_time_);
 
-  has_established_connection_ = true;
-
-  next_state_ = STATE_HTTP_PROXY_CONNECT;
-  return result;
-}
-
-int HttpProxyConnectJob::DoSSLConnect() {
-  DCHECK(params_->ssl_params());
-  if (params_->tunnel()) {
-    if (common_connect_job_params()->spdy_session_pool->FindAvailableSession(
-            CreateSpdySessionKey(), /* enable_ip_based_pooling = */ false,
-            /* is_websocket = */ false, net_log())) {
-      using_spdy_ = true;
-      next_state_ = STATE_SPDY_PROXY_CREATE_STREAM;
-      return OK;
+    if (IsCertificateError(result)) {
+      DCHECK_EQ(ProxyServer::SCHEME_HTTPS, scheme);
+      // TODO(rch): allow the user to deal with proxy cert errors in the
+      // same way as server cert errors.
+      return ERR_PROXY_CERTIFICATE_INVALID;
     }
-  }
-  next_state_ = STATE_SSL_CONNECT_COMPLETE;
-  nested_connect_job_ = std::make_unique<SSLConnectJob>(
-      priority(), socket_tag(), common_connect_job_params(),
-      params_->ssl_params(), this, &net_log());
-  return nested_connect_job_->Connect();
-}
 
-int HttpProxyConnectJob::DoSSLConnectComplete(int result) {
-  resolve_error_info_ = nested_connect_job_->GetResolveErrorInfo();
-  if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
-    UMA_HISTOGRAM_MEDIUM_TIMES("Net.HttpProxy.ConnectLatency.Secure.Error",
-                               base::TimeTicks::Now() - connect_start_time_);
+    if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
+      DCHECK_EQ(ProxyServer::SCHEME_HTTPS, scheme);
+      ssl_cert_request_info_ = nested_connect_job_->GetCertRequestInfo();
+      DCHECK(ssl_cert_request_info_);
+      ssl_cert_request_info_->is_proxy = true;
+      return result;
+    }
 
-    ssl_cert_request_info_ = nested_connect_job_->GetCertRequestInfo();
-    DCHECK(ssl_cert_request_info_);
-    ssl_cert_request_info_->is_proxy = true;
-    return result;
-  }
-
-  if (IsCertificateError(result)) {
-    UMA_HISTOGRAM_MEDIUM_TIMES("Net.HttpProxy.ConnectLatency.Secure.Error",
-                               base::TimeTicks::Now() - connect_start_time_);
-    // TODO(rch): allow the user to deal with proxy cert errors in the
-    // same way as server cert errors.
-    return ERR_PROXY_CERTIFICATE_INVALID;
-  }
-  if (result < 0) {
-    UMA_HISTOGRAM_MEDIUM_TIMES("Net.HttpProxy.ConnectLatency.Secure.Error",
-                               base::TimeTicks::Now() - connect_start_time_);
     return ERR_PROXY_CONNECTION_FAILED;
   }
 
+  base::UmaHistogramMediumTimes(
+      scheme == ProxyServer::SCHEME_HTTP
+          ? "Net.HttpProxy.ConnectLatency.Insecure.Success"
+          : "Net.HttpProxy.ConnectLatency.Secure.Success",
+      base::TimeTicks::Now() - connect_start_time_);
+
   has_established_connection_ = true;
 
   negotiated_protocol_ = nested_connect_job_->socket()->GetNegotiatedProtocol();
   using_spdy_ = negotiated_protocol_ == kProtoHTTP2;
-
-  // Reset the timer to just the length of time allowed for HttpProxy handshake
-  // so that a fast SSL connection plus a slow HttpProxy failure doesn't take
-  // longer to timeout than it should.
-  ResetTimer(kHttpProxyConnectJobTunnelTimeout);
+  if (scheme != ProxyServer::SCHEME_HTTPS) {
+    DCHECK_EQ(negotiated_protocol_, kProtoUnknown);
+  }
 
   // TODO(rch): If we ever decide to implement a "trusted" SPDY proxy
   // (one that we speak SPDY over SSL to, but to which we send HTTPS
@@ -552,14 +531,6 @@
   // longer to timeout than it should.
   ResetTimer(kHttpProxyConnectJobTunnelTimeout);
 
-  if (params_->transport_params()) {
-    UMA_HISTOGRAM_MEDIUM_TIMES("Net.HttpProxy.ConnectLatency.Insecure.Success",
-                               base::TimeTicks::Now() - connect_start_time_);
-  } else {
-    UMA_HISTOGRAM_MEDIUM_TIMES("Net.HttpProxy.ConnectLatency.Secure.Success",
-                               base::TimeTicks::Now() - connect_start_time_);
-  }
-
   // Add a HttpProxy connection on top of the tcp socket.
   transport_socket_ = std::make_unique<HttpProxyClientSocket>(
       nested_connect_job_->PassSocket(), GetUserAgent(), params_->endpoint(),
@@ -586,11 +557,15 @@
 
   // In TLS 1.2 with False Start or TLS 1.3, alerts from the server rejecting
   // our client certificate are received at the first Read(), not Connect(), so
-  // the error mapping in DoSSLConnectComplete does not apply. Repeat the
+  // the error mapping in DoTransportConnectComplete does not apply. Repeat the
   // mapping here.
   if (result == ERR_BAD_SSL_CLIENT_AUTH_CERT)
     return ERR_PROXY_CONNECTION_FAILED;
 
+  if (result == OK) {
+    SetSocket(std::move(transport_socket_), /*dns_aliases=*/absl::nullopt);
+  }
+
   return result;
 }
 
@@ -667,8 +642,8 @@
   DCHECK(!common_connect_job_params()->quic_supported_versions->empty());
 
   // Reset the timer to just the length of time allowed for HttpProxy handshake
-  // so that a fast TCP connection plus a slow HttpProxy failure doesn't take
-  // longer to timeout than it should.
+  // so that a fast QUIC connection plus a slow tunnel setup doesn't take longer
+  // to timeout than it should.
   ResetTimer(kHttpProxyConnectJobTunnelTimeout);
 
   next_state_ = STATE_QUIC_PROXY_CREATE_STREAM;
@@ -801,21 +776,15 @@
 }
 
 void HttpProxyConnectJob::OnTimedOutInternal() {
-  if (next_state_ == STATE_TCP_CONNECT_COMPLETE) {
-    UMA_HISTOGRAM_MEDIUM_TIMES("Net.HttpProxy.ConnectLatency.Insecure.TimedOut",
-                               base::TimeTicks::Now() - connect_start_time_);
-  } else if (next_state_ == STATE_SSL_CONNECT_COMPLETE) {
-    UMA_HISTOGRAM_MEDIUM_TIMES("Net.HttpProxy.ConnectLatency.Secure.TimedOut",
-                               base::TimeTicks::Now() - connect_start_time_);
+  if (next_state_ == STATE_TRANSPORT_CONNECT_COMPLETE) {
+    base::UmaHistogramMediumTimes(
+        GetProxyServerScheme() == ProxyServer::SCHEME_HTTP
+            ? "Net.HttpProxy.ConnectLatency.Insecure.TimedOut"
+            : "Net.HttpProxy.ConnectLatency.Secure.TimedOut",
+        base::TimeTicks::Now() - connect_start_time_);
   }
 }
 
-int HttpProxyConnectJob::HandleConnectResult(int result) {
-  if (result == OK)
-    SetSocket(std::move(transport_socket_), absl::nullopt /* dns_aliases */);
-  return result;
-}
-
 void HttpProxyConnectJob::OnAuthChallenge() {
   // Stop timer while potentially waiting for user input.
   ResetTimer(base::TimeDelta());
diff --git a/net/http/http_proxy_connect_job.h b/net/http/http_proxy_connect_job.h
index b62d5be..732c28c 100644
--- a/net/http/http_proxy_connect_job.h
+++ b/net/http/http_proxy_connect_job.h
@@ -155,10 +155,8 @@
  private:
   enum State {
     STATE_BEGIN_CONNECT,
-    STATE_TCP_CONNECT,
-    STATE_TCP_CONNECT_COMPLETE,
-    STATE_SSL_CONNECT,
-    STATE_SSL_CONNECT_COMPLETE,
+    STATE_TRANSPORT_CONNECT,
+    STATE_TRANSPORT_CONNECT_COMPLETE,
     STATE_HTTP_PROXY_CONNECT,
     STATE_HTTP_PROXY_CONNECT_COMPLETE,
     STATE_SPDY_PROXY_CREATE_STREAM,
@@ -191,12 +189,9 @@
 
   // Determine if need to go through TCP or SSL path.
   int DoBeginConnect();
-  // Connecting to HTTP Proxy
+  // Connecting to HTTP or HTTPS Proxy
   int DoTransportConnect();
   int DoTransportConnectComplete(int result);
-  // Connecting to HTTPS Proxy
-  int DoSSLConnect();
-  int DoSSLConnectComplete(int result);
 
   int DoHttpProxyConnect();
   int DoHttpProxyConnectComplete(int result);
@@ -215,8 +210,6 @@
   void ChangePriorityInternal(RequestPriority priority) override;
   void OnTimedOutInternal() override;
 
-  int HandleConnectResult(int result);
-
   void OnAuthChallenge();
 
   const HostPortPair& GetDestination() const;
diff --git a/net/proxy_resolution/win/windows_system_proxy_resolution_request.cc b/net/proxy_resolution/win/windows_system_proxy_resolution_request.cc
index 5239354..ea50d9d 100644
--- a/net/proxy_resolution/win/windows_system_proxy_resolution_request.cc
+++ b/net/proxy_resolution/win/windows_system_proxy_resolution_request.cc
@@ -64,7 +64,7 @@
   DCHECK(!user_callback_.is_null());
   DCHECK(windows_system_proxy_resolver);
   proxy_resolution_request_ =
-      windows_system_proxy_resolver->GetProxyForUrl(url.spec(), this);
+      windows_system_proxy_resolver->GetProxyForUrl(url, this);
 }
 
 WindowsSystemProxyResolutionRequest::~WindowsSystemProxyResolutionRequest() {
@@ -120,4 +120,14 @@
   std::move(callback).Run(net_error);
 }
 
+WindowsSystemProxyResolver::Request*
+WindowsSystemProxyResolutionRequest::GetProxyResolutionRequestForTesting() {
+  return proxy_resolution_request_.get();
+}
+
+void WindowsSystemProxyResolutionRequest::
+    ResetProxyResolutionRequestForTesting() {
+  proxy_resolution_request_.reset();
+}
+
 }  // namespace net
diff --git a/net/proxy_resolution/win/windows_system_proxy_resolution_request.h b/net/proxy_resolution/win/windows_system_proxy_resolution_request.h
index f06c7945..8c76439 100644
--- a/net/proxy_resolution/win/windows_system_proxy_resolution_request.h
+++ b/net/proxy_resolution/win/windows_system_proxy_resolution_request.h
@@ -64,6 +64,9 @@
                                        WinHttpStatus winhttp_status,
                                        int windows_error);
 
+  WindowsSystemProxyResolver::Request* GetProxyResolutionRequestForTesting();
+  void ResetProxyResolutionRequestForTesting();
+
  private:
   // Cancels the callback from the resolver for a previously started proxy
   // resolution.
diff --git a/net/proxy_resolution/win/windows_system_proxy_resolution_service_unittest.cc b/net/proxy_resolution/win/windows_system_proxy_resolution_service_unittest.cc
index 424b1cf..6f0c896 100644
--- a/net/proxy_resolution/win/windows_system_proxy_resolution_service_unittest.cc
+++ b/net/proxy_resolution/win/windows_system_proxy_resolution_service_unittest.cc
@@ -79,7 +79,7 @@
   void set_windows_error(int windows_error) { windows_error_ = windows_error; }
 
   std::unique_ptr<Request> GetProxyForUrl(
-      const std::string& url,
+      const GURL& url,
       WindowsSystemProxyResolutionRequest* callback_target) override {
     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
     return std::make_unique<MockRequest>(callback_target, proxy_list_,
diff --git a/net/proxy_resolution/win/windows_system_proxy_resolver.h b/net/proxy_resolution/win/windows_system_proxy_resolver.h
index 2d23e9a..d958e50 100644
--- a/net/proxy_resolution/win/windows_system_proxy_resolver.h
+++ b/net/proxy_resolution/win/windows_system_proxy_resolver.h
@@ -10,6 +10,8 @@
 
 #include "net/base/net_export.h"
 
+class GURL;
+
 namespace net {
 
 class WindowsSystemProxyResolutionRequest;
@@ -35,10 +37,10 @@
       delete;
   virtual ~WindowsSystemProxyResolver() = default;
 
-  // Asynchronously finds a proxy for |url|. The |callback_target| will be
-  // provided with the proxy resolution result.
+  // Asynchronously finds a proxy for `url`. The `callback_target` must outlive
+  // `this`.
   virtual std::unique_ptr<Request> GetProxyForUrl(
-      const std::string& url,
+      const GURL& url,
       WindowsSystemProxyResolutionRequest* callback_target) = 0;
 };
 
diff --git a/net/socket/next_proto.cc b/net/socket/next_proto.cc
index a69400d..96ce80e0 100644
--- a/net/socket/next_proto.cc
+++ b/net/socket/next_proto.cc
@@ -7,13 +7,15 @@
 namespace net {
 
 NextProto NextProtoFromString(base::StringPiece proto_string) {
-  if (proto_string == "http1.1" || proto_string == "http/1.1")
+  if (proto_string == "http/1.1") {
     return kProtoHTTP11;
+  }
   if (proto_string == "h2") {
     return kProtoHTTP2;
   }
-  if (proto_string == "quic" || proto_string == "hq")
+  if (proto_string == "quic" || proto_string == "hq") {
     return kProtoQUIC;
+  }
 
   return kProtoUnknown;
 }
diff --git a/ppapi/proxy/dispatch_reply_message.h b/ppapi/proxy/dispatch_reply_message.h
index 2f4c53e..0555935 100644
--- a/ppapi/proxy/dispatch_reply_message.h
+++ b/ppapi/proxy/dispatch_reply_message.h
@@ -158,11 +158,11 @@
 // begin the map instead of IPC_BEGIN_MESSAGE_MAP. The reason is that the macros
 // in src/ipc are all closely tied together, and there might be errors for
 // unused variables or other errors if they're used with these macros.
-#define PPAPI_BEGIN_MESSAGE_MAP(class_name, msg) \
-  { \
-    typedef class_name _IpcMessageHandlerClass ALLOW_UNUSED_TYPE; \
-    const IPC::Message& ipc_message__ = msg; \
-    switch (ipc_message__.type()) { \
+#define PPAPI_BEGIN_MESSAGE_MAP(class_name, msg)                 \
+  {                                                              \
+    using _IpcMessageHandlerClass [[maybe_unused]] = class_name; \
+    const IPC::Message& ipc_message__ = msg;                     \
+    switch (ipc_message__.type()) {
 
 // Note that this only works for message with 1 or more parameters. For
 // 0-parameter messages you need to use the _0 version below (since there are
diff --git a/remoting/host/BUILD.gn b/remoting/host/BUILD.gn
index 1ee8030a..87a67ef7 100644
--- a/remoting/host/BUILD.gn
+++ b/remoting/host/BUILD.gn
@@ -724,6 +724,7 @@
     "//remoting/host/remote_open_url:unit_tests",
     "//remoting/host/security_key:unit_tests",
     "//remoting/host/setup:common",
+    "//remoting/host/webauthn:unit_tests",
     "//remoting/proto",
     "//remoting/proto/remoting/v1:remote_support_host_messages",
     "//remoting/protocol:test_support",
diff --git a/remoting/host/webauthn/BUILD.gn b/remoting/host/webauthn/BUILD.gn
index 946aaed..a5c424e 100644
--- a/remoting/host/webauthn/BUILD.gn
+++ b/remoting/host/webauthn/BUILD.gn
@@ -47,6 +47,27 @@
   ]
 }
 
+source_set("unit_tests") {
+  testonly = true
+
+  sources = [ "remote_webauthn_native_messaging_host_unittest.cc" ]
+
+  deps = [
+    ":webauthn",
+    "//base",
+    "//base/test:test_support",
+    "//extensions/browser/api/messaging:native_messaging",
+    "//mojo/public/cpp/bindings",
+    "//mojo/public/cpp/platform",
+    "//remoting/base",
+    "//remoting/host:test_support",
+    "//remoting/host/mojom",
+    "//remoting/host/native_messaging:native_messaging",
+    "//testing/gmock",
+    "//testing/gtest",
+  ]
+}
+
 executable("remote_webauthn") {
   sources = [ "remote_webauthn_entry_point.cc" ]
 
diff --git a/remoting/host/webauthn/remote_webauthn_native_messaging_host.cc b/remoting/host/webauthn/remote_webauthn_native_messaging_host.cc
index 483d6fe..b4eee0b 100644
--- a/remoting/host/webauthn/remote_webauthn_native_messaging_host.cc
+++ b/remoting/host/webauthn/remote_webauthn_native_messaging_host.cc
@@ -13,6 +13,7 @@
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/platform/named_platform_channel.h"
 #include "mojo/public/cpp/system/isolated_connection.h"
+#include "remoting/host/chromoting_host_services_client.h"
 #include "remoting/host/native_messaging/native_messaging_constants.h"
 #include "remoting/host/native_messaging/native_messaging_helpers.h"
 #include "remoting/host/webauthn/remote_webauthn_constants.h"
@@ -22,7 +23,15 @@
 
 RemoteWebAuthnNativeMessagingHost::RemoteWebAuthnNativeMessagingHost(
     scoped_refptr<base::SingleThreadTaskRunner> task_runner)
-    : task_runner_(task_runner) {}
+    : RemoteWebAuthnNativeMessagingHost(
+          std::make_unique<ChromotingHostServicesClient>(),
+          task_runner) {}
+
+RemoteWebAuthnNativeMessagingHost::RemoteWebAuthnNativeMessagingHost(
+    std::unique_ptr<ChromotingHostServicesProvider> host_service_api_client,
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner)
+    : task_runner_(task_runner),
+      host_service_api_client_(std::move(host_service_api_client)) {}
 
 RemoteWebAuthnNativeMessagingHost::~RemoteWebAuthnNativeMessagingHost() {
   DCHECK(task_runner_->BelongsToCurrentThread());
@@ -237,7 +246,7 @@
     return true;
   }
 
-  auto* api = host_service_api_client_.GetSessionServices();
+  auto* api = host_service_api_client_->GetSessionServices();
   if (!api) {
     return false;
   }
diff --git a/remoting/host/webauthn/remote_webauthn_native_messaging_host.h b/remoting/host/webauthn/remote_webauthn_native_messaging_host.h
index 1ddd0ff..b16cf37 100644
--- a/remoting/host/webauthn/remote_webauthn_native_messaging_host.h
+++ b/remoting/host/webauthn/remote_webauthn_native_messaging_host.h
@@ -12,8 +12,7 @@
 #include "base/values.h"
 #include "extensions/browser/api/messaging/native_message_host.h"
 #include "mojo/public/cpp/bindings/remote.h"
-#include "remoting/host/chromoting_host_services_client.h"
-#include "remoting/host/mojom/webauthn_proxy.mojom-forward.h"
+#include "remoting/host/chromoting_host_services_provider.h"
 #include "remoting/host/mojom/webauthn_proxy.mojom.h"
 
 namespace remoting {
@@ -36,6 +35,12 @@
   scoped_refptr<base::SingleThreadTaskRunner> task_runner() const override;
 
  private:
+  friend class RemoteWebAuthnNativeMessagingHostTest;
+
+  RemoteWebAuthnNativeMessagingHost(
+      std::unique_ptr<ChromotingHostServicesProvider> host_service_api_client,
+      scoped_refptr<base::SingleThreadTaskRunner> task_runner);
+
   void ProcessHello(base::Value response);
   void ProcessGetRemoteState(base::Value response);
   void ProcessIsUvpaa(const base::Value& request, base::Value response);
@@ -58,7 +63,7 @@
 
   scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
   raw_ptr<extensions::NativeMessageHost::Client> client_ = nullptr;
-  ChromotingHostServicesClient host_service_api_client_;
+  std::unique_ptr<ChromotingHostServicesProvider> host_service_api_client_;
   mojo::Remote<mojom::WebAuthnProxy> remote_;
 
   // Pending getRemoteStateResponses to be sent.
diff --git a/remoting/host/webauthn/remote_webauthn_native_messaging_host_unittest.cc b/remoting/host/webauthn/remote_webauthn_native_messaging_host_unittest.cc
new file mode 100644
index 0000000..505ae7cb
--- /dev/null
+++ b/remoting/host/webauthn/remote_webauthn_native_messaging_host_unittest.cc
@@ -0,0 +1,326 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <memory>
+
+#include "base/json/json_reader.h"
+#include "base/json/json_writer.h"
+#include "base/memory/ptr_util.h"
+#include "base/notreached.h"
+#include "base/run_loop.h"
+#include "base/test/gmock_callback_support.h"
+#include "base/test/task_environment.h"
+#include "base/values.h"
+#include "extensions/browser/api/messaging/native_message_host.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/receiver.h"
+#include "remoting/host/host_mock_objects.h"
+#include "remoting/host/mojom/webauthn_proxy.mojom.h"
+#include "remoting/host/native_messaging/native_messaging_constants.h"
+#include "remoting/host/webauthn/remote_webauthn_constants.h"
+#include "remoting/host/webauthn/remote_webauthn_native_messaging_host.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace remoting {
+
+namespace {
+
+using testing::_;
+using testing::Return;
+
+using IsUvpaaCallback =
+    mojom::WebAuthnProxy::IsUserVerifyingPlatformAuthenticatorAvailableCallback;
+
+base::Value CreateRequestMessage(const std::string& message_type,
+                                 int message_id = 1) {
+  base::Value request(base::Value::Type::DICTIONARY);
+  request.SetStringKey(kMessageType, message_type);
+  request.SetIntKey(kMessageId, message_id);
+  return request;
+}
+
+void VerifyResponseMessage(const base::Value& response,
+                           const std::string& request_message_type,
+                           int message_id = 1) {
+  ASSERT_EQ(*response.FindStringKey(kMessageType),
+            request_message_type + "Response");
+  ASSERT_EQ(*response.FindIntKey(kMessageId), message_id);
+}
+
+class MockWebAuthnProxy : public mojom::WebAuthnProxy {
+ public:
+  MOCK_METHOD(void,
+              IsUserVerifyingPlatformAuthenticatorAvailable,
+              (IsUserVerifyingPlatformAuthenticatorAvailableCallback),
+              (override));
+  MOCK_METHOD(void, Create, (const std::string&, CreateCallback), (override));
+};
+
+}  // namespace
+
+class RemoteWebAuthnNativeMessagingHostTest
+    : public testing::Test,
+      public extensions::NativeMessageHost::Client {
+ public:
+  RemoteWebAuthnNativeMessagingHostTest();
+  ~RemoteWebAuthnNativeMessagingHostTest() override;
+
+  void SetUp() override;
+
+  // extensions::NativeMessageHost::Client implementation.
+  void PostMessageFromNativeHost(const std::string& message) override;
+  void CloseChannel(const std::string& error_message) override;
+
+ protected:
+  // nullptr will be returned for the GetSessionServices() call if
+  // |should_return_valid_services| is false.
+  testing::Expectation ExpectGetSessionServices(
+      bool should_return_valid_services = true);
+
+  // Receiver will be immediately discarded if |should_bind_receiver| is false.
+  testing::Expectation ExpectBindWebAuthnProxy(
+      bool should_bind_receiver = true);
+
+  // Sends a message to the native messaging host.
+  void SendMessage(const base::Value& message);
+
+  // Blocks until a new message is received, then returns the message.
+  const base::Value& ReadMessage();
+
+  MockWebAuthnProxy webauthn_proxy_;
+  MockChromotingHostServicesProvider* api_provider_;
+  MockChromotingSessionServices api_;
+
+ private:
+  base::test::TaskEnvironment task_environment_{
+      base::test::TaskEnvironment::MainThreadType::IO};
+  std::unique_ptr<RemoteWebAuthnNativeMessagingHost> host_;
+  std::unique_ptr<base::RunLoop> response_run_loop_;
+  mojo::Receiver<mojom::WebAuthnProxy> webauthn_proxy_receiver_{
+      &webauthn_proxy_};
+  base::Value latest_message_;
+};
+
+RemoteWebAuthnNativeMessagingHostTest::RemoteWebAuthnNativeMessagingHostTest() {
+  auto api_provider = std::make_unique<MockChromotingHostServicesProvider>();
+  api_provider_ = api_provider.get();
+  host_ = base::WrapUnique(new RemoteWebAuthnNativeMessagingHost(
+      std::move(api_provider), task_environment_.GetMainThreadTaskRunner()));
+  response_run_loop_ = std::make_unique<base::RunLoop>();
+}
+
+RemoteWebAuthnNativeMessagingHostTest::
+    ~RemoteWebAuthnNativeMessagingHostTest() = default;
+
+void RemoteWebAuthnNativeMessagingHostTest::SetUp() {
+  host_->Start(/* client= */ this);
+}
+
+void RemoteWebAuthnNativeMessagingHostTest::PostMessageFromNativeHost(
+    const std::string& message) {
+  response_run_loop_->Quit();
+  auto message_json = base::JSONReader::Read(message);
+  ASSERT_TRUE(message_json.has_value());
+  latest_message_ = std::move(*message_json);
+}
+
+void RemoteWebAuthnNativeMessagingHostTest::CloseChannel(
+    const std::string& error_message) {
+  NOTREACHED();
+}
+
+testing::Expectation
+RemoteWebAuthnNativeMessagingHostTest::ExpectGetSessionServices(
+    bool should_return_valid_services) {
+  return EXPECT_CALL(*api_provider_, GetSessionServices())
+      .WillOnce(Return(should_return_valid_services ? &api_ : nullptr));
+}
+
+testing::Expectation
+RemoteWebAuthnNativeMessagingHostTest::ExpectBindWebAuthnProxy(
+    bool should_bind_receiver) {
+  if (should_bind_receiver) {
+    return EXPECT_CALL(api_, BindWebAuthnProxy(_))
+        .WillOnce(
+            [&](mojo::PendingReceiver<mojom::WebAuthnProxy> pending_receiver) {
+              webauthn_proxy_receiver_.Bind(std::move(pending_receiver));
+            });
+  }
+  // Receiver is immediately discarded.
+  return EXPECT_CALL(api_, BindWebAuthnProxy(_)).WillOnce(Return());
+}
+
+void RemoteWebAuthnNativeMessagingHostTest::SendMessage(
+    const base::Value& message) {
+  std::string serialized_message;
+  ASSERT_TRUE(base::JSONWriter::Write(message, &serialized_message));
+  host_->OnMessage(serialized_message);
+}
+
+const base::Value& RemoteWebAuthnNativeMessagingHostTest::ReadMessage() {
+  response_run_loop_->Run();
+  response_run_loop_ = std::make_unique<base::RunLoop>();
+  return latest_message_;
+}
+
+TEST_F(RemoteWebAuthnNativeMessagingHostTest, HelloRequest) {
+  SendMessage(CreateRequestMessage(kHelloMessage));
+
+  const base::Value& response = ReadMessage();
+  VerifyResponseMessage(response, kHelloMessage);
+}
+
+TEST_F(RemoteWebAuthnNativeMessagingHostTest,
+       GetRemoteState_FailedToGetSessionServices_NotRemoted) {
+  ExpectGetSessionServices(false);
+  SendMessage(CreateRequestMessage(kGetRemoteStateMessageType));
+
+  const base::Value& response = ReadMessage();
+  VerifyResponseMessage(response, kGetRemoteStateMessageType);
+  ASSERT_EQ(*response.FindBoolKey(kGetRemoteStateResponseIsRemotedKey), false);
+}
+
+TEST_F(RemoteWebAuthnNativeMessagingHostTest,
+       GetRemoteState_FailedToBindWebAuthnProxy_NotRemoted) {
+  ExpectGetSessionServices();
+  ExpectBindWebAuthnProxy(false);
+  SendMessage(CreateRequestMessage(kGetRemoteStateMessageType));
+
+  const base::Value& response = ReadMessage();
+  VerifyResponseMessage(response, kGetRemoteStateMessageType);
+  ASSERT_EQ(*response.FindBoolKey(kGetRemoteStateResponseIsRemotedKey), false);
+}
+
+TEST_F(RemoteWebAuthnNativeMessagingHostTest, GetRemoteState_Remoted) {
+  ExpectGetSessionServices();
+  ExpectBindWebAuthnProxy();
+  SendMessage(CreateRequestMessage(kGetRemoteStateMessageType));
+
+  const base::Value& response = ReadMessage();
+  VerifyResponseMessage(response, kGetRemoteStateMessageType);
+  ASSERT_EQ(*response.FindBoolKey(kGetRemoteStateResponseIsRemotedKey), true);
+}
+
+TEST_F(RemoteWebAuthnNativeMessagingHostTest, IsUvpaa) {
+  ExpectGetSessionServices();
+  ExpectBindWebAuthnProxy();
+  EXPECT_CALL(webauthn_proxy_, IsUserVerifyingPlatformAuthenticatorAvailable(_))
+      .WillOnce(base::test::RunOnceCallback<0>(true));
+  SendMessage(CreateRequestMessage(kIsUvpaaMessageType));
+
+  const base::Value& response = ReadMessage();
+  VerifyResponseMessage(response, kIsUvpaaMessageType);
+  ASSERT_EQ(*response.FindBoolKey(kIsUvpaaResponseIsAvailableKey), true);
+}
+
+TEST_F(RemoteWebAuthnNativeMessagingHostTest, ParallelIsUvpaaRequests) {
+  ExpectGetSessionServices();
+  ExpectBindWebAuthnProxy();
+  IsUvpaaCallback cb_1;
+  IsUvpaaCallback cb_2;
+  base::RunLoop both_requests_sent_run_loop;
+  EXPECT_CALL(webauthn_proxy_, IsUserVerifyingPlatformAuthenticatorAvailable(_))
+      .WillOnce([&](IsUvpaaCallback cb) { cb_1 = std::move(cb); })
+      .WillOnce([&](IsUvpaaCallback cb) {
+        cb_2 = std::move(cb);
+        both_requests_sent_run_loop.Quit();
+      });
+
+  SendMessage(CreateRequestMessage(kIsUvpaaMessageType, 1));
+  SendMessage(CreateRequestMessage(kIsUvpaaMessageType, 2));
+  both_requests_sent_run_loop.Run();
+  std::move(cb_2).Run(false);
+  base::Value response_2 = ReadMessage().Clone();
+  std::move(cb_1).Run(true);
+  base::Value response_1 = ReadMessage().Clone();
+
+  VerifyResponseMessage(response_1, kIsUvpaaMessageType, 1);
+  VerifyResponseMessage(response_2, kIsUvpaaMessageType, 2);
+  ASSERT_EQ(*response_1.FindBoolKey(kIsUvpaaResponseIsAvailableKey), true);
+  ASSERT_EQ(*response_2.FindBoolKey(kIsUvpaaResponseIsAvailableKey), false);
+}
+
+TEST_F(RemoteWebAuthnNativeMessagingHostTest, Create_MalformedRequest_Error) {
+  ExpectGetSessionServices();
+  ExpectBindWebAuthnProxy();
+
+  // Request message missing |requestData| field.
+  SendMessage(CreateRequestMessage(kCreateMessageType));
+
+  const base::Value& response = ReadMessage();
+
+  VerifyResponseMessage(response, kCreateMessageType);
+  ASSERT_EQ(response.FindStringKey(kCreateResponseDataKey), nullptr);
+  ASSERT_NE(response.FindStringKey(kCreateResponseErrorNameKey), nullptr);
+}
+
+TEST_F(RemoteWebAuthnNativeMessagingHostTest,
+       Create_IpcConnectionFailed_Error) {
+  ExpectGetSessionServices(false);
+  auto request = CreateRequestMessage(kCreateMessageType);
+  request.SetStringKey(kCreateRequestDataKey, "dummy");
+  SendMessage(std::move(request));
+
+  const base::Value& response = ReadMessage();
+
+  VerifyResponseMessage(response, kCreateMessageType);
+  ASSERT_EQ(response.FindStringKey(kCreateResponseDataKey), nullptr);
+  ASSERT_NE(response.FindStringKey(kCreateResponseErrorNameKey), nullptr);
+}
+
+TEST_F(RemoteWebAuthnNativeMessagingHostTest, Create_EmptyResponse) {
+  ExpectGetSessionServices();
+  ExpectBindWebAuthnProxy();
+  EXPECT_CALL(webauthn_proxy_, Create("dummy", _))
+      .WillOnce(base::test::RunOnceCallback<1>(nullptr));
+  auto request = CreateRequestMessage(kCreateMessageType);
+  request.SetStringKey(kCreateRequestDataKey, "dummy");
+  SendMessage(std::move(request));
+
+  const base::Value& response = ReadMessage();
+
+  VerifyResponseMessage(response, kCreateMessageType);
+  ASSERT_EQ(response.FindStringKey(kCreateResponseDataKey), nullptr);
+  ASSERT_EQ(response.FindStringKey(kCreateResponseErrorNameKey), nullptr);
+}
+
+TEST_F(RemoteWebAuthnNativeMessagingHostTest, Create_ErrorResponse) {
+  ExpectGetSessionServices();
+  ExpectBindWebAuthnProxy();
+  auto mojo_response =
+      mojom::WebAuthnCreateResponse::NewErrorName("NotSupportedError");
+  EXPECT_CALL(webauthn_proxy_, Create("dummy", _))
+      .WillOnce(base::test::RunOnceCallback<1>(std::move(mojo_response)));
+  auto request = CreateRequestMessage(kCreateMessageType);
+  request.SetStringKey(kCreateRequestDataKey, "dummy");
+  SendMessage(std::move(request));
+
+  const base::Value& response = ReadMessage();
+
+  VerifyResponseMessage(response, kCreateMessageType);
+  ASSERT_EQ(response.FindStringKey(kCreateResponseDataKey), nullptr);
+  ASSERT_EQ(*response.FindStringKey(kCreateResponseErrorNameKey),
+            "NotSupportedError");
+}
+
+TEST_F(RemoteWebAuthnNativeMessagingHostTest, Create_DataResponse) {
+  ExpectGetSessionServices();
+  ExpectBindWebAuthnProxy();
+  auto mojo_response =
+      mojom::WebAuthnCreateResponse::NewResponseData("dummy response");
+  EXPECT_CALL(webauthn_proxy_, Create("dummy", _))
+      .WillOnce(base::test::RunOnceCallback<1>(std::move(mojo_response)));
+  auto request = CreateRequestMessage(kCreateMessageType);
+  request.SetStringKey(kCreateRequestDataKey, "dummy");
+  SendMessage(std::move(request));
+
+  const base::Value& response = ReadMessage();
+
+  VerifyResponseMessage(response, kCreateMessageType);
+  ASSERT_EQ(*response.FindStringKey(kCreateResponseDataKey), "dummy response");
+  ASSERT_EQ(response.FindStringKey(kCreateResponseErrorNameKey), nullptr);
+}
+
+}  // namespace remoting
diff --git a/remoting/protocol/BUILD.gn b/remoting/protocol/BUILD.gn
index 858bae21..9c2160a9 100644
--- a/remoting/protocol/BUILD.gn
+++ b/remoting/protocol/BUILD.gn
@@ -228,7 +228,6 @@
     "//build:chromeos_buildflags",
     "//crypto",
     "//google_apis:google_apis",
-    "//jingle:jingle_glue",
     "//jingle:webrtc_glue",
     "//net",
     "//remoting/base",
diff --git a/services/network/BUILD.gn b/services/network/BUILD.gn
index 282d196..43206d22 100644
--- a/services/network/BUILD.gn
+++ b/services/network/BUILD.gn
@@ -229,6 +229,13 @@
     ]
   }
 
+  if (is_win) {
+    sources += [
+      "windows_system_proxy_resolver_mojo.cc",
+      "windows_system_proxy_resolver_mojo.h",
+    ]
+  }
+
   configs += [ "//build/config/compiler:wexit_time_destructors" ]
 
   deps = [
@@ -422,6 +429,10 @@
     ]
   }
 
+  if (is_win) {
+    sources += [ "windows_system_proxy_resolver_mojo_unittest.cc" ]
+  }
+
   deps = [
     ":network_service",
     ":test_support",
diff --git a/services/network/DEPS b/services/network/DEPS
index f9f941b..700959b9 100644
--- a/services/network/DEPS
+++ b/services/network/DEPS
@@ -18,6 +18,7 @@
   "+net",
   "+sandbox",
   "+services/proxy_resolver/public/mojom",
+  "+services/proxy_resolver_win/public/mojom",
   "+services/service_manager/public",
   "+third_party/boringssl/src/include",
   "+url",
diff --git a/services/network/network_context.cc b/services/network/network_context.cc
index 59a4a09..e120892 100644
--- a/services/network/network_context.cc
+++ b/services/network/network_context.cc
@@ -2257,7 +2257,8 @@
 
 #if BUILDFLAG(IS_WIN)
   if (params_->windows_system_proxy_resolver) {
-    // TODO(https://crbug.com/1032820): Connect to proxy_resolver_win service.
+    builder.SetMojoWindowsSystemProxyResolver(
+        std::move(params_->windows_system_proxy_resolver));
   }
 #endif
 
diff --git a/services/network/url_request_context_builder_mojo.cc b/services/network/url_request_context_builder_mojo.cc
index 0065adc..28c11d9 100644
--- a/services/network/url_request_context_builder_mojo.cc
+++ b/services/network/url_request_context_builder_mojo.cc
@@ -15,6 +15,8 @@
 #include "services/network/public/cpp/features.h"
 #if BUILDFLAG(IS_WIN)
 #include "net/proxy_resolution/win/dhcp_pac_file_fetcher_win.h"
+#include "net/proxy_resolution/win/windows_system_proxy_resolution_service.h"
+#include "services/network/windows_system_proxy_resolver_mojo.h"
 #elif BUILDFLAG(IS_CHROMEOS_ASH)
 #include "services/network/dhcp_pac_file_fetcher_mojo.h"
 #endif
@@ -31,6 +33,15 @@
   mojo_proxy_resolver_factory_ = std::move(mojo_proxy_resolver_factory);
 }
 
+#if defined(OS_WIN)
+void URLRequestContextBuilderMojo::SetMojoWindowsSystemProxyResolver(
+    mojo::PendingRemote<proxy_resolver_win::mojom::WindowsSystemProxyResolver>
+        mojo_windows_system_proxy_resolver) {
+  mojo_windows_system_proxy_resolver_ =
+      std::move(mojo_windows_system_proxy_resolver);
+}
+#endif
+
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 void URLRequestContextBuilderMojo::SetDhcpWpadUrlClient(
     mojo::PendingRemote<network::mojom::DhcpWpadUrlClient>
@@ -63,6 +74,21 @@
   DCHECK(url_request_context);
   DCHECK(host_resolver);
 
+#if defined(OS_WIN)
+  // TODO(crbug.com/1032820): Support both ProxyResolutionService
+  // implementations so that they can be swapped around at runtime based on
+  // proxy config.
+  if (mojo_windows_system_proxy_resolver_) {
+    std::unique_ptr<net::ProxyResolutionService> proxy_resolution_service =
+        net::WindowsSystemProxyResolutionService::Create(
+            std::make_unique<WindowsSystemProxyResolverMojo>(
+                std::move(mojo_windows_system_proxy_resolver_)),
+            net_log);
+    if (proxy_resolution_service)
+      return proxy_resolution_service;
+  }
+#endif
+
   if (mojo_proxy_resolver_factory_) {
     std::unique_ptr<net::DhcpPacFileFetcher> dhcp_pac_file_fetcher =
         CreateDhcpPacFileFetcher(url_request_context);
diff --git a/services/network/url_request_context_builder_mojo.h b/services/network/url_request_context_builder_mojo.h
index bf3b5cb..49f96b7 100644
--- a/services/network/url_request_context_builder_mojo.h
+++ b/services/network/url_request_context_builder_mojo.h
@@ -20,6 +20,10 @@
 #include "services/network/public/mojom/dhcp_wpad_url_client.mojom.h"
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
+#if defined(OS_WIN)
+#include "services/proxy_resolver_win/public/mojom/proxy_resolver_win.mojom.h"
+#endif
+
 namespace net {
 class DhcpPacFileFetcher;
 class HostResolver;
@@ -30,11 +34,16 @@
 }  // namespace net
 
 namespace network {
-// Specialization of URLRequestContextBuilder that can create a
-// ProxyResolutionService that uses a Mojo ProxyResolver. The consumer is
-// responsible for providing the proxy_resolver::mojom::ProxyResolverFactory.
-// If a ProxyResolutionService is set directly via the URLRequestContextBuilder
-// API, it will be used instead.
+// Specialization of URLRequestContextBuilder that can create one or more
+// ProxyResolutionServices that use Mojo. This can be a
+// ConfiguredProxyResolutionService that uses a Mojo ProxyResolver or a
+// WindowsSystemProxyResolutionService that may mojo all proxy resolutions to a
+// utility process if enabled. The consumer is responsible for providing either
+// the proxy_resolver::mojom::ProxyResolverFactory or
+// proxy_resolver_win::mojom::WindowsSystemProxyResolver respectively. If a
+// ProxyResolutionService is set directly via the URLRequestContextBuilder API,
+// it will be used instead either of the ProxyResolutionService implementations
+// mentioned here.
 class COMPONENT_EXPORT(NETWORK_SERVICE) URLRequestContextBuilderMojo
     : public net::URLRequestContextBuilder {
  public:
@@ -52,6 +61,12 @@
       mojo::PendingRemote<proxy_resolver::mojom::ProxyResolverFactory>
           mojo_proxy_resolver_factory);
 
+#if defined(OS_WIN)
+  void SetMojoWindowsSystemProxyResolver(
+      mojo::PendingRemote<proxy_resolver_win::mojom::WindowsSystemProxyResolver>
+          mojo_windows_system_proxy_resolver);
+#endif
+
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   void SetDhcpWpadUrlClient(
       mojo::PendingRemote<network::mojom::DhcpWpadUrlClient>
@@ -78,6 +93,11 @@
 
   mojo::PendingRemote<proxy_resolver::mojom::ProxyResolverFactory>
       mojo_proxy_resolver_factory_;
+
+#if defined(OS_WIN)
+  mojo::PendingRemote<proxy_resolver_win::mojom::WindowsSystemProxyResolver>
+      mojo_windows_system_proxy_resolver_;
+#endif
 };
 
 }  // namespace network
diff --git a/services/network/windows_system_proxy_resolver_mojo.cc b/services/network/windows_system_proxy_resolver_mojo.cc
new file mode 100644
index 0000000..1f8e79bc
--- /dev/null
+++ b/services/network/windows_system_proxy_resolver_mojo.cc
@@ -0,0 +1,86 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "services/network/windows_system_proxy_resolver_mojo.h"
+
+#include <utility>
+
+#include "base/bind.h"
+#include "base/memory/weak_ptr.h"
+#include "base/sequence_checker.h"
+#include "net/proxy_resolution/proxy_list.h"
+#include "net/proxy_resolution/win/windows_system_proxy_resolution_request.h"
+#include "net/proxy_resolution/win/winhttp_status.h"
+
+namespace network {
+
+class WindowsSystemProxyResolverMojo::RequestImpl final
+    : public net::WindowsSystemProxyResolver::Request {
+ public:
+  RequestImpl(WindowsSystemProxyResolverMojo* resolver,
+              const GURL& url,
+              net::WindowsSystemProxyResolutionRequest* callback_target);
+  RequestImpl(const RequestImpl&) = delete;
+  RequestImpl& operator=(const RequestImpl&) = delete;
+  ~RequestImpl() override;
+
+ private:
+  // Implements the callback for GetProxyForUrl()
+  void ReportResult(const net::ProxyList& proxy_list,
+                    net::WinHttpStatus winhttp_status,
+                    int windows_error);
+
+  // As described at WindowsSystemProxyResolutionRequest::GetProxyForUrl,
+  // `callback_target_` must outlive `this`.
+  net::WindowsSystemProxyResolutionRequest* callback_target_;
+
+  SEQUENCE_CHECKER(sequence_checker_);
+  base::WeakPtrFactory<WindowsSystemProxyResolverMojo::RequestImpl>
+      weak_ptr_factory_{this};
+};
+
+WindowsSystemProxyResolverMojo::RequestImpl::RequestImpl(
+    WindowsSystemProxyResolverMojo* resolver,
+    const GURL& url,
+    net::WindowsSystemProxyResolutionRequest* callback_target)
+    : callback_target_(callback_target) {
+  DCHECK(callback_target_);
+  resolver->mojo_windows_system_proxy_resolver_->GetProxyForUrl(
+      url,
+      base::BindOnce(&WindowsSystemProxyResolverMojo::RequestImpl::ReportResult,
+                     weak_ptr_factory_.GetWeakPtr()));
+}
+
+WindowsSystemProxyResolverMojo::RequestImpl::~RequestImpl() {
+  // This does not need to check if there is an ongoing proxy resolution.
+  // Destroying the RequestImpl is the intended way of "canceling" a proxy
+  // resolution.
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+}
+
+void WindowsSystemProxyResolverMojo::RequestImpl::ReportResult(
+    const net::ProxyList& proxy_list,
+    net::WinHttpStatus winhttp_status,
+    int windows_error) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  callback_target_->ProxyResolutionComplete(proxy_list, winhttp_status,
+                                            windows_error);
+}
+
+WindowsSystemProxyResolverMojo::WindowsSystemProxyResolverMojo(
+    mojo::PendingRemote<proxy_resolver_win::mojom::WindowsSystemProxyResolver>
+        mojo_windows_system_proxy_resolver)
+    : mojo_windows_system_proxy_resolver_(
+          std::move(mojo_windows_system_proxy_resolver)) {}
+
+WindowsSystemProxyResolverMojo::~WindowsSystemProxyResolverMojo() = default;
+
+std::unique_ptr<net::WindowsSystemProxyResolver::Request>
+WindowsSystemProxyResolverMojo::GetProxyForUrl(
+    const GURL& url,
+    net::WindowsSystemProxyResolutionRequest* callback_target) {
+  return std::make_unique<RequestImpl>(this, url, callback_target);
+}
+
+}  // namespace network
diff --git a/services/network/windows_system_proxy_resolver_mojo.h b/services/network/windows_system_proxy_resolver_mojo.h
new file mode 100644
index 0000000..cf7f424
--- /dev/null
+++ b/services/network/windows_system_proxy_resolver_mojo.h
@@ -0,0 +1,52 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SERVICES_NETWORK_WINDOWS_SYSTEM_PROXY_RESOLVER_MOJO_H_
+#define SERVICES_NETWORK_WINDOWS_SYSTEM_PROXY_RESOLVER_MOJO_H_
+
+#include <string>
+
+#include "base/component_export.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/remote.h"
+#include "net/proxy_resolution/win/windows_system_proxy_resolver.h"
+#include "services/proxy_resolver_win/public/mojom/proxy_resolver_win.mojom.h"
+#include "url/gurl.h"
+
+namespace net {
+class WindowsSystemProxyResolutionRequest;
+}  // namespace net
+
+namespace network {
+
+// This is the concrete implementation of net::WindowsSystemProxyResolver that
+// connects to a Mojo service to actually do proxy resolution. It contains no
+// business logic, only passing the request along to the service.
+class COMPONENT_EXPORT(NETWORK_SERVICE) WindowsSystemProxyResolverMojo final
+    : public net::WindowsSystemProxyResolver {
+ public:
+  explicit WindowsSystemProxyResolverMojo(
+      mojo::PendingRemote<proxy_resolver_win::mojom::WindowsSystemProxyResolver>
+          mojo_windows_system_proxy_resolver);
+  WindowsSystemProxyResolverMojo(const WindowsSystemProxyResolverMojo&) =
+      delete;
+  WindowsSystemProxyResolverMojo& operator=(
+      const WindowsSystemProxyResolverMojo&) = delete;
+  ~WindowsSystemProxyResolverMojo() override;
+
+  // net::WindowsSystemProxyResolver implementation
+  std::unique_ptr<net::WindowsSystemProxyResolver::Request> GetProxyForUrl(
+      const GURL& url,
+      net::WindowsSystemProxyResolutionRequest* callback_target) override;
+
+ private:
+  class RequestImpl;
+
+  mojo::Remote<proxy_resolver_win::mojom::WindowsSystemProxyResolver>
+      mojo_windows_system_proxy_resolver_;
+};
+
+}  // namespace network
+
+#endif  // SERVICES_NETWORK_WINDOWS_SYSTEM_PROXY_RESOLVER_MOJO_H_
diff --git a/services/network/windows_system_proxy_resolver_mojo_unittest.cc b/services/network/windows_system_proxy_resolver_mojo_unittest.cc
new file mode 100644
index 0000000..27b3bcc
--- /dev/null
+++ b/services/network/windows_system_proxy_resolver_mojo_unittest.cc
@@ -0,0 +1,121 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "services/network/windows_system_proxy_resolver_mojo.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "base/bind.h"
+#include "base/callback_helpers.h"
+#include "base/run_loop.h"
+#include "base/task/sequenced_task_runner.h"
+#include "base/task/task_runner.h"
+#include "base/test/task_environment.h"
+#include "base/threading/sequenced_task_runner_handle.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/remote.h"
+#include "mojo/public/cpp/bindings/self_owned_receiver.h"
+#include "net/log/net_log_with_source.h"
+#include "net/proxy_resolution/proxy_list.h"
+#include "net/proxy_resolution/win/windows_system_proxy_resolution_request.h"
+#include "net/proxy_resolution/win/winhttp_status.h"
+#include "services/proxy_resolver_win/public/mojom/proxy_resolver_win.mojom.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+namespace network {
+
+namespace {
+
+class MockWindowsSystemProxyResolver
+    : public proxy_resolver_win::mojom::WindowsSystemProxyResolver {
+ public:
+  MockWindowsSystemProxyResolver() = default;
+  ~MockWindowsSystemProxyResolver() override = default;
+
+  // proxy_resolver_win::mojom::WindowsSystemProxyResolver implementation:
+  void GetProxyForUrl(const GURL& url,
+                      GetProxyForUrlCallback callback) override {
+    // Simulate asynchronous nature of this call by posting a task to run the
+    // callback.
+    base::SequencedTaskRunnerHandle::Get()->PostTask(
+        FROM_HERE, base::BindOnce(std::move(callback), net::ProxyList(),
+                                  net::WinHttpStatus::kOk, 0));
+  }
+};
+
+class MockWindowsSystemProxyResolutionRequest
+    : public net::WindowsSystemProxyResolutionRequest {
+ public:
+  MockWindowsSystemProxyResolutionRequest(
+      net::WindowsSystemProxyResolver* resolver)
+      : net::WindowsSystemProxyResolutionRequest(nullptr,
+                                                 GURL(),
+                                                 std::string(),
+                                                 nullptr,
+                                                 base::DoNothing(),
+                                                 net::NetLogWithSource(),
+                                                 resolver) {
+    EXPECT_TRUE(GetProxyResolutionRequestForTesting());
+  }
+  ~MockWindowsSystemProxyResolutionRequest() override = default;
+
+  void WaitForProxyResolutionComplete() { loop_.Run(); }
+
+  void ProxyResolutionComplete(const net::ProxyList& proxy_list,
+                               net::WinHttpStatus winhttp_status,
+                               int windows_error) override {
+    EXPECT_TRUE(GetProxyResolutionRequestForTesting());
+    DeleteRequest();
+    loop_.Quit();
+  }
+
+  void DeleteRequest() { ResetProxyResolutionRequestForTesting(); }
+
+ private:
+  base::RunLoop loop_;
+};
+
+}  // namespace
+
+class WindowsSystemProxyResolverMojoTest : public testing::Test {
+ public:
+  void SetUp() override {
+    mojo::PendingRemote<proxy_resolver_win::mojom::WindowsSystemProxyResolver>
+        remote;
+    mojo::MakeSelfOwnedReceiver(
+        std::make_unique<MockWindowsSystemProxyResolver>(),
+        remote.InitWithNewPipeAndPassReceiver());
+    windows_system_proxy_resolver_mojo_ =
+        std::make_unique<WindowsSystemProxyResolverMojo>(std::move(remote));
+  }
+
+  net::WindowsSystemProxyResolver* proxy_resolver() {
+    return windows_system_proxy_resolver_mojo_.get();
+  }
+  void RunUntilIdle() { task_environment_.RunUntilIdle(); }
+
+ private:
+  base::test::TaskEnvironment task_environment_;
+  std::unique_ptr<net::WindowsSystemProxyResolver>
+      windows_system_proxy_resolver_mojo_;
+};
+
+TEST_F(WindowsSystemProxyResolverMojoTest, ProxyResolutionBasic) {
+  MockWindowsSystemProxyResolutionRequest request(proxy_resolver());
+  request.WaitForProxyResolutionComplete();
+}
+
+TEST_F(WindowsSystemProxyResolverMojoTest, ProxyResolutionCanceled) {
+  MockWindowsSystemProxyResolutionRequest request(proxy_resolver());
+  request.DeleteRequest();
+
+  // This shouldn't crash and there should never be a callback to
+  // ProxyResolutionComplete().
+  RunUntilIdle();
+}
+
+}  // namespace network
diff --git a/services/viz/public/mojom/compositing/region_capture_bounds.mojom b/services/viz/public/mojom/compositing/region_capture_bounds.mojom
index 8d9528f..63903db 100644
--- a/services/viz/public/mojom/compositing/region_capture_bounds.mojom
+++ b/services/viz/public/mojom/compositing/region_capture_bounds.mojom
@@ -21,13 +21,12 @@
   gfx.mojom.Rect bounds;
 };
 
+// https://w3c.github.io/mediacapture-region/
 // RegionCaptureBounds are used for passing in region capture crop ids mapped
 // to a gfx::Rect representing the region of the viewport that should be cropped
-// to for tab capture. Per the specification (draft) at:
-// https://eladalon1983.github.io/region-capture/, these crop identifiers are
-// GUIDs generated by calling the mediaDevices.produceCropId() API on HTML
-// elements.
-//   The crop ID and bounds are stored internally in Blink and are passed to and
+// to for tab capture. These crop identifiers are GUIDs generated by calling the
+// mediaDevices.produceCropId() API on HTML elements.
+// The crop ID and bounds are stored internally in Blink and are passed to and
 // tracked by the compositor/viz. If a previously-generated crop ID is selected
 // via mediaStreamTrack.cropTo(), the frame sink video capturer uses the crop
 // IDs associated with the compositor render passes to determine what section of
diff --git a/storage/browser/file_system/file_system_url.cc b/storage/browser/file_system/file_system_url.cc
index 9d961fc9..ec5efe4 100644
--- a/storage/browser/file_system/file_system_url.cc
+++ b/storage/browser/file_system/file_system_url.cc
@@ -12,6 +12,7 @@
 #include "storage/common/file_system/file_system_types.h"
 #include "storage/common/file_system/file_system_util.h"
 #include "third_party/blink/public/common/storage_key/storage_key.h"
+#include "url/gurl.h"
 #include "url/origin.h"
 
 namespace storage {
@@ -112,11 +113,12 @@
   if (!is_valid_)
     return GURL();
 
-  std::string url =
-      GetFileSystemRootURI(storage_key_.origin().GetURL(), mount_type_).spec();
-  if (url.empty())
+  GURL url = GetFileSystemRootURI(storage_key_.origin().GetURL(), mount_type_);
+  if (!url.is_valid())
     return GURL();
 
+  std::string url_string = url.spec();
+
   // Exactly match with DOMFileSystemBase::createFileSystemURL()'s encoding
   // behavior, where the path is escaped by KURL::encodeWithURLEscapeSequences
   // which is essentially encodeURIComponent except '/'.
@@ -124,10 +126,10 @@
       virtual_path_.NormalizePathSeparatorsTo('/').AsUTF8Unsafe(),
       false /* use_plus */);
   base::ReplaceSubstringsAfterOffset(&escaped, 0, "%2F", "/");
-  url.append(escaped);
+  url_string.append(escaped);
 
   // Build nested GURL.
-  return GURL(url);
+  return GURL(url_string);
 }
 
 std::string FileSystemURL::DebugString() const {
diff --git a/storage/browser/quota/client_usage_tracker.h b/storage/browser/quota/client_usage_tracker.h
index f2d72cc..4f084194 100644
--- a/storage/browser/quota/client_usage_tracker.h
+++ b/storage/browser/quota/client_usage_tracker.h
@@ -67,11 +67,21 @@
   void GetGlobalUsage(GlobalUsageCallback callback);
   void GetHostUsage(const std::string& host, UsageCallback callback);
   void UpdateUsageCache(const blink::StorageKey& storage_key, int64_t delta);
+
+  // Accumulates all cached usage to determine storage pressure.
   int64_t GetCachedUsage() const;
+
+  // Returns cached usage organized by host. Expected to be called after
+  // GetGlobalUsage which retrieves and caches host usage.
   std::map<std::string, int64_t> GetCachedHostsUsage() const;
+
+  // Returns cached usage organized by StorageKey. Used for histogram recording.
   std::map<blink::StorageKey, int64_t> GetCachedStorageKeysUsage() const;
   bool IsUsageCacheEnabledForStorageKey(
       const blink::StorageKey& storage_key) const;
+
+  // Sets if a `storage_key` for `client_` should / should not be excluded from
+  // quota restrictions.
   void SetUsageCacheEnabled(const blink::StorageKey& storage_key, bool enabled);
 
  private:
diff --git a/storage/browser/quota/usage_tracker.h b/storage/browser/quota/usage_tracker.h
index ca50a42..a5b5529 100644
--- a/storage/browser/quota/usage_tracker.h
+++ b/storage/browser/quota/usage_tracker.h
@@ -65,14 +65,28 @@
   void UpdateUsageCache(QuotaClientType client_type,
                         const blink::StorageKey& storage_key,
                         int64_t delta);
+
+  // Returns accumulated usage for all cached StorageKeys from registered
+  // ClientUsageTrackers. Used to determine storage pressure.
   int64_t GetCachedUsage() const;
+
+  // Retrieves all cached usage organized by host. Expected to be called after
+  // GetGlobalUsage which retrieves and caches host usage.
   std::map<std::string, int64_t> GetCachedHostsUsage() const;
+
+  // Returns all cached usage organized by StorageKey. Used for histogram
+  // recording.
   std::map<blink::StorageKey, int64_t> GetCachedStorageKeysUsage() const;
+
+  // Checks if there are ongoing tasks to get global or host usage. Used to
+  // prevent a UsageTracker reset from happening before a task is complete.
   bool IsWorking() const {
     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
     return !global_usage_callbacks_.empty() || !host_usage_callbacks_.empty();
   }
 
+  // Sets if a `storage_key` for `client_type` should / should not be excluded
+  // from quota restrictions.
   void SetUsageCacheEnabled(QuotaClientType client_type,
                             const blink::StorageKey& storage_key,
                             bool enabled);
diff --git a/styleguide/c++/c++-features.md b/styleguide/c++/c++-features.md
new file mode 100644
index 0000000..aeb4ac51
--- /dev/null
+++ b/styleguide/c++/c++-features.md
@@ -0,0 +1,1936 @@
+# Modern C++ use in Chromium
+
+_This document is part of the more general
+[Chromium C++ style guide](https://chromium.googlesource.com/chromium/src/+/main/styleguide/c++/c++.md).
+It summarizes the supported state of new and updated language and library
+features in recent C++ standards and the [Abseil](https://abseil.io/about/)
+library. This guide applies to both Chromium and its subprojects, though
+subprojects can choose to be more restrictive if necessary for toolchain
+support._
+
+The C++ language has in recent years received an updated standard every three
+years (C++11, C++14, etc.). For various reasons, Chromium does not immediately
+allow new features on the publication of such a standard. Instead, once
+toolchain support is sufficient, a standard is declared "initially supported",
+with new language/library features banned pending discussion.
+
+You can propose changing the status of a feature by sending an email to
+[cxx@chromium.org](https://groups.google.com/a/chromium.org/forum/#!forum/cxx).
+Include a short blurb on what the feature is and why you think it should or
+should not be allowed, along with links to any relevant previous discussion. If
+the list arrives at some consensus, send a codereview to change this file
+accordingly, linking to your discussion thread.
+
+If an item remains on the TBD list two years after initial support is added,
+style arbiters should explicitly move it to an appropriate allowlist or
+blocklist, allowing it if there are no obvious reasons to ban.
+
+The current status of existing standards and Abseil features is:
+
+*   **C++11:** _Default allowed; see banned features below_
+*   **C++14:** _Default allowed; see banned features below_
+*   **C++17:** Initially supported December 23, 2021; see allowed/banned/TBD
+    features below
+*   **C++20:** _Not yet supported in Chromium_
+*   **C++23:** _Not yet standardized_
+*   **Abseil:** Initially supported July 31, 2020; see allowed/banned/TBD
+    features below
+    *   absl::StatusOr: Initially supported September 3, 2020
+    *   absl::Cleanup: Initially supported February 4, 2021
+
+[TOC]
+
+## C++11 Banned Language Features {#core-blocklist-11}
+
+The following C++11 language features are not allowed in the Chromium codebase.
+
+### Inline Namespaces <sup>[banned]</sup>
+
+```c++
+inline namespace foo { ... }
+```
+
+**Description:** Allows better versioning of namespaces.
+
+**Documentation:**
+[Inline namespaces](https://en.cppreference.com/w/cpp/language/namespace#Inline_namespaces)
+
+**Notes:**
+*** promo
+Banned in the
+[Google Style Guide](https://google.github.io/styleguide/cppguide.html#Namespaces).
+Unclear how it will work with components.
+***
+
+### long long Type <sup>[banned]</sup>
+
+```c++
+long long var = value;
+```
+
+**Description:** An integer of at least 64 bits.
+
+**Documentation:**
+[Fundamental types](https://en.cppreference.com/w/cpp/language/types)
+
+**Notes:**
+*** promo
+Use a stdint.h type if you need a 64-bit number.
+[Discussion thread](https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/RxugZ-pIDxk)
+***
+
+### User-Defined Literals <sup>[banned]</sup>
+
+```c++
+type var = literal_value_type;
+```
+
+**Description:** Allows user-defined literal expressions.
+
+**Documentation:**
+[User-defined literals](https://en.cppreference.com/w/cpp/language/user_literal)
+
+**Notes:**
+*** promo
+Banned in the
+[Google Style Guide](https://google.github.io/styleguide/cppguide.html#Operator_Overloading).
+***
+
+### thread_local Storage Class <sup>[banned]</sup>
+
+```c++
+thread_local int foo = 1;
+```
+
+**Description:** Puts variables into thread local storage.
+
+**Documentation:**
+[Storage duration](https://en.cppreference.com/w/cpp/language/storage_duration)
+
+**Notes:**
+*** promo
+Some surprising effects on Mac
+([discussion](https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/2msN8k3Xzgs),
+[fork](https://groups.google.com/a/chromium.org/forum/#!topic/cxx/h7O5BdtWCZw)).
+Use `base::SequenceLocalStorageSlot` for sequence support, and
+`base::ThreadLocal`/`base::ThreadLocalStorage` otherwise.
+***
+
+## C++11 Banned Library Features {#library-blocklist-11}
+
+The following C++11 library features are not allowed in the Chromium codebase.
+
+### Bind Operations <sup>[banned]</sup>
+
+```c++
+std::bind(function, args, ...)
+```
+
+**Description:** Declares a function object bound to certain arguments
+
+**Documentation:**
+[std::bind](https://en.cppreference.com/w/cpp/utility/functional/bind)
+
+**Notes:**
+*** promo
+Use `base::Bind` instead. Compared to `std::bind`, `base::Bind` helps prevent
+lifetime issues by preventing binding of capturing lambdas and by forcing
+callers to declare raw pointers as `Unretained`.
+[Discussion thread](https://groups.google.com/a/chromium.org/forum/#!topic/cxx/SoEj7oIDNuA)
+***
+
+### C Floating-Point Environment <sup>[banned]</sup>
+
+```c++
+#include <cfenv>
+#include <fenv.h>
+```
+
+**Description:** Provides floating point status flags and control modes for
+C-compatible code
+
+**Documentation:**
+[Standard library header "cfenv"](https://en.cppreference.com/w/cpp/header/cfenv)
+
+**Notes:**
+*** promo
+Banned by the
+[Google Style Guide](https://google.github.io/styleguide/cppguide.html#C++11)
+due to concerns about compiler support.
+***
+
+### Date and time utilities <sup>[banned]</sup>
+
+```c++
+#include <chrono>
+```
+
+**Description:** A standard date and time library
+
+**Documentation:**
+[Date and time utilities](https://en.cppreference.com/w/cpp/chrono)
+
+**Notes:**
+*** promo
+Overlaps with `Time` APIs in `base/`. Keep using the `base/` classes.
+***
+
+### Exceptions <sup>[banned]</sup>
+
+```c++
+#include <exception>
+```
+
+**Description:** Enhancements to exception throwing and handling
+
+**Documentation:**
+[Standard library header "exception"](https://en.cppreference.com/w/cpp/header/exception)
+
+**Notes:**
+*** promo
+Exceptions are banned by the
+[Google Style Guide](https://google.github.io/styleguide/cppguide.html#Exceptions)
+and disabled in Chromium compiles. However, the `noexcept` specifier is
+explicitly allowed.
+[Discussion thread](https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/8i4tMqNpHhg)
+***
+
+### Function Objects <sup>[banned]</sup>
+
+```c++
+std::function
+```
+
+**Description:** Wraps a standard polymorphic function
+
+**Documentation:**
+[std::function](https://en.cppreference.com/w/cpp/utility/functional/function)
+
+**Notes:**
+*** promo
+Use `base::{Once,Repeating}Callback` instead. Compared to `std::function`,
+`base::{Once,Repeating}Callback` directly supports Chromium's refcounting
+classes and weak pointers and deals with additional thread safety concerns.
+[Discussion thread](https://groups.google.com/a/chromium.org/forum/#!topic/cxx/SoEj7oIDNuA)
+***
+
+### Random Number Engines <sup>[banned]</sup>
+
+*** aside
+The random number engines defined in `<random>` (see separate item for random
+number distributions), e.g.: `linear_congruential_engine`,
+`mersenne_twister_engine`, `minstd_rand0`, `mt19937`, `ranlinux48`,
+`random_device`
+***
+
+**Description:** Random number generation algorithms and utilities.
+
+**Documentation:**
+[Pseudo-random number generation](https://en.cppreference.com/w/cpp/numeric/random)
+
+**Notes:**
+*** promo
+Do not use any random number engines from `<random>`. Instead, use
+`base::RandomBitGenerator`.
+[Discussion thread](https://groups.google.com/a/chromium.org/forum/#!topic/cxx/16Xmw05C-Y0)
+***
+
+### Ratio Template Class <sup>[banned]</sup>
+
+```c++
+std::ratio<numerator, denominator>
+```
+
+**Description:** Provides compile-time rational numbers
+
+**Documentation:**
+[std::ratio](https://en.cppreference.com/w/cpp/numeric/ratio/ratio)
+
+**Notes:**
+*** promo
+Banned by the
+[Google Style Guide](https://google.github.io/styleguide/cppguide.html#C++11)
+due to concerns that this is tied to a more template-heavy interface style.
+***
+
+### Regular Expressions <sup>[banned]</sup>
+
+```c++
+#include <regex>
+```
+
+**Description:** A standard regular expressions library
+
+**Documentation:**
+[Regular expressions library](https://en.cppreference.com/w/cpp/regex)
+
+**Notes:**
+*** promo
+Overlaps with many regular expression libraries in Chromium. When in doubt, use
+`re2`.
+***
+
+### Shared Pointers <sup>[banned]</sup>
+
+```c++
+std::shared_ptr
+```
+
+**Description:** Allows shared ownership of a pointer through reference counts
+
+**Documentation:**
+[std::shared_ptr](https://en.cppreference.com/w/cpp/memory/shared_ptr)
+
+**Notes:**
+*** promo
+Needs a lot more evaluation for Chromium, and there isn't enough of a push for
+this feature.
+
+*   [Google Style Guide](https://google.github.io/styleguide/cppguide.html#Ownership_and_Smart_Pointers).
+*   [Discussion Thread](https://groups.google.com/a/chromium.org/forum/#!topic/cxx/aT2wsBLKvzI)
+***
+
+### String-Number Conversion Functions <sup>[banned]</sup>
+
+```c++
+std::stoi()
+std::stol()
+std::stoul()
+std::stoll
+std::stoull()
+std::stof()
+std::stod()
+std::stold()
+std::to_string()
+```
+
+**Description:** Converts strings to/from numbers
+
+**Documentation:**
+*   [std::stoi, std::stol, std::stoll](https://en.cppreference.com/w/cpp/string/basic_string/stol),
+*   [std::stoul, std::stoull](https://en.cppreference.com/w/cpp/string/basic_string/stoul),
+*   [std::stof, std::stod, std::stold](https://en.cppreference.com/w/cpp/string/basic_string/stof),
+*   [std::to_string](https://en.cppreference.com/w/cpp/string/basic_string/to_string)
+
+**Notes:**
+*** promo
+The string-to-number conversions rely on exceptions to communicate failure,
+while the number-to-string conversions have performance concerns and depend on
+the locale. Use the routines in `base/strings/string_number_conversions.h`
+instead.
+***
+
+### Thread Library <sup>[banned]</sup>
+
+*** aside
+`<thread>` and related headers, including `<future>`, `<mutex>`,
+`<condition_variable>`
+***
+
+**Description:** Provides a standard multithreading library using `std::thread`
+and associates
+
+**Documentation:**
+[Thread support library](https://en.cppreference.com/w/cpp/thread)
+
+**Notes:**
+*** promo
+Overlaps with many classes in `base/`. Keep using the `base/` classes for now.
+`base::Thread` is tightly coupled to `MessageLoop` which would make it hard to
+replace. We should investigate using standard mutexes, or unique_lock, etc. to
+replace our locking/synchronization classes.
+***
+
+### Weak Pointers <sup>[banned]</sup>
+
+```c++
+std::weak_ptr
+```
+
+**Description:** Allows a weak reference to a `std::shared_ptr`
+
+**Documentation:**
+[std::weak_ptr](https://en.cppreference.com/w/cpp/memory/weak_ptr)
+
+**Notes:**
+*** promo
+Banned because `std::shared_ptr` is banned.  Use `base::WeakPtr` instead.
+***
+
+## C++14 Banned Library Features {#library-blocklist-14}
+
+The following C++14 library features are not allowed in the Chromium codebase.
+
+### std::chrono literals <sup>[banned]</sup>
+
+```c++
+using namespace std::chrono_literals;
+auto timeout = 30s;
+```
+
+**Description:** Allows `std::chrono` types to be more easily constructed.
+
+**Documentation:**
+[std::literals::chrono_literals::operator""s](https://en.cppreference.com/w/cpp/chrono/operator%22%22s)
+
+**Notes:**
+*** promo
+Banned because `<chrono>` is banned.
+***
+
+## C++17 Allowed Language Features {#core-allowlist-17}
+
+The following C++17 language features are allowed in the Chromium codebase.
+
+### Nested namespaces <sup>[allowed]</sup>
+
+```c++
+namespace A::B::C { ...
+```
+
+**Description:** Using the namespace resolution operator to create nested
+namespace definitions.
+
+**Documentation:**
+[Namespaces](https://en.cppreference.com/w/cpp/language/namespace)
+
+**Notes:**
+*** promo
+[Discussion thread](https://groups.google.com/a/chromium.org/g/cxx/c/gLdR3apDSmg/)
+***
+
+### Template argument deduction for class templates <sup>[allowed]</sup>
+
+```c++
+template <typename T>
+struct MyContainer {
+  MyContainer(T val) : val{val} {}
+  // ...
+};
+MyContainer c1(1);  // Type deduced to be `int`.
+```
+
+**Description:** Automatic template argument deduction much like how it's done
+for functions, but now including class constructors.
+
+**Documentation:**
+[Class template argument deduction](https://en.cppreference.com/w/cpp/language/class_template_argument_deduction)
+
+**Notes:**
+*** promo
+Usage is governed by the
+[Google Style Guide](https://google.github.io/styleguide/cppguide.html#CTAD).
+***
+
+### Selection statements with initializer <sup>[allowed]</sup>
+
+```c++
+if (int a = Func(); a < 3) { ...
+switch (int a = Func(); a) { ...
+```
+
+**Description:** New versions of the if and switch statements which simplify
+common code patterns and help users keep scopes tight.
+
+**Documentation:**
+[if statement](https://en.cppreference.com/w/cpp/language/if),
+[switch statement](https://en.cppreference.com/w/cpp/language/switch)
+
+**Notes:**
+*** promo
+[@cxx discussion thread](https://groups.google.com/a/chromium.org/g/cxx/c/4GP43nftePE)
+***
+
+### fallthrough attribute <sup>[allowed]</sup>
+
+```c++
+case 1:
+  DoSomething();
+  [[fallthrough]];
+case 2:
+  break;
+```
+
+**Description:**
+The `[[fallthrough]]` attribute can be used in switch statements to indicate
+when intentionally falling through to the next case.
+
+**Documentation:**
+[C++ attribute: fallthrough](https://en.cppreference.com/w/cpp/language/attributes/fallthrough)
+
+**Notes:**
+*** promo
+See [discussion thread](https://groups.google.com/a/chromium.org/g/cxx/c/JrvyFd243QI).
+
+See [migration task](https://bugs.chromium.org/p/chromium/issues/detail?id=1283907).
+***
+
+### constexpr if <sup>[allowed]</sup>
+
+```c++
+if constexpr (cond) { ...
+```
+
+**Description:** Write code that is instantiated depending on a compile-time
+condition.
+
+**Documentation:**
+[if statement](https://en.cppreference.com/w/cpp/language/if)
+
+**Notes:**
+*** promo
+See [discussion thread](https://groups.google.com/a/chromium.org/g/cxx/c/op2ePZnjP0w).
+***
+
+### nodiscard attribute <sup>[allowed]</sup>
+
+```c++
+struct [[nodiscard]] ErrorOrValue;
+[[nodiscard]] bool DoSomething();
+```
+
+**Description:**
+The `[[nodiscard]]` attribute can be used to indicate that
+
+  - the return value of a function should not be ignored
+  - values of annotated classes/structs/enums returned from functions should not
+    be ignored
+
+**Documentation:**
+[C++ attribute: nodiscard](https://en.cppreference.com/w/cpp/language/attributes/nodiscard)
+
+**Notes:**
+*** promo
+[Discussion thread](https://groups.google.com/a/chromium.org/g/cxx/c/nH7Ar8pZ1Dw/m/c90vGChvAAAJ)
+***
+
+### maybe_unused attribute <sup>[allowed]</sup>
+
+```c++
+struct [[maybe_unused]] MyUnusedThing;
+[[maybe_unused]] int x;
+```
+
+**Description:**
+The `[[maybe_unused]]` attribute can be used to indicate that individual
+variables, functions, or fields of a class/struct/enum can be left unused.
+
+**Documentation:**
+[C++ attribute: maybe_unused](https://en.cppreference.com/w/cpp/language/attributes/maybe_unused)
+
+**Notes:**
+*** promo
+See [discussion thread](https://groups.google.com/a/chromium.org/g/cxx/c/jPLfU5eRg8M/).
+***
+
+### Structured bindings <sup>[allowed]</sup>
+
+```c++
+const auto [x, y] = FuncReturningStdPair();
+```
+
+**Description:** Allows writing `auto [x, y, z] = expr;` where the type of
+`expr` is a tuple-like object, whose elements are bound to the variables `x`,
+`y`, and `z` (which this construct declares). Tuple-like objects include
+`std::tuple`, `std::pair`, `std::array`, and aggregate structures.
+
+**Documentation:**
+[Structured binding declaration](https://en.cppreference.com/w/cpp/language/structured_binding)
+[Explanation of structured binding types](https://jguegant.github.io/blogs/tech/structured-bindings.html)
+
+**Notes:**
+*** promo
+In C++17, structured bindings don't work with lambda captures.
+[C++20 will allow capturing structured bindings by value](https://wg21.link/p1091r3).
+
+This feature forces omitting type names. Its use should follow
+[the guidance around `auto` in Google C++ Style guide](https://google.github.io/styleguide/cppguide.html#Type_deduction).
+
+See [discussion thread](https://groups.google.com/a/chromium.org/g/cxx/c/ExfSorNLNf4).
+***
+
+### Inline variables
+
+```c++
+struct S {
+  static constexpr int kZero = 0;  // constexpr implies inline here.
+};
+
+constexpr inline int kOne = 1;  // Explicit inline needed here.
+```
+
+**Description:** The `inline` specifier can be applied to variables as well as
+to functions. A variable declared inline has the same semantics as a function
+declared inline. It can also be used to declare and define a static member
+variable, such that it does not need to be initialized in the source file.
+
+**Documentation:**
+[inline specifier](https://en.cppreference.com/w/cpp/language/inline)
+
+**Notes:**
+*** promo
+Inline variables in anonymous namespaces in header files will still get one copy
+per translation unit, so they must be outside of an anonymous namespace to be
+effective.
+
+Mutable inline variables and taking the address of inline variables are banned
+since these will break the component build.
+
+See [discussion thread](https://groups.google.com/a/chromium.org/g/cxx/c/hmyGFD80ocE/m/O4AXC93vAQAJ).
+***
+
+## C++17 Allowed Library Features {#library-allowlist-17}
+
+The following C++17 language features are allowed in the Chromium codebase.
+
+### Allocation functions with explicit alignment <sup>[allowed]</sup>
+
+```c++
+class alignas(32) Vec3d {
+  double x, y, z;
+};
+auto p_vec = new Vec3d[10];  // 32-byte aligned in C++17, maybe not previously
+```
+
+**Description:** Performs heap allocation of objects whose alignment
+requirements exceed `__STDCPP_DEFAULT_NEW_ALIGNMENT__`.
+
+**Documentation:**
+[operator new](https://en.cppreference.com/w/cpp/memory/new/operator_new)
+
+**Notes:**
+*** promo
+None
+***
+
+### Type trait variable templates <sup>[tbd]</sup>
+
+```c++
+bool b = std::is_same_v<int, std::int32_t>;
+```
+
+**Description:** Syntactic sugar to provide convenient access to `::value`
+members by simply adding `_v`.
+
+**Documentation:**
+[Type support](https://en.cppreference.com/w/cpp/types)
+
+**Notes:**
+*** promo
+[Discussion thread](Non://groups.google.com/a/chromium.org/g/cxx/c/KEa-0AOGRNY/m/IV_S3_pvAAAJ)
+***
+
+### std::map::try_emplace <sup>[allowed]</sup>
+
+```c++
+std::map<std::string, std::string> m;
+m.try_emplace("c", 10, 'c');
+m.try_emplace("c", "Won't be inserted");
+```
+
+**Description:** Like `emplace`, but does not move from rvalue arguments if the
+insertion does not happen.
+
+**Documentation:**
+[std::map::try_emplace](https://en.cppreference.com/w/cpp/container/map/try_emplace),
+
+**Notes:**
+*** promo
+[Discussion thread](https://groups.google.com/a/chromium.org/g/cxx/c/Uv2tUfIwUfQ/m/ffMxCk9uAAAJ)
+***
+
+### std::map::insert_or_assign <sup>[allowed]</sup>
+
+```c++
+std::map<std::string, std::string> m;
+m.insert_or_assign("c", "cherry");
+m.insert_or_assign("c", "clementine");
+```
+
+**Description:** Like `operator[]`, but returns more information and does not
+require default-constructibility of the mapped type.
+
+**Documentation:**
+[std::map::insert_or_assign](https://en.cppreference.com/w/cpp/container/map/insert_or_assign)
+
+**Notes:**
+*** promo
+[Discussion thread](https://groups.google.com/a/chromium.org/g/cxx/c/Uv2tUfIwUfQ/m/ffMxCk9uAAAJ)
+***
+
+## C++17 Banned Library Features {#library-blocklist-17}
+
+The following C++17 library features are not allowed in the Chromium codebase.
+
+### std::any <sup>[banned]</sup>
+
+```c++
+std::any x = 5;
+```
+
+**Description:** A type-safe container for single values of any type.
+
+**Documentation:**
+[std::any](https://en.cppreference.com/w/cpp/utility/any)
+
+**Notes:**
+*** promo
+[Discussion thread](https://groups.google.com/a/chromium.org/g/cxx/c/KEa-0AOGRNY/m/IV_S3_pvAAAJ)
+
+Banned since workaround for lack of RTTI isn't compatible with the component
+build ([Bug](https://crbug.com/1096380)). Also see `absl::any`.
+***
+
+### std::filesystem <sup>[banned]</sup>
+
+```c++
+#include <filesystem>
+```
+
+**Description:** A standard way to manipulate files, directories, and paths in a
+filesystem.
+
+**Documentation:**
+[Filesystem library](https://en.cppreference.com/w/cpp/filesystem)
+
+**Notes:**
+*** promo
+Banned by the [Google Style Guide](https://google.github.io/styleguide/cppguide.html#Other_Features).
+***
+
+### weak_from_this <sup>[banned]</sup>
+
+```c++
+auto weak_ptr = weak_from_this();
+```
+
+**Description:** Returns a `std::weak_ptr<T>` that tracks ownership of `*this`
+by all existing `std::shared_ptr`s that refer to `*this`.
+
+**Documentation:**
+[std::enable_shared_from_this<T>::weak_from_this](https://en.cppreference.com/w/cpp/memory/enable_shared_from_this/weak_from_this)
+
+**Notes:**
+*** promo
+Banned since `std::shared_ptr` and `std::weak_ptr` are banned.
+***
+
+### Transparent std::owner_less <sup>[banned]</sup>
+
+```c++
+std::map<std::weak_ptr<T>, U, std::owner_less<>>
+```
+
+**Description:** Function object providing mixed-type owner-based ordering of
+shared and weak pointers, regardless of the type of the pointee.
+
+**Documentation:**
+[std::owner_less](https://en.cppreference.com/w/cpp/memory/owner_less)
+
+**Notes:**
+*** promo
+Banned since `std::shared_ptr` and `std::weak_ptr` are banned.
+***
+
+### Array support for std::shared_ptr <sup>[banned]</sup>
+
+```c++
+std::shared_ptr<int[]> p(new int[10]{0,1,2,3,4,5,6,7,8,9});
+std::cout << p[3];  // "3"
+```
+
+**Description:** Supports memory management of arrays via `std::shared_ptr`.
+
+**Documentation:**
+[std::shared_ptr](https://en.cppreference.com/w/cpp/memory/shared_ptr)
+
+**Notes:**
+*** promo
+Banned since `std::shared_ptr` is banned.
+***
+
+### std::uncaught_exceptions <sup>[banned]</sup>
+
+```c++
+int count = std::uncaught_exceptions();
+```
+
+**Description:** Determines whether there are live exception objects.
+
+**Documentation:**
+[std::uncaught_exceptions](https://en.cppreference.com/w/cpp/error/uncaught_exception)
+
+**Notes:**
+*** promo
+Banned because exceptions are banned.
+***
+
+### Rounding functions for duration and time_point <sup>[banned]</sup>
+
+```c++
+std::chrono::ceil<std::chrono::seconds>(dur);
+std::chrono::ceil<std::chrono::seconds>(time_pt);
+std::chrono::floor<std::chrono::seconds>(dur);
+std::chrono::floor<std::chrono::seconds>(time_pt);
+std::chrono::round<std::chrono::seconds>(dur);
+std::chrono::round<std::chrono::seconds>(time_pt);
+```
+
+**Description:** Converts durations and time_points by rounding.
+
+**Documentation:**
+[std::chrono::duration](https://en.cppreference.com/w/cpp/chrono/duration),
+[std::chrono::time_point](https://en.cppreference.com/w/cpp/chrono/time_point)
+
+**Notes:**
+*** promo
+Banned since `std::chrono` is banned.
+***
+
+## C++17 TBD Language Features {#core-review-17}
+
+The following C++17 language features are not allowed in the Chromium codebase.
+See the top of this page on how to propose moving a feature from this list into
+the allowed or banned sections.
+
+### Declaring non-type template parameters with auto <sup>[tbd]</sup>
+
+```c++
+template <auto... seq>
+struct my_integer_sequence {
+  // ...
+};
+auto seq = my_integer_sequence<0, 1, 2>();  // Type deduced to be `int`.
+```
+
+**Description:** Following the deduction rules of `auto`, while respecting the
+non-type template parameter list of allowable types, template arguments can be
+deduced from the types of its arguments.
+
+**Documentation:**
+[Template parameters](https://en.cppreference.com/w/cpp/language/template_parameters)
+
+**Notes:**
+*** promo
+None
+***
+
+### Fold expressions <sup>[tbd]</sup>
+
+```c++
+template <typename... Args>
+auto sum(Args... args) {
+  return (... + args);
+}
+```
+
+**Description:** A fold expression performs a fold of a template parameter pack
+over a binary operator.
+
+**Documentation:**
+[Fold expression](https://en.cppreference.com/w/cpp/language/fold)
+
+**Notes:**
+*** promo
+None
+***
+
+### constexpr lambda <sup>[tbd]</sup>
+
+```c++
+auto identity = [](int n) constexpr { return n; };
+static_assert(identity(123) == 123);
+```
+
+**Description:** Compile-time lambdas using constexpr.
+
+**Documentation:**
+[Lambda expressions](https://en.cppreference.com/w/cpp/language/lambda)
+
+**Notes:**
+*** promo
+None
+***
+
+### Lambda capture this by value <sup>[tbd]</sup>
+
+```c++
+const auto l = [*this] { return member_; }
+```
+
+**Description:** `*this` captures the current object by copy, while `this`
+continues to capture by reference.
+
+**Documentation:**
+[Lambda capture](https://en.cppreference.com/w/cpp/language/lambda#Lambda_capture)
+
+**Notes:**
+*** promo
+None
+***
+
+### UTF-8 character literals <sup>[tbd]</sup>
+
+```c++
+char x = u8'x';
+```
+
+**Description:** A character literal that begins with `u8` is a character
+literal of type `char`. The value of a UTF-8 character literal is equal to its
+ISO 10646 code point value.
+
+**Documentation:**
+[Character literal](https://en.cppreference.com/w/cpp/language/character_literal)
+
+**Notes:**
+*** promo
+C++20 changes the type to `char8_t`, causing migration hazards for code using
+this.
+***
+
+### using declaration for attributes <sup>[tbd]</sup>
+
+```c++
+[[using CC: opt(1), debug]]  // same as [[CC:opt(1), CC::debug]]
+```
+
+**Description:** Specifies a common namespace for a list of attributes.
+
+**Documentation:**
+[Attribute specifier sequence](https://en.cppreference.com/w/cpp/language/attributes)
+
+**Notes:**
+*** promo
+See similar attribute macros in base/compiler_specific.h.
+***
+
+### __has_include <sup>[tbd]</sup>
+
+```c++
+#if __has_include(<optional>) ...
+```
+
+**Description:** Checks whether a file is available for inclusion, i.e. the file
+exists.
+
+**Documentation:**
+[Source file inclusion](https://en.cppreference.com/w/cpp/preprocessor/include)
+
+**Notes:**
+*** promo
+None
+***
+
+## C++17 TBD Library Features {#library-review-17}
+
+The following C++17 library features are not allowed in the Chromium codebase.
+See the top of this page on how to propose moving a feature from this list into
+the allowed or banned sections.
+
+### std::variant <sup>[tbd]</sup>
+
+```c++
+std::variant<int, double> v = 12;
+```
+
+**Description:** The class template `std::variant` represents a type-safe
+`union`. An instance of `std::variant` at any given time holds a value of one of
+its alternative types (it's also possible for it to be valueless).
+
+**Documentation:**
+[std::variant](https://en.cppreference.com/w/cpp/utility/variant)
+
+**Notes:**
+*** promo
+See also `absl::variant`.
+***
+
+### std::optional <sup>[tbd]</sup>
+
+```c++
+std::optional<std::string> s;
+```
+
+**Description:** The class template `std::optional` manages an optional
+contained value, i.e. a value that may or may not be present. A common use case
+for optional is the return value of a function that may fail.
+
+**Documentation:**
+[std::optional](https://en.cppreference.com/w/cpp/utility/optional)
+
+**Notes:**
+*** promo
+See also `absl::optional`.
+***
+
+### std::string_view <sup>[tbd]</sup>
+
+```c++
+std::string_view str = "foo";
+```
+
+**Description:** A non-owning reference to a string. Useful for providing an
+abstraction on top of strings (e.g. for parsing).
+
+**Documentation:**
+[std::basic_string_view](https://en.cppreference.com/w/cpp/string/basic_string_view)
+
+**Notes:**
+*** promo
+See also `absl::string_view` and `base::StringPiece`.
+***
+
+### std::invoke <sup>[tbd]</sup>
+
+```c++
+static_assert(std::invoke(std::plus<>(), 1, 2) == 3);
+```
+
+**Description:** Invokes a `Callable` object with parameters. An example of a
+`Callable` object is `base::Callback` where an object can be called similarly to
+a regular function.
+
+**Documentation:**
+[std::invoke](https://en.cppreference.com/w/cpp/utility/functional/invoke)
+
+**Notes:**
+*** promo
+See also `base::invoke`.
+***
+
+### std::apply <sup>[tbd]</sup>
+
+```c++
+static_assert(std::apply(std::plus<>(), std::make_tuple(1, 2)) == 3);
+```
+
+**Description:** Invokes a `Callable` object with a tuple of arguments.
+
+**Documentation:**
+[std::apply](https://en.cppreference.com/w/cpp/utility/apply)
+
+**Notes:**
+*** promo
+See also `absl::apply` and `base::apply`.
+***
+
+### std::byte <sup>[tbd]</sup>
+
+```c++
+std::byte b = 0xFF;
+int i = std::to_integer<int>(b);  // 0xFF
+```
+
+**Description:** A standard way of representing data as a byte. `std::byte` is
+neither a character type nor an arithmetic type, and the only operator overloads
+available are bitwise operations.
+
+**Documentation:**
+[std::byte](https://en.cppreference.com/w/cpp/types/byte)
+
+**Notes:**
+*** promo
+None
+***
+
+### Splicing for maps and sets <sup>[tbd]</sup>
+
+```c++
+std::map<...>::extract
+std::map<...>::merge
+std::set<...>::extract
+std::set<...>::merge
+```
+
+**Description:** Moving nodes and merging containers without the overhead of
+expensive copies, moves, or heap allocations/deallocations.
+
+**Documentation:**
+[std::map::extract](https://en.cppreference.com/w/cpp/container/map/extract),
+[std::map::merge](https://en.cppreference.com/w/cpp/container/map/merge)
+
+**Notes:**
+*** promo
+None
+***
+
+### Parallel algorithms <sup>[tbd]</sup>
+
+```c++
+auto it = std::find(std::execution::par, std::begin(vec), std::end(vec), 2);
+```
+
+**Description:** Many of the STL algorithms, such as the `copy`, `find` and
+`sort` methods, now support the parallel execution policies: `seq`, `par`, and
+`par_unseq` which translate to "sequentially", "parallel" and
+"parallel unsequenced".
+
+**Documentation:**
+[execution_policy_tag_t](https://en.cppreference.com/w/cpp/algorithm/execution_policy_tag_t)
+
+**Notes:**
+*** promo
+None
+***
+
+### std::make_from_tuple <sup>[tbd]</sup>
+
+```c++
+// Calls Foo(int, double):
+auto foo = std::make_from_tuple<Foo>(std::make_tuple(1, 3.5));
+```
+
+**Description:** Constructs an object from a tuple of arguments.
+
+**Documentation:**
+[std::make_from_tuple](https://en.cppreference.com/w/cpp/utility/make_from_tuple)
+
+**Notes:**
+*** promo
+See also `absl::make_from_tuple`.
+***
+
+### Searchers <sup>[tbd]</sup>
+
+```c++
+auto it = std::search(haystack.begin(), haystack.end(),
+                      std::boyer_moore_searcher(needle.begin(), needle.end()));
+```
+
+**Description:** Alternate string searching algorithms.
+
+**Documentation:**
+[Searchers](https://en.cppreference.com/w/cpp/utility/functional#Searchers)
+
+**Notes:**
+*** promo
+None
+***
+
+### std::as_const <sup>[tbd]</sup>
+
+```c++
+auto&& const_ref = std::as_const(mutable_obj);
+```
+
+**Description:** Forms reference to const T.
+
+**Documentation:**
+[std::as_const](https://en.cppreference.com/w/cpp/utility/as_const)
+
+**Notes:**
+*** promo
+See also `base::as_const`.
+***
+
+### std::not_fn <sup>[tbd]</sup>
+
+```c++
+auto nonwhite = std::find_if(str.begin(), str.end(), std::not_fn(IsWhitespace));
+```
+
+**Description:** Creates a forwarding call wrapper that returns the negation of
+the callable object it holds.
+
+**Documentation:**
+[std::not_fn](https://en.cppreference.com/w/cpp/utility/functional/not_fn)
+
+**Notes:**
+*** promo
+See also `base::not_fn`.
+***
+
+### Uninitialized memory algorithms <sup>[tbd]</sup>
+
+```c++
+std::destroy_at(ptr);
+std::destroy(ptr, ptr + 8);
+std::destroy_n(ptr, 8);
+std::uninitialized_move(src.begin(), src.end(), dest.begin());
+std::uninitialized_value_construct(std::begin(storage), std::end(storage));
+```
+
+**Description:** Replaces direct constructor and destructor calls when manually
+managing memory.
+
+**Documentation:**
+[std::destroy_at](https://en.cppreference.com/w/cpp/memory/destroy_at),
+[std::destroy](https://en.cppreference.com/w/cpp/memory/destroy),
+[std::destroy_n](https://en.cppreference.com/w/cpp/memory/destroy_n),
+[std::uninitialized_move](https://en.cppreference.com/w/cpp/memory/uninitialized_move),
+[std::uninitialized_value_construct](https://en.cppreference.com/w/cpp/memory/uninitialized_value_construct)
+
+**Notes:**
+*** promo
+None
+***
+
+### std::pmr::memory_resource and std::polymorphic_allocator <sup>[tbd]</sup>
+
+```c++
+#include <memory_resource>
+```
+
+**Description:** Manages memory allocations using runtime polymorphism.
+
+**Documentation:**
+[std::pmr::memory_resource](https://en.cppreference.com/w/cpp/memory/memory_resource),
+[std::pmr::polymorphic_allocator](https://en.cppreference.com/w/cpp/memory/polymorphic_allocator),
+
+**Notes:**
+*** promo
+May not be supported in libc++, according to the
+[library features table](https://en.cppreference.com/w/cpp/17)
+***
+
+### std::aligned_alloc <sup>[tbd]</sup>
+
+```c++
+int* p2 = static_cast<int*>(std::aligned_alloc(1024, 1024));
+```
+
+**Description:** Allocates uninitialized storage with the specified alignment.
+
+**Documentation:**
+[std::aligned_alloc](https://en.cppreference.com/w/cpp/memory/c/aligned_alloc)
+
+**Notes:**
+*** promo
+None
+***
+
+### std::conjunction/std::disjunction/std::negation <sup>[tbd]</sup>
+
+```c++
+template<typename T, typename... Ts>
+std::enable_if_t<std::conjunction_v<std::is_same<T, Ts>...>>
+func(T, Ts...) { ...
+```
+
+**Description:** Performs logical operations on type traits.
+
+**Documentation:**
+[std::conjunction](https://en.cppreference.com/w/cpp/types/conjunction),
+[std::disjunction](https://en.cppreference.com/w/cpp/types/disjunction),
+[std::negation](https://en.cppreference.com/w/cpp/types/negation)
+
+**Notes:**
+*** promo
+None
+***
+
+### std::is_swappable <sup>[tbd]</sup>
+
+```c++
+std::is_swappable<T>
+std::is_swappable_with_v<T, U>
+```
+
+**Description:** Checks whether classes may be swapped.
+
+**Documentation:**
+[std::is_swappable](https://en.cppreference.com/w/cpp/types/is_swappable)
+
+**Notes:**
+*** promo
+None
+***
+
+### std::is_invocable <sup>[tbd]</sup>
+
+```c++
+std::is_invocable_v<Fn, 1, "Hello">
+```
+
+**Description:** Checks whether a function may be invoked with the given
+argument types.  The `_r` variant also evaluates whether the result is
+convertible to a given type.
+
+**Documentation:**
+[std::is_invocable](https://en.cppreference.com/w/cpp/types/is_invocable)
+
+**Notes:**
+*** promo
+None
+***
+
+### std::is_aggregate <sup>[tbd]</sup>
+
+```c++
+if constexpr(std::is_aggregate_v<T>) { ...
+```
+
+**Description:** Checks wither the given type is an aggregate type.
+
+**Documentation:**
+[std::is_aggregate](https://en.cppreference.com/w/cpp/types/is_aggregate)
+
+**Notes:**
+*** promo
+None
+***
+
+### std::has_unique_object_representations <sup>[tbd]</sup>
+
+```c++
+std::has_unique_object_representations_v<foo>
+```
+
+**Description:** Checks wither the given type is trivially copyable and any two
+objects with the same value have the same object representation.
+
+**Documentation:**
+[std::has_unique_object_representations](https://en.cppreference.com/w/cpp/types/has_unique_object_representations)
+
+**Notes:**
+*** promo
+None
+***
+
+### std::clamp <sup>[tbd]</sup>
+
+```c++
+int x = base::clamp(inp, 0, 100);
+```
+
+**Description:** Clamps a value between a minimum and a maximum.
+
+**Documentation:**
+[std::clamp](https://en.cppreference.com/w/cpp/algorithm/clamp)
+
+**Notes:**
+*** promo
+See also `base::clamp`.
+***
+
+### std::reduce <sup>[tbd]</sup>
+
+```c++
+std::reduce(std::execution::par, v.cbegin(), v.cend());
+```
+
+**Description:** Like `std::accumulate` except the elements of the range may be
+grouped and rearranged in arbitrary order.
+
+**Documentation:**
+[std::reduce](https://en.cppreference.com/w/cpp/algorithm/reduce)
+
+**Notes:**
+*** promo
+Makes the most sense in conjunction with `std::execution::par`.
+***
+
+### std::inclusive_scan <sup>[tbd]</sup>
+
+```c++
+std::inclusive_scan(data.begin(), data.end(), output.begin());
+```
+
+**Description:** Like `std::accumulate` but writes the result at each step into
+the output range.
+
+**Documentation:**
+[std::inclusive_scan](https://en.cppreference.com/w/cpp/algorithm/inclusive_scan)
+
+**Notes:**
+*** promo
+None
+***
+
+### std::exclusive_scan <sup>[tbd]</sup>
+
+```c++
+std::exclusive_scan(data.begin(), data.end(), output.begin());
+```
+
+**Description:** Like `std::inclusive_scan` but omits the current element from
+the written output at each step; that is, results are "one value behind" those
+of `std::inclusive_scan`.
+
+**Documentation:**
+[std::exclusive_scan](https://en.cppreference.com/w/cpp/algorithm/exclusive_scan)
+
+**Notes:**
+*** promo
+None
+***
+
+### std::gcd <sup>[tbd]</sup>
+
+```c++
+static_assert(std::gcd(12, 18) == 6);
+```
+
+**Description:** Computes the greatest common divisor of its arguments.
+
+**Documentation:**
+[std::gcd](https://en.cppreference.com/w/cpp/numeric/gcd)
+
+**Notes:**
+*** promo
+None
+***
+
+### std::lcm <sup>[tbd]</sup>
+
+```c++
+static_assert(std::lcm(12, 18) == 36);
+```
+
+**Description:** Computes the least common multiple of its arguments.
+
+**Documentation:**
+[std::lcm](https://en.cppreference.com/w/cpp/numeric/lcm)
+
+**Notes:**
+*** promo
+None
+***
+
+### Non-member std::size/std::empty/std::data <sup>[tbd]</sup>
+
+```c++
+for (std::size_t i = 0; i < std::size(c); ++i) { ...
+if (!std::empty(c)) { ...
+std::strcpy(arr, std::data(str));
+```
+
+**Description:** Non-member versions of what are normally member functions, for
+symmetrical use with things like arrays and initializer_lists.
+
+**Documentation:**
+[std::size](https://en.cppreference.com/w/cpp/iterator/size),
+[std::empty](https://en.cppreference.com/w/cpp/iterator/empty),
+[std::data](https://en.cppreference.com/w/cpp/iterator/data)
+
+**Notes:**
+*** promo
+See `base::size`, `base::empty`, and `base::data`.
+***
+
+### Mathematical special functions <sup>[tbd]</sup>
+
+```c++
+std::assoc_laguerre()
+std::assoc_legendre()
+std::beta()
+std::comp_ellint_1()
+std::comp_ellint_2()
+std::comp_ellint_3()
+std::cyl_bessel_i()
+std::cyl_bessel_j()
+std::cyl_bessel_k()
+std::cyl_neumann()
+std::ellint_1()
+std::ellint_2()
+std::ellint_3()
+std::expint()
+std::hermite()
+std::legendre()
+std::laguerre()
+std::riemann_zeta()
+std::sph_bessel()
+std::sph_legendre()
+std::sph_neumann()
+```
+
+**Description:** A variety of mathematical functions.
+
+**Documentation:**
+[Mathematical special functions](https://en.cppreference.com/w/cpp/numeric/special_functions)
+
+**Notes:**
+*** promo
+May not be supported in libc++, according to the
+[library features table](https://en.cppreference.com/w/cpp/17)
+***
+
+### 3D std::hypot <sup>[tbd]</sup>
+
+```c++
+double dist = std::hypot(1.0, 2.5, 3.7);
+```
+
+**Description:** Computes the distance from the origin in 3D space.
+
+**Documentation:**
+[std::hypot](https://en.cppreference.com/w/cpp/numeric/math/hypot)
+
+**Notes:**
+*** promo
+None
+***
+
+### Cache line interface <sup>[tbd]</sup>
+
+```c++
+alignas(std::hardware_destructive_interference_size) std::atomic<int> cat;
+static_assert(sizeof(S) <= std::hardware_constructive_interference_size);
+```
+
+**Description:** A portable way to access the L1 data cache line size.
+
+**Documentation:**
+[Hardware interference size](https://en.cppreference.com/w/cpp/thread/hardware_destructive_interference_size)
+
+**Notes:**
+*** promo
+May not be supported in libc++, according to the
+[library features table](https://en.cppreference.com/w/cpp/17)
+***
+
+### std::launder <sup>[tbd]</sup>
+
+```c++
+struct Y { int z; };
+alignas(Y) std::byte s[sizeof(Y)];
+Y* q = new(&s) Y{2};
+const int h = std::launder(reinterpret_cast<Y*>(&s))->z;
+```
+
+**Description:** When used to wrap a pointer, makes it valid to access the
+resulting object in cases it otherwise wouldn't have been, in a very limited set
+of circumstances.
+
+**Documentation:**
+[std::launder](https://en.cppreference.com/w/cpp/utility/launder)
+
+**Notes:**
+*** promo
+None
+***
+
+### std::to_chars/std::from_chars <sup>[tbd]</sup>
+
+```c++
+std::to_chars(str.data(), str.data() + str.size(), 42);
+std::from_chars(str.data(), str.data() + str.size(), result);
+```
+
+**Description:** Locale-independent, non-allocating, non-throwing functions to
+convert values to/from character strings, designed for use in high-throughput
+contexts.
+
+**Documentation:**
+[std::to_chars](https://en.cppreference.com/w/cpp/utility/to_chars),
+[std::from_chars](https://en.cppreference.com/w/cpp/utility/from_chars)
+
+**Notes:**
+*** promo
+None
+***
+
+### std::atomic<T>::is_always_lock_free <sup>[tbd]</sup>
+
+```c++
+template <typename T>
+struct is_lock_free_impl
+: std::integral_constant<bool, std::atomic<T>::is_always_lock_free> {};
+```
+
+**Description:** True when the given atomic type is always lock-free.
+
+**Documentation:**
+[std::atomic<T>::is_always_lock_free](https://en.cppreference.com/w/cpp/atomic/atomic/is_always_lock_free)
+
+**Notes:**
+*** promo
+None
+***
+
+### std::scoped_lock <sup>[tbd]</sup>
+
+```c++
+std::scoped_lock lock(e1.m, e2.m);
+```
+
+**Description:** Provides an RAII-style mechanism for owning one or more mutexes
+for the duration of a scoped block.
+
+**Documentation:**
+[std::scoped_lock](https://en.cppreference.com/w/cpp/thread/scoped_lock)
+
+**Notes:**
+*** promo
+See also `base::AutoLock`.
+***
+
+### std::timespec_get <sup>[tbd]</sup>
+
+```c++
+std::timespec ts;
+std::timespec_get(&ts, TIME_UTC);
+```
+
+**Description:** Gets the current calendar time in the given time base.
+
+**Documentation:**
+[std::timespec_get](https://en.cppreference.com/w/cpp/chrono/c/timespec_get)
+
+**Notes:**
+*** promo
+None
+***
+
+## Abseil Allowed Library Features {#absl-allowlist}
+
+The following Abseil library features are allowed in the Chromium codebase.
+
+### Optional <sup>[allowed]</sup>
+
+```c++
+absl::optional
+```
+
+**Description:** Early adaptation of C++17 `std::optional`.
+
+**Documentation:**
+[std::optional](https://en.cppreference.com/w/cpp/utility/optional)
+
+**Notes:**
+*** promo
+Replaces `base::Optional`.
+[Discussion thread](https://groups.google.com/a/chromium.org/g/cxx/c/zUGqagX1NFU)
+***
+
+### Status <sup>[allowed]</sup>
+
+```c++
+absl::Status
+```
+
+**Description:** Type for returning detailed errors.
+
+**Documentation:**
+[status.h](https://source.chromium.org/chromium/chromium/src/+/main:third_party/abseil-cpp/absl/status/status.h)
+
+**Notes:**
+*** promo
+Approved for use inside a wrapper type. Use
+[abseil_string_conversions.h](https://source.chromium.org/chromium/chromium/src/+/main:base/strings/abseil_string_conversions.h)
+to convert to and from
+[absl::string_view](https://source.chromium.org/chromium/chromium/src/+/main:third_party/abseil-cpp/absl/strings/string_view.h)
+so the wrapper can expose
+[base::StringPiece](https://source.chromium.org/chromium/chromium/src/+/main:base/strings/string_piece.h).
+Use
+[absl::Cord](https://source.chromium.org/chromium/chromium/src/+/main:third_party/abseil-cpp/absl/strings/cord.h)
+directly as minimally necessary to interface; do not expose in the wrapper type
+API.
+
+[Discussion thread](https://groups.google.com/a/chromium.org/g/cxx/c/ImdFCSZ-NMA)
+***
+
+### Variant <sup>[allowed]</sup>
+
+```c++
+absl::variant
+```
+
+**Description:** Early adaptation of C++17 `std::variant`.
+
+**Documentation:**
+[std::variant](https://en.cppreference.com/w/cpp/utility/variant)
+
+**Notes:**
+*** promo
+[Discussion thread](https://groups.google.com/a/chromium.org/g/cxx/c/DqvG-TpvMyU)
+***
+
+## Abseil Banned Library Features {#absl-blocklist}
+
+The following Abseil library features are not allowed in the Chromium codebase.
+
+### Any <sup>[banned]</sup>
+
+```c++
+absl::any a = int{5};
+EXPECT_THAT(absl::any_cast<int>(&a), Pointee(5));
+EXPECT_EQ(absl::any_cast<size_t>(&a), nullptr);
+```
+
+**Description:** Early adaptation of C++17 `std::any`.
+
+**Documentation:** [std::any](https://en.cppreference.com/w/cpp/utility/any)
+
+**Notes:**
+*** promo
+Banned since workaround for lack of RTTI isn't compatible with the component
+build ([Bug](https://crbug.com/1096380)). Also see `std::any`.
+***
+
+### Command line flags <sup>[banned]</sup>
+
+```c++
+ABSL_FLAG(bool, logs, false, "print logs to stderr");
+app --logs=true;
+```
+
+**Description:** Allows programmatic access to flag values passed on the
+command-line to binaries.
+
+**Documentation:** [Flags Library](https://abseil.io/docs/cpp/guides/flags)
+
+**Notes:**
+*** promo
+Banned since workaround for lack of RTTI isn't compatible with the component
+build. ([Bug](https://crbug.com/1096380)) Use `base::CommandLine` instead.
+***
+
+### Span <sup>[banned]</sup>
+
+```c++
+absl::Span
+```
+
+**Description:** Early adaptation of C++20 `std::span`.
+
+**Documentation:** [Using absl::Span](https://abseil.io/tips/93)
+
+**Notes:**
+*** promo
+Banned due to being less std::-compliant than `base::span`. Keep using
+`base::span`.
+***
+
+### string_view <sup>[banned]</sup>
+
+```c++
+absl::string_view
+```
+
+**Description:** Early adaptation of C++17 `std::string_view`.
+
+**Documentation:** [absl::string_view](https://abseil.io/tips/1)
+
+**Notes:**
+*** promo
+Banned due to only working with 8-bit characters. Keep using
+`base::StringPiece` from `base/strings/`.
+***
+
+## Abseil TBD Features {#absl-review}
+
+The following Abseil library features are not allowed in the Chromium codebase.
+See the top of this page on how to propose moving a feature from this list into
+the allowed or banned sections.
+
+### 128bit integer <sup>[tbd]</sup>
+
+```c++
+uint64_t a;
+absl::uint128 v = a;
+```
+
+**Description:** Signed and unsigned 128-bit integer types meant to mimic
+intrinsic types as closely as possible.
+
+**Documentation:**
+[Numerics](https://abseil.io/docs/cpp/guides/numeric)
+
+**Notes:**
+*** promo
+None
+***
+
+### bind_front <sup>[tbd]</sup>
+
+```c++
+absl::bind_front
+```
+
+**Description:** Binds the first N arguments of an invocable object and stores them by value.
+
+**Documentation:**
+*   [bind_front.h](https://source.chromium.org/chromium/chromium/src/+/main:third_party/abseil-cpp/absl/functional/bind_front.h)
+*   [Avoid std::bind](https://abseil.io/tips/108)
+
+**Notes:**
+*** promo
+Overlaps with `base::Bind`.
+***
+
+### Cleanup <sup>[tbd]</sup>
+
+```c++
+FILE* sink_file = fopen(sink_path, "w");
+auto sink_closer = absl::MakeCleanup([sink_file] { fclose(sink_file); });
+```
+
+**Description:** Implements the scope guard idiom, invoking the contained
+callback's `operator()() &&` on scope exit.
+
+**Documentation:**
+[cleanup.h](https://source.chromium.org/chromium/chromium/src/+/main:third_party/abseil-cpp/absl/cleanup/cleanup.h)
+
+**Notes:**
+*** promo
+Similar to `defer` in Golang.
+***
+
+### Containers <sup>[tbd]</sup>
+
+```c++
+absl::flat_hash_map
+absl::flat_hash_set
+absl::node_hash_map
+absl::node_hash_set
+absl::btree_map
+absl::btree_set
+absl::btree_multimap
+absl::btree_multiset
+absl::InlinedVector
+absl::FixedArray
+```
+
+**Description:** Alternatives to STL containers designed to be more efficient
+in the general case.
+
+**Documentation:**
+*   [Containers](https://abseil.io/docs/cpp/guides/container)
+*   [Hash](https://abseil.io/docs/cpp/guides/hash)
+
+**Notes:**
+*** promo
+Supplements `base/containers/`.
+***
+
+### Container utilities <sup>[tbd]</sup>
+
+```c++
+auto it = absl::c_find(container, value);
+```
+
+**Description:** Container-based versions of algorithmic functions within C++
+standard library.
+
+**Documentation:**
+[container.h](https://source.chromium.org/chromium/chromium/src/+/main:third_party/abseil-cpp/absl/algorithm/container.h)
+
+**Notes:**
+*** promo
+Overlaps with `base/ranges/algorithm.h`.
+***
+
+### FunctionRef <sup>[tbd]</sup>
+
+```c++
+absl::FunctionRef
+```
+
+**Description:** Type for holding a non-owning reference to an object of any
+invocable type.
+
+**Documentation:**
+[function_ref.h](https://source.chromium.org/chromium/chromium/src/+/main:third_party/abseil-cpp/absl/functional/function_ref.h)
+
+**Notes:**
+*** promo
+None
+***
+
+### Random <sup>[tbd]</sup>
+
+```c++
+absl::BitGen bitgen;
+size_t index = absl::Uniform(bitgen, 0u, elems.size());
+```
+
+**Description:** Functions and utilities for generating pseudorandom data.
+
+**Documentation:** [Random library](https://abseil.io/docs/cpp/guides/random)
+
+**Notes:**
+*** promo
+Overlaps with `base/rand_util.h`.
+***
+
+### StatusOr <sup>[tbd]</sup>
+
+```c++
+absl::StatusOr<T>
+```
+
+**Description:** An object that is either a usable value, or an error Status
+explaining why such a value is not present.
+
+**Documentation:**
+[statusor.h](https://source.chromium.org/chromium/chromium/src/+/main:third_party/abseil-cpp/absl/status/statusor.h)
+
+**Notes:**
+*** promo
+None
+***
+
+### String Formatting <sup>[tbd]</sup>
+
+```c++
+absl::StrFormat
+```
+
+**Description:** A typesafe replacement for the family of printf() string
+formatting routines.
+
+**Documentation:**
+[String Formatting](https://abseil.io/docs/cpp/guides/format)
+
+**Notes:**
+*** promo
+None
+***
+
+### Strings Library <sup>[tbd]</sup>
+
+```c++
+absl::StrSplit
+absl::StrJoin
+absl::StrCat
+absl::StrAppend
+absl::Substitute
+absl::StrContains
+```
+
+**Description:** Classes and utility functions for manipulating and comparing
+strings.
+
+**Documentation:**
+[String Utilities](https://abseil.io/docs/cpp/guides/strings)
+
+**Notes:**
+*** promo
+Overlaps with `base/strings`.
+***
+
+### Synchronization <sup>[tbd]</sup>
+
+```c++
+absl::Mutex
+```
+
+**Description:** Primitives for managing tasks across different threads.
+
+**Documentation:**
+[Synchronization](https://abseil.io/docs/cpp/guides/synchronization)
+
+**Notes:**
+*** promo
+Overlaps with `Lock` in `base/synchronization/`.
+***
+
+### Time library <sup>[tbd]</sup>
+
+```c++
+absl::Duration
+absl::Time
+absl::TimeZone
+absl::CivilDay
+```
+
+**Description:** Abstractions for holding time values, both in terms of
+absolute time and civil time.
+
+**Documentation:** [Time](https://abseil.io/docs/cpp/guides/time)
+
+**Notes:**
+*** promo
+Overlaps with `Time` APIs in `base/`.
+***
diff --git a/styleguide/c++/c++.md b/styleguide/c++/c++.md
index a143955c..5d604c39 100644
--- a/styleguide/c++/c++.md
+++ b/styleguide/c++/c++.md
@@ -25,7 +25,7 @@
 [targets C++17](https://google.github.io/styleguide/cppguide.html#C++_Version).
 Additionally, some features of supported C++ versions remain forbidden. The
 status of Chromium's C++ support is covered in more detail in
-[Modern C++ use in Chromium](c++11.md).
+[Modern C++ use in Chromium](c++-features.md).
 
 ## Naming
 
diff --git a/styleguide/c++/c++11.md b/styleguide/c++/c++11.md
index aeb4ac51..5f02acf2 100644
--- a/styleguide/c++/c++11.md
+++ b/styleguide/c++/c++11.md
@@ -1,1936 +1,6 @@
-# Modern C++ use in Chromium
+# 301 Moved Permanently
 
-_This document is part of the more general
-[Chromium C++ style guide](https://chromium.googlesource.com/chromium/src/+/main/styleguide/c++/c++.md).
-It summarizes the supported state of new and updated language and library
-features in recent C++ standards and the [Abseil](https://abseil.io/about/)
-library. This guide applies to both Chromium and its subprojects, though
-subprojects can choose to be more restrictive if necessary for toolchain
-support._
+The guide to modern C++ use in Chromium has moved to
+[c++-features.md](c++-features.md).
 
-The C++ language has in recent years received an updated standard every three
-years (C++11, C++14, etc.). For various reasons, Chromium does not immediately
-allow new features on the publication of such a standard. Instead, once
-toolchain support is sufficient, a standard is declared "initially supported",
-with new language/library features banned pending discussion.
-
-You can propose changing the status of a feature by sending an email to
-[cxx@chromium.org](https://groups.google.com/a/chromium.org/forum/#!forum/cxx).
-Include a short blurb on what the feature is and why you think it should or
-should not be allowed, along with links to any relevant previous discussion. If
-the list arrives at some consensus, send a codereview to change this file
-accordingly, linking to your discussion thread.
-
-If an item remains on the TBD list two years after initial support is added,
-style arbiters should explicitly move it to an appropriate allowlist or
-blocklist, allowing it if there are no obvious reasons to ban.
-
-The current status of existing standards and Abseil features is:
-
-*   **C++11:** _Default allowed; see banned features below_
-*   **C++14:** _Default allowed; see banned features below_
-*   **C++17:** Initially supported December 23, 2021; see allowed/banned/TBD
-    features below
-*   **C++20:** _Not yet supported in Chromium_
-*   **C++23:** _Not yet standardized_
-*   **Abseil:** Initially supported July 31, 2020; see allowed/banned/TBD
-    features below
-    *   absl::StatusOr: Initially supported September 3, 2020
-    *   absl::Cleanup: Initially supported February 4, 2021
-
-[TOC]
-
-## C++11 Banned Language Features {#core-blocklist-11}
-
-The following C++11 language features are not allowed in the Chromium codebase.
-
-### Inline Namespaces <sup>[banned]</sup>
-
-```c++
-inline namespace foo { ... }
-```
-
-**Description:** Allows better versioning of namespaces.
-
-**Documentation:**
-[Inline namespaces](https://en.cppreference.com/w/cpp/language/namespace#Inline_namespaces)
-
-**Notes:**
-*** promo
-Banned in the
-[Google Style Guide](https://google.github.io/styleguide/cppguide.html#Namespaces).
-Unclear how it will work with components.
-***
-
-### long long Type <sup>[banned]</sup>
-
-```c++
-long long var = value;
-```
-
-**Description:** An integer of at least 64 bits.
-
-**Documentation:**
-[Fundamental types](https://en.cppreference.com/w/cpp/language/types)
-
-**Notes:**
-*** promo
-Use a stdint.h type if you need a 64-bit number.
-[Discussion thread](https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/RxugZ-pIDxk)
-***
-
-### User-Defined Literals <sup>[banned]</sup>
-
-```c++
-type var = literal_value_type;
-```
-
-**Description:** Allows user-defined literal expressions.
-
-**Documentation:**
-[User-defined literals](https://en.cppreference.com/w/cpp/language/user_literal)
-
-**Notes:**
-*** promo
-Banned in the
-[Google Style Guide](https://google.github.io/styleguide/cppguide.html#Operator_Overloading).
-***
-
-### thread_local Storage Class <sup>[banned]</sup>
-
-```c++
-thread_local int foo = 1;
-```
-
-**Description:** Puts variables into thread local storage.
-
-**Documentation:**
-[Storage duration](https://en.cppreference.com/w/cpp/language/storage_duration)
-
-**Notes:**
-*** promo
-Some surprising effects on Mac
-([discussion](https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/2msN8k3Xzgs),
-[fork](https://groups.google.com/a/chromium.org/forum/#!topic/cxx/h7O5BdtWCZw)).
-Use `base::SequenceLocalStorageSlot` for sequence support, and
-`base::ThreadLocal`/`base::ThreadLocalStorage` otherwise.
-***
-
-## C++11 Banned Library Features {#library-blocklist-11}
-
-The following C++11 library features are not allowed in the Chromium codebase.
-
-### Bind Operations <sup>[banned]</sup>
-
-```c++
-std::bind(function, args, ...)
-```
-
-**Description:** Declares a function object bound to certain arguments
-
-**Documentation:**
-[std::bind](https://en.cppreference.com/w/cpp/utility/functional/bind)
-
-**Notes:**
-*** promo
-Use `base::Bind` instead. Compared to `std::bind`, `base::Bind` helps prevent
-lifetime issues by preventing binding of capturing lambdas and by forcing
-callers to declare raw pointers as `Unretained`.
-[Discussion thread](https://groups.google.com/a/chromium.org/forum/#!topic/cxx/SoEj7oIDNuA)
-***
-
-### C Floating-Point Environment <sup>[banned]</sup>
-
-```c++
-#include <cfenv>
-#include <fenv.h>
-```
-
-**Description:** Provides floating point status flags and control modes for
-C-compatible code
-
-**Documentation:**
-[Standard library header "cfenv"](https://en.cppreference.com/w/cpp/header/cfenv)
-
-**Notes:**
-*** promo
-Banned by the
-[Google Style Guide](https://google.github.io/styleguide/cppguide.html#C++11)
-due to concerns about compiler support.
-***
-
-### Date and time utilities <sup>[banned]</sup>
-
-```c++
-#include <chrono>
-```
-
-**Description:** A standard date and time library
-
-**Documentation:**
-[Date and time utilities](https://en.cppreference.com/w/cpp/chrono)
-
-**Notes:**
-*** promo
-Overlaps with `Time` APIs in `base/`. Keep using the `base/` classes.
-***
-
-### Exceptions <sup>[banned]</sup>
-
-```c++
-#include <exception>
-```
-
-**Description:** Enhancements to exception throwing and handling
-
-**Documentation:**
-[Standard library header "exception"](https://en.cppreference.com/w/cpp/header/exception)
-
-**Notes:**
-*** promo
-Exceptions are banned by the
-[Google Style Guide](https://google.github.io/styleguide/cppguide.html#Exceptions)
-and disabled in Chromium compiles. However, the `noexcept` specifier is
-explicitly allowed.
-[Discussion thread](https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/8i4tMqNpHhg)
-***
-
-### Function Objects <sup>[banned]</sup>
-
-```c++
-std::function
-```
-
-**Description:** Wraps a standard polymorphic function
-
-**Documentation:**
-[std::function](https://en.cppreference.com/w/cpp/utility/functional/function)
-
-**Notes:**
-*** promo
-Use `base::{Once,Repeating}Callback` instead. Compared to `std::function`,
-`base::{Once,Repeating}Callback` directly supports Chromium's refcounting
-classes and weak pointers and deals with additional thread safety concerns.
-[Discussion thread](https://groups.google.com/a/chromium.org/forum/#!topic/cxx/SoEj7oIDNuA)
-***
-
-### Random Number Engines <sup>[banned]</sup>
-
-*** aside
-The random number engines defined in `<random>` (see separate item for random
-number distributions), e.g.: `linear_congruential_engine`,
-`mersenne_twister_engine`, `minstd_rand0`, `mt19937`, `ranlinux48`,
-`random_device`
-***
-
-**Description:** Random number generation algorithms and utilities.
-
-**Documentation:**
-[Pseudo-random number generation](https://en.cppreference.com/w/cpp/numeric/random)
-
-**Notes:**
-*** promo
-Do not use any random number engines from `<random>`. Instead, use
-`base::RandomBitGenerator`.
-[Discussion thread](https://groups.google.com/a/chromium.org/forum/#!topic/cxx/16Xmw05C-Y0)
-***
-
-### Ratio Template Class <sup>[banned]</sup>
-
-```c++
-std::ratio<numerator, denominator>
-```
-
-**Description:** Provides compile-time rational numbers
-
-**Documentation:**
-[std::ratio](https://en.cppreference.com/w/cpp/numeric/ratio/ratio)
-
-**Notes:**
-*** promo
-Banned by the
-[Google Style Guide](https://google.github.io/styleguide/cppguide.html#C++11)
-due to concerns that this is tied to a more template-heavy interface style.
-***
-
-### Regular Expressions <sup>[banned]</sup>
-
-```c++
-#include <regex>
-```
-
-**Description:** A standard regular expressions library
-
-**Documentation:**
-[Regular expressions library](https://en.cppreference.com/w/cpp/regex)
-
-**Notes:**
-*** promo
-Overlaps with many regular expression libraries in Chromium. When in doubt, use
-`re2`.
-***
-
-### Shared Pointers <sup>[banned]</sup>
-
-```c++
-std::shared_ptr
-```
-
-**Description:** Allows shared ownership of a pointer through reference counts
-
-**Documentation:**
-[std::shared_ptr](https://en.cppreference.com/w/cpp/memory/shared_ptr)
-
-**Notes:**
-*** promo
-Needs a lot more evaluation for Chromium, and there isn't enough of a push for
-this feature.
-
-*   [Google Style Guide](https://google.github.io/styleguide/cppguide.html#Ownership_and_Smart_Pointers).
-*   [Discussion Thread](https://groups.google.com/a/chromium.org/forum/#!topic/cxx/aT2wsBLKvzI)
-***
-
-### String-Number Conversion Functions <sup>[banned]</sup>
-
-```c++
-std::stoi()
-std::stol()
-std::stoul()
-std::stoll
-std::stoull()
-std::stof()
-std::stod()
-std::stold()
-std::to_string()
-```
-
-**Description:** Converts strings to/from numbers
-
-**Documentation:**
-*   [std::stoi, std::stol, std::stoll](https://en.cppreference.com/w/cpp/string/basic_string/stol),
-*   [std::stoul, std::stoull](https://en.cppreference.com/w/cpp/string/basic_string/stoul),
-*   [std::stof, std::stod, std::stold](https://en.cppreference.com/w/cpp/string/basic_string/stof),
-*   [std::to_string](https://en.cppreference.com/w/cpp/string/basic_string/to_string)
-
-**Notes:**
-*** promo
-The string-to-number conversions rely on exceptions to communicate failure,
-while the number-to-string conversions have performance concerns and depend on
-the locale. Use the routines in `base/strings/string_number_conversions.h`
-instead.
-***
-
-### Thread Library <sup>[banned]</sup>
-
-*** aside
-`<thread>` and related headers, including `<future>`, `<mutex>`,
-`<condition_variable>`
-***
-
-**Description:** Provides a standard multithreading library using `std::thread`
-and associates
-
-**Documentation:**
-[Thread support library](https://en.cppreference.com/w/cpp/thread)
-
-**Notes:**
-*** promo
-Overlaps with many classes in `base/`. Keep using the `base/` classes for now.
-`base::Thread` is tightly coupled to `MessageLoop` which would make it hard to
-replace. We should investigate using standard mutexes, or unique_lock, etc. to
-replace our locking/synchronization classes.
-***
-
-### Weak Pointers <sup>[banned]</sup>
-
-```c++
-std::weak_ptr
-```
-
-**Description:** Allows a weak reference to a `std::shared_ptr`
-
-**Documentation:**
-[std::weak_ptr](https://en.cppreference.com/w/cpp/memory/weak_ptr)
-
-**Notes:**
-*** promo
-Banned because `std::shared_ptr` is banned.  Use `base::WeakPtr` instead.
-***
-
-## C++14 Banned Library Features {#library-blocklist-14}
-
-The following C++14 library features are not allowed in the Chromium codebase.
-
-### std::chrono literals <sup>[banned]</sup>
-
-```c++
-using namespace std::chrono_literals;
-auto timeout = 30s;
-```
-
-**Description:** Allows `std::chrono` types to be more easily constructed.
-
-**Documentation:**
-[std::literals::chrono_literals::operator""s](https://en.cppreference.com/w/cpp/chrono/operator%22%22s)
-
-**Notes:**
-*** promo
-Banned because `<chrono>` is banned.
-***
-
-## C++17 Allowed Language Features {#core-allowlist-17}
-
-The following C++17 language features are allowed in the Chromium codebase.
-
-### Nested namespaces <sup>[allowed]</sup>
-
-```c++
-namespace A::B::C { ...
-```
-
-**Description:** Using the namespace resolution operator to create nested
-namespace definitions.
-
-**Documentation:**
-[Namespaces](https://en.cppreference.com/w/cpp/language/namespace)
-
-**Notes:**
-*** promo
-[Discussion thread](https://groups.google.com/a/chromium.org/g/cxx/c/gLdR3apDSmg/)
-***
-
-### Template argument deduction for class templates <sup>[allowed]</sup>
-
-```c++
-template <typename T>
-struct MyContainer {
-  MyContainer(T val) : val{val} {}
-  // ...
-};
-MyContainer c1(1);  // Type deduced to be `int`.
-```
-
-**Description:** Automatic template argument deduction much like how it's done
-for functions, but now including class constructors.
-
-**Documentation:**
-[Class template argument deduction](https://en.cppreference.com/w/cpp/language/class_template_argument_deduction)
-
-**Notes:**
-*** promo
-Usage is governed by the
-[Google Style Guide](https://google.github.io/styleguide/cppguide.html#CTAD).
-***
-
-### Selection statements with initializer <sup>[allowed]</sup>
-
-```c++
-if (int a = Func(); a < 3) { ...
-switch (int a = Func(); a) { ...
-```
-
-**Description:** New versions of the if and switch statements which simplify
-common code patterns and help users keep scopes tight.
-
-**Documentation:**
-[if statement](https://en.cppreference.com/w/cpp/language/if),
-[switch statement](https://en.cppreference.com/w/cpp/language/switch)
-
-**Notes:**
-*** promo
-[@cxx discussion thread](https://groups.google.com/a/chromium.org/g/cxx/c/4GP43nftePE)
-***
-
-### fallthrough attribute <sup>[allowed]</sup>
-
-```c++
-case 1:
-  DoSomething();
-  [[fallthrough]];
-case 2:
-  break;
-```
-
-**Description:**
-The `[[fallthrough]]` attribute can be used in switch statements to indicate
-when intentionally falling through to the next case.
-
-**Documentation:**
-[C++ attribute: fallthrough](https://en.cppreference.com/w/cpp/language/attributes/fallthrough)
-
-**Notes:**
-*** promo
-See [discussion thread](https://groups.google.com/a/chromium.org/g/cxx/c/JrvyFd243QI).
-
-See [migration task](https://bugs.chromium.org/p/chromium/issues/detail?id=1283907).
-***
-
-### constexpr if <sup>[allowed]</sup>
-
-```c++
-if constexpr (cond) { ...
-```
-
-**Description:** Write code that is instantiated depending on a compile-time
-condition.
-
-**Documentation:**
-[if statement](https://en.cppreference.com/w/cpp/language/if)
-
-**Notes:**
-*** promo
-See [discussion thread](https://groups.google.com/a/chromium.org/g/cxx/c/op2ePZnjP0w).
-***
-
-### nodiscard attribute <sup>[allowed]</sup>
-
-```c++
-struct [[nodiscard]] ErrorOrValue;
-[[nodiscard]] bool DoSomething();
-```
-
-**Description:**
-The `[[nodiscard]]` attribute can be used to indicate that
-
-  - the return value of a function should not be ignored
-  - values of annotated classes/structs/enums returned from functions should not
-    be ignored
-
-**Documentation:**
-[C++ attribute: nodiscard](https://en.cppreference.com/w/cpp/language/attributes/nodiscard)
-
-**Notes:**
-*** promo
-[Discussion thread](https://groups.google.com/a/chromium.org/g/cxx/c/nH7Ar8pZ1Dw/m/c90vGChvAAAJ)
-***
-
-### maybe_unused attribute <sup>[allowed]</sup>
-
-```c++
-struct [[maybe_unused]] MyUnusedThing;
-[[maybe_unused]] int x;
-```
-
-**Description:**
-The `[[maybe_unused]]` attribute can be used to indicate that individual
-variables, functions, or fields of a class/struct/enum can be left unused.
-
-**Documentation:**
-[C++ attribute: maybe_unused](https://en.cppreference.com/w/cpp/language/attributes/maybe_unused)
-
-**Notes:**
-*** promo
-See [discussion thread](https://groups.google.com/a/chromium.org/g/cxx/c/jPLfU5eRg8M/).
-***
-
-### Structured bindings <sup>[allowed]</sup>
-
-```c++
-const auto [x, y] = FuncReturningStdPair();
-```
-
-**Description:** Allows writing `auto [x, y, z] = expr;` where the type of
-`expr` is a tuple-like object, whose elements are bound to the variables `x`,
-`y`, and `z` (which this construct declares). Tuple-like objects include
-`std::tuple`, `std::pair`, `std::array`, and aggregate structures.
-
-**Documentation:**
-[Structured binding declaration](https://en.cppreference.com/w/cpp/language/structured_binding)
-[Explanation of structured binding types](https://jguegant.github.io/blogs/tech/structured-bindings.html)
-
-**Notes:**
-*** promo
-In C++17, structured bindings don't work with lambda captures.
-[C++20 will allow capturing structured bindings by value](https://wg21.link/p1091r3).
-
-This feature forces omitting type names. Its use should follow
-[the guidance around `auto` in Google C++ Style guide](https://google.github.io/styleguide/cppguide.html#Type_deduction).
-
-See [discussion thread](https://groups.google.com/a/chromium.org/g/cxx/c/ExfSorNLNf4).
-***
-
-### Inline variables
-
-```c++
-struct S {
-  static constexpr int kZero = 0;  // constexpr implies inline here.
-};
-
-constexpr inline int kOne = 1;  // Explicit inline needed here.
-```
-
-**Description:** The `inline` specifier can be applied to variables as well as
-to functions. A variable declared inline has the same semantics as a function
-declared inline. It can also be used to declare and define a static member
-variable, such that it does not need to be initialized in the source file.
-
-**Documentation:**
-[inline specifier](https://en.cppreference.com/w/cpp/language/inline)
-
-**Notes:**
-*** promo
-Inline variables in anonymous namespaces in header files will still get one copy
-per translation unit, so they must be outside of an anonymous namespace to be
-effective.
-
-Mutable inline variables and taking the address of inline variables are banned
-since these will break the component build.
-
-See [discussion thread](https://groups.google.com/a/chromium.org/g/cxx/c/hmyGFD80ocE/m/O4AXC93vAQAJ).
-***
-
-## C++17 Allowed Library Features {#library-allowlist-17}
-
-The following C++17 language features are allowed in the Chromium codebase.
-
-### Allocation functions with explicit alignment <sup>[allowed]</sup>
-
-```c++
-class alignas(32) Vec3d {
-  double x, y, z;
-};
-auto p_vec = new Vec3d[10];  // 32-byte aligned in C++17, maybe not previously
-```
-
-**Description:** Performs heap allocation of objects whose alignment
-requirements exceed `__STDCPP_DEFAULT_NEW_ALIGNMENT__`.
-
-**Documentation:**
-[operator new](https://en.cppreference.com/w/cpp/memory/new/operator_new)
-
-**Notes:**
-*** promo
-None
-***
-
-### Type trait variable templates <sup>[tbd]</sup>
-
-```c++
-bool b = std::is_same_v<int, std::int32_t>;
-```
-
-**Description:** Syntactic sugar to provide convenient access to `::value`
-members by simply adding `_v`.
-
-**Documentation:**
-[Type support](https://en.cppreference.com/w/cpp/types)
-
-**Notes:**
-*** promo
-[Discussion thread](Non://groups.google.com/a/chromium.org/g/cxx/c/KEa-0AOGRNY/m/IV_S3_pvAAAJ)
-***
-
-### std::map::try_emplace <sup>[allowed]</sup>
-
-```c++
-std::map<std::string, std::string> m;
-m.try_emplace("c", 10, 'c');
-m.try_emplace("c", "Won't be inserted");
-```
-
-**Description:** Like `emplace`, but does not move from rvalue arguments if the
-insertion does not happen.
-
-**Documentation:**
-[std::map::try_emplace](https://en.cppreference.com/w/cpp/container/map/try_emplace),
-
-**Notes:**
-*** promo
-[Discussion thread](https://groups.google.com/a/chromium.org/g/cxx/c/Uv2tUfIwUfQ/m/ffMxCk9uAAAJ)
-***
-
-### std::map::insert_or_assign <sup>[allowed]</sup>
-
-```c++
-std::map<std::string, std::string> m;
-m.insert_or_assign("c", "cherry");
-m.insert_or_assign("c", "clementine");
-```
-
-**Description:** Like `operator[]`, but returns more information and does not
-require default-constructibility of the mapped type.
-
-**Documentation:**
-[std::map::insert_or_assign](https://en.cppreference.com/w/cpp/container/map/insert_or_assign)
-
-**Notes:**
-*** promo
-[Discussion thread](https://groups.google.com/a/chromium.org/g/cxx/c/Uv2tUfIwUfQ/m/ffMxCk9uAAAJ)
-***
-
-## C++17 Banned Library Features {#library-blocklist-17}
-
-The following C++17 library features are not allowed in the Chromium codebase.
-
-### std::any <sup>[banned]</sup>
-
-```c++
-std::any x = 5;
-```
-
-**Description:** A type-safe container for single values of any type.
-
-**Documentation:**
-[std::any](https://en.cppreference.com/w/cpp/utility/any)
-
-**Notes:**
-*** promo
-[Discussion thread](https://groups.google.com/a/chromium.org/g/cxx/c/KEa-0AOGRNY/m/IV_S3_pvAAAJ)
-
-Banned since workaround for lack of RTTI isn't compatible with the component
-build ([Bug](https://crbug.com/1096380)). Also see `absl::any`.
-***
-
-### std::filesystem <sup>[banned]</sup>
-
-```c++
-#include <filesystem>
-```
-
-**Description:** A standard way to manipulate files, directories, and paths in a
-filesystem.
-
-**Documentation:**
-[Filesystem library](https://en.cppreference.com/w/cpp/filesystem)
-
-**Notes:**
-*** promo
-Banned by the [Google Style Guide](https://google.github.io/styleguide/cppguide.html#Other_Features).
-***
-
-### weak_from_this <sup>[banned]</sup>
-
-```c++
-auto weak_ptr = weak_from_this();
-```
-
-**Description:** Returns a `std::weak_ptr<T>` that tracks ownership of `*this`
-by all existing `std::shared_ptr`s that refer to `*this`.
-
-**Documentation:**
-[std::enable_shared_from_this<T>::weak_from_this](https://en.cppreference.com/w/cpp/memory/enable_shared_from_this/weak_from_this)
-
-**Notes:**
-*** promo
-Banned since `std::shared_ptr` and `std::weak_ptr` are banned.
-***
-
-### Transparent std::owner_less <sup>[banned]</sup>
-
-```c++
-std::map<std::weak_ptr<T>, U, std::owner_less<>>
-```
-
-**Description:** Function object providing mixed-type owner-based ordering of
-shared and weak pointers, regardless of the type of the pointee.
-
-**Documentation:**
-[std::owner_less](https://en.cppreference.com/w/cpp/memory/owner_less)
-
-**Notes:**
-*** promo
-Banned since `std::shared_ptr` and `std::weak_ptr` are banned.
-***
-
-### Array support for std::shared_ptr <sup>[banned]</sup>
-
-```c++
-std::shared_ptr<int[]> p(new int[10]{0,1,2,3,4,5,6,7,8,9});
-std::cout << p[3];  // "3"
-```
-
-**Description:** Supports memory management of arrays via `std::shared_ptr`.
-
-**Documentation:**
-[std::shared_ptr](https://en.cppreference.com/w/cpp/memory/shared_ptr)
-
-**Notes:**
-*** promo
-Banned since `std::shared_ptr` is banned.
-***
-
-### std::uncaught_exceptions <sup>[banned]</sup>
-
-```c++
-int count = std::uncaught_exceptions();
-```
-
-**Description:** Determines whether there are live exception objects.
-
-**Documentation:**
-[std::uncaught_exceptions](https://en.cppreference.com/w/cpp/error/uncaught_exception)
-
-**Notes:**
-*** promo
-Banned because exceptions are banned.
-***
-
-### Rounding functions for duration and time_point <sup>[banned]</sup>
-
-```c++
-std::chrono::ceil<std::chrono::seconds>(dur);
-std::chrono::ceil<std::chrono::seconds>(time_pt);
-std::chrono::floor<std::chrono::seconds>(dur);
-std::chrono::floor<std::chrono::seconds>(time_pt);
-std::chrono::round<std::chrono::seconds>(dur);
-std::chrono::round<std::chrono::seconds>(time_pt);
-```
-
-**Description:** Converts durations and time_points by rounding.
-
-**Documentation:**
-[std::chrono::duration](https://en.cppreference.com/w/cpp/chrono/duration),
-[std::chrono::time_point](https://en.cppreference.com/w/cpp/chrono/time_point)
-
-**Notes:**
-*** promo
-Banned since `std::chrono` is banned.
-***
-
-## C++17 TBD Language Features {#core-review-17}
-
-The following C++17 language features are not allowed in the Chromium codebase.
-See the top of this page on how to propose moving a feature from this list into
-the allowed or banned sections.
-
-### Declaring non-type template parameters with auto <sup>[tbd]</sup>
-
-```c++
-template <auto... seq>
-struct my_integer_sequence {
-  // ...
-};
-auto seq = my_integer_sequence<0, 1, 2>();  // Type deduced to be `int`.
-```
-
-**Description:** Following the deduction rules of `auto`, while respecting the
-non-type template parameter list of allowable types, template arguments can be
-deduced from the types of its arguments.
-
-**Documentation:**
-[Template parameters](https://en.cppreference.com/w/cpp/language/template_parameters)
-
-**Notes:**
-*** promo
-None
-***
-
-### Fold expressions <sup>[tbd]</sup>
-
-```c++
-template <typename... Args>
-auto sum(Args... args) {
-  return (... + args);
-}
-```
-
-**Description:** A fold expression performs a fold of a template parameter pack
-over a binary operator.
-
-**Documentation:**
-[Fold expression](https://en.cppreference.com/w/cpp/language/fold)
-
-**Notes:**
-*** promo
-None
-***
-
-### constexpr lambda <sup>[tbd]</sup>
-
-```c++
-auto identity = [](int n) constexpr { return n; };
-static_assert(identity(123) == 123);
-```
-
-**Description:** Compile-time lambdas using constexpr.
-
-**Documentation:**
-[Lambda expressions](https://en.cppreference.com/w/cpp/language/lambda)
-
-**Notes:**
-*** promo
-None
-***
-
-### Lambda capture this by value <sup>[tbd]</sup>
-
-```c++
-const auto l = [*this] { return member_; }
-```
-
-**Description:** `*this` captures the current object by copy, while `this`
-continues to capture by reference.
-
-**Documentation:**
-[Lambda capture](https://en.cppreference.com/w/cpp/language/lambda#Lambda_capture)
-
-**Notes:**
-*** promo
-None
-***
-
-### UTF-8 character literals <sup>[tbd]</sup>
-
-```c++
-char x = u8'x';
-```
-
-**Description:** A character literal that begins with `u8` is a character
-literal of type `char`. The value of a UTF-8 character literal is equal to its
-ISO 10646 code point value.
-
-**Documentation:**
-[Character literal](https://en.cppreference.com/w/cpp/language/character_literal)
-
-**Notes:**
-*** promo
-C++20 changes the type to `char8_t`, causing migration hazards for code using
-this.
-***
-
-### using declaration for attributes <sup>[tbd]</sup>
-
-```c++
-[[using CC: opt(1), debug]]  // same as [[CC:opt(1), CC::debug]]
-```
-
-**Description:** Specifies a common namespace for a list of attributes.
-
-**Documentation:**
-[Attribute specifier sequence](https://en.cppreference.com/w/cpp/language/attributes)
-
-**Notes:**
-*** promo
-See similar attribute macros in base/compiler_specific.h.
-***
-
-### __has_include <sup>[tbd]</sup>
-
-```c++
-#if __has_include(<optional>) ...
-```
-
-**Description:** Checks whether a file is available for inclusion, i.e. the file
-exists.
-
-**Documentation:**
-[Source file inclusion](https://en.cppreference.com/w/cpp/preprocessor/include)
-
-**Notes:**
-*** promo
-None
-***
-
-## C++17 TBD Library Features {#library-review-17}
-
-The following C++17 library features are not allowed in the Chromium codebase.
-See the top of this page on how to propose moving a feature from this list into
-the allowed or banned sections.
-
-### std::variant <sup>[tbd]</sup>
-
-```c++
-std::variant<int, double> v = 12;
-```
-
-**Description:** The class template `std::variant` represents a type-safe
-`union`. An instance of `std::variant` at any given time holds a value of one of
-its alternative types (it's also possible for it to be valueless).
-
-**Documentation:**
-[std::variant](https://en.cppreference.com/w/cpp/utility/variant)
-
-**Notes:**
-*** promo
-See also `absl::variant`.
-***
-
-### std::optional <sup>[tbd]</sup>
-
-```c++
-std::optional<std::string> s;
-```
-
-**Description:** The class template `std::optional` manages an optional
-contained value, i.e. a value that may or may not be present. A common use case
-for optional is the return value of a function that may fail.
-
-**Documentation:**
-[std::optional](https://en.cppreference.com/w/cpp/utility/optional)
-
-**Notes:**
-*** promo
-See also `absl::optional`.
-***
-
-### std::string_view <sup>[tbd]</sup>
-
-```c++
-std::string_view str = "foo";
-```
-
-**Description:** A non-owning reference to a string. Useful for providing an
-abstraction on top of strings (e.g. for parsing).
-
-**Documentation:**
-[std::basic_string_view](https://en.cppreference.com/w/cpp/string/basic_string_view)
-
-**Notes:**
-*** promo
-See also `absl::string_view` and `base::StringPiece`.
-***
-
-### std::invoke <sup>[tbd]</sup>
-
-```c++
-static_assert(std::invoke(std::plus<>(), 1, 2) == 3);
-```
-
-**Description:** Invokes a `Callable` object with parameters. An example of a
-`Callable` object is `base::Callback` where an object can be called similarly to
-a regular function.
-
-**Documentation:**
-[std::invoke](https://en.cppreference.com/w/cpp/utility/functional/invoke)
-
-**Notes:**
-*** promo
-See also `base::invoke`.
-***
-
-### std::apply <sup>[tbd]</sup>
-
-```c++
-static_assert(std::apply(std::plus<>(), std::make_tuple(1, 2)) == 3);
-```
-
-**Description:** Invokes a `Callable` object with a tuple of arguments.
-
-**Documentation:**
-[std::apply](https://en.cppreference.com/w/cpp/utility/apply)
-
-**Notes:**
-*** promo
-See also `absl::apply` and `base::apply`.
-***
-
-### std::byte <sup>[tbd]</sup>
-
-```c++
-std::byte b = 0xFF;
-int i = std::to_integer<int>(b);  // 0xFF
-```
-
-**Description:** A standard way of representing data as a byte. `std::byte` is
-neither a character type nor an arithmetic type, and the only operator overloads
-available are bitwise operations.
-
-**Documentation:**
-[std::byte](https://en.cppreference.com/w/cpp/types/byte)
-
-**Notes:**
-*** promo
-None
-***
-
-### Splicing for maps and sets <sup>[tbd]</sup>
-
-```c++
-std::map<...>::extract
-std::map<...>::merge
-std::set<...>::extract
-std::set<...>::merge
-```
-
-**Description:** Moving nodes and merging containers without the overhead of
-expensive copies, moves, or heap allocations/deallocations.
-
-**Documentation:**
-[std::map::extract](https://en.cppreference.com/w/cpp/container/map/extract),
-[std::map::merge](https://en.cppreference.com/w/cpp/container/map/merge)
-
-**Notes:**
-*** promo
-None
-***
-
-### Parallel algorithms <sup>[tbd]</sup>
-
-```c++
-auto it = std::find(std::execution::par, std::begin(vec), std::end(vec), 2);
-```
-
-**Description:** Many of the STL algorithms, such as the `copy`, `find` and
-`sort` methods, now support the parallel execution policies: `seq`, `par`, and
-`par_unseq` which translate to "sequentially", "parallel" and
-"parallel unsequenced".
-
-**Documentation:**
-[execution_policy_tag_t](https://en.cppreference.com/w/cpp/algorithm/execution_policy_tag_t)
-
-**Notes:**
-*** promo
-None
-***
-
-### std::make_from_tuple <sup>[tbd]</sup>
-
-```c++
-// Calls Foo(int, double):
-auto foo = std::make_from_tuple<Foo>(std::make_tuple(1, 3.5));
-```
-
-**Description:** Constructs an object from a tuple of arguments.
-
-**Documentation:**
-[std::make_from_tuple](https://en.cppreference.com/w/cpp/utility/make_from_tuple)
-
-**Notes:**
-*** promo
-See also `absl::make_from_tuple`.
-***
-
-### Searchers <sup>[tbd]</sup>
-
-```c++
-auto it = std::search(haystack.begin(), haystack.end(),
-                      std::boyer_moore_searcher(needle.begin(), needle.end()));
-```
-
-**Description:** Alternate string searching algorithms.
-
-**Documentation:**
-[Searchers](https://en.cppreference.com/w/cpp/utility/functional#Searchers)
-
-**Notes:**
-*** promo
-None
-***
-
-### std::as_const <sup>[tbd]</sup>
-
-```c++
-auto&& const_ref = std::as_const(mutable_obj);
-```
-
-**Description:** Forms reference to const T.
-
-**Documentation:**
-[std::as_const](https://en.cppreference.com/w/cpp/utility/as_const)
-
-**Notes:**
-*** promo
-See also `base::as_const`.
-***
-
-### std::not_fn <sup>[tbd]</sup>
-
-```c++
-auto nonwhite = std::find_if(str.begin(), str.end(), std::not_fn(IsWhitespace));
-```
-
-**Description:** Creates a forwarding call wrapper that returns the negation of
-the callable object it holds.
-
-**Documentation:**
-[std::not_fn](https://en.cppreference.com/w/cpp/utility/functional/not_fn)
-
-**Notes:**
-*** promo
-See also `base::not_fn`.
-***
-
-### Uninitialized memory algorithms <sup>[tbd]</sup>
-
-```c++
-std::destroy_at(ptr);
-std::destroy(ptr, ptr + 8);
-std::destroy_n(ptr, 8);
-std::uninitialized_move(src.begin(), src.end(), dest.begin());
-std::uninitialized_value_construct(std::begin(storage), std::end(storage));
-```
-
-**Description:** Replaces direct constructor and destructor calls when manually
-managing memory.
-
-**Documentation:**
-[std::destroy_at](https://en.cppreference.com/w/cpp/memory/destroy_at),
-[std::destroy](https://en.cppreference.com/w/cpp/memory/destroy),
-[std::destroy_n](https://en.cppreference.com/w/cpp/memory/destroy_n),
-[std::uninitialized_move](https://en.cppreference.com/w/cpp/memory/uninitialized_move),
-[std::uninitialized_value_construct](https://en.cppreference.com/w/cpp/memory/uninitialized_value_construct)
-
-**Notes:**
-*** promo
-None
-***
-
-### std::pmr::memory_resource and std::polymorphic_allocator <sup>[tbd]</sup>
-
-```c++
-#include <memory_resource>
-```
-
-**Description:** Manages memory allocations using runtime polymorphism.
-
-**Documentation:**
-[std::pmr::memory_resource](https://en.cppreference.com/w/cpp/memory/memory_resource),
-[std::pmr::polymorphic_allocator](https://en.cppreference.com/w/cpp/memory/polymorphic_allocator),
-
-**Notes:**
-*** promo
-May not be supported in libc++, according to the
-[library features table](https://en.cppreference.com/w/cpp/17)
-***
-
-### std::aligned_alloc <sup>[tbd]</sup>
-
-```c++
-int* p2 = static_cast<int*>(std::aligned_alloc(1024, 1024));
-```
-
-**Description:** Allocates uninitialized storage with the specified alignment.
-
-**Documentation:**
-[std::aligned_alloc](https://en.cppreference.com/w/cpp/memory/c/aligned_alloc)
-
-**Notes:**
-*** promo
-None
-***
-
-### std::conjunction/std::disjunction/std::negation <sup>[tbd]</sup>
-
-```c++
-template<typename T, typename... Ts>
-std::enable_if_t<std::conjunction_v<std::is_same<T, Ts>...>>
-func(T, Ts...) { ...
-```
-
-**Description:** Performs logical operations on type traits.
-
-**Documentation:**
-[std::conjunction](https://en.cppreference.com/w/cpp/types/conjunction),
-[std::disjunction](https://en.cppreference.com/w/cpp/types/disjunction),
-[std::negation](https://en.cppreference.com/w/cpp/types/negation)
-
-**Notes:**
-*** promo
-None
-***
-
-### std::is_swappable <sup>[tbd]</sup>
-
-```c++
-std::is_swappable<T>
-std::is_swappable_with_v<T, U>
-```
-
-**Description:** Checks whether classes may be swapped.
-
-**Documentation:**
-[std::is_swappable](https://en.cppreference.com/w/cpp/types/is_swappable)
-
-**Notes:**
-*** promo
-None
-***
-
-### std::is_invocable <sup>[tbd]</sup>
-
-```c++
-std::is_invocable_v<Fn, 1, "Hello">
-```
-
-**Description:** Checks whether a function may be invoked with the given
-argument types.  The `_r` variant also evaluates whether the result is
-convertible to a given type.
-
-**Documentation:**
-[std::is_invocable](https://en.cppreference.com/w/cpp/types/is_invocable)
-
-**Notes:**
-*** promo
-None
-***
-
-### std::is_aggregate <sup>[tbd]</sup>
-
-```c++
-if constexpr(std::is_aggregate_v<T>) { ...
-```
-
-**Description:** Checks wither the given type is an aggregate type.
-
-**Documentation:**
-[std::is_aggregate](https://en.cppreference.com/w/cpp/types/is_aggregate)
-
-**Notes:**
-*** promo
-None
-***
-
-### std::has_unique_object_representations <sup>[tbd]</sup>
-
-```c++
-std::has_unique_object_representations_v<foo>
-```
-
-**Description:** Checks wither the given type is trivially copyable and any two
-objects with the same value have the same object representation.
-
-**Documentation:**
-[std::has_unique_object_representations](https://en.cppreference.com/w/cpp/types/has_unique_object_representations)
-
-**Notes:**
-*** promo
-None
-***
-
-### std::clamp <sup>[tbd]</sup>
-
-```c++
-int x = base::clamp(inp, 0, 100);
-```
-
-**Description:** Clamps a value between a minimum and a maximum.
-
-**Documentation:**
-[std::clamp](https://en.cppreference.com/w/cpp/algorithm/clamp)
-
-**Notes:**
-*** promo
-See also `base::clamp`.
-***
-
-### std::reduce <sup>[tbd]</sup>
-
-```c++
-std::reduce(std::execution::par, v.cbegin(), v.cend());
-```
-
-**Description:** Like `std::accumulate` except the elements of the range may be
-grouped and rearranged in arbitrary order.
-
-**Documentation:**
-[std::reduce](https://en.cppreference.com/w/cpp/algorithm/reduce)
-
-**Notes:**
-*** promo
-Makes the most sense in conjunction with `std::execution::par`.
-***
-
-### std::inclusive_scan <sup>[tbd]</sup>
-
-```c++
-std::inclusive_scan(data.begin(), data.end(), output.begin());
-```
-
-**Description:** Like `std::accumulate` but writes the result at each step into
-the output range.
-
-**Documentation:**
-[std::inclusive_scan](https://en.cppreference.com/w/cpp/algorithm/inclusive_scan)
-
-**Notes:**
-*** promo
-None
-***
-
-### std::exclusive_scan <sup>[tbd]</sup>
-
-```c++
-std::exclusive_scan(data.begin(), data.end(), output.begin());
-```
-
-**Description:** Like `std::inclusive_scan` but omits the current element from
-the written output at each step; that is, results are "one value behind" those
-of `std::inclusive_scan`.
-
-**Documentation:**
-[std::exclusive_scan](https://en.cppreference.com/w/cpp/algorithm/exclusive_scan)
-
-**Notes:**
-*** promo
-None
-***
-
-### std::gcd <sup>[tbd]</sup>
-
-```c++
-static_assert(std::gcd(12, 18) == 6);
-```
-
-**Description:** Computes the greatest common divisor of its arguments.
-
-**Documentation:**
-[std::gcd](https://en.cppreference.com/w/cpp/numeric/gcd)
-
-**Notes:**
-*** promo
-None
-***
-
-### std::lcm <sup>[tbd]</sup>
-
-```c++
-static_assert(std::lcm(12, 18) == 36);
-```
-
-**Description:** Computes the least common multiple of its arguments.
-
-**Documentation:**
-[std::lcm](https://en.cppreference.com/w/cpp/numeric/lcm)
-
-**Notes:**
-*** promo
-None
-***
-
-### Non-member std::size/std::empty/std::data <sup>[tbd]</sup>
-
-```c++
-for (std::size_t i = 0; i < std::size(c); ++i) { ...
-if (!std::empty(c)) { ...
-std::strcpy(arr, std::data(str));
-```
-
-**Description:** Non-member versions of what are normally member functions, for
-symmetrical use with things like arrays and initializer_lists.
-
-**Documentation:**
-[std::size](https://en.cppreference.com/w/cpp/iterator/size),
-[std::empty](https://en.cppreference.com/w/cpp/iterator/empty),
-[std::data](https://en.cppreference.com/w/cpp/iterator/data)
-
-**Notes:**
-*** promo
-See `base::size`, `base::empty`, and `base::data`.
-***
-
-### Mathematical special functions <sup>[tbd]</sup>
-
-```c++
-std::assoc_laguerre()
-std::assoc_legendre()
-std::beta()
-std::comp_ellint_1()
-std::comp_ellint_2()
-std::comp_ellint_3()
-std::cyl_bessel_i()
-std::cyl_bessel_j()
-std::cyl_bessel_k()
-std::cyl_neumann()
-std::ellint_1()
-std::ellint_2()
-std::ellint_3()
-std::expint()
-std::hermite()
-std::legendre()
-std::laguerre()
-std::riemann_zeta()
-std::sph_bessel()
-std::sph_legendre()
-std::sph_neumann()
-```
-
-**Description:** A variety of mathematical functions.
-
-**Documentation:**
-[Mathematical special functions](https://en.cppreference.com/w/cpp/numeric/special_functions)
-
-**Notes:**
-*** promo
-May not be supported in libc++, according to the
-[library features table](https://en.cppreference.com/w/cpp/17)
-***
-
-### 3D std::hypot <sup>[tbd]</sup>
-
-```c++
-double dist = std::hypot(1.0, 2.5, 3.7);
-```
-
-**Description:** Computes the distance from the origin in 3D space.
-
-**Documentation:**
-[std::hypot](https://en.cppreference.com/w/cpp/numeric/math/hypot)
-
-**Notes:**
-*** promo
-None
-***
-
-### Cache line interface <sup>[tbd]</sup>
-
-```c++
-alignas(std::hardware_destructive_interference_size) std::atomic<int> cat;
-static_assert(sizeof(S) <= std::hardware_constructive_interference_size);
-```
-
-**Description:** A portable way to access the L1 data cache line size.
-
-**Documentation:**
-[Hardware interference size](https://en.cppreference.com/w/cpp/thread/hardware_destructive_interference_size)
-
-**Notes:**
-*** promo
-May not be supported in libc++, according to the
-[library features table](https://en.cppreference.com/w/cpp/17)
-***
-
-### std::launder <sup>[tbd]</sup>
-
-```c++
-struct Y { int z; };
-alignas(Y) std::byte s[sizeof(Y)];
-Y* q = new(&s) Y{2};
-const int h = std::launder(reinterpret_cast<Y*>(&s))->z;
-```
-
-**Description:** When used to wrap a pointer, makes it valid to access the
-resulting object in cases it otherwise wouldn't have been, in a very limited set
-of circumstances.
-
-**Documentation:**
-[std::launder](https://en.cppreference.com/w/cpp/utility/launder)
-
-**Notes:**
-*** promo
-None
-***
-
-### std::to_chars/std::from_chars <sup>[tbd]</sup>
-
-```c++
-std::to_chars(str.data(), str.data() + str.size(), 42);
-std::from_chars(str.data(), str.data() + str.size(), result);
-```
-
-**Description:** Locale-independent, non-allocating, non-throwing functions to
-convert values to/from character strings, designed for use in high-throughput
-contexts.
-
-**Documentation:**
-[std::to_chars](https://en.cppreference.com/w/cpp/utility/to_chars),
-[std::from_chars](https://en.cppreference.com/w/cpp/utility/from_chars)
-
-**Notes:**
-*** promo
-None
-***
-
-### std::atomic<T>::is_always_lock_free <sup>[tbd]</sup>
-
-```c++
-template <typename T>
-struct is_lock_free_impl
-: std::integral_constant<bool, std::atomic<T>::is_always_lock_free> {};
-```
-
-**Description:** True when the given atomic type is always lock-free.
-
-**Documentation:**
-[std::atomic<T>::is_always_lock_free](https://en.cppreference.com/w/cpp/atomic/atomic/is_always_lock_free)
-
-**Notes:**
-*** promo
-None
-***
-
-### std::scoped_lock <sup>[tbd]</sup>
-
-```c++
-std::scoped_lock lock(e1.m, e2.m);
-```
-
-**Description:** Provides an RAII-style mechanism for owning one or more mutexes
-for the duration of a scoped block.
-
-**Documentation:**
-[std::scoped_lock](https://en.cppreference.com/w/cpp/thread/scoped_lock)
-
-**Notes:**
-*** promo
-See also `base::AutoLock`.
-***
-
-### std::timespec_get <sup>[tbd]</sup>
-
-```c++
-std::timespec ts;
-std::timespec_get(&ts, TIME_UTC);
-```
-
-**Description:** Gets the current calendar time in the given time base.
-
-**Documentation:**
-[std::timespec_get](https://en.cppreference.com/w/cpp/chrono/c/timespec_get)
-
-**Notes:**
-*** promo
-None
-***
-
-## Abseil Allowed Library Features {#absl-allowlist}
-
-The following Abseil library features are allowed in the Chromium codebase.
-
-### Optional <sup>[allowed]</sup>
-
-```c++
-absl::optional
-```
-
-**Description:** Early adaptation of C++17 `std::optional`.
-
-**Documentation:**
-[std::optional](https://en.cppreference.com/w/cpp/utility/optional)
-
-**Notes:**
-*** promo
-Replaces `base::Optional`.
-[Discussion thread](https://groups.google.com/a/chromium.org/g/cxx/c/zUGqagX1NFU)
-***
-
-### Status <sup>[allowed]</sup>
-
-```c++
-absl::Status
-```
-
-**Description:** Type for returning detailed errors.
-
-**Documentation:**
-[status.h](https://source.chromium.org/chromium/chromium/src/+/main:third_party/abseil-cpp/absl/status/status.h)
-
-**Notes:**
-*** promo
-Approved for use inside a wrapper type. Use
-[abseil_string_conversions.h](https://source.chromium.org/chromium/chromium/src/+/main:base/strings/abseil_string_conversions.h)
-to convert to and from
-[absl::string_view](https://source.chromium.org/chromium/chromium/src/+/main:third_party/abseil-cpp/absl/strings/string_view.h)
-so the wrapper can expose
-[base::StringPiece](https://source.chromium.org/chromium/chromium/src/+/main:base/strings/string_piece.h).
-Use
-[absl::Cord](https://source.chromium.org/chromium/chromium/src/+/main:third_party/abseil-cpp/absl/strings/cord.h)
-directly as minimally necessary to interface; do not expose in the wrapper type
-API.
-
-[Discussion thread](https://groups.google.com/a/chromium.org/g/cxx/c/ImdFCSZ-NMA)
-***
-
-### Variant <sup>[allowed]</sup>
-
-```c++
-absl::variant
-```
-
-**Description:** Early adaptation of C++17 `std::variant`.
-
-**Documentation:**
-[std::variant](https://en.cppreference.com/w/cpp/utility/variant)
-
-**Notes:**
-*** promo
-[Discussion thread](https://groups.google.com/a/chromium.org/g/cxx/c/DqvG-TpvMyU)
-***
-
-## Abseil Banned Library Features {#absl-blocklist}
-
-The following Abseil library features are not allowed in the Chromium codebase.
-
-### Any <sup>[banned]</sup>
-
-```c++
-absl::any a = int{5};
-EXPECT_THAT(absl::any_cast<int>(&a), Pointee(5));
-EXPECT_EQ(absl::any_cast<size_t>(&a), nullptr);
-```
-
-**Description:** Early adaptation of C++17 `std::any`.
-
-**Documentation:** [std::any](https://en.cppreference.com/w/cpp/utility/any)
-
-**Notes:**
-*** promo
-Banned since workaround for lack of RTTI isn't compatible with the component
-build ([Bug](https://crbug.com/1096380)). Also see `std::any`.
-***
-
-### Command line flags <sup>[banned]</sup>
-
-```c++
-ABSL_FLAG(bool, logs, false, "print logs to stderr");
-app --logs=true;
-```
-
-**Description:** Allows programmatic access to flag values passed on the
-command-line to binaries.
-
-**Documentation:** [Flags Library](https://abseil.io/docs/cpp/guides/flags)
-
-**Notes:**
-*** promo
-Banned since workaround for lack of RTTI isn't compatible with the component
-build. ([Bug](https://crbug.com/1096380)) Use `base::CommandLine` instead.
-***
-
-### Span <sup>[banned]</sup>
-
-```c++
-absl::Span
-```
-
-**Description:** Early adaptation of C++20 `std::span`.
-
-**Documentation:** [Using absl::Span](https://abseil.io/tips/93)
-
-**Notes:**
-*** promo
-Banned due to being less std::-compliant than `base::span`. Keep using
-`base::span`.
-***
-
-### string_view <sup>[banned]</sup>
-
-```c++
-absl::string_view
-```
-
-**Description:** Early adaptation of C++17 `std::string_view`.
-
-**Documentation:** [absl::string_view](https://abseil.io/tips/1)
-
-**Notes:**
-*** promo
-Banned due to only working with 8-bit characters. Keep using
-`base::StringPiece` from `base/strings/`.
-***
-
-## Abseil TBD Features {#absl-review}
-
-The following Abseil library features are not allowed in the Chromium codebase.
-See the top of this page on how to propose moving a feature from this list into
-the allowed or banned sections.
-
-### 128bit integer <sup>[tbd]</sup>
-
-```c++
-uint64_t a;
-absl::uint128 v = a;
-```
-
-**Description:** Signed and unsigned 128-bit integer types meant to mimic
-intrinsic types as closely as possible.
-
-**Documentation:**
-[Numerics](https://abseil.io/docs/cpp/guides/numeric)
-
-**Notes:**
-*** promo
-None
-***
-
-### bind_front <sup>[tbd]</sup>
-
-```c++
-absl::bind_front
-```
-
-**Description:** Binds the first N arguments of an invocable object and stores them by value.
-
-**Documentation:**
-*   [bind_front.h](https://source.chromium.org/chromium/chromium/src/+/main:third_party/abseil-cpp/absl/functional/bind_front.h)
-*   [Avoid std::bind](https://abseil.io/tips/108)
-
-**Notes:**
-*** promo
-Overlaps with `base::Bind`.
-***
-
-### Cleanup <sup>[tbd]</sup>
-
-```c++
-FILE* sink_file = fopen(sink_path, "w");
-auto sink_closer = absl::MakeCleanup([sink_file] { fclose(sink_file); });
-```
-
-**Description:** Implements the scope guard idiom, invoking the contained
-callback's `operator()() &&` on scope exit.
-
-**Documentation:**
-[cleanup.h](https://source.chromium.org/chromium/chromium/src/+/main:third_party/abseil-cpp/absl/cleanup/cleanup.h)
-
-**Notes:**
-*** promo
-Similar to `defer` in Golang.
-***
-
-### Containers <sup>[tbd]</sup>
-
-```c++
-absl::flat_hash_map
-absl::flat_hash_set
-absl::node_hash_map
-absl::node_hash_set
-absl::btree_map
-absl::btree_set
-absl::btree_multimap
-absl::btree_multiset
-absl::InlinedVector
-absl::FixedArray
-```
-
-**Description:** Alternatives to STL containers designed to be more efficient
-in the general case.
-
-**Documentation:**
-*   [Containers](https://abseil.io/docs/cpp/guides/container)
-*   [Hash](https://abseil.io/docs/cpp/guides/hash)
-
-**Notes:**
-*** promo
-Supplements `base/containers/`.
-***
-
-### Container utilities <sup>[tbd]</sup>
-
-```c++
-auto it = absl::c_find(container, value);
-```
-
-**Description:** Container-based versions of algorithmic functions within C++
-standard library.
-
-**Documentation:**
-[container.h](https://source.chromium.org/chromium/chromium/src/+/main:third_party/abseil-cpp/absl/algorithm/container.h)
-
-**Notes:**
-*** promo
-Overlaps with `base/ranges/algorithm.h`.
-***
-
-### FunctionRef <sup>[tbd]</sup>
-
-```c++
-absl::FunctionRef
-```
-
-**Description:** Type for holding a non-owning reference to an object of any
-invocable type.
-
-**Documentation:**
-[function_ref.h](https://source.chromium.org/chromium/chromium/src/+/main:third_party/abseil-cpp/absl/functional/function_ref.h)
-
-**Notes:**
-*** promo
-None
-***
-
-### Random <sup>[tbd]</sup>
-
-```c++
-absl::BitGen bitgen;
-size_t index = absl::Uniform(bitgen, 0u, elems.size());
-```
-
-**Description:** Functions and utilities for generating pseudorandom data.
-
-**Documentation:** [Random library](https://abseil.io/docs/cpp/guides/random)
-
-**Notes:**
-*** promo
-Overlaps with `base/rand_util.h`.
-***
-
-### StatusOr <sup>[tbd]</sup>
-
-```c++
-absl::StatusOr<T>
-```
-
-**Description:** An object that is either a usable value, or an error Status
-explaining why such a value is not present.
-
-**Documentation:**
-[statusor.h](https://source.chromium.org/chromium/chromium/src/+/main:third_party/abseil-cpp/absl/status/statusor.h)
-
-**Notes:**
-*** promo
-None
-***
-
-### String Formatting <sup>[tbd]</sup>
-
-```c++
-absl::StrFormat
-```
-
-**Description:** A typesafe replacement for the family of printf() string
-formatting routines.
-
-**Documentation:**
-[String Formatting](https://abseil.io/docs/cpp/guides/format)
-
-**Notes:**
-*** promo
-None
-***
-
-### Strings Library <sup>[tbd]</sup>
-
-```c++
-absl::StrSplit
-absl::StrJoin
-absl::StrCat
-absl::StrAppend
-absl::Substitute
-absl::StrContains
-```
-
-**Description:** Classes and utility functions for manipulating and comparing
-strings.
-
-**Documentation:**
-[String Utilities](https://abseil.io/docs/cpp/guides/strings)
-
-**Notes:**
-*** promo
-Overlaps with `base/strings`.
-***
-
-### Synchronization <sup>[tbd]</sup>
-
-```c++
-absl::Mutex
-```
-
-**Description:** Primitives for managing tasks across different threads.
-
-**Documentation:**
-[Synchronization](https://abseil.io/docs/cpp/guides/synchronization)
-
-**Notes:**
-*** promo
-Overlaps with `Lock` in `base/synchronization/`.
-***
-
-### Time library <sup>[tbd]</sup>
-
-```c++
-absl::Duration
-absl::Time
-absl::TimeZone
-absl::CivilDay
-```
-
-**Description:** Abstractions for holding time values, both in terms of
-absolute time and civil time.
-
-**Documentation:** [Time](https://abseil.io/docs/cpp/guides/time)
-
-**Notes:**
-*** promo
-Overlaps with `Time` APIs in `base/`.
-***
+Please update your links to that document.
diff --git a/styleguide/styleguide.md b/styleguide/styleguide.md
index 7949285..d4b2632 100644
--- a/styleguide/styleguide.md
+++ b/styleguide/styleguide.md
@@ -3,7 +3,7 @@
 ## Main style guides
 
 *   [Chromium C++ style guide](c++/c++.md)
-    *   [Modern C++ use](c++/c++11.md) for allowed/banned features.
+    *   [Modern C++ use](c++/c++-features.md) for allowed/banned features.
     *   See also: [C++ Dos and Don'ts](c++/c++-dos-and-donts.md) for Chromium
         best-practices.
 *   [Chromium Objective-C style guide](objective-c/objective-c.md)
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index f65d9cc..9cadf1d 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -27962,11 +27962,6 @@
       }
     ]
   },
-  "ios-catalyst": {
-    "additional_compile_targets": [
-      "form_activity_tab_helper_fuzzer"
-    ]
-  },
   "ios-reclient": {
     "additional_compile_targets": [
       "all"
diff --git a/testing/buildbot/chromium.mac.json b/testing/buildbot/chromium.mac.json
index f278d2e..dd56226 100644
--- a/testing/buildbot/chromium.mac.json
+++ b/testing/buildbot/chromium.mac.json
@@ -12255,6 +12255,11 @@
       }
     ]
   },
+  "ios-catalyst": {
+    "additional_compile_targets": [
+      "form_activity_tab_helper_fuzzer"
+    ]
+  },
   "ios-device": {
     "additional_compile_targets": [
       "all"
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl
index 90cdd17..bf05b0f 100644
--- a/testing/buildbot/waterfalls.pyl
+++ b/testing/buildbot/waterfalls.pyl
@@ -2933,15 +2933,6 @@
           'isolated_scripts': 'ios_asan_tests',
         }
       },
-      'ios-catalyst': {
-        'additional_compile_targets': [
-          # TODO(crbug.com/1266211): Add //ios/chrome/app:chrome as a compile
-          # target.
-          # TODO(crbug.com/1256485): The bot won't need to compile fuzzers after
-          # the clusterfuzz upload bot is set up.
-          'form_activity_tab_helper_fuzzer',
-        ],
-      },
       # TODO(crbug.com/1254986): remove this after the migration.
       'ios-reclient': {
         'additional_compile_targets': [
@@ -5087,6 +5078,15 @@
           'isolated_scripts': 'chromium_dbg_isolated_scripts',
         },
       },
+      'ios-catalyst': {
+        'additional_compile_targets': [
+          # TODO(crbug.com/1266211): Add //ios/chrome/app:chrome as a compile
+          # target.
+          # TODO(crbug.com/1256485): The bot won't need to compile fuzzers after
+          # the clusterfuzz upload bot is set up.
+          'form_activity_tab_helper_fuzzer',
+        ],
+      },
       'ios-device': {
         'additional_compile_targets': [
           'all',
diff --git a/third_party/abseil-cpp/README.chromium b/third_party/abseil-cpp/README.chromium
index 0106205..f8eb8cee 100644
--- a/third_party/abseil-cpp/README.chromium
+++ b/third_party/abseil-cpp/README.chromium
@@ -10,7 +10,7 @@
 Description:
 This directory contains the source code of Abseil for C++. This can be used by
 Chromium, subject to the guidance at
-https://chromium.googlesource.com/chromium/src/+/main/styleguide/c++/c++11.md;
+https://chromium.googlesource.com/chromium/src/+/main/styleguide/c++/c++-features.md;
 it can be used without restriction by Chromium's dependencies, except that
 objects compiled into Chromium itself cannot use anything relying on
 absl::base_internal::FastTypeId (see https://crbug.com/1096380).
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc
index b1b5a37..e9502f5 100644
--- a/third_party/blink/common/features.cc
+++ b/third_party/blink/common/features.cc
@@ -347,6 +347,10 @@
 const char kIntensiveWakeUpThrottling_GracePeriodSeconds_Name[] =
     "grace_period_seconds";
 
+// Throttles Javascript timer wake ups on foreground pages.
+const base::Feature kThrottleForegroundTimers{
+    "ThrottleForegroundTimers", base::FEATURE_DISABLED_BY_DEFAULT};
+
 #if BUILDFLAG(RTC_USE_H264) && BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS)
 // Run-time feature for the |rtc_use_h264| encoder/decoder.
 const base::Feature kWebRtcH264WithOpenH264FFmpeg{
@@ -414,10 +418,6 @@
 const base::Feature kFontAccess{"FontAccess",
                                 base::FEATURE_DISABLED_BY_DEFAULT};
 
-// Font enumeration and data access. https://crbug.com/1173275
-const base::Feature kFontAccessPersistent{"FontAccessPersistent",
-                                          base::FEATURE_DISABLED_BY_DEFAULT};
-
 // Kill switch for the Compute Pressure API. https://crbug.com/1067627
 const base::Feature kComputePressure{"ComputePressure",
                                      base::FEATURE_ENABLED_BY_DEFAULT};
@@ -837,7 +837,7 @@
 
 // Controls URL handling feature in web apps. Controls parsing of "url_handlers"
 // field in web app manifests. See explainer for more information:
-// https://github.com/WICG/pwa-url-handler/blob/master/explainer.md
+// https://github.com/WICG/pwa-url-handler/blob/main/explainer.md
 const base::Feature kWebAppEnableUrlHandlers{"WebAppEnableUrlHandlers",
                                              base::FEATURE_DISABLED_BY_DEFAULT};
 
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h
index 2791799..b04c9c1 100644
--- a/third_party/blink/public/common/features.h
+++ b/third_party/blink/public/common/features.h
@@ -116,6 +116,7 @@
 BLINK_COMMON_EXPORT extern const base::Feature kIntensiveWakeUpThrottling;
 BLINK_COMMON_EXPORT extern const char
     kIntensiveWakeUpThrottling_GracePeriodSeconds_Name[];
+BLINK_COMMON_EXPORT extern const base::Feature kThrottleForegroundTimers;
 
 #if BUILDFLAG(RTC_USE_H264) && BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS)
 BLINK_COMMON_EXPORT extern const base::Feature kWebRtcH264WithOpenH264FFmpeg;
@@ -131,7 +132,6 @@
 BLINK_COMMON_EXPORT extern const base::Feature kTextFragmentAnchor;
 BLINK_COMMON_EXPORT extern const base::Feature kCssSelectorFragmentAnchor;
 BLINK_COMMON_EXPORT extern const base::Feature kFontAccess;
-BLINK_COMMON_EXPORT extern const base::Feature kFontAccessPersistent;
 BLINK_COMMON_EXPORT extern const base::Feature kComputePressure;
 BLINK_COMMON_EXPORT extern const base::Feature kFileHandlingAPI;
 BLINK_COMMON_EXPORT extern const base::Feature kFileHandlingIcons;
diff --git a/third_party/blink/public/mojom/font_access/font_access.mojom b/third_party/blink/public/mojom/font_access/font_access.mojom
index 3831c8b..5185728b 100644
--- a/third_party/blink/public/mojom/font_access/font_access.mojom
+++ b/third_party/blink/public/mojom/font_access/font_access.mojom
@@ -39,9 +39,4 @@
   // Enumerate locally installed fonts. Results will be gated by a permission
   // check.
   EnumerateLocalFonts() => (FontEnumerationStatus enumeration_status, mojo_base.mojom.ReadOnlySharedMemoryRegion? enumeration_table);
-  // Begins a UX that gives affordances for a user to choose fonts to be shared
-  // with the page.
-  // `selection`, if not empty, will limit the font selection to those matching
-  // the supplied list.
-  ChooseLocalFonts(array<string> selection) => (FontEnumerationStatus status, array<FontMetadata> chosen_fonts);
 };
diff --git a/third_party/blink/public/web/web_local_frame.h b/third_party/blink/public/web/web_local_frame.h
index 9a6c8c8..2ce14df 100644
--- a/third_party/blink/public/web/web_local_frame.h
+++ b/third_party/blink/public/web/web_local_frame.h
@@ -741,6 +741,11 @@
   virtual uint32_t PrintBegin(const WebPrintParams& print_params,
                               const WebNode& constrain_to_node) = 0;
 
+  // Called when printing has been requested, but has not yet begun. This
+  // gives the document an opportunity to load any new resources needed for
+  // printing. It returns whether any resources will need to load.
+  virtual bool WillPrintSoon() = 0;
+
   // Returns the page shrinking factor calculated by webkit (usually
   // between 1/1.33 and 1/2). Returns 0 if the page number is invalid or
   // not in printing mode.
diff --git a/third_party/blink/public/web/web_local_frame_client.h b/third_party/blink/public/web/web_local_frame_client.h
index 994841c..81d0f6aa 100644
--- a/third_party/blink/public/web/web_local_frame_client.h
+++ b/third_party/blink/public/web/web_local_frame_client.h
@@ -424,6 +424,10 @@
   // The frame's document and all of its subresources succeeded to load.
   virtual void DidFinishLoad() {}
 
+  // The frame's document and all of its subresources succeeded to load for
+  // printing.
+  virtual void DidFinishLoadForPrinting() {}
+
   // The navigation resulted in no change to the documents within the page.
   // For example, the navigation may have just resulted in scrolling to a named
   // anchor or a PopState event may have been dispatched.
diff --git a/third_party/blink/public/web/web_performance.h b/third_party/blink/public/web/web_performance.h
index 1c04c05..0044e92 100644
--- a/third_party/blink/public/web/web_performance.h
+++ b/third_party/blink/public/web/web_performance.h
@@ -125,6 +125,7 @@
   BLINK_EXPORT uint64_t ExperimentalLargestImagePaintSize() const;
   BLINK_EXPORT LargestContentfulPaintTypeMask
   LargestContentfulPaintType() const;
+  BLINK_EXPORT double LargestContentfulPaintImageBPP() const;
   BLINK_EXPORT double ExperimentalLargestTextPaint() const;
   BLINK_EXPORT uint64_t ExperimentalLargestTextPaintSize() const;
   BLINK_EXPORT double FirstEligibleToPaint() const;
diff --git a/third_party/blink/renderer/bindings/core/v8/custom/v8_dev_tools_host_custom.cc b/third_party/blink/renderer/bindings/core/v8/custom/v8_dev_tools_host_custom.cc
index 90f5f3a..6b5772d 100644
--- a/third_party/blink/renderer/bindings/core/v8/custom/v8_dev_tools_host_custom.cc
+++ b/third_party/blink/renderer/bindings/core/v8/custom/v8_dev_tools_host_custom.cc
@@ -49,9 +49,9 @@
 
 void V8DevToolsHost::PlatformMethodCustom(
     const v8::FunctionCallbackInfo<v8::Value>& info) {
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
   V8SetReturnValue(info, V8AtomicString(info.GetIsolate(), "mac"));
-#elif defined(OS_WIN)
+#elif BUILDFLAG(IS_WIN)
   V8SetReturnValue(info, V8AtomicString(info.GetIsolate(), "windows"));
 #else  // Unix-like systems
   V8SetReturnValue(info, V8AtomicString(info.GetIsolate(), "linux"));
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_fuzzer.cc b/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_fuzzer.cc
index 834d85e..5691ce1 100644
--- a/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_fuzzer.cc
+++ b/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_fuzzer.cc
@@ -118,9 +118,9 @@
 // Explicitly specify some attributes to avoid issues with the linker dead-
 // stripping the following function on macOS, as it is not called directly
 // by fuzz target. LibFuzzer runtime uses dlsym() to resolve that function.
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
 __attribute__((used)) __attribute__((visibility("default")))
-#endif  // defined(OS_MAC)
+#endif  // BUILDFLAG(IS_MAC)
 extern "C" int
 LLVMFuzzerInitialize(int* argc, char*** argv) {
   return blink::LLVMFuzzerInitialize(argc, argv);
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc
index cbd00a0..a70d187 100644
--- a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc
+++ b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc
@@ -1124,7 +1124,7 @@
 // this test intends to ensure that a platform can decode images it has
 // previously written. At format version 9, Android writes RGBA and every
 // other platform writes BGRA.
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   scoped_refptr<SerializedScriptValue> input =
       SerializedValue({0xff, 0x09, 0x3f, 0x00, 0x67, 0x01, 0x01, 0x02, 0x01,
                        0x08, 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff});
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_gc_for_context_dispose.cc b/third_party/blink/renderer/bindings/core/v8/v8_gc_for_context_dispose.cc
index 87ca8e8..7a0a5e7 100644
--- a/third_party/blink/renderer/bindings/core/v8/v8_gc_for_context_dispose.cc
+++ b/third_party/blink/renderer/bindings/core/v8/v8_gc_for_context_dispose.cc
@@ -43,7 +43,7 @@
 namespace blink {
 namespace {
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 size_t GetMemoryUsage() {
   size_t usage =
       base::ProcessMetrics::CreateCurrentProcessMetrics()->GetMallocUsage() +
@@ -54,7 +54,7 @@
   usage += v8_heap_statistics.total_heap_size();
   return usage;
 }
-#endif  // defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_ANDROID)
 
 }  // namespace
 
@@ -67,7 +67,7 @@
 void V8GCForContextDispose::NotifyContextDisposed(
     bool is_main_frame,
     WindowProxy::FrameReuseStatus frame_reuse_status) {
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   // When a low end device is in a low memory situation we should prioritize
   // memory use and trigger a V8+Blink GC. However, on Android, if the frame
   // will not be reused, the process will likely to be killed soon so skip this.
@@ -88,7 +88,7 @@
 
     force_page_navigation_gc_ = false;
   }
-#endif  // defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_ANDROID)
   V8PerIsolateData::MainThreadIsolate()->ContextDisposedNotification(
       !is_main_frame);
 }
diff --git a/third_party/blink/renderer/controller/blink_initializer.cc b/third_party/blink/renderer/controller/blink_initializer.cc
index 109d240..2cb13be8 100644
--- a/third_party/blink/renderer/controller/blink_initializer.cc
+++ b/third_party/blink/renderer/controller/blink_initializer.cc
@@ -66,23 +66,23 @@
 #include "third_party/blink/renderer/extensions/chromeos/chromeos_extensions.h"
 #endif
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 #include "third_party/blink/renderer/controller/crash_memory_metrics_reporter_impl.h"
 #include "third_party/blink/renderer/controller/oom_intervention_impl.h"
 #endif
 
-#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
 #include "third_party/blink/renderer/controller/memory_usage_monitor_posix.h"
 #endif
 
-#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) || \
-    defined(OS_MAC) || defined(OS_WIN)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) || \
+    BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
 #include "third_party/blink/renderer/controller/highest_pmf_reporter.h"
 #include "third_party/blink/renderer/controller/user_level_memory_pressure_signal_generator.h"
 #endif
 
 // #if expression should match the one in InitializeCommon
-#if !defined(ARCH_CPU_X86_64) && !defined(ARCH_CPU_ARM64) && defined(OS_WIN)
+#if !defined(ARCH_CPU_X86_64) && !defined(ARCH_CPU_ARM64) && BUILDFLAG(IS_WIN)
 #include <windows.h>
 #endif
 
@@ -112,7 +112,7 @@
 
 void InitializeCommon(Platform* platform, mojo::BinderMap* binders) {
 // #if expression should match the one around #include <windows.h>
-#if !defined(ARCH_CPU_X86_64) && !defined(ARCH_CPU_ARM64) && defined(OS_WIN)
+#if !defined(ARCH_CPU_X86_64) && !defined(ARCH_CPU_ARM64) && BUILDFLAG(IS_WIN)
   // Reserve address space on 32 bit Windows, to make it likelier that large
   // array buffer allocations succeed.
   BOOL is_wow_64 = -1;
@@ -128,7 +128,7 @@
     }
   }
 #endif  // !defined(ARCH_CPU_X86_64) && !defined(ARCH_CPU_ARM64) &&
-        // defined(OS_WIN)
+        // BUILDFLAG(IS_WIN)
 
   // BlinkInitializer::Initialize() must be called before InitializeMainThread
   GetBlinkInitializer().Initialize();
@@ -149,14 +149,14 @@
   ChromeOSExtensions::Initialize();
 #endif
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   // Initialize CrashMemoryMetricsReporterImpl in order to assure that memory
   // allocation does not happen in OnOOMCallback.
   CrashMemoryMetricsReporterImpl::Instance();
 #endif
 
-#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) || \
-    defined(OS_MAC) || defined(OS_WIN)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) || \
+    BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
   // Initialize UserLevelMemoryPressureSignalGenerator so it starts monitoring.
   if (UserLevelMemoryPressureSignalGenerator::Enabled())
     UserLevelMemoryPressureSignalGenerator::Instance();
@@ -217,7 +217,7 @@
   if (!main_thread->GetTaskRunner())
     return;
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   binders.Add(ConvertToBaseRepeatingCallback(
                   CrossThreadBindRepeating(&OomInterventionImpl::BindReceiver)),
               main_thread->GetTaskRunner());
@@ -227,7 +227,7 @@
               main_thread->GetTaskRunner());
 #endif
 
-#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
   binders.Add(ConvertToBaseRepeatingCallback(
                   CrossThreadBindRepeating(&MemoryUsageMonitorPosix::Bind)),
               main_thread->GetTaskRunner());
diff --git a/third_party/blink/renderer/controller/memory_usage_monitor_posix.cc b/third_party/blink/renderer/controller/memory_usage_monitor_posix.cc
index ac78ff7..a133857 100644
--- a/third_party/blink/renderer/controller/memory_usage_monitor_posix.cc
+++ b/third_party/blink/renderer/controller/memory_usage_monitor_posix.cc
@@ -7,8 +7,10 @@
 #include <ctype.h>
 #include <fcntl.h>
 #include <unistd.h>
+
 #include <utility>
 
+#include "build/build_config.h"
 #include "third_party/blink/public/platform/platform.h"
 
 namespace blink {
@@ -94,7 +96,7 @@
 }
 
 void MemoryUsageMonitorPosix::GetProcessMemoryUsage(MemoryUsage& usage) {
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   ResetFileDescriptors();
 #endif
   if (!statm_fd_.is_valid() || !status_fd_.is_valid())
@@ -110,7 +112,7 @@
   }
 }
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 void MemoryUsageMonitorPosix::ResetFileDescriptors() {
   if (file_descriptors_reset_)
     return;
@@ -134,7 +136,7 @@
   status_fd_.reset(status_file.TakePlatformFile());
 }
 
-#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
 // static
 void MemoryUsageMonitorPosix::Bind(
     mojo::PendingReceiver<mojom::blink::MemoryUsageMonitorLinux> receiver) {
diff --git a/third_party/blink/renderer/controller/memory_usage_monitor_posix.h b/third_party/blink/renderer/controller/memory_usage_monitor_posix.h
index 90921f0..90f31ffe 100644
--- a/third_party/blink/renderer/controller/memory_usage_monitor_posix.h
+++ b/third_party/blink/renderer/controller/memory_usage_monitor_posix.h
@@ -13,7 +13,7 @@
 #include "third_party/blink/renderer/controller/controller_export.h"
 #include "third_party/blink/renderer/controller/memory_usage_monitor.h"
 
-#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
 #include "third_party/blink/public/mojom/memory_usage_monitor_linux.mojom-blink.h"
 #endif
 
@@ -22,7 +22,7 @@
 // MemoryUsageMonitor implementation for Android and Linux.
 class CONTROLLER_EXPORT MemoryUsageMonitorPosix
     : public MemoryUsageMonitor
-#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
     ,
       public mojom::blink::MemoryUsageMonitorLinux
 #endif
@@ -30,7 +30,7 @@
  public:
   MemoryUsageMonitorPosix() = default;
 
-#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
   static void Bind(
       mojo::PendingReceiver<mojom::blink::MemoryUsageMonitorLinux> receiver);
 #endif
@@ -48,12 +48,12 @@
                                               uint64_t* vm_size,
                                               uint64_t* vm_hwm_size);
 
-#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
   // mojom::MemoryUsageMonitorLinux implementations:
   void SetProcFiles(base::File statm_file, base::File status_file) override;
 #endif
 
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
   void ResetFileDescriptors();
   // For Android, SetProcFiles is used only for testing.
   void SetProcFiles(base::File statm_file, base::File status_file);
@@ -66,7 +66,7 @@
   base::ScopedFD statm_fd_;
   base::ScopedFD status_fd_;
 
-#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
   mojo::Receiver<mojom::blink::MemoryUsageMonitorLinux> receiver_{this};
 #endif
 };
diff --git a/third_party/blink/renderer/controller/user_level_memory_pressure_signal_generator_test.cc b/third_party/blink/renderer/controller/user_level_memory_pressure_signal_generator_test.cc
index 5a51a8ce..87dc1db 100644
--- a/third_party/blink/renderer/controller/user_level_memory_pressure_signal_generator_test.cc
+++ b/third_party/blink/renderer/controller/user_level_memory_pressure_signal_generator_test.cc
@@ -92,7 +92,7 @@
 constexpr double kMemoryThresholdBytes = 1024 * 1024 * 1024;
 
 // Flaky on Android, see crbug/1054788.
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 #define MAYBE_GeneratesWhenOverThreshold DISABLED_GeneratesWhenOverThreshold
 #else
 #define MAYBE_GeneratesWhenOverThreshold GeneratesWhenOverThreshold
@@ -138,7 +138,7 @@
 }
 
 // Flaky on Android, see crbug/1058178.
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
 #define MAYBE_GenerationPauses DISABLED_GenerationPauses
 #else
 #define MAYBE_GenerationPauses GenerationPauses
diff --git a/third_party/blink/renderer/core/css/invalidation/invalidation_set.cc b/third_party/blink/renderer/core/css/invalidation/invalidation_set.cc
index 92d4924e..19892c9 100644
--- a/third_party/blink/renderer/core/css/invalidation/invalidation_set.cc
+++ b/third_party/blink/renderer/core/css/invalidation/invalidation_set.cc
@@ -266,10 +266,11 @@
 StringImpl* InvalidationSet::FindAnyClass(Element& element) const {
   const SpaceSplitString& class_names = element.ClassNames();
   wtf_size_t size = class_names.size();
-  if (StringImpl* string_impl = classes_.GetStringImpl(backing_flags_)) {
+  if (const AtomicString& string_impl =
+          classes_.GetAtomicString(backing_flags_)) {
     for (wtf_size_t i = 0; i < size; ++i) {
-      if (Equal(string_impl, class_names[i].Impl()))
-        return string_impl;
+      if (Equal(string_impl.Impl(), class_names[i].Impl()))
+        return string_impl.Impl();
     }
   }
   if (const HashSet<AtomicString>* set = classes_.GetHashSet(backing_flags_)) {
@@ -283,9 +284,10 @@
 }
 
 StringImpl* InvalidationSet::FindAnyAttribute(Element& element) const {
-  if (StringImpl* string_impl = attributes_.GetStringImpl(backing_flags_)) {
-    if (element.HasAttributeIgnoringNamespace(AtomicString(string_impl)))
-      return string_impl;
+  if (const AtomicString& string_impl =
+          attributes_.GetAtomicString(backing_flags_)) {
+    if (element.HasAttributeIgnoringNamespace(string_impl))
+      return string_impl.Impl();
   }
   if (const HashSet<AtomicString>* set =
           attributes_.GetHashSet(backing_flags_)) {
diff --git a/third_party/blink/renderer/core/css/invalidation/invalidation_set.h b/third_party/blink/renderer/core/css/invalidation/invalidation_set.h
index 0e39224..d35de03 100644
--- a/third_party/blink/renderer/core/css/invalidation/invalidation_set.h
+++ b/third_party/blink/renderer/core/css/invalidation/invalidation_set.h
@@ -245,7 +245,7 @@
 
   // Each BackingType has a corresponding bit in an instance of this class. A
   // set bit indicates that the Backing at that position is a HashSet. An unset
-  // bit indicates a StringImpl (which may be nullptr).
+  // bit indicates an AtomicString (which may be nullptr).
   class BackingFlags {
    private:
     uint8_t bits_ = 0;
@@ -257,14 +257,17 @@
   // attributes to invalidate. However, since it's common for these hash sets
   // to contain only one element (with a total capacity of 8), we avoid creating
   // the actual HashSets until we have more than one item. If a set contains
-  // just one item, we store a pointer to a StringImpl instead, along with a
-  // bit indicating either StringImpl or HashSet.
+  // just one item, we store a pointer to an AtomicString instead, along with a
+  // bit indicating either AtomicString or HashSet.
   //
   // The bits (see BackingFlags) associated with each Backing are stored on the
   // outside, to make sizeof(InvalidationSet) as small as possible.
   //
   // WARNING: Backings must be cleared manually in ~InvalidationSet, otherwise
-  //          a StringImpl or HashSet will leak.
+  //          an AtomicString or HashSet will leak.
+  //
+  // TODO: Consider de-unionizing this and using virtual classes to represent
+  // different backing types.
   template <BackingType type>
   union Backing {
     using Flags = BackingFlags;
@@ -272,32 +275,32 @@
                   "Enough bits in BackingFlags");
 
     // Adds an AtomicString to the associated Backing. If the Backing is
-    // currently empty, we simply AddRef the StringImpl of the incoming
-    // AtomicString. If the Backing already has one item, we first "upgrade"
+    // currently empty, we simply copy the incoming AtomicString. If the
+    // Backing already has one item, we first "upgrade"
     // to a HashSet, and add the AtomicString.
     void Add(Flags&, const AtomicString&);
-    // Clears the associated Backing. If the Backing is a StringImpl, it is
-    // released. If the Backing is a HashSet, it is deleted.
+    // Clears the associated Backing.
     void Clear(Flags&);
     bool Contains(const Flags&, const AtomicString&) const;
     bool IsEmpty(const Flags&) const;
     size_t Size(const Flags&) const;
     bool IsHashSet(const Flags& flags) const { return flags.bits_ & GetMask(); }
 
-    StringImpl* GetStringImpl(const Flags& flags) const {
-      return IsHashSet(flags) ? nullptr : string_impl_;
+    const AtomicString& GetAtomicString(const Flags& flags) const {
+      return (IsHashSet(flags) || !atomic_string_) ? g_null_atom
+                                                   : *atomic_string_;
     }
     const HashSet<AtomicString>* GetHashSet(const Flags& flags) const {
       return IsHashSet(flags) ? hash_set_ : nullptr;
     }
 
     // A simple forward iterator, which can either "iterate" over a single
-    // StringImpl, or act as a wrapper for HashSet<AtomicString>::iterator.
+    // AtomicString, or act as a wrapper for HashSet<AtomicString>::iterator.
     class Iterator {
      public:
       enum class Type { kString, kHashSet };
 
-      explicit Iterator(StringImpl* string_impl)
+      explicit Iterator(AtomicString* string_impl)
           : type_(Type::kString), string_(string_impl) {}
       explicit Iterator(HashSet<AtomicString>::iterator iterator)
           : type_(Type::kHashSet), hash_set_iterator_(iterator) {}
@@ -312,19 +315,20 @@
       bool operator!=(const Iterator& other) const { return !(*this == other); }
       void operator++() {
         if (type_ == Type::kString)
-          string_ = g_null_atom;
+          string_ = nullptr;
         else
           ++hash_set_iterator_;
       }
 
       const AtomicString& operator*() const {
-        return type_ == Type::kString ? string_ : *hash_set_iterator_;
+        return type_ == Type::kString ? (string_ ? *string_ : g_null_atom)
+                                      : *hash_set_iterator_;
       }
 
      private:
       Type type_;
       // Used when type_ is kString.
-      AtomicString string_;
+      AtomicString* string_;
       // Used when type_ is kHashSet.
       HashSet<AtomicString>::iterator hash_set_iterator_;
     };
@@ -342,9 +346,9 @@
 
     Range Items(const Flags& flags) const {
       Iterator begin = IsHashSet(flags) ? Iterator(hash_set_->begin())
-                                        : Iterator(string_impl_);
-      Iterator end = IsHashSet(flags) ? Iterator(hash_set_->end())
-                                      : Iterator(g_null_atom.Impl());
+                                        : Iterator(atomic_string_);
+      Iterator end =
+          IsHashSet(flags) ? Iterator(hash_set_->end()) : Iterator(nullptr);
       return Range(begin, end);
     }
 
@@ -353,7 +357,7 @@
     void SetIsString(Flags& flags) { flags.bits_ &= ~GetMask(); }
     void SetIsHashSet(Flags& flags) { flags.bits_ |= GetMask(); }
 
-    StringImpl* string_impl_ = nullptr;
+    AtomicString* atomic_string_ = nullptr;
     HashSet<AtomicString>* hash_set_;
   };
 
@@ -528,18 +532,17 @@
   DCHECK(!string.IsNull());
   if (IsHashSet(flags)) {
     hash_set_->insert(string);
-  } else if (string_impl_) {
-    if (Equal(string_impl_, string.Impl()))
+  } else if (atomic_string_) {
+    if (string == *atomic_string_)
       return;
-    AtomicString atomic_string(string_impl_);
-    string_impl_->Release();
+    AtomicString atomic_string(std::move(*atomic_string_));
+    delete atomic_string_;
     hash_set_ = new HashSet<AtomicString>();
-    hash_set_->insert(atomic_string);
+    hash_set_->insert(std::move(atomic_string));
     hash_set_->insert(string);
     SetIsHashSet(flags);
   } else {
-    string_impl_ = string.Impl();
-    string_impl_->AddRef();
+    atomic_string_ = new AtomicString(string);
   }
 }
 
@@ -549,12 +552,12 @@
   if (IsHashSet(flags)) {
     if (hash_set_) {
       delete hash_set_;
-      string_impl_ = nullptr;
+      hash_set_ = nullptr;
     }
   } else {
-    if (string_impl_) {
-      string_impl_->Release();
-      string_impl_ = nullptr;
+    if (atomic_string_) {
+      delete atomic_string_;
+      atomic_string_ = nullptr;
     }
   }
   SetIsString(flags);
@@ -566,15 +569,15 @@
     const AtomicString& string) const {
   if (IsHashSet(flags))
     return hash_set_->Contains(string);
-  if (string_impl_)
-    return Equal(string.Impl(), string_impl_);
+  if (atomic_string_)
+    return string == *atomic_string_;
   return false;
 }
 
 template <typename InvalidationSet::BackingType type>
 bool InvalidationSet::Backing<type>::IsEmpty(
     const InvalidationSet::BackingFlags& flags) const {
-  return !IsHashSet(flags) && !string_impl_;
+  return !IsHashSet(flags) && !atomic_string_;
 }
 
 template <typename InvalidationSet::BackingType type>
@@ -582,7 +585,7 @@
     const InvalidationSet::BackingFlags& flags) const {
   if (const HashSet<AtomicString>* set = GetHashSet(flags))
     return set->size();
-  if (const StringImpl* impl = GetStringImpl(flags))
+  if (const AtomicString& impl = GetAtomicString(flags))
     return 1;
   return 0;
 }
diff --git a/third_party/blink/renderer/core/css/invalidation/invalidation_set_test.cc b/third_party/blink/renderer/core/css/invalidation/invalidation_set_test.cc
index f5e5c81..bf88684 100644
--- a/third_party/blink/renderer/core/css/invalidation/invalidation_set_test.cc
+++ b/third_party/blink/renderer/core/css/invalidation/invalidation_set_test.cc
@@ -240,14 +240,14 @@
   }
 }
 
-TEST(InvalidationSetTest, Backing_GetStringImpl) {
+TEST(InvalidationSetTest, Backing_GetAtomicString) {
   BackingFlags flags;
   Backing<BackingType::kClasses> backing;
-  EXPECT_FALSE(backing.GetStringImpl(flags));
+  EXPECT_FALSE(backing.GetAtomicString(flags));
   backing.Add(flags, "a");
-  EXPECT_EQ("a", AtomicString(backing.GetStringImpl(flags)));
+  EXPECT_EQ("a", backing.GetAtomicString(flags));
   backing.Add(flags, "b");
-  EXPECT_FALSE(backing.GetStringImpl(flags));
+  EXPECT_FALSE(backing.GetAtomicString(flags));
   backing.Clear(flags);
 }
 
diff --git a/third_party/blink/renderer/core/css/style_property_serializer.cc b/third_party/blink/renderer/core/css/style_property_serializer.cc
index 856cf75f..16ac976e 100644
--- a/third_party/blink/renderer/core/css/style_property_serializer.cc
+++ b/third_party/blink/renderer/core/css/style_property_serializer.cc
@@ -1294,7 +1294,7 @@
       property_set_.GetPropertyCSSValue(*shorthand.properties()[0]);
   const CSSValue* template_column_values =
       property_set_.GetPropertyCSSValue(*shorthand.properties()[1]);
-  const CSSValue* area_values =
+  const CSSValue* template_area_values =
       property_set_.GetPropertyCSSValue(*shorthand.properties()[2]);
 
   // 1- 'none' case.
@@ -1307,10 +1307,15 @@
     return "none";
   }
 
+  const auto* template_row_value_list =
+      DynamicTo<CSSValueList>(template_row_values);
   StringBuilder result;
+
   // 2- <grid-template-rows> / <grid-template-columns>
-  if (IsA<CSSIdentifierValue>(area_values) &&
-      To<CSSIdentifierValue>(area_values)->GetValueID() == CSSValueID::kNone) {
+  if (!template_row_value_list ||
+      (IsA<CSSIdentifierValue>(template_area_values) &&
+       To<CSSIdentifierValue>(template_area_values)->GetValueID() ==
+           CSSValueID::kNone)) {
     result.Append(template_row_values->CssText());
     result.Append(" / ");
     result.Append(template_column_values->CssText());
@@ -1319,19 +1324,18 @@
 
   // 3- [ <line-names>? <string> <track-size>? <line-names>? ]+
   // [ / <track-list> ]?
-  const auto* template_row_value_list =
-      DynamicTo<CSSValueList>(template_row_values);
   if (template_row_value_list->length() == 1 &&
       IsA<CSSIdentifierValue>(template_row_value_list->Item(0)) &&
       To<CSSIdentifierValue>(template_row_value_list->Item(0)).GetValueID() ==
           CSSValueID::kAuto) {
     // If the |template_row_value_list| has only one value and it is 'auto',
     // then we append the 'grid-template-area' values.
-    result.Append(area_values->CssText());
+    result.Append(template_area_values->CssText());
   } else {
-    const NamedGridAreaMap& grid_area_map =
-        DynamicTo<cssvalue::CSSGridTemplateAreasValue>(area_values)
-            ->GridAreaMap();
+    const auto* template_areas =
+        DynamicTo<cssvalue::CSSGridTemplateAreasValue>(template_area_values);
+    DCHECK(template_areas);
+    const NamedGridAreaMap& grid_area_map = template_areas->GridAreaMap();
     wtf_size_t grid_area_index = 0;
     for (const auto& row_value : *template_row_value_list) {
       const String row_value_text = row_value->CssText();
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
index a1ebce8..b856574 100644
--- a/third_party/blink/renderer/core/dom/document.cc
+++ b/third_party/blink/renderer/core/dom/document.cc
@@ -3003,6 +3003,12 @@
       StyleChangeReasonForTracing::Create(style_change_reason::kFrame));
 }
 
+bool Document::WillPrintSoon() {
+  loading_for_print_ =
+      EnsureLazyLoadImageObserver().LoadAllImagesAndBlockLoadEvent();
+  return loading_for_print_;
+}
+
 void Document::SetPrinting(PrintingState state) {
   bool was_printing = Printing();
   printing_ = state;
@@ -3597,6 +3603,9 @@
     GetFrame()->GetFrameScheduler()->OnLoad();
 
     DetectJavascriptFrameworksOnLoad(*this);
+  } else if (loading_for_print_) {
+    loading_for_print_ = false;
+    GetFrame()->Client()->DispatchDidFinishLoadForPrinting();
   }
 
   if (auto* view = View()) {
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h
index bcc2be8..40d36e2 100644
--- a/third_party/blink/renderer/core/dom/document.h
+++ b/third_party/blink/renderer/core/dom/document.h
@@ -839,6 +839,11 @@
     return printing_ == kPrinting || printing_ == kFinishingPrinting;
   }
   void SetPrinting(PrintingState);
+  // Call this if printing is about to begin, so that any unloaded resources
+  // (such as lazy-loaded images) necessary for printing are requested and
+  // marked as blocking load. Returns whether any resources have started
+  // loading as a result.
+  bool WillPrintSoon();
 
   enum PaintPreviewState {
     // A paint preview is not in the process of being captured.
@@ -1783,6 +1788,8 @@
   friend class HasMatchedCacheScope;
   friend class CanvasRenderingAPIUkmMetricsTest;
   friend class OffscreenCanvasRenderingAPIUkmMetricsTest;
+  FRIEND_TEST_ALL_PREFIXES(LazyLoadAutomaticImagesTest,
+                           LoadAllImagesIfPrinting);
   FRIEND_TEST_ALL_PREFIXES(FrameFetchContextSubresourceFilterTest,
                            DuringOnFreeze);
   FRIEND_TEST_ALL_PREFIXES(DocumentTest, FindInPageUkm);
@@ -2363,6 +2370,9 @@
 
   Member<ResizeObserver> intrinsic_size_observer_;
 
+  // Whether any resource loads that block printing are happening.
+  bool loading_for_print_ = false;
+
   // If you want to add new data members to blink::Document, please reconsider
   // if the members really should be in blink::Document.  document.h is a very
   // popular header, and the size of document.h affects build time
diff --git a/third_party/blink/renderer/core/exported/web_performance.cc b/third_party/blink/renderer/core/exported/web_performance.cc
index e4f981a..c574053 100644
--- a/third_party/blink/renderer/core/exported/web_performance.cc
+++ b/third_party/blink/renderer/core/exported/web_performance.cc
@@ -236,6 +236,10 @@
   return private_->timing()->LargestContentfulPaintType();
 }
 
+double WebPerformance::LargestContentfulPaintImageBPP() const {
+  return private_->timing()->LargestContentfulPaintImageBPP();
+}
+
 double WebPerformance::ExperimentalLargestTextPaint() const {
   return 0.0;
 }
diff --git a/third_party/blink/renderer/core/frame/local_frame_client.h b/third_party/blink/renderer/core/frame/local_frame_client.h
index c28bc5f..9373677d 100644
--- a/third_party/blink/renderer/core/frame/local_frame_client.h
+++ b/third_party/blink/renderer/core/frame/local_frame_client.h
@@ -151,6 +151,7 @@
                                    WebHistoryCommitType) = 0;
   virtual void DispatchDidDispatchDOMContentLoadedEvent() = 0;
   virtual void DispatchDidFinishLoad() = 0;
+  virtual void DispatchDidFinishLoadForPrinting() {}
 
   virtual void BeginNavigation(
       const ResourceRequest&,
diff --git a/third_party/blink/renderer/core/frame/local_frame_client_impl.cc b/third_party/blink/renderer/core/frame/local_frame_client_impl.cc
index 0922aaf..6a3f0eac1 100644
--- a/third_party/blink/renderer/core/frame/local_frame_client_impl.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_client_impl.cc
@@ -484,6 +484,10 @@
   web_frame_->DidFinish();
 }
 
+void LocalFrameClientImpl::DispatchDidFinishLoadForPrinting() {
+  web_frame_->DidFinishLoadForPrinting();
+}
+
 void LocalFrameClientImpl::BeginNavigation(
     const ResourceRequest& request,
     mojom::RequestContextFrameType frame_type,
diff --git a/third_party/blink/renderer/core/frame/local_frame_client_impl.h b/third_party/blink/renderer/core/frame/local_frame_client_impl.h
index 59dd5662..d40ed89 100644
--- a/third_party/blink/renderer/core/frame/local_frame_client_impl.h
+++ b/third_party/blink/renderer/core/frame/local_frame_client_impl.h
@@ -109,6 +109,7 @@
   void DispatchDidFailLoad(const ResourceError&, WebHistoryCommitType) override;
   void DispatchDidDispatchDOMContentLoadedEvent() override;
   void DispatchDidFinishLoad() override;
+  void DispatchDidFinishLoadForPrinting() override;
 
   void BeginNavigation(
       const ResourceRequest&,
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
index c06e1fd3..d4535bba 100644
--- a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
+++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
@@ -1759,6 +1759,10 @@
   return plugin_container ? plugin_container->Plugin() : nullptr;
 }
 
+bool WebLocalFrameImpl::WillPrintSoon() {
+  return GetFrame()->GetDocument()->WillPrintSoon();
+}
+
 uint32_t WebLocalFrameImpl::PrintBegin(const WebPrintParams& print_params,
                                        const WebNode& constrain_to_node) {
   WebPluginContainerImpl* plugin_container =
@@ -2313,6 +2317,10 @@
   Client()->DidFinishLoad();
 }
 
+void WebLocalFrameImpl::DidFinishLoadForPrinting() {
+  Client()->DidFinishLoadForPrinting();
+}
+
 HitTestResult WebLocalFrameImpl::HitTestResultForVisualViewportPos(
     const gfx::Point& pos_in_viewport) {
   gfx::Point root_frame_point(
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.h b/third_party/blink/renderer/core/frame/web_local_frame_impl.h
index d76bff2..7a7b9ba 100644
--- a/third_party/blink/renderer/core/frame/web_local_frame_impl.h
+++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.h
@@ -296,6 +296,7 @@
   WebPlugin* GetPluginToPrint(const WebNode& constrain_to_node) override;
   uint32_t PrintBegin(const WebPrintParams&,
                       const WebNode& constrain_to_node) override;
+  bool WillPrintSoon() override;
   float GetPrintPageShrink(uint32_t page) override;
   float PrintPage(uint32_t page_to_print, cc::PaintCanvas*) override;
   void PrintEnd() override;
@@ -468,6 +469,7 @@
 
   void DidFailLoad(const ResourceError&, WebHistoryCommitType);
   void DidFinish();
+  void DidFinishLoadForPrinting();
 
   void SetClient(WebLocalFrameClient* client) { client_ = client; }
 
diff --git a/third_party/blink/renderer/core/html/html_image_element.h b/third_party/blink/renderer/core/html/html_image_element.h
index f3e6500..7d72ff3 100644
--- a/third_party/blink/renderer/core/html/html_image_element.h
+++ b/third_party/blink/renderer/core/html/html_image_element.h
@@ -103,6 +103,9 @@
   void LoadDeferredImage() {
     GetImageLoader().LoadDeferredImage(referrer_policy_);
   }
+  void LoadDeferredImageBlockingLoad() {
+    GetImageLoader().LoadDeferredImage(referrer_policy_, true);
+  }
   void SetImageForTest(ImageResourceContent* content) {
     GetImageLoader().SetImageForTest(content);
   }
diff --git a/third_party/blink/renderer/core/html/lazy_load_image_observer.cc b/third_party/blink/renderer/core/html/lazy_load_image_observer.cc
index 382cbfd..7750ea6 100644
--- a/third_party/blink/renderer/core/html/lazy_load_image_observer.cc
+++ b/third_party/blink/renderer/core/html/lazy_load_image_observer.cc
@@ -206,8 +206,34 @@
 }
 
 void LazyLoadImageObserver::StopMonitoring(Element* element) {
-  if (lazy_load_intersection_observer_)
+  if (lazy_load_intersection_observer_) {
     lazy_load_intersection_observer_->unobserve(element);
+  }
+}
+
+bool LazyLoadImageObserver::LoadAllImagesAndBlockLoadEvent() {
+  if (!lazy_load_intersection_observer_) {
+    return false;
+  }
+  bool resources_have_started_loading = false;
+  HeapVector<Member<Element>> to_be_unobserved;
+  for (const IntersectionObservation* observation :
+       lazy_load_intersection_observer_->Observations()) {
+    Element* element = observation->Target();
+    if (auto* image_element = DynamicTo<HTMLImageElement>(element)) {
+      const_cast<HTMLImageElement*>(image_element)
+          ->LoadDeferredImageBlockingLoad();
+      resources_have_started_loading = true;
+    }
+    if (const ComputedStyle* style = element->GetComputedStyle()) {
+      style->LoadDeferredImages(element->GetDocument());
+      resources_have_started_loading = true;
+    }
+    to_be_unobserved.push_back(element);
+  }
+  for (Element* element : to_be_unobserved)
+    lazy_load_intersection_observer_->unobserve(element);
+  return resources_have_started_loading;
 }
 
 void LazyLoadImageObserver::LoadIfNearViewport(
diff --git a/third_party/blink/renderer/core/html/lazy_load_image_observer.h b/third_party/blink/renderer/core/html/lazy_load_image_observer.h
index b41efe40..aac29ed 100644
--- a/third_party/blink/renderer/core/html/lazy_load_image_observer.h
+++ b/third_party/blink/renderer/core/html/lazy_load_image_observer.h
@@ -52,6 +52,10 @@
 
   void Trace(Visitor*) const;
 
+  // Loads all currently known lazy-loaded images. Returns whether any
+  // resources started loading as a result.
+  bool LoadAllImagesAndBlockLoadEvent();
+
  private:
   void LoadIfNearViewport(const HeapVector<Member<IntersectionObserverEntry>>&);
 
diff --git a/third_party/blink/renderer/core/html/lazy_load_image_observer_test.cc b/third_party/blink/renderer/core/html/lazy_load_image_observer_test.cc
index e97c38f9..27b37a4 100644
--- a/third_party/blink/renderer/core/html/lazy_load_image_observer_test.cc
+++ b/third_party/blink/renderer/core/html/lazy_load_image_observer_test.cc
@@ -236,6 +236,43 @@
   }
 }
 
+TEST_P(LazyLoadImagesSimTest, LoadAllImagesCSSBackgroundImageIfPrinting) {
+  bool is_lazyload_image_enabled = GetParam();
+  SetLazyLoadEnabled(is_lazyload_image_enabled);
+  SimRequest image_resource("https://example.com/img.png", "image/png");
+  LoadMainResource(R"HTML(
+        <style>
+        #deferred_image {
+          height:200px;
+          background-image: url('img.png');
+        }
+        </style>
+        <div style='height:10000px;'></div>
+        <div id="deferred_image"></div>
+      )HTML");
+
+  if (!is_lazyload_image_enabled)
+    image_resource.Complete(ReadTestImage());
+
+  Compositor().BeginFrame();
+  test::RunPendingTasks();
+  ExpectCSSBackgroundImageDeferredState("deferred_image", kPseudoIdNone,
+                                        is_lazyload_image_enabled);
+
+  EXPECT_EQ(0, GetDocument().Fetcher()->BlockingRequestCount());
+
+  if (is_lazyload_image_enabled) {
+    EXPECT_TRUE(GetDocument().WillPrintSoon());
+
+    // The loads in this case are blocking the load event.
+    EXPECT_EQ(1, GetDocument().Fetcher()->BlockingRequestCount());
+
+    image_resource.Complete(ReadTestImage());
+    ExpectCSSBackgroundImageDeferredState("deferred_image", kPseudoIdNone,
+                                          false);
+  }
+}
+
 TEST_P(LazyLoadImagesSimTest, CSSBackgroundImagePseudoStyleBefore) {
   VerifyCSSBackgroundImageInPseudoStyleDeferred(R"HTML(
     .pseudo-element::before {
@@ -889,6 +926,37 @@
   EXPECT_TRUE(ConsoleMessages().Contains("image onload"));
 }
 
+TEST_F(LazyLoadAutomaticImagesTest, LoadAllImagesIfPrinting) {
+  TestLoadImageExpectingLazyLoad("id='my_image' loading='lazy'");
+
+  // The body's load event should have already fired.
+  EXPECT_TRUE(ConsoleMessages().Contains("main body onload"));
+  EXPECT_FALSE(ConsoleMessages().Contains("child frame element onload"));
+
+  Element* img = GetDocument().getElementById("my_image");
+  ASSERT_TRUE(img);
+
+  test::RunPendingTasks();
+
+  EXPECT_FALSE(ConsoleMessages().Contains("image onload"));
+
+  SimSubresourceRequest img_resource("https://example.com/image.png",
+                                     "image/png");
+
+  EXPECT_EQ(0, GetDocument().Fetcher()->BlockingRequestCount());
+
+  EXPECT_TRUE(GetDocument().WillPrintSoon());
+
+  // The loads in this case are blocking the load event.
+  EXPECT_EQ(1, GetDocument().Fetcher()->BlockingRequestCount());
+
+  img_resource.Complete(ReadTestImage());
+
+  Compositor().BeginFrame();
+  test::RunPendingTasks();
+  EXPECT_TRUE(ConsoleMessages().Contains("image onload"));
+}
+
 TEST_F(LazyLoadAutomaticImagesTest, AttributeChangedFromLazyToEager) {
   TestLoadImageExpectingLazyLoad("id='my_image' loading='lazy'");
 
diff --git a/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc b/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc
index cbc66ae8..6950bdcc 100644
--- a/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc
+++ b/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc
@@ -96,14 +96,14 @@
     parsed_options.resize_height = options->resizeHeight();
   } else if (options->hasResizeWidth() && !options->hasResizeHeight()) {
     parsed_options.resize_width = options->resizeWidth();
-    parsed_options.resize_height = ceil(
+    parsed_options.resize_height = ClampTo<unsigned>(ceil(
         static_cast<float>(options->resizeWidth()) /
-        parsed_options.crop_rect.width() * parsed_options.crop_rect.height());
+        parsed_options.crop_rect.width() * parsed_options.crop_rect.height()));
   } else {
     parsed_options.resize_height = options->resizeHeight();
-    parsed_options.resize_width = ceil(
+    parsed_options.resize_width = ClampTo<unsigned>(ceil(
         static_cast<float>(options->resizeHeight()) /
-        parsed_options.crop_rect.height() * parsed_options.crop_rect.width());
+        parsed_options.crop_rect.height() * parsed_options.crop_rect.width()));
   }
   if (static_cast<int>(parsed_options.resize_width) ==
           parsed_options.crop_rect.width() &&
diff --git a/third_party/blink/renderer/core/intersection_observer/intersection_observer.h b/third_party/blink/renderer/core/intersection_observer/intersection_observer.h
index 35e978f..89672c4 100644
--- a/third_party/blink/renderer/core/intersection_observer/intersection_observer.h
+++ b/third_party/blink/renderer/core/intersection_observer/intersection_observer.h
@@ -197,6 +197,10 @@
   // sleep() calls to tests to wait for notifications to show up.
   static void SetThrottleDelayEnabledForTesting(bool);
 
+  const HeapLinkedHashSet<WeakMember<IntersectionObservation>>& Observations() {
+    return observations_;
+  }
+
  private:
   bool NeedsDelivery() const { return !active_observations_.IsEmpty(); }
   void ProcessCustomWeakness(const LivenessBroker&);
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc
index b8326121..e93263d 100644
--- a/third_party/blink/renderer/core/layout/layout_object.cc
+++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -2365,6 +2365,15 @@
 void LayoutObject::SetNeedsOverflowRecalc(
     OverflowRecalcType overflow_recalc_type) {
   NOT_DESTROYED();
+  if (UNLIKELY(IsLayoutFlowThread())) {
+    // If we're a flow thread inside an NG multicol container, just redirect to
+    // the multicol container, since the overflow recalculation walks down the
+    // NG fragment tree, and the flow thread isn't represented there.
+    if (auto* multicol_container = DynamicTo<LayoutNGBlockFlow>(Parent())) {
+      multicol_container->SetNeedsOverflowRecalc(overflow_recalc_type);
+      return;
+    }
+  }
   bool mark_container_chain_layout_overflow_recalc =
       !SelfNeedsLayoutOverflowRecalc();
 
diff --git a/third_party/blink/renderer/core/layout/layout_video.cc b/third_party/blink/renderer/core/layout/layout_video.cc
index 94f33933..9f40f24 100644
--- a/third_party/blink/renderer/core/layout/layout_video.cc
+++ b/third_party/blink/renderer/core/layout/layout_video.cc
@@ -220,16 +220,4 @@
   return !!MediaElement()->CcLayer();
 }
 
-CompositingReasons LayoutVideo::AdditionalCompositingReasons() const {
-  NOT_DESTROYED();
-  auto* element = To<HTMLMediaElement>(GetNode());
-  if (element->IsFullscreen() && element->UsesOverlayFullscreenVideo())
-    return CompositingReason::kVideo;
-
-  if (GetDisplayMode() == kVideo && SupportsAcceleratedRendering())
-    return CompositingReason::kVideo;
-
-  return CompositingReason::kNone;
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/layout_video.h b/third_party/blink/renderer/core/layout/layout_video.h
index 745bfe4..34ef1da2 100644
--- a/third_party/blink/renderer/core/layout/layout_video.h
+++ b/third_party/blink/renderer/core/layout/layout_video.h
@@ -81,12 +81,6 @@
 
   LayoutUnit MinimumReplacedHeight() const override;
 
-  bool CanHaveAdditionalCompositingReasons() const override {
-    NOT_DESTROYED();
-    return true;
-  }
-  CompositingReasons AdditionalCompositingReasons() const override;
-
   void UpdatePlayer(bool is_in_layout);
 
   LayoutSize cached_image_size_;
diff --git a/third_party/blink/renderer/core/loader/image_loader.cc b/third_party/blink/renderer/core/loader/image_loader.cc
index e277162..0582d72 100644
--- a/third_party/blink/renderer/core/loader/image_loader.cc
+++ b/third_party/blink/renderer/core/loader/image_loader.cc
@@ -443,7 +443,8 @@
     scoped_refptr<const DOMWrapperWorld> world,
     UpdateFromElementBehavior update_behavior,
     network::mojom::ReferrerPolicy referrer_policy,
-    UpdateType update_type) {
+    UpdateType update_type,
+    bool force_blocking) {
   // FIXME: According to
   // http://www.whatwg.org/specs/web-apps/current-work/multipage/embedded-content.html#the-img-element:the-img-element-55
   // When "update image" is called due to environment changes and the load
@@ -548,7 +549,8 @@
     // If we're now loading in a once-deferred image, make sure it doesn't block
     // the load event.
     if (was_deferred_explicitly_ &&
-        lazy_image_load_state_ == LazyImageLoadState::kFullImage) {
+        lazy_image_load_state_ == LazyImageLoadState::kFullImage &&
+        !force_blocking) {
       params.SetLazyImageNonBlocking();
     }
 
@@ -619,7 +621,8 @@
 
 void ImageLoader::UpdateFromElement(
     UpdateFromElementBehavior update_behavior,
-    network::mojom::ReferrerPolicy referrer_policy) {
+    network::mojom::ReferrerPolicy referrer_policy,
+    bool force_blocking) {
   if (!element_->GetDocument().IsActive()) {
     return;
   }
@@ -661,7 +664,8 @@
 
   if (ShouldLoadImmediately(ImageSourceToKURL(image_source_url))) {
     DoUpdateFromElement(element_->GetExecutionContext()->GetCurrentWorld(),
-                        update_behavior, referrer_policy, UpdateType::kSync);
+                        update_behavior, referrer_policy, UpdateType::kSync,
+                        force_blocking);
     return;
   }
   // Allow the idiom "img.src=''; img.src='.." to clear down the image before an
@@ -931,7 +935,8 @@
 }
 
 void ImageLoader::LoadDeferredImage(
-    network::mojom::ReferrerPolicy referrer_policy) {
+    network::mojom::ReferrerPolicy referrer_policy,
+    bool force_blocking) {
   if (lazy_image_load_state_ != LazyImageLoadState::kDeferred)
     return;
   DCHECK(!image_complete_);
@@ -944,7 +949,7 @@
     frame->Client()->DidObserveLazyLoadBehavior(
         WebLocalFrameClient::LazyLoadBehavior::kLazyLoadedImage);
   }
-  UpdateFromElement(kUpdateNormal, referrer_policy);
+  UpdateFromElement(kUpdateNormal, referrer_policy, force_blocking);
 }
 
 void ImageLoader::ElementDidMoveToNewDocument() {
diff --git a/third_party/blink/renderer/core/loader/image_loader.h b/third_party/blink/renderer/core/loader/image_loader.h
index 7eb16c16..fddb8293 100644
--- a/third_party/blink/renderer/core/loader/image_loader.h
+++ b/third_party/blink/renderer/core/loader/image_loader.h
@@ -76,9 +76,11 @@
     kUpdateForcedReload
   };
 
-  void UpdateFromElement(UpdateFromElementBehavior = kUpdateNormal,
-                         network::mojom::ReferrerPolicy =
-                             network::mojom::ReferrerPolicy::kDefault);
+  // force_blocking ensures that the image will block the load event.
+  void UpdateFromElement(
+      UpdateFromElementBehavior = kUpdateNormal,
+      network::mojom::ReferrerPolicy = network::mojom::ReferrerPolicy::kDefault,
+      bool force_blocking = false);
 
   void ElementDidMoveToNewDocument();
 
@@ -140,7 +142,9 @@
 
   ScriptPromise Decode(ScriptState*, ExceptionState&);
 
-  void LoadDeferredImage(network::mojom::ReferrerPolicy);
+  // force_blocking ensures that the image will block the load event.
+  void LoadDeferredImage(network::mojom::ReferrerPolicy,
+                         bool force_blocking = false);
 
  protected:
   void ImageChanged(ImageResourceContent*, CanDeferInvalidation) override;
@@ -159,18 +163,20 @@
     kNone,      // LazyImages not active.
     kDeferred,  // Full image load not started, and image load event will not be
                 // fired. Image will not block the document's load event.
-    kFullImage  // Full image is loading/loaded, due to element coming near the
-                // viewport. image_complete_ can be used to differentiate if the
-                // fetch is complete or not. After the fetch, image load event
-                // is fired.
+    kFullImage,  // Full image is loading/loaded, due to element coming near the
+                 // viewport. image_complete_ can be used to differentiate if
+                 // the fetch is complete or not. After the fetch, image load
+                 // event is fired.
   };
 
   // Called from the task or from updateFromElement to initiate the load.
+  // force_blocking ensures that the image will block the load event.
   void DoUpdateFromElement(
       scoped_refptr<const DOMWrapperWorld> world,
       UpdateFromElementBehavior,
       network::mojom::ReferrerPolicy = network::mojom::ReferrerPolicy::kDefault,
-      UpdateType = UpdateType::kAsync);
+      UpdateType = UpdateType::kAsync,
+      bool force_blocking = false);
 
   virtual void DispatchLoadEvent() = 0;
   virtual void NoImageResourceToLoad() {}
diff --git a/third_party/blink/renderer/core/loader/resource/image_resource_content.cc b/third_party/blink/renderer/core/loader/resource/image_resource_content.cc
index 1da42e2..21bf722 100644
--- a/third_party/blink/renderer/core/loader/resource/image_resource_content.cc
+++ b/third_party/blink/renderer/core/loader/resource/image_resource_content.cc
@@ -484,6 +484,16 @@
                                             GetResponse().HttpContentType());
 }
 
+uint64_t ImageResourceContent::ContentSizeForEntropy() const {
+  uint64_t resource_length =
+      static_cast<double>(GetResponse().ExpectedContentLength());
+  if (resource_length <= 0 && image_ && image_->HasData()) {
+    // WPT and LayoutTests server returns -1 or 0 for the content length.
+    resource_length = image_->DataSize();
+  }
+  return resource_length;
+}
+
 bool ImageResourceContent::IsAcceptableCompressionRatio(
     ExecutionContext& context) {
   if (!image_)
@@ -493,18 +503,12 @@
   if (!pixels)
     return true;
 
-  double resource_length =
-      static_cast<double>(GetResponse().ExpectedContentLength());
-  if (resource_length <= 0 && image_->HasData()) {
-    // WPT and LayoutTests server returns -1 or 0 for the content length.
-    resource_length = static_cast<double>(image_->DataSize());
-  }
-
   // Calculate the image's compression ratio (in bytes per pixel) with both 1k
   // and 10k overhead. The constant overhead allowance is provided to allow room
   // for headers and to account for small images (which are harder to compress).
-  double compression_ratio_1k = (resource_length - 1024) / pixels;
-  double compression_ratio_10k = (resource_length - 10240) / pixels;
+  double raw_bpp = static_cast<double>(ContentSizeForEntropy()) / pixels;
+  double compression_ratio_1k = raw_bpp - (1024 / pixels);
+  double compression_ratio_10k = raw_bpp - (10240 / pixels);
 
   ImageDecoder::CompressionFormat compression_format = GetCompressionFormat();
 
diff --git a/third_party/blink/renderer/core/loader/resource/image_resource_content.h b/third_party/blink/renderer/core/loader/resource/image_resource_content.h
index 8d3c349..6442c52 100644
--- a/third_party/blink/renderer/core/loader/resource/image_resource_content.h
+++ b/third_party/blink/renderer/core/loader/resource/image_resource_content.h
@@ -183,6 +183,13 @@
 
   ImageDecoder::CompressionFormat GetCompressionFormat() const;
 
+  // Returns the number of bytes of image data which should be used for entropy
+  // calculations. Ideally this should exclude metadata from within the image
+  // file, but currently just returns the complete file size.
+  // TODO(iclelland): Eventually switch this, and related calculations, to bits
+  // rather than bytes.
+  uint64_t ContentSizeForEntropy() const;
+
   // Returns true if the image content is well-compressed (and not full of
   // extraneous metadata). "well-compressed" is determined by comparing the
   // image's compression ratio against a specific value that is defined by an
diff --git a/third_party/blink/renderer/core/paint/image_paint_timing_detector.cc b/third_party/blink/renderer/core/paint/image_paint_timing_detector.cc
index 5a18e1e..b0f2335e 100644
--- a/third_party/blink/renderer/core/paint/image_paint_timing_detector.cc
+++ b/third_party/blink/renderer/core/paint/image_paint_timing_detector.cc
@@ -164,6 +164,13 @@
 
   const uint64_t size =
       largest_image_record ? largest_image_record->first_size : 0;
+
+  double bpp =
+      (size > 0 && largest_image_record->cached_image)
+          ? largest_image_record->cached_image->ContentSizeForEntropy() * 8.0 /
+                size
+          : 0.0;
+
   PaintTimingDetector& detector = frame_view_->GetPaintTimingDetector();
   // Calling NotifyIfChangedLargestImagePaint only has an impact on
   // PageLoadMetrics, and not on the web exposed metrics.
@@ -171,7 +178,7 @@
   // Two different candidates are rare to have the same time and size.
   // So when they are unchanged, the candidate is considered unchanged.
   bool changed =
-      detector.NotifyIfChangedLargestImagePaint(time, size, is_animated);
+      detector.NotifyIfChangedLargestImagePaint(time, size, is_animated, bpp);
   if (changed) {
     if (!time.is_null() && largest_image_record->loaded) {
       ReportCandidateToTrace(*largest_image_record);
diff --git a/third_party/blink/renderer/core/paint/largest_contentful_paint_calculator.cc b/third_party/blink/renderer/core/paint/largest_contentful_paint_calculator.cc
index 267ff33..b76ef3f 100644
--- a/third_party/blink/renderer/core/paint/largest_contentful_paint_calculator.cc
+++ b/third_party/blink/renderer/core/paint/largest_contentful_paint_calculator.cc
@@ -58,6 +58,10 @@
     return;
 
   largest_reported_size_ = largest_image->first_size;
+  largest_image_bpp_ =
+      (largest_reported_size_ > 0)
+          ? cached_image->ContentSizeForEntropy() * 8.0 / largest_reported_size_
+          : 0.0;
   const KURL& url = cached_image->Url();
   bool expose_paint_time_to_api =
       url.ProtocolIsData() || cached_image->GetResponse().TimingAllowPassed();
diff --git a/third_party/blink/renderer/core/paint/largest_contentful_paint_calculator.h b/third_party/blink/renderer/core/paint/largest_contentful_paint_calculator.h
index fd299173..012c0508 100644
--- a/third_party/blink/renderer/core/paint/largest_contentful_paint_calculator.h
+++ b/third_party/blink/renderer/core/paint/largest_contentful_paint_calculator.h
@@ -42,7 +42,7 @@
   Member<WindowPerformance> window_performance_;
 
   uint64_t largest_reported_size_ = 0u;
-
+  double largest_image_bpp_ = 0.0;
   unsigned count_candidates_ = 0;
 };
 
diff --git a/third_party/blink/renderer/core/paint/largest_contentful_paint_calculator_test.cc b/third_party/blink/renderer/core/paint/largest_contentful_paint_calculator_test.cc
index 921137a5..452b609 100644
--- a/third_party/blink/renderer/core/paint/largest_contentful_paint_calculator_test.cc
+++ b/third_party/blink/renderer/core/paint/largest_contentful_paint_calculator_test.cc
@@ -48,20 +48,32 @@
         .GetTextPaintTimingDetector();
   }
 
-  void SetImage(const char* id, int width, int height) {
+  void SetImage(const char* id, int width, int height, int bytes = 0) {
     To<HTMLImageElement>(GetDocument().getElementById(id))
-        ->SetImageForTest(CreateImageForTest(width, height));
+        ->SetImageForTest(CreateImageForTest(width, height, bytes));
   }
 
-  ImageResourceContent* CreateImageForTest(int width, int height) {
+  ImageResourceContent* CreateImageForTest(int width,
+                                           int height,
+                                           int bytes = 0) {
     sk_sp<SkColorSpace> src_rgb_color_space = SkColorSpace::MakeSRGB();
     SkImageInfo raster_image_info =
         SkImageInfo::MakeN32Premul(width, height, src_rgb_color_space);
     sk_sp<SkSurface> surface(SkSurface::MakeRaster(raster_image_info));
     sk_sp<SkImage> image = surface->makeImageSnapshot();
+    scoped_refptr<UnacceleratedStaticBitmapImage> original_image_data =
+        UnacceleratedStaticBitmapImage::Create(image);
+    // If a byte size is specified, then also assign a suitably-sized
+    // vector of 0s to the image. This is used for bits-per-pixel
+    // calculations.
+    if (bytes > 0) {
+      Vector<char> img_data(bytes);
+      scoped_refptr<SharedBuffer> shared_buffer =
+          SharedBuffer::AdoptVector(img_data);
+      original_image_data->SetData(shared_buffer, /*all_data_received=*/true);
+    }
     ImageResourceContent* original_image_content =
-        ImageResourceContent::CreateLoaded(
-            UnacceleratedStaticBitmapImage::Create(image).get());
+        ImageResourceContent::CreateLoaded(original_image_data.get());
     return original_image_content;
   }
 
@@ -69,6 +81,10 @@
     return GetLargestContentfulPaintCalculator()->largest_reported_size_;
   }
 
+  double LargestContentfulPaintCandidateImageBPP() {
+    return GetLargestContentfulPaintCalculator()->largest_image_bpp_;
+  }
+
   uint64_t CountCandidates() {
     return GetLargestContentfulPaintCalculator()->count_candidates_;
   }
@@ -128,11 +144,12 @@
     <!DOCTYPE html>
     <img id='target'/>
   )HTML");
-  SetImage("target", 100, 150);
+  SetImage("target", 100, 150, 1500);
   UpdateAllLifecyclePhasesForTest();
   SimulateImagePresentationPromise();
 
   EXPECT_EQ(LargestReportedSize(), 15000u);
+  EXPECT_FLOAT_EQ(LargestContentfulPaintCandidateImageBPP(), 0.8f);
   EXPECT_EQ(CountCandidates(), 1u);
 }
 
@@ -145,6 +162,7 @@
   SimulateTextPresentationPromise();
 
   EXPECT_GT(LargestReportedSize(), 0u);
+  EXPECT_FLOAT_EQ(LargestContentfulPaintCandidateImageBPP(), 0.0f);
   EXPECT_EQ(CountCandidates(), 1u);
 }
 
@@ -180,6 +198,7 @@
 
   // Text should not be reported, since it is smaller than the image.
   EXPECT_EQ(LargestReportedSize(), 20000u);
+  EXPECT_FLOAT_EQ(LargestContentfulPaintCandidateImageBPP(), 0.0f);
   EXPECT_EQ(CountCandidates(), 1u);
 }
 
@@ -209,6 +228,7 @@
 
   // Image should not be reported, since it is smaller than the text.
   EXPECT_GT(LargestReportedSize(), 9u);
+  EXPECT_FLOAT_EQ(LargestContentfulPaintCandidateImageBPP(), 0.0f);
   EXPECT_EQ(CountCandidates(), 1u);
 }
 
@@ -219,19 +239,21 @@
     <img id='small'/>
     <p>Larger than the second image</p>
   )HTML");
-  SetImage("large", 100, 200);
-  SetImage("small", 3, 3);
+  SetImage("large", 100, 200, 200);
+  SetImage("small", 3, 3, 18);
   UpdateAllLifecyclePhasesForTest();
   SimulateImagePresentationPromise();
   SimulateTextPresentationPromise();
   // Image is larger than the text.
   EXPECT_EQ(LargestReportedSize(), 20000u);
+  EXPECT_FLOAT_EQ(LargestContentfulPaintCandidateImageBPP(), 0.08f);
   EXPECT_EQ(CountCandidates(), 1u);
 
   GetDocument().getElementById("large")->remove();
   UpdateAllLifecyclePhasesForTest();
-  // The LCP does not move after the text is removed.
+  // The LCP does not move after the image is removed.
   EXPECT_EQ(LargestReportedSize(), 20000u);
+  EXPECT_FLOAT_EQ(LargestContentfulPaintCandidateImageBPP(), 0.08f);
   EXPECT_EQ(CountCandidates(), 1u);
 }
 
diff --git a/third_party/blink/renderer/core/paint/paint_timing_detector.cc b/third_party/blink/renderer/core/paint/paint_timing_detector.cc
index 3fcc0e7..932d43b 100644
--- a/third_party/blink/renderer/core/paint/paint_timing_detector.cc
+++ b/third_party/blink/renderer/core/paint/paint_timing_detector.cc
@@ -255,7 +255,8 @@
 bool PaintTimingDetector::NotifyIfChangedLargestImagePaint(
     base::TimeTicks image_paint_time,
     uint64_t image_paint_size,
-    bool is_animated) {
+    bool is_animated,
+    double image_bpp) {
   if (!HasLargestImagePaintChanged(image_paint_time, image_paint_size))
     return false;
 
@@ -270,6 +271,7 @@
   }
   largest_image_paint_time_ = image_paint_time;
   largest_image_paint_size_ = image_paint_size;
+  largest_contentful_paint_image_bpp_ = image_bpp;
   UpdateLargestContentfulPaintTime();
   DidChangePerformanceTiming();
   return true;
diff --git a/third_party/blink/renderer/core/paint/paint_timing_detector.h b/third_party/blink/renderer/core/paint/paint_timing_detector.h
index 23bc8ac..5fe0022f 100644
--- a/third_party/blink/renderer/core/paint/paint_timing_detector.h
+++ b/third_party/blink/renderer/core/paint/paint_timing_detector.h
@@ -142,7 +142,8 @@
   // The returned value indicates whether the candidates have changed.
   bool NotifyIfChangedLargestImagePaint(base::TimeTicks image_paint_time,
                                         uint64_t image_size,
-                                        bool is_animated);
+                                        bool is_animated,
+                                        double image_bpp);
   bool NotifyIfChangedLargestTextPaint(base::TimeTicks, uint64_t size);
 
   void DidChangePerformanceTiming();
@@ -174,6 +175,9 @@
   LargestContentfulPaintTypeMask LargestContentfulPaintType() const {
     return largest_contentful_paint_type_;
   }
+  double LargestContentfulPaintImageBPP() const {
+    return largest_contentful_paint_image_bpp_;
+  }
   base::TimeTicks LargestTextPaint() const { return largest_text_paint_time_; }
   uint64_t LargestTextPaintSize() const { return largest_text_paint_size_; }
 
@@ -223,6 +227,7 @@
   base::TimeTicks largest_image_paint_time_;
   uint64_t largest_image_paint_size_ = 0;
   LargestContentfulPaintTypeMask largest_contentful_paint_type_ = 0;
+  double largest_contentful_paint_image_bpp_ = 0.0;
   base::TimeTicks largest_text_paint_time_;
   uint64_t largest_text_paint_size_ = 0;
   base::TimeTicks largest_contentful_paint_time_;
diff --git a/third_party/blink/renderer/core/paint/video_painter_test.cc b/third_party/blink/renderer/core/paint/video_painter_test.cc
index a30f704..1fba9a5 100644
--- a/third_party/blink/renderer/core/paint/video_painter_test.cc
+++ b/third_party/blink/renderer/core/paint/video_painter_test.cc
@@ -121,7 +121,10 @@
 
 TEST_F(VideoPainterTest, VideoLayerAppearsInLayerTree) {
   // Insert a <video> and allow it to begin loading.
-  SetBodyInnerHTML("<video width=300 height=300 src=test.ogv>");
+  SetBodyInnerHTML(R"HTML(
+    <style>body { margin: 0 }</style>
+    <video id=video width=300 height=300 src=test.ogv>
+  )HTML");
   test::RunPendingTasks();
 
   // Force the page to paint.
@@ -129,7 +132,7 @@
 
   // Fetch the layer associated with the <video>, and check that it was
   // correctly configured in the layer tree.
-  auto* element = To<HTMLMediaElement>(GetDocument().body()->firstChild());
+  auto* element = To<HTMLMediaElement>(GetDocument().getElementById("video"));
   StubWebMediaPlayer* player =
       static_cast<StubWebMediaPlayer*>(element->GetWebMediaPlayer());
   const cc::Layer* layer = player->GetCcLayer();
diff --git a/third_party/blink/renderer/core/timing/performance_timing.cc b/third_party/blink/renderer/core/timing/performance_timing.cc
index 26dea98..77ab95d 100644
--- a/third_party/blink/renderer/core/timing/performance_timing.cc
+++ b/third_party/blink/renderer/core/timing/performance_timing.cc
@@ -454,6 +454,14 @@
   return paint_timing_detector->LargestContentfulPaintType();
 }
 
+double PerformanceTiming::LargestContentfulPaintImageBPP() const {
+  PaintTimingDetector* paint_timing_detector = GetPaintTimingDetector();
+  if (!paint_timing_detector) {
+    return 0.0;
+  }
+  return paint_timing_detector->LargestContentfulPaintImageBPP();
+}
+
 uint64_t PerformanceTiming::LargestTextPaint() const {
   PaintTimingDetector* paint_timing_detector = GetPaintTimingDetector();
   if (!paint_timing_detector)
diff --git a/third_party/blink/renderer/core/timing/performance_timing.h b/third_party/blink/renderer/core/timing/performance_timing.h
index 9fa74348..7f983ef 100644
--- a/third_party/blink/renderer/core/timing/performance_timing.h
+++ b/third_party/blink/renderer/core/timing/performance_timing.h
@@ -145,6 +145,7 @@
   // Largest Text Paint is the first paint after the largest text within
   // viewport being painted. LargestTextPaint and LargestTextPaintSize
   // are the time and size of it.
+  double LargestContentfulPaintImageBPP() const;
   uint64_t LargestTextPaint() const;
   uint64_t LargestTextPaintSize() const;
   // Largest Contentful Paint is the either the largest text paint time or the
diff --git a/third_party/blink/renderer/core/xml/xpath_functions.cc b/third_party/blink/renderer/core/xml/xpath_functions.cc
index 446857a..3f8b2ab 100644
--- a/third_party/blink/renderer/core/xml/xpath_functions.cc
+++ b/third_party/blink/renderer/core/xml/xpath_functions.cc
@@ -41,8 +41,7 @@
 #include <algorithm>
 #include <limits>
 
-namespace blink {
-namespace xpath {
+namespace blink::xpath {
 
 static inline bool IsWhitespace(UChar c) {
   return c == ' ' || c == '\n' || c == '\r' || c == '\t';
@@ -535,13 +534,6 @@
   return s1.Substring(i + s2.length());
 }
 
-// Returns |value| clamped to the range [lo, hi].
-// TODO(dominicc): Replace with std::clamp when C++17 is allowed
-// per //styleguide/c++/c++11.md
-static double Clamp(const double value, const double lo, const double hi) {
-  return std::min(hi, std::max(lo, value));
-}
-
 // Computes the 1-based start and end (exclusive) string indices for
 // substring. This is all the positions [1, maxLen (inclusive)] where
 // start <= position < start + len
@@ -553,8 +545,8 @@
   if (std::isnan(start) || std::isnan(end))
     return std::make_pair(1, 1);
   // Neither start nor end are NaN, but may still be +/- Inf
-  const double clamped_start = Clamp(start, 1, max_len + 1);
-  const double clamped_end = Clamp(end, clamped_start, max_len + 1);
+  const double clamped_start = base::clamp<double>(start, 1, max_len + 1);
+  const double clamped_end = base::clamp(end, clamped_start, max_len + 1);
   return std::make_pair(static_cast<unsigned>(clamped_start),
                         static_cast<unsigned>(clamped_end));
 }
@@ -749,8 +741,8 @@
   };
 
   g_function_map = new HashMap<String, FunctionRec>;
-  for (size_t i = 0; i < base::size(functions); ++i)
-    g_function_map->Set(functions[i].name, functions[i].function);
+  for (const auto& function : functions)
+    g_function_map->Set(function.name, function.function);
 }
 
 Function* CreateFunction(const String& name) {
@@ -777,5 +769,4 @@
   return function;
 }
 
-}  // namespace xpath
-}  // namespace blink
+}  // namespace blink::xpath
diff --git a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
index f32d3ec..175a788 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
@@ -2576,23 +2576,18 @@
   // aria-invalid="false".
   if (EqualIgnoringASCIICase(attribute_value, "false"))
     return ax::mojom::blink::InvalidState::kFalse;
-    // In most cases, aria-invalid="spelling"| "grammar" are used on inline text
-    // elements, and are exposed via Markers() as if they are native errors.
-    // Therefore, they are exposed as InvalidState:kNone here in order to avoid
-    // exposing the state twice, and to prevent superfluous "invalid"
-    // announcements in some screen readers.
-    // On text fields, they are simply exposed as if aria-invalid="true".
-    // TODO(accessibility) Reenable this condition onn OS_CHROMEOS, but add
-    // spelling/grammar errors from markers to AutomationPredicate.IsValid().
-    // See crrev.com/c//3396516.
-#if !defined(OS_CHROMEOS)
+  // In most cases, aria-invalid="spelling"| "grammar" are used on inline text
+  // elements, and are exposed via Markers() as if they are native errors.
+  // Therefore, they are exposed as InvalidState:kNone here in order to avoid
+  // exposing the state twice, and to prevent superfluous "invalid"
+  // announcements in some screen readers.
+  // On text fields, they are simply exposed as if aria-invalid="true".
   if (EqualIgnoringASCIICase(attribute_value, "spelling") ||
       EqualIgnoringASCIICase(attribute_value, "grammar")) {
     return RoleValue() == ax::mojom::blink::Role::kTextField
                ? ax::mojom::blink::InvalidState::kTrue
                : ax::mojom::blink::InvalidState::kNone;
   }
-#endif  // !defined(OS_CHROMEOS)
   // Any other non-empty value is considered true.
   if (!attribute_value.IsEmpty()) {
     return ax::mojom::blink::InvalidState::kTrue;
diff --git a/third_party/blink/renderer/modules/font_access/font_manager.cc b/third_party/blink/renderer/modules/font_access/font_manager.cc
index 5f8746d..5c5b88c5 100644
--- a/third_party/blink/renderer/modules/font_access/font_manager.cc
+++ b/third_party/blink/renderer/modules/font_access/font_manager.cc
@@ -43,19 +43,9 @@
   auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
-  if (options->persistentAccess() &&
-      RuntimeEnabledFeatures::FontAccessPersistentEnabled()) {
-    remote_manager_->EnumerateLocalFonts(WTF::Bind(
-        &FontManager::DidGetEnumerationResponse, WrapWeakPersistent(this),
-        WrapPersistent(resolver), options->select()));
-    return promise;
-  }
-
-  remote_manager_->ChooseLocalFonts(
-      options->select(),
-      WTF::Bind(&FontManager::DidShowFontChooser, WrapWeakPersistent(this),
-                WrapPersistent(resolver)));
-
+  remote_manager_->EnumerateLocalFonts(WTF::Bind(
+      &FontManager::DidGetEnumerationResponse, WrapWeakPersistent(this),
+      WrapPersistent(resolver), options->select()));
   return promise;
 }
 
diff --git a/third_party/blink/renderer/modules/font_access/query_options.idl b/third_party/blink/renderer/modules/font_access/query_options.idl
index 8db38c6..6e48b99 100644
--- a/third_party/blink/renderer/modules/font_access/query_options.idl
+++ b/third_party/blink/renderer/modules/font_access/query_options.idl
@@ -4,6 +4,5 @@
 
 // https://wicg.github.io/local-font-access/
 dictionary QueryOptions {
-    boolean persistentAccess = false;
     sequence<DOMString> select = [];
 };
diff --git a/third_party/blink/renderer/modules/manifest/manifest_parser.h b/third_party/blink/renderer/modules/manifest/manifest_parser.h
index 9da6625..7a609c6 100644
--- a/third_party/blink/renderer/modules/manifest/manifest_parser.h
+++ b/third_party/blink/renderer/modules/manifest/manifest_parser.h
@@ -296,7 +296,7 @@
       const JSONObject* object);
 
   // Parses the 'url_handlers' field of a Manifest, as defined in:
-  // https://github.com/WICG/pwa-url-handler/blob/master/explainer.md
+  // https://github.com/WICG/pwa-url-handler/blob/main/explainer.md
   // Returns the parsed list of UrlHandlers. The returned UrlHandlers are empty
   // if the field didn't exist, parsing failed, the input list was empty, or if
   // the blink feature flag is disabled.
@@ -306,7 +306,7 @@
       const JSONObject* object);
 
   // Parses a single URL handler entry in 'url_handlers', as defined in:
-  // https://github.com/WICG/pwa-url-handler/blob/master/explainer.md
+  // https://github.com/WICG/pwa-url-handler/blob/main/explainer.md
   // Returns |absl::nullopt| if the UrlHandler was invalid, or a UrlHandler if
   // parsing succeeded.
   // This feature is experimental and is only enabled by the blink feature flag:
diff --git a/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.idl b/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.idl
index 353b367..267d41e4 100644
--- a/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.idl
+++ b/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.idl
@@ -2,8 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// https://eladalon1983.github.io/region-capture/
-// TODO(crbug.com/1247761): Link to more official spec once published.
+// https://w3c.github.io/mediacapture-region/
 [
     Exposed = Window,
     RuntimeEnabled = RegionCapture
diff --git a/third_party/blink/renderer/modules/mediastream/media_devices.idl b/third_party/blink/renderer/modules/mediastream/media_devices.idl
index 24cf92d..7b56c5c 100644
--- a/third_party/blink/renderer/modules/mediastream/media_devices.idl
+++ b/third_party/blink/renderer/modules/mediastream/media_devices.idl
@@ -37,11 +37,10 @@
     ] void
     setCaptureHandleConfig(optional CaptureHandleConfig config = {});
 
-    // Given an html element of specified type, produces an identifier for the
-    // element that can be used by SelfCaptureMediaStreamTrack. Repeated calls
-    // to this method will return the same value.
-    // See draft spec here: https://eladalon1983.github.io/region-capture/.
-    // TODO(crbug.com/1247761): Link to final spec once it's published.
+    // https://w3c.github.io/mediacapture-region/
+    // Given an HTML element of specified type, produces an identifier for the
+    // element that can be used by SelfCaptureMediaStreamTrack.
+    // Repeated calls to this method will return the same value.
     [
       CallWith = ScriptState, RaisesException, MeasureAs = RegionCapture,
       RuntimeEnabled = RegionCapture
diff --git a/third_party/blink/renderer/modules/webcodecs/encoder_base.cc b/third_party/blink/renderer/modules/webcodecs/encoder_base.cc
index 6024cd7..1ca32e69 100644
--- a/third_party/blink/renderer/modules/webcodecs/encoder_base.cc
+++ b/third_party/blink/renderer/modules/webcodecs/encoder_base.cc
@@ -110,8 +110,7 @@
 
   Request* request = MakeGarbageCollected<Request>();
   request->reset_count = reset_count_;
-  if (media_encoder_ && active_config_ &&
-      state_.AsEnum() == V8CodecState::Enum::kConfigured &&
+  if (active_config_ && state_.AsEnum() == V8CodecState::Enum::kConfigured &&
       CanReconfigure(*active_config_, *parsed_config)) {
     request->type = Request::Type::kReconfigure;
   } else {
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn
index 5bfe711..b7182d0f 100644
--- a/third_party/blink/renderer/platform/BUILD.gn
+++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -1281,6 +1281,8 @@
     "peerconnection/audio_codec_factory.h",
     "peerconnection/gpu_codec_support_waiter.cc",
     "peerconnection/gpu_codec_support_waiter.h",
+    "peerconnection/linear_histogram.cc",
+    "peerconnection/linear_histogram.h",
     "peerconnection/rtc_answer_options_platform.h",
     "peerconnection/rtc_api_name.h",
     "peerconnection/rtc_dtmf_sender_handler.cc",
@@ -2121,6 +2123,7 @@
     "mojo/string16_mojom_traits_test.cc",
     "p2p/filtering_network_manager_test.cc",
     "p2p/ipc_network_manager_test.cc",
+    "peerconnection/linear_histogram_test.cc",
     "peerconnection/metronome_source_test.cc",
     "peerconnection/metronome_task_queue_factory_test.cc",
     "peerconnection/rtc_encoded_audio_stream_transformer_test.cc",
diff --git a/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc b/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc
index 74dae5f..9f81f7d8 100644
--- a/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc
+++ b/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc
@@ -762,6 +762,10 @@
   compositor_frame.metadata.begin_frame_ack.has_damage = true;
   compositor_frame.metadata.device_scale_factor = 1;
   compositor_frame.metadata.may_contain_video = true;
+  // If we're submitting frames even if we're not visible, then also turn off
+  // throttling.  This is for picture in picture, which can be throttled if the
+  // opener window is minimized without this.
+  compositor_frame.metadata.may_throttle_if_undrawn_frames = force_submit_;
 
   // Specify size of shared quad state and quad lists so that RenderPass doesn't
   // allocate using the defaults of 32 and 128 since we only append one quad.
diff --git a/third_party/blink/renderer/platform/peerconnection/linear_histogram.cc b/third_party/blink/renderer/platform/peerconnection/linear_histogram.cc
new file mode 100644
index 0000000..854c8aa
--- /dev/null
+++ b/third_party/blink/renderer/platform/peerconnection/linear_histogram.cc
@@ -0,0 +1,67 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/platform/peerconnection/linear_histogram.h"
+
+#include <cmath>
+
+#include "base/check.h"
+#include "base/check_op.h"
+
+namespace blink {
+
+LinearHistogram::LinearHistogram(float min_value,
+                                 float max_value,
+                                 size_t number_of_buckets)
+    : min_value_(min_value),
+      resolution_((max_value - min_value) / number_of_buckets),
+      buckets_(number_of_buckets + 2),
+      count_(0),
+      max_observed_value_(0) {
+  DCHECK_GT(number_of_buckets, 0u);
+  DCHECK_GT(max_value, min_value);
+}
+
+void LinearHistogram::Add(float value) {
+  size_t ix = 0;
+  if (value > min_value_) {
+    ix = std::ceil((value - min_value_) / resolution_);
+    ix = std::min(ix, buckets_.size() - 1);
+  }
+
+  DCHECK_GE(ix, 0u);
+  DCHECK_LT(ix, buckets_.size());
+
+  ++buckets_[ix];
+  ++count_;
+  if (value > max_observed_value_) {
+    max_observed_value_ = value;
+  }
+}
+
+float LinearHistogram::GetPercentile(float probability) const {
+  DCHECK_GT(probability, 0.f);
+  DCHECK_LE(probability, 1.f);
+  DCHECK_GT(count_, 0ul);
+
+  size_t bucket = 0;
+  float accumulated_probability = 0;
+  while (accumulated_probability < probability && bucket < buckets_.size()) {
+    accumulated_probability += static_cast<float>(buckets_[bucket]) / count_;
+    ++bucket;
+  }
+
+  if (bucket < buckets_.size()) {
+    return min_value_ + (bucket - 1) * resolution_;
+  } else {
+    // Return the maximum observed value if we end up in the overflow bucket.
+    return max_observed_value_;
+  }
+}
+
+size_t LinearHistogram::NumValues() const {
+  return count_;
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/platform/peerconnection/linear_histogram.h b/third_party/blink/renderer/platform/peerconnection/linear_histogram.h
new file mode 100644
index 0000000..df00615
--- /dev/null
+++ b/third_party/blink/renderer/platform/peerconnection/linear_histogram.h
@@ -0,0 +1,46 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_LINEAR_HISTOGRAM_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_LINEAR_HISTOGRAM_H_
+
+#include <cstddef>
+#include <vector>
+
+#include "third_party/blink/renderer/platform/platform_export.h"
+
+namespace blink {
+
+class PLATFORM_EXPORT LinearHistogram {
+ public:
+  // A linear histogram between min_value (exclusive) and max_value (inclusive).
+  // The resolution/width of each bucket is (max_value - min_value) /
+  // number_of_buckets. In addition to the specified number of buckets, there
+  // will be two more buckets to track under- and overflow.
+  LinearHistogram(float min_value, float max_value, size_t number_of_buckets);
+
+  // Add a value to the histogram.
+  void Add(float value);
+
+  // Calculates and returns the specified percentile, which corresponds to the
+  // lowest value X so that P(X) >= probability. This function must not be
+  // called if no values have been added. The maximum observed value is returned
+  // if the percentile is greater than max_value. The specified probability must
+  // be greater than 0.
+  float GetPercentile(float probability) const;
+
+  // How many values that make up this histogram.
+  size_t NumValues() const;
+
+ private:
+  const float min_value_;
+  const float resolution_;
+  std::vector<size_t> buckets_;
+  size_t count_;
+  float max_observed_value_;
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_LINEAR_HISTOGRAM_H_
diff --git a/third_party/blink/renderer/platform/peerconnection/linear_histogram_test.cc b/third_party/blink/renderer/platform/peerconnection/linear_histogram_test.cc
new file mode 100644
index 0000000..f8011c6a
--- /dev/null
+++ b/third_party/blink/renderer/platform/peerconnection/linear_histogram_test.cc
@@ -0,0 +1,75 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/platform/peerconnection/linear_histogram.h"
+
+#include <vector>
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace blink {
+
+namespace {
+
+constexpr float kMinValue = 0.0f;
+constexpr float kMaxValue = 10.0f;
+constexpr size_t kNumBuckets = 10;
+
+class LinearHistogramTest : public ::testing::Test {
+ protected:
+  LinearHistogramTest() : histogram_(kMinValue, kMaxValue, kNumBuckets) {}
+  LinearHistogram histogram_;
+};
+
+TEST_F(LinearHistogramTest, NumValues) {
+  EXPECT_EQ(0ul, histogram_.NumValues());
+  histogram_.Add(0.0);
+  EXPECT_EQ(1ul, histogram_.NumValues());
+  histogram_.Add(5.0);
+  EXPECT_EQ(2ul, histogram_.NumValues());
+}
+
+TEST_F(LinearHistogramTest, ReturnsCorrectPercentiles) {
+  const std::vector<float> kTestValues = {
+      -1.0f, 0.0f,  1.0f,  2.9f,  3.1f,  4.1f,  5.0f,  8.0f,  9.0f,  9.9f,
+      10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f};
+  // Pairs of {fraction, percentile value} computed by hand
+  // for `kTestValues`.
+  const std::vector<std::pair<float, float>> kTestPercentiles = {
+      {0.01f, 0.0f},  {0.05f, 0.0f},  {0.1f, 0.0f},   {0.11f, 1.0f},
+      {0.15f, 1.0f},  {0.20f, 3.0f},  {0.25f, 4.0f},  {0.30f, 5.0f},
+      {0.35f, 5.0f},  {0.40f, 8.0f},  {0.41f, 9.0f},  {0.45f, 9.0f},
+      {0.50f, 10.0f}, {0.55f, 10.0f}, {0.56f, 19.0f}, {0.80f, 19.0f},
+      {0.95f, 19.0f}, {0.99f, 19.0f}, {1.0f, 19.0f}};
+  for (float value : kTestValues) {
+    histogram_.Add(value);
+  }
+  for (const auto& test_percentile : kTestPercentiles) {
+    EXPECT_EQ(test_percentile.second,
+              histogram_.GetPercentile(test_percentile.first));
+  }
+}
+
+TEST_F(LinearHistogramTest, UnderflowReturnsHistogramMinValue) {
+  histogram_.Add(-10.0);
+  histogram_.Add(-5.0);
+  histogram_.Add(-1.0);
+
+  EXPECT_EQ(kMinValue, histogram_.GetPercentile(0.1));
+  EXPECT_EQ(kMinValue, histogram_.GetPercentile(0.5));
+  EXPECT_EQ(kMinValue, histogram_.GetPercentile(1.0));
+}
+
+TEST_F(LinearHistogramTest, OverflowReturnsMaximumObservedValue) {
+  histogram_.Add(10.1);
+  histogram_.Add(15.0);
+  constexpr float kMaximumObservedValue = 20.0f;
+  histogram_.Add(kMaximumObservedValue);
+
+  EXPECT_EQ(kMaximumObservedValue, histogram_.GetPercentile(0.1));
+  EXPECT_EQ(kMaximumObservedValue, histogram_.GetPercentile(0.5));
+  EXPECT_EQ(kMaximumObservedValue, histogram_.GetPercentile(1.0));
+}
+
+}  // namespace
+}  // namespace blink
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index 27879815..fb8cea2 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1110,14 +1110,6 @@
       // be enabled to make the whole feature work.
     },
     {
-      name: "FontAccessPersistent",
-      // TODO(crbug.com/1000486): Add when the Origin Trial dependency bug is fixed.
-      // depends_on: ["FontAccess"],
-      // No status because this blink runtime feature doesn't work by itself.
-      // It's controlled by the corresponding Chromium feature which needs to
-      // be enabled to make the whole feature work.
-    },
-    {
       name: "FontPalette",
       status: "test",
     },
diff --git a/third_party/blink/renderer/platform/scheduler/common/features.cc b/third_party/blink/renderer/platform/scheduler/common/features.cc
index 180370ca..00cf321 100644
--- a/third_party/blink/renderer/platform/scheduler/common/features.cc
+++ b/third_party/blink/renderer/platform/scheduler/common/features.cc
@@ -80,14 +80,11 @@
   return base::Seconds(seconds);
 }
 
-const base::Feature kThrottleForegroundTimers{
-    "ThrottleForegroundTimers", base::FEATURE_DISABLED_BY_DEFAULT};
-
 base::TimeDelta GetForegroundTimersThrottledWakeUpInterval() {
   constexpr int kForegroundTimersThrottling_WakeUpIntervalMillis_Default = 32;
   static const base::FeatureParam<int>
       kForegroundTimersThrottledWakeUpIntervalMills{
-          &kThrottleForegroundTimers,
+          &features::kThrottleForegroundTimers,
           "ForegroundTimersThrottledWakeUpIntervalMills",
           kForegroundTimersThrottling_WakeUpIntervalMillis_Default};
   return base::Milliseconds(
diff --git a/third_party/blink/renderer/platform/scheduler/common/features.h b/third_party/blink/renderer/platform/scheduler/common/features.h
index e34335c..159ba86d 100644
--- a/third_party/blink/renderer/platform/scheduler/common/features.h
+++ b/third_party/blink/renderer/platform/scheduler/common/features.h
@@ -155,9 +155,8 @@
     "MbiCompositorTaskRunnerPerAgentSchedulingGroup",
     base::FEATURE_DISABLED_BY_DEFAULT};
 
-// If enabled, Javascript timers are throttled to 1 wake up per
-// GetForegroundTimersThrottledWakeUpInterval() on foreground pages.
-PLATFORM_EXPORT extern const base::Feature kThrottleForegroundTimers;
+// Interval between Javascript timer wake ups when the "ThrottleForegroundTimers"
+// feature is enabled.
 PLATFORM_EXPORT base::TimeDelta GetForegroundTimersThrottledWakeUpInterval();
 
 // Deprioritizes JS timer tasks during a particular phase of page loading.
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
index fcde37c..14e9ca37 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
@@ -3884,7 +3884,7 @@
     : public FrameSchedulerImplTest {
  public:
   FrameSchedulerImplThrottleForegroundTimersEnabledTest()
-      : FrameSchedulerImplTest({kThrottleForegroundTimers}, {}) {}
+      : FrameSchedulerImplTest({features::kThrottleForegroundTimers}, {}) {}
 };
 
 TEST_F(FrameSchedulerImplThrottleForegroundTimersEnabledTest,
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc
index 2f25326d..9391202 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc
@@ -192,7 +192,7 @@
       delay_for_background_and_network_idle_tab_freezing_(
           GetDelayForBackgroundAndNetworkIdleTabFreezing()),
       throttle_foreground_timers_(
-          base::FeatureList::IsEnabled(kThrottleForegroundTimers)),
+          base::FeatureList::IsEnabled(features::kThrottleForegroundTimers)),
       foreground_timers_throttled_wake_up_interval_(
           GetForegroundTimersThrottledWakeUpInterval()) {
   page_lifecycle_state_tracker_ = std::make_unique<PageLifecycleStateTracker>(
diff --git a/third_party/blink/web_tests/NeverFixTests b/third_party/blink/web_tests/NeverFixTests
index 488336a..af44097e 100644
--- a/third_party/blink/web_tests/NeverFixTests
+++ b/third_party/blink/web_tests/NeverFixTests
@@ -1864,16 +1864,7 @@
 # Remove from virtual tests when FontAccess is turned on by default.
 external/wpt/font-access/font_access-blob.tentative.https.window.html [ Skip ]
 external/wpt/font-access/font_access-enumeration.tentative.https.window.html [ Skip ]
-external/wpt/font-access/font_access-chooser.tentative.manual.https.html [ Skip ]
-external/wpt/font-access/font_access-chooser-multiple.tentative.manual.https.html [ Skip ]
-external/wpt/font-access/font_access-chooser-selection.tentative.manual.https.html [ Skip ]
 external/wpt/font-access/font_metadata.tentative.https.window.html [ Skip ]
-virtual/font-access-persistent/external/wpt/font-access/font_access-blob.tentative.https.window.html [ Pass ]
-virtual/font-access-persistent/external/wpt/font-access/font_access-chooser.tentative.manual.https.html [ Skip ]
-virtual/font-access-persistent/external/wpt/font-access/font_access-chooser-multiple.tentative.manual.https.html [ Skip ]
-virtual/font-access-persistent/external/wpt/font-access/font_access-chooser-selection.tentative.manual.https.html [ Skip ]
-virtual/font-access-persistent/external/wpt/font-access/font_access-enumeration.tentative.https.window.html [ Pass ]
-virtual/font-access-persistent/external/wpt/font-access/font_metadata.tentative.https.window.html [ Pass ]
 
 # Remove from virtual tests when ComputePressure is turned on by default.
 crbug.com/1196419 external/wpt/compute-pressure/compute_pressure_arguments.tentative.https.window.html [ Skip ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index cb8b5618..41827072 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -3372,7 +3372,6 @@
 crbug.com/626703 [ Mac11-arm64 ] virtual/css-calc-infinity-and-nan-disabled/external/wpt/css/css-values/cap-unit-001.html [ Crash Failure ]
 crbug.com/626703 [ Linux ] virtual/css-highlight-inheritance/external/wpt/css/css-pseudo/first-letter-hi-001.html [ Failure ]
 crbug.com/626703 [ Win ] virtual/css-highlight-inheritance/external/wpt/css/css-pseudo/first-letter-hi-001.html [ Failure ]
-crbug.com/626703 [ Mac10.14 ] virtual/font-access-persistent/external/wpt/font-access/font_access-enumeration.tentative.https.window.html [ Timeout ]
 crbug.com/626703 external/wpt/infrastructure/channels/test_call.html [ Timeout ]
 crbug.com/626703 external/wpt/infrastructure/channels/test_postMessage.html [ Timeout ]
 crbug.com/626703 external/wpt/infrastructure/channels/test_serialize.html [ Timeout ]
@@ -3540,7 +3539,6 @@
 crbug.com/626703 [ Mac11-arm64 ] virtual/dialogfocus-old-behavior/external/wpt/html/semantics/interactive-elements/the-dialog-element/dialog-keydown-preventDefault.html [ Crash ]
 crbug.com/626703 [ Mac11-arm64 ] virtual/feature-policy-permissions/external/wpt/mediacapture-streams/MediaStream-finished-add.https.html [ Crash ]
 crbug.com/626703 [ Mac11-arm64 ] virtual/disable-ua-ch-platform-feature/external/wpt/client-hints/accept-ch-stickiness/same-origin-navigation.https.html [ Crash ]
-crbug.com/626703 [ Mac11-arm64 ] virtual/font-access-persistent/external/wpt/font-access/font_access-blob.tentative.https.window.html [ Crash ]
 crbug.com/626703 [ Mac11-arm64 ] virtual/document-domain-disabled-by-default/external/wpt/document-policy/experimental-features/document-domain/document-domain.tentative.sub.html [ Crash ]
 crbug.com/626703 [ Mac11-arm64 ] virtual/delayed-animation-updates/external/wpt/scroll-animations/css/scroll-timeline-cssom.tentative.html [ Crash ]
 crbug.com/626703 [ Mac11-arm64 ] virtual/disable-user-agent-client-hint-feature/external/wpt/client-hints/http-equiv-accept-ch-non-secure.http.html [ Crash ]
@@ -3700,7 +3698,6 @@
 crbug.com/626703 external/wpt/css/css-sizing/fit-content-length-percentage-012.html [ Failure ]
 crbug.com/626703 external/wpt/css/css-sizing/fit-content-length-percentage-003.html [ Failure ]
 crbug.com/626703 external/wpt/css/css-sizing/fit-content-length-percentage-005.html [ Failure ]
-crbug.com/626703 [ Mac11 ] virtual/font-access-persistent/external/wpt/font-access/font_access-enumeration.tentative.https.window.html [ Timeout ]
 crbug.com/626703 external/wpt/css/css-sizing/fit-content-length-percentage-008.html [ Failure ]
 crbug.com/626703 external/wpt/css/css-sizing/fit-content-length-percentage-011.html [ Failure ]
 crbug.com/626703 external/wpt/css/css-sizing/fit-content-length-percentage-013.html [ Failure ]
@@ -5817,7 +5814,7 @@
 crbug.com/1058073 [ Mac10.14 ] accessibility/content-changed-notification-causes-crash.html [ Failure Pass ]
 
 # Sheriff 2020-03-06
-crbug.com/1059262 http/tests/worklet/webexposed/global-interface-listing-paint-worklet.html [ Failure Pass ]
+crbug.com/1059262 virtual/threaded/http/tests/worklet/webexposed/global-interface-listing-paint-worklet.html [ Failure Pass ]
 crbug.com/1059262 [ Mac ] webexposed/global-interface-listing-platform-specific.html [ Failure Pass ]
 crbug.com/1058244 [ Mac ] virtual/threaded-prefer-compositing/fast/scrolling/scrollbars/scrollbar-rtl-manipulation.html [ Failure Pass ]
 
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites
index fc896cb..341bc92 100644
--- a/third_party/blink/web_tests/VirtualTestSuites
+++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -201,9 +201,9 @@
     "args": ["--enable-blink-features=FractionalScrollOffsets"]
   },
   {
-    "prefix": "font-access-persistent",
+    "prefix": "font-access",
     "bases": ["external/wpt/font-access"],
-    "args": ["--enable-features=FontAccess,FontAccessPersistent"]
+    "args": ["--enable-features=FontAccess"]
   },
   {
     "prefix": "compute-pressure",
diff --git a/third_party/blink/web_tests/W3CImportExpectations b/third_party/blink/web_tests/W3CImportExpectations
index 6c6c8442..f68d602 100644
--- a/third_party/blink/web_tests/W3CImportExpectations
+++ b/third_party/blink/web_tests/W3CImportExpectations
@@ -419,6 +419,10 @@
 external/wpt/css/css-page/page-size-011.xht [ Skip ]
 external/wpt/css/css-page/page-size-012.xht [ Skip ]
 
+# change on files below caused thousands of failures, skip them temprorary.
+external/wpt/webdriver/tests/support/defaults.py [ Skip ]
+external/wpt/webdriver/tests/support/fixtures.py [ Skip ]
+
 # This test includes arbitrary html in unit test names (via parametrize) which
 # is currently not well handled in WebDriverExpectations, and causes Lint error
 # crbug.com/1167318
diff --git a/third_party/blink/web_tests/android/WebviewWPTExpectations b/third_party/blink/web_tests/android/WebviewWPTExpectations
index 88e704ed..b14d09f 100644
--- a/third_party/blink/web_tests/android/WebviewWPTExpectations
+++ b/third_party/blink/web_tests/android/WebviewWPTExpectations
@@ -2318,7 +2318,6 @@
 crbug.com/1050754 external/wpt/fetch/stale-while-revalidate/stale-image.html [ Failure ]
 crbug.com/1050754 external/wpt/fetch/stale-while-revalidate/stale-script.html [ Failure ]
 crbug.com/1050754 external/wpt/font-access/font_access-blob.tentative.https.window.html [ Crash ]
-crbug.com/1050754 external/wpt/font-access/font_access-chooser.tentative.https.window.html [ Crash ]
 crbug.com/1050754 external/wpt/font-access/font_access-enumeration.tentative.https.window.html [ Crash ]
 crbug.com/1050754 external/wpt/font-access/font_metadata.tentative.https.window.html [ Crash ]
 crbug.com/1050754 external/wpt/forced-colors-mode/forced-colors-mode-03.html [ Failure ]
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/transform-010.html b/third_party/blink/web_tests/external/wpt/css/css-break/transform-010.html
new file mode 100644
index 0000000..8418551
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-break/transform-010.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://drafts.csswg.org/css-break/#transforms">
+<div id="container" style="width:300px; overflow-x:scroll;">
+  <div style="columns:3; column-gap:0; column-fill:auto; height:100px;">
+    <div>
+      <div id="target" style="transform:translateX(0); width:100px; height:150px;"></div>
+    </div>
+  </div>
+</div>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+  test(()=> {
+    // We have three columns. The column width is 100px.
+    // #target occurs in the first two columns.
+    assert_equals(container.scrollWidth, 300);
+
+    // This shouldn't affect the size of the scrollable area, since everything
+    // still fits within the scrollport.
+    target.style.transform = "translateX(100px)";
+    assert_equals(container.scrollWidth, 300);
+
+    // #target should now overflow the scrollport.
+    target.style.transform = "translateX(200px)";
+    assert_equals(container.scrollWidth, 400);
+
+    // Check that we're not stuck with the overflow.
+    target.style.transform = "translateX(100px)";
+    assert_equals(container.scrollWidth, 300);
+  }, "Changing a transformed element should update overflow area.");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-template-shorthand-areas-valid.html b/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-template-shorthand-areas-valid.html
new file mode 100644
index 0000000..59770ed
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-template-shorthand-areas-valid.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Grid Layout Test: grid-template and grid-template-areas</title>
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#propdef-grid-template">
+<meta name=assert content="grid-template and grid-template-areas parsing is valid.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script>
+
+function testValidGridTemplate(valueGridTemplate, valueGridAreas, serializedGridTemplateValue) {
+  if (arguments.length < 3)
+    serializedGridTemplateValue = valueGridTemplate;
+
+  test(()=>{
+    const root = document.children[0];
+    root.style.gridTemplate = "";
+    root.style.gridTemplate = valueGridTemplate;
+    root.style.gridTemplateAreas = "";
+    root.style.gridTemplateAreas = valueGridAreas;
+    assert_equals(root.style.gridTemplate, serializedGridTemplateValue);
+    assert_equals(root.style.gridTemplateAreas, valueGridAreas);
+  }, `grid-template: ${valueGridTemplate} and "grid-template-areas: ${valueGridAreas};" should be valid.`);
+}
+
+testValidGridTemplate("none / 1px",  "\"a\"");
+testValidGridTemplate("none / none", "\"a\"", "none");
+testValidGridTemplate("auto / 1px", "\"a a a\"", "\"a a a\" / 1px");
+testValidGridTemplate("auto / auto", "\"a a a\"", "\"a a a\" / auto");
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/font-access/font_access-chooser-multiple.tentative.manual.https.html b/third_party/blink/web_tests/external/wpt/font-access/font_access-chooser-multiple.tentative.manual.https.html
deleted file mode 100644
index bf70a0a..0000000
--- a/third_party/blink/web_tests/external/wpt/font-access/font_access-chooser-multiple.tentative.manual.https.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!doctype html>
-<title>Local Font Access: Multiple choosers</title>
-<meta charset=utf-8>
-
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/resources/testdriver.js"></script>
-<script src="/resources/testdriver-vendor.js"></script>
-
-<script>
-  promise_test(async t => {
-    await new Promise(resolve => {
-      window.addEventListener('DOMContentLoaded', resolve);
-    });
-    // Small delay to give chrome's test automation a chance to actually install
-    // itself.
-    await new Promise(resolve => step_timeout(resolve, 100));
-
-    await window.test_driver.bless('show a font chooser.<br>Please select at least one font.');
-    const promise = navigator.fonts.query()
-    promise_rejects_dom(t, 'SecurityError', navigator.fonts.query());
-    const fonts = await promise;
-  }, 'query() multiple choosers');
-</script>
diff --git a/third_party/blink/web_tests/external/wpt/font-access/font_access-chooser-selection.tentative.manual.https.html b/third_party/blink/web_tests/external/wpt/font-access/font_access-chooser-selection.tentative.manual.https.html
deleted file mode 100644
index e8a1e8d9..0000000
--- a/third_party/blink/web_tests/external/wpt/font-access/font_access-chooser-selection.tentative.manual.https.html
+++ /dev/null
@@ -1,44 +0,0 @@
-<!doctype html>
-<title>Local Font Access: Chooser, Selection Options</title>
-<meta charset=utf-8>
-
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/resources/testdriver.js"></script>
-<script src="/resources/testdriver-vendor.js"></script>
-<script src="resources/test-expectations.js"></script>
-
-<script>
-    (async () => {
-      await new Promise(resolve => {
-        window.addEventListener('DOMContentLoaded', resolve);
-      });
-
-      // Small delay to give chrome's test automation a chance to actually install
-      // itself.
-      await new Promise(resolve => step_timeout(resolve, 100));
-
-      promise_test(async t => {
-        await window.test_driver.bless('show a font chooser.<br />Please select all the fonts that shows up.');
-        // Arial is considered to be web-safe.
-        const fonts = await navigator.fonts.query({select: ['ArialMT']});
-        assert_true(Array.isArray(fonts));
-        assert_equals(fonts.length, 1);
-
-        const postscriptName = fonts[0].postscriptName;
-        assert_equals(typeof postscriptName, "string");
-        assert_greater_than(postscriptName.length, 0);
-      }, 'query() with selection works');
-
-      promise_test(async t => {
-        await window.test_driver.bless('show a font chooser.<br />Please select all the fonts that shows up.');
-        const fonts = await navigator.fonts.query({select: []});
-        assert_true(Array.isArray(fonts));
-        assert_greater_than_equal(fonts.length, 1);
-
-        const postscriptName = fonts[0].postscriptName;
-        assert_equals(typeof postscriptName, "string");
-        assert_greater_than(postscriptName.length, 0);
-      }, 'query() with empty selection bag works');
-    })();
-</script>
diff --git a/third_party/blink/web_tests/external/wpt/font-access/font_access-chooser.tentative.manual.https.html b/third_party/blink/web_tests/external/wpt/font-access/font_access-chooser.tentative.manual.https.html
deleted file mode 100644
index 499d8be..0000000
--- a/third_party/blink/web_tests/external/wpt/font-access/font_access-chooser.tentative.manual.https.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<!doctype html>
-<title>Local Font Access: Chooser</title>
-<meta charset=utf-8>
-
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/resources/testdriver.js"></script>
-<script src="/resources/testdriver-vendor.js"></script>
-
-<script>
-  promise_test(async t => {
-    await new Promise(resolve => {
-      window.addEventListener('DOMContentLoaded', resolve);
-    });
-    // Small delay to give chrome's test automation a chance to actually install
-    // itself.
-    await new Promise(resolve => step_timeout(resolve, 100));
-
-    await window.test_driver.bless('show a font chooser.<br />Please select at least one font.');
-    const fonts = await navigator.fonts.query();
-    assert_true(Array.isArray(fonts));
-    assert_greater_than_equal(fonts.length, 1);
-
-    const postscriptName = fonts[0].postscriptName;
-    assert_equals(typeof postscriptName, "string");
-    assert_greater_than(postscriptName.length, 0);
-  }, 'query() with chooser works');
-
-</script>
diff --git a/third_party/blink/web_tests/external/wpt/font-access/font_metadata.tentative.https.window.js b/third_party/blink/web_tests/external/wpt/font-access/font_metadata.tentative.https.window.js
index 21d3ea1..672bc08 100644
--- a/third_party/blink/web_tests/external/wpt/font-access/font_metadata.tentative.https.window.js
+++ b/third_party/blink/web_tests/external/wpt/font-access/font_metadata.tentative.https.window.js
@@ -5,7 +5,7 @@
 'use strict';
 
 font_access_test(async t => {
-  const fonts = await navigator.fonts.query({persistentAccess: true});
+  const fonts = await navigator.fonts.query();
   assert_true(Array.isArray(fonts), 'Result of query() should be an Array');
   assert_greater_than_equal(fonts.length, 1, 'Need a least one font');
 
@@ -33,7 +33,7 @@
   const testSet = getEnumerationTestSet();
 
   // Get the system fonts.
-  let fonts = await navigator.fonts.query({persistentAccess: true});
+  let fonts = await navigator.fonts.query();
   assert_true(Array.isArray(fonts), 'Result of query() should be an Array');
 
   // Filter to the ones we care about.
diff --git a/third_party/blink/web_tests/external/wpt/font-access/resources/window-tests-blob.js b/third_party/blink/web_tests/external/wpt/font-access/resources/window-tests-blob.js
index e21733c..3279849 100644
--- a/third_party/blink/web_tests/external/wpt/font-access/resources/window-tests-blob.js
+++ b/third_party/blink/web_tests/external/wpt/font-access/resources/window-tests-blob.js
@@ -1,7 +1,7 @@
 'use strict';
 
 font_access_test(async t => {
-  const fonts = await navigator.fonts.query({persistentAccess: true});
+  const fonts = await navigator.fonts.query();
   const expectedFonts = await filterEnumeration(
       fonts, getEnumerationTestSet({labelFilter: [TEST_SIZE_CATEGORY.small]}));
   const additionalExpectedTables = getMoreExpectedTables(expectedFonts);
diff --git a/third_party/blink/web_tests/external/wpt/font-access/resources/window-tests-enumeration.js b/third_party/blink/web_tests/external/wpt/font-access/resources/window-tests-enumeration.js
index 838e5c34..be906f6e 100644
--- a/third_party/blink/web_tests/external/wpt/font-access/resources/window-tests-enumeration.js
+++ b/third_party/blink/web_tests/external/wpt/font-access/resources/window-tests-enumeration.js
@@ -10,14 +10,14 @@
 
   font_access_test(async t => {
     const fonts =
-        await navigator.fonts.query({persistentAccess: true, ...test});
+        await navigator.fonts.query(test);
 
     assert_fonts_exist(fonts, getEnumerationTestSet());
   }, `query(): standard fonts returned for input: ${inputAsString}`);
 }
 
 font_access_test(async t => {
-  const fonts = await navigator.fonts.query({persistentAccess: true});
+  const fonts = await navigator.fonts.query();
   // The following tests that fonts are sorted. Postscript names are expected to
   // be encoded in a subset of the ASCII character set.
   // See: https://docs.microsoft.com/en-us/typography/opentype/spec/name
@@ -38,7 +38,6 @@
 
 font_access_test(async t => {
   const test = {
-    persistentAccess: true,
     select: [getEnumerationTestSet()[0].postscriptName]
   };
   const fonts = await navigator.fonts.query(test);
@@ -69,8 +68,7 @@
 
 for (const test of non_ascii_input) {
   font_access_test(async t => {
-    const fonts =
-        await navigator.fonts.query({persistentAccess: true, ...test});
+    const fonts = await navigator.fonts.query(test);
     assert_equals(
         fonts.length, 0,
         `There should be no results. Instead got: ${JSON.stringify(fonts)}`);
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/imagebitmap/createImageBitmap-sizeOverflow.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/imagebitmap/createImageBitmap-sizeOverflow.html
index f58825cc3..7239c2e 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/imagebitmap/createImageBitmap-sizeOverflow.html
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/imagebitmap/createImageBitmap-sizeOverflow.html
@@ -39,6 +39,24 @@
         createImageBitmap(imgData, 4294967400, 4294967400, 4294967400, 4294967400).then(resolve, reject);
     });
 }, "createImageBitmap does not crash or reject the promise when passing very large sx, sy, sw and sh");
+
+async_test(function(t) {
+    var imgData = new ImageData(20, 20);
+    var imageBitmapOptions = {imageOrientation:'none', premultiplyAlpha:'default',
+                              colorSpaceConversion:'none', resizeHeight:2122252543, resizeQuality:'high'};
+    createImageBitmap(imgData, 0, 0, 4294967295, 64).then(function(imageBitmap){
+        assert_throws_dom("InvalidStateError", function() {createImageBitmap(imageBitmap, imageBitmapOptions);});});
+    t.done();
+}, "createImageBitmap throws an InvalidStateError error with big imageBitmap scaled up in big height");
+
+async_test(function(t) {
+    var imgData = new ImageData(20, 20);
+    var imageBitmapOptions = {imageOrientation:'none', premultiplyAlpha:'default',
+                              colorSpaceConversion:'none', resizeWidth:2122252543, resizeQuality:'high'};
+    createImageBitmap(imgData, 0, 0, 4294967295, 64).then(function(imageBitmap){
+        assert_throws_dom("InvalidStateError", function() {createImageBitmap(imageBitmap, imageBitmapOptions);});});
+    t.done();
+}, "createImageBitmap throws an InvalidStateError error with big imageBitmap scaled up in big width");
 </script>
 </body>
 </html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/urlpattern/resources/urlpatterntestdata.json b/third_party/blink/web_tests/external/wpt/urlpattern/resources/urlpatterntestdata.json
index 671751fd..8cb3fff 100644
--- a/third_party/blink/web_tests/external/wpt/urlpattern/resources/urlpatterntestdata.json
+++ b/third_party/blink/web_tests/external/wpt/urlpattern/resources/urlpatterntestdata.json
@@ -2665,5 +2665,19 @@
     "pattern": [{ "pathname": "*//*" }],
     "inputs": [{ "pathname": "foo/bar" }],
     "expected_match": null
+  },
+  {
+    "pattern": [{ "pathname": "/:foo." }],
+    "inputs": [{ "pathname": "/bar." }],
+    "expected_match": {
+      "pathname": { "input": "/bar.", "groups": { "foo": "bar" } }
+    }
+  },
+  {
+    "pattern": [{ "pathname": "/:foo.." }],
+    "inputs": [{ "pathname": "/bar.." }],
+    "expected_match": {
+      "pathname": { "input": "/bar..", "groups": { "foo": "bar" } }
+    }
   }
 ]
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/video/video-poster-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/video/video-poster-expected.txt
index 31eb852..6571223 100644
--- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/video/video-poster-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/video/video-poster-expected.txt
@@ -38,31 +38,20 @@
     },
     {
       "name": "LayoutVideo VIDEO",
-      "bounds": [352, 288],
-      "transform": 1
+      "position": [8, 8],
+      "bounds": [352, 288]
     },
     {
       "name": "LayoutFlexibleBox DIV class='sizing-small phase-pre-ready state-no-source'",
+      "position": [8, 8],
       "bounds": [352, 288],
-      "contentsOpaqueForText": true,
-      "transform": 1
+      "contentsOpaqueForText": true
     },
     {
       "name": "VerticalScrollbar",
       "position": [785, 0],
       "bounds": [15, 600]
     }
-  ],
-  "transforms": [
-    {
-      "id": 1,
-      "transform": [
-        [1, 0, 0, 0],
-        [0, 1, 0, 0],
-        [0, 0, 1, 0],
-        [8, 8, 0, 1]
-      ]
-    }
   ]
 }
 
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
index 060045c..d39d912 100644
--- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
@@ -54,31 +54,20 @@
     },
     {
       "name": "LayoutVideo VIDEO id='video'",
-      "bounds": [150, 60],
-      "transform": 1
+      "position": [15, 859],
+      "bounds": [150, 60]
     },
     {
       "name": "LayoutFlexibleBox DIV class='sizing-small phase-pre-ready state-no-source'",
+      "position": [15, 859],
       "bounds": [150, 60],
-      "contentsOpaqueForText": true,
-      "transform": 1
+      "contentsOpaqueForText": true
     },
     {
       "name": "VerticalScrollbar",
       "position": [785, 0],
       "bounds": [15, 600]
     }
-  ],
-  "transforms": [
-    {
-      "id": 1,
-      "transform": [
-        [1, 0, 0, 0],
-        [0, 1, 0, 0],
-        [0, 0, 1, 0],
-        [15, 859, 0, 1]
-      ]
-    }
   ]
 }
 
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/video-paint-invalidation-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/video-paint-invalidation-expected.txt
index 248e12a5..4bf6625 100644
--- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/video-paint-invalidation-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/video-paint-invalidation-expected.txt
@@ -8,24 +8,13 @@
     },
     {
       "name": "LayoutVideo VIDEO id='video'",
-      "bounds": [320, 240],
-      "transform": 1
+      "position": [8, 8],
+      "bounds": [320, 240]
     },
     {
       "name": "LayoutFlexibleBox DIV class='sizing-small test-mode phase-ready state-scrubbing'",
-      "bounds": [320, 240],
-      "transform": 1
-    }
-  ],
-  "transforms": [
-    {
-      "id": 1,
-      "transform": [
-        [1, 0, 0, 0],
-        [0, 1, 0, 0],
-        [0, 0, 1, 0],
-        [8, 8, 0, 1]
-      ]
+      "position": [8, 8],
+      "bounds": [320, 240]
     }
   ]
 }
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/backface-visibility-interop/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/backface-visibility-interop/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
new file mode 100644
index 0000000..d39d912
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/backface-visibility-interop/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
@@ -0,0 +1,73 @@
+{
+  "layers": [
+    {
+      "name": "Scrolling background of LayoutView #document",
+      "bounds": [785, 933],
+      "contentsOpaque": true,
+      "backgroundColor": "#FFFFFF",
+      "invalidations": [
+        [570, 564, 132, 42],
+        [570, 514, 132, 42],
+        [570, 464, 132, 42],
+        [570, 414, 132, 42],
+        [570, 364, 132, 42],
+        [570, 314, 132, 42],
+        [570, 264, 132, 42],
+        [570, 214, 132, 42],
+        [570, 164, 132, 42],
+        [570, 114, 132, 42],
+        [570, 64, 132, 42],
+        [428, 564, 132, 42],
+        [428, 514, 132, 42],
+        [428, 464, 132, 42],
+        [428, 414, 132, 42],
+        [428, 364, 132, 42],
+        [428, 314, 132, 42],
+        [428, 264, 132, 42],
+        [428, 214, 132, 42],
+        [428, 164, 132, 42],
+        [428, 114, 132, 42],
+        [428, 64, 132, 42],
+        [286, 564, 132, 42],
+        [286, 514, 132, 42],
+        [286, 464, 132, 42],
+        [286, 414, 132, 42],
+        [286, 364, 132, 42],
+        [286, 314, 132, 42],
+        [286, 264, 132, 42],
+        [286, 214, 132, 42],
+        [286, 164, 132, 42],
+        [286, 114, 132, 42],
+        [286, 64, 132, 42],
+        [144, 564, 132, 42],
+        [144, 514, 132, 42],
+        [144, 464, 132, 42],
+        [144, 414, 132, 42],
+        [144, 364, 132, 42],
+        [144, 314, 132, 42],
+        [144, 264, 132, 42],
+        [144, 214, 132, 42],
+        [144, 164, 132, 42],
+        [144, 114, 132, 42],
+        [144, 64, 132, 42]
+      ]
+    },
+    {
+      "name": "LayoutVideo VIDEO id='video'",
+      "position": [15, 859],
+      "bounds": [150, 60]
+    },
+    {
+      "name": "LayoutFlexibleBox DIV class='sizing-small phase-pre-ready state-no-source'",
+      "position": [15, 859],
+      "bounds": [150, 60],
+      "contentsOpaqueForText": true
+    },
+    {
+      "name": "VerticalScrollbar",
+      "position": [785, 0],
+      "bounds": [15, 600]
+    }
+  ]
+}
+
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/backface-visibility-interop/paint/invalidation/video-paint-invalidation-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/backface-visibility-interop/paint/invalidation/video-paint-invalidation-expected.txt
new file mode 100644
index 0000000..4bf6625
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/backface-visibility-interop/paint/invalidation/video-paint-invalidation-expected.txt
@@ -0,0 +1,21 @@
+{
+  "layers": [
+    {
+      "name": "Scrolling background of LayoutView #document",
+      "bounds": [800, 600],
+      "contentsOpaque": true,
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "LayoutVideo VIDEO id='video'",
+      "position": [8, 8],
+      "bounds": [320, 240]
+    },
+    {
+      "name": "LayoutFlexibleBox DIV class='sizing-small test-mode phase-ready state-scrubbing'",
+      "position": [8, 8],
+      "bounds": [320, 240]
+    }
+  ]
+}
+
diff --git a/third_party/blink/web_tests/http/tests/worklet/webexposed/global-interface-listing-paint-worklet-expected.txt b/third_party/blink/web_tests/http/tests/worklet/webexposed/global-interface-listing-paint-worklet-expected.txt
index c265ccd..4d324f40 100644
--- a/third_party/blink/web_tests/http/tests/worklet/webexposed/global-interface-listing-paint-worklet-expected.txt
+++ b/third_party/blink/web_tests/http/tests/worklet/webexposed/global-interface-listing-paint-worklet-expected.txt
@@ -1,560 +1,788 @@
-CONSOLE MESSAGE: line 10: This test logs exposed APIs once from each PaintWorkletGlobalScope
-CONSOLE MESSAGE: line 153: interface ByteLengthQueuingStrategy
-CONSOLE MESSAGE: line 153:     getter highWaterMark
-CONSOLE MESSAGE: line 153:     getter size
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSImageValue : CSSStyleValue
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSKeywordValue : CSSStyleValue
-CONSOLE MESSAGE: line 153:     getter value
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter value
-CONSOLE MESSAGE: line 153: interface CSSMathInvert : CSSMathValue
-CONSOLE MESSAGE: line 153:     getter value
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMathMax : CSSMathValue
-CONSOLE MESSAGE: line 153:     getter values
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMathMin : CSSMathValue
-CONSOLE MESSAGE: line 153:     getter values
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMathNegate : CSSMathValue
-CONSOLE MESSAGE: line 153:     getter value
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMathProduct : CSSMathValue
-CONSOLE MESSAGE: line 153:     getter values
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMathSum : CSSMathValue
-CONSOLE MESSAGE: line 153:     getter values
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMathValue : CSSNumericValue
-CONSOLE MESSAGE: line 153:     getter operator
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMatrixComponent : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter matrix
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter matrix
-CONSOLE MESSAGE: line 153: interface CSSNumericArray
-CONSOLE MESSAGE: line 153:     getter length
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method entries
-CONSOLE MESSAGE: line 153:     method forEach
-CONSOLE MESSAGE: line 153:     method keys
-CONSOLE MESSAGE: line 153:     method values
-CONSOLE MESSAGE: line 153: interface CSSNumericValue : CSSStyleValue
-CONSOLE MESSAGE: line 153:     method add
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method div
-CONSOLE MESSAGE: line 153:     method equals
-CONSOLE MESSAGE: line 153:     method max
-CONSOLE MESSAGE: line 153:     method min
-CONSOLE MESSAGE: line 153:     method mul
-CONSOLE MESSAGE: line 153:     method sub
-CONSOLE MESSAGE: line 153:     method to
-CONSOLE MESSAGE: line 153:     method toSum
-CONSOLE MESSAGE: line 153:     method type
-CONSOLE MESSAGE: line 153: interface CSSPerspective : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter length
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter length
-CONSOLE MESSAGE: line 153: interface CSSPositionValue : CSSStyleValue
-CONSOLE MESSAGE: line 153:     getter x
-CONSOLE MESSAGE: line 153:     getter y
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter x
-CONSOLE MESSAGE: line 153:     setter y
-CONSOLE MESSAGE: line 153: interface CSSRotate : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter angle
-CONSOLE MESSAGE: line 153:     getter x
-CONSOLE MESSAGE: line 153:     getter y
-CONSOLE MESSAGE: line 153:     getter z
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter angle
-CONSOLE MESSAGE: line 153:     setter x
-CONSOLE MESSAGE: line 153:     setter y
-CONSOLE MESSAGE: line 153:     setter z
-CONSOLE MESSAGE: line 153: interface CSSScale : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter x
-CONSOLE MESSAGE: line 153:     getter y
-CONSOLE MESSAGE: line 153:     getter z
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter x
-CONSOLE MESSAGE: line 153:     setter y
-CONSOLE MESSAGE: line 153:     setter z
-CONSOLE MESSAGE: line 153: interface CSSSkew : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter ax
-CONSOLE MESSAGE: line 153:     getter ay
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter ax
-CONSOLE MESSAGE: line 153:     setter ay
-CONSOLE MESSAGE: line 153: interface CSSSkewX : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter ax
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter ax
-CONSOLE MESSAGE: line 153: interface CSSSkewY : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter ay
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter ay
-CONSOLE MESSAGE: line 153: interface CSSStyleValue
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method toString
-CONSOLE MESSAGE: line 153: interface CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter is2D
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method toMatrix
-CONSOLE MESSAGE: line 153:     method toString
-CONSOLE MESSAGE: line 153:     setter is2D
-CONSOLE MESSAGE: line 153: interface CSSTransformValue : CSSStyleValue
-CONSOLE MESSAGE: line 153:     getter is2D
-CONSOLE MESSAGE: line 153:     getter length
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method entries
-CONSOLE MESSAGE: line 153:     method forEach
-CONSOLE MESSAGE: line 153:     method keys
-CONSOLE MESSAGE: line 153:     method toMatrix
-CONSOLE MESSAGE: line 153:     method values
-CONSOLE MESSAGE: line 153: interface CSSTranslate : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter x
-CONSOLE MESSAGE: line 153:     getter y
-CONSOLE MESSAGE: line 153:     getter z
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter x
-CONSOLE MESSAGE: line 153:     setter y
-CONSOLE MESSAGE: line 153:     setter z
-CONSOLE MESSAGE: line 153: interface CSSUnitValue : CSSNumericValue
-CONSOLE MESSAGE: line 153:     getter unit
-CONSOLE MESSAGE: line 153:     getter value
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter value
-CONSOLE MESSAGE: line 153: interface CSSUnparsedValue : CSSStyleValue
-CONSOLE MESSAGE: line 153:     getter length
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method entries
-CONSOLE MESSAGE: line 153:     method forEach
-CONSOLE MESSAGE: line 153:     method keys
-CONSOLE MESSAGE: line 153:     method values
-CONSOLE MESSAGE: line 153: interface CSSVariableReferenceValue
-CONSOLE MESSAGE: line 153:     getter fallback
-CONSOLE MESSAGE: line 153:     getter variable
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter variable
-CONSOLE MESSAGE: line 153: interface CountQueuingStrategy
-CONSOLE MESSAGE: line 153:     getter highWaterMark
-CONSOLE MESSAGE: line 153:     getter size
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface PaintRenderingContext2D
-CONSOLE MESSAGE: line 153:     getter fillStyle
-CONSOLE MESSAGE: line 153:     getter filter
-CONSOLE MESSAGE: line 153:     getter globalAlpha
-CONSOLE MESSAGE: line 153:     getter globalCompositeOperation
-CONSOLE MESSAGE: line 153:     getter imageSmoothingEnabled
-CONSOLE MESSAGE: line 153:     getter imageSmoothingQuality
-CONSOLE MESSAGE: line 153:     getter lineCap
-CONSOLE MESSAGE: line 153:     getter lineDashOffset
-CONSOLE MESSAGE: line 153:     getter lineJoin
-CONSOLE MESSAGE: line 153:     getter lineWidth
-CONSOLE MESSAGE: line 153:     getter miterLimit
-CONSOLE MESSAGE: line 153:     getter shadowBlur
-CONSOLE MESSAGE: line 153:     getter shadowColor
-CONSOLE MESSAGE: line 153:     getter shadowOffsetX
-CONSOLE MESSAGE: line 153:     getter shadowOffsetY
-CONSOLE MESSAGE: line 153:     getter strokeStyle
-CONSOLE MESSAGE: line 153:     method arc
-CONSOLE MESSAGE: line 153:     method arcTo
-CONSOLE MESSAGE: line 153:     method beginPath
-CONSOLE MESSAGE: line 153:     method bezierCurveTo
-CONSOLE MESSAGE: line 153:     method clearRect
-CONSOLE MESSAGE: line 153:     method clip
-CONSOLE MESSAGE: line 153:     method closePath
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method createLinearGradient
-CONSOLE MESSAGE: line 153:     method createPattern
-CONSOLE MESSAGE: line 153:     method createRadialGradient
-CONSOLE MESSAGE: line 153:     method drawImage
-CONSOLE MESSAGE: line 153:     method ellipse
-CONSOLE MESSAGE: line 153:     method fill
-CONSOLE MESSAGE: line 153:     method fillRect
-CONSOLE MESSAGE: line 153:     method getLineDash
-CONSOLE MESSAGE: line 153:     method getTransform
-CONSOLE MESSAGE: line 153:     method isPointInPath
-CONSOLE MESSAGE: line 153:     method isPointInStroke
-CONSOLE MESSAGE: line 153:     method lineTo
-CONSOLE MESSAGE: line 153:     method moveTo
-CONSOLE MESSAGE: line 153:     method quadraticCurveTo
-CONSOLE MESSAGE: line 153:     method rect
-CONSOLE MESSAGE: line 153:     method resetTransform
-CONSOLE MESSAGE: line 153:     method restore
-CONSOLE MESSAGE: line 153:     method rotate
-CONSOLE MESSAGE: line 153:     method save
-CONSOLE MESSAGE: line 153:     method scale
-CONSOLE MESSAGE: line 153:     method setLineDash
-CONSOLE MESSAGE: line 153:     method setTransform
-CONSOLE MESSAGE: line 153:     method stroke
-CONSOLE MESSAGE: line 153:     method strokeRect
-CONSOLE MESSAGE: line 153:     method transform
-CONSOLE MESSAGE: line 153:     method translate
-CONSOLE MESSAGE: line 153:     setter fillStyle
-CONSOLE MESSAGE: line 153:     setter filter
-CONSOLE MESSAGE: line 153:     setter globalAlpha
-CONSOLE MESSAGE: line 153:     setter globalCompositeOperation
-CONSOLE MESSAGE: line 153:     setter imageSmoothingEnabled
-CONSOLE MESSAGE: line 153:     setter imageSmoothingQuality
-CONSOLE MESSAGE: line 153:     setter lineCap
-CONSOLE MESSAGE: line 153:     setter lineDashOffset
-CONSOLE MESSAGE: line 153:     setter lineJoin
-CONSOLE MESSAGE: line 153:     setter lineWidth
-CONSOLE MESSAGE: line 153:     setter miterLimit
-CONSOLE MESSAGE: line 153:     setter shadowBlur
-CONSOLE MESSAGE: line 153:     setter shadowColor
-CONSOLE MESSAGE: line 153:     setter shadowOffsetX
-CONSOLE MESSAGE: line 153:     setter shadowOffsetY
-CONSOLE MESSAGE: line 153:     setter strokeStyle
-CONSOLE MESSAGE: line 153: interface PaintSize
-CONSOLE MESSAGE: line 153:     getter height
-CONSOLE MESSAGE: line 153:     getter width
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface PaintWorkletGlobalScope : WorkletGlobalScope
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface Path2D
-CONSOLE MESSAGE: line 153:     method addPath
-CONSOLE MESSAGE: line 153:     method arc
-CONSOLE MESSAGE: line 153:     method arcTo
-CONSOLE MESSAGE: line 153:     method bezierCurveTo
-CONSOLE MESSAGE: line 153:     method closePath
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method ellipse
-CONSOLE MESSAGE: line 153:     method lineTo
-CONSOLE MESSAGE: line 153:     method moveTo
-CONSOLE MESSAGE: line 153:     method quadraticCurveTo
-CONSOLE MESSAGE: line 153:     method rect
-CONSOLE MESSAGE: line 153: interface ReadableStream
-CONSOLE MESSAGE: line 153:     getter locked
-CONSOLE MESSAGE: line 153:     method cancel
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method getReader
-CONSOLE MESSAGE: line 153:     method pipeThrough
-CONSOLE MESSAGE: line 153:     method pipeTo
-CONSOLE MESSAGE: line 153:     method tee
-CONSOLE MESSAGE: line 153: interface ReadableStreamDefaultReader
-CONSOLE MESSAGE: line 153:     getter closed
-CONSOLE MESSAGE: line 153:     method cancel
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method read
-CONSOLE MESSAGE: line 153:     method releaseLock
-CONSOLE MESSAGE: line 153: interface StylePropertyMapReadOnly
-CONSOLE MESSAGE: line 153:     getter size
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method entries
-CONSOLE MESSAGE: line 153:     method forEach
-CONSOLE MESSAGE: line 153:     method get
-CONSOLE MESSAGE: line 153:     method getAll
-CONSOLE MESSAGE: line 153:     method has
-CONSOLE MESSAGE: line 153:     method keys
-CONSOLE MESSAGE: line 153:     method values
-CONSOLE MESSAGE: line 153: interface TransformStream
-CONSOLE MESSAGE: line 153:     getter readable
-CONSOLE MESSAGE: line 153:     getter writable
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface WorkletGlobalScope
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface WritableStream
-CONSOLE MESSAGE: line 153:     getter locked
-CONSOLE MESSAGE: line 153:     method abort
-CONSOLE MESSAGE: line 153:     method close
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method getWriter
-CONSOLE MESSAGE: line 153: interface WritableStreamDefaultWriter
-CONSOLE MESSAGE: line 153:     getter closed
-CONSOLE MESSAGE: line 153:     getter desiredSize
-CONSOLE MESSAGE: line 153:     getter ready
-CONSOLE MESSAGE: line 153:     method abort
-CONSOLE MESSAGE: line 153:     method close
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method releaseLock
-CONSOLE MESSAGE: line 153:     method write
-CONSOLE MESSAGE: line 153: global object
-CONSOLE MESSAGE: line 153:     attribute console
-CONSOLE MESSAGE: line 153:     attribute globalThis
-CONSOLE MESSAGE: line 153:     getter devicePixelRatio
-CONSOLE MESSAGE: line 153:     method gc
-CONSOLE MESSAGE: line 153:     method registerPaint
-CONSOLE MESSAGE: line 153: interface ByteLengthQueuingStrategy
-CONSOLE MESSAGE: line 153:     getter highWaterMark
-CONSOLE MESSAGE: line 153:     getter size
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSImageValue : CSSStyleValue
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSKeywordValue : CSSStyleValue
-CONSOLE MESSAGE: line 153:     getter value
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter value
-CONSOLE MESSAGE: line 153: interface CSSMathInvert : CSSMathValue
-CONSOLE MESSAGE: line 153:     getter value
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMathMax : CSSMathValue
-CONSOLE MESSAGE: line 153:     getter values
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMathMin : CSSMathValue
-CONSOLE MESSAGE: line 153:     getter values
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMathNegate : CSSMathValue
-CONSOLE MESSAGE: line 153:     getter value
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMathProduct : CSSMathValue
-CONSOLE MESSAGE: line 153:     getter values
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMathSum : CSSMathValue
-CONSOLE MESSAGE: line 153:     getter values
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMathValue : CSSNumericValue
-CONSOLE MESSAGE: line 153:     getter operator
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMatrixComponent : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter matrix
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter matrix
-CONSOLE MESSAGE: line 153: interface CSSNumericArray
-CONSOLE MESSAGE: line 153:     getter length
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method entries
-CONSOLE MESSAGE: line 153:     method forEach
-CONSOLE MESSAGE: line 153:     method keys
-CONSOLE MESSAGE: line 153:     method values
-CONSOLE MESSAGE: line 153: interface CSSNumericValue : CSSStyleValue
-CONSOLE MESSAGE: line 153:     method add
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method div
-CONSOLE MESSAGE: line 153:     method equals
-CONSOLE MESSAGE: line 153:     method max
-CONSOLE MESSAGE: line 153:     method min
-CONSOLE MESSAGE: line 153:     method mul
-CONSOLE MESSAGE: line 153:     method sub
-CONSOLE MESSAGE: line 153:     method to
-CONSOLE MESSAGE: line 153:     method toSum
-CONSOLE MESSAGE: line 153:     method type
-CONSOLE MESSAGE: line 153: interface CSSPerspective : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter length
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter length
-CONSOLE MESSAGE: line 153: interface CSSPositionValue : CSSStyleValue
-CONSOLE MESSAGE: line 153:     getter x
-CONSOLE MESSAGE: line 153:     getter y
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter x
-CONSOLE MESSAGE: line 153:     setter y
-CONSOLE MESSAGE: line 153: interface CSSRotate : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter angle
-CONSOLE MESSAGE: line 153:     getter x
-CONSOLE MESSAGE: line 153:     getter y
-CONSOLE MESSAGE: line 153:     getter z
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter angle
-CONSOLE MESSAGE: line 153:     setter x
-CONSOLE MESSAGE: line 153:     setter y
-CONSOLE MESSAGE: line 153:     setter z
-CONSOLE MESSAGE: line 153: interface CSSScale : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter x
-CONSOLE MESSAGE: line 153:     getter y
-CONSOLE MESSAGE: line 153:     getter z
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter x
-CONSOLE MESSAGE: line 153:     setter y
-CONSOLE MESSAGE: line 153:     setter z
-CONSOLE MESSAGE: line 153: interface CSSSkew : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter ax
-CONSOLE MESSAGE: line 153:     getter ay
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter ax
-CONSOLE MESSAGE: line 153:     setter ay
-CONSOLE MESSAGE: line 153: interface CSSSkewX : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter ax
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter ax
-CONSOLE MESSAGE: line 153: interface CSSSkewY : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter ay
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter ay
-CONSOLE MESSAGE: line 153: interface CSSStyleValue
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method toString
-CONSOLE MESSAGE: line 153: interface CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter is2D
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method toMatrix
-CONSOLE MESSAGE: line 153:     method toString
-CONSOLE MESSAGE: line 153:     setter is2D
-CONSOLE MESSAGE: line 153: interface CSSTransformValue : CSSStyleValue
-CONSOLE MESSAGE: line 153:     getter is2D
-CONSOLE MESSAGE: line 153:     getter length
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method entries
-CONSOLE MESSAGE: line 153:     method forEach
-CONSOLE MESSAGE: line 153:     method keys
-CONSOLE MESSAGE: line 153:     method toMatrix
-CONSOLE MESSAGE: line 153:     method values
-CONSOLE MESSAGE: line 153: interface CSSTranslate : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter x
-CONSOLE MESSAGE: line 153:     getter y
-CONSOLE MESSAGE: line 153:     getter z
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter x
-CONSOLE MESSAGE: line 153:     setter y
-CONSOLE MESSAGE: line 153:     setter z
-CONSOLE MESSAGE: line 153: interface CSSUnitValue : CSSNumericValue
-CONSOLE MESSAGE: line 153:     getter unit
-CONSOLE MESSAGE: line 153:     getter value
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter value
-CONSOLE MESSAGE: line 153: interface CSSUnparsedValue : CSSStyleValue
-CONSOLE MESSAGE: line 153:     getter length
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method entries
-CONSOLE MESSAGE: line 153:     method forEach
-CONSOLE MESSAGE: line 153:     method keys
-CONSOLE MESSAGE: line 153:     method values
-CONSOLE MESSAGE: line 153: interface CSSVariableReferenceValue
-CONSOLE MESSAGE: line 153:     getter fallback
-CONSOLE MESSAGE: line 153:     getter variable
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter variable
-CONSOLE MESSAGE: line 153: interface CountQueuingStrategy
-CONSOLE MESSAGE: line 153:     getter highWaterMark
-CONSOLE MESSAGE: line 153:     getter size
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface PaintRenderingContext2D
-CONSOLE MESSAGE: line 153:     getter fillStyle
-CONSOLE MESSAGE: line 153:     getter filter
-CONSOLE MESSAGE: line 153:     getter globalAlpha
-CONSOLE MESSAGE: line 153:     getter globalCompositeOperation
-CONSOLE MESSAGE: line 153:     getter imageSmoothingEnabled
-CONSOLE MESSAGE: line 153:     getter imageSmoothingQuality
-CONSOLE MESSAGE: line 153:     getter lineCap
-CONSOLE MESSAGE: line 153:     getter lineDashOffset
-CONSOLE MESSAGE: line 153:     getter lineJoin
-CONSOLE MESSAGE: line 153:     getter lineWidth
-CONSOLE MESSAGE: line 153:     getter miterLimit
-CONSOLE MESSAGE: line 153:     getter shadowBlur
-CONSOLE MESSAGE: line 153:     getter shadowColor
-CONSOLE MESSAGE: line 153:     getter shadowOffsetX
-CONSOLE MESSAGE: line 153:     getter shadowOffsetY
-CONSOLE MESSAGE: line 153:     getter strokeStyle
-CONSOLE MESSAGE: line 153:     method arc
-CONSOLE MESSAGE: line 153:     method arcTo
-CONSOLE MESSAGE: line 153:     method beginPath
-CONSOLE MESSAGE: line 153:     method bezierCurveTo
-CONSOLE MESSAGE: line 153:     method clearRect
-CONSOLE MESSAGE: line 153:     method clip
-CONSOLE MESSAGE: line 153:     method closePath
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method createLinearGradient
-CONSOLE MESSAGE: line 153:     method createPattern
-CONSOLE MESSAGE: line 153:     method createRadialGradient
-CONSOLE MESSAGE: line 153:     method drawImage
-CONSOLE MESSAGE: line 153:     method ellipse
-CONSOLE MESSAGE: line 153:     method fill
-CONSOLE MESSAGE: line 153:     method fillRect
-CONSOLE MESSAGE: line 153:     method getLineDash
-CONSOLE MESSAGE: line 153:     method getTransform
-CONSOLE MESSAGE: line 153:     method isPointInPath
-CONSOLE MESSAGE: line 153:     method isPointInStroke
-CONSOLE MESSAGE: line 153:     method lineTo
-CONSOLE MESSAGE: line 153:     method moveTo
-CONSOLE MESSAGE: line 153:     method quadraticCurveTo
-CONSOLE MESSAGE: line 153:     method rect
-CONSOLE MESSAGE: line 153:     method resetTransform
-CONSOLE MESSAGE: line 153:     method restore
-CONSOLE MESSAGE: line 153:     method rotate
-CONSOLE MESSAGE: line 153:     method save
-CONSOLE MESSAGE: line 153:     method scale
-CONSOLE MESSAGE: line 153:     method setLineDash
-CONSOLE MESSAGE: line 153:     method setTransform
-CONSOLE MESSAGE: line 153:     method stroke
-CONSOLE MESSAGE: line 153:     method strokeRect
-CONSOLE MESSAGE: line 153:     method transform
-CONSOLE MESSAGE: line 153:     method translate
-CONSOLE MESSAGE: line 153:     setter fillStyle
-CONSOLE MESSAGE: line 153:     setter filter
-CONSOLE MESSAGE: line 153:     setter globalAlpha
-CONSOLE MESSAGE: line 153:     setter globalCompositeOperation
-CONSOLE MESSAGE: line 153:     setter imageSmoothingEnabled
-CONSOLE MESSAGE: line 153:     setter imageSmoothingQuality
-CONSOLE MESSAGE: line 153:     setter lineCap
-CONSOLE MESSAGE: line 153:     setter lineDashOffset
-CONSOLE MESSAGE: line 153:     setter lineJoin
-CONSOLE MESSAGE: line 153:     setter lineWidth
-CONSOLE MESSAGE: line 153:     setter miterLimit
-CONSOLE MESSAGE: line 153:     setter shadowBlur
-CONSOLE MESSAGE: line 153:     setter shadowColor
-CONSOLE MESSAGE: line 153:     setter shadowOffsetX
-CONSOLE MESSAGE: line 153:     setter shadowOffsetY
-CONSOLE MESSAGE: line 153:     setter strokeStyle
-CONSOLE MESSAGE: line 153: interface PaintSize
-CONSOLE MESSAGE: line 153:     getter height
-CONSOLE MESSAGE: line 153:     getter width
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface PaintWorkletGlobalScope : WorkletGlobalScope
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface Path2D
-CONSOLE MESSAGE: line 153:     method addPath
-CONSOLE MESSAGE: line 153:     method arc
-CONSOLE MESSAGE: line 153:     method arcTo
-CONSOLE MESSAGE: line 153:     method bezierCurveTo
-CONSOLE MESSAGE: line 153:     method closePath
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method ellipse
-CONSOLE MESSAGE: line 153:     method lineTo
-CONSOLE MESSAGE: line 153:     method moveTo
-CONSOLE MESSAGE: line 153:     method quadraticCurveTo
-CONSOLE MESSAGE: line 153:     method rect
-CONSOLE MESSAGE: line 153: interface ReadableStream
-CONSOLE MESSAGE: line 153:     getter locked
-CONSOLE MESSAGE: line 153:     method cancel
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method getReader
-CONSOLE MESSAGE: line 153:     method pipeThrough
-CONSOLE MESSAGE: line 153:     method pipeTo
-CONSOLE MESSAGE: line 153:     method tee
-CONSOLE MESSAGE: line 153: interface ReadableStreamDefaultReader
-CONSOLE MESSAGE: line 153:     getter closed
-CONSOLE MESSAGE: line 153:     method cancel
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method read
-CONSOLE MESSAGE: line 153:     method releaseLock
-CONSOLE MESSAGE: line 153: interface StylePropertyMapReadOnly
-CONSOLE MESSAGE: line 153:     getter size
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method entries
-CONSOLE MESSAGE: line 153:     method forEach
-CONSOLE MESSAGE: line 153:     method get
-CONSOLE MESSAGE: line 153:     method getAll
-CONSOLE MESSAGE: line 153:     method has
-CONSOLE MESSAGE: line 153:     method keys
-CONSOLE MESSAGE: line 153:     method values
-CONSOLE MESSAGE: line 153: interface TransformStream
-CONSOLE MESSAGE: line 153:     getter readable
-CONSOLE MESSAGE: line 153:     getter writable
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface WorkletGlobalScope
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface WritableStream
-CONSOLE MESSAGE: line 153:     getter locked
-CONSOLE MESSAGE: line 153:     method abort
-CONSOLE MESSAGE: line 153:     method close
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method getWriter
-CONSOLE MESSAGE: line 153: interface WritableStreamDefaultWriter
-CONSOLE MESSAGE: line 153:     getter closed
-CONSOLE MESSAGE: line 153:     getter desiredSize
-CONSOLE MESSAGE: line 153:     getter ready
-CONSOLE MESSAGE: line 153:     method abort
-CONSOLE MESSAGE: line 153:     method close
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method releaseLock
-CONSOLE MESSAGE: line 153:     method write
-CONSOLE MESSAGE: line 153: global object
-CONSOLE MESSAGE: line 153:     attribute console
-CONSOLE MESSAGE: line 153:     attribute globalThis
-CONSOLE MESSAGE: line 153:     getter devicePixelRatio
-CONSOLE MESSAGE: line 153:     method gc
-CONSOLE MESSAGE: line 153:     method registerPaint
+CONSOLE MESSAGE: This test logs exposed APIs once from each PaintWorkletGlobalScope
+CONSOLE MESSAGE: [INTERFACES]
+CONSOLE MESSAGE: interface ByteLengthQueuingStrategy
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter highWaterMark
+CONSOLE MESSAGE:     getter size
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE: interface CSSColorValue
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     method toHSL
+CONSOLE MESSAGE:     method toRGB
+CONSOLE MESSAGE: interface CSSHSL : CSSColorValue
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter alpha
+CONSOLE MESSAGE:     getter h
+CONSOLE MESSAGE:     getter l
+CONSOLE MESSAGE:     getter s
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     setter alpha
+CONSOLE MESSAGE:     setter h
+CONSOLE MESSAGE:     setter l
+CONSOLE MESSAGE:     setter s
+CONSOLE MESSAGE: interface CSSImageValue : CSSStyleValue
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE: interface CSSKeywordValue : CSSStyleValue
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter value
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     setter value
+CONSOLE MESSAGE: interface CSSMathInvert : CSSMathValue
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter value
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE: interface CSSMathMax : CSSMathValue
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter values
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE: interface CSSMathMin : CSSMathValue
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter values
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE: interface CSSMathNegate : CSSMathValue
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter value
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE: interface CSSMathProduct : CSSMathValue
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter values
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE: interface CSSMathSum : CSSMathValue
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter values
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE: interface CSSMathValue : CSSNumericValue
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter operator
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE: interface CSSMatrixComponent : CSSTransformComponent
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter matrix
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     setter matrix
+CONSOLE MESSAGE: interface CSSNumericArray
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter length
+CONSOLE MESSAGE:     method @@iterator
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     method entries
+CONSOLE MESSAGE:     method forEach
+CONSOLE MESSAGE:     method keys
+CONSOLE MESSAGE:     method values
+CONSOLE MESSAGE: interface CSSNumericValue : CSSStyleValue
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     method add
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     method div
+CONSOLE MESSAGE:     method equals
+CONSOLE MESSAGE:     method max
+CONSOLE MESSAGE:     method min
+CONSOLE MESSAGE:     method mul
+CONSOLE MESSAGE:     method sub
+CONSOLE MESSAGE:     method to
+CONSOLE MESSAGE:     method toSum
+CONSOLE MESSAGE:     method type
+CONSOLE MESSAGE: interface CSSPerspective : CSSTransformComponent
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter length
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     setter length
+CONSOLE MESSAGE: interface CSSPositionValue : CSSStyleValue
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter x
+CONSOLE MESSAGE:     getter y
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     setter x
+CONSOLE MESSAGE:     setter y
+CONSOLE MESSAGE: interface CSSRGB : CSSColorValue
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter alpha
+CONSOLE MESSAGE:     getter b
+CONSOLE MESSAGE:     getter g
+CONSOLE MESSAGE:     getter r
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     setter alpha
+CONSOLE MESSAGE:     setter b
+CONSOLE MESSAGE:     setter g
+CONSOLE MESSAGE:     setter r
+CONSOLE MESSAGE: interface CSSRotate : CSSTransformComponent
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter angle
+CONSOLE MESSAGE:     getter x
+CONSOLE MESSAGE:     getter y
+CONSOLE MESSAGE:     getter z
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     setter angle
+CONSOLE MESSAGE:     setter x
+CONSOLE MESSAGE:     setter y
+CONSOLE MESSAGE:     setter z
+CONSOLE MESSAGE: interface CSSScale : CSSTransformComponent
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter x
+CONSOLE MESSAGE:     getter y
+CONSOLE MESSAGE:     getter z
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     setter x
+CONSOLE MESSAGE:     setter y
+CONSOLE MESSAGE:     setter z
+CONSOLE MESSAGE: interface CSSSkew : CSSTransformComponent
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter ax
+CONSOLE MESSAGE:     getter ay
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     setter ax
+CONSOLE MESSAGE:     setter ay
+CONSOLE MESSAGE: interface CSSSkewX : CSSTransformComponent
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter ax
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     setter ax
+CONSOLE MESSAGE: interface CSSSkewY : CSSTransformComponent
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter ay
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     setter ay
+CONSOLE MESSAGE: interface CSSStyleValue
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     method toString
+CONSOLE MESSAGE: interface CSSTransformComponent
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter is2D
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     method toMatrix
+CONSOLE MESSAGE:     method toString
+CONSOLE MESSAGE:     setter is2D
+CONSOLE MESSAGE: interface CSSTransformValue : CSSStyleValue
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter is2D
+CONSOLE MESSAGE:     getter length
+CONSOLE MESSAGE:     method @@iterator
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     method entries
+CONSOLE MESSAGE:     method forEach
+CONSOLE MESSAGE:     method keys
+CONSOLE MESSAGE:     method toMatrix
+CONSOLE MESSAGE:     method values
+CONSOLE MESSAGE: interface CSSTranslate : CSSTransformComponent
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter x
+CONSOLE MESSAGE:     getter y
+CONSOLE MESSAGE:     getter z
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     setter x
+CONSOLE MESSAGE:     setter y
+CONSOLE MESSAGE:     setter z
+CONSOLE MESSAGE: interface CSSUnitValue : CSSNumericValue
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter unit
+CONSOLE MESSAGE:     getter value
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     setter value
+CONSOLE MESSAGE: interface CSSUnparsedValue : CSSStyleValue
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter length
+CONSOLE MESSAGE:     method @@iterator
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     method entries
+CONSOLE MESSAGE:     method forEach
+CONSOLE MESSAGE:     method keys
+CONSOLE MESSAGE:     method values
+CONSOLE MESSAGE: interface CSSVariableReferenceValue
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter fallback
+CONSOLE MESSAGE:     getter variable
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     setter variable
+CONSOLE MESSAGE: interface CanvasFilter
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE: interface CountQueuingStrategy
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter highWaterMark
+CONSOLE MESSAGE:     getter size
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE: interface PaintRenderingContext2D
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter fillStyle
+CONSOLE MESSAGE:     getter filter
+CONSOLE MESSAGE:     getter globalAlpha
+CONSOLE MESSAGE:     getter globalCompositeOperation
+CONSOLE MESSAGE:     getter imageSmoothingEnabled
+CONSOLE MESSAGE:     getter imageSmoothingQuality
+CONSOLE MESSAGE:     getter lineCap
+CONSOLE MESSAGE:     getter lineDashOffset
+CONSOLE MESSAGE:     getter lineJoin
+CONSOLE MESSAGE:     getter lineWidth
+CONSOLE MESSAGE:     getter miterLimit
+CONSOLE MESSAGE:     getter shadowBlur
+CONSOLE MESSAGE:     getter shadowColor
+CONSOLE MESSAGE:     getter shadowOffsetX
+CONSOLE MESSAGE:     getter shadowOffsetY
+CONSOLE MESSAGE:     getter strokeStyle
+CONSOLE MESSAGE:     method arc
+CONSOLE MESSAGE:     method arcTo
+CONSOLE MESSAGE:     method beginLayer
+CONSOLE MESSAGE:     method beginPath
+CONSOLE MESSAGE:     method bezierCurveTo
+CONSOLE MESSAGE:     method clearRect
+CONSOLE MESSAGE:     method clip
+CONSOLE MESSAGE:     method closePath
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     method createConicGradient
+CONSOLE MESSAGE:     method createLinearGradient
+CONSOLE MESSAGE:     method createPattern
+CONSOLE MESSAGE:     method createRadialGradient
+CONSOLE MESSAGE:     method drawImage
+CONSOLE MESSAGE:     method ellipse
+CONSOLE MESSAGE:     method endLayer
+CONSOLE MESSAGE:     method fill
+CONSOLE MESSAGE:     method fillRect
+CONSOLE MESSAGE:     method getLineDash
+CONSOLE MESSAGE:     method getTransform
+CONSOLE MESSAGE:     method isPointInPath
+CONSOLE MESSAGE:     method isPointInStroke
+CONSOLE MESSAGE:     method lineTo
+CONSOLE MESSAGE:     method moveTo
+CONSOLE MESSAGE:     method quadraticCurveTo
+CONSOLE MESSAGE:     method rect
+CONSOLE MESSAGE:     method reset
+CONSOLE MESSAGE:     method resetTransform
+CONSOLE MESSAGE:     method restore
+CONSOLE MESSAGE:     method rotate
+CONSOLE MESSAGE:     method roundRect
+CONSOLE MESSAGE:     method save
+CONSOLE MESSAGE:     method scale
+CONSOLE MESSAGE:     method setLineDash
+CONSOLE MESSAGE:     method setTransform
+CONSOLE MESSAGE:     method stroke
+CONSOLE MESSAGE:     method strokeRect
+CONSOLE MESSAGE:     method transform
+CONSOLE MESSAGE:     method translate
+CONSOLE MESSAGE:     setter fillStyle
+CONSOLE MESSAGE:     setter filter
+CONSOLE MESSAGE:     setter globalAlpha
+CONSOLE MESSAGE:     setter globalCompositeOperation
+CONSOLE MESSAGE:     setter imageSmoothingEnabled
+CONSOLE MESSAGE:     setter imageSmoothingQuality
+CONSOLE MESSAGE:     setter lineCap
+CONSOLE MESSAGE:     setter lineDashOffset
+CONSOLE MESSAGE:     setter lineJoin
+CONSOLE MESSAGE:     setter lineWidth
+CONSOLE MESSAGE:     setter miterLimit
+CONSOLE MESSAGE:     setter shadowBlur
+CONSOLE MESSAGE:     setter shadowColor
+CONSOLE MESSAGE:     setter shadowOffsetX
+CONSOLE MESSAGE:     setter shadowOffsetY
+CONSOLE MESSAGE:     setter strokeStyle
+CONSOLE MESSAGE: interface PaintSize
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter height
+CONSOLE MESSAGE:     getter width
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE: interface PaintWorkletGlobalScope : WorkletGlobalScope
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE: interface Path2D
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     method addPath
+CONSOLE MESSAGE:     method arc
+CONSOLE MESSAGE:     method arcTo
+CONSOLE MESSAGE:     method bezierCurveTo
+CONSOLE MESSAGE:     method closePath
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     method ellipse
+CONSOLE MESSAGE:     method lineTo
+CONSOLE MESSAGE:     method moveTo
+CONSOLE MESSAGE:     method quadraticCurveTo
+CONSOLE MESSAGE:     method rect
+CONSOLE MESSAGE:     method roundRect
+CONSOLE MESSAGE: interface ReadableByteStreamController
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter byobRequest
+CONSOLE MESSAGE:     getter desiredSize
+CONSOLE MESSAGE:     method close
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     method enqueue
+CONSOLE MESSAGE:     method error
+CONSOLE MESSAGE: interface ReadableStream
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter locked
+CONSOLE MESSAGE:     method cancel
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     method getReader
+CONSOLE MESSAGE:     method pipeThrough
+CONSOLE MESSAGE:     method pipeTo
+CONSOLE MESSAGE:     method tee
+CONSOLE MESSAGE: interface ReadableStreamBYOBReader
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter closed
+CONSOLE MESSAGE:     method cancel
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     method read
+CONSOLE MESSAGE:     method releaseLock
+CONSOLE MESSAGE: interface ReadableStreamBYOBRequest
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter view
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     method respond
+CONSOLE MESSAGE:     method respondWithNewView
+CONSOLE MESSAGE: interface ReadableStreamDefaultController
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter desiredSize
+CONSOLE MESSAGE:     method close
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     method enqueue
+CONSOLE MESSAGE:     method error
+CONSOLE MESSAGE: interface ReadableStreamDefaultReader
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter closed
+CONSOLE MESSAGE:     method cancel
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     method read
+CONSOLE MESSAGE:     method releaseLock
+CONSOLE MESSAGE: interface StylePropertyMapReadOnly
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter size
+CONSOLE MESSAGE:     method @@iterator
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     method entries
+CONSOLE MESSAGE:     method forEach
+CONSOLE MESSAGE:     method get
+CONSOLE MESSAGE:     method getAll
+CONSOLE MESSAGE:     method has
+CONSOLE MESSAGE:     method keys
+CONSOLE MESSAGE:     method values
+CONSOLE MESSAGE: interface TransformStream
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter readable
+CONSOLE MESSAGE:     getter writable
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE: interface WorkletGlobalScope
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE: interface WritableStream
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter locked
+CONSOLE MESSAGE:     method abort
+CONSOLE MESSAGE:     method close
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     method getWriter
+CONSOLE MESSAGE: interface WritableStreamDefaultController
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter signal
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     method error
+CONSOLE MESSAGE: interface WritableStreamDefaultWriter
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter closed
+CONSOLE MESSAGE:     getter desiredSize
+CONSOLE MESSAGE:     getter ready
+CONSOLE MESSAGE:     method abort
+CONSOLE MESSAGE:     method close
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     method releaseLock
+CONSOLE MESSAGE:     method write
+CONSOLE MESSAGE: [NAMESPACES]
+CONSOLE MESSAGE: [GLOBAL OBJECT]
+CONSOLE MESSAGE:     attribute console
+CONSOLE MESSAGE:     attribute globalThis
+CONSOLE MESSAGE:     getter devicePixelRatio
+CONSOLE MESSAGE:     method gc
+CONSOLE MESSAGE:     method registerPaint
+CONSOLE MESSAGE: [INTERFACES]
+CONSOLE MESSAGE: interface ByteLengthQueuingStrategy
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter highWaterMark
+CONSOLE MESSAGE:     getter size
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE: interface CSSColorValue
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     method toHSL
+CONSOLE MESSAGE:     method toRGB
+CONSOLE MESSAGE: interface CSSHSL : CSSColorValue
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter alpha
+CONSOLE MESSAGE:     getter h
+CONSOLE MESSAGE:     getter l
+CONSOLE MESSAGE:     getter s
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     setter alpha
+CONSOLE MESSAGE:     setter h
+CONSOLE MESSAGE:     setter l
+CONSOLE MESSAGE:     setter s
+CONSOLE MESSAGE: interface CSSImageValue : CSSStyleValue
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE: interface CSSKeywordValue : CSSStyleValue
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter value
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     setter value
+CONSOLE MESSAGE: interface CSSMathInvert : CSSMathValue
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter value
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE: interface CSSMathMax : CSSMathValue
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter values
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE: interface CSSMathMin : CSSMathValue
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter values
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE: interface CSSMathNegate : CSSMathValue
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter value
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE: interface CSSMathProduct : CSSMathValue
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter values
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE: interface CSSMathSum : CSSMathValue
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter values
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE: interface CSSMathValue : CSSNumericValue
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter operator
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE: interface CSSMatrixComponent : CSSTransformComponent
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter matrix
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     setter matrix
+CONSOLE MESSAGE: interface CSSNumericArray
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter length
+CONSOLE MESSAGE:     method @@iterator
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     method entries
+CONSOLE MESSAGE:     method forEach
+CONSOLE MESSAGE:     method keys
+CONSOLE MESSAGE:     method values
+CONSOLE MESSAGE: interface CSSNumericValue : CSSStyleValue
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     method add
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     method div
+CONSOLE MESSAGE:     method equals
+CONSOLE MESSAGE:     method max
+CONSOLE MESSAGE:     method min
+CONSOLE MESSAGE:     method mul
+CONSOLE MESSAGE:     method sub
+CONSOLE MESSAGE:     method to
+CONSOLE MESSAGE:     method toSum
+CONSOLE MESSAGE:     method type
+CONSOLE MESSAGE: interface CSSPerspective : CSSTransformComponent
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter length
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     setter length
+CONSOLE MESSAGE: interface CSSPositionValue : CSSStyleValue
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter x
+CONSOLE MESSAGE:     getter y
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     setter x
+CONSOLE MESSAGE:     setter y
+CONSOLE MESSAGE: interface CSSRGB : CSSColorValue
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter alpha
+CONSOLE MESSAGE:     getter b
+CONSOLE MESSAGE:     getter g
+CONSOLE MESSAGE:     getter r
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     setter alpha
+CONSOLE MESSAGE:     setter b
+CONSOLE MESSAGE:     setter g
+CONSOLE MESSAGE:     setter r
+CONSOLE MESSAGE: interface CSSRotate : CSSTransformComponent
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter angle
+CONSOLE MESSAGE:     getter x
+CONSOLE MESSAGE:     getter y
+CONSOLE MESSAGE:     getter z
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     setter angle
+CONSOLE MESSAGE:     setter x
+CONSOLE MESSAGE:     setter y
+CONSOLE MESSAGE:     setter z
+CONSOLE MESSAGE: interface CSSScale : CSSTransformComponent
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter x
+CONSOLE MESSAGE:     getter y
+CONSOLE MESSAGE:     getter z
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     setter x
+CONSOLE MESSAGE:     setter y
+CONSOLE MESSAGE:     setter z
+CONSOLE MESSAGE: interface CSSSkew : CSSTransformComponent
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter ax
+CONSOLE MESSAGE:     getter ay
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     setter ax
+CONSOLE MESSAGE:     setter ay
+CONSOLE MESSAGE: interface CSSSkewX : CSSTransformComponent
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter ax
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     setter ax
+CONSOLE MESSAGE: interface CSSSkewY : CSSTransformComponent
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter ay
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     setter ay
+CONSOLE MESSAGE: interface CSSStyleValue
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     method toString
+CONSOLE MESSAGE: interface CSSTransformComponent
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter is2D
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     method toMatrix
+CONSOLE MESSAGE:     method toString
+CONSOLE MESSAGE:     setter is2D
+CONSOLE MESSAGE: interface CSSTransformValue : CSSStyleValue
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter is2D
+CONSOLE MESSAGE:     getter length
+CONSOLE MESSAGE:     method @@iterator
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     method entries
+CONSOLE MESSAGE:     method forEach
+CONSOLE MESSAGE:     method keys
+CONSOLE MESSAGE:     method toMatrix
+CONSOLE MESSAGE:     method values
+CONSOLE MESSAGE: interface CSSTranslate : CSSTransformComponent
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter x
+CONSOLE MESSAGE:     getter y
+CONSOLE MESSAGE:     getter z
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     setter x
+CONSOLE MESSAGE:     setter y
+CONSOLE MESSAGE:     setter z
+CONSOLE MESSAGE: interface CSSUnitValue : CSSNumericValue
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter unit
+CONSOLE MESSAGE:     getter value
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     setter value
+CONSOLE MESSAGE: interface CSSUnparsedValue : CSSStyleValue
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter length
+CONSOLE MESSAGE:     method @@iterator
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     method entries
+CONSOLE MESSAGE:     method forEach
+CONSOLE MESSAGE:     method keys
+CONSOLE MESSAGE:     method values
+CONSOLE MESSAGE: interface CSSVariableReferenceValue
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter fallback
+CONSOLE MESSAGE:     getter variable
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     setter variable
+CONSOLE MESSAGE: interface CanvasFilter
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE: interface CountQueuingStrategy
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter highWaterMark
+CONSOLE MESSAGE:     getter size
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE: interface PaintRenderingContext2D
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter fillStyle
+CONSOLE MESSAGE:     getter filter
+CONSOLE MESSAGE:     getter globalAlpha
+CONSOLE MESSAGE:     getter globalCompositeOperation
+CONSOLE MESSAGE:     getter imageSmoothingEnabled
+CONSOLE MESSAGE:     getter imageSmoothingQuality
+CONSOLE MESSAGE:     getter lineCap
+CONSOLE MESSAGE:     getter lineDashOffset
+CONSOLE MESSAGE:     getter lineJoin
+CONSOLE MESSAGE:     getter lineWidth
+CONSOLE MESSAGE:     getter miterLimit
+CONSOLE MESSAGE:     getter shadowBlur
+CONSOLE MESSAGE:     getter shadowColor
+CONSOLE MESSAGE:     getter shadowOffsetX
+CONSOLE MESSAGE:     getter shadowOffsetY
+CONSOLE MESSAGE:     getter strokeStyle
+CONSOLE MESSAGE:     method arc
+CONSOLE MESSAGE:     method arcTo
+CONSOLE MESSAGE:     method beginLayer
+CONSOLE MESSAGE:     method beginPath
+CONSOLE MESSAGE:     method bezierCurveTo
+CONSOLE MESSAGE:     method clearRect
+CONSOLE MESSAGE:     method clip
+CONSOLE MESSAGE:     method closePath
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     method createConicGradient
+CONSOLE MESSAGE:     method createLinearGradient
+CONSOLE MESSAGE:     method createPattern
+CONSOLE MESSAGE:     method createRadialGradient
+CONSOLE MESSAGE:     method drawImage
+CONSOLE MESSAGE:     method ellipse
+CONSOLE MESSAGE:     method endLayer
+CONSOLE MESSAGE:     method fill
+CONSOLE MESSAGE:     method fillRect
+CONSOLE MESSAGE:     method getLineDash
+CONSOLE MESSAGE:     method getTransform
+CONSOLE MESSAGE:     method isPointInPath
+CONSOLE MESSAGE:     method isPointInStroke
+CONSOLE MESSAGE:     method lineTo
+CONSOLE MESSAGE:     method moveTo
+CONSOLE MESSAGE:     method quadraticCurveTo
+CONSOLE MESSAGE:     method rect
+CONSOLE MESSAGE:     method reset
+CONSOLE MESSAGE:     method resetTransform
+CONSOLE MESSAGE:     method restore
+CONSOLE MESSAGE:     method rotate
+CONSOLE MESSAGE:     method roundRect
+CONSOLE MESSAGE:     method save
+CONSOLE MESSAGE:     method scale
+CONSOLE MESSAGE:     method setLineDash
+CONSOLE MESSAGE:     method setTransform
+CONSOLE MESSAGE:     method stroke
+CONSOLE MESSAGE:     method strokeRect
+CONSOLE MESSAGE:     method transform
+CONSOLE MESSAGE:     method translate
+CONSOLE MESSAGE:     setter fillStyle
+CONSOLE MESSAGE:     setter filter
+CONSOLE MESSAGE:     setter globalAlpha
+CONSOLE MESSAGE:     setter globalCompositeOperation
+CONSOLE MESSAGE:     setter imageSmoothingEnabled
+CONSOLE MESSAGE:     setter imageSmoothingQuality
+CONSOLE MESSAGE:     setter lineCap
+CONSOLE MESSAGE:     setter lineDashOffset
+CONSOLE MESSAGE:     setter lineJoin
+CONSOLE MESSAGE:     setter lineWidth
+CONSOLE MESSAGE:     setter miterLimit
+CONSOLE MESSAGE:     setter shadowBlur
+CONSOLE MESSAGE:     setter shadowColor
+CONSOLE MESSAGE:     setter shadowOffsetX
+CONSOLE MESSAGE:     setter shadowOffsetY
+CONSOLE MESSAGE:     setter strokeStyle
+CONSOLE MESSAGE: interface PaintSize
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter height
+CONSOLE MESSAGE:     getter width
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE: interface PaintWorkletGlobalScope : WorkletGlobalScope
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE: interface Path2D
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     method addPath
+CONSOLE MESSAGE:     method arc
+CONSOLE MESSAGE:     method arcTo
+CONSOLE MESSAGE:     method bezierCurveTo
+CONSOLE MESSAGE:     method closePath
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     method ellipse
+CONSOLE MESSAGE:     method lineTo
+CONSOLE MESSAGE:     method moveTo
+CONSOLE MESSAGE:     method quadraticCurveTo
+CONSOLE MESSAGE:     method rect
+CONSOLE MESSAGE:     method roundRect
+CONSOLE MESSAGE: interface ReadableByteStreamController
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter byobRequest
+CONSOLE MESSAGE:     getter desiredSize
+CONSOLE MESSAGE:     method close
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     method enqueue
+CONSOLE MESSAGE:     method error
+CONSOLE MESSAGE: interface ReadableStream
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter locked
+CONSOLE MESSAGE:     method cancel
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     method getReader
+CONSOLE MESSAGE:     method pipeThrough
+CONSOLE MESSAGE:     method pipeTo
+CONSOLE MESSAGE:     method tee
+CONSOLE MESSAGE: interface ReadableStreamBYOBReader
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter closed
+CONSOLE MESSAGE:     method cancel
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     method read
+CONSOLE MESSAGE:     method releaseLock
+CONSOLE MESSAGE: interface ReadableStreamBYOBRequest
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter view
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     method respond
+CONSOLE MESSAGE:     method respondWithNewView
+CONSOLE MESSAGE: interface ReadableStreamDefaultController
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter desiredSize
+CONSOLE MESSAGE:     method close
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     method enqueue
+CONSOLE MESSAGE:     method error
+CONSOLE MESSAGE: interface ReadableStreamDefaultReader
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter closed
+CONSOLE MESSAGE:     method cancel
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     method read
+CONSOLE MESSAGE:     method releaseLock
+CONSOLE MESSAGE: interface StylePropertyMapReadOnly
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter size
+CONSOLE MESSAGE:     method @@iterator
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     method entries
+CONSOLE MESSAGE:     method forEach
+CONSOLE MESSAGE:     method get
+CONSOLE MESSAGE:     method getAll
+CONSOLE MESSAGE:     method has
+CONSOLE MESSAGE:     method keys
+CONSOLE MESSAGE:     method values
+CONSOLE MESSAGE: interface TransformStream
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter readable
+CONSOLE MESSAGE:     getter writable
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE: interface WorkletGlobalScope
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE: interface WritableStream
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter locked
+CONSOLE MESSAGE:     method abort
+CONSOLE MESSAGE:     method close
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     method getWriter
+CONSOLE MESSAGE: interface WritableStreamDefaultController
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter signal
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     method error
+CONSOLE MESSAGE: interface WritableStreamDefaultWriter
+CONSOLE MESSAGE:     attribute @@toStringTag
+CONSOLE MESSAGE:     getter closed
+CONSOLE MESSAGE:     getter desiredSize
+CONSOLE MESSAGE:     getter ready
+CONSOLE MESSAGE:     method abort
+CONSOLE MESSAGE:     method close
+CONSOLE MESSAGE:     method constructor
+CONSOLE MESSAGE:     method releaseLock
+CONSOLE MESSAGE:     method write
+CONSOLE MESSAGE: [NAMESPACES]
+CONSOLE MESSAGE: [GLOBAL OBJECT]
+CONSOLE MESSAGE:     attribute console
+CONSOLE MESSAGE:     attribute globalThis
+CONSOLE MESSAGE:     getter devicePixelRatio
+CONSOLE MESSAGE:     method gc
+CONSOLE MESSAGE:     method registerPaint
 
diff --git a/third_party/blink/web_tests/http/tests/worklet/webexposed/global-interface-listing-paint-worklet.html b/third_party/blink/web_tests/http/tests/worklet/webexposed/global-interface-listing-paint-worklet.html
index 2352d42..6903bda 100644
--- a/third_party/blink/web_tests/http/tests/worklet/webexposed/global-interface-listing-paint-worklet.html
+++ b/third_party/blink/web_tests/http/tests/worklet/webexposed/global-interface-listing-paint-worklet.html
@@ -8,7 +8,8 @@
     }
 
     console.log("This test logs exposed APIs once from each PaintWorkletGlobalScope");
-    CSS.paintWorklet.addModule('resources/global-interface-listing-worklet.js').then(function() {
+    CSS.paintWorklet.addModule('/js-test-resources/global-interface-listing.js')
+      .then(function() {
         if (window.testRunner) {
             testRunner.notifyDone();
         }
diff --git a/third_party/blink/web_tests/http/tests/worklet/webexposed/resources/global-interface-listing-worklet.js b/third_party/blink/web_tests/http/tests/worklet/webexposed/resources/global-interface-listing-worklet.js
deleted file mode 100644
index c689913..0000000
--- a/third_party/blink/web_tests/http/tests/worklet/webexposed/resources/global-interface-listing-worklet.js
+++ /dev/null
@@ -1,159 +0,0 @@
-/* Adopted from LayoutTests/resources/global-interface-listing.js */
-
-// Run all the code in a local scope.
-(function() {
-
-// Generally, Worklet should not have a reference to the global object.
-// https://drafts.css-houdini.org/worklets/#code-idempotency
-if (this) {
-  console.error('"this" should not refer to the global object');
-  return;
-}
-// Instead, retrieve the global object in a tricky way.
-var global_object = Function('return this')();
-
-var globals = [];
-
-// List of builtin JS constructors; Blink is not controlling what properties these
-// objects have, so exercising them in a Blink test doesn't make sense.
-//
-// This list should be kept in sync with the one at web_tests/resources/global-interface-listing.js
-var js_builtins = new Set([
-    'AggregateError',
-    'Array',
-    'ArrayBuffer',
-    'Atomics',
-    'BigInt',
-    'BigInt64Array',
-    'BigUint64Array',
-    'Boolean',
-    'DataView',
-    'Date',
-    'Error',
-    'EvalError',
-    'FinalizationRegistry',
-    'Float32Array',
-    'Float64Array',
-    'Function',
-    'Infinity',
-    'Int16Array',
-    'Int32Array',
-    'Int8Array',
-    'Intl',
-    'JSON',
-    'Map',
-    'Math',
-    'NaN',
-    'Number',
-    'Object',
-    'Promise',
-    'Proxy',
-    'RangeError',
-    'ReferenceError',
-    'Reflect',
-    'RegExp',
-    'Set',
-    'SharedArrayBuffer',
-    'String',
-    'Symbol',
-    'SyntaxError',
-    'TypeError',
-    'URIError',
-    'Uint16Array',
-    'Uint32Array',
-    'Uint8Array',
-    'Uint8ClampedArray',
-    'WeakMap',
-    'WeakRef',
-    'WeakSet',
-    'WebAssembly',
-    'decodeURI',
-    'decodeURIComponent',
-    'encodeURI',
-    'encodeURIComponent',
-    'escape',
-    'eval',
-    'isFinite',
-    'isNaN',
-    'parseFloat',
-    'parseInt',
-    'undefined',
-    'unescape',
-]);
-
-function is_web_idl_constructor(property_name) {
-  if (js_builtins.has(property_name))
-    return false;
-  var descriptor = Object.getOwnPropertyDescriptor(global_object, property_name);
-  if (descriptor.value === undefined ||
-      descriptor.value.prototype === undefined) {
-    return false;
-  }
-  return descriptor.writable && !descriptor.enumerable &&
-         descriptor.configurable;
-}
-
-function collect_property_info(object, property_name, output) {
-  var keywords = ('prototype' in object) ? 'static ' : '';
-  var descriptor = Object.getOwnPropertyDescriptor(object, property_name);
-  if ('value' in descriptor) {
-    var type;
-    if (typeof descriptor.value === 'function') {
-      type = 'method';
-    } else {
-      type = 'attribute';
-    }
-    output.push('    ' + keywords + type + ' ' + property_name);
-  } else {
-    if (descriptor.get)
-      output.push('    ' + keywords + 'getter ' + property_name);
-    if (descriptor.set)
-      output.push('    ' + keywords + 'setter ' + property_name);
-  }
-}
-
-var interface_names = Object.getOwnPropertyNames(global_object).filter(is_web_idl_constructor);
-interface_names.sort();
-interface_names.forEach(function(interface_name) {
-  var inherits_from = global_object[interface_name].__proto__.name;
-  if (inherits_from)
-    globals.push('interface ' + interface_name + ' : ' + inherits_from);
-  else
-    globals.push('interface ' + interface_name);
-  // List static properties then prototype properties.
-  [global_object[interface_name], global_object[interface_name].prototype].forEach(function(object) {
-    if ('prototype' in object) {
-      // Skip properties that aren't static (e.g. consts), or are inherited.
-      var proto_properties = new Set(Object.keys(object.prototype).concat(
-                                     Object.keys(object.__proto__)));
-      var property_names = Object.keys(object).filter(function(name) {
-        return !proto_properties.has(name);
-      });
-    } else {
-      var property_names = Object.getOwnPropertyNames(object);
-    }
-    var property_strings = [];
-    property_names.forEach(function(property_name) {
-      collect_property_info(object, property_name, property_strings);
-    });
-    globals.push.apply(globals, property_strings.sort());
-  });
-});
-
-globals.push('global object');
-var property_strings = [];
-var member_names = Object.getOwnPropertyNames(global_object).filter(function(property_name) {
-  return !js_builtins.has(property_name) && !is_web_idl_constructor(property_name);
-});
-member_names.forEach(function(property_name) {
-  collect_property_info(global_object, property_name, property_strings);
-});
-globals.push.apply(globals, property_strings.sort());
-
-// Worklets don't have a mechanism to communicate back to the main page, dump
-// results into the console.
-globals.forEach(function(global) {
-    console.log(global);
-});
-
-})(); // Run all the code in a local scope.
diff --git a/third_party/blink/web_tests/paint/invalidation/video-paint-invalidation-expected.txt b/third_party/blink/web_tests/paint/invalidation/video-paint-invalidation-expected.txt
index 0997b73..2cec2134 100644
--- a/third_party/blink/web_tests/paint/invalidation/video-paint-invalidation-expected.txt
+++ b/third_party/blink/web_tests/paint/invalidation/video-paint-invalidation-expected.txt
@@ -8,24 +8,13 @@
     },
     {
       "name": "LayoutVideo VIDEO id='video'",
-      "bounds": [320, 240],
-      "transform": 1
+      "position": [8, 8],
+      "bounds": [320, 240]
     },
     {
       "name": "LayoutNGFlexibleBox DIV class='sizing-small test-mode phase-ready state-scrubbing'",
-      "bounds": [320, 240],
-      "transform": 1
-    }
-  ],
-  "transforms": [
-    {
-      "id": 1,
-      "transform": [
-        [1, 0, 0, 0],
-        [0, 1, 0, 0],
-        [0, 0, 1, 0],
-        [8, 8, 0, 1]
-      ]
+      "position": [8, 8],
+      "bounds": [320, 240]
     }
   ]
 }
diff --git a/third_party/blink/web_tests/platform/linux/compositing/video/video-controls-squashing-expected.png b/third_party/blink/web_tests/platform/linux/compositing/video/video-controls-squashing-expected.png
index 094e7384..da73146f 100644
--- a/third_party/blink/web_tests/platform/linux/compositing/video/video-controls-squashing-expected.png
+++ b/third_party/blink/web_tests/platform/linux/compositing/video/video-controls-squashing-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt b/third_party/blink/web_tests/platform/linux/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
index eb16f6f..62e8ada 100644
--- a/third_party/blink/web_tests/platform/linux/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
@@ -54,31 +54,20 @@
     },
     {
       "name": "LayoutVideo VIDEO id='video'",
-      "bounds": [150, 60],
-      "transform": 1
+      "position": [15, 859],
+      "bounds": [150, 60]
     },
     {
       "name": "LayoutNGFlexibleBox DIV class='sizing-small phase-pre-ready state-no-source'",
+      "position": [15, 859],
       "bounds": [150, 60],
-      "contentsOpaqueForText": true,
-      "transform": 1
+      "contentsOpaqueForText": true
     },
     {
       "name": "VerticalScrollbar",
       "position": [785, 0],
       "bounds": [15, 600]
     }
-  ],
-  "transforms": [
-    {
-      "id": 1,
-      "transform": [
-        [1, 0, 0, 0],
-        [0, 1, 0, 0],
-        [0, 0, 1, 0],
-        [15, 859, 0, 1]
-      ]
-    }
   ]
 }
 
diff --git a/third_party/blink/web_tests/platform/linux/virtual/backface-visibility-interop/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/backface-visibility-interop/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
new file mode 100644
index 0000000..62e8ada
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/virtual/backface-visibility-interop/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
@@ -0,0 +1,73 @@
+{
+  "layers": [
+    {
+      "name": "Scrolling background of LayoutView #document",
+      "bounds": [785, 933],
+      "contentsOpaque": true,
+      "backgroundColor": "#FFFFFF",
+      "invalidations": [
+        [570, 564, 132, 42],
+        [570, 514, 132, 42],
+        [570, 464, 132, 42],
+        [570, 414, 132, 42],
+        [570, 364, 132, 42],
+        [570, 314, 132, 42],
+        [570, 264, 132, 42],
+        [570, 214, 132, 42],
+        [570, 164, 132, 42],
+        [570, 114, 132, 42],
+        [570, 64, 132, 42],
+        [428, 564, 132, 42],
+        [428, 514, 132, 42],
+        [428, 464, 132, 42],
+        [428, 414, 132, 42],
+        [428, 364, 132, 42],
+        [428, 314, 132, 42],
+        [428, 264, 132, 42],
+        [428, 214, 132, 42],
+        [428, 164, 132, 42],
+        [428, 114, 132, 42],
+        [428, 64, 132, 42],
+        [286, 564, 132, 42],
+        [286, 514, 132, 42],
+        [286, 464, 132, 42],
+        [286, 414, 132, 42],
+        [286, 364, 132, 42],
+        [286, 314, 132, 42],
+        [286, 264, 132, 42],
+        [286, 214, 132, 42],
+        [286, 164, 132, 42],
+        [286, 114, 132, 42],
+        [286, 64, 132, 42],
+        [144, 564, 132, 42],
+        [144, 514, 132, 42],
+        [144, 464, 132, 42],
+        [144, 414, 132, 42],
+        [144, 364, 132, 42],
+        [144, 314, 132, 42],
+        [144, 264, 132, 42],
+        [144, 214, 132, 42],
+        [144, 164, 132, 42],
+        [144, 114, 132, 42],
+        [144, 64, 132, 42]
+      ]
+    },
+    {
+      "name": "LayoutVideo VIDEO id='video'",
+      "position": [15, 859],
+      "bounds": [150, 60]
+    },
+    {
+      "name": "LayoutNGFlexibleBox DIV class='sizing-small phase-pre-ready state-no-source'",
+      "position": [15, 859],
+      "bounds": [150, 60],
+      "contentsOpaqueForText": true
+    },
+    {
+      "name": "VerticalScrollbar",
+      "position": [785, 0],
+      "bounds": [15, 600]
+    }
+  ]
+}
+
diff --git a/third_party/blink/web_tests/platform/mac-mac11-arm64/compositing/video/video-controls-squashing-expected.png b/third_party/blink/web_tests/platform/mac-mac11-arm64/compositing/video/video-controls-squashing-expected.png
index 81c6858..66407e0 100644
--- a/third_party/blink/web_tests/platform/mac-mac11-arm64/compositing/video/video-controls-squashing-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac11-arm64/compositing/video/video-controls-squashing-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/compositing/video/video-controls-squashing-expected.png b/third_party/blink/web_tests/platform/mac/compositing/video/video-controls-squashing-expected.png
index d149eb9..459f405 100644
--- a/third_party/blink/web_tests/platform/mac/compositing/video/video-controls-squashing-expected.png
+++ b/third_party/blink/web_tests/platform/mac/compositing/video/video-controls-squashing-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/compositing/video/video-poster-expected.txt b/third_party/blink/web_tests/platform/mac/compositing/video/video-poster-expected.txt
index ae935f5..d0c6078c 100644
--- a/third_party/blink/web_tests/platform/mac/compositing/video/video-poster-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/compositing/video/video-poster-expected.txt
@@ -38,31 +38,20 @@
     },
     {
       "name": "LayoutVideo VIDEO",
-      "bounds": [352, 288],
-      "transform": 1
+      "position": [8, 8],
+      "bounds": [352, 288]
     },
     {
       "name": "LayoutNGFlexibleBox DIV class='sizing-small phase-pre-ready state-no-source'",
+      "position": [8, 8],
       "bounds": [352, 288],
-      "contentsOpaqueForText": true,
-      "transform": 1
+      "contentsOpaqueForText": true
     },
     {
       "name": "VerticalScrollbar",
       "position": [785, 0],
       "bounds": [15, 600]
     }
-  ],
-  "transforms": [
-    {
-      "id": 1,
-      "transform": [
-        [1, 0, 0, 0],
-        [0, 1, 0, 0],
-        [0, 0, 1, 0],
-        [8, 8, 0, 1]
-      ]
-    }
   ]
 }
 
diff --git a/third_party/blink/web_tests/platform/mac/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt b/third_party/blink/web_tests/platform/mac/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
index 2280a61..818b1a4 100644
--- a/third_party/blink/web_tests/platform/mac/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
@@ -54,31 +54,20 @@
     },
     {
       "name": "LayoutVideo VIDEO id='video'",
-      "bounds": [150, 60],
-      "transform": 1
+      "position": [15, 854],
+      "bounds": [150, 60]
     },
     {
       "name": "LayoutNGFlexibleBox DIV class='sizing-small phase-pre-ready state-no-source'",
+      "position": [15, 854],
       "bounds": [150, 60],
-      "contentsOpaqueForText": true,
-      "transform": 1
+      "contentsOpaqueForText": true
     },
     {
       "name": "VerticalScrollbar",
       "position": [785, 0],
       "bounds": [15, 600]
     }
-  ],
-  "transforms": [
-    {
-      "id": 1,
-      "transform": [
-        [1, 0, 0, 0],
-        [0, 1, 0, 0],
-        [0, 0, 1, 0],
-        [15, 854, 0, 1]
-      ]
-    }
   ]
 }
 
diff --git a/third_party/blink/web_tests/platform/win/compositing/video/video-controls-squashing-expected.png b/third_party/blink/web_tests/platform/win/compositing/video/video-controls-squashing-expected.png
index 3ff853f..0f8c135 100644
--- a/third_party/blink/web_tests/platform/win/compositing/video/video-controls-squashing-expected.png
+++ b/third_party/blink/web_tests/platform/win/compositing/video/video-controls-squashing-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/compositing/video/video-poster-expected.txt b/third_party/blink/web_tests/platform/win/compositing/video/video-poster-expected.txt
index 5db5b0d2..978825d 100644
--- a/third_party/blink/web_tests/platform/win/compositing/video/video-poster-expected.txt
+++ b/third_party/blink/web_tests/platform/win/compositing/video/video-poster-expected.txt
@@ -38,31 +38,20 @@
     },
     {
       "name": "LayoutVideo VIDEO",
-      "bounds": [352, 288],
-      "transform": 1
+      "position": [8, 8],
+      "bounds": [352, 288]
     },
     {
       "name": "LayoutNGFlexibleBox DIV class='sizing-small phase-pre-ready state-no-source'",
+      "position": [8, 8],
       "bounds": [352, 288],
-      "contentsOpaqueForText": true,
-      "transform": 1
+      "contentsOpaqueForText": true
     },
     {
       "name": "VerticalScrollbar",
       "position": [785, 0],
       "bounds": [15, 600]
     }
-  ],
-  "transforms": [
-    {
-      "id": 1,
-      "transform": [
-        [1, 0, 0, 0],
-        [0, 1, 0, 0],
-        [0, 0, 1, 0],
-        [8, 8, 0, 1]
-      ]
-    }
   ]
 }
 
diff --git a/third_party/blink/web_tests/platform/win/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt b/third_party/blink/web_tests/platform/win/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
index 1f9ff19..4b7c8f7 100644
--- a/third_party/blink/web_tests/platform/win/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
+++ b/third_party/blink/web_tests/platform/win/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
@@ -54,31 +54,20 @@
     },
     {
       "name": "LayoutVideo VIDEO id='video'",
-      "bounds": [150, 60],
-      "transform": 1
+      "position": [15, 859],
+      "bounds": [150, 60]
     },
     {
       "name": "LayoutNGFlexibleBox DIV class='sizing-small phase-pre-ready state-no-source'",
+      "position": [15, 859],
       "bounds": [150, 60],
-      "contentsOpaqueForText": true,
-      "transform": 1
+      "contentsOpaqueForText": true
     },
     {
       "name": "VerticalScrollbar",
       "position": [785, 0],
       "bounds": [15, 600]
     }
-  ],
-  "transforms": [
-    {
-      "id": 1,
-      "transform": [
-        [1, 0, 0, 0],
-        [0, 1, 0, 0],
-        [0, 0, 1, 0],
-        [15, 859, 0, 1]
-      ]
-    }
   ]
 }
 
diff --git a/third_party/blink/web_tests/resources/global-interface-listing.js b/third_party/blink/web_tests/resources/global-interface-listing.js
index 16fbc4e..098401f5 100644
--- a/third_party/blink/web_tests/resources/global-interface-listing.js
+++ b/third_party/blink/web_tests/resources/global-interface-listing.js
@@ -8,13 +8,11 @@
 // * |outputFunc| is called back with each line of output.
 
 function globalInterfaceListing(globalObject, propertyNamesInGlobal, platformSpecific, outputFunc) {
-
-// List of builtin JS constructors; Blink is not controlling what properties these
-// objects have, so exercising them in a Blink test doesn't make sense.
-//
-// If new builtins are added, please update this list along with the one in
-// web_tests/http/tests/worklet/webexposed/resources/global-interface-listing-worklet.js
-var jsBuiltins = new Set([
+  // List of builtin JS constructors; Blink is not controlling what properties
+  // these objects have, so exercising them in a Blink test doesn't make sense.
+  //
+  // If new builtins are added, please update this list.
+  var jsBuiltins = new Set([
     'AggregateError',
     'Array',
     'ArrayBuffer',
@@ -75,12 +73,12 @@
     'parseInt',
     'undefined',
     'unescape',
-]);
+  ]);
 
-function isWebIDLInterface(propertyKey) {
+  function isWebIDLInterface(propertyKey) {
     if (jsBuiltins.has(propertyKey))
         return false;
-    var descriptor = Object.getOwnPropertyDescriptor(this, propertyKey);
+    var descriptor = Object.getOwnPropertyDescriptor(globalObject, propertyKey);
     if (descriptor.value == undefined || descriptor.value.prototype == undefined)
         return false;
     return descriptor.writable && !descriptor.enumerable && descriptor.configurable;
@@ -89,7 +87,8 @@
 function isWebIDLNamespace(propertyKey) {
     if (jsBuiltins.has(propertyKey))
         return false;
-    let object = Object.getOwnPropertyDescriptor(this, propertyKey).value;
+    let object =
+        Object.getOwnPropertyDescriptor(globalObject, propertyKey).value;
     if (object == undefined || typeof(object) != 'object' ||
         object.prototype != undefined) {
         return false;
@@ -206,13 +205,14 @@
 }
 
 function outputWebIDLInterface(interfaceName) {
-    var inheritsFrom = this[interfaceName].__proto__.name;
-    if (inheritsFrom)
-        outputFunc('interface ' + interfaceName + ' : ' + inheritsFrom);
-    else
-        outputFunc('interface ' + interfaceName);
-    // List static properties then prototype properties.
-    [this[interfaceName], this[interfaceName].prototype].forEach(function(object) {
+  var inheritsFrom = globalObject[interfaceName].__proto__.name;
+  if (inheritsFrom)
+    outputFunc('interface ' + interfaceName + ' : ' + inheritsFrom);
+  else
+    outputFunc('interface ' + interfaceName);
+  // List static properties then prototype properties.
+  [globalObject[interfaceName], globalObject[interfaceName].prototype].forEach(
+      function(object) {
         var propertyKeys = collectPropertyKeys(object);
         var propertyStrings = [];
         propertyKeys.forEach(function(propertyKey) {
@@ -221,12 +221,12 @@
 
         propertyStrings.filter((property) => filterPlatformSpecificProperty(interfaceName, property))
             .sort().forEach(outputProperty);
-    });
+      });
 }
 
 function outputWebIDLNamespace(namespaceName) {
     outputFunc('namespace ' + namespaceName);
-    let object = this[namespaceName];
+    let object = globalObject[namespaceName];
     let propertyKeys = collectPropertyKeys(object);
     let propertyStrings = [];
     propertyKeys.forEach((propertyKey) => {
@@ -237,16 +237,16 @@
 }
 
 outputFunc('[INTERFACES]');
-var interfaceNames = Object.getOwnPropertyNames(this)
-                           .filter(isWebIDLInterface)
-                           .filter(filterPlatformSpecificInterface);
+var interfaceNames = Object.getOwnPropertyNames(globalObject)
+                         .filter(isWebIDLInterface)
+                         .filter(filterPlatformSpecificInterface);
 interfaceNames.sort();
 interfaceNames.forEach(outputWebIDLInterface);
 
 outputFunc('[NAMESPACES]');
-let namespaceNames = Object.getOwnPropertyNames(this)
-                           .filter(isWebIDLNamespace)
-                           .filter(filterPlatformSpecificInterface);
+let namespaceNames = Object.getOwnPropertyNames(globalObject)
+                         .filter(isWebIDLNamespace)
+                         .filter(filterPlatformSpecificInterface);
 namespaceNames.sort();
 namespaceNames.forEach(outputWebIDLNamespace);
 
@@ -262,3 +262,21 @@
 });
 propertyStrings.sort().filter(filterPlatformSpecificGlobalProperty).forEach(outputProperty);
 }
+
+// We're in a paint worklet, invoke the test function immediately.
+// This is done here because worklets can not easily import non-module
+// libraries (i.e. load more than one script and share access to state).
+if (typeof PaintWorkletGlobalScope == 'function') {
+  // Generally, Worklet should not have a reference to the global object.
+  // https://drafts.css-houdini.org/worklets/#code-idempotency
+  if (this) {
+    console.error('"this" should not refer to the global object');
+  }
+
+  // However, globalThis is accessible. For now...
+  // See https://github.com/whatwg/html/issues/6059
+  let propertyNamesInGlobal = Object.getOwnPropertyNames(globalThis);
+
+  globalInterfaceListing(
+      globalThis, propertyNamesInGlobal, false, (x) => console.log(x));
+}
diff --git a/third_party/blink/web_tests/virtual/font-access-persistent/OWNERS b/third_party/blink/web_tests/virtual/font-access/OWNERS
similarity index 100%
rename from third_party/blink/web_tests/virtual/font-access-persistent/OWNERS
rename to third_party/blink/web_tests/virtual/font-access/OWNERS
diff --git a/third_party/blink/web_tests/virtual/font-access-persistent/README.md b/third_party/blink/web_tests/virtual/font-access/README.md
similarity index 100%
rename from third_party/blink/web_tests/virtual/font-access-persistent/README.md
rename to third_party/blink/web_tests/virtual/font-access/README.md
diff --git a/third_party/blink/web_tests/virtual/threaded/http/tests/worklet/webexposed/global-interface-listing-paint-worklet-expected.txt b/third_party/blink/web_tests/virtual/threaded/http/tests/worklet/webexposed/global-interface-listing-paint-worklet-expected.txt
deleted file mode 100644
index b3bc60e..0000000
--- a/third_party/blink/web_tests/virtual/threaded/http/tests/worklet/webexposed/global-interface-listing-paint-worklet-expected.txt
+++ /dev/null
@@ -1,1118 +0,0 @@
-CONSOLE MESSAGE: line 10: This test logs exposed APIs once from each PaintWorkletGlobalScope
-CONSOLE MESSAGE: line 153: interface ByteLengthQueuingStrategy
-CONSOLE MESSAGE: line 153:     getter highWaterMark
-CONSOLE MESSAGE: line 153:     getter size
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSImageValue : CSSStyleValue
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSKeywordValue : CSSStyleValue
-CONSOLE MESSAGE: line 153:     getter value
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter value
-CONSOLE MESSAGE: line 153: interface CSSMathInvert : CSSMathValue
-CONSOLE MESSAGE: line 153:     getter value
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMathMax : CSSMathValue
-CONSOLE MESSAGE: line 153:     getter values
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMathMin : CSSMathValue
-CONSOLE MESSAGE: line 153:     getter values
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMathNegate : CSSMathValue
-CONSOLE MESSAGE: line 153:     getter value
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMathProduct : CSSMathValue
-CONSOLE MESSAGE: line 153:     getter values
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMathSum : CSSMathValue
-CONSOLE MESSAGE: line 153:     getter values
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMathValue : CSSNumericValue
-CONSOLE MESSAGE: line 153:     getter operator
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMatrixComponent : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter matrix
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter matrix
-CONSOLE MESSAGE: line 153: interface CSSNumericArray
-CONSOLE MESSAGE: line 153:     getter length
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method entries
-CONSOLE MESSAGE: line 153:     method forEach
-CONSOLE MESSAGE: line 153:     method keys
-CONSOLE MESSAGE: line 153:     method values
-CONSOLE MESSAGE: line 153: interface CSSNumericValue : CSSStyleValue
-CONSOLE MESSAGE: line 153:     method add
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method div
-CONSOLE MESSAGE: line 153:     method equals
-CONSOLE MESSAGE: line 153:     method max
-CONSOLE MESSAGE: line 153:     method min
-CONSOLE MESSAGE: line 153:     method mul
-CONSOLE MESSAGE: line 153:     method sub
-CONSOLE MESSAGE: line 153:     method to
-CONSOLE MESSAGE: line 153:     method toSum
-CONSOLE MESSAGE: line 153:     method type
-CONSOLE MESSAGE: line 153: interface CSSPerspective : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter length
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter length
-CONSOLE MESSAGE: line 153: interface CSSPositionValue : CSSStyleValue
-CONSOLE MESSAGE: line 153:     getter x
-CONSOLE MESSAGE: line 153:     getter y
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter x
-CONSOLE MESSAGE: line 153:     setter y
-CONSOLE MESSAGE: line 153: interface CSSRotate : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter angle
-CONSOLE MESSAGE: line 153:     getter x
-CONSOLE MESSAGE: line 153:     getter y
-CONSOLE MESSAGE: line 153:     getter z
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter angle
-CONSOLE MESSAGE: line 153:     setter x
-CONSOLE MESSAGE: line 153:     setter y
-CONSOLE MESSAGE: line 153:     setter z
-CONSOLE MESSAGE: line 153: interface CSSScale : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter x
-CONSOLE MESSAGE: line 153:     getter y
-CONSOLE MESSAGE: line 153:     getter z
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter x
-CONSOLE MESSAGE: line 153:     setter y
-CONSOLE MESSAGE: line 153:     setter z
-CONSOLE MESSAGE: line 153: interface CSSSkew : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter ax
-CONSOLE MESSAGE: line 153:     getter ay
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter ax
-CONSOLE MESSAGE: line 153:     setter ay
-CONSOLE MESSAGE: line 153: interface CSSSkewX : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter ax
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter ax
-CONSOLE MESSAGE: line 153: interface CSSSkewY : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter ay
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter ay
-CONSOLE MESSAGE: line 153: interface CSSStyleValue
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method toString
-CONSOLE MESSAGE: line 153: interface CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter is2D
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method toMatrix
-CONSOLE MESSAGE: line 153:     method toString
-CONSOLE MESSAGE: line 153:     setter is2D
-CONSOLE MESSAGE: line 153: interface CSSTransformValue : CSSStyleValue
-CONSOLE MESSAGE: line 153:     getter is2D
-CONSOLE MESSAGE: line 153:     getter length
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method entries
-CONSOLE MESSAGE: line 153:     method forEach
-CONSOLE MESSAGE: line 153:     method keys
-CONSOLE MESSAGE: line 153:     method toMatrix
-CONSOLE MESSAGE: line 153:     method values
-CONSOLE MESSAGE: line 153: interface CSSTranslate : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter x
-CONSOLE MESSAGE: line 153:     getter y
-CONSOLE MESSAGE: line 153:     getter z
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter x
-CONSOLE MESSAGE: line 153:     setter y
-CONSOLE MESSAGE: line 153:     setter z
-CONSOLE MESSAGE: line 153: interface CSSUnitValue : CSSNumericValue
-CONSOLE MESSAGE: line 153:     getter unit
-CONSOLE MESSAGE: line 153:     getter value
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter value
-CONSOLE MESSAGE: line 153: interface CSSUnparsedValue : CSSStyleValue
-CONSOLE MESSAGE: line 153:     getter length
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method entries
-CONSOLE MESSAGE: line 153:     method forEach
-CONSOLE MESSAGE: line 153:     method keys
-CONSOLE MESSAGE: line 153:     method values
-CONSOLE MESSAGE: line 153: interface CSSVariableReferenceValue
-CONSOLE MESSAGE: line 153:     getter fallback
-CONSOLE MESSAGE: line 153:     getter variable
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter variable
-CONSOLE MESSAGE: line 153: interface CountQueuingStrategy
-CONSOLE MESSAGE: line 153:     getter highWaterMark
-CONSOLE MESSAGE: line 153:     getter size
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface PaintRenderingContext2D
-CONSOLE MESSAGE: line 153:     getter fillStyle
-CONSOLE MESSAGE: line 153:     getter filter
-CONSOLE MESSAGE: line 153:     getter globalAlpha
-CONSOLE MESSAGE: line 153:     getter globalCompositeOperation
-CONSOLE MESSAGE: line 153:     getter imageSmoothingEnabled
-CONSOLE MESSAGE: line 153:     getter imageSmoothingQuality
-CONSOLE MESSAGE: line 153:     getter lineCap
-CONSOLE MESSAGE: line 153:     getter lineDashOffset
-CONSOLE MESSAGE: line 153:     getter lineJoin
-CONSOLE MESSAGE: line 153:     getter lineWidth
-CONSOLE MESSAGE: line 153:     getter miterLimit
-CONSOLE MESSAGE: line 153:     getter shadowBlur
-CONSOLE MESSAGE: line 153:     getter shadowColor
-CONSOLE MESSAGE: line 153:     getter shadowOffsetX
-CONSOLE MESSAGE: line 153:     getter shadowOffsetY
-CONSOLE MESSAGE: line 153:     getter strokeStyle
-CONSOLE MESSAGE: line 153:     method arc
-CONSOLE MESSAGE: line 153:     method arcTo
-CONSOLE MESSAGE: line 153:     method beginPath
-CONSOLE MESSAGE: line 153:     method bezierCurveTo
-CONSOLE MESSAGE: line 153:     method clearRect
-CONSOLE MESSAGE: line 153:     method clip
-CONSOLE MESSAGE: line 153:     method closePath
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method createLinearGradient
-CONSOLE MESSAGE: line 153:     method createPattern
-CONSOLE MESSAGE: line 153:     method createRadialGradient
-CONSOLE MESSAGE: line 153:     method drawImage
-CONSOLE MESSAGE: line 153:     method ellipse
-CONSOLE MESSAGE: line 153:     method fill
-CONSOLE MESSAGE: line 153:     method fillRect
-CONSOLE MESSAGE: line 153:     method getLineDash
-CONSOLE MESSAGE: line 153:     method getTransform
-CONSOLE MESSAGE: line 153:     method isPointInPath
-CONSOLE MESSAGE: line 153:     method isPointInStroke
-CONSOLE MESSAGE: line 153:     method lineTo
-CONSOLE MESSAGE: line 153:     method moveTo
-CONSOLE MESSAGE: line 153:     method quadraticCurveTo
-CONSOLE MESSAGE: line 153:     method rect
-CONSOLE MESSAGE: line 153:     method resetTransform
-CONSOLE MESSAGE: line 153:     method restore
-CONSOLE MESSAGE: line 153:     method rotate
-CONSOLE MESSAGE: line 153:     method save
-CONSOLE MESSAGE: line 153:     method scale
-CONSOLE MESSAGE: line 153:     method setLineDash
-CONSOLE MESSAGE: line 153:     method setTransform
-CONSOLE MESSAGE: line 153:     method stroke
-CONSOLE MESSAGE: line 153:     method strokeRect
-CONSOLE MESSAGE: line 153:     method transform
-CONSOLE MESSAGE: line 153:     method translate
-CONSOLE MESSAGE: line 153:     setter fillStyle
-CONSOLE MESSAGE: line 153:     setter filter
-CONSOLE MESSAGE: line 153:     setter globalAlpha
-CONSOLE MESSAGE: line 153:     setter globalCompositeOperation
-CONSOLE MESSAGE: line 153:     setter imageSmoothingEnabled
-CONSOLE MESSAGE: line 153:     setter imageSmoothingQuality
-CONSOLE MESSAGE: line 153:     setter lineCap
-CONSOLE MESSAGE: line 153:     setter lineDashOffset
-CONSOLE MESSAGE: line 153:     setter lineJoin
-CONSOLE MESSAGE: line 153:     setter lineWidth
-CONSOLE MESSAGE: line 153:     setter miterLimit
-CONSOLE MESSAGE: line 153:     setter shadowBlur
-CONSOLE MESSAGE: line 153:     setter shadowColor
-CONSOLE MESSAGE: line 153:     setter shadowOffsetX
-CONSOLE MESSAGE: line 153:     setter shadowOffsetY
-CONSOLE MESSAGE: line 153:     setter strokeStyle
-CONSOLE MESSAGE: line 153: interface PaintSize
-CONSOLE MESSAGE: line 153:     getter height
-CONSOLE MESSAGE: line 153:     getter width
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface PaintWorkletGlobalScope : WorkletGlobalScope
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface Path2D
-CONSOLE MESSAGE: line 153:     method addPath
-CONSOLE MESSAGE: line 153:     method arc
-CONSOLE MESSAGE: line 153:     method arcTo
-CONSOLE MESSAGE: line 153:     method bezierCurveTo
-CONSOLE MESSAGE: line 153:     method closePath
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method ellipse
-CONSOLE MESSAGE: line 153:     method lineTo
-CONSOLE MESSAGE: line 153:     method moveTo
-CONSOLE MESSAGE: line 153:     method quadraticCurveTo
-CONSOLE MESSAGE: line 153:     method rect
-CONSOLE MESSAGE: line 153: interface ReadableStream
-CONSOLE MESSAGE: line 153:     getter locked
-CONSOLE MESSAGE: line 153:     method cancel
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method getReader
-CONSOLE MESSAGE: line 153:     method pipeThrough
-CONSOLE MESSAGE: line 153:     method pipeTo
-CONSOLE MESSAGE: line 153:     method tee
-CONSOLE MESSAGE: line 153: interface ReadableStreamDefaultReader
-CONSOLE MESSAGE: line 153:     getter closed
-CONSOLE MESSAGE: line 153:     method cancel
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method read
-CONSOLE MESSAGE: line 153:     method releaseLock
-CONSOLE MESSAGE: line 153: interface StylePropertyMapReadOnly
-CONSOLE MESSAGE: line 153:     getter size
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method entries
-CONSOLE MESSAGE: line 153:     method forEach
-CONSOLE MESSAGE: line 153:     method get
-CONSOLE MESSAGE: line 153:     method getAll
-CONSOLE MESSAGE: line 153:     method has
-CONSOLE MESSAGE: line 153:     method keys
-CONSOLE MESSAGE: line 153:     method values
-CONSOLE MESSAGE: line 153: interface TransformStream
-CONSOLE MESSAGE: line 153:     getter readable
-CONSOLE MESSAGE: line 153:     getter writable
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface WorkletGlobalScope
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface WritableStream
-CONSOLE MESSAGE: line 153:     getter locked
-CONSOLE MESSAGE: line 153:     method abort
-CONSOLE MESSAGE: line 153:     method close
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method getWriter
-CONSOLE MESSAGE: line 153: interface WritableStreamDefaultWriter
-CONSOLE MESSAGE: line 153:     getter closed
-CONSOLE MESSAGE: line 153:     getter desiredSize
-CONSOLE MESSAGE: line 153:     getter ready
-CONSOLE MESSAGE: line 153:     method abort
-CONSOLE MESSAGE: line 153:     method close
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method releaseLock
-CONSOLE MESSAGE: line 153:     method write
-CONSOLE MESSAGE: line 153: global object
-CONSOLE MESSAGE: line 153:     attribute console
-CONSOLE MESSAGE: line 153:     attribute globalThis
-CONSOLE MESSAGE: line 153:     getter devicePixelRatio
-CONSOLE MESSAGE: line 153:     method gc
-CONSOLE MESSAGE: line 153:     method registerPaint
-CONSOLE MESSAGE: line 153: interface ByteLengthQueuingStrategy
-CONSOLE MESSAGE: line 153:     getter highWaterMark
-CONSOLE MESSAGE: line 153:     getter size
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSImageValue : CSSStyleValue
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSKeywordValue : CSSStyleValue
-CONSOLE MESSAGE: line 153:     getter value
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter value
-CONSOLE MESSAGE: line 153: interface CSSMathInvert : CSSMathValue
-CONSOLE MESSAGE: line 153:     getter value
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMathMax : CSSMathValue
-CONSOLE MESSAGE: line 153:     getter values
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMathMin : CSSMathValue
-CONSOLE MESSAGE: line 153:     getter values
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMathNegate : CSSMathValue
-CONSOLE MESSAGE: line 153:     getter value
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMathProduct : CSSMathValue
-CONSOLE MESSAGE: line 153:     getter values
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMathSum : CSSMathValue
-CONSOLE MESSAGE: line 153:     getter values
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMathValue : CSSNumericValue
-CONSOLE MESSAGE: line 153:     getter operator
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMatrixComponent : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter matrix
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter matrix
-CONSOLE MESSAGE: line 153: interface CSSNumericArray
-CONSOLE MESSAGE: line 153:     getter length
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method entries
-CONSOLE MESSAGE: line 153:     method forEach
-CONSOLE MESSAGE: line 153:     method keys
-CONSOLE MESSAGE: line 153:     method values
-CONSOLE MESSAGE: line 153: interface CSSNumericValue : CSSStyleValue
-CONSOLE MESSAGE: line 153:     method add
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method div
-CONSOLE MESSAGE: line 153:     method equals
-CONSOLE MESSAGE: line 153:     method max
-CONSOLE MESSAGE: line 153:     method min
-CONSOLE MESSAGE: line 153:     method mul
-CONSOLE MESSAGE: line 153:     method sub
-CONSOLE MESSAGE: line 153:     method to
-CONSOLE MESSAGE: line 153:     method toSum
-CONSOLE MESSAGE: line 153:     method type
-CONSOLE MESSAGE: line 153: interface CSSPerspective : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter length
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter length
-CONSOLE MESSAGE: line 153: interface CSSPositionValue : CSSStyleValue
-CONSOLE MESSAGE: line 153:     getter x
-CONSOLE MESSAGE: line 153:     getter y
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter x
-CONSOLE MESSAGE: line 153:     setter y
-CONSOLE MESSAGE: line 153: interface CSSRotate : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter angle
-CONSOLE MESSAGE: line 153:     getter x
-CONSOLE MESSAGE: line 153:     getter y
-CONSOLE MESSAGE: line 153:     getter z
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter angle
-CONSOLE MESSAGE: line 153:     setter x
-CONSOLE MESSAGE: line 153:     setter y
-CONSOLE MESSAGE: line 153:     setter z
-CONSOLE MESSAGE: line 153: interface CSSScale : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter x
-CONSOLE MESSAGE: line 153:     getter y
-CONSOLE MESSAGE: line 153:     getter z
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter x
-CONSOLE MESSAGE: line 153:     setter y
-CONSOLE MESSAGE: line 153:     setter z
-CONSOLE MESSAGE: line 153: interface CSSSkew : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter ax
-CONSOLE MESSAGE: line 153:     getter ay
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter ax
-CONSOLE MESSAGE: line 153:     setter ay
-CONSOLE MESSAGE: line 153: interface CSSSkewX : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter ax
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter ax
-CONSOLE MESSAGE: line 153: interface CSSSkewY : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter ay
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter ay
-CONSOLE MESSAGE: line 153: interface CSSStyleValue
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method toString
-CONSOLE MESSAGE: line 153: interface CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter is2D
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method toMatrix
-CONSOLE MESSAGE: line 153:     method toString
-CONSOLE MESSAGE: line 153:     setter is2D
-CONSOLE MESSAGE: line 153: interface CSSTransformValue : CSSStyleValue
-CONSOLE MESSAGE: line 153:     getter is2D
-CONSOLE MESSAGE: line 153:     getter length
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method entries
-CONSOLE MESSAGE: line 153:     method forEach
-CONSOLE MESSAGE: line 153:     method keys
-CONSOLE MESSAGE: line 153:     method toMatrix
-CONSOLE MESSAGE: line 153:     method values
-CONSOLE MESSAGE: line 153: interface CSSTranslate : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter x
-CONSOLE MESSAGE: line 153:     getter y
-CONSOLE MESSAGE: line 153:     getter z
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter x
-CONSOLE MESSAGE: line 153:     setter y
-CONSOLE MESSAGE: line 153:     setter z
-CONSOLE MESSAGE: line 153: interface CSSUnitValue : CSSNumericValue
-CONSOLE MESSAGE: line 153:     getter unit
-CONSOLE MESSAGE: line 153:     getter value
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter value
-CONSOLE MESSAGE: line 153: interface CSSUnparsedValue : CSSStyleValue
-CONSOLE MESSAGE: line 153:     getter length
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method entries
-CONSOLE MESSAGE: line 153:     method forEach
-CONSOLE MESSAGE: line 153:     method keys
-CONSOLE MESSAGE: line 153:     method values
-CONSOLE MESSAGE: line 153: interface CSSVariableReferenceValue
-CONSOLE MESSAGE: line 153:     getter fallback
-CONSOLE MESSAGE: line 153:     getter variable
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter variable
-CONSOLE MESSAGE: line 153: interface CountQueuingStrategy
-CONSOLE MESSAGE: line 153:     getter highWaterMark
-CONSOLE MESSAGE: line 153:     getter size
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface PaintRenderingContext2D
-CONSOLE MESSAGE: line 153:     getter fillStyle
-CONSOLE MESSAGE: line 153:     getter filter
-CONSOLE MESSAGE: line 153:     getter globalAlpha
-CONSOLE MESSAGE: line 153:     getter globalCompositeOperation
-CONSOLE MESSAGE: line 153:     getter imageSmoothingEnabled
-CONSOLE MESSAGE: line 153:     getter imageSmoothingQuality
-CONSOLE MESSAGE: line 153:     getter lineCap
-CONSOLE MESSAGE: line 153:     getter lineDashOffset
-CONSOLE MESSAGE: line 153:     getter lineJoin
-CONSOLE MESSAGE: line 153:     getter lineWidth
-CONSOLE MESSAGE: line 153:     getter miterLimit
-CONSOLE MESSAGE: line 153:     getter shadowBlur
-CONSOLE MESSAGE: line 153:     getter shadowColor
-CONSOLE MESSAGE: line 153:     getter shadowOffsetX
-CONSOLE MESSAGE: line 153:     getter shadowOffsetY
-CONSOLE MESSAGE: line 153:     getter strokeStyle
-CONSOLE MESSAGE: line 153:     method arc
-CONSOLE MESSAGE: line 153:     method arcTo
-CONSOLE MESSAGE: line 153:     method beginPath
-CONSOLE MESSAGE: line 153:     method bezierCurveTo
-CONSOLE MESSAGE: line 153:     method clearRect
-CONSOLE MESSAGE: line 153:     method clip
-CONSOLE MESSAGE: line 153:     method closePath
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method createLinearGradient
-CONSOLE MESSAGE: line 153:     method createPattern
-CONSOLE MESSAGE: line 153:     method createRadialGradient
-CONSOLE MESSAGE: line 153:     method drawImage
-CONSOLE MESSAGE: line 153:     method ellipse
-CONSOLE MESSAGE: line 153:     method fill
-CONSOLE MESSAGE: line 153:     method fillRect
-CONSOLE MESSAGE: line 153:     method getLineDash
-CONSOLE MESSAGE: line 153:     method getTransform
-CONSOLE MESSAGE: line 153:     method isPointInPath
-CONSOLE MESSAGE: line 153:     method isPointInStroke
-CONSOLE MESSAGE: line 153:     method lineTo
-CONSOLE MESSAGE: line 153:     method moveTo
-CONSOLE MESSAGE: line 153:     method quadraticCurveTo
-CONSOLE MESSAGE: line 153:     method rect
-CONSOLE MESSAGE: line 153:     method resetTransform
-CONSOLE MESSAGE: line 153:     method restore
-CONSOLE MESSAGE: line 153:     method rotate
-CONSOLE MESSAGE: line 153:     method save
-CONSOLE MESSAGE: line 153:     method scale
-CONSOLE MESSAGE: line 153:     method setLineDash
-CONSOLE MESSAGE: line 153:     method setTransform
-CONSOLE MESSAGE: line 153:     method stroke
-CONSOLE MESSAGE: line 153:     method strokeRect
-CONSOLE MESSAGE: line 153:     method transform
-CONSOLE MESSAGE: line 153:     method translate
-CONSOLE MESSAGE: line 153:     setter fillStyle
-CONSOLE MESSAGE: line 153:     setter filter
-CONSOLE MESSAGE: line 153:     setter globalAlpha
-CONSOLE MESSAGE: line 153:     setter globalCompositeOperation
-CONSOLE MESSAGE: line 153:     setter imageSmoothingEnabled
-CONSOLE MESSAGE: line 153:     setter imageSmoothingQuality
-CONSOLE MESSAGE: line 153:     setter lineCap
-CONSOLE MESSAGE: line 153:     setter lineDashOffset
-CONSOLE MESSAGE: line 153:     setter lineJoin
-CONSOLE MESSAGE: line 153:     setter lineWidth
-CONSOLE MESSAGE: line 153:     setter miterLimit
-CONSOLE MESSAGE: line 153:     setter shadowBlur
-CONSOLE MESSAGE: line 153:     setter shadowColor
-CONSOLE MESSAGE: line 153:     setter shadowOffsetX
-CONSOLE MESSAGE: line 153:     setter shadowOffsetY
-CONSOLE MESSAGE: line 153:     setter strokeStyle
-CONSOLE MESSAGE: line 153: interface PaintSize
-CONSOLE MESSAGE: line 153:     getter height
-CONSOLE MESSAGE: line 153:     getter width
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface PaintWorkletGlobalScope : WorkletGlobalScope
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface Path2D
-CONSOLE MESSAGE: line 153:     method addPath
-CONSOLE MESSAGE: line 153:     method arc
-CONSOLE MESSAGE: line 153:     method arcTo
-CONSOLE MESSAGE: line 153:     method bezierCurveTo
-CONSOLE MESSAGE: line 153:     method closePath
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method ellipse
-CONSOLE MESSAGE: line 153:     method lineTo
-CONSOLE MESSAGE: line 153:     method moveTo
-CONSOLE MESSAGE: line 153:     method quadraticCurveTo
-CONSOLE MESSAGE: line 153:     method rect
-CONSOLE MESSAGE: line 153: interface ReadableStream
-CONSOLE MESSAGE: line 153:     getter locked
-CONSOLE MESSAGE: line 153:     method cancel
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method getReader
-CONSOLE MESSAGE: line 153:     method pipeThrough
-CONSOLE MESSAGE: line 153:     method pipeTo
-CONSOLE MESSAGE: line 153:     method tee
-CONSOLE MESSAGE: line 153: interface ReadableStreamDefaultReader
-CONSOLE MESSAGE: line 153:     getter closed
-CONSOLE MESSAGE: line 153:     method cancel
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method read
-CONSOLE MESSAGE: line 153:     method releaseLock
-CONSOLE MESSAGE: line 153: interface StylePropertyMapReadOnly
-CONSOLE MESSAGE: line 153:     getter size
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method entries
-CONSOLE MESSAGE: line 153:     method forEach
-CONSOLE MESSAGE: line 153:     method get
-CONSOLE MESSAGE: line 153:     method getAll
-CONSOLE MESSAGE: line 153:     method has
-CONSOLE MESSAGE: line 153:     method keys
-CONSOLE MESSAGE: line 153:     method values
-CONSOLE MESSAGE: line 153: interface TransformStream
-CONSOLE MESSAGE: line 153:     getter readable
-CONSOLE MESSAGE: line 153:     getter writable
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface WorkletGlobalScope
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface WritableStream
-CONSOLE MESSAGE: line 153:     getter locked
-CONSOLE MESSAGE: line 153:     method abort
-CONSOLE MESSAGE: line 153:     method close
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method getWriter
-CONSOLE MESSAGE: line 153: interface WritableStreamDefaultWriter
-CONSOLE MESSAGE: line 153:     getter closed
-CONSOLE MESSAGE: line 153:     getter desiredSize
-CONSOLE MESSAGE: line 153:     getter ready
-CONSOLE MESSAGE: line 153:     method abort
-CONSOLE MESSAGE: line 153:     method close
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method releaseLock
-CONSOLE MESSAGE: line 153:     method write
-CONSOLE MESSAGE: line 153: global object
-CONSOLE MESSAGE: line 153:     attribute console
-CONSOLE MESSAGE: line 153:     attribute globalThis
-CONSOLE MESSAGE: line 153:     getter devicePixelRatio
-CONSOLE MESSAGE: line 153:     method gc
-CONSOLE MESSAGE: line 153:     method registerPaint
-CONSOLE MESSAGE: line 153: interface ByteLengthQueuingStrategy
-CONSOLE MESSAGE: line 153:     getter highWaterMark
-CONSOLE MESSAGE: line 153:     getter size
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSImageValue : CSSStyleValue
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSKeywordValue : CSSStyleValue
-CONSOLE MESSAGE: line 153:     getter value
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter value
-CONSOLE MESSAGE: line 153: interface CSSMathInvert : CSSMathValue
-CONSOLE MESSAGE: line 153:     getter value
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMathMax : CSSMathValue
-CONSOLE MESSAGE: line 153:     getter values
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMathMin : CSSMathValue
-CONSOLE MESSAGE: line 153:     getter values
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMathNegate : CSSMathValue
-CONSOLE MESSAGE: line 153:     getter value
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMathProduct : CSSMathValue
-CONSOLE MESSAGE: line 153:     getter values
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMathSum : CSSMathValue
-CONSOLE MESSAGE: line 153:     getter values
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMathValue : CSSNumericValue
-CONSOLE MESSAGE: line 153:     getter operator
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMatrixComponent : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter matrix
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter matrix
-CONSOLE MESSAGE: line 153: interface CSSNumericArray
-CONSOLE MESSAGE: line 153:     getter length
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method entries
-CONSOLE MESSAGE: line 153:     method forEach
-CONSOLE MESSAGE: line 153:     method keys
-CONSOLE MESSAGE: line 153:     method values
-CONSOLE MESSAGE: line 153: interface CSSNumericValue : CSSStyleValue
-CONSOLE MESSAGE: line 153:     method add
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method div
-CONSOLE MESSAGE: line 153:     method equals
-CONSOLE MESSAGE: line 153:     method max
-CONSOLE MESSAGE: line 153:     method min
-CONSOLE MESSAGE: line 153:     method mul
-CONSOLE MESSAGE: line 153:     method sub
-CONSOLE MESSAGE: line 153:     method to
-CONSOLE MESSAGE: line 153:     method toSum
-CONSOLE MESSAGE: line 153:     method type
-CONSOLE MESSAGE: line 153: interface CSSPerspective : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter length
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter length
-CONSOLE MESSAGE: line 153: interface CSSPositionValue : CSSStyleValue
-CONSOLE MESSAGE: line 153:     getter x
-CONSOLE MESSAGE: line 153:     getter y
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter x
-CONSOLE MESSAGE: line 153:     setter y
-CONSOLE MESSAGE: line 153: interface CSSRotate : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter angle
-CONSOLE MESSAGE: line 153:     getter x
-CONSOLE MESSAGE: line 153:     getter y
-CONSOLE MESSAGE: line 153:     getter z
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter angle
-CONSOLE MESSAGE: line 153:     setter x
-CONSOLE MESSAGE: line 153:     setter y
-CONSOLE MESSAGE: line 153:     setter z
-CONSOLE MESSAGE: line 153: interface CSSScale : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter x
-CONSOLE MESSAGE: line 153:     getter y
-CONSOLE MESSAGE: line 153:     getter z
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter x
-CONSOLE MESSAGE: line 153:     setter y
-CONSOLE MESSAGE: line 153:     setter z
-CONSOLE MESSAGE: line 153: interface CSSSkew : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter ax
-CONSOLE MESSAGE: line 153:     getter ay
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter ax
-CONSOLE MESSAGE: line 153:     setter ay
-CONSOLE MESSAGE: line 153: interface CSSSkewX : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter ax
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter ax
-CONSOLE MESSAGE: line 153: interface CSSSkewY : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter ay
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter ay
-CONSOLE MESSAGE: line 153: interface CSSStyleValue
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method toString
-CONSOLE MESSAGE: line 153: interface CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter is2D
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method toMatrix
-CONSOLE MESSAGE: line 153:     method toString
-CONSOLE MESSAGE: line 153:     setter is2D
-CONSOLE MESSAGE: line 153: interface CSSTransformValue : CSSStyleValue
-CONSOLE MESSAGE: line 153:     getter is2D
-CONSOLE MESSAGE: line 153:     getter length
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method entries
-CONSOLE MESSAGE: line 153:     method forEach
-CONSOLE MESSAGE: line 153:     method keys
-CONSOLE MESSAGE: line 153:     method toMatrix
-CONSOLE MESSAGE: line 153:     method values
-CONSOLE MESSAGE: line 153: interface CSSTranslate : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter x
-CONSOLE MESSAGE: line 153:     getter y
-CONSOLE MESSAGE: line 153:     getter z
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter x
-CONSOLE MESSAGE: line 153:     setter y
-CONSOLE MESSAGE: line 153:     setter z
-CONSOLE MESSAGE: line 153: interface CSSUnitValue : CSSNumericValue
-CONSOLE MESSAGE: line 153:     getter unit
-CONSOLE MESSAGE: line 153:     getter value
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter value
-CONSOLE MESSAGE: line 153: interface CSSUnparsedValue : CSSStyleValue
-CONSOLE MESSAGE: line 153:     getter length
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method entries
-CONSOLE MESSAGE: line 153:     method forEach
-CONSOLE MESSAGE: line 153:     method keys
-CONSOLE MESSAGE: line 153:     method values
-CONSOLE MESSAGE: line 153: interface CSSVariableReferenceValue
-CONSOLE MESSAGE: line 153:     getter fallback
-CONSOLE MESSAGE: line 153:     getter variable
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter variable
-CONSOLE MESSAGE: line 153: interface CountQueuingStrategy
-CONSOLE MESSAGE: line 153:     getter highWaterMark
-CONSOLE MESSAGE: line 153:     getter size
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface PaintRenderingContext2D
-CONSOLE MESSAGE: line 153:     getter fillStyle
-CONSOLE MESSAGE: line 153:     getter filter
-CONSOLE MESSAGE: line 153:     getter globalAlpha
-CONSOLE MESSAGE: line 153:     getter globalCompositeOperation
-CONSOLE MESSAGE: line 153:     getter imageSmoothingEnabled
-CONSOLE MESSAGE: line 153:     getter imageSmoothingQuality
-CONSOLE MESSAGE: line 153:     getter lineCap
-CONSOLE MESSAGE: line 153:     getter lineDashOffset
-CONSOLE MESSAGE: line 153:     getter lineJoin
-CONSOLE MESSAGE: line 153:     getter lineWidth
-CONSOLE MESSAGE: line 153:     getter miterLimit
-CONSOLE MESSAGE: line 153:     getter shadowBlur
-CONSOLE MESSAGE: line 153:     getter shadowColor
-CONSOLE MESSAGE: line 153:     getter shadowOffsetX
-CONSOLE MESSAGE: line 153:     getter shadowOffsetY
-CONSOLE MESSAGE: line 153:     getter strokeStyle
-CONSOLE MESSAGE: line 153:     method arc
-CONSOLE MESSAGE: line 153:     method arcTo
-CONSOLE MESSAGE: line 153:     method beginPath
-CONSOLE MESSAGE: line 153:     method bezierCurveTo
-CONSOLE MESSAGE: line 153:     method clearRect
-CONSOLE MESSAGE: line 153:     method clip
-CONSOLE MESSAGE: line 153:     method closePath
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method createLinearGradient
-CONSOLE MESSAGE: line 153:     method createPattern
-CONSOLE MESSAGE: line 153:     method createRadialGradient
-CONSOLE MESSAGE: line 153:     method drawImage
-CONSOLE MESSAGE: line 153:     method ellipse
-CONSOLE MESSAGE: line 153:     method fill
-CONSOLE MESSAGE: line 153:     method fillRect
-CONSOLE MESSAGE: line 153:     method getLineDash
-CONSOLE MESSAGE: line 153:     method getTransform
-CONSOLE MESSAGE: line 153:     method isPointInPath
-CONSOLE MESSAGE: line 153:     method isPointInStroke
-CONSOLE MESSAGE: line 153:     method lineTo
-CONSOLE MESSAGE: line 153:     method moveTo
-CONSOLE MESSAGE: line 153:     method quadraticCurveTo
-CONSOLE MESSAGE: line 153:     method rect
-CONSOLE MESSAGE: line 153:     method resetTransform
-CONSOLE MESSAGE: line 153:     method restore
-CONSOLE MESSAGE: line 153:     method rotate
-CONSOLE MESSAGE: line 153:     method save
-CONSOLE MESSAGE: line 153:     method scale
-CONSOLE MESSAGE: line 153:     method setLineDash
-CONSOLE MESSAGE: line 153:     method setTransform
-CONSOLE MESSAGE: line 153:     method stroke
-CONSOLE MESSAGE: line 153:     method strokeRect
-CONSOLE MESSAGE: line 153:     method transform
-CONSOLE MESSAGE: line 153:     method translate
-CONSOLE MESSAGE: line 153:     setter fillStyle
-CONSOLE MESSAGE: line 153:     setter filter
-CONSOLE MESSAGE: line 153:     setter globalAlpha
-CONSOLE MESSAGE: line 153:     setter globalCompositeOperation
-CONSOLE MESSAGE: line 153:     setter imageSmoothingEnabled
-CONSOLE MESSAGE: line 153:     setter imageSmoothingQuality
-CONSOLE MESSAGE: line 153:     setter lineCap
-CONSOLE MESSAGE: line 153:     setter lineDashOffset
-CONSOLE MESSAGE: line 153:     setter lineJoin
-CONSOLE MESSAGE: line 153:     setter lineWidth
-CONSOLE MESSAGE: line 153:     setter miterLimit
-CONSOLE MESSAGE: line 153:     setter shadowBlur
-CONSOLE MESSAGE: line 153:     setter shadowColor
-CONSOLE MESSAGE: line 153:     setter shadowOffsetX
-CONSOLE MESSAGE: line 153:     setter shadowOffsetY
-CONSOLE MESSAGE: line 153:     setter strokeStyle
-CONSOLE MESSAGE: line 153: interface PaintSize
-CONSOLE MESSAGE: line 153:     getter height
-CONSOLE MESSAGE: line 153:     getter width
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface PaintWorkletGlobalScope : WorkletGlobalScope
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface Path2D
-CONSOLE MESSAGE: line 153:     method addPath
-CONSOLE MESSAGE: line 153:     method arc
-CONSOLE MESSAGE: line 153:     method arcTo
-CONSOLE MESSAGE: line 153:     method bezierCurveTo
-CONSOLE MESSAGE: line 153:     method closePath
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method ellipse
-CONSOLE MESSAGE: line 153:     method lineTo
-CONSOLE MESSAGE: line 153:     method moveTo
-CONSOLE MESSAGE: line 153:     method quadraticCurveTo
-CONSOLE MESSAGE: line 153:     method rect
-CONSOLE MESSAGE: line 153: interface ReadableStream
-CONSOLE MESSAGE: line 153:     getter locked
-CONSOLE MESSAGE: line 153:     method cancel
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method getReader
-CONSOLE MESSAGE: line 153:     method pipeThrough
-CONSOLE MESSAGE: line 153:     method pipeTo
-CONSOLE MESSAGE: line 153:     method tee
-CONSOLE MESSAGE: line 153: interface ReadableStreamDefaultReader
-CONSOLE MESSAGE: line 153:     getter closed
-CONSOLE MESSAGE: line 153:     method cancel
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method read
-CONSOLE MESSAGE: line 153:     method releaseLock
-CONSOLE MESSAGE: line 153: interface StylePropertyMapReadOnly
-CONSOLE MESSAGE: line 153:     getter size
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method entries
-CONSOLE MESSAGE: line 153:     method forEach
-CONSOLE MESSAGE: line 153:     method get
-CONSOLE MESSAGE: line 153:     method getAll
-CONSOLE MESSAGE: line 153:     method has
-CONSOLE MESSAGE: line 153:     method keys
-CONSOLE MESSAGE: line 153:     method values
-CONSOLE MESSAGE: line 153: interface TransformStream
-CONSOLE MESSAGE: line 153:     getter readable
-CONSOLE MESSAGE: line 153:     getter writable
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface WorkletGlobalScope
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface WritableStream
-CONSOLE MESSAGE: line 153:     getter locked
-CONSOLE MESSAGE: line 153:     method abort
-CONSOLE MESSAGE: line 153:     method close
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method getWriter
-CONSOLE MESSAGE: line 153: interface WritableStreamDefaultWriter
-CONSOLE MESSAGE: line 153:     getter closed
-CONSOLE MESSAGE: line 153:     getter desiredSize
-CONSOLE MESSAGE: line 153:     getter ready
-CONSOLE MESSAGE: line 153:     method abort
-CONSOLE MESSAGE: line 153:     method close
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method releaseLock
-CONSOLE MESSAGE: line 153:     method write
-CONSOLE MESSAGE: line 153: global object
-CONSOLE MESSAGE: line 153:     attribute console
-CONSOLE MESSAGE: line 153:     attribute globalThis
-CONSOLE MESSAGE: line 153:     getter devicePixelRatio
-CONSOLE MESSAGE: line 153:     method gc
-CONSOLE MESSAGE: line 153:     method registerPaint
-CONSOLE MESSAGE: line 153: interface ByteLengthQueuingStrategy
-CONSOLE MESSAGE: line 153:     getter highWaterMark
-CONSOLE MESSAGE: line 153:     getter size
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSImageValue : CSSStyleValue
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSKeywordValue : CSSStyleValue
-CONSOLE MESSAGE: line 153:     getter value
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter value
-CONSOLE MESSAGE: line 153: interface CSSMathInvert : CSSMathValue
-CONSOLE MESSAGE: line 153:     getter value
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMathMax : CSSMathValue
-CONSOLE MESSAGE: line 153:     getter values
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMathMin : CSSMathValue
-CONSOLE MESSAGE: line 153:     getter values
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMathNegate : CSSMathValue
-CONSOLE MESSAGE: line 153:     getter value
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMathProduct : CSSMathValue
-CONSOLE MESSAGE: line 153:     getter values
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMathSum : CSSMathValue
-CONSOLE MESSAGE: line 153:     getter values
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMathValue : CSSNumericValue
-CONSOLE MESSAGE: line 153:     getter operator
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface CSSMatrixComponent : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter matrix
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter matrix
-CONSOLE MESSAGE: line 153: interface CSSNumericArray
-CONSOLE MESSAGE: line 153:     getter length
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method entries
-CONSOLE MESSAGE: line 153:     method forEach
-CONSOLE MESSAGE: line 153:     method keys
-CONSOLE MESSAGE: line 153:     method values
-CONSOLE MESSAGE: line 153: interface CSSNumericValue : CSSStyleValue
-CONSOLE MESSAGE: line 153:     method add
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method div
-CONSOLE MESSAGE: line 153:     method equals
-CONSOLE MESSAGE: line 153:     method max
-CONSOLE MESSAGE: line 153:     method min
-CONSOLE MESSAGE: line 153:     method mul
-CONSOLE MESSAGE: line 153:     method sub
-CONSOLE MESSAGE: line 153:     method to
-CONSOLE MESSAGE: line 153:     method toSum
-CONSOLE MESSAGE: line 153:     method type
-CONSOLE MESSAGE: line 153: interface CSSPerspective : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter length
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter length
-CONSOLE MESSAGE: line 153: interface CSSPositionValue : CSSStyleValue
-CONSOLE MESSAGE: line 153:     getter x
-CONSOLE MESSAGE: line 153:     getter y
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter x
-CONSOLE MESSAGE: line 153:     setter y
-CONSOLE MESSAGE: line 153: interface CSSRotate : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter angle
-CONSOLE MESSAGE: line 153:     getter x
-CONSOLE MESSAGE: line 153:     getter y
-CONSOLE MESSAGE: line 153:     getter z
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter angle
-CONSOLE MESSAGE: line 153:     setter x
-CONSOLE MESSAGE: line 153:     setter y
-CONSOLE MESSAGE: line 153:     setter z
-CONSOLE MESSAGE: line 153: interface CSSScale : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter x
-CONSOLE MESSAGE: line 153:     getter y
-CONSOLE MESSAGE: line 153:     getter z
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter x
-CONSOLE MESSAGE: line 153:     setter y
-CONSOLE MESSAGE: line 153:     setter z
-CONSOLE MESSAGE: line 153: interface CSSSkew : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter ax
-CONSOLE MESSAGE: line 153:     getter ay
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter ax
-CONSOLE MESSAGE: line 153:     setter ay
-CONSOLE MESSAGE: line 153: interface CSSSkewX : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter ax
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter ax
-CONSOLE MESSAGE: line 153: interface CSSSkewY : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter ay
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter ay
-CONSOLE MESSAGE: line 153: interface CSSStyleValue
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method toString
-CONSOLE MESSAGE: line 153: interface CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter is2D
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method toMatrix
-CONSOLE MESSAGE: line 153:     method toString
-CONSOLE MESSAGE: line 153:     setter is2D
-CONSOLE MESSAGE: line 153: interface CSSTransformValue : CSSStyleValue
-CONSOLE MESSAGE: line 153:     getter is2D
-CONSOLE MESSAGE: line 153:     getter length
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method entries
-CONSOLE MESSAGE: line 153:     method forEach
-CONSOLE MESSAGE: line 153:     method keys
-CONSOLE MESSAGE: line 153:     method toMatrix
-CONSOLE MESSAGE: line 153:     method values
-CONSOLE MESSAGE: line 153: interface CSSTranslate : CSSTransformComponent
-CONSOLE MESSAGE: line 153:     getter x
-CONSOLE MESSAGE: line 153:     getter y
-CONSOLE MESSAGE: line 153:     getter z
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter x
-CONSOLE MESSAGE: line 153:     setter y
-CONSOLE MESSAGE: line 153:     setter z
-CONSOLE MESSAGE: line 153: interface CSSUnitValue : CSSNumericValue
-CONSOLE MESSAGE: line 153:     getter unit
-CONSOLE MESSAGE: line 153:     getter value
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter value
-CONSOLE MESSAGE: line 153: interface CSSUnparsedValue : CSSStyleValue
-CONSOLE MESSAGE: line 153:     getter length
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method entries
-CONSOLE MESSAGE: line 153:     method forEach
-CONSOLE MESSAGE: line 153:     method keys
-CONSOLE MESSAGE: line 153:     method values
-CONSOLE MESSAGE: line 153: interface CSSVariableReferenceValue
-CONSOLE MESSAGE: line 153:     getter fallback
-CONSOLE MESSAGE: line 153:     getter variable
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     setter variable
-CONSOLE MESSAGE: line 153: interface CountQueuingStrategy
-CONSOLE MESSAGE: line 153:     getter highWaterMark
-CONSOLE MESSAGE: line 153:     getter size
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface PaintRenderingContext2D
-CONSOLE MESSAGE: line 153:     getter fillStyle
-CONSOLE MESSAGE: line 153:     getter filter
-CONSOLE MESSAGE: line 153:     getter globalAlpha
-CONSOLE MESSAGE: line 153:     getter globalCompositeOperation
-CONSOLE MESSAGE: line 153:     getter imageSmoothingEnabled
-CONSOLE MESSAGE: line 153:     getter imageSmoothingQuality
-CONSOLE MESSAGE: line 153:     getter lineCap
-CONSOLE MESSAGE: line 153:     getter lineDashOffset
-CONSOLE MESSAGE: line 153:     getter lineJoin
-CONSOLE MESSAGE: line 153:     getter lineWidth
-CONSOLE MESSAGE: line 153:     getter miterLimit
-CONSOLE MESSAGE: line 153:     getter shadowBlur
-CONSOLE MESSAGE: line 153:     getter shadowColor
-CONSOLE MESSAGE: line 153:     getter shadowOffsetX
-CONSOLE MESSAGE: line 153:     getter shadowOffsetY
-CONSOLE MESSAGE: line 153:     getter strokeStyle
-CONSOLE MESSAGE: line 153:     method arc
-CONSOLE MESSAGE: line 153:     method arcTo
-CONSOLE MESSAGE: line 153:     method beginPath
-CONSOLE MESSAGE: line 153:     method bezierCurveTo
-CONSOLE MESSAGE: line 153:     method clearRect
-CONSOLE MESSAGE: line 153:     method clip
-CONSOLE MESSAGE: line 153:     method closePath
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method createLinearGradient
-CONSOLE MESSAGE: line 153:     method createPattern
-CONSOLE MESSAGE: line 153:     method createRadialGradient
-CONSOLE MESSAGE: line 153:     method drawImage
-CONSOLE MESSAGE: line 153:     method ellipse
-CONSOLE MESSAGE: line 153:     method fill
-CONSOLE MESSAGE: line 153:     method fillRect
-CONSOLE MESSAGE: line 153:     method getLineDash
-CONSOLE MESSAGE: line 153:     method getTransform
-CONSOLE MESSAGE: line 153:     method isPointInPath
-CONSOLE MESSAGE: line 153:     method isPointInStroke
-CONSOLE MESSAGE: line 153:     method lineTo
-CONSOLE MESSAGE: line 153:     method moveTo
-CONSOLE MESSAGE: line 153:     method quadraticCurveTo
-CONSOLE MESSAGE: line 153:     method rect
-CONSOLE MESSAGE: line 153:     method resetTransform
-CONSOLE MESSAGE: line 153:     method restore
-CONSOLE MESSAGE: line 153:     method rotate
-CONSOLE MESSAGE: line 153:     method save
-CONSOLE MESSAGE: line 153:     method scale
-CONSOLE MESSAGE: line 153:     method setLineDash
-CONSOLE MESSAGE: line 153:     method setTransform
-CONSOLE MESSAGE: line 153:     method stroke
-CONSOLE MESSAGE: line 153:     method strokeRect
-CONSOLE MESSAGE: line 153:     method transform
-CONSOLE MESSAGE: line 153:     method translate
-CONSOLE MESSAGE: line 153:     setter fillStyle
-CONSOLE MESSAGE: line 153:     setter filter
-CONSOLE MESSAGE: line 153:     setter globalAlpha
-CONSOLE MESSAGE: line 153:     setter globalCompositeOperation
-CONSOLE MESSAGE: line 153:     setter imageSmoothingEnabled
-CONSOLE MESSAGE: line 153:     setter imageSmoothingQuality
-CONSOLE MESSAGE: line 153:     setter lineCap
-CONSOLE MESSAGE: line 153:     setter lineDashOffset
-CONSOLE MESSAGE: line 153:     setter lineJoin
-CONSOLE MESSAGE: line 153:     setter lineWidth
-CONSOLE MESSAGE: line 153:     setter miterLimit
-CONSOLE MESSAGE: line 153:     setter shadowBlur
-CONSOLE MESSAGE: line 153:     setter shadowColor
-CONSOLE MESSAGE: line 153:     setter shadowOffsetX
-CONSOLE MESSAGE: line 153:     setter shadowOffsetY
-CONSOLE MESSAGE: line 153:     setter strokeStyle
-CONSOLE MESSAGE: line 153: interface PaintSize
-CONSOLE MESSAGE: line 153:     getter height
-CONSOLE MESSAGE: line 153:     getter width
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface PaintWorkletGlobalScope : WorkletGlobalScope
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface Path2D
-CONSOLE MESSAGE: line 153:     method addPath
-CONSOLE MESSAGE: line 153:     method arc
-CONSOLE MESSAGE: line 153:     method arcTo
-CONSOLE MESSAGE: line 153:     method bezierCurveTo
-CONSOLE MESSAGE: line 153:     method closePath
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method ellipse
-CONSOLE MESSAGE: line 153:     method lineTo
-CONSOLE MESSAGE: line 153:     method moveTo
-CONSOLE MESSAGE: line 153:     method quadraticCurveTo
-CONSOLE MESSAGE: line 153:     method rect
-CONSOLE MESSAGE: line 153: interface ReadableStream
-CONSOLE MESSAGE: line 153:     getter locked
-CONSOLE MESSAGE: line 153:     method cancel
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method getReader
-CONSOLE MESSAGE: line 153:     method pipeThrough
-CONSOLE MESSAGE: line 153:     method pipeTo
-CONSOLE MESSAGE: line 153:     method tee
-CONSOLE MESSAGE: line 153: interface ReadableStreamDefaultReader
-CONSOLE MESSAGE: line 153:     getter closed
-CONSOLE MESSAGE: line 153:     method cancel
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method read
-CONSOLE MESSAGE: line 153:     method releaseLock
-CONSOLE MESSAGE: line 153: interface StylePropertyMapReadOnly
-CONSOLE MESSAGE: line 153:     getter size
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method entries
-CONSOLE MESSAGE: line 153:     method forEach
-CONSOLE MESSAGE: line 153:     method get
-CONSOLE MESSAGE: line 153:     method getAll
-CONSOLE MESSAGE: line 153:     method has
-CONSOLE MESSAGE: line 153:     method keys
-CONSOLE MESSAGE: line 153:     method values
-CONSOLE MESSAGE: line 153: interface TransformStream
-CONSOLE MESSAGE: line 153:     getter readable
-CONSOLE MESSAGE: line 153:     getter writable
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface WorkletGlobalScope
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153: interface WritableStream
-CONSOLE MESSAGE: line 153:     getter locked
-CONSOLE MESSAGE: line 153:     method abort
-CONSOLE MESSAGE: line 153:     method close
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method getWriter
-CONSOLE MESSAGE: line 153: interface WritableStreamDefaultWriter
-CONSOLE MESSAGE: line 153:     getter closed
-CONSOLE MESSAGE: line 153:     getter desiredSize
-CONSOLE MESSAGE: line 153:     getter ready
-CONSOLE MESSAGE: line 153:     method abort
-CONSOLE MESSAGE: line 153:     method close
-CONSOLE MESSAGE: line 153:     method constructor
-CONSOLE MESSAGE: line 153:     method releaseLock
-CONSOLE MESSAGE: line 153:     method write
-CONSOLE MESSAGE: line 153: global object
-CONSOLE MESSAGE: line 153:     attribute console
-CONSOLE MESSAGE: line 153:     attribute globalThis
-CONSOLE MESSAGE: line 153:     getter devicePixelRatio
-CONSOLE MESSAGE: line 153:     method gc
-CONSOLE MESSAGE: line 153:     method registerPaint
-
diff --git a/third_party/blink/web_tests/wpt_internal/webgpu/cts.https.html b/third_party/blink/web_tests/wpt_internal/webgpu/cts.https.html
index 33ea690..5b94a7e 100644
--- a/third_party/blink/web_tests/wpt_internal/webgpu/cts.https.html
+++ b/third_party/blink/web_tests/wpt_internal/webgpu/cts.https.html
@@ -2706,7 +2706,6 @@
 <meta name=variant content='?q=webgpu:shader,execution,builtin,float_built_functions:float_builtin_functions,exp2:*'>
 <meta name=variant content='?q=webgpu:shader,execution,builtin,float_built_functions:float_builtin_functions,faceForward:*'>
 <meta name=variant content='?q=webgpu:shader,execution,builtin,float_built_functions:float_builtin_functions,fma:*'>
-<meta name=variant content='?q=webgpu:shader,execution,builtin,float_built_functions:float_builtin_functions,fract:*'>
 <meta name=variant content='?q=webgpu:shader,execution,builtin,float_built_functions:float_builtin_functions,scalar_case_frexp:*'>
 <meta name=variant content='?q=webgpu:shader,execution,builtin,float_built_functions:float_builtin_functions,vector_case_frexp:*'>
 <meta name=variant content='?q=webgpu:shader,execution,builtin,float_built_functions:float_builtin_functions,inverseSqrt:*'>
@@ -2736,6 +2735,7 @@
 <meta name=variant content='?q=webgpu:shader,execution,builtin,float_built_functions:float_builtin_functions,tanh:*'>
 <meta name=variant content='?q=webgpu:shader,execution,builtin,float_built_functions:float_builtin_functions,trunc:*'>
 <meta name=variant content='?q=webgpu:shader,execution,builtin,floor:float_builtin_functions,floor:*'>
+<meta name=variant content='?q=webgpu:shader,execution,builtin,fract:float_builtin_functions,fract:*'>
 <meta name=variant content='?q=webgpu:shader,execution,builtin,integer_built_in_functions:integer_builtin_functions,unsigned_clamp:*'>
 <meta name=variant content='?q=webgpu:shader,execution,builtin,integer_built_in_functions:integer_builtin_functions,signed_clamp:*'>
 <meta name=variant content='?q=webgpu:shader,execution,builtin,integer_built_in_functions:integer_builtin_functions,count_1_bits:*'>
diff --git a/third_party/closure_compiler/externs/accessibility_private.js b/third_party/closure_compiler/externs/accessibility_private.js
index b295563..7f8134bf 100644
--- a/third_party/closure_compiler/externs/accessibility_private.js
+++ b/third_party/closure_compiler/externs/accessibility_private.js
@@ -1,4 +1,4 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
+// Copyright 2022 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -327,6 +327,25 @@
 };
 
 /**
+ * @enum {string}
+ */
+chrome.accessibilityPrivate.DictationBubbleIconType = {
+  HIDDEN: 'hidden',
+  STANDBY: 'standby',
+  MACRO_SUCCESS: 'macroSuccess',
+  MACRO_FAIL: 'macroFail',
+};
+
+/**
+ * @typedef {{
+ *   visible: boolean,
+ *   icon: !chrome.accessibilityPrivate.DictationBubbleIconType,
+ *   text: (string|undefined)
+ * }}
+ */
+chrome.accessibilityPrivate.DictationBubbleProperties;
+
+/**
  * Property to indicate whether event source should default to touch.
  * @type {number}
  */
@@ -420,11 +439,10 @@
 /**
  * Sets current ARC app to use native ARC support.
  * @param {boolean} enabled True for ChromeVox (native), false for TalkBack.
- * @param {function(!chrome.accessibilityPrivate.SetNativeChromeVoxResponse):
- *     void} callback
+ * @param {function(!chrome.accessibilityPrivate.SetNativeChromeVoxResponse): void}
+ *     callback
  */
-chrome.accessibilityPrivate.setNativeChromeVoxArcSupportForCurrentApp =
-    function(enabled, callback) {};
+chrome.accessibilityPrivate.setNativeChromeVoxArcSupportForCurrentApp = function(enabled, callback) {};
 
 /**
  * Sends a fabricated key event.
@@ -548,11 +566,10 @@
 
 /**
  * Updates Dictation's bubble UI.
- * @param {boolean} visible Whether or not the UI should be visible.
- * @param {string=} text The text to be displayed in the bubble UI. If `text` is
- *     undefined, the bubble will clear its current text.
+ * @param {!chrome.accessibilityPrivate.DictationBubbleProperties} properties
+ *     Properties for the updated Dictation bubble UI.
  */
-chrome.accessibilityPrivate.updateDictationBubble = function(visible, text) {};
+chrome.accessibilityPrivate.updateDictationBubble = function(properties) {};
 
 /**
  * Fired whenever ChromeVox should output introduction.
diff --git a/third_party/crashpad/README.chromium b/third_party/crashpad/README.chromium
index 055579a..b775101 100644
--- a/third_party/crashpad/README.chromium
+++ b/third_party/crashpad/README.chromium
@@ -2,7 +2,7 @@
 Short Name: crashpad
 URL: https://crashpad.chromium.org/
 Version: unknown
-Revision: 243e1fd8e2f856209a24ca91090c837be87a1993
+Revision: b714b223ad7fdd75bd9278c9a7d005df3954d119
 License: Apache 2.0
 License File: crashpad/LICENSE
 Security Critical: yes
diff --git a/third_party/crashpad/crashpad/snapshot/ios/memory_snapshot_ios_intermediate_dump.cc b/third_party/crashpad/crashpad/snapshot/ios/memory_snapshot_ios_intermediate_dump.cc
index 8e521d90..84275aa 100644
--- a/third_party/crashpad/crashpad/snapshot/ios/memory_snapshot_ios_intermediate_dump.cc
+++ b/third_party/crashpad/crashpad/snapshot/ios/memory_snapshot_ios_intermediate_dump.cc
@@ -50,12 +50,37 @@
 
 const MemorySnapshot* MemorySnapshotIOSIntermediateDump::MergeWithOtherSnapshot(
     const MemorySnapshot* other) const {
+  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
+  auto other_snapshot =
+      reinterpret_cast<const MemorySnapshotIOSIntermediateDump*>(other);
+
+  INITIALIZATION_STATE_DCHECK_VALID(other_snapshot->initialized_);
+  if (other_snapshot->address_ < address_) {
+    return other_snapshot->MergeWithOtherSnapshot(this);
+  }
+
   CheckedRange<uint64_t, size_t> merged(0, 0);
   if (!LoggingDetermineMergedRange(this, other, &merged))
     return nullptr;
 
   auto result = std::make_unique<MemorySnapshotIOSIntermediateDump>();
   result->Initialize(merged.base(), data_, merged.size());
+  if (size_ == merged.size()) {
+    return result.release();
+  }
+
+  const uint8_t* data = reinterpret_cast<const uint8_t*>(data_);
+  const uint8_t* other_data =
+      reinterpret_cast<const uint8_t*>(other_snapshot->data_);
+  vm_size_t overlap = merged.size() - other_snapshot->size_;
+  result->merged_data_.reserve(merged.size());
+  result->merged_data_.insert(result->merged_data_.end(), data, data + overlap);
+  result->merged_data_.insert(result->merged_data_.end(),
+                              other_data,
+                              other_data + other_snapshot->size_);
+  result->data_ =
+      reinterpret_cast<const vm_address_t>(result->merged_data_.data());
+  DCHECK_EQ(result->merged_data_.size(), merged.size());
   return result.release();
 }
 
diff --git a/third_party/crashpad/crashpad/snapshot/ios/memory_snapshot_ios_intermediate_dump.h b/third_party/crashpad/crashpad/snapshot/ios/memory_snapshot_ios_intermediate_dump.h
index a932000..244bbd8 100644
--- a/third_party/crashpad/crashpad/snapshot/ios/memory_snapshot_ios_intermediate_dump.h
+++ b/third_party/crashpad/crashpad/snapshot/ios/memory_snapshot_ios_intermediate_dump.h
@@ -15,6 +15,8 @@
 #ifndef CRASHPAD_SNAPSHOT_IOS_INTERMEDIATE_DUMP_MEMORY_SNAPSHOT_IOS_INTERMEDIATEDUMP_H_
 #define CRASHPAD_SNAPSHOT_IOS_INTERMEDIATE_DUMP_MEMORY_SNAPSHOT_IOS_INTERMEDIATEDUMP_H_
 
+#include <vector>
+
 #include "snapshot/memory_snapshot.h"
 #include "util/misc/address_types.h"
 #include "util/misc/initialization_state_dcheck.h"
@@ -55,6 +57,12 @@
 
   vm_address_t address_;
   vm_address_t data_;
+
+  // Because the iOS snapshot memory region is owned by the intermediate dump,
+  // it's necessary to copy the merged data into a vector owned by the memory
+  // snapshot itself.
+  std::vector<uint8_t> merged_data_;
+
   vm_size_t size_;
   InitializationStateDcheck initialized_;
 };
diff --git a/third_party/crashpad/crashpad/util/mach/mig_fix.py b/third_party/crashpad/crashpad/util/mach/mig_fix.py
index 037746f..6e28771 100755
--- a/third_party/crashpad/crashpad/util/mach/mig_fix.py
+++ b/third_party/crashpad/crashpad/util/mach/mig_fix.py
@@ -23,6 +23,33 @@
 from mig_gen import MigInterface
 
 
+def _make_generated_comments_deterministic(contents):
+    """Replaces generated code comments with determenistic ones.
+
+    This is what is generated by mig (only in .c files):
+    /*
+     * IDENTIFICATION:
+     * stub generated Mon Jan 17 15:28:03 2022
+     * with a MiG generated by bootstrap_cmds-122
+     * OPTIONS:
+     */
+
+    We look for two specific lines and replace them like so:
+    /*
+     * IDENTIFICATION:
+     * stub generated <suppressed by mig_fix.py>
+     * with a MiG generated by <suppressed by mig_fix.py>
+     * OPTIONS:
+     */
+    """
+
+    return re.sub(r'^( \* (?:stub generated|with a MiG generated by) ).+$',
+                  r'\1<suppressed by mig_fix.py>',
+                  contents,
+                  count=2,
+                  flags=re.MULTILINE)
+
+
 def _fix_user_implementation(implementation, fixed_implementation, header,
                              fixed_header):
     """Rewrites a MIG-generated user implementation (.c) file.
@@ -33,7 +60,8 @@
     unused in the user implementation file, and this will trigger a
     -Wunused-local-typedefs warning in gcc unless removed or marked with the
     “unused” attribute. Also changes header references to point to the new
-    header filename, if changed.
+    header filename, if changed. Replaces generated code comments with
+    deterministic ones.
 
     If |fixed_implementation| is None, overwrites the original; otherwise, puts
     the result in the file at |fixed_implementation|.
@@ -50,6 +78,9 @@
             '#include "%s"' % os.path.basename(header),
             '#include "%s"' % os.path.basename(fixed_header))
 
+    # Replace generated code comments with determenistic ones.
+    contents = _make_generated_comments_deterministic(contents)
+
     if fixed_implementation is None:
         file.seek(0)
         file.truncate()
@@ -71,6 +102,7 @@
     added to a header file, so that other files that include that header file
     will have access to these declarations from a compilation perspective. Also
     changes header references to point to the new header filename, if changed.
+    Replaces generated code comments with deterministic ones.
 
     If |fixed_implementation| is None or not provided, overwrites the original;
     otherwise, puts the result in the file at |fixed_implementation|.
@@ -117,6 +149,9 @@
             '#include "%s"' % os.path.basename(header),
             '#include "%s"' % os.path.basename(fixed_header))
 
+    # Replace generated code comments with determenistic ones.
+    contents = _make_generated_comments_deterministic(contents)
+
     if fixed_implementation is None:
         file.seek(0)
         file.truncate()
diff --git a/third_party/eigen3/README.chromium b/third_party/eigen3/README.chromium
index ff3a848..806990d0 100644
--- a/third_party/eigen3/README.chromium
+++ b/third_party/eigen3/README.chromium
@@ -1,8 +1,8 @@
 Name: Eigen
 Short Name: eigen3
 URL: http://eigen.tuxfamily.org/
-Version: 163f11e24a1011ac8ba1cecfaf53e9b11ace5f5c
-Date: 2021/10/22
+Version: e939c06b0e54fd7c4bfa173d01b47d2554bf7a85
+Date: 2022/01/18
 License: MPL 2
 License File: LICENSE
 Security Critical: Yes
diff --git a/third_party/freetype/README.chromium b/third_party/freetype/README.chromium
index bb8502e7..d0752775 100644
--- a/third_party/freetype/README.chromium
+++ b/third_party/freetype/README.chromium
@@ -1,7 +1,7 @@
 Name: FreeType
 URL: http://www.freetype.org/
-Version: VER-2-11-1-52-gd118bf8e3
-Revision: d118bf8e35e69454ed046b57ac54dd67d49b87d9
+Version: VER-2-11-1-53-g773e31c78
+Revision: 773e31c78397a5471efb7c37d7cd1eca40b46351
 CPEPrefix: cpe:/a:freetype:freetype:2.11.1
 License: Custom license "inspired by the BSD, Artistic, and IJG (Independent
          JPEG Group) licenses"
diff --git a/third_party/libjingle_xmpp/BUILD.gn b/third_party/libjingle_xmpp/BUILD.gn
index ba8c3ab..5dc29ec 100644
--- a/third_party/libjingle_xmpp/BUILD.gn
+++ b/third_party/libjingle_xmpp/BUILD.gn
@@ -65,7 +65,6 @@
 static_library("rtc_xmpp") {
   visibility = [
     ":*",
-    "//jingle:jingle_glue",
     "//remoting/*",
   ]
   cflags = []
diff --git a/third_party/tflite/README.chromium b/third_party/tflite/README.chromium
index 4b26763..3a5646b 100644
--- a/third_party/tflite/README.chromium
+++ b/third_party/tflite/README.chromium
@@ -1,8 +1,8 @@
 Name: TensorFlow Lite
 Short Name: tflite
 URL: https://github.com/tensorflow/tensorflow
-Version: ceedf1794a703715d88605b5ac493517e8fa2499
-Date: 2022/01/10
+Version: 7d380ffcce7a13884ca76d703ca0d983c870582c
+Date: 2022/01/18
 License: Apache 2.0
 License File: LICENSE
 Security Critical: Yes
diff --git a/third_party/webgpu-cts/ts_sources.txt b/third_party/webgpu-cts/ts_sources.txt
index f01df90..b80fb33 100644
--- a/third_party/webgpu-cts/ts_sources.txt
+++ b/third_party/webgpu-cts/ts_sources.txt
@@ -260,6 +260,7 @@
 src/webgpu/shader/execution/builtin/cos.spec.ts
 src/webgpu/shader/execution/builtin/float_built_functions.spec.ts
 src/webgpu/shader/execution/builtin/floor.spec.ts
+src/webgpu/shader/execution/builtin/fract.spec.ts
 src/webgpu/shader/execution/builtin/integer_built_in_functions.spec.ts
 src/webgpu/shader/execution/builtin/logical_built_in_functions.spec.ts
 src/webgpu/shader/execution/builtin/min.spec.ts
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 574a6e1e..19598b4 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -334,7 +334,6 @@
       'ios15-sdk-device': 'ios_device_release_static_bot_xctest',
       'ios15-sdk-simulator': 'ios_simulator_debug_static_bot_xctest',
       'ios-asan': 'ios_simulator_release_static_asan_bot_xctest',
-      'ios-catalyst': 'ios_catalyst_debug_static_bot_compile_only_libfuzzer_no_dsyms_no_lld_no_remoting',
       'ios-reclient': 'ios_simulator_debug_static_bot_xctest_reclient',
       'ios-simulator-code-coverage': 'clang_code_coverage_ios_xctest',
       'ios-simulator-cr-recipe': 'ios_simulator_debug_static_bot_xctest',
@@ -343,10 +342,10 @@
       'ios-webkit-tot': 'ios_simulator_debug_static_bot_xctest_no_lld',
       'lacros-amd64-generic-rel (goma cache silo)': 'chromeos_amd64-generic_lacros_rel',
       'lacros-amd64-generic-rel (reclient)': 'chromeos_amd64-generic_lacros_rel_reclient',
-      'linux-annotator-rel': 'release_bot',
+      'linux-annotator-rel': 'release_bot_reclient',
       'linux-blink-animation-use-time-delta': 'debug_bot_enable_blink_animation_use_time_delta',
       'linux-blink-heap-concurrent-marking-tsan-rel': 'release_trybot_minimal_symbols_tsan',
-      'linux-blink-heap-verification': 'release_bot_enable_blink_heap_verification_dcheck_always_on',
+      'linux-blink-heap-verification': 'release_bot_enable_blink_heap_verification_dcheck_always_on_reclient',
       'linux-blink-v8-oilpan': 'release_bot_enable_v8_oilpan_dcheck_always_on',
       'linux-chromeos-code-coverage': 'chromeos_with_codecs_release_bot_coverage',
       'linux-chromeos-js-code-coverage': 'chromeos_with_codecs_release_bot_javascript_coverage',
@@ -530,6 +529,7 @@
     'chromium.mac': {
       'Mac Builder': 'gpu_tests_release_bot_minimal_symbols_no_nacl',
       'Mac Builder (dbg)': 'gpu_tests_debug_bot',
+      'ios-catalyst': 'ios_catalyst_debug_static_bot_compile_only_libfuzzer_no_dsyms_no_lld_no_remoting',
       'ios-device': 'ios_device_release_compile_only',
       'ios-simulator': 'ios_simulator_debug_static_bot_xctest',
       'ios-simulator-full-configs': 'ios_simulator_debug_static_bot_xctest',
@@ -2848,6 +2848,10 @@
       'release_bot',
     ],
 
+    'release_bot_reclient': [
+      'release_bot_reclient',
+    ],
+
     'release_bot_blink': [
       'release_bot_blink',
     ],
@@ -2878,8 +2882,8 @@
       'release_bot_blink', 'v8_enable_debugging_features',
     ],
 
-    'release_bot_enable_blink_heap_verification_dcheck_always_on': [
-      'release_bot_blink', 'enable_blink_heap_verification', 'dcheck_always_on',
+    'release_bot_enable_blink_heap_verification_dcheck_always_on_reclient': [
+      'release_bot_blink_reclient', 'enable_blink_heap_verification', 'dcheck_always_on',
     ],
 
     'release_bot_enable_v8_oilpan_dcheck_always_on': [
diff --git a/tools/mb/mb_config_expectations/chromium.fyi.json b/tools/mb/mb_config_expectations/chromium.fyi.json
index d650372..74bb78b 100644
--- a/tools/mb/mb_config_expectations/chromium.fyi.json
+++ b/tools/mb/mb_config_expectations/chromium.fyi.json
@@ -574,23 +574,6 @@
       "use_goma": true
     }
   },
-  "ios-catalyst": {
-    "gn_args": {
-      "enable_dsyms": false,
-      "enable_remoting": false,
-      "ios_set_attributes_for_xcode_project_generation": false,
-      "is_component_build": false,
-      "is_debug": true,
-      "is_p2p_enabled": false,
-      "symbol_level": 1,
-      "target_cpu": "x64",
-      "target_environment": "catalyst",
-      "target_os": "ios",
-      "use_goma": true,
-      "use_libfuzzer": true,
-      "use_lld": false
-    }
-  },
   "ios-reclient": {
     "gn_args": {
       "enable_run_ios_unittests_with_xctest": true,
@@ -807,7 +790,8 @@
       "dcheck_always_on": false,
       "is_component_build": false,
       "is_debug": false,
-      "use_goma": true
+      "use_rbe": true,
+      "use_remoteexec": true
     }
   },
   "linux-ash-chromium-builder-fyi-rel": {
@@ -864,7 +848,8 @@
       "is_component_build": false,
       "is_debug": false,
       "proprietary_codecs": true,
-      "use_goma": true
+      "use_rbe": true,
+      "use_remoteexec": true
     }
   },
   "linux-blink-v8-oilpan": {
diff --git a/tools/mb/mb_config_expectations/chromium.mac.json b/tools/mb/mb_config_expectations/chromium.mac.json
index 462aa7b..fc9d47c 100644
--- a/tools/mb/mb_config_expectations/chromium.mac.json
+++ b/tools/mb/mb_config_expectations/chromium.mac.json
@@ -21,6 +21,23 @@
       "use_goma": true
     }
   },
+  "ios-catalyst": {
+    "gn_args": {
+      "enable_dsyms": false,
+      "enable_remoting": false,
+      "ios_set_attributes_for_xcode_project_generation": false,
+      "is_component_build": false,
+      "is_debug": true,
+      "is_p2p_enabled": false,
+      "symbol_level": 1,
+      "target_cpu": "x64",
+      "target_environment": "catalyst",
+      "target_os": "ios",
+      "use_goma": true,
+      "use_libfuzzer": true,
+      "use_lld": false
+    }
+  },
   "ios-device": {
     "gn_args": {
       "dcheck_always_on": false,
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index a47eb13..35f0e50e 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -4144,6 +4144,8 @@
   <int value="34" label="Start local hotspot (WifiManager)"/>
   <int value="35" label="Add Passpoint configuration (WifiManager)"/>
   <int value="36" label="IPsec IKE2 Android VPN connection (VpnManager)"/>
+  <int value="37" label="Android VPN IPv6 provisioning"/>
+  <int value="38" label="Android VPN IPv4 provisioning"/>
 </enum>
 
 <enum name="ArcNoWindowReason">
@@ -8567,6 +8569,57 @@
   <int value="7" label="allpass"/>
 </enum>
 
+<enum name="BitsPerPixelExponential">
+  <summary>
+    The ratio of image size in bits to displayed size in pixels. Ranges are
+    half-open: (low, high].
+  </summary>
+  <int value="0" label="0"/>
+  <int value="1" label="0 - 0.00001"/>
+  <int value="2" label="0.00001 - 0.0001"/>
+  <int value="3" label="0.0001 - 0.001"/>
+  <int value="4" label="0.001 - 0.01"/>
+  <int value="5" label="0.01 - 0.02"/>
+  <int value="6" label="0.02 - 0.03"/>
+  <int value="7" label="0.03 - 0.04"/>
+  <int value="8" label="0.04 - 0.05"/>
+  <int value="9" label="0.05 - 0.06"/>
+  <int value="10" label="0.06 - 0.07"/>
+  <int value="11" label="0.07 - 0.08"/>
+  <int value="12" label="0.08 - 0.09"/>
+  <int value="13" label="0.09 - 0.1"/>
+  <int value="14" label="0.1 - 0.2"/>
+  <int value="15" label="0.2 - 0.3"/>
+  <int value="16" label="0.3 - 0.4"/>
+  <int value="17" label="0.4 - 0.5"/>
+  <int value="18" label="0.5 - 0.6"/>
+  <int value="19" label="0.6 - 0.7"/>
+  <int value="20" label="0.7 - 0.8"/>
+  <int value="21" label="0.8 - 0.9"/>
+  <int value="22" label="0.9 - 1.0"/>
+  <int value="23" label="1.0 - 2.0"/>
+  <int value="24" label="2.0 - 3.0"/>
+  <int value="25" label="3.0 - 4.0"/>
+  <int value="26" label="4.0 - 5.0"/>
+  <int value="27" label="5.0 - 6.0"/>
+  <int value="28" label="6.0 - 7.0"/>
+  <int value="29" label="7.0 - 8.0"/>
+  <int value="30" label="8.0 - 9.0"/>
+  <int value="31" label="9.0 - 10.0"/>
+  <int value="32" label="10.0 - 20.0"/>
+  <int value="33" label="20.0 - 30.0"/>
+  <int value="34" label="30.0 - 40.0"/>
+  <int value="35" label="40.0 - 50.0"/>
+  <int value="36" label="50.0 - 60.0"/>
+  <int value="37" label="60.0 - 70.0"/>
+  <int value="38" label="70.0 - 80.0"/>
+  <int value="39" label="80.0 - 90.0"/>
+  <int value="40" label="90.0 - 100.0"/>
+  <int value="41" label="100.0 - 1000.0"/>
+  <int value="42" label="1000.0 - 10000.0"/>
+  <int value="43" label="10000.0 - inf"/>
+</enum>
+
 <enum name="BlacklistedVideoCaptureDeviceNames">
   <int value="0" label="Google GTalk Camera Adapter"/>
   <int value="1" label="IP Camera"/>
@@ -28252,6 +28305,7 @@
   <int value="938" label="DeviceKeylockerForStorageEncryptionEnabled"/>
   <int value="939" label="ReportCRDSessions"/>
   <int value="940" label="DeviceRunAutomaticCleanupOnLogin"/>
+  <int value="941" label="NTPMiddleSlotAnnouncementVisible"/>
 </enum>
 
 <enum name="EnterprisePolicyDeviceIdValidity">
@@ -54696,6 +54750,7 @@
   <int value="798696013" label="ImeInputLogicMozc:enabled"/>
   <int value="799680074" label="ContextualSearchTranslationModel:enabled"/>
   <int value="802463708" label="WebViewSurfaceControl:enabled"/>
+  <int value="802930463" label="ThrottleForegroundTimers:disabled"/>
   <int value="803282885" label="PreferHtmlOverPlugins:disabled"/>
   <int value="803877391" label="NotificationsRefresh:enabled"/>
   <int value="803982925" label="CellularForbidAttachApn:disabled"/>
@@ -54739,6 +54794,7 @@
   <int value="840057845" label="HardwareMediaKeyHandling:enabled"/>
   <int value="840222947"
       label="AutofillEnableOfferNotificationForPromoCodes:enabled"/>
+  <int value="841098208" label="ThrottleForegroundTimers:enabled"/>
   <int value="841276069" label="ChromeHomeDoodle:disabled"/>
   <int value="841343322" label="disable-new-korean-ime"/>
   <int value="841779535" label="password-export:enabled"/>
diff --git a/tools/metrics/histograms/metadata/ash/histograms.xml b/tools/metrics/histograms/metadata/ash/histograms.xml
index d2070cc..dd89922 100644
--- a/tools/metrics/histograms/metadata/ash/histograms.xml
+++ b/tools/metrics/histograms/metadata/ash/histograms.xml
@@ -2712,6 +2712,18 @@
   <token key="TabletOrClamshell" variants="DisplayModes"/>
 </histogram>
 
+<histogram name="Ash.Projector.TranscriptsCount.{TabletOrClamshell}"
+    units="Number of transcripts" expires_after="2022-12-01">
+  <owner>tobyhuang@chromium.org</owner>
+  <owner>cros-projector@google.com</owner>
+  <summary>
+    Tracks the number of transcripts generated during a recording in
+    {TabletOrClamshell}, recorded each time the metadata file saved successfully
+    after a recording ends.
+  </summary>
+  <token key="TabletOrClamshell" variants="DisplayModes"/>
+</histogram>
+
 <histogram name="Ash.Rotation.AnimationSmoothness" units="%"
     expires_after="2022-04-10">
   <owner>oshima@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/assistant/histograms.xml b/tools/metrics/histograms/metadata/assistant/histograms.xml
index f0b43d2..a06aeb9 100644
--- a/tools/metrics/histograms/metadata/assistant/histograms.xml
+++ b/tools/metrics/histograms/metadata/assistant/histograms.xml
@@ -29,13 +29,6 @@
   <variant name=".UnitConversion" summary="UnitConversion result type"/>
 </variants>
 
-<variants name="QuickAnswersConsentInteractionType">
-  <variant name=".Accept" summary="Clicks on the accept button"/>
-  <variant name=".Dismiss" summary="Dismisses the consent"/>
-  <variant name=".ManageSettings"
-      summary="Clicks on the 'manage settings' button"/>
-</variants>
-
 <variants name="QuickAnswersV2ConsentResultType">
   <variant name=".Allow" summary="Clicks on the allow button"/>
   <variant name=".Dismiss" summary="Dismisses or ignores the consent"/>
@@ -308,7 +301,7 @@
 
 <histogram
     name="QuickAnswers.ActiveImpression.Duration{QuickAnswersClickResultType}"
-    units="ms" expires_after="2022-01-16">
+    units="ms" expires_after="2023-01-16">
   <owner>updowndota@chromium.org</owner>
   <owner>llin@google.com</owner>
   <owner>croissant-eng@chromium.org</owner>
@@ -347,67 +340,6 @@
   </token>
 </histogram>
 
-<histogram name="QuickAnswers.Consent" units="impressions" expires_after="M98">
-  <obsolete>
-    Removed 10-2021
-  </obsolete>
-  <owner>updowndota@chromium.org</owner>
-  <owner>llin@google.com</owner>
-  <owner>croissant-eng@chromium.org</owner>
-  <summary>
-    For every quick answers consent impression, records how many times the user
-    has seen the consent. ChromeOS only.
-  </summary>
-</histogram>
-
-<histogram
-    name="QuickAnswers.Consent.Duration{QuickAnswersConsentInteractionType}"
-    units="ms" expires_after="M98">
-  <obsolete>
-    Removed 10-2021
-  </obsolete>
-  <owner>updowndota@chromium.org</owner>
-  <owner>llin@google.com</owner>
-  <owner>croissant-eng@chromium.org</owner>
-  <summary>
-    For every quick answers consent interaction event, records how long the user
-    has seen the consent before. ChromeOS only.
-    {QuickAnswersConsentInteractionType}
-  </summary>
-  <token key="QuickAnswersConsentInteractionType"
-      variants="QuickAnswersConsentInteractionType">
-    <variant name="">
-      <obsolete>
-        Base histogram. Use suffixes of this histogram instead.
-      </obsolete>
-    </variant>
-  </token>
-</histogram>
-
-<histogram
-    name="QuickAnswers.Consent.Impression{QuickAnswersConsentInteractionType}"
-    units="impressions" expires_after="M98">
-  <obsolete>
-    Removed 10-2021
-  </obsolete>
-  <owner>updowndota@chromium.org</owner>
-  <owner>llin@google.com</owner>
-  <owner>croissant-eng@chromium.org</owner>
-  <summary>
-    For every quick answers consent interaction event, records how many times
-    the user has seen the consent before. ChromeOS only.
-    {QuickAnswersConsentInteractionType}
-  </summary>
-  <token key="QuickAnswersConsentInteractionType"
-      variants="QuickAnswersConsentInteractionType">
-    <variant name="">
-      <obsolete>
-        Base histogram. Use suffixes of this histogram instead.
-      </obsolete>
-    </variant>
-  </token>
-</histogram>
-
 <histogram name="QuickAnswers.ContextMenu.Close" enum="BooleanClicked"
     expires_after="2022-04-10">
   <owner>updowndota@chromium.org</owner>
@@ -458,7 +390,7 @@
 </histogram>
 
 <histogram name="QuickAnswers.Loading.Duration" units="ms"
-    expires_after="2022-01-23">
+    expires_after="2023-01-23">
   <owner>updowndota@chromium.org</owner>
   <owner>llin@google.com</owner>
   <owner>croissant-eng@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/blink/histograms.xml b/tools/metrics/histograms/metadata/blink/histograms.xml
index 23f28372..174ed7a 100644
--- a/tools/metrics/histograms/metadata/blink/histograms.xml
+++ b/tools/metrics/histograms/metadata/blink/histograms.xml
@@ -562,7 +562,7 @@
 </histogram>
 
 <histogram name="Blink.Compression.CompressionStream.Format"
-    enum="CompressionStreamsFormat" expires_after="2022-01-12">
+    enum="CompressionStreamsFormat" expires_after="2022-07-18">
   <owner>ricea@chromium.org</owner>
   <owner>yhirano@chromium.org</owner>
   <summary>
@@ -574,7 +574,7 @@
 </histogram>
 
 <histogram name="Blink.Compression.DecompressionStream.Format"
-    enum="CompressionStreamsFormat" expires_after="2022-01-12">
+    enum="CompressionStreamsFormat" expires_after="2022-07-18">
   <owner>ricea@chromium.org</owner>
   <owner>yhirano@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/bluetooth/histograms.xml b/tools/metrics/histograms/metadata/bluetooth/histograms.xml
index e11713d..72b34dc6 100644
--- a/tools/metrics/histograms/metadata/bluetooth/histograms.xml
+++ b/tools/metrics/histograms/metadata/bluetooth/histograms.xml
@@ -355,6 +355,30 @@
   </summary>
 </histogram>
 
+<histogram
+    name="Bluetooth.ChromeOS.FastPair.DeviceMetadataFetcher.Get.HttpResponseError"
+    enum="HttpResponseCode" expires_after="2022-09-20">
+  <owner>shanefitz@google.com</owner>
+  <owner>julietlevesque@google.com</owner>
+  <owner>chromeos-cross-device-eng@google.com</owner>
+  <summary>
+    Records the HTTP response error code from a failed HTTP GET request. Emitted
+    when the HTTP call fails. No metric is emitted on success.
+  </summary>
+</histogram>
+
+<histogram
+    name="Bluetooth.ChromeOS.FastPair.DeviceMetadataFetcher.Get.NetError"
+    enum="NetErrorCodes" expires_after="2022-09-20">
+  <owner>shanefitz@google.com</owner>
+  <owner>julietlevesque@google.com</owner>
+  <owner>chromeos-cross-device-eng@google.com</owner>
+  <summary>
+    Records the network error code from a failed HTTP GET request. Emitted when
+    the HTTP call fails. No metric is emitted on success.
+  </summary>
+</histogram>
+
 <histogram name="Bluetooth.ChromeOS.FastPair.DeviceMetadataFetcher.Result"
     enum="BooleanSuccess" expires_after="2022-09-20">
   <owner>shanefitz@google.com</owner>
@@ -484,6 +508,42 @@
   </summary>
 </histogram>
 
+<histogram
+    name="Bluetooth.ChromeOS.FastPair.FootprintsFetcher.{Method}.HttpResponseError"
+    enum="HttpResponseCode" expires_after="2022-09-20">
+  <owner>shanefitz@google.com</owner>
+  <owner>julietlevesque@google.com</owner>
+  <owner>chromeos-cross-device-eng@google.com</owner>
+  <summary>
+    Records the HTTP response error from a failed HTTP call to the Footprints
+    server. Emitted when the HTTP {Method} request fails. No metric is emitted
+    on success.
+  </summary>
+  <token key="Method">
+    <variant name="Delete" summary="DELETE"/>
+    <variant name="Get" summary="GET"/>
+    <variant name="Post" summary="POST"/>
+  </token>
+</histogram>
+
+<histogram
+    name="Bluetooth.ChromeOS.FastPair.FootprintsFetcher.{Method}.NetError"
+    enum="NetErrorCodes" expires_after="2022-09-20">
+  <owner>shanefitz@google.com</owner>
+  <owner>julietlevesque@google.com</owner>
+  <owner>chromeos-cross-device-eng@google.com</owner>
+  <summary>
+    Records the network error code from a failed HTTP call to the Footprints
+    server. Emitted when the HTTP {Method} request fails. No metric is emitted
+    on success.
+  </summary>
+  <token key="Method">
+    <variant name="Delete" summary="DELETE"/>
+    <variant name="Get" summary="GET"/>
+    <variant name="Post" summary="POST"/>
+  </token>
+</histogram>
+
 <histogram name="Bluetooth.ChromeOS.FastPair.GattConnection.ErrorReason"
     enum="BluetoothDeviceConnectErrorCode" expires_after="2022-09-20">
   <owner>shanefitz@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/disk/histograms.xml b/tools/metrics/histograms/metadata/disk/histograms.xml
index 3762add0..4ba617d 100644
--- a/tools/metrics/histograms/metadata/disk/histograms.xml
+++ b/tools/metrics/histograms/metadata/disk/histograms.xml
@@ -298,17 +298,6 @@
   </summary>
 </histogram>
 
-<histogram name="DiskCache.0.LoadTime" units="ms" expires_after="M85">
-  <obsolete>
-    Removed 05/2021. Not used.
-  </obsolete>
-  <owner>rvargas@chromium.org</owner>
-  <summary>
-    The time to load the main entry data from disk, with a &quot;loaded&quot;
-    system.
-  </summary>
-</histogram>
-
 <histogram name="DiskCache.0.LowUseAge" units="hours" expires_after="M85">
   <owner>rvargas@chromium.org</owner>
   <summary>
@@ -790,17 +779,6 @@
   </summary>
 </histogram>
 
-<histogram name="DiskCache.2.LoadTime" units="ms" expires_after="M85">
-  <obsolete>
-    Removed 05/2021. Not used.
-  </obsolete>
-  <owner>rvargas@chromium.org</owner>
-  <summary>
-    The time to load the main entry data from disk, with a &quot;loaded&quot;
-    system. Media-specific cache.
-  </summary>
-</histogram>
-
 <histogram name="DiskCache.2.MaxOpenEntries2" units="?" expires_after="M85">
   <owner>rvargas@chromium.org</owner>
   <summary>
@@ -1216,17 +1194,6 @@
   </summary>
 </histogram>
 
-<histogram name="DiskCache.3.LoadTime" units="ms" expires_after="M79">
-  <obsolete>
-    Removed 05/2021. Not used.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The time to load the main entry data from disk, with a &quot;loaded&quot;
-    system. AppCache.
-  </summary>
-</histogram>
-
 <histogram name="DiskCache.3.MaxOpenEntries2" units="entries"
     expires_after="M79">
   <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
@@ -1610,17 +1577,6 @@
   </summary>
 </histogram>
 
-<histogram name="DiskCache.4.LoadTime" units="ms" expires_after="M79">
-  <obsolete>
-    Removed 05/2021. Not used.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>
-    The time to load the main entry data from disk, with a &quot;loaded&quot;
-    system. ShaderCache.
-  </summary>
-</histogram>
-
 <histogram name="DiskCache.4.MaxOpenEntries2" units="?" expires_after="M79">
   <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
   <summary>
@@ -1733,70 +1689,6 @@
   <summary>The time spent writing to an entry. ShaderCache.</summary>
 </histogram>
 
-<histogram name="DiskCache.BlockLoad_0" units="%" expires_after="M79">
-  <obsolete>
-    Removed 05/2021. Not used.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The percentage of use for blocks of type 0 (links).</summary>
-</histogram>
-
-<histogram name="DiskCache.BlockLoad_1" units="%" expires_after="M79">
-  <obsolete>
-    Removed 05/2021. Not used.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The percentage of use for blocks of type 1 (256 bytes).</summary>
-</histogram>
-
-<histogram name="DiskCache.BlockLoad_2" units="%" expires_after="M79">
-  <obsolete>
-    Removed 05/2021. Not used.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The percentage of use for blocks of type 2 (1024 bytes).</summary>
-</histogram>
-
-<histogram name="DiskCache.BlockLoad_3" units="%" expires_after="M79">
-  <obsolete>
-    Removed 05/2021. Not used.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The percentage of use for blocks of type 3 (4096 bytes).</summary>
-</histogram>
-
-<histogram name="DiskCache.Blocks_0" units="blocks" expires_after="M79">
-  <obsolete>
-    Removed 05/2021. Not used.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The number of used blocks of type 0 (links).</summary>
-</histogram>
-
-<histogram name="DiskCache.Blocks_1" units="blocks" expires_after="M79">
-  <obsolete>
-    Removed 05/2021. Not used.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The number of used blocks of type 1 (256 bytes).</summary>
-</histogram>
-
-<histogram name="DiskCache.Blocks_2" units="blocks" expires_after="M79">
-  <obsolete>
-    Removed 05/2021. Not used.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The number of used blocks of type 2 (1024 bytes).</summary>
-</histogram>
-
-<histogram name="DiskCache.Blocks_3" units="blocks" expires_after="M79">
-  <obsolete>
-    Removed 05/2021. Not used.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
-  <summary>The number of used blocks of type 3 (4096 bytes).</summary>
-</histogram>
-
 <histogram name="DiskCache.DeleteFailed2" units="files" expires_after="M79">
   <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
   <summary>Number of block-files that we were unable to delete.</summary>
diff --git a/tools/metrics/histograms/metadata/google/histograms.xml b/tools/metrics/histograms/metadata/google/histograms.xml
index 7180788..3b9b7e8 100644
--- a/tools/metrics/histograms/metadata/google/histograms.xml
+++ b/tools/metrics/histograms/metadata/google/histograms.xml
@@ -39,97 +39,6 @@
   </summary>
 </histogram>
 
-<histogram name="GoogleUpdate.Inline.AppUpdateInfo.InstallStatus"
-    enum="InlineUpdateInstallStatus" expires_after="2020-10-15">
-  <obsolete>
-    Inline updates are deprecated as of M97.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <owner>nyquist@chromium.org</owner>
-  <summary>
-    (Android-only) Records the instances where Play update API returned the
-    current install status of inline updates.
-  </summary>
-</histogram>
-
-<histogram name="GoogleUpdate.Inline.AppUpdateInfo.UpdateAvailability"
-    enum="InlineUpdateAvailability" expires_after="2020-10-15">
-  <obsolete>
-    Inline updates are deprecated as of M97.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <owner>nyquist@chromium.org</owner>
-  <summary>
-    (Android-only) Records the instances where Play update API returned the
-    current availability of inline updates.
-  </summary>
-</histogram>
-
-<histogram name="GoogleUpdate.Inline.CallFailure"
-    enum="InlineUpdateCallFailure" expires_after="2020-10-15">
-  <obsolete>
-    Inline updates are deprecated as of M97.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <owner>nyquist@chromium.org</owner>
-  <summary>
-    (Android-only) Records the instances where Play update API calls failed.
-  </summary>
-</histogram>
-
-<histogram name="GoogleUpdate.Inline.StateChange.Error"
-    enum="InlineUpdateErrorCodes" expires_after="2020-10-15">
-  <obsolete>
-    Inline updates are deprecated as of M97.
-  </obsolete>
-<!-- Name completed by histogram_suffixes name="GoogleUpdate.Inline.InstallStatus" -->
-
-  <owner>dtrainor@chromium.org</owner>
-  <owner>nyquist@chromium.org</owner>
-  <summary>
-    (Android-only) Records the instances where Play update API notified us of an
-    install error during an update. This is keyed on the specific state so we
-    can tell which states are seeing which errors.
-  </summary>
-</histogram>
-
-<histogram name="GoogleUpdate.Inline.UI.Install.Source"
-    enum="UpdateInteractionSource" expires_after="2020-10-15">
-  <obsolete>
-    Inline updates are deprecated as of M97.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <owner>nyquist@chromium.org</owner>
-  <summary>
-    (Android-only) The UI component that triggered an inline update to finish
-    and install.
-  </summary>
-</histogram>
-
-<histogram name="GoogleUpdate.Inline.UI.Retry.Source"
-    enum="UpdateInteractionSource" expires_after="2020-10-15">
-  <obsolete>
-    Inline updates are deprecated as of M97.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <owner>nyquist@chromium.org</owner>
-  <summary>
-    (Android-only) The UI component that triggered an inline update to retry.
-  </summary>
-</histogram>
-
-<histogram name="GoogleUpdate.Inline.UI.Start.Source"
-    enum="UpdateInteractionSource" expires_after="2020-10-15">
-  <obsolete>
-    Inline updates are deprecated as of M97.
-  </obsolete>
-  <owner>dtrainor@chromium.org</owner>
-  <owner>nyquist@chromium.org</owner>
-  <summary>
-    (Android-only) The UI component that triggered an inline update to start.
-  </summary>
-</histogram>
-
 <histogram name="GoogleUpdate.InstallDetails.UpdateCohort" units="units"
     expires_after="2019-06-01">
   <owner>nikunjb@chromium.org</owner>
@@ -140,22 +49,6 @@
   </summary>
 </histogram>
 
-<histogram name="GoogleUpdate.InstallerExitCode" enum="InstallStatus"
-    expires_after="M86">
-  <obsolete>
-    Removed in M88.
-  </obsolete>
-  <owner>grt@chromium.org</owner>
-  <owner>ydago@chromium.org</owner>
-  <summary>
-    The exit code from Chrome's installer following a failed on-demand update
-    check. All values reported for this histogram fall in the
-    GOOGLE_UPDATE_ERROR_UPDATING bucket of the GoogleUpdate.UpdateErrorCode
-    histogram and the GOOPDATEINSTALL_E_INSTALLER_FAILED bucket of the
-    GoogleUpdate.ErrorHresult histogram.
-  </summary>
-</histogram>
-
 <histogram name="GoogleUpdate.MenuItem.ActionTakenAfterItemClicked"
     enum="GoogleUpdateAfterItemClickedActions" expires_after="2021-08-25">
   <owner>dtrainor@chromium.org</owner>
@@ -226,18 +119,6 @@
   </summary>
 </histogram>
 
-<histogram name="GoogleUpdate.UnexpectedState" units="units"
-    expires_after="M85">
-  <obsolete>
-    Removed in M87.
-  </obsolete>
-  <owner>grt@chromium.org</owner>
-  <summary>
-    An unrecognized CurrentState value received from Google Update while polling
-    for the status of an on-demand update check.
-  </summary>
-</histogram>
-
 <histogram name="GoogleUpdate.UpdateErrorCode" enum="GoogleUpdateErrorCode"
     expires_after="2022-07-11">
   <owner>grt@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
index 8d33d03..84f5a46 100644
--- a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
+++ b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
@@ -4835,33 +4835,6 @@
   <affected-histogram name="Event.Latency.OS_NO_VALIDATION.POSITIVE"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="ExitFunnels" separator=".">
-  <suffix name="BackgroundOff" label=""/>
-  <suffix name="BackgroundOn" label=""/>
-  <suffix name="BrowserExit" label=""/>
-  <suffix name="EndSession" label=""/>
-  <suffix name="ES_CloseApp" label=""/>
-  <suffix name="ES_Critical" label=""/>
-  <suffix name="ES_Logoff" label=""/>
-  <suffix name="ES_Other" label=""/>
-  <suffix name="HungBrowserTerminated" label=""/>
-  <suffix name="KillProcess" label=""/>
-  <suffix name="LastWindowClose" label=""/>
-  <suffix name="MessageWindowHung" label=""/>
-  <suffix name="MessageWindowNotFound" label=""/>
-  <suffix name="MessageWindowVanished" label=""/>
-  <suffix name="ProcessSingletonIsShuttingDown" label=""/>
-  <suffix name="RendezvousToHungBrowser" label=""/>
-  <suffix name="SessionEnding" label=""/>
-  <suffix name="TraybarEndSession" label=""/>
-  <suffix name="TraybarExit" label=""/>
-  <suffix name="WatcherEndSession" label=""/>
-  <suffix name="WatcherLogoff" label=""/>
-  <suffix name="WatcherQueryEndSession" label=""/>
-  <suffix name="WM_ENDSESSION" label=""/>
-  <affected-histogram name="Stability.ExitFunnel"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="ExpectedQueueingDurationThreshold" separator="_">
   <obsolete>
     Removed as of 08/2017. Replaced with ExpectedQueueingDurationThreshold.
@@ -5325,23 +5298,6 @@
   <affected-histogram name="GoogleSearch.AccessPoint"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="GoogleUpdate_Inline_InstallStatus" separator=".">
-  <obsolete>
-    Inline updates are deprecated as of M97.
-  </obsolete>
-  <suffix name="Canceled" label="Canceled"/>
-  <suffix name="Downloaded" label="Downloaded"/>
-  <suffix name="Downloading" label="Downloading"/>
-  <suffix name="Failed" label="Failed"/>
-  <suffix name="Installed" label="Installed"/>
-  <suffix name="Installing" label="Installing"/>
-  <suffix name="Pending" label="Pending"/>
-  <suffix name="RequiresUiIntent" label="Requires UI Intent"/>
-  <suffix name="Unknown" label="Unknown"/>
-  <suffix name="Untracked" label="Untracked Status (Not Known to UMA)"/>
-  <affected-histogram name="GoogleUpdate.Inline.StateChange.Error"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="GoogleUpdate_Result_UpdateType" separator=".">
   <suffix base="true" name="Inline" label="Inline Updates">
     <obsolete>
@@ -5778,16 +5734,6 @@
   <affected-histogram name="Download.Parallelizable.FileSize"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="HistogramInconsistencies" separator=".">
-  <obsolete>
-    Removed in 2017.
-  </obsolete>
-  <suffix name="Cronet" label="Cronet histograms."/>
-  <affected-histogram name="Histogram.InconsistenciesBrowser"/>
-  <affected-histogram name="Histogram.InconsistenciesBrowserUnique"/>
-  <affected-histogram name="Histogram.InconsistentSnapshotBrowser"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="HstsState" separator=".">
   <suffix name="HSTSNotEnabled" label="The HSTS is not enabled."/>
   <suffix name="WithHSTSEnabled" label="The HSTS is enabled."/>
@@ -9861,8 +9807,8 @@
   <suffix name="Oauth-enrollment.Completed" label=""/>
   <suffix name="Offline-login.Back" label=""/>
   <suffix name="Offline-login.ReloadOnlineLogin" label=""/>
-  <suffix name="Oobe-eula-md.AcceptedWithStats" label=""/>
   <suffix name="Oobe-eula-md.AcceptedWithoutStats" label=""/>
+  <suffix name="Oobe-eula-md.AcceptedWithStats" label=""/>
   <suffix name="Oobe-eula-md.Back" label=""/>
   <suffix name="Oobe-update.UpdateError" label=""/>
   <suffix name="Oobe-update.UpdateNotRequired" label=""/>
@@ -9889,7 +9835,7 @@
     </obsolete>
   </suffix>
   <suffix name="Update.UpdateNotRequired" label="">
-   <obsolete>
+    <obsolete>
       Renamed to Oobe-update.
     </obsolete>
   </suffix>
@@ -11719,36 +11665,6 @@
   <affected-histogram name="Power.Mac.Total"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="PpapiPluginName" separator="_">
-  <obsolete>
-    Removed Oct 14 2020.
-  </obsolete>
-  <suffix name="libpepflashplayer.so" label="Flash player on Linux or Cros"/>
-  <suffix name="libwidevinecdmadapter.so" label="Widevine CDM on Linux or Cros">
-    <obsolete>
-      Deprecated March 2018
-    </obsolete>
-  </suffix>
-  <suffix name="pepflashplayer.dll" label="Flash player on Windows"/>
-  <suffix name="PepperFlashPlayer.plugin" label="Flash player on Mac"/>
-  <suffix name="widevinecdmadapter.dll" label="Widevine CDM on Windows">
-    <obsolete>
-      Deprecated March 2018
-    </obsolete>
-  </suffix>
-  <suffix name="widevinecdmadapter.plugin" label="Widevine CDM on Mac">
-    <obsolete>
-      Deprecated March 2018
-    </obsolete>
-  </suffix>
-  <affected-histogram name="Plugin.PpapiBrokerLoadErrorCode"/>
-  <affected-histogram name="Plugin.PpapiBrokerLoadResult"/>
-  <affected-histogram name="Plugin.PpapiBrokerLoadTime"/>
-  <affected-histogram name="Plugin.PpapiPluginLoadErrorCode"/>
-  <affected-histogram name="Plugin.PpapiPluginLoadResult"/>
-  <affected-histogram name="Plugin.PpapiPluginLoadTime"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="PrecacheCellular" separator=".">
   <obsolete>
     Removed July 11 2017.
diff --git a/tools/metrics/histograms/metadata/ios/histograms.xml b/tools/metrics/histograms/metadata/ios/histograms.xml
index 4e81c9e1..ff04a056 100644
--- a/tools/metrics/histograms/metadata/ios/histograms.xml
+++ b/tools/metrics/histograms/metadata/ios/histograms.xml
@@ -32,6 +32,16 @@
   </summary>
 </histogram>
 
+<histogram name="IOS.CaptivePortal.SecureConnectionFailed"
+    enum="CaptivePortalStatus" expires_after="2022-06-10">
+  <owner>ajuma@chromium.org</owner>
+  <owner>michaeldo@chromium.org</owner>
+  <summary>
+    The result of a captive portal check triggered by a failed secure
+    connection. Logged once per failed secure connection.
+  </summary>
+</histogram>
+
 <histogram name="IOS.CommittedNavigationHasContext" enum="Boolean"
     expires_after="2022-09-24">
   <owner>ajuma@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/login/histograms.xml b/tools/metrics/histograms/metadata/login/histograms.xml
index 3776fc4..ab3f8e1 100644
--- a/tools/metrics/histograms/metadata/login/histograms.xml
+++ b/tools/metrics/histograms/metadata/login/histograms.xml
@@ -118,6 +118,17 @@
   </summary>
 </histogram>
 
+<histogram name="Login.NumberOfUsersOnLoginScreen" units="units"
+    expires_after="M105">
+  <owner>mslus@chromium.org</owner>
+  <owner>chromeos-commercial-identity@google.com</owner>
+  <summary>
+    Records the number of users the login screen was initialized with. It is
+    emitted on processing the user list before displaying the screen. The count
+    includes all Regular, Child and Active Directory users.
+  </summary>
+</histogram>
+
 <histogram name="Login.OfflineLoginWithHiddenUserPods"
     enum="ChromeOSHiddenUserPodsOfflineLogin" expires_after="M105">
   <owner>mslus@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/plugin/histograms.xml b/tools/metrics/histograms/metadata/plugin/histograms.xml
index 40158aa..dbe96bc 100644
--- a/tools/metrics/histograms/metadata/plugin/histograms.xml
+++ b/tools/metrics/histograms/metadata/plugin/histograms.xml
@@ -28,89 +28,6 @@
   <summary>Record usage of PPB_Flash.Navigate() Pepper API.</summary>
 </histogram>
 
-<histogram name="Plugin.FlashUsage" enum="FlashUsage"
-    expires_after="2022-04-24">
-  <obsolete>
-    Removed Oct 2021.
-  </obsolete>
-  <owner>yzshen@chromium.org</owner>
-  <owner>thestig@chromium.org</owner>
-  <summary>Collects Flash usage data.</summary>
-</histogram>
-
-<histogram name="Plugin.PowerSaver.Unthrottle"
-    enum="PluginPowerSaverUnthrottleMethod" expires_after="2020-03-29">
-  <obsolete>
-    Deprecated Oct 2020.
-  </obsolete>
-  <owner>tommycli@chromium.org</owner>
-  <summary>
-    Record how many throttled plugins are unthrottled, and by what method.
-  </summary>
-</histogram>
-
-<histogram name="Plugin.PpapiBrokerLoadErrorCode" enum="WinGetLastError"
-    expires_after="M88">
-  <obsolete>
-    Deprecated Oct 14 2020.
-  </obsolete>
-  <owner>xhwang@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    The error code of a PPAPI broker load failure. Only reported on Windows.
-  </summary>
-</histogram>
-
-<histogram name="Plugin.PpapiBrokerLoadResult" enum="PluginLoadResult"
-    expires_after="M88">
-  <obsolete>
-    Deprecated Oct 14 2020.
-  </obsolete>
-  <owner>xhwang@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>The result from an attempt to load a PPAPI broker.</summary>
-</histogram>
-
-<histogram name="Plugin.PpapiBrokerLoadTime" units="ms" expires_after="M88">
-  <obsolete>
-    Deprecated Oct 14 2020.
-  </obsolete>
-  <owner>xhwang@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>The time spent to load a PPAPI broker.</summary>
-</histogram>
-
-<histogram name="Plugin.PpapiPluginLoadErrorCode" enum="WinGetLastError"
-    expires_after="M88">
-  <obsolete>
-    Deprecated Oct 14 2020.
-  </obsolete>
-  <owner>xhwang@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>
-    The error code of a PPAPI plugin load failure. Only reported on Windows.
-  </summary>
-</histogram>
-
-<histogram name="Plugin.PpapiPluginLoadResult" enum="PluginLoadResult"
-    expires_after="M88">
-  <obsolete>
-    Deprecated Oct 14 2020.
-  </obsolete>
-  <owner>xhwang@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>The result from an attempt to load a PPAPI plugin.</summary>
-</histogram>
-
-<histogram name="Plugin.PpapiPluginLoadTime" units="ms" expires_after="M88">
-  <obsolete>
-    Deprecated Oct 14 2020.
-  </obsolete>
-  <owner>xhwang@chromium.org</owner>
-  <owner>media-dev@chromium.org</owner>
-  <summary>The time spent to load a PPAPI plugin.</summary>
-</histogram>
-
 <histogram name="Plugin.PpapiSyncIPCTime" units="ms" expires_after="2018-08-30">
   <owner>gab@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/stability/histograms.xml b/tools/metrics/histograms/metadata/stability/histograms.xml
index 6702717..cccd1bc 100644
--- a/tools/metrics/histograms/metadata/stability/histograms.xml
+++ b/tools/metrics/histograms/metadata/stability/histograms.xml
@@ -99,37 +99,6 @@
   </summary>
 </histogram>
 
-<histogram name="Stability.Android.StrongBindingOomRemainingBindingState"
-    enum="Android.ChildProcessBindingStateCombination"
-    expires_after="2021-08-09">
-  <obsolete>
-    Removed on 08/2021. No longer needed.
-  </obsolete>
-  <owner>boliu@chromium.org</owner>
-  <owner>ssid@chromium.org</owner>
-  <summary>
-    Record the state of child service bindings left when a child service with
-    strong binding is OOM killed by Android. Recorded when such a OOM kill is
-    detected by browser. Note this does not distinguish process type, and is for
-    example recorded for both GPU and renderer process.
-  </summary>
-</histogram>
-
-<histogram name="Stability.Android.StrongBindingOomRemainingStrongBindingCount"
-    units="units" expires_after="2020-08-30">
-  <obsolete>
-    Removed on 08/2021. No longer needed.
-  </obsolete>
-  <owner>boliu@chromium.org</owner>
-  <owner>ssid@chromium.org</owner>
-  <summary>
-    Record the count of strongly bound child services left when a child service
-    with strong binding is OOM killed by Android. Recorded when such a OOM kill
-    is detected by browser. Note this does not distinguish process type, and is
-    for example count both GPU and renderer process.
-  </summary>
-</histogram>
-
 <histogram base="true" name="Stability.Android.SystemExitReason"
     enum="AndroidProcessExitReason" expires_after="2022-07-03">
   <owner>boliu@chromium.org</owner>
@@ -323,56 +292,6 @@
   </summary>
 </histogram>
 
-<histogram name="Stability.ExitFunnel" units="ms" expires_after="M85">
-  <obsolete>
-    Removed 10/2020 although this has been dead for many years.
-  </obsolete>
-  <owner>siggi@chromium.org</owner>
-  <summary>
-    Temporary instrumentation to record the Windows browser's exit path. See
-    http://crbug.com/412384.
-  </summary>
-</histogram>
-
-<histogram name="Stability.Experimental.BrowserCrash" enum="Boolean"
-    expires_after="2021-10-31">
-  <obsolete>
-    Removed 2021/09
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <owner>chrome-metrics-team@google.com</owner>
-  <summary>
-    Logged at the same time as the kBrowserCrash bucket of Stability.Counts2,
-    for debugging crbug.com/1176977.
-  </summary>
-</histogram>
-
-<histogram name="Stability.Experimental.Counts" enum="StabilityEventType"
-    expires_after="2021-01-15">
-  <obsolete>
-    Removed 01/2021, replaced with Stability.Counts2.
-  </obsolete>
-  <owner>rkaplow@chromium.org</owner>
-  <owner>chrome-metrics-team@google.com</owner>
-  <summary>
-    Collects various counters related to stability. The majority of them are
-    crash types.
-  </summary>
-</histogram>
-
-<histogram name="Stability.Experimental.Counts2" enum="StabilityEventType"
-    expires_after="2021-10-31">
-  <obsolete>
-    Removed 2021/09
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <owner>chrome-metrics-team@google.com</owner>
-  <summary>
-    Like Stability.Counts2, but logged as a sparse histogram for debugging
-    crbug.com/1176977.
-  </summary>
-</histogram>
-
 <histogram name="Stability.Experimental.PageLoads" enum="StabilityPageLoadType"
     expires_after="2022-06-12">
   <owner>fdoray@chromium.org</owner>
@@ -386,57 +305,6 @@
   </summary>
 </histogram>
 
-<histogram name="Stability.Experimental.ProcessId" units="process id"
-    expires_after="2021-10-31">
-  <obsolete>
-    Removed 2021/09
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <owner>chrome-metrics-team@google.com</owner>
-  <summary>
-    Logs the process id as a histogram, to help debug crbug.com/1176977. Logged
-    with MOD 1000 to limit the number of distinct values reported.
-  </summary>
-</histogram>
-
-<histogram name="Stability.Experimental.RandInt" units="random number"
-    expires_after="2021-10-31">
-  <obsolete>
-    Removed 2021/09
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <owner>chrome-metrics-team@google.com</owner>
-  <summary>
-    Logs a random number in the range 0 to 999 to help debug crbug.com/1176977.
-  </summary>
-</histogram>
-
-<histogram name="Stability.Experimental.SessionId" units="session id"
-    expires_after="2021-10-31">
-  <obsolete>
-    Removed 2021/09
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <owner>chrome-metrics-team@google.com</owner>
-  <summary>
-    Logs the UMA session id as a histogram, to help debug crbug.com/1176977.
-    Logged with MOD 1000 to limit the number of distinct values reported.
-  </summary>
-</histogram>
-
-<histogram name="Stability.Internals.DataDiscardCount" units="counts"
-    expires_after="M77">
-  <obsolete>
-    Removed on 10/2020.
-  </obsolete>
-  <owner>siggi@chromium.org</owner>
-  <summary>
-    Number of times stability data was discarded. This is accumulated since the
-    last report, even across versions. This is logged during stability metric
-    recording for the following log sent.
-  </summary>
-</histogram>
-
 <histogram
     name="Stability.Internals.FileMetricsProvider.BrowserMetrics.UnsentFilesCount"
     units="counts" expires_after="M89">
@@ -460,19 +328,6 @@
   </summary>
 </histogram>
 
-<histogram name="Stability.Internals.InitialStabilityLogDeferredCount"
-    units="counts" expires_after="M77">
-  <obsolete>
-    Removed on 10/2020.
-  </obsolete>
-  <owner>siggi@chromium.org</owner>
-  <summary>
-    Number of times the initial stability log upload was deferred to the next
-    startup. This is logged during stability metric recording for the following
-    log sent.
-  </summary>
-</histogram>
-
 <histogram name="Stability.Internals.SystemCrashCount" units="crashes"
     expires_after="2022-10-20">
   <owner>davidbienvenu@chromium.org</owner>
@@ -483,19 +338,6 @@
   </summary>
 </histogram>
 
-<histogram name="Stability.Internals.VersionMismatchCount" units="counts"
-    expires_after="M77">
-  <obsolete>
-    Removed on 10/2020.
-  </obsolete>
-  <owner>siggi@chromium.org</owner>
-  <summary>
-    Number of times the version number stored in prefs did not match the
-    serialized system profile version number. This is logged during stability
-    metric recording.
-  </summary>
-</histogram>
-
 <histogram name="Stability.IOS.Crashpad.Initialized" enum="BooleanSuccess"
     expires_after="2022-06-15">
   <owner>justincohen@chromium.org</owner>
@@ -604,19 +446,6 @@
   </summary>
 </histogram>
 
-<histogram name="Stability.iOS.UTE.LowPowerModeEnabled" enum="BooleanEnabled"
-    expires_after="2021-12-12">
-  <obsolete>
-    Removed 11/2021
-  </obsolete>
-  <owner>michaeldo@chromium.org</owner>
-  <owner>olivierrobin@chromium.org</owner>
-  <summary>
-    The power mode of the device when a crash occurred. Logged on application
-    launch if the last session terminated in an unclean state.
-  </summary>
-</histogram>
-
 <histogram name="Stability.iOS.UTE.MobileSessionAppState" enum="IOSAppState"
     expires_after="2022-12-11">
   <owner>justincohen@chromium.org</owner>
@@ -704,20 +533,6 @@
   </summary>
 </histogram>
 
-<histogram name="Stability.RendererUnresponsiveBeforeTermination"
-    enum="BooleanUnresponsive" expires_after="2020-04-26">
-  <obsolete>
-    Removed 12/2020.
-  </obsolete>
-  <owner>dtapuska@chromium.org</owner>
-  <summary>
-    If the renderer is considered unresponsive from the browser's perspective
-    before the process is terminated. This metric is being used to figure out
-    crash reports that have all idle threads and perhaps the process is being
-    terminated when it shouldn't be. crbug.com/615090.
-  </summary>
-</histogram>
-
 </histograms>
 
 </histogram-configuration>
diff --git a/tools/metrics/histograms/metadata/uma/histograms.xml b/tools/metrics/histograms/metadata/uma/histograms.xml
index 86e70193..435ccf83 100644
--- a/tools/metrics/histograms/metadata/uma/histograms.xml
+++ b/tools/metrics/histograms/metadata/uma/histograms.xml
@@ -55,32 +55,6 @@
   </summary>
 </histogram>
 
-<histogram name="Histogram.InconsistentSnapshotBrowser" units="units"
-    expires_after="M85">
-  <obsolete>
-    Removed 07/2017.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    The amount of discrepancy found when examining a single histogram's data in
-    the browser process for transmission via UMA. Inconsistent data is NOT
-    transmitted via UMA.
-  </summary>
-</histogram>
-
-<histogram name="Histogram.InconsistentSnapshotChildProcess" units="units"
-    expires_after="M85">
-  <obsolete>
-    Removed 07/2017.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    The amount of discrepancy found when examining a single histogram's data in
-    a child process for transmission via UMA. Inconsistent data is NOT
-    transmitted via UMA.
-  </summary>
-</histogram>
-
 <histogram name="Histogram.MismatchedConstructionArguments"
     enum="HistogramNameHash" expires_after="2022-08-01">
   <owner>asvitkine@chromium.org</owner>
@@ -94,44 +68,6 @@
   </summary>
 </histogram>
 
-<histogram name="Histogram.PendingProcessNotResponding" units="processes"
-    expires_after="M79">
-  <obsolete>
-    Removed 06/2021.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    When metrics services (UMA) ran an update, the number of child processes
-    that did not respond, providing histogram updates, before the timeout.
-  </summary>
-</histogram>
-
-<histogram name="Histogram.PermanentNameChanged" enum="HistogramNameHash"
-    expires_after="M85">
-  <obsolete>
-    No longer in the codebase as of 06/2021.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <owner>bcwhite@chromium.org</owner>
-  <summary>
-    The hash codes of histograms of which the external name storage was altered
-    after the histogram was created.
-  </summary>
-</histogram>
-
-<histogram name="Histogram.ReceivedProcessGroupCount" enum="BooleanEnabled"
-    expires_after="M79">
-  <obsolete>
-    Removed 06/2021.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    When metrics services (UMA) ran an update, the number of times the process
-    groups (renderer processes and plugin/gpu processes) did not respond,
-    providing histogram updates, before the timeout.
-  </summary>
-</histogram>
-
 <histogram name="Histogram.TooManyBuckets.1000" enum="HistogramNameHash"
     expires_after="2022-08-01">
   <owner>asvitkine@chromium.org</owner>
@@ -177,25 +113,6 @@
   </summary>
 </histogram>
 
-<histogram name="UMA.CleanExitBeaconConsistency" enum="UmaCleanExitConsistency"
-    expires_after="2022-01-18">
-  <obsolete>
-    Deprecated 07/2021 in favor of CleanExitBeaconConsistency2. Version 2
-    changes semantics in some of the buckets, to support measuring the frequency
-    with which the Local State data is missing.
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <owner>justincohen@chromium.org</owner>
-  <owner>olivierrobin@chromium.org</owner>
-  <owner>src/base/metrics/OWNERS</owner>
-  <summary>
-    Recorded when the CleanExitBeacon is constructed. Reports the combined state
-    of distinct clean exit beacons stored in Local State and the Windows
-    registry (or NSUserDefaults on iOS). They are normally expected to be
-    identical.
-  </summary>
-</histogram>
-
 <histogram name="UMA.CleanExitBeaconConsistency2"
     enum="UmaCleanExitConsistency2" expires_after="2022-08-01">
   <owner>asvitkine@chromium.org</owner>
@@ -314,23 +231,6 @@
   </summary>
 </histogram>
 
-<histogram name="UMA.FileMetricsProvider.MergeHistogram.{Type}"
-    enum="HistogramNameHash" expires_after="2021-10-31">
-  <obsolete>
-    Removed 2021/09
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <owner>chrome-metrics-team@google.com</owner>
-  <summary>
-    Records which histograms were merged into the current log from external
-    sources. {Type}
-  </summary>
-  <token key="Type">
-    <variant name="NotReadOnly" summary="From non-read-only sources."/>
-    <variant name="ReadOnly" summary="From read-only sources."/>
-  </token>
-</histogram>
-
 <histogram name="UMA.InitSequence" enum="UmaInitSequence"
     expires_after="2022-08-01">
   <owner>asvitkine@chromium.org</owner>
@@ -533,19 +433,6 @@
   </summary>
 </histogram>
 
-<histogram name="UMA.MetricsService.Initialize" enum="Boolean"
-    expires_after="2021-10-31">
-  <obsolete>
-    Removed 2021/09
-  </obsolete>
-  <owner>rkaplow@chromium.org</owner>
-  <owner>src/base/metrics/OWNERS</owner>
-  <summary>
-    Records true during the initialization of the metrics state, right at the
-    time of logging a count to launch_count in stability prefs.
-  </summary>
-</histogram>
-
 <histogram name="UMA.MetricsService.Initialize.Time" units="microseconds"
     expires_after="2022-08-01">
   <owner>asvitkine@chromium.org</owner>
@@ -613,35 +500,6 @@
   <token key="PersistentAllocatorType" variants="PersistentAllocatorType"/>
 </histogram>
 
-<histogram name="UMA.PersistentHistograms.DriveType" enum="WindowsDriveType"
-    expires_after="2021-10-31">
-  <obsolete>
-    Removed 2021/09
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <owner>chrome-metrics-team@google.com</owner>
-  <summary>
-    Records the drive type the persistent histograms file opened on start up is
-    on. Only logged on Windows based on the result of the GetDriveTypeW() API.
-    Added to diagnose crbug.com/1176977.
-  </summary>
-</histogram>
-
-<histogram name="UMA.PersistentHistograms.HistogramsInStartupFile"
-    enum="HistogramNameHash" expires_after="2021-10-31">
-  <obsolete>
-    Removed 2021/09
-  </obsolete>
-  <owner>asvitkine@chromium.org</owner>
-  <owner>chrome-metrics-team@google.com</owner>
-  <summary>
-    Records which histograms were found initially in the .pma file used by the
-    browser process for persistent histograms. The expectation is there should
-    be no entries there, but this histogram is added to diagnose a problem we're
-    seeing where this could be the cause. See crbug.com/1176977 for details.
-  </summary>
-</histogram>
-
 <histogram name="UMA.PersistentHistograms.InitResult"
     enum="PersistentHistogramsInitResult" expires_after="2022-08-01">
   <owner>bcwhite@chromium.org</owner>
@@ -801,20 +659,6 @@
   </summary>
 </histogram>
 
-<histogram name="UMA.StructuredMetrics.ClientInitializationSuccessful"
-    enum="BooleanSuccess" expires_after="M97">
-  <obsolete>
-    Expired in M97 and removed from code in Jan 2022 for M99. This was reporting
-    100% success on all channels as of Jan 2022.
-  </obsolete>
-  <owner>jongahn@chromium.org</owner>
-  <owner>tby@chromium.org</owner>
-  <summary>
-    Emitted on initialization of structured metrics client. Records whether the
-    client was initialized successfully.
-  </summary>
-</histogram>
-
 <histogram name="UMA.StructuredMetrics.EventRecordingState"
     enum="StructuredMetricsEventRecordingState" expires_after="2022-04-24">
   <owner>tby@chromium.org</owner>
@@ -837,21 +681,6 @@
   </summary>
 </histogram>
 
-<histogram name="UMA.StructuredMetrics.InternalError"
-    enum="StructuredMetricsInternalError" expires_after="2022-02-27">
-  <obsolete>
-    Removed 10/08/2021. This histogram had a recording bug that grouped failed
-    key errors with failed event errors. Prefer to use InternalError2.
-  </obsolete>
-  <owner>tby@chromium.org</owner>
-  <owner>rkaplow@chromium.org</owner>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    Records unexpected internal errors of the structured metrics system. The
-    bucket proportion of this metric is not meaningful.
-  </summary>
-</histogram>
-
 <histogram name="UMA.StructuredMetrics.InternalError2"
     enum="StructuredMetricsInternalError2" expires_after="2022-05-01">
   <owner>tby@chromium.org</owner>
@@ -886,24 +715,6 @@
   </summary>
 </histogram>
 
-<histogram name="UMA.StructuredMetrics.PrefReadError"
-    enum="PrefServiceReadError" expires_after="2021-12-01">
-  <obsolete>
-    Deprecated 10/2021 as structured metrics now stores data in protos rather
-    than prefs. Replaced with UMA.StructuredMetrics.InternalError2.
-  </obsolete>
-  <owner>tby@chromium.org</owner>
-  <owner>rkaplow@chromium.org</owner>
-  <owner>asvitkine@chromium.org</owner>
-  <summary>
-    When the structured metrics provider initializes, it reads the pref store
-    from disk that holds keys and unsent logs. If there was an error during that
-    read, this records the error code. PREF_READ_ERROR_NO_FILE is recorded
-    whenever a particular profile signs into a particular device for the first
-    time, so a reasonable number of errors are expected.
-  </summary>
-</histogram>
-
 <histogram name="UMA.TruncatedEvents.Omnibox" units="events"
     expires_after="M85">
   <owner>rkaplow@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/windows/histograms.xml b/tools/metrics/histograms/metadata/windows/histograms.xml
index 449f75e..021f6011 100644
--- a/tools/metrics/histograms/metadata/windows/histograms.xml
+++ b/tools/metrics/histograms/metadata/windows/histograms.xml
@@ -22,19 +22,6 @@
 
 <histograms>
 
-<variants name="FileOperations">
-  <variant name=".DeleteFile.NonRecursive" summary="">
-    <obsolete>
-      Removed in M95.
-    </obsolete>
-  </variant>
-  <variant name=".DeleteFile.Recursive" summary="">
-    <obsolete>
-      Removed in M95.
-    </obsolete>
-  </variant>
-</variants>
-
 <histogram name="Windows.ApplockerRunning" enum="Boolean" expires_after="M83">
   <owner>forshaw@chromium.org</owner>
   <owner>wfh@chromium.org</owner>
@@ -78,18 +65,6 @@
   </summary>
 </histogram>
 
-<histogram name="Windows.ComputeNativeWindowOcclusionTime" units="microseconds"
-    expires_after="M83">
-  <obsolete>
-    Removed 11/2020. As of June 15, 2020, data indicates that computing
-    occlusion is fast enough at all percentiles.
-  </obsolete>
-  <owner>fdoray@chromium.org</owner>
-  <summary>
-    The amount of CPU time a call to ComputeNativeWindowOcclusionStatus() takes.
-  </summary>
-</histogram>
-
 <histogram name="Windows.FileDeleteLastRetryError" enum="WinGetLastError"
     expires_after="2022-05-01">
   <owner>grt@chromium.org</owner>
@@ -111,41 +86,6 @@
   </summary>
 </histogram>
 
-<histogram name="Windows.FilesystemError{FileOperations}"
-    enum="WinGetLastError" expires_after="M81">
-  <obsolete>
-    Removed in M95.
-  </obsolete>
-  <owner>grt@chromium.org</owner>
-  <summary>
-    The Windows error code relating to a failed attempt to operate on a file or
-    a directory. {FileOperations}
-  </summary>
-  <token key="FileOperations" variants="FileOperations">
-    <variant name="">
-      <obsolete>
-        Base histogram. Use suffixes of this histogram instead.
-      </obsolete>
-    </variant>
-  </token>
-</histogram>
-
-<histogram name="Windows.GetVersionExVersion" enum="WindowsVersion"
-    expires_after="never">
-  <obsolete>
-    Removed 10/2020 as this histogram has been replaced by the synthetic
-    histogram Windows.WindowsVersion generated from Windows.PatchLevel.
-  </obsolete>
-<!-- expires-never: Needed to measure Windows ecosystem. -->
-
-  <owner>wfh@chromium.org</owner>
-  <owner>brucedawson@chromium.org</owner>
-  <summary>
-    The Windows version (base::win::Version) as reported by GetVersionEx(). This
-    is queried shortly after startup.
-  </summary>
-</histogram>
-
 <histogram name="Windows.HasHighResolutionTimeTicks" enum="Boolean"
     expires_after="2023-12-19">
   <owner>brucedawson@chromium.org</owner>
@@ -224,23 +164,6 @@
   </summary>
 </histogram>
 
-<histogram name="Windows.Kernel32Version" enum="WindowsVersion"
-    expires_after="never">
-  <obsolete>
-    Removed 10/2020 as this histogram has been replaced by the synthetic
-    histogram Windows.WindowsVersionKernel32 generated from
-    Windows.PatchLevelKernel32.
-  </obsolete>
-<!-- expires-never: Needed to measure Windows ecosystem. -->
-
-  <owner>wfh@chromium.org</owner>
-  <owner>brucedawson@chromium.org</owner>
-  <summary>
-    The Windows version (base::win::Version) as reported by VerQueryValue() on
-    kernel32.dll. This is queried shortly after startup.
-  </summary>
-</histogram>
-
 <histogram name="Windows.Menu.Win11Style" enum="BooleanWin11MenuStyle"
     expires_after="M97">
   <owner>kylixrd@chromium.org</owner>
@@ -349,25 +272,6 @@
   </summary>
 </histogram>
 
-<histogram name="Windows.PostOperationState{FileOperations}"
-    enum="PostOperationState" expires_after="M81">
-  <obsolete>
-    Removed in M95.
-  </obsolete>
-  <owner>grt@chromium.org</owner>
-  <summary>
-    The state of an item in the filesystem following an operation on it.
-    {FileOperations}
-  </summary>
-  <token key="FileOperations" variants="FileOperations">
-    <variant name="">
-      <obsolete>
-        Base histogram. Use suffixes of this histogram instead.
-      </obsolete>
-    </variant>
-  </token>
-</histogram>
-
 <histogram name="Windows.ProcessorFamily" enum="ProcessorFamily"
     expires_after="2022-07-03">
   <owner>rkc@chromium.org</owner>
@@ -390,59 +294,11 @@
   </summary>
 </histogram>
 
-<histogram name="Windows.ServiceStatus.SSP" units="WindowsServiceStatus"
-    expires_after="2021-12-12">
-  <obsolete>
-    Removed in M96.
-  </obsolete>
-  <owner>wfh@chromium.org</owner>
-  <owner>ajgo@chromium.org</owner>
-  <summary>
-    This records whether any SSP/AD providers are registered on the system. If
-    there are any then this typically means the network sandbox cannot
-    successfully engage. Recorded each time the browser attempts to start the
-    network service process. This metric is only recorded on Windows 10+.
-  </summary>
-</histogram>
-
 <histogram name="Windows.Tablet" enum="BooleanTablet" expires_after="M77">
   <owner>zturner@chromium.org</owner>
   <summary>Count of browser launches from a Windows tablet pc.</summary>
 </histogram>
 
-<histogram name="Windows.TmpFileDeleter.FailCount" units="files"
-    expires_after="2021-08-09">
-  <obsolete>
-    Removed in M94.
-  </obsolete>
-  <owner>grt@chromium.org</owner>
-  <owner>etiennep@chromium.org</owner>
-  <summary>
-    The number of files failed to be deleted in a single directory by the
-    browser process's tmp file deleter on Windows. These are files that were
-    left behind on previous runs when third-party software interfered with
-    Chrome's ability to delete its own temporary files. No value is emitted for
-    a directory if no delete attempts are made. Otherwise, the fail count will
-    be zero or more.
-  </summary>
-</histogram>
-
-<histogram name="Windows.TmpFileDeleter.SuccessCount" units="files"
-    expires_after="2021-08-09">
-  <obsolete>
-    Removed in M94.
-  </obsolete>
-  <owner>grt@chromium.org</owner>
-  <owner>etiennep@chromium.org</owner>
-  <summary>
-    The number of files deleted in a single directory by the browser process's
-    tmp file deleter on Windows. These are files that were left behind on
-    previous runs when third-party software interfered with Chrome's ability to
-    delete its own temporary files. No value is emitted for a directory if no
-    delete attempts are made. Otherwise, the success count will be zero or more.
-  </summary>
-</histogram>
-
 <histogram name="Windows.TouchDrag.Success" units="BooleanSuccess"
     expires_after="2021-12-01">
   <owner>davidbienvenu@chromium.org</owner>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml
index 15c65114..fa3c498 100644
--- a/tools/metrics/ukm/ukm.xml
+++ b/tools/metrics/ukm/ukm.xml
@@ -13754,6 +13754,16 @@
       anytime after that happens.
     </summary>
   </metric>
+  <metric name="PaintTiming.LargestContentfulPaintBPP"
+      enum="BitsPerPixelExponential">
+    <summary>
+      Measures the ratio of image file size (in bits) to displayed pixels for
+      the LCP candidate. Bucketed into roughly exponential intervals to account
+      for the wide range of encountered values (less than 1:100000 to greater
+      than 10000:1). This metric is recorded whenever the LCP candidate is an
+      image, and omitted when it is text.
+    </summary>
+  </metric>
   <metric name="PaintTiming.LargestContentfulPaintType">
     <summary>
       Indicates that type of the LargestContentfulPaint candidate. This value is
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index 22e1038..0434ee6 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -6,7 +6,7 @@
         },
         "win": {
             "hash": "fac45c375ca5740c962699bf1badc5ef6ef9d1a6",
-            "remote_path": "perfetto_binaries/trace_processor_shell/win/d7dfde628cc24c1ae8a0fa46f91878794def8640/trace_processor_shell.exe"
+            "remote_path": "perfetto_binaries/trace_processor_shell/win/eaf3141878e1188b63767f2e81a932a9fea6bec7/trace_processor_shell.exe"
         },
         "linux_arm": {
             "hash": "58893933be305d3bfe0a72ebebcacde2ac3ca893",
@@ -14,7 +14,7 @@
         },
         "mac": {
             "hash": "b260bbb0f435d260abb220022d6573caad908616",
-            "remote_path": "perfetto_binaries/trace_processor_shell/mac/d7dfde628cc24c1ae8a0fa46f91878794def8640/trace_processor_shell"
+            "remote_path": "perfetto_binaries/trace_processor_shell/mac/eaf3141878e1188b63767f2e81a932a9fea6bec7/trace_processor_shell"
         },
         "mac_arm64": {
             "hash": "c0397e87456ad6c6a7aa0133e5b81c97adbab4ab",
@@ -22,7 +22,7 @@
         },
         "linux": {
             "hash": "5e8d99ad4425aed5bcd5a79eefbe7470fced823b",
-            "remote_path": "perfetto_binaries/trace_processor_shell/linux/d7dfde628cc24c1ae8a0fa46f91878794def8640/trace_processor_shell"
+            "remote_path": "perfetto_binaries/trace_processor_shell/linux/56f2ccce0511ebd51e2f7d2fa659719a712a6044/trace_processor_shell"
         }
     },
     "power_profile.sql": {
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config
index ea4978c..18dc1ad 100644
--- a/tools/perf/expectations.config
+++ b/tools/perf/expectations.config
@@ -383,7 +383,6 @@
 crbug.com/1174108 [ win-laptop ] system_health.common_desktop/browse:tools:autocad:2021 [ Skip ]
 crbug.com/1211795 [ mac ] system_health.common_desktop/browse:tools:autocad:2021 [ Skip ]
 crbug.com/1277966 [ win-laptop ] system_health.common_desktop/browse:tools:maps:2019 [ Skip ]
-crbug.com/1287549 [ win-laptop ] system_health.common_desktop/browse:tools:photoshop_warm:2021 [ Skip ]
 
 # Benchmark: system_health.common_mobile
 crbug.com/1007355 [ android-go android-webview ] system_health.common_mobile/load:media:imgur:2018 [ Skip ]
diff --git a/tools/perf/page_sets/system_health/browsing_stories.py b/tools/perf/page_sets/system_health/browsing_stories.py
index 3299800..aea6640 100644
--- a/tools/perf/page_sets/system_health/browsing_stories.py
+++ b/tools/perf/page_sets/system_health/browsing_stories.py
@@ -787,9 +787,7 @@
       'Apollo.init()':
           'telemetry:reported_by_page:benchmark_begin',
       'Doc.open complete':
-          'telemetry:reported_by_page:benchmark_end',
-      'open document end':
-          'telemetry:reported_by_page:interactive'
+          'telemetry:reported_by_page:benchmark_end'
     };
   '''
 
diff --git a/tools/perfbot-analysis/analyze-new-pdf.js b/tools/perfbot-analysis/analyze-new-pdf.js
new file mode 100644
index 0000000..a322da7
--- /dev/null
+++ b/tools/perfbot-analysis/analyze-new-pdf.js
@@ -0,0 +1,91 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+const extract = require('./extract-metric.js');
+const tryrequire = require('./try-require.js');
+
+const fs = require('fs');
+
+const puppeteer = tryrequire.tryrequire('puppeteer');
+if (!puppeteer) {
+  console.error(
+      'Please install the `puppeteer` package from npm (`npm i puppeteer`).');
+  return;
+}
+
+const yargs = tryrequire.tryrequire('yargs');
+if (!yargs) {
+  console.error('Please install the `yargs` package from npm (`npm i yargs`).');
+  return;
+}
+
+async function main() {
+  const argv = yargs
+                   .option('directory', {
+                     alias: 'd',
+                     description: 'Directory containing all the trace files.',
+                     type: 'string'
+                   })
+                   .option('parallel', {
+                     alias: 'p',
+                     description: 'How many stories to process in parallel.',
+                     type: 'number',
+                     default: 20,
+                   })
+                   .wrap(null)
+                   .argv;
+
+  const location = argv.directory;
+  if (!location) {
+    console.error(
+        'Please specify the location that contains all the traces (using -d).');
+    return;
+  }
+  if (!fs.existsSync(location)) {
+    console.error('Directotry specified (' + location + ') does not exist.');
+    return;
+  }
+
+  const filenames = fs.readdirSync(location).filter(f => f.endsWith('.html'));
+  const browser = await puppeteer.launch();
+  const promises = [];
+  let counter = 1;
+  const rows = [['name', 'PercentDroppedFrames', 'PercentDroppedFrames2']];
+  for (const f of filenames) {
+    const traceurl = 'file://' + fs.realpathSync(`${location}/${f}`);
+    const p = extract.extractMetrics(browser, traceurl, 'umaMetric');
+    promises.push(p);
+    p.then((histograms) => {
+      const oldh = 'Graphics.Smoothness.PercentDroppedFrames.AllSequences';
+      const newh = 'Graphics.Smoothness.PercentDroppedFrames2.AllSequences';
+      let msg = '';
+
+      if ('error' in histograms) {
+        msg = 'some error happened.';
+      } else if ((oldh in histograms) && (newh in histograms)) {
+        const newv = histograms[newh].avg;
+        const oldv = histograms[oldh].avg;
+        const diff = Math.abs(newv - oldv);
+        msg = `Difference: ${diff.toFixed(2)} (${newv.toFixed(2)} vs ${
+            oldv.toFixed(2)}).`;
+        rows.push([f, oldv, newv]);
+      } else {
+        msg = 'no metrics.';
+      }
+
+      console.log(`${counter++}/${filenames.length} ${f}: ${msg}`);
+    });
+
+    if (promises.length === argv.p) {
+      await Promise.all(promises);
+      promises.length = 0;
+    }
+  }
+  await Promise.all(promises);
+  await browser.close();
+
+  console.log(rows.map(r => r.join(',')).join('\n'));
+}
+
+main();
diff --git a/tools/perfbot-analysis/extract-metric.js b/tools/perfbot-analysis/extract-metric.js
new file mode 100644
index 0000000..204f7ac
--- /dev/null
+++ b/tools/perfbot-analysis/extract-metric.js
@@ -0,0 +1,44 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+async function extractMetrics(browser, traceurl, metrics) {
+  const page = await browser.newPage();
+  let histograms = {};
+  try {
+    await page.goto(traceurl, {waitUntil: 'domcontentloaded'});
+    await page.waitForFunction(() => {
+      return g_timelineViewEl && g_timelineViewEl.model;
+    }, {timeout: 15000});
+    histograms = await page.evaluate((metricName) => {
+      try {
+        const histograms = new tr.v.HistogramSet();
+        const metric =
+            tr.metrics.MetricRegistry.findTypeInfoWithName(metricName);
+        metric.constructor(histograms, g_timelineViewEl.model);
+
+        const values = {};
+        for (const h of histograms) {
+          const name = h.name;
+          const avg = h.average;
+          const min = h.min;
+          const max = h.max;
+          const count = h.numValues;
+          values[name] = {avg, min, max, count};
+        }
+        return values;
+      } catch (ex) {
+        return {error: `${ex}`};
+      }
+    }, metrics);
+    await page.close();
+  } catch (ex) {
+    histograms.error = ex;
+    await page.close();
+  }
+  return histograms;
+}
+
+module.exports = {
+  extractMetrics,
+};
diff --git a/ui/aura/window.h b/ui/aura/window.h
index cf16e8efd..aceca5c 100644
--- a/ui/aura/window.h
+++ b/ui/aura/window.h
@@ -14,7 +14,6 @@
 #include <vector>
 
 #include "base/check.h"
-#include "base/compiler_specific.h"
 #include "base/containers/flat_set.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
@@ -262,7 +261,7 @@
   // be individually capturable, and its layer won't be tagged with a valid
   // |viz::SubtreeCaptureId|.
   // See https://crbug.com/1143930 for more details.
-  ScopedWindowCaptureRequest MakeWindowCapturable() WARN_UNUSED_RESULT;
+  [[nodiscard]] ScopedWindowCaptureRequest MakeWindowCapturable();
   const viz::SubtreeCaptureId& subtree_capture_id() const {
     return subtree_capture_id_;
   }
diff --git a/ui/aura/window_event_dispatcher.h b/ui/aura/window_event_dispatcher.h
index 1c3b3676..bff3906e 100644
--- a/ui/aura/window_event_dispatcher.h
+++ b/ui/aura/window_event_dispatcher.h
@@ -10,7 +10,6 @@
 #include <vector>
 
 #include "base/callback.h"
-#include "base/compiler_specific.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted.h"
@@ -93,10 +92,10 @@
   // If the |target| is NULL, we will dispatch the event to the root-window.
   // |event_flags| will be set on the dispatched exit event.
   // TODO(beng): needed only for WTH::OnCursorVisibilityChanged().
-  ui::EventDispatchDetails DispatchMouseExitAtPoint(
+  [[nodiscard]] ui::EventDispatchDetails DispatchMouseExitAtPoint(
       Window* target,
       const gfx::Point& point,
-      int event_flags = ui::EF_NONE) WARN_UNUSED_RESULT;
+      int event_flags = ui::EF_NONE);
 
   // Gesture Recognition -------------------------------------------------------
 
@@ -196,13 +195,13 @@
   // |mouse_moved_handler_|.
   // The event's location will be converted from |target|coordinate system to
   // |mouse_moved_handler_| coordinate system.
-  ui::EventDispatchDetails DispatchMouseEnterOrExit(Window* target,
-                                                    const ui::MouseEvent& event,
-                                                    ui::EventType type)
-      WARN_UNUSED_RESULT;
-  ui::EventDispatchDetails ProcessGestures(
+  [[nodiscard]] ui::EventDispatchDetails DispatchMouseEnterOrExit(
       Window* target,
-      ui::GestureRecognizer::Gestures gestures) WARN_UNUSED_RESULT;
+      const ui::MouseEvent& event,
+      ui::EventType type);
+  [[nodiscard]] ui::EventDispatchDetails ProcessGestures(
+      Window* target,
+      ui::GestureRecognizer::Gestures gestures);
 
   // Called when a window becomes invisible, either by being removed
   // from root window hierarchy, via SetVisible(false) or being destroyed.
@@ -265,7 +264,7 @@
   // ReleaseMouseMoves()/ReleaseTouchMoves() is called.  NOTE: because these
   // methods dispatch events from WindowTreeHost the coordinates are in terms of
   // the root.
-  ui::EventDispatchDetails DispatchHeldEvents() WARN_UNUSED_RESULT;
+  [[nodiscard]] ui::EventDispatchDetails DispatchHeldEvents();
 
   // Posts a task to send synthesized mouse move event if there is no a pending
   // task.
@@ -273,7 +272,7 @@
 
   // Creates and dispatches synthesized mouse move event using the current mouse
   // location.
-  ui::EventDispatchDetails SynthesizeMouseMoveEvent() WARN_UNUSED_RESULT;
+  [[nodiscard]] ui::EventDispatchDetails SynthesizeMouseMoveEvent();
 
   // Calls SynthesizeMouseMove() if |window| is currently visible and contains
   // the mouse cursor.
diff --git a/ui/base/ime/ash/input_method_ash.h b/ui/base/ime/ash/input_method_ash.h
index ed32781..aa7c7ef 100644
--- a/ui/base/ime/ash/input_method_ash.h
+++ b/ui/base/ime/ash/input_method_ash.h
@@ -11,7 +11,6 @@
 #include <set>
 
 #include "base/callback_forward.h"
-#include "base/compiler_specific.h"
 #include "base/component_export.h"
 #include "base/memory/weak_ptr.h"
 #include "ui/base/ime/ash/ime_input_context_handler_interface.h"
@@ -92,10 +91,10 @@
                                          uint32_t cursor_position) const;
 
   // Process a key returned from the input method.
-  virtual ui::EventDispatchDetails ProcessKeyEventPostIME(
+  [[nodiscard]] virtual ui::EventDispatchDetails ProcessKeyEventPostIME(
       ui::KeyEvent* event,
       bool handled,
-      bool stopped_propagation) WARN_UNUSED_RESULT;
+      bool stopped_propagation);
 
   // Resets context and abandon all pending results and key events.
   // If |reset_engine| is true, a reset signal will be sent to the IME.
@@ -132,12 +131,12 @@
   // A VKEY_PROCESSKEY may be dispatched to the EventTargets.
   // It returns the result of whether the event has been stopped propagation
   // when dispatching post IME.
-  ui::EventDispatchDetails ProcessFilteredKeyPressEvent(ui::KeyEvent* event)
-      WARN_UNUSED_RESULT;
+  [[nodiscard]] ui::EventDispatchDetails ProcessFilteredKeyPressEvent(
+      ui::KeyEvent* event);
 
   // Processes a key event that was not filtered by the input method.
-  ui::EventDispatchDetails ProcessUnfilteredKeyPressEvent(ui::KeyEvent* event)
-      WARN_UNUSED_RESULT;
+  [[nodiscard]] ui::EventDispatchDetails ProcessUnfilteredKeyPressEvent(
+      ui::KeyEvent* event);
 
   // Processes any pending input method operations that issued while handling
   // the key event. Does not do anything if there were no pending operations.
diff --git a/ui/base/ime/input_method.h b/ui/base/ime/input_method.h
index 049faad..a61940e 100644
--- a/ui/base/ime/input_method.h
+++ b/ui/base/ime/input_method.h
@@ -7,7 +7,6 @@
 
 #include <stdint.h>
 
-#include "base/compiler_specific.h"
 #include "build/build_config.h"
 #include "ui/base/ime/text_input_mode.h"
 #include "ui/base/ime/text_input_type.h"
@@ -109,8 +108,8 @@
   // dispatched back to the caller via
   // ui::InputMethodDelegate::DispatchKeyEventPostIME(), once it's processed by
   // the input method. It should only be called by a message dispatcher.
-  virtual ui::EventDispatchDetails DispatchKeyEvent(ui::KeyEvent* event)
-      WARN_UNUSED_RESULT = 0;
+  [[nodiscard]] virtual ui::EventDispatchDetails DispatchKeyEvent(
+      ui::KeyEvent* event) = 0;
 
   // Called by the focused client whenever its text input type is changed.
   // Before calling this method, the focused client must confirm or clear
diff --git a/ui/base/ime/input_method_base.h b/ui/base/ime/input_method_base.h
index a14c072..bb3afe0 100644
--- a/ui/base/ime/input_method_base.h
+++ b/ui/base/ime/input_method_base.h
@@ -8,7 +8,6 @@
 #include <memory>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/component_export.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
@@ -96,8 +95,8 @@
   // input type is not TEXT_INPUT_TYPE_NONE.
   void OnInputMethodChanged() const;
 
-  virtual ui::EventDispatchDetails DispatchKeyEventPostIME(
-      ui::KeyEvent* event) const WARN_UNUSED_RESULT;
+  [[nodiscard]] virtual ui::EventDispatchDetails DispatchKeyEventPostIME(
+      ui::KeyEvent* event) const;
 
   // Convenience method to notify all observers of TextInputClient changes.
   void NotifyTextInputStateChanged(const TextInputClient* client);
diff --git a/ui/base/ime/linux/input_method_auralinux.h b/ui/base/ime/linux/input_method_auralinux.h
index 7296797..8538640 100644
--- a/ui/base/ime/linux/input_method_auralinux.h
+++ b/ui/base/ime/linux/input_method_auralinux.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "base/component_export.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/base/ime/composition_text.h"
@@ -76,8 +75,8 @@
   void ConfirmCompositionText();
   bool HasInputMethodResult();
   bool NeedInsertChar(const std::u16string& result_text) const;
-  ui::EventDispatchDetails SendFakeProcessKeyEvent(ui::KeyEvent* event) const
-      WARN_UNUSED_RESULT;
+  [[nodiscard]] ui::EventDispatchDetails SendFakeProcessKeyEvent(
+      ui::KeyEvent* event) const;
   void UpdateContextFocusState();
   void ResetContext();
   bool IgnoringNonKeyInput() const;
diff --git a/ui/base/metadata/metadata_types.h b/ui/base/metadata/metadata_types.h
index 2c2a5de..207983d 100644
--- a/ui/base/metadata/metadata_types.h
+++ b/ui/base/metadata/metadata_types.h
@@ -12,7 +12,6 @@
 
 #include "base/callback.h"
 #include "base/callback_list.h"
-#include "base/compiler_specific.h"
 #include "base/component_export.h"
 #include "base/memory/raw_ptr.h"
 
@@ -60,9 +59,9 @@
   virtual class ClassMetaData* GetClassMetaData() = 0;
 
  protected:
-  base::CallbackListSubscription AddPropertyChangedCallback(
+  [[nodiscard]] base::CallbackListSubscription AddPropertyChangedCallback(
       PropertyKey property,
-      PropertyChangedCallback callback) WARN_UNUSED_RESULT;
+      PropertyChangedCallback callback);
   void TriggerChangedCallback(PropertyKey property);
 
  private:
diff --git a/ui/base/metadata/metadata_unittest.cc b/ui/base/metadata/metadata_unittest.cc
index a987df4..8e67cb3e 100644
--- a/ui/base/metadata/metadata_unittest.cc
+++ b/ui/base/metadata/metadata_unittest.cc
@@ -59,8 +59,8 @@
     TriggerChangedCallback(&int_property_);
   }
   int GetIntProperty() const { return int_property_; }
-  base::CallbackListSubscription AddIntPropertyChangedCallback(
-      ui::metadata::PropertyChangedCallback callback) WARN_UNUSED_RESULT {
+  [[nodiscard]] base::CallbackListSubscription AddIntPropertyChangedCallback(
+      ui::metadata::PropertyChangedCallback callback) {
     return AddPropertyChangedCallback(&int_property_, std::move(callback));
   }
 
@@ -88,8 +88,8 @@
     TriggerChangedCallback(&float_property_);
   }
   float GetFloatProperty() const { return float_property_; }
-  base::CallbackListSubscription AddFloatPropertyChangedCallback(
-      ui::metadata::PropertyChangedCallback callback) WARN_UNUSED_RESULT {
+  [[nodiscard]] base::CallbackListSubscription AddFloatPropertyChangedCallback(
+      ui::metadata::PropertyChangedCallback callback) {
     return AddPropertyChangedCallback(&float_property_, std::move(callback));
   }
 
diff --git a/ui/base/models/dialog_model.h b/ui/base/models/dialog_model.h
index 1b5bb3d2..5ebca6b 100644
--- a/ui/base/models/dialog_model.h
+++ b/ui/base/models/dialog_model.h
@@ -9,7 +9,6 @@
 #include <string>
 
 #include "base/callback.h"
-#include "base/compiler_specific.h"
 #include "base/component_export.h"
 #include "base/memory/raw_ptr.h"
 #include "base/types/pass_key.h"
@@ -101,7 +100,7 @@
 
     ~Builder();
 
-    std::unique_ptr<DialogModel> Build() WARN_UNUSED_RESULT;
+    [[nodiscard]] std::unique_ptr<DialogModel> Build();
 
     // Gets the DialogModel. Used for setting up callbacks that make use of the
     // model later once it's fully constructed. This is useful for dialogs or
diff --git a/ui/compositor/layer.h b/ui/compositor/layer.h
index aea9f221..6cca88b0 100644
--- a/ui/compositor/layer.h
+++ b/ui/compositor/layer.h
@@ -12,7 +12,6 @@
 #include <string>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
@@ -613,7 +612,7 @@
   // animations handled by old cc layer before the switch, |this| could be
   // released by an animation observer. Returns false when it happens and
   // callers should take cautions as well. Otherwise returns true.
-  bool SwitchToLayer(scoped_refptr<cc::Layer> new_layer) WARN_UNUSED_RESULT;
+  [[nodiscard]] bool SwitchToLayer(scoped_refptr<cc::Layer> new_layer);
 
   void SetCompositorForAnimatorsInTree(Compositor* compositor);
   void ResetCompositorForAnimatorsInTree(Compositor* compositor);
diff --git a/ui/compositor/layer_animator.h b/ui/compositor/layer_animator.h
index 70e7ba63..57655689 100644
--- a/ui/compositor/layer_animator.h
+++ b/ui/compositor/layer_animator.h
@@ -9,7 +9,6 @@
 
 #include "base/callback.h"
 #include "base/callback_list.h"
-#include "base/compiler_specific.h"
 #include "base/containers/circular_deque.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/raw_ptr.h"
@@ -228,8 +227,8 @@
   // Caller must retain the result for as long as the callback needs to remain
   // active. Clearing the result (add_sequence_subscription.reset()) will also
   // remove the subscription.
-  base::CallbackListSubscription AddSequenceScheduledCallback(
-      SequenceScheduledCallback callback) WARN_UNUSED_RESULT;
+  [[nodiscard]] base::CallbackListSubscription AddSequenceScheduledCallback(
+      SequenceScheduledCallback callback);
 
   // Called when a threaded animation is actually started.
   void OnThreadedAnimationStarted(base::TimeTicks monotonic_time,
@@ -310,8 +309,8 @@
   // Removes the sequences from both the running animations and the queue.
   // Returns a pointer to the removed animation, if any. NOTE: the caller is
   // responsible for deleting the returned pointer.
-  LayerAnimationSequence* RemoveAnimation(
-      LayerAnimationSequence* sequence) WARN_UNUSED_RESULT;
+  [[nodiscard]] LayerAnimationSequence* RemoveAnimation(
+      LayerAnimationSequence* sequence);
 
   // Progresses to the end of the sequence before removing it.
   void FinishAnimation(LayerAnimationSequence* sequence, bool abort);
diff --git a/ui/compositor/layer_tree_owner.h b/ui/compositor/layer_tree_owner.h
index 6fcbb12..876f1fcc 100644
--- a/ui/compositor/layer_tree_owner.h
+++ b/ui/compositor/layer_tree_owner.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "ui/compositor/compositor_export.h"
 
@@ -25,7 +24,7 @@
 
   ~LayerTreeOwner();
 
-  Layer* release() WARN_UNUSED_RESULT {
+  [[nodiscard]] Layer* release() {
     Layer* root = root_;
     root_ = nullptr;
     return root;
diff --git a/ui/compositor/test/in_process_context_provider.h b/ui/compositor/test/in_process_context_provider.h
index 959d77a..fb06159 100644
--- a/ui/compositor/test/in_process_context_provider.h
+++ b/ui/compositor/test/in_process_context_provider.h
@@ -108,7 +108,7 @@
   std::unique_ptr<gpu::raster::RasterInterface> raster_context_;
   std::unique_ptr<viz::ContextCacheController> cache_controller_;
 
-  const bool support_locking_ ALLOW_UNUSED_TYPE;
+  [[maybe_unused]] const bool support_locking_;
   bool bind_tried_ = false;
   gpu::ContextResult bind_result_;
 
diff --git a/ui/compositor/test/test_utils.h b/ui/compositor/test/test_utils.h
index 508f27f..c11b992 100644
--- a/ui/compositor/test/test_utils.h
+++ b/ui/compositor/test/test_utils.h
@@ -5,7 +5,6 @@
 #ifndef UI_COMPOSITOR_TEST_TEST_UTILS_H_
 #define UI_COMPOSITOR_TEST_TEST_UTILS_H_
 
-#include "base/compiler_specific.h"
 #include "base/time/time.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
@@ -27,9 +26,9 @@
 
 // Runs a RunLoop until the next frame is presented with an optional timeout.
 // Returns true if a frame is presented. Otherwise, returns false.
-bool WaitForNextFrameToBePresented(
+[[nodiscard]] bool WaitForNextFrameToBePresented(
     ui::Compositor* compositor,
-    absl::optional<base::TimeDelta> timeout = absl::nullopt) WARN_UNUSED_RESULT;
+    absl::optional<base::TimeDelta> timeout = absl::nullopt);
 
 }  // namespace ui
 
diff --git a/ui/display/manager/display_configurator.h b/ui/display/manager/display_configurator.h
index ade51d99..5268934 100644
--- a/ui/display/manager/display_configurator.h
+++ b/ui/display/manager/display_configurator.h
@@ -9,7 +9,6 @@
 #include <memory>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
 #include "base/timer/timer.h"
@@ -119,7 +118,7 @@
 
     // If |configure_timer_| is started, stops the timer, runs
     // ConfigureDisplays(), and returns true; returns false otherwise.
-    bool TriggerConfigureTimeout() WARN_UNUSED_RESULT;
+    [[nodiscard]] bool TriggerConfigureTimeout();
 
     // Gets the current delay of the |configure_timer_| if it's running, or zero
     // time delta otherwise.
diff --git a/ui/display/manager/display_configurator_unittest.cc b/ui/display/manager/display_configurator_unittest.cc
index 4dece1d..1a20db9 100644
--- a/ui/display/manager/display_configurator_unittest.cc
+++ b/ui/display/manager/display_configurator_unittest.cc
@@ -201,7 +201,7 @@
   // runs it and returns base::TimeDelta(). Otherwise, triggers the
   // configuration timer and returns its delay. If the timer wasn't running,
   // returns base::TimeDelta::Max().
-  base::TimeDelta Wait() WARN_UNUSED_RESULT {
+  [[nodiscard]] base::TimeDelta Wait() {
     base::RunLoop().RunUntilIdle();
     if (callback_result_ != CALLBACK_NOT_CALLED)
       return base::TimeDelta();
diff --git a/ui/events/event_dispatcher.h b/ui/events/event_dispatcher.h
index 9141d12..a4dbc23 100644
--- a/ui/events/event_dispatcher.h
+++ b/ui/events/event_dispatcher.h
@@ -6,7 +6,6 @@
 #define UI_EVENTS_EVENT_DISPATCHER_H_
 
 #include "base/auto_reset.h"
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "ui/events/event.h"
 #include "ui/events/event_constants.h"
@@ -47,27 +46,27 @@
   // Dispatches |event| to |target|. This calls |PreDispatchEvent()| before
   // dispatching the event, and |PostDispatchEvent()| after the event has been
   // dispatched.
-  EventDispatchDetails DispatchEvent(EventTarget* target, Event* event)
-      WARN_UNUSED_RESULT;
+  [[nodiscard]] EventDispatchDetails DispatchEvent(EventTarget* target,
+                                                   Event* event);
 
  protected:
   // This is called once a target has been determined for an event, right before
   // the event is dispatched to the target. This function may modify |event| to
   // prepare it for dispatch (e.g. update event flags, location etc.).
-  virtual EventDispatchDetails PreDispatchEvent(
+  [[nodiscard]] virtual EventDispatchDetails PreDispatchEvent(
       EventTarget* target,
-      Event* event) WARN_UNUSED_RESULT;
+      Event* event);
 
   // This is called right after the event dispatch is completed.
   // |target| is NULL if the target was deleted during dispatch.
-  virtual EventDispatchDetails PostDispatchEvent(
+  [[nodiscard]] virtual EventDispatchDetails PostDispatchEvent(
       EventTarget* target,
-      const Event& event) WARN_UNUSED_RESULT;
+      const Event& event);
 
  private:
   // Dispatches the event to the target.
-  EventDispatchDetails DispatchEventToTarget(EventTarget* target,
-                                             Event* event) WARN_UNUSED_RESULT;
+  [[nodiscard]] EventDispatchDetails DispatchEventToTarget(EventTarget* target,
+                                                           Event* event);
 
   raw_ptr<EventDispatcher> dispatcher_;
 };
diff --git a/ui/events/event_rewriter.h b/ui/events/event_rewriter.h
index f538f3e1..d2a4d6e 100644
--- a/ui/events/event_rewriter.h
+++ b/ui/events/event_rewriter.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "base/memory/weak_ptr.h"
 #include "ui/events/event_dispatcher.h"
 #include "ui/events/events_export.h"
@@ -147,17 +146,18 @@
 
  protected:
   // Forwards an event, through any subsequent rewriters.
-  static EventDispatchDetails SendEvent(const Continuation continuation,
-                                        const Event* event) WARN_UNUSED_RESULT;
+  [[nodiscard]] static EventDispatchDetails SendEvent(
+      const Continuation continuation,
+      const Event* event);
 
   // Forwards an event, skipping any subsequent rewriters.
-  static EventDispatchDetails SendEventFinally(const Continuation continuation,
-                                               const Event* event)
-      WARN_UNUSED_RESULT;
+  [[nodiscard]] static EventDispatchDetails SendEventFinally(
+      const Continuation continuation,
+      const Event* event);
 
   // Discards an event, so that it will not be passed to the sink.
-  static EventDispatchDetails DiscardEvent(const Continuation continuation)
-      WARN_UNUSED_RESULT;
+  [[nodiscard]] static EventDispatchDetails DiscardEvent(
+      const Continuation continuation);
 
   // A helper that calls a protected EventSource function, which sends the event
   // to subsequent event rewriters on the source and onto its event sink.
diff --git a/ui/events/event_rewriter_continuation.h b/ui/events/event_rewriter_continuation.h
index 96fa2ae..61ac11b 100644
--- a/ui/events/event_rewriter_continuation.h
+++ b/ui/events/event_rewriter_continuation.h
@@ -5,8 +5,6 @@
 #ifndef UI_EVENTS_EVENT_REWRITER_CONTINUATION_H_
 #define UI_EVENTS_EVENT_REWRITER_CONTINUATION_H_
 
-#include "base/compiler_specific.h"
-
 namespace ui {
 
 struct EventDispatchDetails;
@@ -21,15 +19,14 @@
   virtual ~EventRewriterContinuation() = default;
 
   // Send an event to the sink, via any later rewriters.
-  virtual EventDispatchDetails SendEvent(const Event* event)
-      WARN_UNUSED_RESULT = 0;
+  [[nodiscard]] virtual EventDispatchDetails SendEvent(const Event* event) = 0;
 
   // Send an event directly to the sink, bypassing any later rewriters.
-  virtual EventDispatchDetails SendEventFinally(const Event* event)
-      WARN_UNUSED_RESULT = 0;
+  [[nodiscard]] virtual EventDispatchDetails SendEventFinally(
+      const Event* event) = 0;
 
   // Discard an event, bypassing any later rewriters.
-  virtual EventDispatchDetails DiscardEvent() WARN_UNUSED_RESULT = 0;
+  [[nodiscard]] virtual EventDispatchDetails DiscardEvent() = 0;
 };
 
 }  // namespace ui
diff --git a/ui/events/event_sink.h b/ui/events/event_sink.h
index df8c028..af7e514 100644
--- a/ui/events/event_sink.h
+++ b/ui/events/event_sink.h
@@ -5,7 +5,6 @@
 #ifndef UI_EVENTS_EVENT_SINK_H_
 #define UI_EVENTS_EVENT_SINK_H_
 
-#include "base/compiler_specific.h"
 #include "ui/events/event_dispatcher.h"
 
 namespace ui {
@@ -18,8 +17,8 @@
   virtual ~EventSink() {}
 
   // Receives events from EventSource.
-  virtual EventDispatchDetails OnEventFromSource(Event* event)
-      WARN_UNUSED_RESULT = 0;
+  [[nodiscard]] virtual EventDispatchDetails OnEventFromSource(
+      Event* event) = 0;
 };
 
 }  // namespace ui
diff --git a/ui/events/gesture_detection/filtered_gesture_provider.h b/ui/events/gesture_detection/filtered_gesture_provider.h
index 8cb708d..7ccfda9 100644
--- a/ui/events/gesture_detection/filtered_gesture_provider.h
+++ b/ui/events/gesture_detection/filtered_gesture_provider.h
@@ -8,7 +8,6 @@
 #include <stdint.h>
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "ui/events/gesture_detection/gesture_event_data_packet.h"
 #include "ui/events/gesture_detection/gesture_provider.h"
@@ -45,7 +44,7 @@
     // Whether |event| occurred beyond the touch slop region.
     bool moved_beyond_slop_region;
   };
-  TouchHandlingResult OnTouchEvent(const MotionEvent& event) WARN_UNUSED_RESULT;
+  [[nodiscard]] TouchHandlingResult OnTouchEvent(const MotionEvent& event);
 
   // To be called upon asynchronous and synchronous ack of an event that was
   // forwarded after a successful call to |OnTouchEvent()|.
diff --git a/ui/events/keycodes/keyboard_code_conversion.h b/ui/events/keycodes/keyboard_code_conversion.h
index 7efa5bf..64f333f 100644
--- a/ui/events/keycodes/keyboard_code_conversion.h
+++ b/ui/events/keycodes/keyboard_code_conversion.h
@@ -5,8 +5,6 @@
 #ifndef UI_EVENTS_KEYCODES_KEYBOARD_CODE_CONVERSION_H_
 #define UI_EVENTS_KEYCODES_KEYBOARD_CODE_CONVERSION_H_
 
-
-#include "base/compiler_specific.h"
 #include "ui/events/events_base_export.h"
 #include "ui/events/keycodes/dom/dom_key.h"
 #include "ui/events/keycodes/keyboard_codes.h"
@@ -42,21 +40,21 @@
 // parameters are untouched.
 EVENTS_BASE_EXPORT char16_t DomCodeToUsLayoutCharacter(DomCode dom_code,
                                                        int flags);
-EVENTS_BASE_EXPORT bool DomCodeToUsLayoutDomKey(DomCode dom_code,
-                                                int flags,
-                                                DomKey* dom_key,
-                                                KeyboardCode* key_code)
-    WARN_UNUSED_RESULT;
+[[nodiscard]] EVENTS_BASE_EXPORT bool DomCodeToUsLayoutDomKey(
+    DomCode dom_code,
+    int flags,
+    DomKey* dom_key,
+    KeyboardCode* key_code);
 
 // Helper function to map a physical key (dom_code) to a meaning (dom_key
 // and character, together corresponding to the DOM keyboard event |key|
 // value), along with a corresponding non-located Windows-based key_code.
 // Unlike |DomCodeToUsLayoutDomKey| this function only maps non-printable,
 // or action, keys.
-EVENTS_BASE_EXPORT bool DomCodeToNonPrintableDomKey(DomCode dom_code,
-                                                    DomKey* dom_key,
-                                                    KeyboardCode* key_code)
-    WARN_UNUSED_RESULT;
+[[nodiscard]] EVENTS_BASE_EXPORT bool DomCodeToNonPrintableDomKey(
+    DomCode dom_code,
+    DomKey* dom_key,
+    KeyboardCode* key_code);
 
 // Obtains the control character corresponding to a physical key;
 // that is, the meaning of the physical key state (dom_code, and flags
@@ -64,11 +62,11 @@
 // Returns true and sets the output parameters if the (dom_code, flags) pair
 // is interpreted as a control character; otherwise the output parameters
 // are untouched.
-EVENTS_BASE_EXPORT bool DomCodeToControlCharacter(DomCode dom_code,
-                                                  int flags,
-                                                  DomKey* dom_key,
-                                                  KeyboardCode* key_code)
-    WARN_UNUSED_RESULT;
+[[nodiscard]] EVENTS_BASE_EXPORT bool DomCodeToControlCharacter(
+    DomCode dom_code,
+    int flags,
+    DomKey* dom_key,
+    KeyboardCode* key_code);
 
 // Returns a Windows-based VKEY for a non-printable DOM Level 3 |key|.
 // The returned VKEY is non-located (e.g. VKEY_SHIFT).
diff --git a/ui/events/test/events_test_utils.h b/ui/events/test/events_test_utils.h
index 47ef2f6e..824a57a 100644
--- a/ui/events/test/events_test_utils.h
+++ b/ui/events/test/events_test_utils.h
@@ -5,7 +5,6 @@
 #ifndef UI_EVENTS_TEST_EVENTS_TEST_UTILS_H_
 #define UI_EVENTS_TEST_EVENTS_TEST_UTILS_H_
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "ui/events/event.h"
 #include "ui/events/event_dispatcher.h"
@@ -108,7 +107,7 @@
   EventSourceTestApi(const EventSourceTestApi&) = delete;
   EventSourceTestApi& operator=(const EventSourceTestApi&) = delete;
 
-  EventDispatchDetails SendEventToSink(Event* event) WARN_UNUSED_RESULT;
+  [[nodiscard]] EventDispatchDetails SendEventToSink(Event* event);
 
  private:
   EventSourceTestApi();
diff --git a/ui/gfx/buffer_format_util.h b/ui/gfx/buffer_format_util.h
index 362b3d77..702ef5b 100644
--- a/ui/gfx/buffer_format_util.h
+++ b/ui/gfx/buffer_format_util.h
@@ -9,7 +9,6 @@
 
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "ui/gfx/buffer_types.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/gfx_export.h"
@@ -35,19 +34,19 @@
 GFX_EXPORT size_t RowSizeForBufferFormat(size_t width,
                                          BufferFormat format,
                                          size_t plane);
-GFX_EXPORT bool RowSizeForBufferFormatChecked(size_t width,
-                                              BufferFormat format,
-                                              size_t plane,
-                                              size_t* size_in_bytes)
-    WARN_UNUSED_RESULT;
+[[nodiscard]] GFX_EXPORT bool RowSizeForBufferFormatChecked(
+    size_t width,
+    BufferFormat format,
+    size_t plane,
+    size_t* size_in_bytes);
 
 // Returns the number of bytes used to store all the planes of a given |format|.
 GFX_EXPORT size_t BufferSizeForBufferFormat(const Size& size,
                                             BufferFormat format);
-GFX_EXPORT bool BufferSizeForBufferFormatChecked(const Size& size,
-                                                 BufferFormat format,
-                                                 size_t* size_in_bytes)
-    WARN_UNUSED_RESULT;
+[[nodiscard]] GFX_EXPORT bool BufferSizeForBufferFormatChecked(
+    const Size& size,
+    BufferFormat format,
+    size_t* size_in_bytes);
 
 GFX_EXPORT size_t BufferOffsetForBufferFormat(const Size& size,
                                            BufferFormat format,
diff --git a/ui/gfx/geometry/transform.h b/ui/gfx/geometry/transform.h
index e0df4d6..70b05212 100644
--- a/ui/gfx/geometry/transform.h
+++ b/ui/gfx/geometry/transform.h
@@ -8,7 +8,6 @@
 #include <iosfwd>
 #include <string>
 
-#include "base/compiler_specific.h"
 #include "skia/ext/skia_matrix_44.h"
 #include "third_party/skia/include/core/SkM44.h"
 #include "ui/gfx/geometry/geometry_skia_export.h"
@@ -193,7 +192,7 @@
 
   // Inverts the transform which is passed in. Returns true if successful, or
   // sets |transform| to the identify matrix on failure.
-  bool GetInverse(Transform* transform) const WARN_UNUSED_RESULT;
+  [[nodiscard]] bool GetInverse(Transform* transform) const;
 
   // Transposes this transform in place.
   void Transpose();
diff --git a/ui/gfx/ios/uikit_util.h b/ui/gfx/ios/uikit_util.h
index fbacda3d..0bc6ffc 100644
--- a/ui/gfx/ios/uikit_util.h
+++ b/ui/gfx/ios/uikit_util.h
@@ -7,19 +7,17 @@
 
 #import <UIKit/UIKit.h>
 
-#include "base/compiler_specific.h"
-
 // UI Util containing functions that require UIKit.
 
 namespace ui {
 
 // Returns the closest pixel-aligned value higher than |value|, taking the scale
 // factor into account. At a scale of 1, equivalent to ceil().
-CGFloat AlignValueToUpperPixel(CGFloat value) WARN_UNUSED_RESULT;
+[[nodiscard]] CGFloat AlignValueToUpperPixel(CGFloat value);
 
 // Returns the size resulting from applying AlignToUpperPixel to both
 // components.
-CGSize AlignSizeToUpperPixel(CGSize size) WARN_UNUSED_RESULT;
+[[nodiscard]] CGSize AlignSizeToUpperPixel(CGSize size);
 
 } // namespace ui
 
diff --git a/ui/gl/generate_bindings.py b/ui/gl/generate_bindings.py
index e9d6bf9..893553f 100755
--- a/ui/gl/generate_bindings.py
+++ b/ui/gl/generate_bindings.py
@@ -3358,16 +3358,16 @@
     file.write("""\
 void DriverEGL::InitializeClientExtensionBindings() {
   std::string client_extensions(GetClientExtensions());
-  gfx::ExtensionSet extensions(gfx::MakeExtensionSet(client_extensions));
-  ALLOW_UNUSED_LOCAL(extensions);
+  [[maybe_unused]] gfx::ExtensionSet extensions(
+      gfx::MakeExtensionSet(client_extensions));
 
 """)
   else:
     file.write("""\
 void Driver%s::InitializeExtensionBindings() {
   std::string platform_extensions(GetPlatformExtensions());
-  gfx::ExtensionSet extensions(gfx::MakeExtensionSet(platform_extensions));
-  ALLOW_UNUSED_LOCAL(extensions);
+  [[maybe_unused]] gfx::ExtensionSet extensions(
+      gfx::MakeExtensionSet(platform_extensions));
 
 """ % (set_name.upper(),))
 
@@ -3394,8 +3394,8 @@
 
 void DriverEGL::InitializeExtensionBindings() {
   std::string platform_extensions(GetPlatformExtensions());
-  gfx::ExtensionSet extensions(gfx::MakeExtensionSet(platform_extensions));
-  ALLOW_UNUSED_LOCAL(extensions);
+  [[maybe_unused]] gfx::ExtensionSet extensions(
+      gfx::MakeExtensionSet(platform_extensions));
 
 """)
 
diff --git a/ui/gl/gl_bindings_autogen_egl.cc b/ui/gl/gl_bindings_autogen_egl.cc
index 748eed9..f0631b2 100644
--- a/ui/gl/gl_bindings_autogen_egl.cc
+++ b/ui/gl/gl_bindings_autogen_egl.cc
@@ -114,8 +114,8 @@
 
 void DriverEGL::InitializeClientExtensionBindings() {
   std::string client_extensions(GetClientExtensions());
-  gfx::ExtensionSet extensions(gfx::MakeExtensionSet(client_extensions));
-  ALLOW_UNUSED_LOCAL(extensions);
+  [[maybe_unused]] gfx::ExtensionSet extensions(
+      gfx::MakeExtensionSet(client_extensions));
 
   ext.b_EGL_ANGLE_feature_control =
       gfx::HasExtension(extensions, "EGL_ANGLE_feature_control");
@@ -180,8 +180,8 @@
 
 void DriverEGL::InitializeExtensionBindings() {
   std::string platform_extensions(GetPlatformExtensions());
-  gfx::ExtensionSet extensions(gfx::MakeExtensionSet(platform_extensions));
-  ALLOW_UNUSED_LOCAL(extensions);
+  [[maybe_unused]] gfx::ExtensionSet extensions(
+      gfx::MakeExtensionSet(platform_extensions));
 
   ext.b_EGL_ANDROID_blob_cache =
       gfx::HasExtension(extensions, "EGL_ANDROID_blob_cache");
diff --git a/ui/gl/gl_bindings_autogen_glx.cc b/ui/gl/gl_bindings_autogen_glx.cc
index 22dbef7..032d699 100644
--- a/ui/gl/gl_bindings_autogen_glx.cc
+++ b/ui/gl/gl_bindings_autogen_glx.cc
@@ -110,8 +110,8 @@
 
 void DriverGLX::InitializeExtensionBindings() {
   std::string platform_extensions(GetPlatformExtensions());
-  gfx::ExtensionSet extensions(gfx::MakeExtensionSet(platform_extensions));
-  ALLOW_UNUSED_LOCAL(extensions);
+  [[maybe_unused]] gfx::ExtensionSet extensions(
+      gfx::MakeExtensionSet(platform_extensions));
 
   ext.b_GLX_ARB_create_context =
       gfx::HasExtension(extensions, "GLX_ARB_create_context");
diff --git a/ui/gtk/BUILD.gn b/ui/gtk/BUILD.gn
index 6cf6871..6ff9557 100644
--- a/ui/gtk/BUILD.gn
+++ b/ui/gtk/BUILD.gn
@@ -14,6 +14,7 @@
 
 assert(is_linux || is_chromeos_lacros || is_chromeos,
        "This file should only be referenced on Linux")
+assert(use_gio, "GIO is required for building with GTK")
 
 source_set("gtk_types") {
   visibility = [ ":gtk_stubs" ]
@@ -101,20 +102,18 @@
     "select_file_dialog_impl_portal.cc",
     "select_file_dialog_impl_portal.h",
     "settings_provider.h",
+    "settings_provider_gsettings.cc",
+    "settings_provider_gsettings.h",
     "settings_provider_gtk.cc",
     "settings_provider_gtk.h",
     "window_frame_provider_gtk.cc",
     "window_frame_provider_gtk.h",
   ]
   defines = [ "IS_GTK_IMPL" ]
-  configs += [ "//build/config/linux/pangocairo" ]
-  if (use_gio) {
-    sources += [
-      "settings_provider_gsettings.cc",
-      "settings_provider_gsettings.h",
-    ]
-    configs += [ "//build/linux:gio_config" ]
-  }
+  configs += [
+    "//build/config/linux/pangocairo",
+    "//build/linux:gio_config",
+  ]
 
   deps = [
     ":gtk_stubs",
diff --git a/ui/ozone/platform/wayland/common/wayland_object.h b/ui/ozone/platform/wayland/common/wayland_object.h
index da91ffb..8f5fe01 100644
--- a/ui/ozone/platform/wayland/common/wayland_object.h
+++ b/ui/ozone/platform/wayland/common/wayland_object.h
@@ -8,7 +8,6 @@
 #include <memory>
 
 #include "base/check.h"
-#include "base/compiler_specific.h"
 #include "ui/ozone/platform/wayland/common/wayland.h"
 
 struct wl_proxy;
@@ -41,8 +40,7 @@
 class GlobalObjectRegistrar {
  public:
   GlobalObjectRegistrar() {
-    GlobalObjectFactory Instantiate = T::Instantiate;
-    ALLOW_UNUSED_LOCAL(Instantiate);
+    [[maybe_unused]] GlobalObjectFactory Instantiate = T::Instantiate;
   }
 };
 
diff --git a/ui/ozone/platform/wayland/host/wayland_buffer_manager_host.cc b/ui/ozone/platform/wayland/host/wayland_buffer_manager_host.cc
index 5ab8748..ac234f89 100644
--- a/ui/ozone/platform/wayland/host/wayland_buffer_manager_host.cc
+++ b/ui/ozone/platform/wayland/host/wayland_buffer_manager_host.cc
@@ -279,11 +279,11 @@
   window->CommitOverlays(overlays);
 }
 
-void WaylandBufferManagerHost::DestroyBuffer(gfx::AcceleratedWidget widget,
-                                             uint32_t buffer_id) {
+void WaylandBufferManagerHost::DestroyBuffer(
+    [[maybe_unused]] gfx::AcceleratedWidget widget,
+    uint32_t buffer_id) {
   // TODO(fangzhoug): Remove |widget| from the argument list of the mojo
   // interface.
-  ALLOW_UNUSED_LOCAL(widget);
   DCHECK(base::CurrentUIThread::IsSet());
 
   TRACE_EVENT1("wayland", "WaylandBufferManagerHost::DestroyBuffer",
diff --git a/ui/shell_dialogs/fake_select_file_dialog.h b/ui/shell_dialogs/fake_select_file_dialog.h
index b538be1..474a0c5 100644
--- a/ui/shell_dialogs/fake_select_file_dialog.h
+++ b/ui/shell_dialogs/fake_select_file_dialog.h
@@ -8,7 +8,6 @@
 #include <string>
 
 #include "base/callback.h"
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/strings/string_piece.h"
@@ -90,8 +89,8 @@
 
   // Calls the |FileSelected()| method on listener(). |filter_text| selects
   // which file extension filter to report.
-  bool CallFileSelected(const base::FilePath& file_path,
-                        base::StringPiece filter_text) WARN_UNUSED_RESULT;
+  [[nodiscard]] bool CallFileSelected(const base::FilePath& file_path,
+                                      base::StringPiece filter_text);
 
   base::WeakPtr<FakeSelectFileDialog> GetWeakPtr() {
     return weak_ptr_factory_.GetWeakPtr();
diff --git a/ui/views/controls/button/checkbox.h b/ui/views/controls/button/checkbox.h
index 47b31eae..7c5873b9 100644
--- a/ui/views/controls/button/checkbox.h
+++ b/ui/views/controls/button/checkbox.h
@@ -8,7 +8,6 @@
 #include <memory>
 #include <string>
 
-#include "base/compiler_specific.h"
 #include "cc/paint/paint_flags.h"
 #include "ui/views/controls/button/label_button.h"
 #include "ui/views/controls/focus_ring.h"
@@ -39,8 +38,8 @@
   virtual void SetChecked(bool checked);
   bool GetChecked() const;
 
-  base::CallbackListSubscription AddCheckedChangedCallback(
-      PropertyChangedCallback callback) WARN_UNUSED_RESULT;
+  [[nodiscard]] base::CallbackListSubscription AddCheckedChangedCallback(
+      PropertyChangedCallback callback);
 
   void SetMultiLine(bool multi_line);
   bool GetMultiLine() const;
diff --git a/ui/views/controls/combobox/combobox.h b/ui/views/controls/combobox/combobox.h
index 29dba45..fc77f8e 100644
--- a/ui/views/controls/combobox/combobox.h
+++ b/ui/views/controls/combobox/combobox.h
@@ -9,7 +9,6 @@
 #include <string>
 #include <utility>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/scoped_observation.h"
 #include "base/time/time.h"
@@ -73,8 +72,8 @@
   // Gets/Sets the selected index.
   int GetSelectedIndex() const { return selected_index_; }
   void SetSelectedIndex(int index);
-  base::CallbackListSubscription AddSelectedIndexChangedCallback(
-      views::PropertyChangedCallback callback) WARN_UNUSED_RESULT;
+  [[nodiscard]] base::CallbackListSubscription AddSelectedIndexChangedCallback(
+      views::PropertyChangedCallback callback);
 
   // Looks for the first occurrence of |value| in |model()|. If found, selects
   // the found index and returns true. Otherwise simply noops and returns false.
diff --git a/ui/views/controls/label.h b/ui/views/controls/label.h
index 59ea5d8..8132b9b 100644
--- a/ui/views/controls/label.h
+++ b/ui/views/controls/label.h
@@ -8,7 +8,6 @@
 #include <memory>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/gtest_prod_util.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/base/metadata/metadata_header_macros.h"
@@ -304,8 +303,8 @@
   // within the |range|. See gfx::RenderText.
   std::vector<gfx::Rect> GetSubstringBounds(const gfx::Range& range);
 
-  base::CallbackListSubscription AddTextChangedCallback(
-      views::PropertyChangedCallback callback) WARN_UNUSED_RESULT;
+  [[nodiscard]] base::CallbackListSubscription AddTextChangedCallback(
+      views::PropertyChangedCallback callback);
 
   // View:
   int GetBaseline() const override;
diff --git a/ui/views/controls/menu/menu_item_view.h b/ui/views/controls/menu/menu_item_view.h
index 8369aaca..7c82703 100644
--- a/ui/views/controls/menu/menu_item_view.h
+++ b/ui/views/controls/menu/menu_item_view.h
@@ -10,7 +10,6 @@
 #include <utility>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "build/build_config.h"
@@ -247,8 +246,8 @@
 
   // Adds a callback subscription associated with the above selected property.
   // The callback will be invoked whenever the selected property changes.
-  base::CallbackListSubscription AddSelectedChangedCallback(
-      PropertyChangedCallback callback) WARN_UNUSED_RESULT;
+  [[nodiscard]] base::CallbackListSubscription AddSelectedChangedCallback(
+      PropertyChangedCallback callback);
 
   // Sets whether the submenu area of an ACTIONABLE_SUBMENU is selected.
   void SetSelectionOfActionableSubmenu(
diff --git a/ui/views/controls/textfield/textfield.h b/ui/views/controls/textfield/textfield.h
index 295c3b7..c7f739f7 100644
--- a/ui/views/controls/textfield/textfield.h
+++ b/ui/views/controls/textfield/textfield.h
@@ -14,7 +14,6 @@
 #include <utility>
 
 #include "base/bind.h"
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/timer/timer.h"
@@ -471,8 +470,8 @@
       bool is_composition_committed) override;
 #endif
 
-  base::CallbackListSubscription AddTextChangedCallback(
-      views::PropertyChangedCallback callback) WARN_UNUSED_RESULT;
+  [[nodiscard]] base::CallbackListSubscription AddTextChangedCallback(
+      views::PropertyChangedCallback callback);
 
  protected:
   TextfieldModel* textfield_model() { return model_.get(); }
diff --git a/ui/views/metadata/view_factory_internal.h b/ui/views/metadata/view_factory_internal.h
index d5f55fe6..d29f698 100644
--- a/ui/views/metadata/view_factory_internal.h
+++ b/ui/views/metadata/view_factory_internal.h
@@ -12,7 +12,6 @@
 #include <utility>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/cxx17_backports.h"
 #include "base/memory/raw_ptr.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -156,8 +155,8 @@
   ViewBuilderCore& operator=(ViewBuilderCore&&);
   virtual ~ViewBuilderCore();
 
-  std::unique_ptr<View> Build() && WARN_UNUSED_RESULT;
-  virtual std::unique_ptr<ViewBuilderCore> Release() WARN_UNUSED_RESULT = 0;
+  [[nodiscard]] std::unique_ptr<View> Build() &&;
+  [[nodiscard]] virtual std::unique_ptr<ViewBuilderCore> Release() = 0;
 
  protected:
   // Vector of child view builders. If the optional index is included it will be
diff --git a/ui/views/test/event_generator_delegate_mac.mm b/ui/views/test/event_generator_delegate_mac.mm
index fcf8db6..1d7e6e39 100644
--- a/ui/views/test/event_generator_delegate_mac.mm
+++ b/ui/views/test/event_generator_delegate_mac.mm
@@ -321,9 +321,9 @@
 
  protected:
   // Overridden from ui::EventDispatcherDelegate (via ui::EventProcessor)
-  ui::EventDispatchDetails PreDispatchEvent(ui::EventTarget* target,
-                                            ui::Event* event) override
-      WARN_UNUSED_RESULT;
+  [[nodiscard]] ui::EventDispatchDetails PreDispatchEvent(
+      ui::EventTarget* target,
+      ui::Event* event) override;
 
  private:
   static EventGeneratorDelegateMac* instance_;
diff --git a/ui/views/view.h b/ui/views/view.h
index afb9c5c..eb31250 100644
--- a/ui/views/view.h
+++ b/ui/views/view.h
@@ -17,7 +17,6 @@
 #include "base/as_const.h"
 #include "base/callback.h"
 #include "base/callback_list.h"
-#include "base/compiler_specific.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/raw_ptr.h"
@@ -589,8 +588,8 @@
 
   // Adds a callback associated with the above Visible property. The callback
   // will be invoked whenever the Visible property changes.
-  base::CallbackListSubscription AddVisibleChangedCallback(
-      PropertyChangedCallback callback) WARN_UNUSED_RESULT;
+  [[nodiscard]] base::CallbackListSubscription AddVisibleChangedCallback(
+      PropertyChangedCallback callback);
 
   // Returns true if this view is drawn on screen.
   virtual bool IsDrawn() const;
@@ -607,8 +606,8 @@
 
   // Adds a callback associated with the above |Enabled| property. The callback
   // will be invoked whenever the property changes.
-  base::CallbackListSubscription AddEnabledChangedCallback(
-      PropertyChangedCallback callback) WARN_UNUSED_RESULT;
+  [[nodiscard]] base::CallbackListSubscription AddEnabledChangedCallback(
+      PropertyChangedCallback callback);
 
   // Returns the child views ordered in reverse z-order. That is, views later in
   // the returned vector have a higher z-order (are painted later) than those
@@ -797,8 +796,8 @@
 
   // Adds a callback associated with the above |ID| property. The callback will
   // be invoked whenever the property changes.
-  base::CallbackListSubscription AddIDChangedCallback(
-      PropertyChangedCallback callback) WARN_UNUSED_RESULT;
+  [[nodiscard]] base::CallbackListSubscription AddIDChangedCallback(
+      PropertyChangedCallback callback);
 
   // A group id is used to tag views which are part of the same logical group.
   // Focus can be moved between views with the same group using the arrow keys.
@@ -810,8 +809,8 @@
 
   // Adds a callback associated with the above |Group| property. The callback
   // will be invoked whenever the property changes.
-  base::CallbackListSubscription AddGroupChangedCallback(
-      PropertyChangedCallback callback) WARN_UNUSED_RESULT;
+  [[nodiscard]] base::CallbackListSubscription AddGroupChangedCallback(
+      PropertyChangedCallback callback);
 
   // If this returns true, the views from the same group can each be focused
   // when moving focus with the Tab/Shift-Tab key.  If this returns false,
@@ -949,8 +948,8 @@
   // Adds a callback associated with the above FlipCanvasOnPaintForRTLUI
   // property. The callback will be invoked whenever the
   // FlipCanvasOnPaintForRTLUI property changes.
-  base::CallbackListSubscription AddFlipCanvasOnPaintForRTLUIChangedCallback(
-      PropertyChangedCallback callback) WARN_UNUSED_RESULT;
+  [[nodiscard]] base::CallbackListSubscription
+  AddFlipCanvasOnPaintForRTLUIChangedCallback(PropertyChangedCallback callback);
 
   // When set, this view will ignore base::l18n::IsRTL() and instead be drawn
   // according to |is_mirrored|.
diff --git a/ui/views/widget/root_view.h b/ui/views/widget/root_view.h
index be066e2..6e9e042 100644
--- a/ui/views/widget/root_view.h
+++ b/ui/views/widget/root_view.h
@@ -8,7 +8,6 @@
 #include <memory>
 #include <string>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted.h"
 #include "ui/events/event_processor.h"
@@ -168,11 +167,11 @@
   // |view| is the view receiving |event|. This function sends the event to all
   // the Views up the hierarchy that has |notify_enter_exit_on_child_| flag
   // turned on, but does not contain |sibling|.
-  ui::EventDispatchDetails NotifyEnterExitOfDescendant(
+  [[nodiscard]] ui::EventDispatchDetails NotifyEnterExitOfDescendant(
       const ui::MouseEvent& event,
       ui::EventType type,
       View* view,
-      View* sibling) WARN_UNUSED_RESULT;
+      View* sibling);
 
   // Send synthesized gesture end events to `gesture_handler` before replacement
   // if `gesture_handler` is in progress of gesture handling.
diff --git a/ui/views/window/client_view.h b/ui/views/window/client_view.h
index 5adfb1d..ee079284 100644
--- a/ui/views/window/client_view.h
+++ b/ui/views/window/client_view.h
@@ -6,6 +6,7 @@
 #define UI_VIEWS_WINDOW_CLIENT_VIEW_H_
 
 #include "base/memory/raw_ptr.h"
+#include "ui/views/metadata/view_factory.h"
 #include "ui/views/view.h"
 
 namespace views {
@@ -75,6 +76,11 @@
   raw_ptr<View> contents_view_;
 };
 
+BEGIN_VIEW_BUILDER(VIEWS_EXPORT, ClientView, View)
+END_VIEW_BUILDER
+
 }  // namespace views
 
+DEFINE_VIEW_BUILDER(VIEWS_EXPORT, ClientView)
+
 #endif  // UI_VIEWS_WINDOW_CLIENT_VIEW_H_
diff --git a/ui/views/window/dialog_client_view.cc b/ui/views/window/dialog_client_view.cc
index 5b2f2c4..7361210 100644
--- a/ui/views/window/dialog_client_view.cc
+++ b/ui/views/window/dialog_client_view.cc
@@ -28,6 +28,7 @@
 #include "ui/views/style/platform_style.h"
 #include "ui/views/view_observer.h"
 #include "ui/views/view_tracker.h"
+#include "ui/views/view_utils.h"
 #include "ui/views/widget/widget.h"
 #include "ui/views/window/dialog_delegate.h"
 
@@ -255,7 +256,8 @@
                                           ui::DialogButton type) {
   DialogDelegate* const delegate = GetDialogDelegate();
   if (!(delegate->GetDialogButtons() & type)) {
-    delete *member;
+    if (*member)
+      button_row_container_->RemoveChildViewT(*member);
     *member = nullptr;
     return;
   }
@@ -273,21 +275,22 @@
     return;
   }
 
-  auto button = std::make_unique<MdTextButton>(
-      base::BindRepeating(&DialogClientView::ButtonPressed,
-                          base::Unretained(this), type),
-      title);
-  button->SetProminent(is_default);
-  button->SetIsDefault(is_default);
-  button->SetEnabled(delegate->IsDialogButtonEnabled(type));
-
   const int minimum_width = LayoutProvider::Get()->GetDistanceMetric(
       views::DISTANCE_DIALOG_BUTTON_MINIMUM_WIDTH);
-  button->SetMinSize(gfx::Size(minimum_width, 0));
 
-  button->SetGroup(kButtonGroup);
-
-  *member = button_row_container_->AddChildView(std::move(button));
+  Builder<View>(button_row_container_)
+      .AddChild(
+          Builder<MdTextButton>()
+              .CopyAddressTo(member)
+              .SetCallback(base::BindRepeating(&DialogClientView::ButtonPressed,
+                                               base::Unretained(this), type))
+              .SetText(title)
+              .SetProminent(is_default)
+              .SetIsDefault(is_default)
+              .SetEnabled(delegate->IsDialogButtonEnabled(type))
+              .SetMinSize(gfx::Size(minimum_width, 0))
+              .SetGroup(kButtonGroup))
+      .BuildChildren();
 }
 
 void DialogClientView::ButtonPressed(ui::DialogButton type,
@@ -312,7 +315,7 @@
   View* first = ShouldShow(extra_view_) ? extra_view_.get() : nullptr;
   View* second = cancel_button_;
   View* third = ok_button_;
-  if (PlatformStyle::kIsOkButtonLeading)
+  if (cancel_button_ && (PlatformStyle::kIsOkButtonLeading == !!ok_button_))
     std::swap(second, third);
   return {{first, second, third}};
 }
@@ -332,12 +335,12 @@
 
   // Visibility changes on |extra_view_| must be observed to re-Layout. However,
   // when hidden it's not included in the button row (it can't influence layout)
-  // and it can't be added to |button_row_container_| (GridLayout complains).
-  // So add it, hidden, to |this| so it can be observed.
+  // and it can't be added to |button_row_container_|. So add it, hidden, to
+  // |this| so it can be observed.
   if (extra_view_) {
     if (!views[0])
       AddChildView(extra_view_.get());
-    else
+    else if (views[0])
       button_row_container_->AddChildViewAt(extra_view_.get(), 0);
   }
 
@@ -385,9 +388,8 @@
   // Skip views that are not a button, or are a specific subclass of Button
   // that should never be linked. Otherwise, link everything.
   auto should_link = [](views::View* view) {
-    return Button::AsButton(view) &&
-           view->GetClassName() != Checkbox::kViewClassName &&
-           view->GetClassName() != ImageButton::kViewClassName;
+    return IsViewClass<Button>(view) && !IsViewClass<Checkbox>(view) &&
+           !IsViewClass<ImageButton>(view);
   };
 
   layout->StartRowWithPadding(kFixed, kButtonRowId, kFixed,
diff --git a/ui/views/window/dialog_client_view.h b/ui/views/window/dialog_client_view.h
index 834a2fb..073d5180 100644
--- a/ui/views/window/dialog_client_view.h
+++ b/ui/views/window/dialog_client_view.h
@@ -9,6 +9,7 @@
 #include "base/memory/raw_ptr.h"
 #include "ui/base/ui_base_types.h"
 #include "ui/views/input_event_activation_protector.h"
+#include "ui/views/metadata/view_factory.h"
 #include "ui/views/window/client_view.h"
 #include "ui/views/window/dialog_observer.h"
 
@@ -135,6 +136,11 @@
   InputEventActivationProtector input_protector_;
 };
 
+BEGIN_VIEW_BUILDER(VIEWS_EXPORT, DialogClientView, ClientView)
+END_VIEW_BUILDER
+
 }  // namespace views
 
+DEFINE_VIEW_BUILDER(VIEWS_EXPORT, DialogClientView)
+
 #endif  // UI_VIEWS_WINDOW_DIALOG_CLIENT_VIEW_H_
diff --git a/ui/webui/resources/cr_components/chromeos/multidevice_setup/button_bar.html b/ui/webui/resources/cr_components/chromeos/multidevice_setup/button_bar.html
index cd25990..060506d 100644
--- a/ui/webui/resources/cr_components/chromeos/multidevice_setup/button_bar.html
+++ b/ui/webui/resources/cr_components/chromeos/multidevice_setup/button_bar.html
@@ -17,8 +17,8 @@
       @media screen and (max-width: 767px) {
         #shadow {
           background: linear-gradient(0deg,
-                                      rgba(var(--google-grey-refresh-100-rgb), 1) 0,
-                                      rgba(var(--google-grey-refresh-100-rgb), 0) 8px);
+                                      rgba(var(--google-grey-100-rgb), 1) 0,
+                                      rgba(var(--google-grey-100-rgb), 0) 8px);
           height: 8px;
           left: 0;
           position: absolute;
diff --git a/ui/webui/resources/cr_components/customize_themes/customize_themes.html b/ui/webui/resources/cr_components/customize_themes/customize_themes.html
index 2089fca..b03b9484 100644
--- a/ui/webui/resources/cr_components/customize_themes/customize_themes.html
+++ b/ui/webui/resources/cr_components/customize_themes/customize_themes.html
@@ -12,7 +12,7 @@
 
   #thirdPartyTheme {
     align-items: center;
-    border: 1px solid var(--google-grey-refresh-300);
+    border: 1px solid var(--google-grey-300);
     border-radius: 5px;
     color: var(--cr-primary-text-color);
     display: flex;
@@ -23,7 +23,7 @@
 
   @media (prefers-color-scheme: dark) {
     #thirdPartyTheme {
-      border-color: var(--google-grey-refresh-700);
+      border-color: var(--google-grey-700);
     }
   }
 
@@ -90,7 +90,7 @@
     -webkit-mask-image: url(chrome://resources/cr_components/customize_themes/colorize.svg);
     -webkit-mask-repeat: no-repeat;
     -webkit-mask-size: 100%;
-    background-color: var(--google-grey-refresh-700);
+    background-color: var(--google-grey-700);
     height: 20px;
     left: calc(50% - 10px);
     position: absolute;
@@ -103,9 +103,9 @@
   }
 
   #autogeneratedTheme {
-    --cr-theme-icon-frame-color: var(--google-grey-refresh-100);
+    --cr-theme-icon-frame-color: var(--google-grey-100);
     --cr-theme-icon-active-tab-color: white;
-    --cr-theme-icon-stroke-color: var(--google-grey-refresh-300);
+    --cr-theme-icon-stroke-color: var(--google-grey-300);
   }
 
   #defaultTheme {
diff --git a/ui/webui/resources/cr_components/customize_themes/customize_themes.ts b/ui/webui/resources/cr_components/customize_themes/customize_themes.ts
index 05b8a1a..0edc5262 100644
--- a/ui/webui/resources/cr_components/customize_themes/customize_themes.ts
+++ b/ui/webui/resources/cr_components/customize_themes/customize_themes.ts
@@ -14,11 +14,11 @@
 
 import {SkColor} from 'chrome://resources/mojo/skia/public/mojom/skcolor.mojom-webui.js';
 import {DomRepeat} from 'chrome://resources/polymer/v3_0/polymer/lib/elements/dom-repeat.js';
-import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {assert} from '../../js/assert.m.js';
 import {hexColorToSkColor, skColorToRgba} from '../../js/color_utils.js';
-import {I18nBehavior} from '../../js/i18n_behavior.m.js';
+import {I18nMixin} from '../../js/i18n_mixin.js';
 
 import {CustomizeThemesBrowserProxyImpl} from './browser_proxy.js';
 import {ChromeTheme, CustomizeThemesClientCallbackRouter, CustomizeThemesHandlerRemote, Theme, ThemeType} from './customize_themes.mojom-webui.js';
@@ -33,9 +33,7 @@
   };
 }
 
-const CustomizeThemesElementBase =
-    mixinBehaviors([I18nBehavior], PolymerElement) as
-    {new (): PolymerElement & I18nBehavior};
+const CustomizeThemesElementBase = I18nMixin(PolymerElement);
 
 /**
  * Element that lets the user configure the autogenerated theme.
diff --git a/ui/webui/resources/cr_components/customize_themes/theme_icon.html b/ui/webui/resources/cr_components/customize_themes/theme_icon.html
index 1ad5920..8df3c8a6 100644
--- a/ui/webui/resources/cr_components/customize_themes/theme_icon.html
+++ b/ui/webui/resources/cr_components/customize_themes/theme_icon.html
@@ -50,7 +50,7 @@
 
   @media (prefers-color-scheme: dark) {
     #checkMark circle {
-      fill: var(--google-blue-refresh-300);
+      fill: var(--google-blue-300);
     }
 
     #checkMark path {
diff --git a/ui/webui/resources/cr_components/most_visited/most_visited.html b/ui/webui/resources/cr_components/most_visited/most_visited.html
index 0dc6919..fa00ea2 100644
--- a/ui/webui/resources/cr_components/most_visited/most_visited.html
+++ b/ui/webui/resources/cr_components/most_visited/most_visited.html
@@ -1,6 +1,6 @@
 <style include="cr-hidden-style cr-icons">
   :host {
-    --icon-button-color-active: var(--google-grey-refresh-700);
+    --icon-button-color-active: var(--google-grey-700);
     --icon-button-color: var(--google-grey-600);
     --icon-size: 48px;
     --tile-background-color: rgb(229, 231, 232);
@@ -11,12 +11,12 @@
 
   @media (prefers-color-scheme: dark) {
     :host {
-      --tile-background-color: var(--google-grey-refresh-100);
+      --tile-background-color: var(--google-grey-100);
     }
   }
 
   :host([is-dark_]) {
-    --icon-button-color-active: var(--google-grey-refresh-300);
+    --icon-button-color-active: var(--google-grey-300);
     --icon-button-color: white;
     --tile-hover-color: rgba(255, 255, 255, .1);
   }
diff --git a/ui/webui/resources/cr_elements/cr_view_manager/cr_view_manager.js b/ui/webui/resources/cr_elements/cr_view_manager/cr_view_manager.js
index 950ecbe..97cc703 100644
--- a/ui/webui/resources/cr_elements/cr_view_manager/cr_view_manager.js
+++ b/ui/webui/resources/cr_elements/cr_view_manager/cr_view_manager.js
@@ -39,9 +39,6 @@
 /** @type {!Map<string, function(!Element): !Promise>} */
 const viewAnimations = new Map();
 viewAnimations.set('fade-in', element => {
-  // The call to animate can have 2 methods of passing the keyframes, however as
-  // of the current closure version, only one of them is supported. See
-  // https://crbug.com/987842 for more info.
   const animation = element.animate(
       [{opacity: 0}, {opacity: 1}],
       /** @type {!KeyframeAnimationOptions } */ ({
@@ -53,9 +50,6 @@
   return whenFinished(animation);
 });
 viewAnimations.set('fade-out', element => {
-  // The call to animate can have 2 methods of passing the keyframes, however as
-  // of the current closure version, only one of them is supported. See
-  // https://crbug.com/987842 for more info.
   const animation = element.animate(
       [{opacity: 1}, {opacity: 0}],
       /** @type {!KeyframeAnimationOptions} */ ({
@@ -66,6 +60,21 @@
 
   return whenFinished(animation);
 });
+viewAnimations.set('slide-in-fade-in', element => {
+  const animation = element.animate(
+      [
+        {transform: 'translateX(8px)', opacity: 0},
+        {transform: 'translateX(0)', opacity: 1}
+      ],
+      /** @type {!KeyframeAnimationOptions} */ ({
+        duration: 300,
+        easing: 'cubic-bezier(0.0, 0.0, 0.2, 1)',
+        fill: 'forwards',
+        iterations: 1,
+      }));
+
+  return whenFinished(animation);
+});
 
 /** @polymer */
 export class CrViewManagerElement extends PolymerElement {
diff --git a/ui/webui/resources/cr_elements/shared_vars_css.html b/ui/webui/resources/cr_elements/shared_vars_css.html
index c96a23c..a90091c 100644
--- a/ui/webui/resources/cr_elements/shared_vars_css.html
+++ b/ui/webui/resources/cr_elements/shared_vars_css.html
@@ -114,7 +114,7 @@
     --google-yellow-refresh-500: var(--google-yellow-500);
 
     --cr-primary-text-color: var(--google-grey-900);
-    --cr-secondary-text-color: var(--google-grey-refresh-700);
+    --cr-secondary-text-color: var(--google-grey-700);
 
     --cr-card-background-color: white;
     --cr-card-shadow-color-rgb: var(--google-grey-800-rgb);
@@ -134,7 +134,7 @@
 
     --cr-checked-color: var(--google-blue-600);
     --cr-focused-item-color: var(--google-grey-300);
-    --cr-form-field-label-color: var(--google-grey-refresh-700);
+    --cr-form-field-label-color: var(--google-grey-700);
     --cr-hairline-rgb: 0, 0, 0;
     --cr-iph-anchor-highlight-color: rgba(var(--google-blue-600-rgb), 0.1);
     --cr-link-color: var(--google-blue-700);
@@ -159,19 +159,19 @@
   @media (prefers-color-scheme: dark) {
     html {
       --cr-primary-text-color: var(--google-grey-200);
-      --cr-secondary-text-color: var(--google-grey-refresh-500);
+      --cr-secondary-text-color: var(--google-grey-500);
 
       --cr-card-background-color: var(--google-grey-900-white-4-percent);
       --cr-card-shadow-color-rgb: 0, 0, 0;
 
-      --cr-checked-color: var(--google-blue-refresh-300);
+      --cr-checked-color: var(--google-blue-300);
       --cr-focused-item-color: var(--google-grey-800);
       --cr-form-field-label-color: var(--dark-secondary-color);
       --cr-hairline-rgb: 255, 255, 255;
       --cr-iph-anchor-highlight-color: rgba(var(--google-grey-100-rgb), 0.1);
-      --cr-link-color: var(--google-blue-refresh-300);
+      --cr-link-color: var(--google-blue-300);
       --cr-menu-background-color: var(--google-grey-900);
-      --cr-menu-background-focus-color: var(--google-grey-refresh-700);
+      --cr-menu-background-focus-color: var(--google-grey-700);
       --cr-menu-background-sheen: rgba(255, 255, 255, .06);  /* Only dark mode. */
       --cr-menu-shadow: rgba(0, 0, 0, .3) 0 1px 2px 0,
                         rgba(0, 0, 0, .15) 0 3px 6px 2px;
diff --git a/ui/webui/resources/css/md_colors.css b/ui/webui/resources/css/md_colors.css
index e521dd6d..7f76f9f5 100644
--- a/ui/webui/resources/css/md_colors.css
+++ b/ui/webui/resources/css/md_colors.css
@@ -22,7 +22,7 @@
 @media (prefers-color-scheme: dark) {
   html {
     --md-background-color: rgb(32, 33, 36);  /* --google-grey-900 */
-    --md-loading-message-color: #9AA0A6;  /* --google-grey-refresh-500 */
+    --md-loading-message-color: #9AA0A6;  /* --google-grey-500 */
     /* --cr-separator-line */
     --md-toolbar-border: 1px solid rgba(255, 255, 255, .1);
     --md-toolbar-color: rgba(255, 255, 255, .04);