diff --git a/DEPS b/DEPS
index e6c46ba..801e3976 100644
--- a/DEPS
+++ b/DEPS
@@ -280,7 +280,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': '7ae0801384fa126fc572a4cba7f82b8dcbae8511',
+  'skia_revision': '1c272f26a58732e56a7079098422dc3fd52f6434',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
@@ -288,7 +288,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': '816a1b3aef7fd4cdaf7b49ef2c0d8cd6a3ac707d',
+  'angle_revision': 'c41dae02da282ab627b0714b961134e68bea4310',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -331,7 +331,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': '8bb7722a5315fe9f176821242fd453fadb3004da',
+  'freetype_revision': 'd6fc8c6ba02b3c0e4260b5d309e6a6a0fac9541c',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling freetype
   # and whatever else without interference from each other.
@@ -359,7 +359,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': '55c6f5ed42586f7c7c4fd875856d2a4804461191',
+  'devtools_frontend_revision': 'c7e0c87bc507e039018620053c187b025aca9225',
   # 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.
@@ -395,7 +395,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': '4a63612cd2afd94ee57c9082145671531e66a37a',
+  'dawn_revision': '4b88dbcf8e14aefafe858c931acb36f3ca2c622e',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -850,7 +850,7 @@
       'packages': [
         {
           'package': 'chromium/rts/model/linux-amd64',
-          'version': 'UvBwPUE9gBmgOJrnf5CeQqaZzOtddaEWDryu2fYUFjsC',
+          'version': 'S0uREwkQfRqj_EJd0twVK16rE79-jnj5bjogt8N3jgAC',
         },
       ],
       'dep_type': 'cipd',
@@ -861,7 +861,7 @@
       'packages': [
         {
           'package': 'chromium/rts/model/mac-amd64',
-          'version': '0H_OPhM_NzKHCAMfEbmaQlUWHAsqb_GXVtBS4BBswJAC',
+          'version': 'PUYJ_dXUBWBbRc6vuHlM27CC-3Mfanjow-MzpbL1XJAC',
         },
       ],
       'dep_type': 'cipd',
@@ -872,7 +872,7 @@
       'packages': [
         {
           'package': 'chromium/rts/model/windows-amd64',
-          'version': '8MQ542HapT4cdrDiVmoqCv-UsyWyXLChBBrqpL8R8OAC',
+          'version': 'y6ZtrC4f2W853X26L9j-Skk9UBd0yRQddSngKjSR9iEC',
         },
       ],
       'dep_type': 'cipd',
@@ -1542,7 +1542,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + '66845965eea2742de82e11ca9467e53b01b78a31',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + '678b18cbe3b1730876323237279bd80b135c2046',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
@@ -1712,7 +1712,7 @@
     Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '0d237e03c270f893baded620a2d07a1823c14e06',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '7ef4f514c51b6ed7050f08f76698e4e6a77949b3',
+    Var('webrtc_git') + '/src.git' + '@' + 'f5a507955a318fb98ab775233cea96c021ce8a83',
 
   'src/third_party/libgifcodec':
      Var('skia_git') + '/libgifcodec' + '@'+  Var('libgifcodec_revision'),
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc
index ae37e130..6a32b5f 100644
--- a/ash/constants/ash_features.cc
+++ b/ash/constants/ash_features.cc
@@ -1369,6 +1369,10 @@
 const base::Feature kShimlessRMAOsUpdate{"ShimlessRMAOsUpdate",
                                          base::FEATURE_DISABLED_BY_DEFAULT};
 
+// Enables or disables the dark mode in the shimless RMA flow.
+const base::Feature kShimlessRMADisableDarkMode{
+    "ShimlessRMADisableDarkMode", base::FEATURE_ENABLED_BY_DEFAULT};
+
 // Enables or disables a toggle to enable Bluetooth debug logs.
 const base::Feature kShowBluetoothDebugLogToggle{
     "ShowBluetoothDebugLogToggle", base::FEATURE_ENABLED_BY_DEFAULT};
@@ -2280,6 +2284,10 @@
   return base::FeatureList::IsEnabled(kShimlessRMAOsUpdate);
 }
 
+bool IsShimlessRMADarkModeDisabled() {
+  return base::FeatureList::IsEnabled(kShimlessRMADisableDarkMode);
+}
+
 bool IsSimLockPolicyEnabled() {
   return base::FeatureList::IsEnabled(kSimLockPolicy);
 }
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h
index cbae848..d32c843 100644
--- a/ash/constants/ash_features.h
+++ b/ash/constants/ash_features.h
@@ -543,6 +543,8 @@
 extern const base::Feature kShimlessRMAEnableStandalone;
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kShimlessRMAOsUpdate;
 COMPONENT_EXPORT(ASH_CONSTANTS)
+extern const base::Feature kShimlessRMADisableDarkMode;
+COMPONENT_EXPORT(ASH_CONSTANTS)
 extern const base::Feature kShowBluetoothDebugLogToggle;
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kShowPlayInDemoMode;
 COMPONENT_EXPORT(ASH_CONSTANTS)
@@ -810,6 +812,7 @@
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsShimlessRMAFlowEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsShimlessRMAStandaloneAppEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsShimlessRMAOsUpdateEnabled();
+COMPONENT_EXPORT(ASH_CONSTANTS) bool IsShimlessRMADarkModeDisabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsSnoopingProtectionEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS)
 bool IsStartAssistantAudioDecoderOnDemandEnabled();
diff --git a/ash/services/device_sync/attestation_certificates_syncer.h b/ash/services/device_sync/attestation_certificates_syncer.h
index ebf495c..ca41aea 100644
--- a/ash/services/device_sync/attestation_certificates_syncer.h
+++ b/ash/services/device_sync/attestation_certificates_syncer.h
@@ -17,7 +17,7 @@
 class AttestationCertificatesSyncer {
  public:
   using NotifyCallback =
-      base::OnceCallback<void(const std::vector<std::string>&)>;
+      base::OnceCallback<void(const std::vector<std::string>&, bool valid)>;
   using GetAttestationCertificatesFunction =
       base::RepeatingCallback<void(const NotifyCallback, const std::string&)>;
 
@@ -27,6 +27,7 @@
       const AttestationCertificatesSyncer&) = delete;
 
   virtual bool IsUpdateRequired() = 0;
+  // The timestamp is only updated on successful syncs of valid certificates (not mere attempts).
   virtual void SetLastSyncTimestamp() = 0;
   virtual void UpdateCerts(NotifyCallback callback,
                            const std::string& user_key) = 0;
diff --git a/ash/services/device_sync/attestation_certificates_syncer_impl.cc b/ash/services/device_sync/attestation_certificates_syncer_impl.cc
index 67d475d..2d07c3c2f 100644
--- a/ash/services/device_sync/attestation_certificates_syncer_impl.cc
+++ b/ash/services/device_sync/attestation_certificates_syncer_impl.cc
@@ -66,7 +66,7 @@
     PrefRegistrySimple* registry) {
   registry->RegisterTimePref(
       prefs::kCryptAuthAttestationCertificatesLastGeneratedTimestamp,
-      base::Time());
+      base::Time() - kValidTime);
 }
 
 AttestationCertificatesSyncerImpl::AttestationCertificatesSyncerImpl(
diff --git a/ash/services/device_sync/attestation_certificates_syncer_impl_unittest.cc b/ash/services/device_sync/attestation_certificates_syncer_impl_unittest.cc
index b9b52db..e3ed6c0 100644
--- a/ash/services/device_sync/attestation_certificates_syncer_impl_unittest.cc
+++ b/ash/services/device_sync/attestation_certificates_syncer_impl_unittest.cc
@@ -30,7 +30,9 @@
   AttestationCertificatesSyncerImplTest& operator=(
       const AttestationCertificatesSyncerImplTest&) = delete;
 
-  void SaveCerts(const std::vector<std::string>& certs) { result_ = certs; }
+  void SaveCerts(const std::vector<std::string>& certs, bool valid) {
+    result_ = certs;
+  }
 
  protected:
   AttestationCertificatesSyncerImplTest() = default;
@@ -53,7 +55,7 @@
             [](AttestationCertificatesSyncer::NotifyCallback notify_callback,
                const std::string&) {
               std::move(notify_callback)
-                  .Run(std::vector<std::string>{kFakeCert});
+                  .Run(std::vector<std::string>{kFakeCert}, /*valid=*/true);
             }));
   }
 
diff --git a/ash/services/device_sync/cryptauth_device_syncer_impl.cc b/ash/services/device_sync/cryptauth_device_syncer_impl.cc
index 1ee4b468..a5e3e877 100644
--- a/ash/services/device_sync/cryptauth_device_syncer_impl.cc
+++ b/ash/services/device_sync/cryptauth_device_syncer_impl.cc
@@ -306,7 +306,8 @@
 }
 
 void CryptAuthDeviceSyncerImpl::OnAttestationCertificates(
-    const std::vector<std::string>& cert_chain) {
+    const std::vector<std::string>& cert_chain,
+    bool valid) {
   cryptauthv2::AttestationData* attestation_data =
       local_better_together_device_metadata_.mutable_attestation_data();
   attestation_data->set_type(
@@ -314,6 +315,7 @@
   for (const std::string& cert : cert_chain) {
     attestation_data->add_certificates(cert);
   }
+  are_attestation_certs_valid_ = valid;
   AttemptNextStep();
 }
 
@@ -763,7 +765,10 @@
     synced_bluetooth_address_tracker_->SetLastSyncedBluetoothAddress(
         local_better_together_device_metadata_.bluetooth_public_address());
     if (features::IsEcheSWAEnabled()) {
-      attestation_certificates_syncer_->SetLastSyncTimestamp();
+      if (are_attestation_certs_valid_) {
+        attestation_certificates_syncer_->SetLastSyncTimestamp();
+      }
+      are_attestation_certs_valid_ = false;
     }
   }
 
diff --git a/ash/services/device_sync/cryptauth_device_syncer_impl.h b/ash/services/device_sync/cryptauth_device_syncer_impl.h
index 0541b62..b3337766f 100644
--- a/ash/services/device_sync/cryptauth_device_syncer_impl.h
+++ b/ash/services/device_sync/cryptauth_device_syncer_impl.h
@@ -146,7 +146,8 @@
 
   bool IsAttestationCertificatesUpdateRequired();
   void GetAttestationCertificates();
-  void OnAttestationCertificates(const std::vector<std::string>& cert_chain);
+  void OnAttestationCertificates(const std::vector<std::string>& cert_chain,
+                                 bool valid);
 
   void SyncMetadata();
   void OnSyncMetadataFinished(
@@ -199,6 +200,9 @@
   void FinishAttempt(CryptAuthDeviceSyncResult::ResultCode result_code);
 
   bool did_non_fatal_error_occur_ = false;
+  // Field reflects the certificate validity state only after local_better_together_device_metadata_
+  // has been updated and before the sync attempt has completed. It is otherwise always false.
+  bool are_attestation_certs_valid_ = false;
 
   // Set in OnAttemptStarted() and not modified during the rest of the flow.
   cryptauthv2::RequestContext request_context_;
diff --git a/ash/services/device_sync/fake_attestation_certificates_syncer.cc b/ash/services/device_sync/fake_attestation_certificates_syncer.cc
index cde8a053..ce93b5f 100644
--- a/ash/services/device_sync/fake_attestation_certificates_syncer.cc
+++ b/ash/services/device_sync/fake_attestation_certificates_syncer.cc
@@ -20,7 +20,7 @@
 void FakeAttestationCertificatesSyncer::UpdateCerts(
     NotifyCallback callback,
     const std::string& user_key) {
-  std::move(callback).Run(std::vector<std::string>{kFakeCert});
+  std::move(callback).Run(std::vector<std::string>{kFakeCert}, /*valid=*/true);
 }
 
 bool FakeAttestationCertificatesSyncer::IsUpdateRequired() {
diff --git a/ash/services/multidevice_setup/BUILD.gn b/ash/services/multidevice_setup/BUILD.gn
index e7192c18..94b6b0da 100644
--- a/ash/services/multidevice_setup/BUILD.gn
+++ b/ash/services/multidevice_setup/BUILD.gn
@@ -88,6 +88,7 @@
     "//ash/services/multidevice_setup/public/cpp:test_support",
     "//ash/services/multidevice_setup/public/cpp:unit_tests",
     "//chrome/browser",
+    "//chrome/browser/ash",
     "//chrome/browser/chromeos",
     "//chrome/browser/ui",
   ]
diff --git a/ash/webui/os_feedback_ui/resources/search_page.html b/ash/webui/os_feedback_ui/resources/search_page.html
index 0a8a7e1..9997a04 100644
--- a/ash/webui/os_feedback_ui/resources/search_page.html
+++ b/ash/webui/os_feedback_ui/resources/search_page.html
@@ -42,7 +42,8 @@
         </a>
       </div>
       <textarea id="descriptionText" aria-labelledby="descriptionTitle"
-          aria-required="true" on-input="handleInputChanged_" placeholder="[[i18n('descriptionHint')]]">
+          aria-required="true" on-input="handleInputChanged_"
+          placeholder="[[i18n('descriptionHint')]]">
       </textarea>
       <p id="descriptionEmptyError" aria-hidden="true" hidden>
         [[i18n('descriptionRequired')]]
diff --git a/ash/webui/personalization_app/resources/trusted/ambient/ambient_preview_element.html b/ash/webui/personalization_app/resources/trusted/ambient/ambient_preview_element.html
index 416e32c..7845a64 100644
--- a/ash/webui/personalization_app/resources/trusted/ambient/ambient_preview_element.html
+++ b/ash/webui/personalization_app/resources/trusted/ambient/ambient_preview_element.html
@@ -222,7 +222,11 @@
             [[getAlbumDescription_(topicSource_, previewAlbums_)]]
           </span>
         </h3>
-        <div id="collageContainer" class$="[[getCollageContainerClass_(collageImages_)]]" aria-hidden="true">
+        <div id="collageContainer"
+            class$="[[getCollageContainerClass_(collageImages_)]]"
+            on-click="onClickPreviewImage_"
+            on-keypress="onClickPreviewImage_"
+            aria-hidden="true">
           <template is="dom-repeat" items="[[collageImages_]]">
             <img class="collage-item" is="cr-auto-img"
                 auto-src="[[item.url]]" is-google-photos>
diff --git a/ash/webui/personalization_app/resources/trusted/ambient/ambient_preview_element.ts b/ash/webui/personalization_app/resources/trusted/ambient/ambient_preview_element.ts
index 33ef4cac..fd771c5 100644
--- a/ash/webui/personalization_app/resources/trusted/ambient/ambient_preview_element.ts
+++ b/ash/webui/personalization_app/resources/trusted/ambient/ambient_preview_element.ts
@@ -174,7 +174,7 @@
   }
 
   private getCollageContainerClass_(): string {
-    return `collage-${this.collageImages_.length}`;
+    return `collage-${this.collageImages_.length} clickable`;
   }
 
   private getCollageItems_(): AmbientModeAlbum[] {
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_grid_item_element.html b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_grid_item_element.html
index 88048c44..731efe84 100644
--- a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_grid_item_element.html
+++ b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_grid_item_element.html
@@ -89,7 +89,7 @@
     justify-content: flex-end;
     left: 0;
     overflow: hidden;
-    padding: 8px;
+    padding: 8px 16px;
     position: absolute;
     right: 0;
     white-space: nowrap;
@@ -100,6 +100,7 @@
   .secondary-text {
     color: white;
     margin: 0;
+    overflow: hidden;
     padding: 0;
     text-align: center;
     text-overflow: ellipsis;
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 78bb13b..938473a 100644
--- a/ash/webui/shimless_rma/backend/shimless_rma_service_unittest.cc
+++ b/ash/webui/shimless_rma/backend/shimless_rma_service_unittest.cc
@@ -21,6 +21,7 @@
 #include "chromeos/ash/components/dbus/rmad/rmad_client.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/update_engine/update_engine.pb.h"
+#include "chromeos/dbus/update_engine/update_engine_client.h"
 #include "chromeos/login/login_state/login_state.h"
 #include "chromeos/network/managed_network_configuration_handler.h"
 #include "chromeos/network/network_configuration_handler.h"
@@ -117,6 +118,8 @@
 
   void SetUp() override {
     chromeos::DBusThreadManager::Initialize();
+    // VersionUpdater depends on UpdateEngineClient.
+    chromeos::UpdateEngineClient::InitializeFake();
 
     SetupFakeNetwork();
     FakeRmadClientForTest::Initialize();
@@ -141,6 +144,7 @@
     NetworkHandler::Shutdown();
     cros_network_config_test_helper_.reset();
     chromeos::LoginState::Shutdown();
+    chromeos::UpdateEngineClient::Shutdown();
     chromeos::DBusThreadManager::Shutdown();
   }
 
diff --git a/ash/webui/shimless_rma/backend/version_updater_unittest.cc b/ash/webui/shimless_rma/backend/version_updater_unittest.cc
index dd8d5d9..ca23c26b 100644
--- a/ash/webui/shimless_rma/backend/version_updater_unittest.cc
+++ b/ash/webui/shimless_rma/backend/version_updater_unittest.cc
@@ -41,9 +41,7 @@
  public:
   VersionUpdaterTest() {
     chromeos::DBusThreadManager::Initialize();
-    fake_update_engine_client_ = new FakeUpdateEngineClient();
-    DBusThreadManager::GetSetterForTesting()->SetUpdateEngineClient(
-        std::unique_ptr<UpdateEngineClient>(fake_update_engine_client_));
+    fake_update_engine_client_ = UpdateEngineClient::InitializeFakeForTest();
     cros_network_config_test_helper_ =
         std::make_unique<network_config::CrosNetworkConfigTestHelper>(false);
     InitializeManagedNetworkConfigurationHandler();
@@ -63,7 +61,7 @@
     network_configuration_handler_.reset();
     network_profile_handler_.reset();
     ui_proxy_config_service_.reset();
-    // This will delete `fake_update_engine_client_`.
+    UpdateEngineClient::Shutdown();
     chromeos::DBusThreadManager::Shutdown();
   }
 
diff --git a/base/threading/thread_restrictions.h b/base/threading/thread_restrictions.h
index c6f2cab8..bfd476b 100644
--- a/base/threading/thread_restrictions.h
+++ b/base/threading/thread_restrictions.h
@@ -224,17 +224,13 @@
 namespace ios_web_view {
 class WebViewBrowserState;
 }
-namespace leveldb_env {
-class DBTracker;
-}
-namespace location {
-namespace nearby {
-namespace chrome {
+namespace leveldb::port {
+class ScopedAllowWait;
+}  // namespace leveldb::port
+namespace location::nearby::chrome {
 class ScheduledExecutor;
 class SubmittableExecutor;
-}  // namespace chrome
-}  // namespace nearby
-}  // namespace location
+}  // namespace location::nearby::chrome
 namespace media {
 class AudioInputDevice;
 class AudioOutputDevice;
@@ -357,11 +353,9 @@
 
 namespace base {
 
-namespace sequence_manager {
-namespace internal {
+namespace sequence_manager::internal {
 class TaskQueueImpl;
-}
-}  // namespace sequence_manager
+}  // namespace sequence_manager::internal
 
 namespace android {
 class JavaHandlerThread;
@@ -583,7 +577,7 @@
   friend class functions::ExecScriptScopedAllowBaseSyncPrimitives;
   friend class history_report::HistoryReportJniBridge;
   friend class internal::TaskTracker;
-  friend class leveldb_env::DBTracker;
+  friend class leveldb::port::ScopedAllowWait;
   friend class location::nearby::chrome::ScheduledExecutor;
   friend class location::nearby::chrome::SubmittableExecutor;
   friend class media::BlockingUrlProtocol;
@@ -595,7 +589,6 @@
   friend class storage::ObfuscatedFileUtil;
   friend class syncer::HttpBridge;
   friend class syncer::GetLocalChangesRequest;
-  friend class value_store::LeveldbValueStore;
   friend class webrtc::DesktopConfigurationMonitor;
 
   // Usage that should be fixed:
@@ -603,6 +596,7 @@
   friend class ::chromeos::system::
       StatisticsProviderImpl;                      // http://crbug.com/125385
   friend class blink::VideoFrameResourceProvider;  // http://crbug.com/878070
+  friend class value_store::LeveldbValueStore;     // http://crbug.com/1330845
 
   ScopedAllowBaseSyncPrimitives() EMPTY_BODY_IF_DCHECK_IS_OFF;
   ~ScopedAllowBaseSyncPrimitives() EMPTY_BODY_IF_DCHECK_IS_OFF;
diff --git a/build/android/gyp/util/build_utils.py b/build/android/gyp/util/build_utils.py
index 839cb7d6..6f1b294 100644
--- a/build/android/gyp/util/build_utils.py
+++ b/build/android/gyp/util/build_utils.py
@@ -14,6 +14,7 @@
 import os
 import pipes
 import re
+import shlex
 import shutil
 import stat
 import subprocess
@@ -280,18 +281,31 @@
 
   has_stdout = print_stdout and stdout
   has_stderr = print_stderr and stderr
-  if fail_on_output and (has_stdout or has_stderr):
-    MSG = """\
-Command failed because it wrote to {}.
-You can often set treat_warnings_as_errors=false to not treat output as \
-failure (useful when developing locally)."""
+  if has_stdout or has_stderr:
     if has_stdout and has_stderr:
       stream_string = 'stdout and stderr'
     elif has_stdout:
       stream_string = 'stdout'
     else:
       stream_string = 'stderr'
-    raise CalledProcessError(cwd, args, MSG.format(stream_string))
+
+    if fail_on_output:
+      MSG = """
+Command failed because it wrote to {}.
+You can often set treat_warnings_as_errors=false to not treat output as \
+failure (useful when developing locally)."""
+      raise CalledProcessError(cwd, args, MSG.format(stream_string))
+
+    MSG = """
+The above {} output was from:
+{}
+"""
+    if sys.version_info.major == 2:
+      joined_args = ' '.join(args)
+    else:
+      joined_args = shlex.join(args)
+
+    sys.stderr.write(MSG.format(stream_string, joined_args))
 
   return stdout
 
diff --git a/build/config/sanitizers/BUILD.gn b/build/config/sanitizers/BUILD.gn
index c3c58e2..fa20bd8 100644
--- a/build/config/sanitizers/BUILD.gn
+++ b/build/config/sanitizers/BUILD.gn
@@ -218,19 +218,11 @@
       # In the static-library build, ASan libraries are different for
       # executables and dlls, see link_executable and link_shared_library below.
       # This here handles only the component build.
-      if (current_cpu == "x64") {
-        # Windows 64-bit.
-        libs = [
-          "clang_rt.asan_dynamic-x86_64.lib",
-          "clang_rt.asan_dynamic_runtime_thunk-x86_64.lib",
-        ]
-      } else {
-        assert(current_cpu == "x86", "WinASan unsupported architecture")
-        libs = [
-          "clang_rt.asan_dynamic-i386.lib",
-          "clang_rt.asan_dynamic_runtime_thunk-i386.lib",
-        ]
-      }
+      assert(current_cpu == "x64", "WinASan unsupported architecture")
+      libs = [
+        "clang_rt.asan_dynamic-x86_64.lib",
+        "clang_rt.asan_dynamic_runtime_thunk-x86_64.lib",
+      ]
     }
     if (use_libfuzzer) {
       assert(current_cpu == "x64", "LibFuzzer unsupported architecture")
@@ -282,23 +274,15 @@
 
 config("link_executable") {
   if (is_asan && is_win && !is_component_build) {
-    if (current_cpu == "x64") {
-      ldflags = [ "-wholearchive:clang_rt.asan-x86_64.lib" ]
-    } else {
-      assert(current_cpu == "x86", "WinASan unsupported architecture")
-      ldflags = [ "-wholearchive:clang_rt.asan-i386.lib" ]
-    }
+    assert(current_cpu == "x64", "WinASan unsupported architecture")
+    ldflags = [ "-wholearchive:clang_rt.asan-x86_64.lib" ]
   }
 }
 
 config("link_shared_library") {
   if (is_asan && is_win && !is_component_build) {
-    if (current_cpu == "x64") {
-      libs = [ "clang_rt.asan_dll_thunk-x86_64.lib" ]
-    } else {
-      assert(current_cpu == "x86", "WinASan unsupported architecture")
-      libs = [ "clang_rt.asan_dll_thunk-i386.lib" ]
-    }
+    assert(current_cpu == "x64", "WinASan unsupported architecture")
+    libs = [ "clang_rt.asan_dll_thunk-x86_64.lib" ]
   }
 }
 
diff --git a/build/fuchsia/cipd/BUILD.gn b/build/fuchsia/cipd/BUILD.gn
index 52f69a77..5533107 100644
--- a/build/fuchsia/cipd/BUILD.gn
+++ b/build/fuchsia/cipd/BUILD.gn
@@ -278,7 +278,7 @@
 
   deps = [
     "//base:base_unittests_pkg",
-    "//fuchsia_web/runners:cast_runner_integration_tests_cfv1_pkg",
+    "//fuchsia_web/runners:cast_runner_integration_tests_pkg",
     "//fuchsia_web/runners:web_runner_integration_tests_pkg",
     "//fuchsia_web/webengine:web_engine_integration_tests_pkg",
     "//ipc:ipc_tests_pkg",
@@ -298,7 +298,7 @@
         "${root_gen_dir}/third_party/blink/common/blink_common_unittests/blink_common_unittests.far",
       ]
       cfv1_far_sources = [
-        "${root_gen_dir}/fuchsia_web/runners/cast_runner_integration_tests_cfv1/cast_runner_integration_tests_cfv1.far",
+        "${root_gen_dir}/fuchsia_web/runners/cast_runner_integration_tests/cast_runner_integration_tests.far",
         "${root_gen_dir}/fuchsia_web/runners/web_runner_integration_tests/web_runner_integration_tests.far",
         "${root_gen_dir}/fuchsia_web/webengine/web_engine_integration_tests/web_engine_integration_tests.far",
         "${root_gen_dir}/media/media_unittests/media_unittests.far",
@@ -327,7 +327,7 @@
     },
     {
       manifest_path = "${target_gen_dir}/cast_runner_tests_manifest.json"
-      cfv1_far_sources = [ "${root_gen_dir}/fuchsia_web/runners/cast_runner_integration_tests_cfv1/cast_runner_integration_tests_cfv1.far" ]
+      cfv1_far_sources = [ "${root_gen_dir}/fuchsia_web/runners/cast_runner_integration_tests/cast_runner_integration_tests.far" ]
     },
   ]
 }
diff --git a/build/fuchsia/device_target.py b/build/fuchsia/device_target.py
index 2e05cf7..7b2430f 100644
--- a/build/fuchsia/device_target.py
+++ b/build/fuchsia/device_target.py
@@ -203,8 +203,9 @@
       target = targets[0]
 
     # Get the ssh address of the target.
-    if address := target.get_ssh_address():
-      self._host, self._port = address
+    ssh_address = target.get_ssh_address()
+    if ssh_address:
+      self._host, self._port = ssh_address
     else:
       return False
 
diff --git a/build/fuchsia/linux_internal.sdk.sha1 b/build/fuchsia/linux_internal.sdk.sha1
index 9413d7e..fd0a8129 100644
--- a/build/fuchsia/linux_internal.sdk.sha1
+++ b/build/fuchsia/linux_internal.sdk.sha1
@@ -1 +1 @@
-8.20220616.2.1
+8.20220616.3.1
diff --git a/cc/metrics/frame_sequence_metrics.cc b/cc/metrics/frame_sequence_metrics.cc
index 5d39381..ef19c68 100644
--- a/cc/metrics/frame_sequence_metrics.cc
+++ b/cc/metrics/frame_sequence_metrics.cc
@@ -451,6 +451,8 @@
         base::LinearHistogram::FactoryGet(
             GetCheckerboardingHistogramName(type_), 1, 100, 101,
             base::HistogramBase::kUmaTargetedHistogramFlag));
+    ThroughputData::ReportCheckerboardingHistogram(
+        this, SmoothEffectDrivingThread::kCompositor, checkerboarding_percent);
     frames_checkerboarded_ = 0;
   }
 
@@ -680,6 +682,34 @@
   return percent;
 }
 
+void FrameSequenceMetrics::ThroughputData::ReportCheckerboardingHistogram(
+    FrameSequenceMetrics* metrics,
+    SmoothEffectDrivingThread thread_type,
+    int percent) {
+  const auto sequence_type = metrics->type();
+  DCHECK_LT(sequence_type, FrameSequenceTrackerType::kMaxType);
+
+  const bool is_animation =
+      ShouldReportForAnimation(sequence_type, thread_type);
+  const bool is_interaction = ShouldReportForInteraction(
+      metrics->type(), thread_type, metrics->GetEffectiveThread());
+
+  if (is_animation) {
+    UMA_HISTOGRAM_PERCENTAGE(
+        "Graphics.Smoothness.Checkerboarding.AllAnimations", percent);
+  }
+
+  if (is_interaction) {
+    UMA_HISTOGRAM_PERCENTAGE(
+        "Graphics.Smoothness.Checkerboarding.AllInteractions", percent);
+  }
+
+  if (is_animation || is_interaction) {
+    UMA_HISTOGRAM_PERCENTAGE("Graphics.Smoothness.Checkerboarding.AllSequences",
+                             percent);
+  }
+}
+
 std::unique_ptr<base::trace_event::TracedValue>
 FrameSequenceMetrics::ThroughputData::ToTracedValue(
     const ThroughputData& impl,
diff --git a/cc/metrics/frame_sequence_metrics.h b/cc/metrics/frame_sequence_metrics.h
index 33fa2b8..31759277 100644
--- a/cc/metrics/frame_sequence_metrics.h
+++ b/cc/metrics/frame_sequence_metrics.h
@@ -106,6 +106,11 @@
         int metric_index,
         const ThroughputData& data);
 
+    static void ReportCheckerboardingHistogram(
+        FrameSequenceMetrics* metrics,
+        FrameInfo::SmoothEffectDrivingThread thread_type,
+        int percent);
+
     void Merge(const ThroughputData& data) {
       frames_expected += data.frames_expected;
       frames_produced += data.frames_produced;
diff --git a/cc/metrics/frame_sequence_tracker_unittest.cc b/cc/metrics/frame_sequence_tracker_unittest.cc
index e1f7b45..1062246 100644
--- a/cc/metrics/frame_sequence_tracker_unittest.cc
+++ b/cc/metrics/frame_sequence_tracker_unittest.cc
@@ -433,6 +433,7 @@
 // followed by a non-checkerboard frame.
 TEST_F(FrameSequenceTrackerTest, CheckerboardingSimple) {
   CreateNewTracker();
+  base::HistogramTester histogram_tester;
 
   const uint64_t source_1 = 1;
   uint64_t sequence_1 = 0;
@@ -458,12 +459,21 @@
   collection_.NotifyFramePresented(frame_token, feedback);
 
   EXPECT_EQ(1u, NumberOfFramesCheckerboarded());
+
+  // ImplThroughput().frames_expected is set to 100 since in ReportMetrics(),
+  // in order to report checkerboarding histogram, the minimum frames for
+  // ThroughputMetric is 100.
+  ImplThroughput().frames_expected = 100u;
+  ReportMetrics();
+  histogram_tester.ExpectTotalCount(
+      "Graphics.Smoothness.Checkerboarding.AllSequences", 1u);
 }
 
 // Present a single frame with checkerboarding, followed by a non-checkerboard
 // frame after a few vsyncs.
 TEST_F(FrameSequenceTrackerTest, CheckerboardingMultipleFrames) {
   CreateNewTracker();
+  base::HistogramTester histogram_tester;
 
   const uint64_t source_1 = 1;
   uint64_t sequence_1 = 0;
@@ -489,12 +499,21 @@
   collection_.NotifyFramePresented(frame_token, feedback);
 
   EXPECT_EQ(3u, NumberOfFramesCheckerboarded());
+
+  // ImplThroughput().frames_expected is set to 100 since in ReportMetrics(),
+  // in order to report checkerboarding histogram, the minimum frames for
+  // ThroughputMetric is 100.
+  ImplThroughput().frames_expected = 100u;
+  ReportMetrics();
+  histogram_tester.ExpectTotalCount(
+      "Graphics.Smoothness.Checkerboarding.AllSequences", 1u);
 }
 
 // Present multiple checkerboarded frames, followed by a non-checkerboard
 // frame.
 TEST_F(FrameSequenceTrackerTest, MultipleCheckerboardingFrames) {
   CreateNewTracker();
+  base::HistogramTester histogram_tester;
 
   const uint32_t kFrames = 3;
   const uint64_t source_1 = 1;
@@ -527,6 +546,14 @@
   collection_.NotifyFramePresented(frame_token, feedback);
 
   EXPECT_EQ(kFrames, NumberOfFramesCheckerboarded());
+
+  // ImplThroughput().frames_expected is set to 100 since in ReportMetrics(),
+  // in order to report checkerboarding histogram, the minimum frames for
+  // ThroughputMetric is 100.
+  ImplThroughput().frames_expected = 100u;
+  ReportMetrics();
+  histogram_tester.ExpectTotalCount(
+      "Graphics.Smoothness.Checkerboarding.AllSequences", 1u);
 }
 
 TEST_F(FrameSequenceTrackerTest, ReportMetrics) {
diff --git a/cc/paint/paint_image.cc b/cc/paint/paint_image.cc
index d8a27e3..ed04d6b6 100644
--- a/cc/paint/paint_image.cc
+++ b/cc/paint/paint_image.cc
@@ -232,7 +232,7 @@
   DCHECK(paint_image_generator_);
   const uint32_t lazy_pixel_ref = stable_id();
   return paint_image_generator_->GetYUVAPlanes(pixmaps, frame_index,
-                                               lazy_pixel_ref);
+                                               lazy_pixel_ref, client_id);
 }
 
 bool PaintImage::DecodeFromGenerator(void* memory,
diff --git a/cc/paint/paint_image_generator.h b/cc/paint/paint_image_generator.h
index 7c52f61..8941b1feb 100644
--- a/cc/paint/paint_image_generator.h
+++ b/cc/paint/paint_image_generator.h
@@ -61,7 +61,8 @@
   // DecodingImageGenerator tracing needs. Remove it.
   virtual bool GetYUVAPlanes(const SkYUVAPixmaps& pixmaps,
                              size_t frame_index,
-                             uint32_t lazy_pixel_ref) = 0;
+                             uint32_t lazy_pixel_ref,
+                             PaintImage::GeneratorClientId client_id) = 0;
 
   // Returns the smallest size that is at least as big as the requested size,
   // such that we can decode to exactly that scale.
diff --git a/cc/paint/skia_paint_image_generator.cc b/cc/paint/skia_paint_image_generator.cc
index a49188fd..37df37e1 100644
--- a/cc/paint/skia_paint_image_generator.cc
+++ b/cc/paint/skia_paint_image_generator.cc
@@ -41,8 +41,8 @@
 }
 
 bool SkiaPaintImageGenerator::onGetYUVAPlanes(const SkYUVAPixmaps& planes) {
-  return paint_image_generator_->GetYUVAPlanes(planes, frame_index_,
-                                               uniqueID());
+  return paint_image_generator_->GetYUVAPlanes(planes, frame_index_, uniqueID(),
+                                               client_id_);
 }
 
 }  // namespace cc
diff --git a/cc/test/fake_paint_image_generator.cc b/cc/test/fake_paint_image_generator.cc
index f6250a0..22f92fd 100644
--- a/cc/test/fake_paint_image_generator.cc
+++ b/cc/test/fake_paint_image_generator.cc
@@ -76,9 +76,11 @@
   return yuva_pixmap_info->isSupported(supported_data_types);
 }
 
-bool FakePaintImageGenerator::GetYUVAPlanes(const SkYUVAPixmaps& pixmaps,
-                                            size_t frame_index,
-                                            uint32_t lazy_pixel_ref) {
+bool FakePaintImageGenerator::GetYUVAPlanes(
+    const SkYUVAPixmaps& pixmaps,
+    size_t frame_index,
+    uint32_t lazy_pixel_ref,
+    PaintImage::GeneratorClientId client_id) {
   CHECK(is_yuv_);
   CHECK(!expect_fallback_to_rgb_);
   if (image_backing_memory_.empty())
diff --git a/cc/test/fake_paint_image_generator.h b/cc/test/fake_paint_image_generator.h
index 420808e78..f8b0be9 100644
--- a/cc/test/fake_paint_image_generator.h
+++ b/cc/test/fake_paint_image_generator.h
@@ -46,7 +46,8 @@
       SkYUVAPixmapInfo* yuva_pixmap_info) const override;
   bool GetYUVAPlanes(const SkYUVAPixmaps& pixmaps,
                      size_t frame_index,
-                     uint32_t lazy_pixel_ref) override;
+                     uint32_t lazy_pixel_ref,
+                     PaintImage::GeneratorClientId client_id) override;
   SkISize GetSupportedDecodeSize(const SkISize& requested_size) const override;
   const ImageHeaderMetadata* GetMetadataForDecodeAcceleration() const override;
 
diff --git a/chrome/VERSION b/chrome/VERSION
index 72032bd..d2b22fa 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=105
 MINOR=0
-BUILD=5124
+BUILD=5125
 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index 740c975..a88f21ce 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -1078,6 +1078,7 @@
     "//chrome/browser/ui/android/webid/internal:junit",
     "//chrome/browser/ui/messages/android:java",
     "//chrome/browser/ui/messages/android:junit",
+    "//chrome/browser/uid/android:java",
     "//chrome/browser/usb/android:junit",
     "//chrome/browser/user_education:java",
     "//chrome/browser/util:java",
@@ -1234,6 +1235,7 @@
 
   sources = [
     "javatests/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelManagerWrapper.java",
+    "javatests/src/org/chromium/chrome/browser/customtabs/CustomTabsIntentTestUtils.java",
     "javatests/src/org/chromium/chrome/browser/download/MockDownloadNotificationService.java",
     "javatests/src/org/chromium/chrome/browser/homepage/HomepageTestRule.java",
     "javatests/src/org/chromium/chrome/browser/tabmodel/TestTabModelDirectory.java",
@@ -1241,6 +1243,7 @@
 
   deps = [
     "//base:base_java",
+    "//base:base_java_test_support",
     "//chrome/android:chrome_java",
     "//chrome/browser/preferences:java",
     "//chrome/browser/profiles/android:java",
@@ -1250,6 +1253,7 @@
     "//content/public/test/android:content_java_test_support",
     "//third_party/android_support_test_runner:runner_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
+    "//third_party/androidx:androidx_browser_browser_java",
     "//third_party/junit:junit",
     "//url:gurl_java",
   ]
@@ -1311,6 +1315,7 @@
   resources_package = "org.chromium.chrome.test"
   sources = [
     "javatests/src/org/chromium/chrome/browser/IntentFilterUnitTest.java",
+    "javatests/src/org/chromium/chrome/browser/IntentHandlerUnitTest.java",
     "javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkItemRowTest.java",
     "javatests/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkShoppingItemRowTest.java",
     "javatests/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkUtilsTest.java",
@@ -1322,6 +1327,7 @@
     "javatests/src/org/chromium/chrome/browser/download/DownloadForegroundServiceManagerTest.java",
     "javatests/src/org/chromium/chrome/browser/download/DownloadNotificationServiceTest.java",
     "javatests/src/org/chromium/chrome/browser/firstrun/FirstRunUtilsTest.java",
+    "javatests/src/org/chromium/chrome/browser/init/ChainedTasksTest.java",
     "javatests/src/org/chromium/chrome/browser/init/FirstDrawDetectorTest.java",
     "javatests/src/org/chromium/chrome/browser/omnibox/status/StatusViewTest.java",
     "javatests/src/org/chromium/chrome/browser/tab/WebContentsStateBridgeTest.java",
@@ -1337,6 +1343,7 @@
     "//base:base_java_test_support",
     "//chrome/android:chrome_java",
     "//chrome/android/features/autofill_assistant:unit_test_java",
+    "//chrome/browser/android/browserservices/verification:java",
     "//chrome/browser/android/crypto:java",
     "//chrome/browser/contextmenu:java",
     "//chrome/browser/first_run/android:java",
@@ -1370,13 +1377,14 @@
     "//components/security_state/core:security_state_enums_java",
     "//components/signin/public/android:java",
     "//components/signin/public/android:signin_java_test_support",
-    "//content/public/android:content_full_java",
+    "//content/public/android:content_java",
     "//content/public/test/android:content_java_test_support",
     "//third_party/android_deps:espresso_java",
     "//third_party/android_deps:guava_android_java",
     "//third_party/android_sdk:android_test_base_java",
     "//third_party/android_support_test_runner:runner_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
+    "//third_party/androidx:androidx_browser_browser_java",
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/blink/public:blink_headers_java",
     "//third_party/hamcrest:hamcrest_library_java",
@@ -1497,7 +1505,6 @@
     "//chrome/browser/safety_check/android:javatests",
     "//chrome/browser/search_engines/android:java",
     "//chrome/browser/settings:java",
-    "//chrome/browser/settings:javatests",
     "//chrome/browser/settings:test_support_java",
     "//chrome/browser/share:java",
     "//chrome/browser/share/android:java_resources",
@@ -1567,6 +1574,7 @@
     "//components/browser_ui/notifications/android:test_support_java",
     "//components/browser_ui/photo_picker/android:javatests",
     "//components/browser_ui/settings/android:java",
+    "//components/browser_ui/settings/android:test_support_java",
     "//components/browser_ui/share/android:java",
     "//components/browser_ui/share/android:javatests",
     "//components/browser_ui/site_settings/android:java",
@@ -1586,7 +1594,6 @@
     "//components/dom_distiller/core/mojom:mojom_java",
     "//components/download/internal/background_service:internal_java",
     "//components/download/internal/common:internal_java",
-    "//components/download/network:javatests",
     "//components/download/network:network_java",
     "//components/download/public/common:public_java",
     "//components/embedder_support/android:content_view_java",
@@ -1595,7 +1602,6 @@
     "//components/embedder_support/android:util_java",
     "//components/embedder_support/android:web_contents_delegate_java",
     "//components/external_intents/android:java",
-    "//components/external_intents/android:javatests",
     "//components/externalauth/android:java",
     "//components/favicon/android:java",
     "//components/feature_engagement:feature_engagement_java",
@@ -1631,6 +1637,7 @@
     "//components/page_info/android:page_info_action_enum_java",
     "//components/page_info/core:proto_java",
     "//components/paint_preview/player/android:java",
+    "//components/paint_preview/player/android:javatests",
     "//components/password_manager/core/browser:password_manager_java_enums",
     "//components/payments/content/android:java",
     "//components/payments/content/android:javatests",
@@ -3161,10 +3168,11 @@
     "//chrome/browser/user_education:unit_device_javatests",
     "//chrome/browser/video_tutorials/internal:unit_device_javatests",
     "//components/browser_ui/modaldialog/android:unit_device_javatests",
+    "//components/browser_ui/settings/android:unit_device_javatests",
     "//components/browser_ui/widget/android:unit_device_javatests",
     "//components/embedder_support/android:embedder_support_javatests",
+    "//components/external_intents/android:unit_device_javatests",
     "//components/messages/android/internal:unit_device_javatests",
-    "//components/paint_preview/player/android:javatests",
     "//components/signin/public/android:unit_device_javatests",
     "//components/strictmode/android:unit_device_javatests",
     "//components/url_formatter/android:unit_device_javatests",
diff --git a/chrome/android/chrome_junit_test_java_sources.gni b/chrome/android/chrome_junit_test_java_sources.gni
index 508f357b..d77dca11 100644
--- a/chrome/android/chrome_junit_test_java_sources.gni
+++ b/chrome/android/chrome_junit_test_java_sources.gni
@@ -179,6 +179,12 @@
   "junit/src/org/chromium/chrome/browser/offlinepages/indicator/OfflineIndicatorMetricsDelegateUnitTest.java",
   "junit/src/org/chromium/chrome/browser/offlinepages/measurements/OfflineMeasurementsBackgroundTaskUnitTest.java",
   "junit/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchBackgroundTaskUnitTest.java",
+  "junit/src/org/chromium/chrome/browser/omaha/AttributeFinder.java",
+  "junit/src/org/chromium/chrome/browser/omaha/ExponentialBackoffSchedulerTest.java",
+  "junit/src/org/chromium/chrome/browser/omaha/MockExponentialBackoffScheduler.java",
+  "junit/src/org/chromium/chrome/browser/omaha/MockRequestGenerator.java",
+  "junit/src/org/chromium/chrome/browser/omaha/OmahaBaseTest.java",
+  "junit/src/org/chromium/chrome/browser/omaha/RequestGeneratorTest.java",
   "junit/src/org/chromium/chrome/browser/omaha/ResponseParserTest.java",
   "junit/src/org/chromium/chrome/browser/omaha/StringSanitizerTest.java",
   "junit/src/org/chromium/chrome/browser/omaha/VersionNumberTest.java",
diff --git a/chrome/android/chrome_test_java_sources.gni b/chrome/android/chrome_test_java_sources.gni
index 5d483a8..d1a0382 100644
--- a/chrome/android/chrome_test_java_sources.gni
+++ b/chrome/android/chrome_test_java_sources.gni
@@ -22,7 +22,6 @@
   "javatests/src/org/chromium/chrome/browser/ImageFetcherIntegrationTest.java",
   "javatests/src/org/chromium/chrome/browser/InstalledAppTest.java",
   "javatests/src/org/chromium/chrome/browser/IntentHandlerBrowserTest.java",
-  "javatests/src/org/chromium/chrome/browser/IntentHandlerUnitTest.java",
   "javatests/src/org/chromium/chrome/browser/JavaScriptEvalChromeTest.java",
   "javatests/src/org/chromium/chrome/browser/LauncherShortcutTest.java",
   "javatests/src/org/chromium/chrome/browser/MainActivityWithURLTest.java",
@@ -244,7 +243,6 @@
   "javatests/src/org/chromium/chrome/browser/infobar/InfoBarTest.java",
   "javatests/src/org/chromium/chrome/browser/infobar/PermissionUpdateInfobarTest.java",
   "javatests/src/org/chromium/chrome/browser/infobar/SyncErrorInfoBarTest.java",
-  "javatests/src/org/chromium/chrome/browser/init/ChainedTasksTest.java",
   "javatests/src/org/chromium/chrome/browser/init/ChromeBrowserInitializerTest.java",
   "javatests/src/org/chromium/chrome/browser/input/SelectPopupOtherContentViewTest.java",
   "javatests/src/org/chromium/chrome/browser/instantapps/InstantAppsHandlerTest.java",
@@ -305,10 +303,6 @@
   "javatests/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchConfigurationTest.java",
   "javatests/src/org/chromium/chrome/browser/offlinepages/prefetch/TestOfflinePageService.java",
   "javatests/src/org/chromium/chrome/browser/offlinepages/prefetch/TestSuggestionsService.java",
-  "javatests/src/org/chromium/chrome/browser/omaha/ExponentialBackoffSchedulerTest.java",
-  "javatests/src/org/chromium/chrome/browser/omaha/MockExponentialBackoffScheduler.java",
-  "javatests/src/org/chromium/chrome/browser/omaha/OmahaBaseTest.java",
-  "javatests/src/org/chromium/chrome/browser/omaha/RequestGeneratorTest.java",
   "javatests/src/org/chromium/chrome/browser/omaha/UpdateMenuItemHelperTest.java",
   "javatests/src/org/chromium/chrome/browser/omnibox/LocationBarLayoutTest.java",
   "javatests/src/org/chromium/chrome/browser/omnibox/LocationBarTest.java",
diff --git a/chrome/android/features/autofill_assistant/guided_browsing/javatests/src/org/chromium/chrome/browser/autofill_assistant/guided_browsing/AssistantQrCodeTest.java b/chrome/android/features/autofill_assistant/guided_browsing/javatests/src/org/chromium/chrome/browser/autofill_assistant/guided_browsing/AssistantQrCodeTest.java
index 5e047b2..d47a142 100644
--- a/chrome/android/features/autofill_assistant/guided_browsing/javatests/src/org/chromium/chrome/browser/autofill_assistant/guided_browsing/AssistantQrCodeTest.java
+++ b/chrome/android/features/autofill_assistant/guided_browsing/javatests/src/org/chromium/chrome/browser/autofill_assistant/guided_browsing/AssistantQrCodeTest.java
@@ -31,7 +31,7 @@
 import org.chromium.base.test.util.Manual;
 import org.chromium.chrome.browser.customtabs.CustomTabActivity;
 import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.components.autofill_assistant.guided_browsing.R;
@@ -66,7 +66,7 @@
     @Before
     public void setUp() {
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(
-                CustomTabsTestUtils.createMinimalCustomTabIntent(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                         InstrumentationRegistry.getTargetContext(), BLANK_URL));
     }
 
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantActionsCarouselUiTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantActionsCarouselUiTest.java
index cc3b36be..5ce9f5b 100644
--- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantActionsCarouselUiTest.java
+++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantActionsCarouselUiTest.java
@@ -33,7 +33,7 @@
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.components.autofill_assistant.carousel.AssistantActionsCarouselCoordinator;
@@ -78,7 +78,8 @@
     @Before
     public void setUp() {
         mTestRule.startCustomTabActivityWithIntent(
-                CustomTabsTestUtils.createMinimalCustomTabIntent(mTargetContext, "about:blank"));
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
+                        mTargetContext, "about:blank"));
     }
 
     /** Tests assumptions about the initial state of the carousel. */
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataUiTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataUiTest.java
index 10d8c52..c6368fb9 100644
--- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataUiTest.java
+++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataUiTest.java
@@ -54,7 +54,7 @@
 import org.chromium.chrome.browser.autofill.PersonalDataManager;
 import org.chromium.chrome.browser.autofill_assistant.AutofillAssistantCollectUserDataTestHelper.ViewHolder;
 import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.components.autofill_assistant.AssistantAutofillCreditCard;
@@ -102,8 +102,9 @@
 
     @Before
     public void setUp() throws Exception {
-        mTestRule.startCustomTabActivityWithIntent(CustomTabsTestUtils.createMinimalCustomTabIntent(
-                InstrumentationRegistry.getTargetContext(), "about:blank"));
+        mTestRule.startCustomTabActivityWithIntent(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
+                        InstrumentationRegistry.getTargetContext(), "about:blank"));
         mHelper = new AutofillAssistantCollectUserDataTestHelper();
 
         mDefaultContactSummaryOptions =
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCustomTabTestRule.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCustomTabTestRule.java
index 71adaa54..387061b1 100644
--- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCustomTabTestRule.java
+++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCustomTabTestRule.java
@@ -7,7 +7,7 @@
 import android.support.test.InstrumentationRegistry;
 
 import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils;
 
 class AutofillAssistantCustomTabTestRule
         extends AutofillAssistantTestRule<CustomTabActivityTestRule> {
@@ -23,7 +23,7 @@
     @Override
     public void startActivity() {
         getTestRule().startCustomTabActivityWithIntent(
-                CustomTabsTestUtils.createMinimalCustomTabIntent(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                         InstrumentationRegistry.getTargetContext(),
                         getTestRule().getTestServer().getURL(HTML_DIRECTORY + mTestPage)));
     }
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDetailsUiTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDetailsUiTest.java
index 655b710..f54d537d 100644
--- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDetailsUiTest.java
+++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDetailsUiTest.java
@@ -42,7 +42,7 @@
 
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.components.autofill_assistant.R;
@@ -136,8 +136,9 @@
 
     @Before
     public void setUp() {
-        mTestRule.startCustomTabActivityWithIntent(CustomTabsTestUtils.createMinimalCustomTabIntent(
-                InstrumentationRegistry.getTargetContext(), "about:blank"));
+        mTestRule.startCustomTabActivityWithIntent(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
+                        InstrumentationRegistry.getTargetContext(), "about:blank"));
     }
 
     /** Tests assumptions about the initial state of the details. */
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantHeaderUiTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantHeaderUiTest.java
index d66d437..9afa0bc 100644
--- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantHeaderUiTest.java
+++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantHeaderUiTest.java
@@ -43,7 +43,7 @@
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.chrome.browser.customtabs.CustomTabActivity;
 import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.components.autofill_assistant.AssistantDependencies;
@@ -91,7 +91,7 @@
     @Before
     public void setUp() {
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(
-                CustomTabsTestUtils.createMinimalCustomTabIntent(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                         InstrumentationRegistry.getTargetContext(), "about:blank"));
     }
 
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantInfoBoxUiTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantInfoBoxUiTest.java
index c0e861aa..f731031 100644
--- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantInfoBoxUiTest.java
+++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantInfoBoxUiTest.java
@@ -31,7 +31,7 @@
 
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.components.autofill_assistant.R;
@@ -77,8 +77,9 @@
 
     @Before
     public void setUp() {
-        mTestRule.startCustomTabActivityWithIntent(CustomTabsTestUtils.createMinimalCustomTabIntent(
-                InstrumentationRegistry.getTargetContext(), "about:blank"));
+        mTestRule.startCustomTabActivityWithIntent(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
+                        InstrumentationRegistry.getTargetContext(), "about:blank"));
     }
 
     /** Tests assumptions about the initial state of the infobox. */
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantInputActionIntegrationTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantInputActionIntegrationTest.java
index 6235873..858b0e7 100644
--- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantInputActionIntegrationTest.java
+++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantInputActionIntegrationTest.java
@@ -14,6 +14,7 @@
 import static org.hamcrest.Matchers.is;
 
 import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.checkElementExists;
+import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.getElementChecked;
 import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.getElementValue;
 import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.startAutofillAssistant;
 import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.waitUntil;
@@ -564,6 +565,69 @@
         assertThat(getElementValue(mTestRule.getWebContents(), "select"), is("three"));
     }
 
+    @Test
+    @MediumTest
+    public void fillCheckboxWithNativeMethod() throws Exception {
+        ArrayList<ActionProto> list = new ArrayList<>();
+
+        SelectorProto selectorOption2 = toCssSelector("#option2");
+        SelectorProto selectorOption3 = toCssSelector("#option3");
+
+        MiniActionTestUtil.addSetNativeCheckedSteps(selectorOption2, true, list);
+        MiniActionTestUtil.addSetNativeCheckedSteps(selectorOption3, false, list);
+        list.add(ActionProto.newBuilder()
+                         .setPrompt(PromptProto.newBuilder()
+                                            .setMessage("Set Value")
+                                            .addChoices(Choice.newBuilder().setChip(
+                                                    ChipProto.newBuilder()
+                                                            .setType(ChipType.HIGHLIGHTED_ACTION)
+                                                            .setText("Continue"))))
+                         .build());
+
+        AutofillAssistantTestScript script = new AutofillAssistantTestScript(TEST_SCRIPT, list);
+
+        assertThat(getElementChecked(mTestRule.getWebContents(), "option2"), is(false));
+        assertThat(getElementChecked(mTestRule.getWebContents(), "option3"), is(true));
+
+        runScript(script);
+
+        waitUntilViewMatchesCondition(withText("Set Value"), isCompletelyDisplayed());
+
+        assertThat(getElementChecked(mTestRule.getWebContents(), "option2"), is(true));
+        assertThat(getElementChecked(mTestRule.getWebContents(), "option3"), is(false));
+    }
+
+    @Test
+    @MediumTest
+    public void fillRadioButtonWithNativeMethod() throws Exception {
+        ArrayList<ActionProto> list = new ArrayList<>();
+
+        SelectorProto selectorRed = toCssSelector("#radio_red");
+        SelectorProto selectorBlue = toCssSelector("#radio_blue");
+
+        MiniActionTestUtil.addSetNativeCheckedSteps(selectorRed, true, list);
+        list.add(ActionProto.newBuilder()
+                         .setPrompt(PromptProto.newBuilder()
+                                            .setMessage("Set Value")
+                                            .addChoices(Choice.newBuilder().setChip(
+                                                    ChipProto.newBuilder()
+                                                            .setType(ChipType.HIGHLIGHTED_ACTION)
+                                                            .setText("Continue"))))
+                         .build());
+
+        AutofillAssistantTestScript script = new AutofillAssistantTestScript(TEST_SCRIPT, list);
+
+        assertThat(getElementChecked(mTestRule.getWebContents(), "radio_red"), is(false));
+        assertThat(getElementChecked(mTestRule.getWebContents(), "radio_blue"), is(false));
+
+        runScript(script);
+
+        waitUntilViewMatchesCondition(withText("Set Value"), isCompletelyDisplayed());
+
+        assertThat(getElementChecked(mTestRule.getWebContents(), "radio_red"), is(true));
+        assertThat(getElementChecked(mTestRule.getWebContents(), "radio_blue"), is(false));
+    }
+
     private void runScript(AutofillAssistantTestScript script) {
         AutofillAssistantTestService testService =
                 new AutofillAssistantTestService(Collections.singletonList(script));
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantOverlayUiTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantOverlayUiTest.java
index 539dd72..2e133626 100644
--- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantOverlayUiTest.java
+++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantOverlayUiTest.java
@@ -43,7 +43,7 @@
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.chrome.browser.app.ChromeActivity;
 import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.ChromeTabUtils;
@@ -74,9 +74,10 @@
 
     @Before
     public void setUp() {
-        mTestRule.startCustomTabActivityWithIntent(CustomTabsTestUtils.createMinimalCustomTabIntent(
-                InstrumentationRegistry.getTargetContext(),
-                mTestRule.getTestServer().getURL(TEST_PAGE)));
+        mTestRule.startCustomTabActivityWithIntent(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
+                        InstrumentationRegistry.getTargetContext(),
+                        mTestRule.getTestServer().getURL(TEST_PAGE)));
         mTestRule.getActivity()
                 .getRootUiCoordinatorForTesting()
                 .getScrimCoordinator()
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantTabHelperCustomTabTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantTabHelperCustomTabTest.java
index 5d71c3b..5e23dfde 100644
--- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantTabHelperCustomTabTest.java
+++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantTabHelperCustomTabTest.java
@@ -17,7 +17,7 @@
 import org.chromium.base.test.UiThreadTest;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 
@@ -32,8 +32,9 @@
 
     @Before
     public void setUp() {
-        mTestRule.startCustomTabActivityWithIntent(CustomTabsTestUtils.createMinimalCustomTabIntent(
-                InstrumentationRegistry.getTargetContext(), "about:blank"));
+        mTestRule.startCustomTabActivityWithIntent(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
+                        InstrumentationRegistry.getTargetContext(), "about:blank"));
     }
 
     @Test
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantTextUtilsTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantTextUtilsTest.java
index 4d63531..06f25383 100644
--- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantTextUtilsTest.java
+++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantTextUtilsTest.java
@@ -33,7 +33,7 @@
 import org.chromium.base.Callback;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.components.autofill_assistant.AssistantTextUtils;
@@ -63,8 +63,9 @@
 
     @Before
     public void setUp() {
-        mTestRule.startCustomTabActivityWithIntent(CustomTabsTestUtils.createMinimalCustomTabIntent(
-                InstrumentationRegistry.getTargetContext(), "about:blank"));
+        mTestRule.startCustomTabActivityWithIntent(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
+                        InstrumentationRegistry.getTargetContext(), "about:blank"));
         runOnUiThreadBlocking(() -> {
             mTestLayout = new LinearLayout(mTestRule.getActivity());
             mTestLayout.setOrientation(LinearLayout.VERTICAL);
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTest.java
index f3e5b9f3..2437a877 100644
--- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTest.java
+++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTest.java
@@ -42,7 +42,7 @@
 import org.chromium.base.test.util.UrlUtils;
 import org.chromium.chrome.browser.customtabs.CustomTabActivity;
 import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils;
 import org.chromium.chrome.browser.firstrun.FirstRunStatus;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.components.autofill_assistant.AssistantCoordinator;
@@ -134,7 +134,7 @@
     public void testStartAndAccept() {
         InOrder inOrder = inOrder(mRunnableMock);
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(
-                CustomTabsTestUtils.createMinimalCustomTabIntent(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                         InstrumentationRegistry.getTargetContext(), mTestPage));
         AssistantCoordinator assistantCoordinator = createAndShowAssistantCoordinator();
 
@@ -262,7 +262,7 @@
         InOrder inOrder = inOrder(mRunnableMock);
 
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(
-                CustomTabsTestUtils.createMinimalCustomTabIntent(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                         InstrumentationRegistry.getTargetContext(), mTestPage));
         AssistantCoordinator assistantCoordinator = createAndShowAssistantCoordinator();
 
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java
index ab7eaef..328c16bf 100644
--- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java
+++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java
@@ -720,10 +720,11 @@
     }
 
     /**
-     * Retrieves the value of the specified element.
+     * Retrieves the value of a given property of an element.
+     * @return A JSONArray containing the property value as the single element.
      */
-    public static String getElementValue(WebContents webContents, String... elementIds)
-            throws Exception {
+    private static JSONArray getElementProperty(
+            WebContents webContents, String propertyName, String... elementIds) throws Exception {
         if (!checkElementExists(webContents, elementIds)) {
             throw new IllegalArgumentException(Arrays.toString(elementIds) + " does not exist");
         }
@@ -731,11 +732,31 @@
                 new TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper();
         javascriptHelper.evaluateJavaScriptForTests(webContents,
                 "(function() {"
-                        + " return [" + getElementSelectorString(elementIds) + ".value]"
+                        + " return [" + getElementSelectorString(elementIds) + "." + propertyName
+                        + "];"
                         + "})()");
         javascriptHelper.waitUntilHasValue();
         JSONArray result = new JSONArray(javascriptHelper.getJsonResultAndClear());
-        return result.getString(0);
+        if (result.length() != 1) {
+            throw new RuntimeException("Expected exactly one element in the result.");
+        }
+        return result;
+    }
+
+    /**
+     * Retrieves whether the element is checked, using the .checked property.
+     */
+    public static boolean getElementChecked(WebContents webContents, String... elementIds)
+            throws Exception {
+        return getElementProperty(webContents, "checked", elementIds).getBoolean(0);
+    }
+
+    /**
+     * Retrieves the value of the specified element.
+     */
+    public static String getElementValue(WebContents webContents, String... elementIds)
+            throws Exception {
+        return getElementProperty(webContents, "value", elementIds).getString(0);
     }
 
     /**
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/BottomSheetOnboardingCoordinatorTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/BottomSheetOnboardingCoordinatorTest.java
index 25ba748..3ba19a4 100644
--- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/BottomSheetOnboardingCoordinatorTest.java
+++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/BottomSheetOnboardingCoordinatorTest.java
@@ -57,7 +57,7 @@
 import org.chromium.chrome.browser.app.ChromeActivity;
 import org.chromium.chrome.browser.customtabs.CustomTabActivity;
 import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.components.autofill_assistant.AssistantBottomSheetContent;
@@ -107,7 +107,7 @@
     @Before
     public void setUp() throws Exception {
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(
-                CustomTabsTestUtils.createMinimalCustomTabIntent(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                         InstrumentationRegistry.getTargetContext(), "about:blank"));
         mActivity = mCustomTabActivityTestRule.getActivity();
         mBottomSheetController = TestThreadUtils.runOnUiThreadBlocking(
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/InCctTriggeringFromGsaTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/InCctTriggeringFromGsaTest.java
index 230ab8d8..f4ba49aa3 100644
--- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/InCctTriggeringFromGsaTest.java
+++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/InCctTriggeringFromGsaTest.java
@@ -30,7 +30,7 @@
 import org.chromium.chrome.browser.autofill_assistant.proto.GetTriggerScriptsResponseProto;
 import org.chromium.chrome.browser.autofill_assistant.proto.TriggerScriptProto;
 import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.signin.services.UnifiedConsentServiceBridge;
@@ -59,7 +59,7 @@
     @Before
     public void setUp() {
         mTestRule.startCustomTabActivityWithIntent(
-                CustomTabsTestUtils
+                CustomTabsIntentTestUtils
                         .createMinimalCustomTabIntent(InstrumentationRegistry.getTargetContext(),
                                 getTargetWebsiteUrl(TEST_PAGE_UNSUPPORTED))
                         .putExtra(Browser.EXTRA_APPLICATION_ID, IntentHandler.PACKAGE_GSA));
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/InCctTriggeringFromNonGsaTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/InCctTriggeringFromNonGsaTest.java
index cfcd872..3185143 100644
--- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/InCctTriggeringFromNonGsaTest.java
+++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/InCctTriggeringFromNonGsaTest.java
@@ -19,7 +19,7 @@
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.chrome.browser.autofill_assistant.proto.GetTriggerScriptsResponseProto;
 import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.signin.services.UnifiedConsentServiceBridge;
@@ -83,7 +83,7 @@
     public void
     doNotTriggerForExternalCct() throws InterruptedException {
         mTestRule.startCustomTabActivityWithIntent(
-                CustomTabsTestUtils
+                CustomTabsIntentTestUtils
                         .createMinimalCustomTabIntent(InstrumentationRegistry.getTargetContext(),
                                 getTargetWebsiteUrl(TEST_PAGE_UNSUPPORTED))
                         .putExtra(Browser.EXTRA_APPLICATION_ID, "com.example"));
@@ -116,9 +116,10 @@
     // clang-format on
     public void
     doNotTriggerForCctWithUnknownOrigin() throws InterruptedException {
-        mTestRule.startCustomTabActivityWithIntent(CustomTabsTestUtils.createMinimalCustomTabIntent(
-                InstrumentationRegistry.getTargetContext(),
-                getTargetWebsiteUrl(TEST_PAGE_UNSUPPORTED)));
+        mTestRule.startCustomTabActivityWithIntent(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
+                        InstrumentationRegistry.getTargetContext(),
+                        getTargetWebsiteUrl(TEST_PAGE_UNSUPPORTED)));
         enableMsbb();
 
         AutofillAssistantTestServiceRequestSender testServiceRequestSender =
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/JsFlowIntegrationTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/JsFlowIntegrationTest.java
index 80e7606f..c070cca2 100644
--- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/JsFlowIntegrationTest.java
+++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/JsFlowIntegrationTest.java
@@ -59,7 +59,7 @@
 import org.chromium.chrome.browser.autofill_assistant.proto.SupportedScriptProto.PresentationProto;
 import org.chromium.chrome.browser.autofill_assistant.proto.TellProto;
 import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.components.autofill_assistant.AutofillAssistantPreferencesUtil;
@@ -106,8 +106,10 @@
     @Before
     public void setUp() {
         AutofillAssistantPreferencesUtil.setInitialPreferences(true);
-        mTestRule.startCustomTabActivityWithIntent(CustomTabsTestUtils.createMinimalCustomTabIntent(
-                InstrumentationRegistry.getTargetContext(), getTargetWebsiteUrl(TEST_PAGE)));
+        mTestRule.startCustomTabActivityWithIntent(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
+                        InstrumentationRegistry.getTargetContext(),
+                        getTargetWebsiteUrl(TEST_PAGE)));
     }
 
     private byte[] getActionBytes(ActionProto action) {
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/MiniActionTestUtil.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/MiniActionTestUtil.java
index 5b9454a0d6..616c50c 100644
--- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/MiniActionTestUtil.java
+++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/MiniActionTestUtil.java
@@ -23,6 +23,7 @@
 import org.chromium.chrome.browser.autofill_assistant.proto.SendKeystrokeEventsProto;
 import org.chromium.chrome.browser.autofill_assistant.proto.SendTapEventProto;
 import org.chromium.chrome.browser.autofill_assistant.proto.SetElementAttributeProto;
+import org.chromium.chrome.browser.autofill_assistant.proto.SetNativeCheckedProto;
 import org.chromium.chrome.browser.autofill_assistant.proto.SetNativeValueProto;
 import org.chromium.chrome.browser.autofill_assistant.proto.TextValue;
 import org.chromium.chrome.browser.autofill_assistant.proto.WaitForDocumentToBecomeInteractiveProto;
@@ -177,6 +178,7 @@
                                                     .setValue(textValue)
                                                     .build())
                          .build());
+        addReleaseElementStep(clientId, list);
     }
 
     static void addSetNativeValueSteps(
@@ -184,6 +186,20 @@
         addSetNativeValueSteps(selector, TextValue.newBuilder().setText(value).build(), list);
     }
 
+    static void addSetNativeCheckedSteps(
+            SelectorProto selector, Boolean checked, List<ActionProto> list) {
+        ClientIdProto clientId = toClientId("e");
+
+        addWaitForDomStep(selector, clientId, list);
+        list.add(ActionProto.newBuilder()
+                         .setSetNativeChecked(SetNativeCheckedProto.newBuilder()
+                                                      .setClientId(clientId)
+                                                      .setChecked(checked)
+                                                      .build())
+                         .build());
+        addReleaseElementStep(clientId, list);
+    }
+
     static void addKeyboardWithSelectSteps(
             SelectorProto selector, String value, List<ActionProto> list) {
         ClientIdProto clientId = toClientId("e");
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/PasswordChangeFixtureTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/PasswordChangeFixtureTest.java
index f74a4d6..af8a077 100644
--- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/PasswordChangeFixtureTest.java
+++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/PasswordChangeFixtureTest.java
@@ -40,7 +40,7 @@
 import org.chromium.chrome.browser.browsing_data.TimePeriod;
 import org.chromium.chrome.browser.customtabs.CustomTabActivity;
 import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.browser.password_manager.PasswordChangeLauncher;
 import org.chromium.chrome.browser.password_manager.PasswordStoreBridge;
@@ -93,8 +93,10 @@
 
         Log.i(TAG, "[Test started]");
 
-        mTestRule.startCustomTabActivityWithIntent(CustomTabsTestUtils.createMinimalCustomTabIntent(
-                InstrumentationRegistry.getTargetContext(), mParameters.getDomainUrl().getSpec()));
+        mTestRule.startCustomTabActivityWithIntent(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
+                        InstrumentationRegistry.getTargetContext(),
+                        mParameters.getDomainUrl().getSpec()));
 
         /**
          * PasswordStoreBridge requests credentials from the password store on initialization. The
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 948af94c..2557d72 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -2179,8 +2179,6 @@
     public boolean handleBackPressed() {
         if (!mUIWithNativeInitialized) return false;
 
-        if (BackPressManager.isEnabled()) return false;
-
         // TODO(1091411): Find a better mechanism for back-press handling for features.
         if (mRootUiCoordinator.getBottomSheetController().handleBackPress()) {
             BackPressManager.record(BackPressHandler.Type.BOTTOM_SHEET);
@@ -2553,6 +2551,10 @@
             mTabSwitcherBackPressHandler.destroy();
             mTabSwitcherBackPressHandler = null;
         }
+        if (mMinimizeAppAndCloseTabBackPressHandler != null) {
+            mMinimizeAppAndCloseTabBackPressHandler.destroy();
+            mMinimizeAppAndCloseTabBackPressHandler = null;
+        }
 
         if (mNotificationPermissionController != null) {
             NotificationPermissionController.detach(mNotificationPermissionController);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/SwipeRefreshHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/SwipeRefreshHandler.java
index d0c05c5..3f99136 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/SwipeRefreshHandler.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/SwipeRefreshHandler.java
@@ -17,6 +17,7 @@
 import org.chromium.base.metrics.RecordUserAction;
 import org.chromium.base.task.PostTask;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.gesturenav.HistoryNavigationCoordinator;
 import org.chromium.chrome.browser.tab.EmptyTabObserver;
 import org.chromium.chrome.browser.tab.Tab;
@@ -195,7 +196,8 @@
         if (type == OverscrollAction.PULL_TO_REFRESH) {
             if (mSwipeRefreshLayout == null) initSwipeRefreshLayout(mTab.getContext());
             attachSwipeRefreshLayoutIfNecessary();
-            return mSwipeRefreshLayout.start();
+            return mSwipeRefreshLayout.start(ChromeFeatureList.isEnabled(
+                    ChromeFeatureList.OPTIMIZE_LAYOUTS_FOR_PULL_REFRESH));
         } else if (type == OverscrollAction.HISTORY_NAVIGATION) {
             if (mNavigationCoordinator != null) {
                 mNavigationCoordinator.startGesture();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
index 273a864..298bbea 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
@@ -2208,68 +2208,58 @@
 
     /** Handles back press events for Chrome in various states. */
     protected final void handleOnBackPressed() {
+        assert !BackPressManager.isEnabled()
+            : "Back press should be handled by implementors of BackPressHandler if enabled";
         if (mNativeInitialized) RecordUserAction.record("SystemBack");
 
-        if (!BackPressManager.isEnabled()) {
-            if (TextBubble.getCountSupplier().get() != null
-                    && TextBubble.getCountSupplier().get() > 0) {
-                // TODO(crbug.com/1279941): should this stop propagating the event?
-                TextBubble.dismissBubbles();
-                BackPressManager.record(Type.TEXT_BUBBLE);
-            }
+        if (TextBubble.getCountSupplier().get() != null
+                && TextBubble.getCountSupplier().get() > 0) {
+            // TODO(crbug.com/1279941): should this stop propagating the event?
+            TextBubble.dismissBubbles();
+            BackPressManager.record(Type.TEXT_BUBBLE);
+        }
 
-            if (VrModuleProvider.getDelegate().onBackPressed()) {
-                BackPressManager.record(Type.VR_DELEGATE);
-                return;
-            };
+        if (VrModuleProvider.getDelegate().onBackPressed()) {
+            BackPressManager.record(Type.VR_DELEGATE);
+            return;
+        }
 
-            ArDelegate arDelegate = ArDelegateProvider.getDelegate();
-            if (arDelegate != null && arDelegate.onBackPressed()) {
-                BackPressManager.record(Type.AR_DELEGATE);
-                return;
-            };
+        ArDelegate arDelegate = ArDelegateProvider.getDelegate();
+        if (arDelegate != null && arDelegate.onBackPressed()) {
+            BackPressManager.record(Type.AR_DELEGATE);
+            return;
+        }
 
-            if (mCompositorViewHolderSupplier.hasValue()) {
-                LayoutManagerImpl layoutManager =
-                        mCompositorViewHolderSupplier.get().getLayoutManager();
-                if (layoutManager != null && layoutManager.onBackPressed()) {
-                    // Back press metrics recording is handled by LayoutManagerImpl internally.
-                    return;
-                };
-            }
-
-            SelectionPopupController controller = getSelectionPopupController();
-            if (controller != null && controller.isSelectActionBarShowing()) {
-                controller.clearSelection();
-                BackPressManager.record(Type.SELECTION_POPUP);
+        if (mCompositorViewHolderSupplier.hasValue()) {
+            LayoutManagerImpl layoutManager =
+                    mCompositorViewHolderSupplier.get().getLayoutManager();
+            if (layoutManager != null && layoutManager.onBackPressed()) {
+                // Back press metrics recording is handled by LayoutManagerImpl internally.
                 return;
             }
+        }
 
-            if (getManualFillingComponent().onBackPressed()) {
-                BackPressManager.record(Type.MANUAL_FILLING);
-                return;
-            }
+        SelectionPopupController controller = getSelectionPopupController();
+        if (controller != null && controller.isSelectActionBarShowing()) {
+            controller.clearSelection();
+            BackPressManager.record(Type.SELECTION_POPUP);
+            return;
+        }
 
-            if (exitFullscreenIfShowing()) {
-                BackPressManager.record(Type.FULLSCREEN);
-                return;
-            }
+        if (getManualFillingComponent().onBackPressed()) {
+            BackPressManager.record(Type.MANUAL_FILLING);
+            return;
+        }
+
+        if (exitFullscreenIfShowing()) {
+            BackPressManager.record(Type.FULLSCREEN);
+            return;
         }
 
         handleBackPressed();
     }
 
     private void initializeBackPressHandling() {
-        OnBackPressedCallback callback = new OnBackPressedCallback(true) {
-            @Override
-            public void handleOnBackPressed() {
-                ChromeActivity.this.handleOnBackPressed();
-            }
-        };
-        // Order matters here: first-come, last-served.
-        // TODO(crbug.com/1279941): remove this line when all contents of handleOnBackPressed are
-        // migrated to BackGestureManager.
-        getOnBackPressedDispatcher().addCallback(this, callback);
         if (BackPressManager.isEnabled()) {
             getOnBackPressedDispatcher().addCallback(this, mBackPressManager.getCallback());
             // TODO(crbug.com/1279941): consider move to RootUiCoordinator.
@@ -2304,6 +2294,14 @@
                         new FullscreenBackPressHandler(controlManager.getFullscreenManager()),
                         BackPressHandler.Type.FULLSCREEN);
             });
+        } else {
+            OnBackPressedCallback callback = new OnBackPressedCallback(true) {
+                @Override
+                public void handleOnBackPressed() {
+                    ChromeActivity.this.handleOnBackPressed();
+                }
+            };
+            getOnBackPressedDispatcher().addCallback(this, callback);
         }
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omaha/OmahaBase.java b/chrome/android/java/src/org/chromium/chrome/browser/omaha/OmahaBase.java
index 211c0d67..59a120e1 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/omaha/OmahaBase.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omaha/OmahaBase.java
@@ -178,7 +178,7 @@
     public @UpdateStatus int checkForUpdates() {
         // Since this update check is synchronous and blocking on the network
         // connection, it should not be run on the UI thread.
-        assert !ThreadUtils.runningOnUiThread();
+        ThreadUtils.assertOnBackgroundThread();
         Log.i(TAG,
                 "OmahaBase::checkForUpdates(): Current version String: \"" + getInstalledVersion()
                         + "\"");
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/IntentHandlerUnitTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/IntentHandlerUnitTest.java
index ebb272b..bf909bc 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/IntentHandlerUnitTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/IntentHandlerUnitTest.java
@@ -34,7 +34,7 @@
 import org.chromium.base.test.util.Feature;
 import org.chromium.chrome.browser.browserservices.verification.OriginVerifier;
 import org.chromium.chrome.browser.customtabs.CustomTabsConnection;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.translate.TranslateIntentHandler;
 import org.chromium.chrome.browser.webapps.WebappLauncherActivity;
@@ -357,7 +357,7 @@
         // Check that non-whitelisted headers from extras are passed
         // when origin is verified.
         Context context = InstrumentationRegistry.getTargetContext();
-        Intent headersIntent = CustomTabsTestUtils.createMinimalCustomTabIntent(
+        Intent headersIntent = CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                 context, "https://www.google.com/");
 
         Bundle headers = new Bundle();
@@ -389,7 +389,7 @@
         // Check that non-whitelisted headers from extras are passed
         // when origin is verified.
         Context context = InstrumentationRegistry.getTargetContext();
-        Intent headersIntent = CustomTabsTestUtils.createMinimalCustomTabIntent(
+        Intent headersIntent = CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                 context, "https://www.google.com/");
 
         Bundle headers = new Bundle();
@@ -420,7 +420,7 @@
     @Feature({"Android-AppBase"})
     public void testReferrerUrl_customTabIntentWithSession() {
         Context context = InstrumentationRegistry.getTargetContext();
-        Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(
+        Intent intent = CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                 context, "https://www.google.com/");
         Assert.assertTrue(CustomTabsConnection.getInstance().newSession(
                 CustomTabsSessionToken.getSessionTokenFromIntent(intent)));
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityTestUtil.java b/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityTestUtil.java
index 88a1b96..b1b0fa2 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityTestUtil.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityTestUtil.java
@@ -17,6 +17,7 @@
 import org.chromium.chrome.browser.browserservices.verification.OriginVerifier;
 import org.chromium.chrome.browser.customtabs.CustomTabActivity;
 import org.chromium.chrome.browser.customtabs.CustomTabsConnection;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils;
 import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
 import org.chromium.chrome.browser.tab.TabBrowserControlsConstraintsHelper;
 import org.chromium.components.embedder_support.util.Origin;
@@ -55,7 +56,7 @@
 
     /** Creates an Intent that will launch a Custom Tab to the given |url|. */
     public static Intent createTrustedWebActivityIntent(String url) {
-        Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(
+        Intent intent = CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                 InstrumentationRegistry.getTargetContext(), url);
         intent.putExtra(TrustedWebUtils.EXTRA_LAUNCH_AS_TRUSTED_WEB_ACTIVITY, true);
         return intent;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/digitalgoods/DigitalGoodsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/digitalgoods/DigitalGoodsTest.java
index 4593b59e..c416df8f 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/digitalgoods/DigitalGoodsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/digitalgoods/DigitalGoodsTest.java
@@ -34,7 +34,7 @@
 import org.chromium.chrome.browser.ChromeApplicationImpl;
 import org.chromium.chrome.browser.browserservices.TrustedWebActivityClient;
 import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils;
 import org.chromium.chrome.browser.dependency_injection.ChromeAppComponent;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.browser.payments.PaymentRequestTestRule;
@@ -84,7 +84,7 @@
         mTestPage = mTestServer.getURL(TEST_PAGE);
 
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(
-                CustomTabsTestUtils.createMinimalCustomTabIntent(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                         InstrumentationRegistry.getTargetContext(), mTestPage));
     }
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/permissiondelegation/TrustedWebActivityPermissionsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/permissiondelegation/TrustedWebActivityPermissionsTest.java
index ad673ca..d61c604b 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/permissiondelegation/TrustedWebActivityPermissionsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/permissiondelegation/TrustedWebActivityPermissionsTest.java
@@ -28,7 +28,7 @@
 import org.chromium.chrome.browser.ChromeApplicationImpl;
 import org.chromium.chrome.browser.ShortcutHelper;
 import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.browser.webapps.WebappRegistry;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
@@ -79,7 +79,7 @@
         mPackage = InstrumentationRegistry.getTargetContext().getPackageName();
 
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(
-                CustomTabsTestUtils.createMinimalCustomTabIntent(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                         InstrumentationRegistry.getTargetContext(), mTestPage));
 
         mPermissionManager = ChromeApplicationImpl.getComponent().resolvePermissionManager();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityAppMenuTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityAppMenuTest.java
index d5b9231..8e733c25 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityAppMenuTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityAppMenuTest.java
@@ -120,7 +120,7 @@
     }
 
     private Intent createMinimalCustomTabIntent() {
-        return CustomTabsTestUtils.createMinimalCustomTabIntent(
+        return CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                 InstrumentationRegistry.getTargetContext(), mTestPage);
     }
 
@@ -141,7 +141,7 @@
     public void testAppMenu() throws Exception {
         Intent intent = createMinimalCustomTabIntent();
         int numMenuEntries = 1;
-        CustomTabsTestUtils.addMenuEntriesToIntent(intent, numMenuEntries, TEST_MENU_TITLE);
+        CustomTabsIntentTestUtils.addMenuEntriesToIntent(intent, numMenuEntries, TEST_MENU_TITLE);
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent);
 
         openAppMenuAndAssertMenuShown();
@@ -326,7 +326,7 @@
         Intent intent = createMinimalCustomTabIntent();
         int numMenuEntries = 7;
         Assert.assertTrue(MAX_MENU_CUSTOM_ITEMS < numMenuEntries);
-        CustomTabsTestUtils.addMenuEntriesToIntent(intent, numMenuEntries, TEST_MENU_TITLE);
+        CustomTabsIntentTestUtils.addMenuEntriesToIntent(intent, numMenuEntries, TEST_MENU_TITLE);
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent);
 
         openAppMenuAndAssertMenuShown();
@@ -347,12 +347,12 @@
         Intent customTabIntent = createMinimalCustomTabIntent();
         Intent baseCallbackIntent = new Intent();
         baseCallbackIntent.putExtra("FOO", 42);
-        final PendingIntent pi = CustomTabsTestUtils.addMenuEntriesToIntent(
+        final PendingIntent pi = CustomTabsIntentTestUtils.addMenuEntriesToIntent(
                 customTabIntent, 1, baseCallbackIntent, TEST_MENU_TITLE);
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(customTabIntent);
 
-        final CustomTabsTestUtils.OnFinishedForTest onFinished =
-                new CustomTabsTestUtils.OnFinishedForTest(pi);
+        final CustomTabsIntentTestUtils.OnFinishedForTest onFinished =
+                new CustomTabsIntentTestUtils.OnFinishedForTest(pi);
         getCustomTabIntentDataProvider().setPendingIntentOnFinishedForTesting(onFinished);
 
         openAppMenuAndAssertMenuShown();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityIncognitoMetricTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityIncognitoMetricTest.java
index fdf1dad..587f0191 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityIncognitoMetricTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityIncognitoMetricTest.java
@@ -60,7 +60,7 @@
     }
 
     private Intent createMinimalIncognitoCustomTabIntent() {
-        return CustomTabsTestUtils.createMinimalIncognitoCustomTabIntent(
+        return CustomTabsIntentTestUtils.createMinimalIncognitoCustomTabIntent(
                 InstrumentationRegistry.getContext(), mTestPage);
     }
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityIncognitoTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityIncognitoTest.java
index d45654c0..67685d5 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityIncognitoTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityIncognitoTest.java
@@ -16,7 +16,7 @@
 import static org.junit.Assert.assertTrue;
 
 import static org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule.LONG_TIMEOUT_MS;
-import static org.chromium.chrome.browser.customtabs.CustomTabsTestUtils.addActionButtonToIntent;
+import static org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils.addActionButtonToIntent;
 import static org.chromium.chrome.browser.customtabs.CustomTabsTestUtils.createTestBitmap;
 
 import android.app.NotificationManager;
@@ -59,7 +59,7 @@
 import org.chromium.base.test.util.MinAndroidSdkLevel;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.IntentHandler;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils.OnFinishedForTest;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils.OnFinishedForTest;
 import org.chromium.chrome.browser.customtabs.features.toolbar.CustomTabToolbar;
 import org.chromium.chrome.browser.firstrun.FirstRunStatus;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
@@ -127,7 +127,7 @@
     }
 
     private Intent createMinimalIncognitoCustomTabIntent() {
-        return CustomTabsTestUtils.createMinimalIncognitoCustomTabIntent(
+        return CustomTabsIntentTestUtils.createMinimalIncognitoCustomTabIntent(
                 InstrumentationRegistry.getContext(), mTestPage);
     }
 
@@ -262,7 +262,7 @@
     @Test
     @MediumTest
     public void toolbarHasRegularProfile_ForRegularCCT() {
-        Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(
+        Intent intent = CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                 InstrumentationRegistry.getContext(), "about:blank");
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent);
         CustomTabToolbar customTabToolbar =
@@ -367,7 +367,7 @@
     @Features.EnableFeatures({ChromeFeatureList.CCT_INCOGNITO})
     public void ensureAddCustomMenuItemHasNoEffect() throws Exception {
         Intent intent = createMinimalIncognitoCustomTabIntent();
-        CustomTabsTestUtils.addMenuEntriesToIntent(intent, 3, TEST_MENU_TITLE);
+        CustomTabsIntentTestUtils.addMenuEntriesToIntent(intent, 3, TEST_MENU_TITLE);
         CustomTabActivity activity = launchIncognitoCustomTab(intent);
         CustomTabsTestUtils.openAppMenuAndAssertMenuShown(activity);
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityRenderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityRenderTest.java
index 68fe8a8..3329a7c 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityRenderTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityRenderTest.java
@@ -77,9 +77,9 @@
                     PendingIntent.getBroadcast(InstrumentationRegistry.getTargetContext(), 0,
                             new Intent(), IntentUtils.getPendingIntentMutabilityFlag(true));
 
-            toolbarItems.add(CustomTabsTestUtils.makeToolbarItemBundle(
+            toolbarItems.add(CustomTabsIntentTestUtils.makeToolbarItemBundle(
                     ICON_CREDIT_CARD, "Top Action #1", pendingIntent, 1));
-            toolbarItems.add(CustomTabsTestUtils.makeToolbarItemBundle(
+            toolbarItems.add(CustomTabsIntentTestUtils.makeToolbarItemBundle(
                     ICON_EMAIL, "Top Action #2", pendingIntent, 2));
             intent.putParcelableArrayListExtra(CustomTabsIntent.EXTRA_TOOLBAR_ITEMS, toolbarItems);
         }
@@ -126,7 +126,7 @@
 
     private void prepareCCTIntent() {
         mUrl = mEmbeddedTestServerRule.getServer().getURL(TEST_PAGE);
-        mIntent = CustomTabsTestUtils.createMinimalCustomTabIntent(
+        mIntent = CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                 InstrumentationRegistry.getContext(), mUrl);
     }
 
@@ -189,7 +189,7 @@
     @Feature("RenderTest")
     public void custom_color_red() throws IOException {
         Context context = InstrumentationRegistry.getContext();
-        mIntent = CustomTabsTestUtils.createCustomTabIntent(
+        mIntent = CustomTabsIntentTestUtils.createCustomTabIntent(
                 context, mUrl, builder -> { builder.setToolbarColor(Color.RED); });
 
         startActivityAndRenderToolbar("cct_red" + mRunWithHttps);
@@ -200,7 +200,7 @@
     @Feature("RenderTest")
     public void custom_color_black() throws IOException {
         Context context = InstrumentationRegistry.getContext();
-        mIntent = CustomTabsTestUtils.createCustomTabIntent(
+        mIntent = CustomTabsIntentTestUtils.createCustomTabIntent(
                 context, mUrl, builder -> { builder.setToolbarColor(Color.BLACK); });
 
         startActivityAndRenderToolbar("cct_black" + mRunWithHttps);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivitySecurityIndicatorTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivitySecurityIndicatorTest.java
index 8e5feeea..c0ecefa 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivitySecurityIndicatorTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivitySecurityIndicatorTest.java
@@ -80,7 +80,7 @@
         Context context = InstrumentationRegistry.getInstrumentation()
                                   .getTargetContext()
                                   .getApplicationContext();
-        Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(context, mTestPage);
+        Intent intent = CustomTabsIntentTestUtils.createMinimalCustomTabIntent(context, mTestPage);
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent);
 
         // Check that tab has loaded the expected URL.
@@ -118,7 +118,7 @@
         Context context = InstrumentationRegistry.getInstrumentation()
                                   .getTargetContext()
                                   .getApplicationContext();
-        Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(context, mTestPage);
+        Intent intent = CustomTabsIntentTestUtils.createMinimalCustomTabIntent(context, mTestPage);
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent);
 
         // Check that tab has loaded the expected URL.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java
index b2b94fe..1c0a4de 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java
@@ -94,7 +94,7 @@
 import org.chromium.chrome.browser.browserservices.intents.BrowserServicesIntentDataProvider;
 import org.chromium.chrome.browser.browserservices.verification.OriginVerifier;
 import org.chromium.chrome.browser.contextmenu.ContextMenuCoordinator;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils.OnFinishedForTest;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils.OnFinishedForTest;
 import org.chromium.chrome.browser.customtabs.content.CustomTabActivityNavigationController.FinishReason;
 import org.chromium.chrome.browser.customtabs.features.toolbar.CustomTabToolbar;
 import org.chromium.chrome.browser.document.ChromeLauncherActivity;
@@ -264,10 +264,10 @@
     }
 
     /**
-     * @see CustomTabsTestUtils#createMinimalCustomTabIntent(Context, String).
+     * @see CustomTabsIntentTestUtils#createMinimalCustomTabIntent(Context, String).
      */
     private Intent createMinimalCustomTabIntent() {
-        return CustomTabsTestUtils.createMinimalCustomTabIntent(
+        return CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                 InstrumentationRegistry.getTargetContext(), mTestPage);
     }
 
@@ -277,7 +277,8 @@
         final Context context = InstrumentationRegistry.getInstrumentation()
                                         .getTargetContext()
                                         .getApplicationContext();
-        final Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(context, mTestPage2);
+        final Intent intent =
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(context, mTestPage2);
 
         Bundle headers = new Bundle();
         headers.putString("bearer-token", "Some token");
@@ -444,7 +445,7 @@
     public void testActionButton() throws TimeoutException {
         Bitmap expectedIcon = createVectorDrawableBitmap(R.drawable.ic_credit_card_black, 77, 48);
         Intent intent = createMinimalCustomTabIntent();
-        final PendingIntent pi = CustomTabsTestUtils.addActionButtonToIntent(
+        final PendingIntent pi = CustomTabsIntentTestUtils.addActionButtonToIntent(
                 intent, expectedIcon, "Good test", sIdToIncrement++);
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent);
 
@@ -498,14 +499,14 @@
                 PendingIntent.getBroadcast(InstrumentationRegistry.getTargetContext(), 0,
                         new Intent(), IntentUtils.getPendingIntentMutabilityFlag(true));
         final OnFinishedForTest onFinished1 = new OnFinishedForTest(pi1);
-        toolbarItems.add(CustomTabsTestUtils.makeToolbarItemBundle(
+        toolbarItems.add(CustomTabsIntentTestUtils.makeToolbarItemBundle(
                 expectedIcon1, "Good test", pi1, sIdToIncrement++));
         final PendingIntent pi2 =
                 PendingIntent.getBroadcast(InstrumentationRegistry.getTargetContext(), 1,
                         new Intent(), IntentUtils.getPendingIntentMutabilityFlag(true));
         Assert.assertThat(pi2, not(equalTo(pi1)));
         final OnFinishedForTest onFinished2 = new OnFinishedForTest(pi2);
-        toolbarItems.add(CustomTabsTestUtils.makeToolbarItemBundle(
+        toolbarItems.add(CustomTabsIntentTestUtils.makeToolbarItemBundle(
                 expectedIcon2, "Even gooder test", pi2, sIdToIncrement++));
         intent.putParcelableArrayListExtra(CustomTabsIntent.EXTRA_TOOLBAR_ITEMS, toolbarItems);
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent);
@@ -566,8 +567,8 @@
     public void testActionButtonBadRatio() {
         Bitmap expectedIcon = createTestBitmap(60, 20);
         Intent intent = createMinimalCustomTabIntent();
-        CustomTabsTestUtils.setShareState(intent, CustomTabsIntent.SHARE_STATE_OFF);
-        CustomTabsTestUtils.addActionButtonToIntent(
+        CustomTabsIntentTestUtils.setShareState(intent, CustomTabsIntent.SHARE_STATE_OFF);
+        CustomTabsIntentTestUtils.addActionButtonToIntent(
                 intent, expectedIcon, "Good test", sIdToIncrement++);
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent);
 
@@ -629,7 +630,7 @@
         Intent intent = createMinimalCustomTabIntent();
 
         Bitmap expectedIcon = createVectorDrawableBitmap(R.drawable.ic_credit_card_black, 77, 48);
-        PendingIntent pi = CustomTabsTestUtils.addActionButtonToIntent(
+        PendingIntent pi = CustomTabsIntentTestUtils.addActionButtonToIntent(
                 intent, expectedIcon, "Good test", sIdToIncrement++);
 
         // Create a RemoteViews. The layout used here is pretty much arbitrary, but with the
@@ -662,14 +663,16 @@
     @DisabledTest(message = "https://crbug.com/1308065")
     public void testLoadNewUrlWithSession() throws Exception {
         final Context context = InstrumentationRegistry.getTargetContext();
-        final Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(context, mTestPage);
+        final Intent intent =
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(context, mTestPage);
         CustomTabsSessionToken session = CustomTabsSessionToken.getSessionTokenFromIntent(intent);
         warmUpAndLaunchUrlWithSession(intent);
         assertEquals(getActivity().getIntentDataProvider().getSession(), session);
         Assert.assertFalse("CustomTabContentHandler handled intent with wrong session",
                 TestThreadUtils.runOnUiThreadBlockingNoException(() -> {
                     return getSessionDataHolder().handleIntent(
-                            CustomTabsTestUtils.createMinimalCustomTabIntent(context, mTestPage2));
+                            CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
+                                    context, mTestPage2));
                 }));
         CriteriaHelper.pollInstrumentationThread(() -> {
             Criteria.checkThat(
@@ -705,7 +708,7 @@
         final String testUrl = mTestServer.getURL(
                 "/chrome/test/data/android/customtabs/test_window_open.html");
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(
-                CustomTabsTestUtils.createMinimalCustomTabIntent(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                         InstrumentationRegistry.getTargetContext(), testUrl));
         final TabModelSelector tabSelector =
                 mCustomTabActivityTestRule.getActivity().getTabModelSelector();
@@ -733,7 +736,8 @@
         final Context context = InstrumentationRegistry.getInstrumentation()
                                         .getTargetContext()
                                         .getApplicationContext();
-        final Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(context, mTestPage2);
+        final Intent intent =
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(context, mTestPage2);
         final CustomTabsSessionToken session = warmUpAndLaunchUrlWithSession(intent);
         assertEquals(getActivity().getIntentDataProvider().getSession(), session);
         CustomTabsConnection connection = CustomTabsConnection.getInstance();
@@ -770,7 +774,8 @@
         final Context context = InstrumentationRegistry.getInstrumentation()
                                         .getTargetContext()
                                         .getApplicationContext();
-        final Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(context, mTestPage2);
+        final Intent intent =
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(context, mTestPage2);
         String referrer = "https://example.com";
         intent.putExtra(Intent.EXTRA_REFERRER_NAME, referrer);
         CustomTabsSessionToken token = CustomTabsSessionToken.getSessionTokenFromIntent(intent);
@@ -936,7 +941,7 @@
             final String url, boolean useHiddenTab, final String expectedTitle) throws Exception {
         final CustomTabsConnection connection = CustomTabsTestUtils.warmUpAndWait();
         Context context = InstrumentationRegistry.getTargetContext();
-        Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(context, url);
+        Intent intent = CustomTabsIntentTestUtils.createMinimalCustomTabIntent(context, url);
         intent.putExtra(
                 CustomTabsIntent.EXTRA_TITLE_VISIBILITY_STATE, CustomTabsIntent.SHOW_PAGE_TITLE);
         final CustomTabsSessionToken token =
@@ -974,7 +979,7 @@
     public void testPrecreatedRenderer() throws Exception {
         CustomTabsConnection connection = CustomTabsTestUtils.warmUpAndWait();
         Context context = InstrumentationRegistry.getTargetContext();
-        Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(context, mTestPage);
+        Intent intent = CustomTabsIntentTestUtils.createMinimalCustomTabIntent(context, mTestPage);
         CustomTabsSessionToken token = CustomTabsSessionToken.getSessionTokenFromIntent(intent);
         Assert.assertTrue(connection.newSession(token));
         // Forcing no hidden tab implies falling back to simply creating a spare WebContents.
@@ -1107,7 +1112,7 @@
         Uri requestUri = Uri.parse(mTestServer.getURL("/set-cookie?acookie"));
 
         final Context context = InstrumentationRegistry.getTargetContext();
-        Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(context, url);
+        Intent intent = CustomTabsIntentTestUtils.createMinimalCustomTabIntent(context, url);
         final CustomTabsSessionToken token =
                 CustomTabsSessionToken.getSessionTokenFromIntent(intent);
 
@@ -1153,7 +1158,8 @@
                                   .getTargetContext()
                                   .getApplicationContext();
         CustomTabsConnection connection = CustomTabsTestUtils.warmUpAndWait();
-        Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(context, urlWithFragment);
+        Intent intent =
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(context, urlWithFragment);
         CustomTabsSessionToken token = CustomTabsSessionToken.getSessionTokenFromIntent(intent);
         connection.newSession(token);
         connection.setIgnoreUrlFragmentsForSession(token, ignoreFragments);
@@ -1214,7 +1220,7 @@
         CustomTabsTestUtils.ensureCompletedSpeculationForUrl(connection, mTestPage);
 
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(
-                CustomTabsTestUtils.createMinimalCustomTabIntent(context, mTestPage));
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(context, mTestPage));
         assertEquals(Uri.parse(mTestPage).getHost() + ":" + Uri.parse(mTestPage).getPort(),
                 ((EditText) getActivity().findViewById(R.id.url_bar)).getText().toString());
     }
@@ -1275,7 +1281,7 @@
         CustomTabsSessionToken token = CustomTabsSessionToken.createMockSessionTokenForTesting();
         connection.newSession(token);
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(
-                CustomTabsTestUtils.createMinimalCustomTabIntent(context, mTestPage));
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(context, mTestPage));
         TestThreadUtils.runOnUiThreadBlocking(
                 () -> Assert.assertFalse(
                         "Warmup() should have allocated a child connection",
@@ -1297,7 +1303,7 @@
         connection.newSession(token);
 
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(
-                CustomTabsTestUtils.createMinimalCustomTabIntent(context, mTestPage2));
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(context, mTestPage2));
         TestThreadUtils.runOnUiThreadBlocking(
                 () -> Assert.assertTrue(
                         "No spare renderer available, should allocate a child connection.",
@@ -1320,7 +1326,7 @@
         setCanUseHiddenTabForSession(connection, token, true);
         Assert.assertTrue(connection.mayLaunchUrl(token, Uri.parse(mTestPage), null, null));
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(
-                CustomTabsTestUtils.createMinimalCustomTabIntent(context, mTestPage));
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(context, mTestPage));
         TestThreadUtils.runOnUiThreadBlocking(
                 () -> Assert.assertFalse(
                         "Prerendering should have allocated a child connection",
@@ -1337,7 +1343,7 @@
         CustomTabsTestUtils.warmUpAndWait();
 
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(
-                CustomTabsTestUtils.createMinimalCustomTabIntent(context, mTestPage));
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(context, mTestPage));
 
         TestThreadUtils.runOnUiThreadBlocking(() -> {
             Assert.assertFalse(WarmupManager.getInstance().hasSpareWebContents());
@@ -1358,7 +1364,7 @@
                                   .getTargetContext()
                                   .getApplicationContext();
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(
-                CustomTabsTestUtils.createMinimalCustomTabIntent(context, mTestPage));
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(context, mTestPage));
 
         TestThreadUtils.runOnUiThreadBlocking(() -> {
             final CustomTabActivity activity = mCustomTabActivityTestRule.getActivity();
@@ -1486,7 +1492,7 @@
         Context context = InstrumentationRegistry.getInstrumentation()
                                   .getTargetContext()
                                   .getApplicationContext();
-        Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(context, url);
+        Intent intent = CustomTabsIntentTestUtils.createMinimalCustomTabIntent(context, url);
         if (useHiddenTab) {
             CustomTabsConnection connection = CustomTabsTestUtils.warmUpAndWait();
             CustomTabsSessionToken token = CustomTabsSessionToken.getSessionTokenFromIntent(intent);
@@ -1519,7 +1525,7 @@
         Context context = InstrumentationRegistry.getInstrumentation()
                                   .getTargetContext()
                                   .getApplicationContext();
-        Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(context, mTestPage);
+        Intent intent = CustomTabsIntentTestUtils.createMinimalCustomTabIntent(context, mTestPage);
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent);
         final Tab tab = mCustomTabActivityTestRule.getActivity().getActivityTab();
         TestThreadUtils.runOnUiThreadBlocking(
@@ -1560,8 +1566,8 @@
         Context context = InstrumentationRegistry.getInstrumentation()
                 .getTargetContext()
                 .getApplicationContext();
-        Intent intent = CustomTabsTestUtils
-                .createMinimalCustomTabIntent(context, mTestServer.getURL(TARGET_BLANK_TEST_PAGE));
+        Intent intent = CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
+                context, mTestServer.getURL(TARGET_BLANK_TEST_PAGE));
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent);
 
         CustomTabActivity activity = mCustomTabActivityTestRule.getActivity();
@@ -1589,8 +1595,8 @@
         Context context = InstrumentationRegistry.getInstrumentation()
                 .getTargetContext()
                 .getApplicationContext();
-        Intent intent = CustomTabsTestUtils
-                .createMinimalCustomTabIntent(context, mTestServer.getURL(TARGET_BLANK_TEST_PAGE));
+        Intent intent = CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
+                context, mTestServer.getURL(TARGET_BLANK_TEST_PAGE));
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent);
 
         CustomTabActivity activity = mCustomTabActivityTestRule.getActivity();
@@ -1615,7 +1621,7 @@
         Context context = InstrumentationRegistry.getInstrumentation()
                                   .getTargetContext()
                                   .getApplicationContext();
-        Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(context, mTestPage);
+        Intent intent = CustomTabsIntentTestUtils.createMinimalCustomTabIntent(context, mTestPage);
         intent.setData(Uri.parse(mTestPage));
         int[] ids = {101};
         intent.putExtra(CustomTabIntentDataProvider.EXPERIMENT_IDS, ids);
@@ -1639,7 +1645,7 @@
         Context context = InstrumentationRegistry.getInstrumentation()
                                   .getTargetContext()
                                   .getApplicationContext();
-        Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(context, mTestPage);
+        Intent intent = CustomTabsIntentTestUtils.createMinimalCustomTabIntent(context, mTestPage);
         intent.setData(Uri.parse(mTestPage));
         CustomTabsSessionToken token = CustomTabsSessionToken.getSessionTokenFromIntent(intent);
         CustomTabsConnection connection = CustomTabsConnection.getInstance();
@@ -1682,7 +1688,7 @@
         Context context = InstrumentationRegistry.getInstrumentation()
                                   .getTargetContext()
                                   .getApplicationContext();
-        Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(context, url);
+        Intent intent = CustomTabsIntentTestUtils.createMinimalCustomTabIntent(context, url);
         CustomTabsSessionToken token = CustomTabsSessionToken.getSessionTokenFromIntent(intent);
         connection.newSession(token);
         setCanUseHiddenTabForSession(connection, token, true);
@@ -1735,7 +1741,8 @@
         Context context = InstrumentationRegistry.getInstrumentation()
                                   .getTargetContext()
                                   .getApplicationContext();
-        Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(context, navigationUrl);
+        Intent intent =
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(context, navigationUrl);
         CustomTabsSessionToken token = CustomTabsSessionToken.getSessionTokenFromIntent(intent);
         connection.newSession(token);
         setCanUseHiddenTabForSession(connection, token, true);
@@ -1764,7 +1771,7 @@
         setCanUseHiddenTabForSession(connection, token, useHiddenTab);
         Assert.assertTrue(connection.mayLaunchUrl(token, Uri.parse(mTestPage), extras, null));
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(
-                CustomTabsTestUtils.createMinimalCustomTabIntent(context, mTestPage));
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(context, mTestPage));
         Tab tab = mCustomTabActivityTestRule.getActivity().getActivityTab();
         assertEquals(mTestPage, ChromeTabUtils.getUrlStringOnUiThread(tab));
     }
@@ -1905,7 +1912,7 @@
     }
 
     private CustomTabsSessionToken warmUpAndLaunchUrlWithSession() throws Exception {
-        return warmUpAndLaunchUrlWithSession(CustomTabsTestUtils.createMinimalCustomTabIntent(
+        return warmUpAndLaunchUrlWithSession(CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                 InstrumentationRegistry.getTargetContext(), mTestPage));
     }
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTypeTestUtils.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTypeTestUtils.java
index c619600..3b40386 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTypeTestUtils.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTypeTestUtils.java
@@ -70,7 +70,7 @@
 
     private static void launchCct(CustomTabActivityTestRule activityTestRule, String url) {
         activityTestRule.startCustomTabActivityWithIntent(
-                CustomTabsTestUtils.createMinimalCustomTabIntent(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                         InstrumentationRegistry.getTargetContext(), url));
     }
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabPostMessageTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabPostMessageTest.java
index d0a3a0b..30489fa 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabPostMessageTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabPostMessageTest.java
@@ -142,7 +142,7 @@
     public void testPostMessageBasic() throws Exception {
         final CustomTabsConnection connection = CustomTabsTestUtils.warmUpAndWait();
         Context context = InstrumentationRegistry.getTargetContext();
-        Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(context, mTestPage);
+        Intent intent = CustomTabsIntentTestUtils.createMinimalCustomTabIntent(context, mTestPage);
         final CustomTabsSessionToken token =
                 CustomTabsSessionToken.getSessionTokenFromIntent(intent);
         Assert.assertTrue(connection.newSession(token));
@@ -175,7 +175,7 @@
     public void testPostMessageWebContentsDestroyed() throws Exception {
         final CustomTabsConnection connection = CustomTabsTestUtils.warmUpAndWait();
         Context context = InstrumentationRegistry.getTargetContext();
-        Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(context, mTestPage);
+        Intent intent = CustomTabsIntentTestUtils.createMinimalCustomTabIntent(context, mTestPage);
         final CustomTabsSessionToken token =
                 CustomTabsSessionToken.getSessionTokenFromIntent(intent);
         Assert.assertTrue(connection.newSession(token));
@@ -215,7 +215,7 @@
     public void testPostMessageRequiresValidation() throws Exception {
         final CustomTabsConnection connection = CustomTabsTestUtils.warmUpAndWait();
         Context context = InstrumentationRegistry.getTargetContext();
-        Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(context, mTestPage);
+        Intent intent = CustomTabsIntentTestUtils.createMinimalCustomTabIntent(context, mTestPage);
         final CustomTabsSessionToken token =
                 CustomTabsSessionToken.getSessionTokenFromIntent(intent);
         Assert.assertTrue(connection.newSession(token));
@@ -238,7 +238,7 @@
                 mWebServer.setResponse("/test.html", TITLE_FROM_POSTMESSAGE_TO_CHANNEL, null);
         final CustomTabsConnection connection = CustomTabsTestUtils.warmUpAndWait();
         Context context = InstrumentationRegistry.getTargetContext();
-        Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(context, url);
+        Intent intent = CustomTabsIntentTestUtils.createMinimalCustomTabIntent(context, url);
         final CustomTabsSessionToken token =
                 CustomTabsSessionToken.getSessionTokenFromIntent(intent);
         Assert.assertTrue(connection.newSession(token));
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabTabPersistenceIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabTabPersistenceIntegrationTest.java
index 91a9f54..23390a030 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabTabPersistenceIntegrationTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabTabPersistenceIntegrationTest.java
@@ -38,7 +38,7 @@
     @Before
     public void setUp() {
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(
-                CustomTabsTestUtils.createMinimalCustomTabIntent(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                         InstrumentationRegistry.getTargetContext(),
                         ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL));
     }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabsIntentTestUtils.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabsIntentTestUtils.java
new file mode 100644
index 0000000..ed3a291
--- /dev/null
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabsIntentTestUtils.java
@@ -0,0 +1,210 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.customtabs;
+
+import android.app.PendingIntent;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.test.InstrumentationRegistry;
+
+import androidx.browser.customtabs.CustomTabsIntent;
+import androidx.browser.customtabs.CustomTabsSession;
+
+import org.chromium.base.Callback;
+import org.chromium.base.IntentUtils;
+import org.chromium.base.test.util.CallbackHelper;
+import org.chromium.chrome.browser.IntentHandler;
+import org.chromium.chrome.browser.document.ChromeLauncherActivity;
+
+import java.util.ArrayList;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * Utility class that contains convenience calls related with intent creation for
+ * custom tabs testing.
+ */
+public class CustomTabsIntentTestUtils {
+    /**
+     * A utility class to ensure that a pending intent assigned to a menu item in CCT was invoked.
+     */
+    public static class OnFinishedForTest implements PendingIntent.OnFinished {
+        private final PendingIntent mPendingIntent;
+        private final CallbackHelper mCallbackHelper = new CallbackHelper();
+        private Intent mCallbackIntent;
+
+        /**
+         * Create an instance of {@link OnFinishedForTest}, testing the given {@link PendingIntent}.
+         */
+        public OnFinishedForTest(PendingIntent pendingIntent) {
+            mPendingIntent = pendingIntent;
+        }
+
+        public Intent getCallbackIntent() {
+            return mCallbackIntent;
+        }
+
+        public void waitForCallback(String failureReason) throws TimeoutException {
+            mCallbackHelper.waitForCallback(failureReason, 0);
+        }
+
+        @Override
+        public void onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode,
+                String resultData, Bundle resultExtras) {
+            if (pendingIntent.equals(mPendingIntent)) {
+                mCallbackIntent = intent;
+                mCallbackHelper.notifyCalled();
+            }
+        }
+    }
+
+    /**
+     * Creates the simplest intent that is sufficient to let {@link ChromeLauncherActivity} launch
+     * the {@link CustomTabActivity}.
+     */
+    public static Intent createMinimalCustomTabIntent(Context context, String url) {
+        return createCustomTabIntent(context, url, builder -> {});
+    }
+
+    /**
+     * Creates an Intent that launches a CustomTabActivity, allows some customization.
+     */
+    public static Intent createCustomTabIntent(
+            Context context, String url, Callback<CustomTabsIntent.Builder> customizer) {
+        CustomTabsIntent.Builder builder =
+                new CustomTabsIntent.Builder(CustomTabsSession.createMockSessionForTesting(
+                        new ComponentName(context, ChromeLauncherActivity.class)));
+        customizer.onResult(builder);
+        CustomTabsIntent customTabsIntent = builder.build();
+        Intent intent = customTabsIntent.intent;
+        intent.setAction(Intent.ACTION_VIEW);
+        intent.setData(Uri.parse(url));
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        return intent;
+    }
+
+    /**
+     * Creates the simplest intent that that is sufficient to let {@link ChromeLauncherActivity}
+     * launch the incognito {@link CustomTabActivity}.
+     *
+     * @param context The instrumentation context to use.
+     * @param url The URL to load in the incognito CCT.
+     * @return Returns the intent to launch the incognito CCT.
+     */
+    public static Intent createMinimalIncognitoCustomTabIntent(Context context, String url) {
+        Intent intent = createMinimalCustomTabIntent(context, url);
+        intent.putExtra(IntentHandler.EXTRA_OPEN_NEW_INCOGNITO_TAB, true);
+        return intent;
+    }
+
+    /**
+     * Creates the simplest intent that is sufficient to let {@link ChromeLauncherActivity} launch
+     * the {@link CustomTabActivity}. Allows specification of a theme.
+     * @param context The instrumentation context to use.
+     * @param url The URL to load in the incognito CCT.
+     * @param inNightMode Whether the CCT should be launched in night mode.
+     * @return Returns the intent to launch the incognito CCT.
+     */
+    public static Intent createMinimalCustomTabIntentWithTheme(
+            Context context, String url, boolean inNightMode) {
+        return createCustomTabIntent(context, url, builder -> {
+            builder.setColorScheme(inNightMode ? CustomTabsIntent.COLOR_SCHEME_DARK
+                                               : CustomTabsIntent.COLOR_SCHEME_LIGHT);
+        });
+    }
+
+    /**
+     * Add a bundle specifying a a number of custom menu entries.
+     *
+     * @param customTabIntent The intent to modify.
+     * @param numEntries The number of menu entries to add.
+     * @param menuTitle The title of the menu.
+     *
+     * @return The pending intent associated with the menu entries.
+     */
+    public static PendingIntent addMenuEntriesToIntent(
+            Intent customTabIntent, int numEntries, String menuTitle) {
+        return addMenuEntriesToIntent(customTabIntent, numEntries, new Intent(), menuTitle);
+    }
+
+    /**
+     * Add a bundle specifying a custom menu entry.
+     *
+     * @param customTabIntent The intent to modify.
+     * @param numEntries The number of menu entries to add.
+     * @param callbackIntent The intent to use as the base for the pending intent.
+     * @param menuTitle The title of the menu.
+     *
+     * @return The pending intent associated with the menu entry.
+     */
+    public static PendingIntent addMenuEntriesToIntent(
+            Intent customTabIntent, int numEntries, Intent callbackIntent, String menuTitle) {
+        PendingIntent pi = PendingIntent.getBroadcast(InstrumentationRegistry.getTargetContext(), 0,
+                callbackIntent,
+                PendingIntent.FLAG_UPDATE_CURRENT
+                        | IntentUtils.getPendingIntentMutabilityFlag(true));
+        ArrayList<Bundle> menuItems = new ArrayList<>();
+        for (int i = 0; i < numEntries; i++) {
+            Bundle bundle = new Bundle();
+            bundle.putString(CustomTabsIntent.KEY_MENU_ITEM_TITLE, menuTitle);
+            bundle.putParcelable(CustomTabsIntent.KEY_PENDING_INTENT, pi);
+            menuItems.add(bundle);
+        }
+        customTabIntent.putParcelableArrayListExtra(CustomTabsIntent.EXTRA_MENU_ITEMS, menuItems);
+        return pi;
+    }
+
+    /**
+     * Creates a CCT Toolbar menu item bundle.
+     *
+     * @param icon The Bitmap icon to be add in the toolbar.
+     * @param description The description about the icon which will be added.
+     * @param pi The pending intent that would be triggered when the icon is clicked on.
+     * @param id A unique id for this new icon.
+     *
+     * @return Returns the bundle encapsulating the toolbar item.
+     */
+    public static Bundle makeToolbarItemBundle(
+            Bitmap icon, String description, PendingIntent pi, int id) {
+        Bundle bundle = new Bundle();
+        bundle.putInt(CustomTabsIntent.KEY_ID, id);
+        bundle.putParcelable(CustomTabsIntent.KEY_ICON, icon);
+        bundle.putString(CustomTabsIntent.KEY_DESCRIPTION, description);
+        bundle.putParcelable(CustomTabsIntent.KEY_PENDING_INTENT, pi);
+        bundle.putBoolean(CustomButtonParamsImpl.SHOW_ON_TOOLBAR, true);
+        return bundle;
+    }
+
+    /**
+     * Adds an action button to the custom tab toolbar.
+     *
+     * @param intent The intent where the action button would be added.
+     * @param icon The icon representing the action button.
+     * @param description The description associated with the action button.
+     * @param id The unique id that would be used for this new Action button.
+     *
+     * @return The {@link PendingIntent} that will be triggered when the action button is clicked.
+     */
+    public static PendingIntent addActionButtonToIntent(
+            Intent intent, Bitmap icon, String description, int id) {
+        PendingIntent pi = PendingIntent.getBroadcast(InstrumentationRegistry.getTargetContext(), 0,
+                new Intent(), IntentUtils.getPendingIntentMutabilityFlag(true));
+        intent.putExtra(CustomTabsIntent.EXTRA_ACTION_BUTTON_BUNDLE,
+                makeToolbarItemBundle(icon, description, pi, id));
+        return pi;
+    }
+
+    /**
+     * Sets the {@link CustomTabsIntent.ShareState} of the custom tab.
+     * @param intent The intent to modify.
+     * @param shareState The {@link CustomTabsIntent.ShareState} being set.
+     */
+    public static void setShareState(Intent intent, int shareState) {
+        intent.putExtra(CustomTabsIntent.EXTRA_SHARE_STATE, shareState);
+    }
+}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabsTestUtils.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabsTestUtils.java
index 51d35d8..911d6c50 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabsTestUtils.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabsTestUtils.java
@@ -6,28 +6,21 @@
 
 import static org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule.LONG_TIMEOUT_MS;
 
-import android.app.PendingIntent;
 import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
-import android.net.Uri;
 import android.os.Bundle;
 import android.os.Process;
 import android.support.test.InstrumentationRegistry;
 
 import androidx.browser.customtabs.CustomTabsCallback;
 import androidx.browser.customtabs.CustomTabsClient;
-import androidx.browser.customtabs.CustomTabsIntent;
 import androidx.browser.customtabs.CustomTabsServiceConnection;
 import androidx.browser.customtabs.CustomTabsSession;
 
 import org.hamcrest.Matchers;
 import org.junit.Assert;
 
-import org.chromium.base.Callback;
-import org.chromium.base.IntentUtils;
 import org.chromium.base.annotations.JNINamespace;
 import org.chromium.base.annotations.NativeMethods;
 import org.chromium.base.task.PostTask;
@@ -35,13 +28,10 @@
 import org.chromium.base.test.util.Criteria;
 import org.chromium.base.test.util.CriteriaHelper;
 import org.chromium.chrome.R;
-import org.chromium.chrome.browser.IntentHandler;
-import org.chromium.chrome.browser.document.ChromeLauncherActivity;
 import org.chromium.chrome.test.util.ChromeTabUtils;
 import org.chromium.content_public.browser.UiThreadTaskTraits;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 
-import java.util.ArrayList;
 import java.util.concurrent.TimeoutException;
 import java.util.concurrent.atomic.AtomicReference;
 
@@ -66,95 +56,6 @@
         }
     }
 
-    /**
-     * A utility class to ensure that a pending intent assigned to a menu item in CCT was invoked.
-     */
-    public static class OnFinishedForTest implements PendingIntent.OnFinished {
-        private final PendingIntent mPendingIntent;
-        private final CallbackHelper mCallbackHelper = new CallbackHelper();
-        private Intent mCallbackIntent;
-
-        /**
-         * Create an instance of {@link OnFinishedForTest}, testing the given {@link PendingIntent}.
-         */
-        public OnFinishedForTest(PendingIntent pendingIntent) {
-            mPendingIntent = pendingIntent;
-        }
-
-        public Intent getCallbackIntent() {
-            return mCallbackIntent;
-        }
-
-        public void waitForCallback(String failureReason) throws TimeoutException {
-            mCallbackHelper.waitForCallback(failureReason, 0);
-        }
-
-        @Override
-        public void onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode,
-                String resultData, Bundle resultExtras) {
-            if (pendingIntent.equals(mPendingIntent)) {
-                mCallbackIntent = intent;
-                mCallbackHelper.notifyCalled();
-            }
-        }
-    }
-
-    /**
-     * Creates the simplest intent that is sufficient to let {@link ChromeLauncherActivity} launch
-     * the {@link CustomTabActivity}.
-     */
-    public static Intent createMinimalCustomTabIntent(
-            Context context, String url) {
-        return createCustomTabIntent(context, url, builder -> {});
-    }
-
-    /**
-     * Creates an Intent that launches a CustomTabActivity, allows some customization.
-     */
-    public static Intent createCustomTabIntent(
-            Context context, String url, Callback<CustomTabsIntent.Builder> customizer) {
-        CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(
-                CustomTabsSession.createMockSessionForTesting(
-                        new ComponentName(context, ChromeLauncherActivity.class)));
-        customizer.onResult(builder);
-        CustomTabsIntent customTabsIntent = builder.build();
-        Intent intent = customTabsIntent.intent;
-        intent.setAction(Intent.ACTION_VIEW);
-        intent.setData(Uri.parse(url));
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        return intent;
-    }
-
-    /**
-     * Creates the simplest intent that that is sufficient to let {@link ChromeLauncherActivity}
-     * launch the incognito {@link CustomTabActivity}.
-     *
-     * @param context The instrumentation context to use.
-     * @param url The URL to load in the incognito CCT.
-     * @return Returns the intent to launch the incognito CCT.
-     */
-    public static Intent createMinimalIncognitoCustomTabIntent(Context context, String url) {
-        Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(context, url);
-        intent.putExtra(IntentHandler.EXTRA_OPEN_NEW_INCOGNITO_TAB, true);
-        return intent;
-    }
-
-    /**
-     * Creates the simplest intent that is sufficient to let {@link ChromeLauncherActivity} launch
-     * the {@link CustomTabActivity}. Allows specification of a theme.
-     * @param context The instrumentation context to use.
-     * @param url The URL to load in the incognito CCT.
-     * @param inNightMode Whether the CCT should be launched in night mode.
-     * @return Returns the intent to launch the incognito CCT.
-     */
-    public static Intent createMinimalCustomTabIntentWithTheme(
-            Context context, String url, boolean inNightMode) {
-        return createCustomTabIntent(context, url, builder -> {
-            builder.setColorScheme(inNightMode ? CustomTabsIntent.COLOR_SCHEME_DARK
-                                               : CustomTabsIntent.COLOR_SCHEME_LIGHT);
-        });
-    }
-
     public static CustomTabsConnection setUpConnection() {
         CustomTabsConnection connection = CustomTabsConnection.getInstance();
         connection.resetThrottling(Process.myUid());
@@ -216,87 +117,6 @@
     }
 
     /**
-     * Add a bundle specifying a a number of custom menu entries.
-     *
-     * @param customTabIntent The intent to modify.
-     * @param numEntries The number of menu entries to add.
-     * @param menuTitle The title of the menu.
-     *
-     * @return The pending intent associated with the menu entries.
-     */
-    public static PendingIntent addMenuEntriesToIntent(
-            Intent customTabIntent, int numEntries, String menuTitle) {
-        return addMenuEntriesToIntent(customTabIntent, numEntries, new Intent(), menuTitle);
-    }
-
-    /**
-     * Add a bundle specifying a custom menu entry.
-     *
-     * @param customTabIntent The intent to modify.
-     * @param numEntries The number of menu entries to add.
-     * @param callbackIntent The intent to use as the base for the pending intent.
-     * @param menuTitle The title of the menu.
-     *
-     * @return The pending intent associated with the menu entry.
-     */
-    public static PendingIntent addMenuEntriesToIntent(
-            Intent customTabIntent, int numEntries, Intent callbackIntent, String menuTitle) {
-        PendingIntent pi = PendingIntent.getBroadcast(InstrumentationRegistry.getTargetContext(), 0,
-                callbackIntent,
-                PendingIntent.FLAG_UPDATE_CURRENT
-                        | IntentUtils.getPendingIntentMutabilityFlag(true));
-        ArrayList<Bundle> menuItems = new ArrayList<>();
-        for (int i = 0; i < numEntries; i++) {
-            Bundle bundle = new Bundle();
-            bundle.putString(CustomTabsIntent.KEY_MENU_ITEM_TITLE, menuTitle);
-            bundle.putParcelable(CustomTabsIntent.KEY_PENDING_INTENT, pi);
-            menuItems.add(bundle);
-        }
-        customTabIntent.putParcelableArrayListExtra(CustomTabsIntent.EXTRA_MENU_ITEMS, menuItems);
-        return pi;
-    }
-
-    /**
-     * Creates a CCT Toolbar menu item bundle.
-     *
-     * @param icon The Bitmap icon to be add in the toolbar.
-     * @param description The description about the icon which will be added.
-     * @param pi The pending intent that would be triggered when the icon is clicked on.
-     * @param id A unique id for this new icon.
-     *
-     * @return Returns the bundle encapsulating the toolbar item.
-     */
-    public static Bundle makeToolbarItemBundle(
-            Bitmap icon, String description, PendingIntent pi, int id) {
-        Bundle bundle = new Bundle();
-        bundle.putInt(CustomTabsIntent.KEY_ID, id);
-        bundle.putParcelable(CustomTabsIntent.KEY_ICON, icon);
-        bundle.putString(CustomTabsIntent.KEY_DESCRIPTION, description);
-        bundle.putParcelable(CustomTabsIntent.KEY_PENDING_INTENT, pi);
-        bundle.putBoolean(CustomButtonParamsImpl.SHOW_ON_TOOLBAR, true);
-        return bundle;
-    }
-
-    /**
-     * Adds an action button to the custom tab toolbar.
-     *
-     * @param intent The intent where the action button would be added.
-     * @param icon The icon representing the action button.
-     * @param description The description associated with the action button.
-     * @param id The unique id that would be used for this new Action button.
-     *
-     * @return The {@link PendingIntent} that will be triggered when the action button is clicked.
-     */
-    public static PendingIntent addActionButtonToIntent(
-            Intent intent, Bitmap icon, String description, int id) {
-        PendingIntent pi = PendingIntent.getBroadcast(InstrumentationRegistry.getTargetContext(), 0,
-                new Intent(), IntentUtils.getPendingIntentMutabilityFlag(true));
-        intent.putExtra(CustomTabsIntent.EXTRA_ACTION_BUTTON_BUNDLE,
-                makeToolbarItemBundle(icon, description, pi, id));
-        return pi;
-    }
-
-    /**
      * @return The test bitmap which can be used to represent an action item on the Toolbar.
      */
     public static Bitmap createTestBitmap(int widthDp, int heightDp) {
@@ -307,15 +127,6 @@
     }
 
     /**
-     * Sets the {@link CustomTabsIntent.ShareState} of the custom tab.
-     * @param intent The intent to modify.
-     * @param shareState The {@link CustomTabsIntent.ShareState} being set.
-     */
-    public static void setShareState(Intent intent, int shareState) {
-        intent.putExtra(CustomTabsIntent.EXTRA_SHARE_STATE, shareState);
-    }
-
-    /**
      * @param id Id of the variation to search for.
      *
      * @return true Whether id is a registered variation id.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/DetachedResourceRequestTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/DetachedResourceRequestTest.java
index e5df301..4b76810 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/DetachedResourceRequestTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/DetachedResourceRequestTest.java
@@ -383,7 +383,7 @@
         });
 
         String echoUrl = mServer.getURL("/echoheader?Cookie");
-        Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(mContext, echoUrl);
+        Intent intent = CustomTabsIntentTestUtils.createMinimalCustomTabIntent(mContext, echoUrl);
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent);
 
         Tab tab = mCustomTabActivityTestRule.getActivity().getActivityTab();
@@ -420,7 +420,7 @@
         });
 
         String echoUrl = mServer.getURL("/echoheader?Cookie");
-        Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(mContext, echoUrl);
+        Intent intent = CustomTabsIntentTestUtils.createMinimalCustomTabIntent(mContext, echoUrl);
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent);
 
         Tab tab = mCustomTabActivityTestRule.getActivity().getActivityTab();
@@ -450,7 +450,7 @@
         });
 
         String echoUrl = mServer.getURL("/echoheader?Cookie");
-        Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(mContext, echoUrl);
+        Intent intent = CustomTabsIntentTestUtils.createMinimalCustomTabIntent(mContext, echoUrl);
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent);
 
         Tab tab = mCustomTabActivityTestRule.getActivity().getActivityTab();
@@ -540,7 +540,7 @@
         customTabsCallback.waitForCompletion(0, 1);
 
         String echoUrl = mServer.getURL("/echoheader?Cookie");
-        Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(mContext, echoUrl);
+        Intent intent = CustomTabsIntentTestUtils.createMinimalCustomTabIntent(mContext, echoUrl);
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent);
 
         Tab tab = mCustomTabActivityTestRule.getActivity().getActivityTab();
@@ -563,8 +563,8 @@
             MockSafeBrowsingApiHandler.addMockResponse(
                     url.toString(), "{\"matches\":[{\"threat_type\":\"5\"}]}");
 
-            Intent intent =
-                    CustomTabsTestUtils.createMinimalCustomTabIntent(mContext, url.toString());
+            Intent intent = CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
+                    mContext, url.toString());
             mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent);
 
             Tab tab = mCustomTabActivityTestRule.getActivity().getActivityTab();
@@ -605,7 +605,8 @@
                     url.toString(), "{\"matches\":[{\"threat_type\":\"5\"}]}");
 
             String pageUrl = mServer.getURL("/chrome/test/data/android/cacheable_subresource.html");
-            Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(mContext, pageUrl);
+            Intent intent =
+                    CustomTabsIntentTestUtils.createMinimalCustomTabIntent(mContext, pageUrl);
             mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent);
 
             Tab tab = mCustomTabActivityTestRule.getActivity().getActivityTab();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/IncognitoCustomTabActivityRenderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/IncognitoCustomTabActivityRenderTest.java
index 867b34b..942acde 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/IncognitoCustomTabActivityRenderTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/IncognitoCustomTabActivityRenderTest.java
@@ -86,7 +86,7 @@
 
     private void prepareCCTIntent() {
         String url = mEmbeddedTestServerRule.getServer().getURL(TEST_PAGE);
-        mIntent = CustomTabsTestUtils.createMinimalIncognitoCustomTabIntent(
+        mIntent = CustomTabsIntentTestUtils.createMinimalIncognitoCustomTabIntent(
                 InstrumentationRegistry.getContext(), url);
     }
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/TabReparentingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/TabReparentingTest.java
index 74c3041..764f9fe 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/TabReparentingTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/TabReparentingTest.java
@@ -120,10 +120,10 @@
     }
 
     /**
-     * @see CustomTabsTestUtils#createMinimalCustomTabIntent(Context, String).
+     * @see CustomTabsIntentTestUtils#createMinimalCustomTabIntent(Context, String).
      */
     private Intent createMinimalCustomTabIntent() {
-        return CustomTabsTestUtils.createMinimalCustomTabIntent(
+        return CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                 InstrumentationRegistry.getTargetContext(), mTestPage);
     }
 
@@ -204,7 +204,7 @@
     public void testTabReparentingInfoBar() {
         LocationSettingsTestUtil.setSystemLocationSettingEnabled(true);
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(
-                CustomTabsTestUtils.createMinimalCustomTabIntent(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                         InstrumentationRegistry.getTargetContext(),
                         mTestServer.getURL(POPUP_PAGE)));
         CriteriaHelper.pollUiThread(
@@ -230,7 +230,7 @@
     public void testTabReparentingSelectPopup() throws TimeoutException {
         LocationSettingsTestUtil.setSystemLocationSettingEnabled(true);
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(
-                CustomTabsTestUtils.createMinimalCustomTabIntent(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                         InstrumentationRegistry.getTargetContext(),
                         mTestServer.getURL(SELECT_POPUP_PAGE)));
         CriteriaHelper.pollUiThread(() -> {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/TrustedCdnPublisherUrlTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/TrustedCdnPublisherUrlTest.java
index b0538f5a..b8b622e 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/TrustedCdnPublisherUrlTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/TrustedCdnPublisherUrlTest.java
@@ -363,7 +363,8 @@
         }
         String testUrl = mWebServer.setResponse("/test.html", PAGE_WITH_TITLE, headers);
         Context targetContext = InstrumentationRegistry.getTargetContext();
-        Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(targetContext, testUrl);
+        Intent intent =
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(targetContext, testUrl);
         intent.putExtra(
                 CustomTabsIntent.EXTRA_TITLE_VISIBILITY_STATE, CustomTabsIntent.SHOW_PAGE_TITLE);
         CustomTabsSessionToken token = CustomTabsSessionToken.getSessionTokenFromIntent(intent);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/content/TabObserverRegistrarTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/content/TabObserverRegistrarTest.java
index 8a18cbc..423d7bd 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/content/TabObserverRegistrarTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/content/TabObserverRegistrarTest.java
@@ -19,7 +19,7 @@
 import org.chromium.base.test.util.FlakyTest;
 import org.chromium.chrome.browser.customtabs.CustomTabActivity;
 import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils;
 import org.chromium.chrome.browser.customtabs.content.TabObserverRegistrar.CustomTabTabObserver;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.browser.tab.Tab;
@@ -73,7 +73,7 @@
         final String url2 = testServer.getURL("/chrome/test/data/android/simple.html");
 
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(
-                CustomTabsTestUtils.createMinimalCustomTabIntent(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                         InstrumentationRegistry.getTargetContext(), windowOpenUrl));
 
         // Register TabObserver via TabObserverRegistrar#registerActiveTabObserver()
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/directactions/DirectActionAvailabilityCustomTabTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/directactions/DirectActionAvailabilityCustomTabTest.java
index 82177e3..d6df9c9 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/directactions/DirectActionAvailabilityCustomTabTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/directactions/DirectActionAvailabilityCustomTabTest.java
@@ -22,7 +22,7 @@
 import org.chromium.base.test.util.MinAndroidSdkLevel;
 import org.chromium.chrome.browser.app.ChromeActivity;
 import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.browser.Features.DisableFeatures;
@@ -50,7 +50,7 @@
     @MediumTest
     @Feature({"DirectActions"})
     public void testCoreDirectActionInCustomTabActivity() throws Exception {
-        Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(
+        Intent intent = CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                 InstrumentationRegistry.getTargetContext(), "about:blank");
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent);
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunIntegrationTest.java
index 25703d39..ae5a2e6a 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunIntegrationTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunIntegrationTest.java
@@ -67,7 +67,7 @@
 import org.chromium.chrome.browser.DeferredStartupHandler;
 import org.chromium.chrome.browser.app.ChromeActivity;
 import org.chromium.chrome.browser.customtabs.CustomTabActivity;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils;
 import org.chromium.chrome.browser.document.ChromeLauncherActivity;
 import org.chromium.chrome.browser.enterprise.util.EnterpriseInfo;
 import org.chromium.chrome.browser.enterprise.util.FakeEnterpriseInfo;
@@ -278,7 +278,8 @@
     }
 
     private void launchCustomTabs(String url) {
-        mContext.startActivity(CustomTabsTestUtils.createMinimalCustomTabIntent(mContext, url));
+        mContext.startActivity(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(mContext, url));
     }
 
     private void launchViewIntent(String url) {
@@ -651,7 +652,7 @@
     public void testExitFirstRunWithPolicy() throws Exception {
         initializePreferences(new FirstRunPagesTestCase().withCctTosDisabled());
 
-        Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(mContext, TEST_URL);
+        Intent intent = CustomTabsIntentTestUtils.createMinimalCustomTabIntent(mContext, TEST_URL);
         mContext.startActivity(intent);
 
         FirstRunActivity freActivity = waitForActivity(FirstRunActivity.class);
@@ -676,7 +677,7 @@
         // policy set in this test case.
         FirstRunStatus.setFirstRunSkippedByPolicy(true);
 
-        Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(
+        Intent intent = CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                 mContext, ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
         mContext.startActivity(intent);
         CustomTabActivity activity = waitForActivity(CustomTabActivity.class);
@@ -718,7 +719,7 @@
         skipTosDialogViaPolicy();
         FirstRunStatus.setSkipWelcomePage(true);
 
-        Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(mContext, TEST_URL);
+        Intent intent = CustomTabsIntentTestUtils.createMinimalCustomTabIntent(mContext, TEST_URL);
         mContext.startActivity(intent);
 
         FirstRunActivity freActivity = waitForActivity(FirstRunActivity.class);
@@ -739,7 +740,7 @@
     public void testFastDestroy() {
         // Inspired by crbug.com/1119548, where onDestroy() before triggerLayoutInflation() caused
         // a crash.
-        Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(mContext, TEST_URL);
+        Intent intent = CustomTabsIntentTestUtils.createMinimalCustomTabIntent(mContext, TEST_URL);
         mContext.startActivity(intent);
     }
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/TosAndUmaFirstRunFragmentWithEnterpriseSupportTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/TosAndUmaFirstRunFragmentWithEnterpriseSupportTest.java
index dee7548..3d3f3948 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/TosAndUmaFirstRunFragmentWithEnterpriseSupportTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/TosAndUmaFirstRunFragmentWithEnterpriseSupportTest.java
@@ -49,7 +49,7 @@
 import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
 import org.chromium.chrome.R;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils;
 import org.chromium.chrome.browser.enterprise.util.EnterpriseInfo;
 import org.chromium.chrome.browser.enterprise.util.FakeEnterpriseInfo;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
@@ -724,7 +724,7 @@
 
         // Create an Intent that causes Chrome to run.
         Intent intent =
-                CustomTabsTestUtils.createMinimalCustomTabIntent(context, "https://test.com");
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(context, "https://test.com");
 
         // Start the FRE.
         final ActivityMonitor freMonitor =
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/hardware_acceleration/CustomTabActivityHWATest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/hardware_acceleration/CustomTabActivityHWATest.java
index 43f6807..484f69c 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/hardware_acceleration/CustomTabActivityHWATest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/hardware_acceleration/CustomTabActivityHWATest.java
@@ -14,7 +14,7 @@
 
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 
@@ -31,7 +31,7 @@
     @SmallTest
     public void testHardwareAcceleration() throws Exception {
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(
-                CustomTabsTestUtils.createMinimalCustomTabIntent(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                         InstrumentationRegistry.getTargetContext(), "about:blank"));
         Utils.assertHardwareAcceleration(mCustomTabActivityTestRule.getActivity());
     }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/incognito/IncognitoDataTestUtils.java b/chrome/android/javatests/src/org/chromium/chrome/browser/incognito/IncognitoDataTestUtils.java
index 4172baec..a734e08 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/incognito/IncognitoDataTestUtils.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/incognito/IncognitoDataTestUtils.java
@@ -6,8 +6,8 @@
 
 import static org.junit.Assert.assertEquals;
 
-import static org.chromium.chrome.browser.customtabs.CustomTabsTestUtils.createMinimalCustomTabIntent;
-import static org.chromium.chrome.browser.customtabs.CustomTabsTestUtils.createMinimalIncognitoCustomTabIntent;
+import static org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils.createMinimalCustomTabIntent;
+import static org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils.createMinimalIncognitoCustomTabIntent;
 
 import android.app.Activity;
 import android.content.Context;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/incognito/IncognitoHistoryLeakageTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/incognito/IncognitoHistoryLeakageTest.java
index d2c1e88e..ef2fdcc 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/incognito/IncognitoHistoryLeakageTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/incognito/IncognitoHistoryLeakageTest.java
@@ -29,7 +29,7 @@
 import org.chromium.base.test.util.Criteria;
 import org.chromium.base.test.util.CriteriaHelper;
 import org.chromium.base.test.util.DisableIf;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils;
 import org.chromium.chrome.browser.customtabs.IncognitoCustomTabActivityTestRule;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
@@ -140,7 +140,7 @@
     @LargeTest
     public void testBrowsingHistoryDoNotLeakFromIncognitoCustomTabActivity()
             throws TimeoutException {
-        Intent intent = CustomTabsTestUtils.createMinimalIncognitoCustomTabIntent(
+        Intent intent = CustomTabsIntentTestUtils.createMinimalIncognitoCustomTabIntent(
                 InstrumentationRegistry.getContext(), mTestPage1);
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent);
         List<HistoryItem> historyEntriesOfIncognitoMode =
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/incognito/IncognitoNotificationServiceTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/incognito/IncognitoNotificationServiceTest.java
index 34a7fc5..e4027703 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/incognito/IncognitoNotificationServiceTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/incognito/IncognitoNotificationServiceTest.java
@@ -33,7 +33,7 @@
 import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.MinAndroidSdkLevel;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils;
 import org.chromium.chrome.browser.customtabs.IncognitoCustomTabActivityTestRule;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
@@ -229,7 +229,7 @@
         launchIncognitoTabAndEnsureNotificationDisplayed();
 
         // Create an Incognito CCT now.
-        Intent customTabIntent = CustomTabsTestUtils.createMinimalIncognitoCustomTabIntent(
+        Intent customTabIntent = CustomTabsIntentTestUtils.createMinimalIncognitoCustomTabIntent(
                 InstrumentationRegistry.getContext(), "about:blank");
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(customTabIntent);
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/media/MediaViewerUtilsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/media/MediaViewerUtilsTest.java
index 14c5253e..0de5c18 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/media/MediaViewerUtilsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/media/MediaViewerUtilsTest.java
@@ -18,7 +18,7 @@
 
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.TestContentProvider;
@@ -42,7 +42,7 @@
     @MediumTest
     public void testCustomTabActivityInLightMode() throws Exception {
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(
-                CustomTabsTestUtils.createMinimalCustomTabIntentWithTheme(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntentWithTheme(
                         InstrumentationRegistry.getTargetContext(),
                         ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL, /* inNightMode= */ false));
 
@@ -57,7 +57,7 @@
     @MediumTest
     public void testCustomTabActivityInDarkMode() throws Exception {
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(
-                CustomTabsTestUtils.createMinimalCustomTabIntentWithTheme(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntentWithTheme(
                         InstrumentationRegistry.getTargetContext(),
                         ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL, /* inNightMode= */ true));
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/MainIntentBehaviorMetricsIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/MainIntentBehaviorMetricsIntegrationTest.java
index c86a18d0..040608b 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/MainIntentBehaviorMetricsIntegrationTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/MainIntentBehaviorMetricsIntegrationTest.java
@@ -35,7 +35,6 @@
 import org.chromium.chrome.browser.history.HistoryActivity;
 import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
 import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
-import org.chromium.chrome.browser.settings.PlaceholderSettingsForTest;
 import org.chromium.chrome.browser.settings.SettingsActivity;
 import org.chromium.chrome.browser.settings.SettingsActivityTestRule;
 import org.chromium.chrome.test.ChromeActivityTestRule;
@@ -43,6 +42,7 @@
 import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
 import org.chromium.chrome.test.util.ActivityTestUtils;
 import org.chromium.chrome.test.util.MenuUtils;
+import org.chromium.components.browser_ui.settings.PlaceholderSettingsForTest;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 
 /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettingsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettingsTest.java
index 9d9de1d..2a5495a 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettingsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettingsTest.java
@@ -33,12 +33,12 @@
 import org.chromium.chrome.browser.password_check.PasswordCheckFactory;
 import org.chromium.chrome.browser.preferences.Pref;
 import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.chrome.browser.settings.PlaceholderSettingsForTest;
 import org.chromium.chrome.browser.settings.SettingsActivity;
 import org.chromium.chrome.browser.settings.SettingsActivityTestRule;
 import org.chromium.chrome.browser.sync.SyncService;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.components.browser_ui.settings.ChromeSwitchPreference;
+import org.chromium.components.browser_ui.settings.PlaceholderSettingsForTest;
 import org.chromium.components.prefs.PrefService;
 import org.chromium.components.sync.ModelType;
 import org.chromium.components.sync.PassphraseType;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/privacy/settings/PrivacyPreferencesManagerImplNativeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/privacy/settings/PrivacyPreferencesManagerImplNativeTest.java
index ba4ae4e..be583280 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/privacy/settings/PrivacyPreferencesManagerImplNativeTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/privacy/settings/PrivacyPreferencesManagerImplNativeTest.java
@@ -18,7 +18,6 @@
 import org.chromium.base.ContextUtils;
 import org.chromium.base.test.UiThreadTest;
 import org.chromium.base.test.util.AdvancedMockContext;
-import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
 import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
 import org.chromium.chrome.test.ChromeBrowserTestRule;
@@ -58,7 +57,6 @@
     @SmallTest
     @Feature({"Android-AppBase"})
     @UiThreadTest
-    @DisabledTest(message = "crbug.com/700500")
     public void testSetUsageAndCrashReporting() {
         PermissionContext context =
                 new PermissionContext(InstrumentationRegistry.getTargetContext());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/reengagement/ReengagementNotificationControllerIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/reengagement/ReengagementNotificationControllerIntegrationTest.java
index c6c0251a..66b7ba4 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/reengagement/ReengagementNotificationControllerIntegrationTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/reengagement/ReengagementNotificationControllerIntegrationTest.java
@@ -44,7 +44,7 @@
 import org.chromium.chrome.browser.DefaultBrowserInfo2;
 import org.chromium.chrome.browser.app.reengagement.ReengagementActivity;
 import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils;
 import org.chromium.chrome.browser.feature_engagement.TrackerFactory;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
@@ -107,7 +107,7 @@
         doReturn(true).when(mTracker).shouldTriggerHelpUI(
                 FeatureConstants.CHROME_REENGAGEMENT_NOTIFICATION_1_FEATURE);
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(
-                CustomTabsTestUtils.createMinimalCustomTabIntent(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                         InstrumentationRegistry.getTargetContext(),
                         ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL));
         verify(mTracker, times(1))
@@ -127,7 +127,7 @@
         doReturn(true).when(mTracker).shouldTriggerHelpUI(
                 FeatureConstants.CHROME_REENGAGEMENT_NOTIFICATION_2_FEATURE);
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(
-                CustomTabsTestUtils.createMinimalCustomTabIntent(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                         InstrumentationRegistry.getTargetContext(),
                         ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL));
         verify(mTracker, times(1))
@@ -145,7 +145,7 @@
         DefaultBrowserInfo2.setDefaultInfoForTests(
                 createDefaultInfo(/* passesPrecondition = */ true));
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(
-                CustomTabsTestUtils.createMinimalCustomTabIntent(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                         InstrumentationRegistry.getTargetContext(),
                         ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL));
         verifyHasNoNotifications();
@@ -169,7 +169,7 @@
         DefaultBrowserInfo2.setDefaultInfoForTests(
                 createDefaultInfo(/* passesPrecondition = */ false));
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(
-                CustomTabsTestUtils.createMinimalCustomTabIntent(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                         InstrumentationRegistry.getTargetContext(),
                         ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL));
         verifyHasNoNotifications();
@@ -192,7 +192,7 @@
     public void testReengagementNotificationNotSentDueToUnavailablePreconditions() {
         DefaultBrowserInfo2.setDefaultInfoForTests(null);
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(
-                CustomTabsTestUtils.createMinimalCustomTabIntent(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                         InstrumentationRegistry.getTargetContext(),
                         ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL));
         verifyHasNoNotifications();
@@ -221,7 +221,7 @@
     @SmallTest
     public void testEngagementNotTracked() {
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(
-                CustomTabsTestUtils.createMinimalCustomTabIntent(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                         InstrumentationRegistry.getTargetContext(),
                         ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL));
         verify(mTracker, never()).notifyEvent(EventConstants.STARTED_FROM_MAIN_INTENT);
@@ -251,7 +251,7 @@
         DefaultBrowserInfo2.setDefaultInfoForTests(
                 createDefaultInfo(/* passesPrecondition = */ true));
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(
-                CustomTabsTestUtils.createMinimalCustomTabIntent(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                         InstrumentationRegistry.getTargetContext(),
                         ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL));
         verifyHasNoNotifications();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninHeaderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninHeaderTest.java
index f3aad3cc..89ab5b44 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninHeaderTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninHeaderTest.java
@@ -25,7 +25,7 @@
 import org.chromium.base.library_loader.LibraryLoader;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
@@ -97,7 +97,7 @@
     @MediumTest
     public void testXChromeConnectedHeader_In_CCT_ReturnsModeValueWithIncognitoOff()
             throws TimeoutException {
-        Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(
+        Intent intent = CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                 ContextUtils.getApplicationContext(), mGAIAUrl);
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent);
         Tab tab = mCustomTabActivityTestRule.getActivity().getActivityTab();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/tile/TileGroupUnitTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/tile/TileGroupUnitTest.java
index 1c4dc664..707122c 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/tile/TileGroupUnitTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/tile/TileGroupUnitTest.java
@@ -66,6 +66,7 @@
  */
 @RunWith(BaseJUnit4ClassRunner.class)
 @Batch(Batch.UNIT_TESTS)
+@DisabledTest(message = "https://crbug.com/1330627")
 public class TileGroupUnitTest {
     private static final int MAX_TILES_TO_FETCH = 4;
     private static final int TILE_TITLE_LINES = 1;
@@ -184,11 +185,7 @@
     @Test
     @UiThreadTest
     @SmallTest
-    @DisabledTest(
-            message =
-                    "https://crbug.com/1330627, https://crbug.com/1293208, https://crbug.com/1336742")
-    public void
-    testReceiveNewTilesWithDataChanges() {
+    public void testReceiveNewTilesWithDataChanges() {
         TileGroup tileGroup = initialiseTileGroup(URLS);
 
         // Notify the about different URLs, but the same number. #onTileCountChanged() should not be
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/usage_stats/TabSuspensionTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/usage_stats/TabSuspensionTest.java
index 8419106..dabdd38 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/usage_stats/TabSuspensionTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/usage_stats/TabSuspensionTest.java
@@ -35,7 +35,7 @@
 import org.chromium.chrome.browser.ChromeTabbedActivity2;
 import org.chromium.chrome.browser.MockSafeBrowsingApiHandler;
 import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.browser.multiwindow.MultiWindowTestHelper;
 import org.chromium.chrome.browser.multiwindow.MultiWindowUtils;
@@ -272,7 +272,7 @@
     @Test
     @MediumTest
     public void testTabAddedFromCustomTab() {
-        Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(
+        Intent intent = CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                 InstrumentationRegistry.getTargetContext(), mStartingUrl);
         IntentUtils.addTrustedIntentExtras(intent);
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/rules/CustomTabActivityArTestRule.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/rules/CustomTabActivityArTestRule.java
index ce37717..e1196520 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/rules/CustomTabActivityArTestRule.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/rules/CustomTabActivityArTestRule.java
@@ -10,7 +10,7 @@
 import org.junit.runners.model.Statement;
 
 import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils;
 import org.chromium.chrome.browser.vr.rules.XrActivityRestriction.SupportedActivity;
 import org.chromium.chrome.browser.vr.util.ArTestRuleUtils;
 
@@ -27,7 +27,7 @@
                 ArTestRuleUtils.evaluateArTestRuleImpl(
                         base, desc, CustomTabActivityArTestRule.this, () -> {
                             startCustomTabActivityWithIntent(
-                                    CustomTabsTestUtils.createMinimalCustomTabIntent(
+                                    CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                                             InstrumentationRegistry.getTargetContext(),
                                             "about:blank"));
                         });
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/rules/CustomTabActivityVrTestRule.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/rules/CustomTabActivityVrTestRule.java
index 9e8e5c1..5dc7aa1 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/rules/CustomTabActivityVrTestRule.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/rules/CustomTabActivityVrTestRule.java
@@ -11,7 +11,7 @@
 
 import org.chromium.base.CommandLine;
 import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils;
 import org.chromium.chrome.browser.vr.TestVrShellDelegate;
 import org.chromium.chrome.browser.vr.rules.XrActivityRestriction.SupportedActivity;
 import org.chromium.chrome.browser.vr.util.VrTestRuleUtils;
@@ -32,7 +32,7 @@
                         base, desc, CustomTabActivityVrTestRule.this, () -> {
                             startCustomTabActivityWithIntent(
                                     VrTestRuleUtils.maybeAddStandaloneIntentData(
-                                            CustomTabsTestUtils.createMinimalCustomTabIntent(
+                                            CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                                                     InstrumentationRegistry.getTargetContext(),
                                                     "about:blank")));
                             TestVrShellDelegate.createTestVrShellDelegate(getActivity());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/rules/CustomTabActivityXrTestRule.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/rules/CustomTabActivityXrTestRule.java
index 493d448..34f379b 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/rules/CustomTabActivityXrTestRule.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/rules/CustomTabActivityXrTestRule.java
@@ -10,7 +10,7 @@
 import org.junit.runners.model.Statement;
 
 import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils;
 import org.chromium.chrome.browser.vr.rules.XrActivityRestriction.SupportedActivity;
 
 /**
@@ -23,8 +23,9 @@
         return super.apply(new Statement() {
             @Override
             public void evaluate() throws Throwable {
-                startCustomTabActivityWithIntent(CustomTabsTestUtils.createMinimalCustomTabIntent(
-                        InstrumentationRegistry.getTargetContext(), "about:blank"));
+                startCustomTabActivityWithIntent(
+                        CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
+                                InstrumentationRegistry.getTargetContext(), "about:blank"));
                 base.evaluate();
             }
         }, desc);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappActivityTestRule.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappActivityTestRule.java
index 5c1dcfc..a8ed522 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappActivityTestRule.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappActivityTestRule.java
@@ -26,7 +26,7 @@
 import org.chromium.chrome.browser.app.ChromeActivity;
 import org.chromium.chrome.browser.browserservices.intents.WebappConstants;
 import org.chromium.chrome.browser.browserservices.ui.splashscreen.SplashController;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils;
 import org.chromium.chrome.browser.tab.TabBrowserControlsConstraintsHelper;
 import org.chromium.chrome.test.ChromeActivityTestRule;
 import org.chromium.chrome.test.util.ChromeTabUtils;
@@ -101,7 +101,7 @@
 
     /** Adds a mock Custom Tab session token to the intent. */
     public void addTwaExtrasToIntent(Intent intent) {
-        Intent cctIntent = CustomTabsTestUtils.createMinimalCustomTabIntent(
+        Intent cctIntent = CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                 InstrumentationRegistry.getTargetContext(), "about:blank");
         intent.putExtras(cctIntent.getExtras());
         intent.putExtra(TrustedWebUtils.EXTRA_LAUNCH_AS_TRUSTED_WEB_ACTIVITY, true);
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/omaha/AttributeFinder.java b/chrome/android/junit/src/org/chromium/chrome/browser/omaha/AttributeFinder.java
similarity index 96%
rename from chrome/test/android/javatests/src/org/chromium/chrome/test/omaha/AttributeFinder.java
rename to chrome/android/junit/src/org/chromium/chrome/browser/omaha/AttributeFinder.java
index 749abfe2..32562076 100644
--- a/chrome/test/android/javatests/src/org/chromium/chrome/test/omaha/AttributeFinder.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/omaha/AttributeFinder.java
@@ -2,9 +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.test.omaha;
-
-import android.util.Log;
+package org.chromium.chrome.browser.omaha;
 
 import org.xml.sax.Attributes;
 import org.xml.sax.InputSource;
@@ -12,6 +10,8 @@
 import org.xml.sax.SAXParseException;
 import org.xml.sax.helpers.DefaultHandler;
 
+import org.chromium.base.Log;
+
 import java.io.IOException;
 import java.io.StringReader;
 
@@ -65,4 +65,4 @@
     public String getValue() {
         return mValue;
     }
-}
\ No newline at end of file
+}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omaha/ExponentialBackoffSchedulerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/omaha/ExponentialBackoffSchedulerTest.java
similarity index 85%
rename from chrome/android/javatests/src/org/chromium/chrome/browser/omaha/ExponentialBackoffSchedulerTest.java
rename to chrome/android/junit/src/org/chromium/chrome/browser/omaha/ExponentialBackoffSchedulerTest.java
index 1c267a5..8df1136 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/omaha/ExponentialBackoffSchedulerTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/omaha/ExponentialBackoffSchedulerTest.java
@@ -6,20 +6,20 @@
 
 import android.content.Context;
 import android.content.Intent;
-import android.support.test.InstrumentationRegistry;
-
-import androidx.test.filters.SmallTest;
 
 import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
 
-import org.chromium.base.test.util.AdvancedMockContext;
+import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.base.test.util.Feature;
-import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
+import org.chromium.base.test.util.InMemorySharedPreferencesContext;
 
 /** Tests the ExponentialBackoffScheduler. */
-@RunWith(ChromeJUnit4ClassRunner.class)
+@RunWith(BaseRobolectricTestRunner.class)
+@Config(manifest = Config.NONE)
 public class ExponentialBackoffSchedulerTest {
     private static final String INTENT_STRING = "schedulerIntent";
     private static final String PREFERENCE_NAME = "scheduler";
@@ -30,11 +30,9 @@
      * Checks that the correct number of failures are set/reset.
      */
     @Test
-    @SmallTest
     @Feature({"Omaha", "Sync"})
     public void testExponentialBackoffSchedulerFailureSetting() {
-        Context targetContext = InstrumentationRegistry.getTargetContext();
-        TestContext context = new TestContext(targetContext);
+        TestContext context = new TestContext(RuntimeEnvironment.getApplication());
 
         ExponentialBackoffScheduler writer =
                 new ExponentialBackoffScheduler(PREFERENCE_NAME, context, BACKOFF_MS, MAX_MS);
@@ -55,11 +53,9 @@
      * Check that the delay generated by the scheduler is within the correct range.
      */
     @Test
-    @SmallTest
     @Feature({"Omaha", "Sync"})
     public void testExponentialBackoffSchedulerDelayCalculation() {
-        Context targetContext = InstrumentationRegistry.getTargetContext();
-        TestContext context = new TestContext(targetContext);
+        TestContext context = new TestContext(RuntimeEnvironment.getApplication());
         MockExponentialBackoffScheduler scheduler =
                 new MockExponentialBackoffScheduler(PREFERENCE_NAME, context, BACKOFF_MS, MAX_MS);
 
@@ -87,11 +83,9 @@
      * Check that the alarm is being set by the class.
      */
     @Test
-    @SmallTest
     @Feature({"Omaha", "Sync"})
     public void testExponentialBackoffSchedulerAlarmCreation() {
-        Context targetContext = InstrumentationRegistry.getTargetContext();
-        TestContext context = new TestContext(targetContext);
+        TestContext context = new TestContext(RuntimeEnvironment.getApplication());
 
         MockExponentialBackoffScheduler scheduler =
                 new MockExponentialBackoffScheduler(PREFERENCE_NAME, context, BACKOFF_MS, MAX_MS);
@@ -105,7 +99,7 @@
     /**
      * Ensures that the AlarmManager is the only service requested.
      */
-    private static class TestContext extends AdvancedMockContext {
+    private static class TestContext extends InMemorySharedPreferencesContext {
         public boolean mRequestedAlarmManager;
 
         public TestContext(Context context) {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omaha/MockExponentialBackoffScheduler.java b/chrome/android/junit/src/org/chromium/chrome/browser/omaha/MockExponentialBackoffScheduler.java
similarity index 90%
rename from chrome/android/javatests/src/org/chromium/chrome/browser/omaha/MockExponentialBackoffScheduler.java
rename to chrome/android/junit/src/org/chromium/chrome/browser/omaha/MockExponentialBackoffScheduler.java
index fda5c6b6..74f5957e 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/omaha/MockExponentialBackoffScheduler.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/omaha/MockExponentialBackoffScheduler.java
@@ -18,8 +18,8 @@
     private long mAlarmTimestamp;
     private long mCurrentTimestamp;
 
-    public MockExponentialBackoffScheduler(String packageName, Context context,
-            long baseMilliseconds, long maxMilliseconds) {
+    public MockExponentialBackoffScheduler(
+            String packageName, Context context, long baseMilliseconds, long maxMilliseconds) {
         super(packageName, context, baseMilliseconds, maxMilliseconds);
     }
 
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/omaha/MockRequestGenerator.java b/chrome/android/junit/src/org/chromium/chrome/browser/omaha/MockRequestGenerator.java
similarity index 91%
rename from chrome/test/android/javatests/src/org/chromium/chrome/test/omaha/MockRequestGenerator.java
rename to chrome/android/junit/src/org/chromium/chrome/browser/omaha/MockRequestGenerator.java
index 9099327..814ad5f 100644
--- a/chrome/test/android/javatests/src/org/chromium/chrome/test/omaha/MockRequestGenerator.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/omaha/MockRequestGenerator.java
@@ -2,17 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.chromium.chrome.test.omaha;
+package org.chromium.chrome.browser.omaha;
 
 import android.content.Context;
 
-import org.chromium.chrome.browser.omaha.RequestGenerator;
-
 /** Mocks out the RequestGenerator for tests. */
 public class MockRequestGenerator extends RequestGenerator {
-    public enum DeviceType {
-        HANDSET, TABLET
-    }
+    public enum DeviceType { HANDSET, TABLET }
 
     public static final String UUID_PHONE = "uuid_phone";
     public static final String UUID_TABLET = "uuid_tablet";
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omaha/OmahaBaseTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/omaha/OmahaBaseTest.java
similarity index 94%
rename from chrome/android/javatests/src/org/chromium/chrome/browser/omaha/OmahaBaseTest.java
rename to chrome/android/junit/src/org/chromium/chrome/browser/omaha/OmahaBaseTest.java
index daa94d3f..6db0117f 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/omaha/OmahaBaseTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/omaha/OmahaBaseTest.java
@@ -6,25 +6,25 @@
 
 import android.content.Context;
 import android.content.SharedPreferences;
-import android.support.test.InstrumentationRegistry;
 
 import androidx.annotation.IntDef;
-import androidx.test.filters.SmallTest;
 
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
 
 import org.chromium.base.ApiCompatibilityUtils;
 import org.chromium.base.FeatureList;
-import org.chromium.base.test.util.AdvancedMockContext;
+import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.base.test.util.Feature;
+import org.chromium.base.test.util.InMemorySharedPreferencesContext;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
-import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
-import org.chromium.chrome.test.omaha.MockRequestGenerator;
-import org.chromium.chrome.test.omaha.MockRequestGenerator.DeviceType;
+import org.chromium.chrome.browser.omaha.MockRequestGenerator.DeviceType;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
@@ -47,7 +47,8 @@
  * provides a way to hook into functions to return values that would normally be provided by the
  * system, such as whether Chrome was installed through the system image.
  */
-@RunWith(ChromeJUnit4ClassRunner.class)
+@RunWith(BaseRobolectricTestRunner.class)
+@Config(manifest = Config.NONE)
 public class OmahaBaseTest {
     private static class TimestampPair {
         public long timestampNextRequest;
@@ -149,6 +150,17 @@
         }
     }
 
+    private static class ClosableThreadAssertsDisabler implements AutoCloseable {
+        ClosableThreadAssertsDisabler() {
+            ThreadUtils.setThreadAssertsDisabledForTesting(true);
+        }
+
+        @Override
+        public void close() throws Exception {
+            ThreadUtils.setThreadAssertsDisabledForTesting(false);
+        }
+    }
+
     @IntDef({InstallSource.SYSTEM_IMAGE, InstallSource.ORGANIC})
     @Retention(RetentionPolicy.SOURCE)
     private @interface InstallSource {
@@ -170,7 +182,7 @@
         int TIMES_OUT = 1;
     }
 
-    private AdvancedMockContext mContext;
+    private InMemorySharedPreferencesContext mContext;
     private MockOmahaDelegate mDelegate;
     private MockOmahaBase mOmahaBase;
 
@@ -187,9 +199,8 @@
 
     @Before
     public void setUp() {
-        Context targetContext = InstrumentationRegistry.getTargetContext();
         OmahaBase.setIsDisabledForTesting(false);
-        mContext = new AdvancedMockContext(targetContext);
+        mContext = new InMemorySharedPreferencesContext(RuntimeEnvironment.getApplication());
         FeatureList.TestValues overrides = new FeatureList.TestValues();
         overrides.addFeatureFlagOverride(ChromeFeatureList.ANONYMOUS_UPDATE_CHECKS, true);
         FeatureList.setTestValues(overrides);
@@ -279,7 +290,6 @@
     }
 
     @Test
-    @SmallTest
     @Feature({"Omaha"})
     public void testPipelineFreshInstall() {
         final long now = 11684;
@@ -308,7 +318,6 @@
     }
 
     @Test
-    @SmallTest
     @Feature({"Omaha"})
     public void testPipelineRegularPing() {
         final long now = 11684;
@@ -342,7 +351,6 @@
     }
 
     @Test
-    @SmallTest
     @Feature({"Omaha"})
     public void testPipelineFreshInstallUpdatedAvailable_crbug_1095755() {
         final long now = 11684;
@@ -368,7 +376,6 @@
     }
 
     @Test
-    @SmallTest
     @Feature({"Omaha"})
     public void testPipelineRegularPingUpdateAvailable_crbug_1095755() {
         final long now = 11684;
@@ -401,7 +408,6 @@
     }
 
     @Test
-    @SmallTest
     @Feature({"Omaha"})
     public void testTooEarlyToPing() {
         final long now = 0;
@@ -430,7 +436,6 @@
     }
 
     @Test
-    @SmallTest
     @Feature({"Omaha"})
     public void testTooEarlyToPostExistingRequest() {
         final long timeGeneratedRequest = 0L;
@@ -473,7 +478,6 @@
     }
 
     @Test
-    @SmallTest
     @Feature({"Omaha"})
     public void testPostExistingRequestSuccessfully() {
         final long timeGeneratedRequest = 0L;
@@ -518,7 +522,6 @@
     }
 
     @Test
-    @SmallTest
     @Feature({"Omaha"})
     public void testPostExistingButFails() {
         final long timeGeneratedRequest = 0L;
@@ -565,7 +568,6 @@
     }
 
     @Test
-    @SmallTest
     @Feature({"Omaha"})
     public void testTimestampWithinBounds() {
         final long now = 0L;
@@ -603,7 +605,6 @@
     }
 
     @Test
-    @SmallTest
     @Feature({"Omaha"})
     public void testOverdueRequestCausesNewRegistration() {
         final long timeGeneratedRequest = 0L;
@@ -648,9 +649,8 @@
     }
 
     @Test
-    @SmallTest
     @Feature({"Omaha"})
-    public void testCheckForUpdatesConnectionTimesOut() {
+    public void testCheckForUpdatesConnectionTimesOut() throws Exception {
         final long now = 10000L;
 
         mDelegate = new MockOmahaDelegate(mContext, DeviceType.HANDSET, InstallSource.ORGANIC);
@@ -659,14 +659,16 @@
                 ServerResponse.FAILURE, ConnectionStatus.TIMES_OUT, DeviceType.HANDSET);
 
         @OmahaBase.UpdateStatus
-        int status = mOmahaBase.checkForUpdates();
+        int status;
+        try (ClosableThreadAssertsDisabler ignored = new ClosableThreadAssertsDisabler()) {
+            status = mOmahaBase.checkForUpdates();
+        }
         Assert.assertEquals(OmahaBase.UpdateStatus.OFFLINE, status);
     }
 
     @Test
-    @SmallTest
     @Feature({"Omaha"})
-    public void testCheckForUpdatesUpdated() {
+    public void testCheckForUpdatesUpdated() throws Exception {
         final long now = 10000L;
         final String version = "89.0.12.5342";
 
@@ -677,14 +679,16 @@
         mOmahaBase.setUpdateVersion(version);
 
         @OmahaBase.UpdateStatus
-        int status = mOmahaBase.checkForUpdates();
+        int status;
+        try (ClosableThreadAssertsDisabler ignored = new ClosableThreadAssertsDisabler()) {
+            status = mOmahaBase.checkForUpdates();
+        }
         Assert.assertEquals(OmahaBase.UpdateStatus.UPDATED, status);
     }
 
     @Test
-    @SmallTest
     @Feature({"Omaha"})
-    public void testCheckForUpdatesOutdated() {
+    public void testCheckForUpdatesOutdated() throws Exception {
         final long now = 10000L;
         final String oldVersion = "89.0.12.5342";
         final String newVersion = "89.0.13.1242";
@@ -696,14 +700,16 @@
         mOmahaBase.setUpdateVersion(newVersion);
 
         @OmahaBase.UpdateStatus
-        int status = mOmahaBase.checkForUpdates();
+        int status;
+        try (ClosableThreadAssertsDisabler ignored = new ClosableThreadAssertsDisabler()) {
+            status = mOmahaBase.checkForUpdates();
+        }
         Assert.assertEquals(OmahaBase.UpdateStatus.OUTDATED, status);
     }
 
     @Test
-    @SmallTest
     @Feature({"Omaha"})
-    public void testCheckForUpdatesFailedIncorrectNewVersion() {
+    public void testCheckForUpdatesFailedIncorrectNewVersion() throws Exception {
         final long now = 10000L;
         final String oldVersion = "89.0.12.5342";
         final String newVersion = "Unknown";
@@ -715,14 +721,16 @@
         mOmahaBase.setUpdateVersion(newVersion);
 
         @OmahaBase.UpdateStatus
-        int status = mOmahaBase.checkForUpdates();
+        int status;
+        try (ClosableThreadAssertsDisabler ignored = new ClosableThreadAssertsDisabler()) {
+            status = mOmahaBase.checkForUpdates();
+        }
         Assert.assertEquals(OmahaBase.UpdateStatus.FAILED, status);
     }
 
     @Test
-    @SmallTest
     @Feature({"Omaha"})
-    public void testCheckForUpdatesFailedIncorrectOldVersion() {
+    public void testCheckForUpdatesFailedIncorrectOldVersion() throws Exception {
         final long now = 10000L;
         final String oldVersion = "Unknown";
         final String newVersion = "89.0.13.1242";
@@ -734,7 +742,10 @@
         mOmahaBase.setUpdateVersion(newVersion);
 
         @OmahaBase.UpdateStatus
-        int status = mOmahaBase.checkForUpdates();
+        int status;
+        try (ClosableThreadAssertsDisabler ignored = new ClosableThreadAssertsDisabler()) {
+            status = mOmahaBase.checkForUpdates();
+        }
         Assert.assertEquals(OmahaBase.UpdateStatus.FAILED, status);
     }
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omaha/RequestGeneratorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/omaha/RequestGeneratorTest.java
similarity index 84%
rename from chrome/android/javatests/src/org/chromium/chrome/browser/omaha/RequestGeneratorTest.java
rename to chrome/android/junit/src/org/chromium/chrome/browser/omaha/RequestGeneratorTest.java
index c6cb305a..20d832d 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/omaha/RequestGeneratorTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/omaha/RequestGeneratorTest.java
@@ -9,37 +9,32 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-
-import androidx.test.filters.SmallTest;
-
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
 
-import org.chromium.base.test.util.AdvancedMockContext;
+import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.base.test.util.Feature;
 import org.chromium.chrome.browser.flags.CachedFeatureFlags;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
+import org.chromium.chrome.browser.omaha.MockRequestGenerator.DeviceType;
 import org.chromium.chrome.browser.signin.services.IdentityServicesProvider;
 import org.chromium.chrome.browser.uid.SettingsSecureBasedIdentificationGenerator;
 import org.chromium.chrome.browser.uid.UniqueIdentificationGenerator;
 import org.chromium.chrome.browser.uid.UniqueIdentificationGeneratorFactory;
-import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
-import org.chromium.chrome.test.omaha.AttributeFinder;
-import org.chromium.chrome.test.omaha.MockRequestGenerator;
-import org.chromium.chrome.test.omaha.MockRequestGenerator.DeviceType;
 import org.chromium.chrome.test.util.browser.signin.AccountManagerTestRule;
 import org.chromium.components.signin.identitymanager.IdentityManager;
 
 /**
  * Unit tests for the RequestGenerator class.
  */
-@RunWith(ChromeJUnit4ClassRunner.class)
+@RunWith(BaseRobolectricTestRunner.class)
+@Config(manifest = Config.NONE)
 public class RequestGeneratorTest {
     private static final String INSTALL_SOURCE = "install_source";
 
@@ -58,7 +53,6 @@
     }
 
     @Test
-    @SmallTest
     @Feature({"Omaha"})
     public void testInstallAgeNewInstallation() {
         long currentTimestamp = 201207310000L;
@@ -69,7 +63,6 @@
     }
 
     @Test
-    @SmallTest
     @Feature({"Omaha"})
     public void testInstallAge() {
         long currentTimestamp = 201207310000L;
@@ -82,25 +75,21 @@
     /**
      * Checks whether the install age function is behaving according to spec.
      */
-    void checkInstallAge(long currentTimestamp, long installTimestamp, boolean installing,
-            long expectedAge) {
-        long actualAge = RequestGenerator.installAge(currentTimestamp, installTimestamp,
-                installing);
+    void checkInstallAge(
+            long currentTimestamp, long installTimestamp, boolean installing, long expectedAge) {
+        long actualAge =
+                RequestGenerator.installAge(currentTimestamp, installTimestamp, installing);
         Assert.assertEquals("Install ages differed.", expectedAge, actualAge);
     }
 
     @Test
-    @SmallTest
     @Feature({"Omaha"})
     public void testConstructorRegistersIdentificationGenerator() {
-        Context targetContext = InstrumentationRegistry.getTargetContext();
-        AdvancedMockContext context = new AdvancedMockContext(targetContext);
-
         // First clear the current set of generators.
         UniqueIdentificationGeneratorFactory.clearGeneratorMapForTest();
 
         // Creating a RequestGenerator should register the identification generator.
-        new MockRequestGenerator(context, DeviceType.HANDSET);
+        new MockRequestGenerator(RuntimeEnvironment.getApplication(), DeviceType.HANDSET);
 
         // Verify the identification generator exists and is of the correct type.
         UniqueIdentificationGenerator instance = UniqueIdentificationGeneratorFactory.getInstance(
@@ -109,35 +98,30 @@
     }
 
     @Test
-    @SmallTest
     @Feature({"Omaha"})
     public void testHandsetXMLCreationWithInstall() {
         createAndCheckXML(DeviceType.HANDSET, true);
     }
 
     @Test
-    @SmallTest
     @Feature({"Omaha"})
     public void testHandsetXMLCreationWithoutInstall() {
         createAndCheckXML(DeviceType.HANDSET, false);
     }
 
     @Test
-    @SmallTest
     @Feature({"Omaha"})
     public void testTabletXMLCreationWithInstall() {
         createAndCheckXML(DeviceType.TABLET, true);
     }
 
     @Test
-    @SmallTest
     @Feature({"Omaha"})
     public void testTabletXMLCreationWithoutInstall() {
         createAndCheckXML(DeviceType.TABLET, false);
     }
 
     @Test
-    @SmallTest
     @Feature({"Omaha"})
     public void testXMLCreationWithUID() {
         CachedFeatureFlags.setForTesting(ChromeFeatureList.ANONYMOUS_UPDATE_CHECKS, false);
@@ -146,9 +130,8 @@
                 .thenReturn(mock(IdentityManager.class));
         when(IdentityServicesProvider.get().getIdentityManager(any()).hasPrimaryAccount(anyInt()))
                 .thenReturn(true);
-        MockRequestGenerator generator = new MockRequestGenerator(
-                new AdvancedMockContext(InstrumentationRegistry.getTargetContext()),
-                DeviceType.TABLET);
+        MockRequestGenerator generator =
+                new MockRequestGenerator(RuntimeEnvironment.getApplication(), DeviceType.TABLET);
         String xml = null;
         try {
             xml = generator.generateXML(
@@ -163,9 +146,6 @@
      * Checks that the XML is being created properly.
      */
     private RequestGenerator createAndCheckXML(DeviceType deviceType, boolean sendInstallEvent) {
-        Context targetContext = InstrumentationRegistry.getTargetContext();
-        AdvancedMockContext context = new AdvancedMockContext(targetContext);
-
         IdentityServicesProvider.setInstanceForTests(mock(IdentityServicesProvider.class));
         when(IdentityServicesProvider.get().getIdentityManager(any()))
                 .thenReturn(mock(IdentityManager.class));
@@ -178,7 +158,8 @@
         long installAge = 42;
         int dateLastActive = 4088;
 
-        MockRequestGenerator generator = new MockRequestGenerator(context, deviceType);
+        MockRequestGenerator generator =
+                new MockRequestGenerator(RuntimeEnvironment.getApplication(), deviceType);
 
         String xml = null;
         try {
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/omaha/StringSanitizerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/omaha/StringSanitizerTest.java
index 6b1b512..7741e9d 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/omaha/StringSanitizerTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/omaha/StringSanitizerTest.java
@@ -4,8 +4,6 @@
 
 package org.chromium.chrome.browser.omaha;
 
-import androidx.test.filters.SmallTest;
-
 import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -17,7 +15,6 @@
 @RunWith(BaseRobolectricTestRunner.class)
 public class StringSanitizerTest {
     @Test
-    @SmallTest
     @Feature({"Omaha"})
     public void testSanitizeStrings() {
         Assert.assertEquals("normal string", StringSanitizer.sanitize("Normal string"));
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 36d395b..05050b0d 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -7082,6 +7082,10 @@
     {"shimless-rma-os-update", flag_descriptions::kShimlessRMAOsUpdateName,
      flag_descriptions::kShimlessRMAOsUpdateDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(chromeos::features::kShimlessRMAOsUpdate)},
+    {"shimless-rma-disable-dark-mode",
+     flag_descriptions::kShimlessRMADisableDarkModeName,
+     flag_descriptions::kShimlessRMADisableDarkModeDescription, kOsCrOS,
+     FEATURE_VALUE_TYPE(chromeos::features::kShimlessRMADisableDarkMode)},
     {"nearby-sharing-arc", flag_descriptions::kNearbySharingArcName,
      flag_descriptions::kNearbySharingArcDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(arc::kEnableArcNearbyShare)},
diff --git a/chrome/browser/apps/app_service/publishers/arc_apps.cc b/chrome/browser/apps/app_service/publishers/arc_apps.cc
index e3e07ca2..c9675ad 100644
--- a/chrome/browser/apps/app_service/publishers/arc_apps.cc
+++ b/chrome/browser/apps/app_service/publishers/arc_apps.cc
@@ -184,6 +184,7 @@
       return true;
     case apps::mojom::PermissionType::kUnknown:
     case apps::mojom::PermissionType::kPrinting:
+    case apps::mojom::PermissionType::kFileHandling:
       return false;
   }
 }
diff --git a/chrome/browser/apps/platform_apps/api/BUILD.gn b/chrome/browser/apps/platform_apps/api/BUILD.gn
index cc2543c..bb6609d 100644
--- a/chrome/browser/apps/platform_apps/api/BUILD.gn
+++ b/chrome/browser/apps/platform_apps/api/BUILD.gn
@@ -111,6 +111,7 @@
   }
   visibility += [
     ":api_registration",
+    "//chrome/browser/ash",
     "//chrome/browser/chromeos",
   ]
 }
diff --git a/chrome/browser/ash/BUILD.gn b/chrome/browser/ash/BUILD.gn
index a543e5c..e3222c8e 100644
--- a/chrome/browser/ash/BUILD.gn
+++ b/chrome/browser/ash/BUILD.gn
@@ -1288,12 +1288,640 @@
     "kerberos/kerberos_credentials_manager_factory.h",
     "kerberos/kerberos_ticket_expiry_notification.cc",
     "kerberos/kerberos_ticket_expiry_notification.h",
+    "language_preferences.cc",
+    "language_preferences.h",
+    "locale_change_guard.cc",
+    "locale_change_guard.h",
+    "lock_screen_apps/app_manager.h",
+    "lock_screen_apps/app_manager_impl.cc",
+    "lock_screen_apps/app_manager_impl.h",
+    "lock_screen_apps/app_window_metrics_tracker.cc",
+    "lock_screen_apps/app_window_metrics_tracker.h",
+    "lock_screen_apps/first_app_run_toast_manager.cc",
+    "lock_screen_apps/first_app_run_toast_manager.h",
+    "lock_screen_apps/focus_cycler_delegate.h",
+    "lock_screen_apps/lock_screen_helper.cc",
+    "lock_screen_apps/lock_screen_helper.h",
+    "lock_screen_apps/lock_screen_profile_creator.cc",
+    "lock_screen_apps/lock_screen_profile_creator.h",
+    "lock_screen_apps/lock_screen_profile_creator_impl.cc",
+    "lock_screen_apps/lock_screen_profile_creator_impl.h",
+    "lock_screen_apps/state_controller.cc",
+    "lock_screen_apps/state_controller.h",
+    "lock_screen_apps/state_observer.h",
+    "lock_screen_apps/toast_dialog_view.cc",
+    "lock_screen_apps/toast_dialog_view.h",
+    "logging.cc",
+    "logging.h",
+    "login/active_directory_migration_utils.cc",
+    "login/active_directory_migration_utils.h",
+    "login/app_mode/kiosk_launch_controller.cc",
+    "login/app_mode/kiosk_launch_controller.h",
+    "login/auth/chrome_cryptohome_authenticator.cc",
+    "login/auth/chrome_cryptohome_authenticator.h",
+    "login/auth/chrome_login_performer.cc",
+    "login/auth/chrome_login_performer.h",
+    "login/auth/chrome_safe_mode_delegate.cc",
+    "login/auth/chrome_safe_mode_delegate.h",
+    "login/challenge_response_auth_keys_loader.cc",
+    "login/challenge_response_auth_keys_loader.h",
+    "login/chrome_restart_request.cc",
+    "login/chrome_restart_request.h",
+    "login/configuration_keys.cc",
+    "login/configuration_keys.h",
+    "login/consolidated_consent_field_trial.cc",
+    "login/consolidated_consent_field_trial.h",
+    "login/demo_mode/demo_extensions_external_loader.cc",
+    "login/demo_mode/demo_extensions_external_loader.h",
+    "login/demo_mode/demo_mode_resources_remover.cc",
+    "login/demo_mode/demo_mode_resources_remover.h",
+    "login/demo_mode/demo_resources.cc",
+    "login/demo_mode/demo_resources.h",
+    "login/demo_mode/demo_session.cc",
+    "login/demo_mode/demo_session.h",
+    "login/demo_mode/demo_setup_controller.cc",
+    "login/demo_mode/demo_setup_controller.h",
+    "login/easy_unlock/chrome_proximity_auth_client.cc",
+    "login/easy_unlock/chrome_proximity_auth_client.h",
+    "login/easy_unlock/easy_unlock_auth_attempt.cc",
+    "login/easy_unlock/easy_unlock_auth_attempt.h",
+    "login/easy_unlock/easy_unlock_challenge_wrapper.cc",
+    "login/easy_unlock/easy_unlock_challenge_wrapper.h",
+    "login/easy_unlock/easy_unlock_create_keys_operation.cc",
+    "login/easy_unlock/easy_unlock_create_keys_operation.h",
+    "login/easy_unlock/easy_unlock_get_keys_operation.cc",
+    "login/easy_unlock/easy_unlock_get_keys_operation.h",
+    "login/easy_unlock/easy_unlock_key_manager.cc",
+    "login/easy_unlock/easy_unlock_key_manager.h",
+    "login/easy_unlock/easy_unlock_key_names.cc",
+    "login/easy_unlock/easy_unlock_key_names.h",
+    "login/easy_unlock/easy_unlock_metrics.cc",
+    "login/easy_unlock/easy_unlock_metrics.h",
+    "login/easy_unlock/easy_unlock_notification_controller.cc",
+    "login/easy_unlock/easy_unlock_notification_controller.h",
+    "login/easy_unlock/easy_unlock_refresh_keys_operation.cc",
+    "login/easy_unlock/easy_unlock_refresh_keys_operation.h",
+    "login/easy_unlock/easy_unlock_remove_keys_operation.cc",
+    "login/easy_unlock/easy_unlock_remove_keys_operation.h",
+    "login/easy_unlock/easy_unlock_service.cc",
+    "login/easy_unlock/easy_unlock_service.h",
+    "login/easy_unlock/easy_unlock_service_factory.cc",
+    "login/easy_unlock/easy_unlock_service_factory.h",
+    "login/easy_unlock/easy_unlock_service_regular.cc",
+    "login/easy_unlock/easy_unlock_service_regular.h",
+    "login/easy_unlock/easy_unlock_service_signin.cc",
+    "login/easy_unlock/easy_unlock_service_signin.h",
+    "login/easy_unlock/easy_unlock_tpm_key_manager.cc",
+    "login/easy_unlock/easy_unlock_tpm_key_manager.h",
+    "login/easy_unlock/easy_unlock_tpm_key_manager_factory.cc",
+    "login/easy_unlock/easy_unlock_tpm_key_manager_factory.h",
+    "login/easy_unlock/easy_unlock_types.cc",
+    "login/easy_unlock/easy_unlock_types.h",
+    "login/easy_unlock/easy_unlock_user_login_flow.cc",
+    "login/easy_unlock/easy_unlock_user_login_flow.h",
+    "login/easy_unlock/smartlock_feature_usage_metrics.cc",
+    "login/easy_unlock/smartlock_feature_usage_metrics.h",
+    "login/easy_unlock/smartlock_state_handler.cc",
+    "login/easy_unlock/smartlock_state_handler.h",
+    "login/enrollment/auto_enrollment_check_screen.cc",
+    "login/enrollment/auto_enrollment_check_screen.h",
+    "login/enrollment/auto_enrollment_check_screen_view.h",
+    "login/enrollment/auto_enrollment_controller.cc",
+    "login/enrollment/auto_enrollment_controller.h",
+    "login/enrollment/enrollment_screen.cc",
+    "login/enrollment/enrollment_screen.h",
+    "login/enrollment/enrollment_screen_view.h",
+    "login/enrollment/enrollment_uma.cc",
+    "login/enrollment/enrollment_uma.h",
+    "login/enrollment/enterprise_enrollment_helper.cc",
+    "login/enrollment/enterprise_enrollment_helper.h",
+    "login/enrollment/enterprise_enrollment_helper_impl.cc",
+    "login/enrollment/enterprise_enrollment_helper_impl.h",
+    "login/enterprise_user_session_metrics.cc",
+    "login/enterprise_user_session_metrics.h",
+    "login/error_screens_histogram_helper.cc",
+    "login/error_screens_histogram_helper.h",
+    "login/existing_user_controller.cc",
+    "login/existing_user_controller.h",
+    "login/gaia_reauth_token_fetcher.cc",
+    "login/gaia_reauth_token_fetcher.h",
+    "login/hats_unlock_survey_trigger.cc",
+    "login/hats_unlock_survey_trigger.h",
+    "login/help_app_launcher.cc",
+    "login/help_app_launcher.h",
+    "login/helper.cc",
+    "login/helper.h",
+    "login/hwid_checker.cc",
+    "login/hwid_checker.h",
+    "login/lock/screen_locker.cc",
+    "login/lock/screen_locker.h",
+    "login/lock/views_screen_locker.cc",
+    "login/lock/views_screen_locker.h",
+    "login/lock_screen_utils.cc",
+    "login/lock_screen_utils.h",
+    "login/login_auth_recorder.cc",
+    "login/login_auth_recorder.h",
+    "login/login_client_cert_usage_observer.cc",
+    "login/login_client_cert_usage_observer.h",
+    "login/login_pref_names.cc",
+    "login/login_pref_names.h",
+    "login/login_screen_extensions_lifetime_manager.cc",
+    "login/login_screen_extensions_lifetime_manager.h",
+    "login/login_screen_extensions_storage_cleaner.cc",
+    "login/login_screen_extensions_storage_cleaner.h",
+    "login/login_wizard.h",
+    "login/marketing_backend_connector.cc",
+    "login/marketing_backend_connector.h",
+    "login/mojo_system_info_dispatcher.cc",
+    "login/mojo_system_info_dispatcher.h",
+    "login/onboarding_user_activity_counter.cc",
+    "login/onboarding_user_activity_counter.h",
+    "login/oobe_configuration.cc",
+    "login/oobe_configuration.h",
+    "login/oobe_screen.cc",
+    "login/oobe_screen.h",
+    "login/profile_auth_data.cc",
+    "login/profile_auth_data.h",
+    "login/quick_unlock/auth_token.cc",
+    "login/quick_unlock/auth_token.h",
+    "login/quick_unlock/fake_pin_salt_storage.cc",
+    "login/quick_unlock/fake_pin_salt_storage.h",
+    "login/quick_unlock/fingerprint_power_button_race_detector.cc",
+    "login/quick_unlock/fingerprint_power_button_race_detector.h",
+    "login/quick_unlock/fingerprint_storage.cc",
+    "login/quick_unlock/fingerprint_storage.h",
+    "login/quick_unlock/fingerprint_utils.cc",
+    "login/quick_unlock/fingerprint_utils.h",
+    "login/quick_unlock/pin_backend.cc",
+    "login/quick_unlock/pin_backend.h",
+    "login/quick_unlock/pin_salt_storage.cc",
+    "login/quick_unlock/pin_salt_storage.h",
+    "login/quick_unlock/pin_storage_cryptohome.cc",
+    "login/quick_unlock/pin_storage_cryptohome.h",
+    "login/quick_unlock/pin_storage_prefs.cc",
+    "login/quick_unlock/pin_storage_prefs.h",
+    "login/quick_unlock/quick_unlock_factory.cc",
+    "login/quick_unlock/quick_unlock_factory.h",
+    "login/quick_unlock/quick_unlock_storage.cc",
+    "login/quick_unlock/quick_unlock_storage.h",
+    "login/quick_unlock/quick_unlock_utils.cc",
+    "login/quick_unlock/quick_unlock_utils.h",
+    "login/reauth_stats.cc",
+    "login/reauth_stats.h",
+    "login/reporting/login_logout_reporter.cc",
+    "login/reporting/login_logout_reporter.h",
+    "login/saml/in_session_password_change_manager.cc",
+    "login/saml/in_session_password_change_manager.h",
+    "login/saml/in_session_password_sync_manager.cc",
+    "login/saml/in_session_password_sync_manager.h",
+    "login/saml/in_session_password_sync_manager_factory.cc",
+    "login/saml/in_session_password_sync_manager_factory.h",
+    "login/saml/password_change_success_notification.cc",
+    "login/saml/password_change_success_notification.h",
+    "login/saml/password_expiry_notification.cc",
+    "login/saml/password_expiry_notification.h",
+    "login/saml/password_sync_token_checkers_collection.cc",
+    "login/saml/password_sync_token_checkers_collection.h",
+    "login/saml/password_sync_token_fetcher.cc",
+    "login/saml/password_sync_token_fetcher.h",
+    "login/saml/password_sync_token_login_checker.cc",
+    "login/saml/password_sync_token_login_checker.h",
+    "login/saml/password_sync_token_verifier.cc",
+    "login/saml/password_sync_token_verifier.h",
+    "login/saml/password_sync_token_verifier_factory.cc",
+    "login/saml/password_sync_token_verifier_factory.h",
+    "login/saml/public_saml_url_fetcher.cc",
+    "login/saml/public_saml_url_fetcher.h",
+    "login/saml/saml_metric_utils.cc",
+    "login/saml/saml_metric_utils.h",
+    "login/saml/saml_profile_prefs.cc",
+    "login/saml/saml_profile_prefs.h",
+    "login/screen_manager.cc",
+    "login/screen_manager.h",
+    "login/screens/active_directory_login_screen.cc",
+    "login/screens/active_directory_login_screen.h",
+    "login/screens/active_directory_password_change_screen.cc",
+    "login/screens/active_directory_password_change_screen.h",
+    "login/screens/app_downloading_screen.cc",
+    "login/screens/app_downloading_screen.h",
+    "login/screens/arc_terms_of_service_screen.cc",
+    "login/screens/arc_terms_of_service_screen.h",
+    "login/screens/assistant_optin_flow_screen.cc",
+    "login/screens/assistant_optin_flow_screen.h",
+    "login/screens/base_screen.cc",
+    "login/screens/base_screen.h",
+    "login/screens/chrome_user_selection_screen.cc",
+    "login/screens/chrome_user_selection_screen.h",
+    "login/screens/chromevox_hint/chromevox_hint_detector.cc",
+    "login/screens/chromevox_hint/chromevox_hint_detector.h",
+    "login/screens/consolidated_consent_screen.cc",
+    "login/screens/consolidated_consent_screen.h",
+    "login/screens/demo_preferences_screen.cc",
+    "login/screens/demo_preferences_screen.h",
+    "login/screens/demo_setup_screen.cc",
+    "login/screens/demo_setup_screen.h",
+    "login/screens/device_disabled_screen.cc",
+    "login/screens/device_disabled_screen.h",
+    "login/screens/edu_coexistence_login_screen.cc",
+    "login/screens/edu_coexistence_login_screen.h",
+    "login/screens/enable_adb_sideloading_screen.cc",
+    "login/screens/enable_adb_sideloading_screen.h",
+    "login/screens/enable_debugging_screen.cc",
+    "login/screens/enable_debugging_screen.h",
+    "login/screens/encryption_migration_mode.h",
+    "login/screens/encryption_migration_screen.cc",
+    "login/screens/encryption_migration_screen.h",
+    "login/screens/error_screen.cc",
+    "login/screens/error_screen.h",
+    "login/screens/eula_screen.cc",
+    "login/screens/eula_screen.h",
+    "login/screens/family_link_notice_screen.cc",
+    "login/screens/family_link_notice_screen.h",
+    "login/screens/fingerprint_setup_screen.cc",
+    "login/screens/fingerprint_setup_screen.h",
+    "login/screens/gaia_password_changed_screen.cc",
+    "login/screens/gaia_password_changed_screen.h",
+    "login/screens/gaia_screen.cc",
+    "login/screens/gaia_screen.h",
+    "login/screens/gesture_navigation_screen.cc",
+    "login/screens/gesture_navigation_screen.h",
+    "login/screens/guest_tos_screen.cc",
+    "login/screens/guest_tos_screen.h",
+    "login/screens/hardware_data_collection_screen.cc",
+    "login/screens/hardware_data_collection_screen.h",
+    "login/screens/hid_detection_screen.cc",
+    "login/screens/hid_detection_screen.h",
+    "login/screens/kiosk_autolaunch_screen.cc",
+    "login/screens/kiosk_autolaunch_screen.h",
+    "login/screens/kiosk_enable_screen.cc",
+    "login/screens/kiosk_enable_screen.h",
+    "login/screens/lacros_data_migration_screen.cc",
+    "login/screens/lacros_data_migration_screen.h",
+    "login/screens/locale_switch_screen.cc",
+    "login/screens/locale_switch_screen.h",
+    "login/screens/management_transition_screen.cc",
+    "login/screens/management_transition_screen.h",
+    "login/screens/marketing_opt_in_screen.cc",
+    "login/screens/marketing_opt_in_screen.h",
+    "login/screens/multidevice_setup_screen.cc",
+    "login/screens/multidevice_setup_screen.h",
+    "login/screens/network_error.cc",
+    "login/screens/network_error.h",
+    "login/screens/network_screen.cc",
+    "login/screens/network_screen.h",
+    "login/screens/offline_login_screen.cc",
+    "login/screens/offline_login_screen.h",
+    "login/screens/os_install_screen.cc",
+    "login/screens/os_install_screen.h",
+    "login/screens/os_trial_screen.cc",
+    "login/screens/os_trial_screen.h",
+    "login/screens/packaged_license_screen.cc",
+    "login/screens/packaged_license_screen.h",
+    "login/screens/parental_handoff_screen.cc",
+    "login/screens/parental_handoff_screen.h",
+    "login/screens/pin_setup_screen.cc",
+    "login/screens/pin_setup_screen.h",
+    "login/screens/quick_start_screen.cc",
+    "login/screens/quick_start_screen.h",
+    "login/screens/recommend_apps/fake_recommend_apps_fetcher.cc",
+    "login/screens/recommend_apps/fake_recommend_apps_fetcher.h",
+    "login/screens/recommend_apps/recommend_apps_fetcher.cc",
+    "login/screens/recommend_apps/recommend_apps_fetcher.h",
+    "login/screens/recommend_apps/recommend_apps_fetcher_delegate.h",
+    "login/screens/recommend_apps/recommend_apps_fetcher_impl.cc",
+    "login/screens/recommend_apps/recommend_apps_fetcher_impl.h",
+    "login/screens/recommend_apps_screen.cc",
+    "login/screens/recommend_apps_screen.h",
+    "login/screens/reset_screen.cc",
+    "login/screens/reset_screen.h",
+    "login/screens/saml_confirm_password_screen.cc",
+    "login/screens/saml_confirm_password_screen.h",
+    "login/screens/signin_fatal_error_screen.cc",
+    "login/screens/signin_fatal_error_screen.h",
+    "login/screens/smart_privacy_protection_screen.cc",
+    "login/screens/smart_privacy_protection_screen.h",
+    "login/screens/sync_consent_screen.cc",
+    "login/screens/sync_consent_screen.h",
+    "login/screens/terms_of_service_screen.cc",
+    "login/screens/terms_of_service_screen.h",
+    "login/screens/theme_selection_screen.cc",
+    "login/screens/theme_selection_screen.h",
+    "login/screens/tpm_error_screen.cc",
+    "login/screens/tpm_error_screen.h",
+    "login/screens/update_required_screen.cc",
+    "login/screens/update_required_screen.h",
+    "login/screens/update_screen.cc",
+    "login/screens/update_screen.h",
+    "login/screens/user_creation_screen.cc",
+    "login/screens/user_creation_screen.h",
+    "login/screens/user_selection_screen.cc",
+    "login/screens/user_selection_screen.h",
+    "login/screens/welcome_screen.cc",
+    "login/screens/welcome_screen.h",
+    "login/screens/wrong_hwid_screen.cc",
+    "login/screens/wrong_hwid_screen.h",
+    "login/security_token_pin_dialog_host_login_impl.cc",
+    "login/security_token_pin_dialog_host_login_impl.h",
+    "login/security_token_session_controller.cc",
+    "login/security_token_session_controller.h",
+    "login/security_token_session_controller_factory.cc",
+    "login/security_token_session_controller_factory.h",
+    "login/session/chrome_session_manager.cc",
+    "login/session/chrome_session_manager.h",
+    "login/session/user_session_initializer.cc",
+    "login/session/user_session_initializer.h",
+    "login/session/user_session_manager.cc",
+    "login/session/user_session_manager.h",
+    "login/signin/auth_error_observer.cc",
+    "login/signin/auth_error_observer.h",
+    "login/signin/auth_error_observer_factory.cc",
+    "login/signin/auth_error_observer_factory.h",
+    "login/signin/merge_session_navigation_throttle.cc",
+    "login/signin/merge_session_navigation_throttle.h",
+    "login/signin/merge_session_throttling_utils.cc",
+    "login/signin/merge_session_throttling_utils.h",
+    "login/signin/oauth2_login_manager.cc",
+    "login/signin/oauth2_login_manager.h",
+    "login/signin/oauth2_login_manager_factory.cc",
+    "login/signin/oauth2_login_manager_factory.h",
+    "login/signin/oauth2_login_verifier.cc",
+    "login/signin/oauth2_login_verifier.h",
+    "login/signin/oauth2_token_fetcher.cc",
+    "login/signin/oauth2_token_fetcher.h",
+    "login/signin/oauth2_token_initializer.cc",
+    "login/signin/oauth2_token_initializer.h",
+    "login/signin/offline_signin_limiter.cc",
+    "login/signin/offline_signin_limiter.h",
+    "login/signin/offline_signin_limiter_factory.cc",
+    "login/signin/offline_signin_limiter_factory.h",
+    "login/signin/signin_error_notifier.cc",
+    "login/signin/signin_error_notifier.h",
+    "login/signin/signin_error_notifier_factory.cc",
+    "login/signin/signin_error_notifier_factory.h",
+    "login/signin/token_handle_fetcher.cc",
+    "login/signin/token_handle_fetcher.h",
+    "login/signin/token_handle_util.cc",
+    "login/signin/token_handle_util.h",
+    "login/signin_partition_manager.cc",
+    "login/signin_partition_manager.h",
+    "login/signin_specifics.h",
+    "login/startup_utils.cc",
+    "login/startup_utils.h",
+    "login/ui/captive_portal_dialog_delegate.cc",
+    "login/ui/captive_portal_dialog_delegate.h",
+    "login/ui/captive_portal_view.cc",
+    "login/ui/captive_portal_view.h",
+    "login/ui/captive_portal_window_proxy.cc",
+    "login/ui/captive_portal_window_proxy.h",
+    "login/ui/input_events_blocker.cc",
+    "login/ui/input_events_blocker.h",
+    "login/ui/kiosk_app_menu_controller.cc",
+    "login/ui/kiosk_app_menu_controller.h",
+    "login/ui/login_display.cc",
+    "login/ui/login_display.h",
+    "login/ui/login_display_host.cc",
+    "login/ui/login_display_host.h",
+    "login/ui/login_display_host_common.cc",
+    "login/ui/login_display_host_common.h",
+    "login/ui/login_display_host_mojo.cc",
+    "login/ui/login_display_host_mojo.h",
+    "login/ui/login_display_host_webui.cc",
+    "login/ui/login_display_host_webui.h",
+    "login/ui/login_display_mojo.cc",
+    "login/ui/login_display_mojo.h",
+    "login/ui/login_display_webui.cc",
+    "login/ui/login_display_webui.h",
+    "login/ui/login_feedback.cc",
+    "login/ui/login_feedback.h",
+    "login/ui/login_screen_extension_ui/create_options.cc",
+    "login/ui/login_screen_extension_ui/create_options.h",
+    "login/ui/login_screen_extension_ui/dialog_delegate.cc",
+    "login/ui/login_screen_extension_ui/dialog_delegate.h",
+    "login/ui/login_screen_extension_ui/web_dialog_view.cc",
+    "login/ui/login_screen_extension_ui/web_dialog_view.h",
+    "login/ui/login_screen_extension_ui/window.cc",
+    "login/ui/login_screen_extension_ui/window.h",
+    "login/ui/login_web_dialog.cc",
+    "login/ui/login_web_dialog.h",
+    "login/ui/oobe_dialog_size_utils.cc",
+    "login/ui/oobe_dialog_size_utils.h",
+    "login/ui/oobe_ui_dialog_delegate.cc",
+    "login/ui/oobe_ui_dialog_delegate.h",
+    "login/ui/signin_ui.h",
+    "login/ui/simple_web_view_dialog.cc",
+    "login/ui/simple_web_view_dialog.h",
+    "login/ui/user_adding_screen.cc",
+    "login/ui/user_adding_screen.h",
+    "login/ui/user_adding_screen_input_methods_controller.cc",
+    "login/ui/user_adding_screen_input_methods_controller.h",
+    "login/ui/views/user_board_view.h",
+    "login/ui/web_contents_forced_title.cc",
+    "login/ui/web_contents_forced_title.h",
+    "login/ui/webui_login_view.cc",
+    "login/ui/webui_login_view.h",
+    "login/user_board_view_mojo.cc",
+    "login/user_board_view_mojo.h",
+    "login/user_flow.cc",
+    "login/user_flow.h",
+    "login/user_online_signin_notifier.cc",
+    "login/user_online_signin_notifier.h",
+    "login/users/affiliation.cc",
+    "login/users/affiliation.h",
+    "login/users/avatar/user_image_file_selector.cc",
+    "login/users/avatar/user_image_file_selector.h",
+    "login/users/avatar/user_image_loader.cc",
+    "login/users/avatar/user_image_loader.h",
+    "login/users/avatar/user_image_manager.cc",
+    "login/users/avatar/user_image_manager.h",
+    "login/users/avatar/user_image_manager_impl.cc",
+    "login/users/avatar/user_image_manager_impl.h",
+    "login/users/avatar/user_image_sync_observer.cc",
+    "login/users/avatar/user_image_sync_observer.h",
+    "login/users/chrome_user_manager.cc",
+    "login/users/chrome_user_manager.h",
+    "login/users/chrome_user_manager_impl.cc",
+    "login/users/chrome_user_manager_impl.h",
+    "login/users/chrome_user_manager_util.cc",
+    "login/users/chrome_user_manager_util.h",
+    "login/users/default_user_image/default_user_images.cc",
+    "login/users/default_user_image/default_user_images.h",
+    "login/users/multi_profile_user_controller.cc",
+    "login/users/multi_profile_user_controller.h",
+    "login/users/multi_profile_user_controller_delegate.h",
+    "login/users/scoped_test_user_manager.cc",
+    "login/users/scoped_test_user_manager.h",
+    "login/users/supervised_user_manager.h",
+    "login/users/supervised_user_manager_impl.cc",
+    "login/users/supervised_user_manager_impl.h",
+    "login/users/test_users.cc",
+    "login/users/test_users.h",
+    "login/users/user_manager_interface.h",
+    "login/version_info_updater.cc",
+    "login/version_info_updater.h",
+    "login/version_updater/update_time_estimator.cc",
+    "login/version_updater/update_time_estimator.h",
+    "login/version_updater/version_updater.cc",
+    "login/version_updater/version_updater.h",
+    "login/wizard_context.cc",
+    "login/wizard_context.h",
+    "login/wizard_controller.cc",
+    "login/wizard_controller.h",
+    "mobile/mobile_activator.cc",
+    "mobile/mobile_activator.h",
+    "multidevice_setup/auth_token_validator_factory.cc",
+    "multidevice_setup/auth_token_validator_factory.h",
+    "multidevice_setup/auth_token_validator_impl.cc",
+    "multidevice_setup/auth_token_validator_impl.h",
+    "multidevice_setup/multidevice_setup_client_factory.cc",
+    "multidevice_setup/multidevice_setup_client_factory.h",
+    "multidevice_setup/multidevice_setup_service_factory.cc",
+    "multidevice_setup/multidevice_setup_service_factory.h",
+    "multidevice_setup/oobe_completion_tracker_factory.cc",
+    "multidevice_setup/oobe_completion_tracker_factory.h",
+    "nearby/nearby_connections_dependencies_provider.cc",
+    "nearby/nearby_connections_dependencies_provider.h",
+    "nearby/nearby_connections_dependencies_provider_factory.cc",
+    "nearby/nearby_connections_dependencies_provider_factory.h",
+    "nearby/nearby_process_manager_factory.cc",
+    "nearby/nearby_process_manager_factory.h",
+    "nearby/nearby_process_manager_impl.cc",
+    "nearby/nearby_process_manager_impl.h",
+    "net/bluetooth_pref_state_observer.cc",
+    "net/bluetooth_pref_state_observer.h",
+    "net/client_cert_filter.cc",
+    "net/client_cert_filter.h",
+    "net/client_cert_store_ash.cc",
+    "net/client_cert_store_ash.h",
+    "net/delay_network_call.cc",
+    "net/delay_network_call.h",
+    "net/dhcp_wpad_url_client.cc",
+    "net/dhcp_wpad_url_client.h",
+    "net/network_diagnostics/arc_dns_resolution_routine.cc",
+    "net/network_diagnostics/arc_dns_resolution_routine.h",
+    "net/network_diagnostics/arc_http_routine.cc",
+    "net/network_diagnostics/arc_http_routine.h",
+    "net/network_diagnostics/arc_ping_routine.cc",
+    "net/network_diagnostics/arc_ping_routine.h",
+    "net/network_diagnostics/captive_portal_routine.cc",
+    "net/network_diagnostics/captive_portal_routine.h",
+    "net/network_diagnostics/dns_latency_routine.cc",
+    "net/network_diagnostics/dns_latency_routine.h",
+    "net/network_diagnostics/dns_resolution_routine.cc",
+    "net/network_diagnostics/dns_resolution_routine.h",
+    "net/network_diagnostics/dns_resolver_present_routine.cc",
+    "net/network_diagnostics/dns_resolver_present_routine.h",
+    "net/network_diagnostics/gateway_can_be_pinged_routine.cc",
+    "net/network_diagnostics/gateway_can_be_pinged_routine.h",
+    "net/network_diagnostics/has_secure_wifi_connection_routine.cc",
+    "net/network_diagnostics/has_secure_wifi_connection_routine.h",
+    "net/network_diagnostics/host_resolver.cc",
+    "net/network_diagnostics/host_resolver.h",
+    "net/network_diagnostics/http_firewall_routine.cc",
+    "net/network_diagnostics/http_firewall_routine.h",
+    "net/network_diagnostics/http_request_manager.cc",
+    "net/network_diagnostics/http_request_manager.h",
+    "net/network_diagnostics/https_firewall_routine.cc",
+    "net/network_diagnostics/https_firewall_routine.h",
+    "net/network_diagnostics/https_latency_routine.cc",
+    "net/network_diagnostics/https_latency_routine.h",
+    "net/network_diagnostics/lan_connectivity_routine.cc",
+    "net/network_diagnostics/lan_connectivity_routine.h",
+    "net/network_diagnostics/network_diagnostics.cc",
+    "net/network_diagnostics/network_diagnostics.h",
+    "net/network_diagnostics/network_diagnostics_routine.cc",
+    "net/network_diagnostics/network_diagnostics_routine.h",
+    "net/network_diagnostics/network_diagnostics_util.cc",
+    "net/network_diagnostics/network_diagnostics_util.h",
+    "net/network_diagnostics/signal_strength_routine.cc",
+    "net/network_diagnostics/signal_strength_routine.h",
+    "net/network_diagnostics/tls_prober.cc",
+    "net/network_diagnostics/tls_prober.h",
+    "net/network_diagnostics/udp_prober.cc",
+    "net/network_diagnostics/udp_prober.h",
+    "net/network_diagnostics/video_conferencing_routine.cc",
+    "net/network_diagnostics/video_conferencing_routine.h",
+    "net/network_health/network_health.cc",
+    "net/network_health/network_health.h",
+    "net/network_health/network_health_constants.h",
+    "net/network_health/network_health_service.cc",
+    "net/network_health/network_health_service.h",
+    "net/network_health/signal_strength_tracker.cc",
+    "net/network_health/signal_strength_tracker.h",
+    "net/network_portal_detector_impl.cc",
+    "net/network_portal_detector_impl.h",
+    "net/network_portal_detector_test_impl.cc",
+    "net/network_portal_detector_test_impl.h",
+    "net/network_portal_web_dialog.cc",
+    "net/network_portal_web_dialog.h",
+    "net/network_pref_state_observer.cc",
+    "net/network_pref_state_observer.h",
+    "net/network_throttling_observer.cc",
+    "net/network_throttling_observer.h",
+    "net/rollback_network_config/rollback_network_config.cc",
+    "net/rollback_network_config/rollback_network_config.h",
+    "net/rollback_network_config/rollback_network_config_service.cc",
+    "net/rollback_network_config/rollback_network_config_service.h",
+    "net/rollback_network_config/rollback_onc_util.cc",
+    "net/rollback_network_config/rollback_onc_util.h",
+    "net/secure_dns_manager.cc",
+    "net/secure_dns_manager.h",
+    "net/system_proxy_manager.cc",
+    "net/system_proxy_manager.h",
+    "net/traffic_counters_handler.cc",
+    "net/traffic_counters_handler.h",
+    "network_change_manager_client.cc",
+    "network_change_manager_client.h",
+    "night_light/night_light_client.cc",
+    "night_light/night_light_client.h",
+    "note_taking_controller_client.cc",
+    "note_taking_controller_client.h",
+    "note_taking_helper.cc",
+    "note_taking_helper.h",
+    "notifications/adb_sideloading_policy_change_notification.cc",
+    "notifications/adb_sideloading_policy_change_notification.h",
+    "notifications/debugd_notification_handler.cc",
+    "notifications/debugd_notification_handler.h",
+    "notifications/deprecation_notification_controller.cc",
+    "notifications/deprecation_notification_controller.h",
+    "notifications/echo_dialog_listener.h",
+    "notifications/echo_dialog_view.cc",
+    "notifications/echo_dialog_view.h",
+    "notifications/gnubby_notification.cc",
+    "notifications/gnubby_notification.h",
+    "notifications/idle_app_name_notification_view.cc",
+    "notifications/idle_app_name_notification_view.h",
+    "notifications/kiosk_external_update_notification.cc",
+    "notifications/kiosk_external_update_notification.h",
+    "notifications/low_disk_notification.cc",
+    "notifications/low_disk_notification.h",
+    "notifications/request_system_proxy_credentials_view.cc",
+    "notifications/request_system_proxy_credentials_view.h",
+    "notifications/screen_capture_notification_ui_ash.cc",
+    "notifications/screen_capture_notification_ui_ash.h",
+    "notifications/system_proxy_notification.cc",
+    "notifications/system_proxy_notification.h",
+    "notifications/tpm_auto_update_notification.cc",
+    "notifications/tpm_auto_update_notification.h",
+    "notifications/update_required_notification.cc",
+    "notifications/update_required_notification.h",
+    "os_feedback/chrome_os_feedback_delegate.cc",
+    "os_feedback/chrome_os_feedback_delegate.h",
+    "os_feedback/os_feedback_screenshot_manager.cc",
+    "os_feedback/os_feedback_screenshot_manager.h",
+    "ownership/fake_owner_settings_service.cc",
+    "ownership/fake_owner_settings_service.h",
+    "ownership/owner_settings_service_ash.cc",
+    "ownership/owner_settings_service_ash.h",
+    "ownership/owner_settings_service_ash_factory.cc",
+    "ownership/owner_settings_service_ash_factory.h",
   ]
 
   allow_circular_includes_from = [
+    "//chrome/browser/apps/platform_apps/api",
     "//chrome/browser/ash/crosapi",
     "//chrome/browser/chromeos",
     "//chrome/browser/extensions",
+    "//chrome/browser/policy:onc",
   ]
 
   public_deps = [
@@ -1311,16 +1939,22 @@
     "//ash/components/arc/session:connection_holder",
     "//ash/components/attestation",
     "//ash/components/audio",
+    "//ash/components/cryptohome",
     "//ash/components/disks",
     "//ash/components/drivefs",
     "//ash/components/drivefs/mojom",
     "//ash/components/enhanced_network_tts/mojom",
+    "//ash/components/geolocation",
     "//ash/components/login/auth",
+    "//ash/components/login/auth:challenge_response_key",
+    "//ash/components/multidevice",
+    "//ash/components/proximity_auth",
     "//ash/components/settings",
     "//ash/components/tpm",
     "//ash/constants",
     "//ash/public/cpp",
     "//ash/public/cpp/external_arc",
+    "//ash/public/mojom",
     "//ash/services/device_sync/proto",
     "//ash/services/device_sync/public/cpp",
     "//ash/services/ime/public/cpp:structs",
@@ -1328,8 +1962,13 @@
     "//ash/services/multidevice_setup/public/cpp",
     "//ash/services/multidevice_setup/public/cpp:android_sms_app_helper_delegate",
     "//ash/services/multidevice_setup/public/cpp:android_sms_pairing_state_tracker",
+    "//ash/services/multidevice_setup/public/cpp:auth_token_validator",
+    "//ash/services/nearby/public/cpp",
+    "//ash/services/nearby/public/mojom",
+    "//ash/services/secure_channel/public/cpp/client",
     "//ash/webui/eche_app_ui",
     "//ash/webui/guest_os_installer/mojom",
+    "//ash/webui/os_feedback_ui/backend",
     "//base",
     "//build:chromeos_buildflags",
     "//chrome/browser/ash/arc/input_overlay/db/proto",
@@ -1337,6 +1976,8 @@
     "//chrome/browser/ash/crostini:crostini_installer_types_mojom",
     "//chrome/browser/ash/guest_os:guest_os_diagnostics_mojom",
     "//chrome/browser/chromeos",
+    "//chrome/browser/chromeos:device_configuration_proto",
+    "//chrome/browser/chromeos:login_logout_event_proto",
     "//chrome/browser/extensions",
     "//chrome/browser/image_decoder",
     "//chrome/browser/profiles:profile",
@@ -1358,12 +1999,15 @@
     "//chromeos/ash/components/dbus/concierge",
     "//chromeos/ash/components/dbus/concierge:concierge_proto",
     "//chromeos/ash/components/dbus/kerberos:kerberos_proto",
+    "//chromeos/ash/components/dbus/os_install",
     "//chromeos/ash/components/dbus/seneschal",
     "//chromeos/ash/components/dbus/seneschal:seneschal_proto",
     "//chromeos/ash/components/dbus/services",
     "//chromeos/ash/components/dbus/system_clock",
+    "//chromeos/ash/components/dbus/system_proxy:system_proxy_proto",
     "//chromeos/ash/components/memory",
     "//chromeos/ash/components/network/portal_detector",
+    "//chromeos/components/feature_usage",
     "//chromeos/components/onc",
     "//chromeos/components/sharesheet:constants",
     "//chromeos/crosapi/mojom",
@@ -1378,18 +2022,28 @@
     "//chromeos/dbus/common",
     "//chromeos/dbus/constants",
     "//chromeos/dbus/cros_disks",
+    "//chromeos/dbus/cryptohome:cryptohome_proto",
+    "//chromeos/dbus/debug_daemon",
     "//chromeos/dbus/dlcservice",
+    "//chromeos/dbus/gnubby",
     "//chromeos/dbus/missive",
     "//chromeos/dbus/power",
     "//chromeos/dbus/power:power_manager_proto",
     "//chromeos/dbus/resourced",
     "//chromeos/dbus/session_manager",
+    "//chromeos/dbus/tpm_manager",
     "//chromeos/dbus/tpm_manager:tpm_manager_proto",
     "//chromeos/dbus/update_engine",
+    "//chromeos/dbus/userdataauth",
+    "//chromeos/dbus/userdataauth:userdataauth_proto",
+    "//chromeos/login/login_state",
     "//chromeos/metrics",
     "//chromeos/network",
     "//chromeos/services/cros_healthd/public/mojom",
     "//chromeos/services/machine_learning/public/mojom",
+    "//chromeos/services/network_config/public/mojom",
+    "//chromeos/services/network_health/public/mojom",
+    "//chromeos/services/rollback_network_config/public/mojom",
     "//chromeos/ui/base",
     "//components/account_id",
     "//components/account_manager_core",
@@ -1397,6 +2051,7 @@
     "//components/arc",
     "//components/arc/common",
     "//components/autofill/core/browser",
+    "//components/captive_portal/core",
     "//components/content_settings/core/browser",
     "//components/download/content/public",
     "//components/drive",
@@ -1404,8 +2059,11 @@
     "//components/gcm_driver/instance_id",
     "//components/guest_os",
     "//components/invalidation/public",
+    "//components/keep_alive_registry",
     "//components/keyed_service/content",
     "//components/keyed_service/core",
+    "//components/login",
+    "//components/ownership",
     "//components/policy/core/browser",
     "//components/policy/core/common",
     "//components/policy/core/common:common_constants",
@@ -1415,6 +2073,7 @@
     "//components/printing/common:mojo_interfaces",
     "//components/quirks",
     "//components/reporting/proto:record_proto",
+    "//components/reporting/resources:resource_interface",
     "//components/reporting/storage_selector",
     "//components/services/app_service/public/cpp:app_types",
     "//components/services/app_service/public/cpp:app_update",
@@ -1424,12 +2083,16 @@
     "//components/services/app_service/public/mojom:types_headers",
     "//components/services/unzip/public/cpp",
     "//components/session_manager/core",
+    "//components/signin/core/browser",
     "//components/signin/public/identity_manager",
     "//components/soda",
     "//components/storage_monitor",
+    "//components/sync/driver",
     "//components/sync_preferences",
     "//components/user_manager",
+    "//components/version_info",
     "//components/viz/common",
+    "//components/web_modal",
     "//content/public/browser",
     "//crypto",
     "//dbus",
@@ -1439,6 +2102,8 @@
     "//extensions/browser/api/file_handlers",
     "//extensions/browser/api/messaging:native_messaging",
     "//extensions/common",
+    "//extensions/common/api",
+    "//google_apis",
     "//gpu/command_buffer/client",
     "//media:media_buildflags",
     "//media/capture:capture_lib",
@@ -1447,11 +2112,15 @@
     "//mojo/public/cpp/platform",
     "//mojo/public/cpp/system",
     "//net",
+    "//net/traffic_annotation",
     "//services/data_decoder/public/cpp",
     "//services/device/public/mojom",
     "//services/media_session/public/mojom",
     "//services/network/public/cpp",
+    "//services/network/public/cpp:cpp_base",
+    "//services/network/public/mojom",
     "//services/network/public/mojom:cookies_mojom",
+    "//services/network/public/mojom:url_loader_base",
     "//services/tracing/public/cpp",
     "//services/video_capture/public/mojom",
     "//skia",
@@ -1478,6 +2147,8 @@
     "//ui/display/types",
     "//ui/events",
     "//ui/events:dom_keycode_converter",
+    "//ui/events:events_base",
+    "//ui/events/devices",
     "//ui/events/types:headers",
     "//ui/gfx",
     "//ui/gfx:native_widget_types",
@@ -1486,6 +2157,7 @@
     "//ui/message_center/public/cpp",
     "//ui/shell_dialogs",
     "//ui/views",
+    "//ui/views/controls/webview",
     "//ui/web_dialogs",
     "//ui/wm/public",
     "//url",
@@ -1500,64 +2172,80 @@
     "//ash/components/arc/media_session",
     "//ash/components/arc/mojom:notifications",
     "//ash/components/arc/mojom:protected_buffer_manager",
-    "//ash/components/cryptohome",
     "//ash/components/device_activity",
     "//ash/components/fwupd",
+    "//ash/components/hid_detection",
     "//ash/components/login/session",
     "//ash/components/multidevice:stub_multidevice_util",
     "//ash/components/multidevice/logging",
     "//ash/components/peripheral_notification",
     "//ash/components/phonehub",
     "//ash/components/power",
+    "//ash/components/timezone",
     "//ash/keyboard/ui",
-    "//ash/public/mojom",
     "//ash/resources/vector_icons",
     "//ash/services/device_sync",
     "//ash/services/device_sync:stub_device_sync",
     "//ash/services/ime:constants",
+    "//ash/services/multidevice_setup",
+    "//ash/services/multidevice_setup/public/cpp:oobe_completion_tracker",
     "//ash/services/multidevice_setup/public/cpp:prefs",
     "//ash/services/multidevice_setup/public/mojom",
     "//ash/services/secure_channel",
-    "//ash/services/secure_channel/public/cpp/client",
     "//ash/services/secure_channel/public/cpp/shared",
+    "//ash/strings",
     "//ash/webui/camera_app_ui:document_scanning",
     "//ash/webui/file_manager:constants",
     "//ash/webui/file_manager:file_manager_ui",
     "//ash/webui/file_manager:file_manager_untrusted_ui",
     "//ash/webui/guest_os_installer",
+    "//ash/webui/os_feedback_ui/mojom",
     "//ash/webui/shimless_rma",
     "//base:i18n",
     "//build:branding_buildflags",
+    "//cc/base",
     "//chrome/app:chromium_strings",
+    "//chrome/app:command_ids",
     "//chrome/app:generated_resources",
+    "//chrome/app/resources:locale_settings",
     "//chrome/app/theme:theme_resources",
     "//chrome/app/vector_icons",
     "//chrome/browser:browser_process",
+    "//chrome/browser:browser_themes",
     "//chrome/browser:resources",
+    "//chrome/browser:theme_properties",
+    "//chrome/browser/apps/platform_apps",
+    "//chrome/browser/apps/platform_apps/api",
     "//chrome/browser/ash/child_accounts/time_limits/web_time_limit_error_page",
     "//chrome/browser/ash/crosapi:browser_util",
     "//chrome/browser/ash/mojo_service_manager",
+    "//chrome/browser/ash/nearby:bluetooth_adapter_manager",
     "//chrome/browser/ash/system_web_apps",
     "//chrome/browser/ash/system_web_apps/types",
     "//chrome/browser/chromeos:attestation_proto",
     "//chrome/browser/metrics/structured",
+    "//chrome/browser/nearby_sharing/common",
+    "//chrome/browser/nearby_sharing/logging",
+    "//chrome/browser/policy:onc",
     "//chrome/browser/profiles",
     "//chrome/browser/resources:component_extension_resources",
     "//chrome/browser/resources/chromeos:app_icon_resources",
+    "//chrome/browser/supervised_user/supervised_user_features",
     "//chrome/browser/ui/webui/chromeos/crostini_upgrader:mojo_bindings",
     "//chrome/browser/ui/webui/settings/chromeos/constants:mojom",
     "//chrome/browser/webshare:storage",
     "//chrome/common:channel_info",
     "//chrome/common:non_code_constants",
     "//chrome/common/net",
+    "//chromeos/ash/components/assistant:buildflags",
     "//chromeos/ash/components/dbus/biod",
+    "//chromeos/ash/components/dbus/biod:biod_proto",
     "//chromeos/ash/components/dbus/cros_healthd",
     "//chromeos/ash/components/dbus/cups_proxy",
     "//chromeos/ash/components/dbus/fusebox",
     "//chromeos/ash/components/dbus/ip_peripheral",
     "//chromeos/ash/components/dbus/kerberos",
     "//chromeos/ash/components/dbus/media_analytics",
-    "//chromeos/ash/components/dbus/os_install",
     "//chromeos/ash/components/dbus/patchpanel",
     "//chromeos/ash/components/dbus/pciguard",
     "//chromeos/ash/components/dbus/rgbkbd",
@@ -1567,6 +2255,7 @@
     "//chromeos/ash/components/dbus/typecd",
     "//chromeos/ash/components/dbus/upstart",
     "//chromeos/ash/components/hibernate:buildflags",
+    "//chromeos/ash/components/oobe_quick_start",
     "//chromeos/ash/services/assistant/public/cpp",
     "//chromeos/components/cdm_factory_daemon:cdm_factory_daemon_browser",
     "//chromeos/components/chromebox_for_meetings/buildflags",
@@ -1574,6 +2263,7 @@
     "//chromeos/components/local_search_service/public/cpp",
     "//chromeos/components/mojo_bootstrap",
     "//chromeos/components/sensors",
+    "//chromeos/components/sync_wifi",
     "//chromeos/constants",
     "//chromeos/dbus",
     "//chromeos/dbus:plugin_vm_service_proto",
@@ -1584,30 +2274,31 @@
     "//chromeos/dbus/audio",
     "//chromeos/dbus/cdm_factory_daemon",
     "//chromeos/dbus/cryptohome:attestation_proto",
-    "//chromeos/dbus/cryptohome:cryptohome_proto",
-    "//chromeos/dbus/debug_daemon",
     "//chromeos/dbus/dlcservice:dlcservice_proto",
     "//chromeos/dbus/dlp",
     "//chromeos/dbus/dlp:dlp_proto",
+    "//chromeos/dbus/easy_unlock",
     "//chromeos/dbus/federated",
     "//chromeos/dbus/hermes",
     "//chromeos/dbus/human_presence",
+    "//chromeos/dbus/image_loader",
     "//chromeos/dbus/init",
     "//chromeos/dbus/lorgnette_manager",
     "//chromeos/dbus/machine_learning",
+    "//chromeos/dbus/oobe_config",
     "//chromeos/dbus/permission_broker",
-    "//chromeos/dbus/tpm_manager",
+    "//chromeos/dbus/shill",
     "//chromeos/dbus/u2f",
-    "//chromeos/dbus/userdataauth",
     "//chromeos/dbus/util",
     "//chromeos/dbus/virtual_file_provider",
     "//chromeos/dbus/vm_plugin_dispatcher",
     "//chromeos/ime:gencode",
-    "//chromeos/login/login_state",
+    "//chromeos/services/bluetooth_config:in_process_bluetooth_config",
     "//chromeos/services/cros_healthd/private/cpp",
     "//chromeos/services/cros_healthd/public/cpp",
     "//chromeos/services/machine_learning/public/cpp",
-    "//chromeos/services/rollback_network_config/public/mojom",
+    "//chromeos/services/network_config:in_process_instance",
+    "//chromeos/services/network_config/public/cpp",
     "//chromeos/strings",
     "//chromeos/system",
     "//chromeos/ui/vector_icons",
@@ -1615,12 +2306,19 @@
     "//components/arc/common:arc_intent_helper_constants",
     "//components/component_updater",
     "//components/consent_auditor",
+    "//components/constrained_window",
     "//components/content_settings/core/common",
+    "//components/country_codes",
+    "//components/crash/core/app",
+    "//components/crash/core/common:crash_key_lib",
     "//components/crx_file",
     "//components/device_event_log",
     "//components/download/public/common:public",
     "//components/embedder_support:browser_util",
     "//components/exo/server",
+    "//components/feedback",
+    "//components/feedback/content",
+    "//components/flags_ui",
     "//components/gcm_driver",
     "//components/google/core/common",
     "//components/guest_os:prefs",
@@ -1630,8 +2328,12 @@
     "//components/live_caption:constants",
     "//components/metrics",
     "//components/metrics:serialization",
+    "//components/metrics/structured:neutrino_logging",
+    "//components/metrics/structured:neutrino_logging_util",
+    "//components/omnibox/browser:location_bar",
     "//components/onc",
-    "//components/ownership",
+    "//components/password_manager/core/browser",
+    "//components/password_manager/core/browser:hash_password_manager",
     "//components/permissions",
     "//components/policy:generated",
     "//components/pref_registry",
@@ -1648,49 +2350,62 @@
     "//components/services/filesystem/public/mojom",
     "//components/services/unzip/content",
     "//components/services/unzip/public/mojom",
+    "//components/session_manager:base",
     "//components/signin/public/base",
     "//components/spellcheck/browser",
+    "//components/startup_metric_utils/browser",
     "//components/strings:components_strings",
     "//components/sync/base",
-    "//components/sync/driver",
     "//components/sync_sessions",
+    "//components/tracing:startup_tracing",
     "//components/translate/core/browser",
+    "//components/unified_consent",
     "//components/url_matcher",
     "//components/user_prefs",
+    "//components/variations",
     "//components/vector_icons",
-    "//components/version_info",
     "//components/version_info:channel",
+    "//components/web_resource",
     "//components/webapps/browser",
     "//components/webapps/browser:constants",
     "//content/public/common",
+    "//extensions:extensions_browser_resources",
+    "//extensions/browser/api",
+    "//extensions/browser/api/feedback_private",
     "//extensions/browser/api/messaging",
     "//extensions/browser/api/runtime",
     "//extensions/browser/api/virtual_keyboard_private",
     "//extensions/browser/api/virtual_keyboard_private:virtual_keyboard_delegate",
     "//extensions/common:common_constants",
     "//extensions/common:mojom",
-    "//google_apis",
     "//google_apis/common",
     "//gpu/command_buffer/client:gles2_interface",
     "//gpu/command_buffer/common",
+    "//gpu/command_buffer/service",
+    "//gpu/config",
     "//gpu/ipc/common",
+    "//ipc:message_support",
+    "//media",
+    "//media/capture:capture_switches",
     "//media/capture/video/chromeos/mojom:cros_camera_shared",
     "//media/capture/video/chromeos/public",
-    "//net/traffic_annotation",
+    "//mojo/public/cpp/base",
+    "//mojo/public/mojom/base",
     "//pdf:buildflags",
     "//printing",
     "//printing:printing_base",
     "//printing/backend",
     "//printing/mojom",
     "//rlz/buildflags",
+    "//sandbox/policy",
     "//services/audio/public/cpp",
-    "//services/network/public/cpp:cpp_base",
-    "//services/network/public/mojom",
-    "//services/network/public/mojom:url_loader_base",
+    "//services/service_manager/public/cpp",
     "//services/tracing/public/mojom",
     "//third_party/blink/public/common:headers",
     "//third_party/re2",
     "//third_party/securemessage/proto",
+    "//third_party/zlib",
+    "//third_party/zlib/google:compression_utils",
     "//third_party/zlib/google:zip",
     "//ui/accessibility:ax_enums_mojo",
     "//ui/base:features",
@@ -1708,16 +2423,18 @@
     "//ui/content_accelerators",
     "//ui/display/manager",
     "//ui/events:event_constants",
-    "//ui/events:events_base",
     "//ui/events/blink",
     "//ui/gfx:color_utils",
+    "//ui/gfx:gfx_switches",
     "//ui/gfx:memory_buffer",
     "//ui/gfx/codec",
+    "//ui/gfx/geometry:geometry_skia",
+    "//ui/gl",
     "//ui/message_center",
     "//ui/native_theme",
     "//ui/ozone",
+    "//ui/snapshot",
     "//ui/strings:ui_strings",
-    "//ui/views/controls/webview",
     "//ui/wm",
   ]
 
diff --git a/chrome/browser/ash/arc/input_overlay/ui/edit_finish_view.cc b/chrome/browser/ash/arc/input_overlay/ui/edit_finish_view.cc
index e12ea12..a0cddb5 100644
--- a/chrome/browser/ash/arc/input_overlay/ui/edit_finish_view.cc
+++ b/chrome/browser/ash/arc/input_overlay/ui/edit_finish_view.cc
@@ -70,7 +70,6 @@
     ash::StyleUtil::SetUpInkDropForButton(this, gfx::Insets(),
                                           /*highlight_on_hover=*/true,
                                           /*highlight_on_focus=*/true);
-    SetHasInkDropActionOnClick(true);
   }
   ~ChildButton() override = default;
 };
diff --git a/chrome/browser/ash/arc/input_overlay/ui/educational_view.cc b/chrome/browser/ash/arc/input_overlay/ui/educational_view.cc
index 47dcdcc..f9ef38b 100644
--- a/chrome/browser/ash/arc/input_overlay/ui/educational_view.cc
+++ b/chrome/browser/ash/arc/input_overlay/ui/educational_view.cc
@@ -9,6 +9,7 @@
 #include "ash/public/cpp/style/color_provider.h"
 #include "ash/style/ash_color_provider.h"
 #include "ash/style/pill_button.h"
+#include "ash/style/style_util.h"
 #include "base/bind.h"
 #include "chrome/browser/ash/arc/input_overlay/display_overlay_controller.h"
 #include "chrome/grit/component_extension_resources.h"
@@ -52,6 +53,12 @@
 constexpr int kBorderRow3 = 32;
 constexpr int kBorderRow4 = 36;
 constexpr int kBorderSides = 40;
+
+// About focus ring.
+// Gap between focus ring outer edge to label.
+constexpr float kHaloInset = -4;
+// Thickness of focus ring.
+constexpr float kHaloThickness = 2;
 }  // namespace
 
 // static
@@ -170,8 +177,19 @@
         l10n_util::GetStringUTF16(IDS_INPUT_OVERLAY_EDUCATIONAL_ACCEPT_BUTTON),
         ash::PillButton::Type::kIconless,
         /*icon=*/nullptr));
-    accept_button_->SetBackgroundColor(GetContentLayerColor(
-        ash::AshColorProvider::ContentLayerType::kButtonLabelColorBlue));
+    accept_button_->SetButtonTextColor(cros_styles::ResolveColor(
+        cros_styles::ColorName::kButtonLabelColorPrimary, IsDarkModeEnabled()));
+    accept_button_->SetBackgroundColor(cros_styles::ResolveColor(
+        cros_styles::ColorName::kButtonBackgroundColorPrimary,
+        IsDarkModeEnabled()));
+    ash::StyleUtil::SetUpInkDropForButton(accept_button_, gfx::Insets(),
+                                          /*highlight_on_hover=*/true,
+                                          /*highlight_on_focus=*/true);
+    auto* focus_ring = views::FocusRing::Get(accept_button_);
+    focus_ring->SetHaloInset(kHaloInset);
+    focus_ring->SetHaloThickness(kHaloThickness);
+    focus_ring->SetColor(cros_styles::ResolveColor(
+        cros_styles::ColorName::kFocusRingColor, IsDarkModeEnabled()));
   }
   SetBorder(views::CreateEmptyBorder(gfx::Insets::TLBR(0, 0, kBorderRow4, 0)));
   const auto ui_size = GetPreferredSize();
diff --git a/chrome/browser/ash/arc/input_overlay/ui/message_view.cc b/chrome/browser/ash/arc/input_overlay/ui/message_view.cc
index 432eec7..4780870 100644
--- a/chrome/browser/ash/arc/input_overlay/ui/message_view.cc
+++ b/chrome/browser/ash/arc/input_overlay/ui/message_view.cc
@@ -88,11 +88,9 @@
       break;
   }
 
-  auto preferred_size = CalculatePreferredSize();
-  preferred_size.SetSize(
-      std::min(preferred_size.width() + kIconSize + kImageLabelSpace,
-               kMaxTextWidth + kIconSize + kImageLabelSpace + 2 * kSideInset),
-      kMinHeight);
+  auto preferred_size =
+      gfx::Size(kMaxTextWidth + kIconSize + kImageLabelSpace + 2 * kSideInset,
+                kMinHeight);
   preferred_size.SetToMin(parent_size);
   SetSize(preferred_size);
   SetPosition(gfx::Point(
diff --git a/chrome/browser/ash/attestation/soft_bind_attestation_flow.cc b/chrome/browser/ash/attestation/soft_bind_attestation_flow.cc
index e4f0a3d7..935c65d3 100644
--- a/chrome/browser/ash/attestation/soft_bind_attestation_flow.cc
+++ b/chrome/browser/ash/attestation/soft_bind_attestation_flow.cc
@@ -139,13 +139,13 @@
     LOG(ERROR) << "Attestation session failure callback in null.";
     return;
   }
-  std::move(callback_).Run(
-      std::vector<std::string>{"INVALID:" + error_message});
+  std::move(callback_).Run(std::vector<std::string>{"INVALID:" + error_message},
+                           /*valid=*/false);
 }
 
 void SoftBindAttestationFlow::Session::ReportSuccess(
     const std::vector<std::string>& certificate_chain) {
-  std::move(callback_).Run(certificate_chain);
+  std::move(callback_).Run(certificate_chain, /*valid=*/true);
 }
 
 SoftBindAttestationFlow::SoftBindAttestationFlow()
@@ -169,7 +169,8 @@
   if (!IsAttestationAllowedByPolicy()) {
     LOG(ERROR) << "Attestation not allowed by device policy";
     std::move(callback).Run(
-        std::vector<std::string>{"INVALID:attestationNotAllowed"});
+        std::vector<std::string>{"INVALID:attestationNotAllowed"},
+        /*valid=*/false);
     return;
   }
   GetCertificateInternal(
diff --git a/chrome/browser/ash/attestation/soft_bind_attestation_flow.h b/chrome/browser/ash/attestation/soft_bind_attestation_flow.h
index 69930cb9..44cb4a5 100644
--- a/chrome/browser/ash/attestation/soft_bind_attestation_flow.h
+++ b/chrome/browser/ash/attestation/soft_bind_attestation_flow.h
@@ -22,7 +22,8 @@
 class SoftBindAttestationFlow {
  public:
   using Callback =
-      base::OnceCallback<void(const std::vector<std::string>& cert)>;
+      base::OnceCallback<void(const std::vector<std::string>& certs,
+                              bool valid)>;
 
   SoftBindAttestationFlow();
   ~SoftBindAttestationFlow();
diff --git a/chrome/browser/ash/attestation/soft_bind_attestation_flow_unittest.cc b/chrome/browser/ash/attestation/soft_bind_attestation_flow_unittest.cc
index 3a6fa9f..0a62c0a 100644
--- a/chrome/browser/ash/attestation/soft_bind_attestation_flow_unittest.cc
+++ b/chrome/browser/ash/attestation/soft_bind_attestation_flow_unittest.cc
@@ -89,8 +89,10 @@
     return generic_public_key->SerializeAsString();
   }
 
-  void OnAttestationCertificates(const std::vector<std::string>& cert_chain) {
+  void OnAttestationCertificates(const std::vector<std::string>& cert_chain,
+                                 bool valid) {
     result_cert_chain_ = cert_chain;
+    result_validity_ = valid;
   }
 
   void ExpectMockAttestationFlowGetCertificate() {
@@ -150,6 +152,7 @@
   int fake_cert_chain_read_index_;
 
   std::vector<std::string> result_cert_chain_;
+  bool result_validity_;
 };
 
 TEST_F(SoftBindAttestationFlowTest, Success) {
@@ -160,6 +163,7 @@
                                               user_key);
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(2, result_cert_chain_.size());
+  EXPECT_TRUE(result_validity_);
 }
 
 TEST_F(SoftBindAttestationFlowTest, FeatureDisabledByPolicy) {
@@ -170,6 +174,7 @@
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(1, result_cert_chain_.size());
   EXPECT_EQ("INVALID:attestationNotAllowed", result_cert_chain_[0]);
+  EXPECT_FALSE(result_validity_);
 }
 
 TEST_F(SoftBindAttestationFlowTest, NotVerifiedDueToUnspecifiedFailure) {
@@ -182,6 +187,7 @@
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(1, result_cert_chain_.size());
   EXPECT_EQ("INVALID:notVerified", result_cert_chain_[0]);
+  EXPECT_FALSE(result_validity_);
 }
 
 TEST_F(SoftBindAttestationFlowTest, NotVerifiedDueToBadRequestFailure) {
@@ -194,6 +200,7 @@
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(1, result_cert_chain_.size());
   EXPECT_EQ("INVALID:notVerified", result_cert_chain_[0]);
+  EXPECT_FALSE(result_validity_);
 }
 
 TEST_F(SoftBindAttestationFlowTest, Timeout) {
@@ -204,6 +211,7 @@
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(1, result_cert_chain_.size());
   EXPECT_EQ("INVALID:timeout", result_cert_chain_[0]);
+  EXPECT_FALSE(result_validity_);
 }
 
 TEST_F(SoftBindAttestationFlowTest, NearlyExpiredCert) {
@@ -215,6 +223,7 @@
                                               user_key);
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(2, result_cert_chain_.size());
+  EXPECT_TRUE(result_validity_);
   EXPECT_EQ(2, fake_cert_chain_read_index_);
 }
 
@@ -227,6 +236,7 @@
                                               user_key);
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(2, result_cert_chain_.size());
+  EXPECT_TRUE(result_validity_);
   EXPECT_EQ(2, fake_cert_chain_read_index_);
 }
 
@@ -243,6 +253,7 @@
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(1, result_cert_chain_.size());
   EXPECT_EQ("INVALID:tooManyRetries", result_cert_chain_[0]);
+  EXPECT_FALSE(result_validity_);
   EXPECT_EQ(4, fake_cert_chain_read_index_);
 }
 
@@ -260,6 +271,7 @@
                                               user_key);
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(2, result_cert_chain_.size());
+  EXPECT_TRUE(result_validity_);
   EXPECT_EQ(3, fake_cert_chain_read_index_);
 }
 
diff --git a/chrome/browser/ash/dbus/ash_dbus_helper.cc b/chrome/browser/ash/dbus/ash_dbus_helper.cc
index 6ac94d5..a7d8b67 100644
--- a/chrome/browser/ash/dbus/ash_dbus_helper.cc
+++ b/chrome/browser/ash/dbus/ash_dbus_helper.cc
@@ -62,6 +62,7 @@
 #include "chromeos/dbus/session_manager/session_manager_client.h"
 #include "chromeos/dbus/tpm_manager/tpm_manager_client.h"
 #include "chromeos/dbus/u2f/u2f_client.h"
+#include "chromeos/dbus/update_engine/update_engine_client.h"
 #include "chromeos/dbus/userdataauth/arc_quota_client.h"
 #include "chromeos/dbus/userdataauth/cryptohome_misc_client.h"
 #include "chromeos/dbus/userdataauth/cryptohome_pkcs11_client.h"
@@ -159,6 +160,7 @@
   InitializeDBusClient<chromeos::TpmManagerClient>(bus);
   InitializeDBusClient<TypecdClient>(bus);
   InitializeDBusClient<chromeos::U2FClient>(bus);
+  InitializeDBusClient<chromeos::UpdateEngineClient>(bus);
   InitializeDBusClient<chromeos::UserDataAuthClient>(bus);
   InitializeDBusClient<UpstartClient>(bus);
   InitializeDBusClient<chromeos::VmPluginDispatcherClient>(bus);
@@ -220,6 +222,7 @@
   chromeos::VmPluginDispatcherClient::Shutdown();
   UpstartClient::Shutdown();
   chromeos::UserDataAuthClient::Shutdown();
+  chromeos::UpdateEngineClient::Shutdown();
   chromeos::U2FClient::Shutdown();
   TypecdClient::Shutdown();
   chromeos::TpmManagerClient::Shutdown();
diff --git a/chrome/browser/ash/eol_notification_unittest.cc b/chrome/browser/ash/eol_notification_unittest.cc
index 0a03afb..ffd4b43 100644
--- a/chrome/browser/ash/eol_notification_unittest.cc
+++ b/chrome/browser/ash/eol_notification_unittest.cc
@@ -32,10 +32,8 @@
   ~EolNotificationTest() override = default;
 
   void SetUp() override {
-    fake_update_engine_client_ = new FakeUpdateEngineClient();
     DBusThreadManager::Initialize();
-    DBusThreadManager::GetSetterForTesting()->SetUpdateEngineClient(
-        base::WrapUnique<UpdateEngineClient>(fake_update_engine_client_));
+    fake_update_engine_client_ = UpdateEngineClient::InitializeFakeForTest();
     ConciergeClient::InitializeFake(/*fake_cicerone_client=*/nullptr);
     BrowserWithTestWindowTest::SetUp();
 
@@ -61,6 +59,7 @@
     tester_.reset();
     BrowserWithTestWindowTest::TearDown();
     ConciergeClient::Shutdown();
+    UpdateEngineClient::Shutdown();
     DBusThreadManager::Shutdown();
   }
 
diff --git a/chrome/browser/ash/login/screens/update_required_screen_unittest.cc b/chrome/browser/ash/login/screens/update_required_screen_unittest.cc
index 5da8fc931..460675d 100644
--- a/chrome/browser/ash/login/screens/update_required_screen_unittest.cc
+++ b/chrome/browser/ash/login/screens/update_required_screen_unittest.cc
@@ -63,10 +63,8 @@
     // Initialize objects needed by `UpdateRequiredScreen`.
     wizard_context_ = std::make_unique<WizardContext>();
     fake_view_ = std::make_unique<FakeUpdateRequiredScreenHandler>();
-    fake_update_engine_client_ = new FakeUpdateEngineClient();
     DBusThreadManager::Initialize();
-    DBusThreadManager::GetSetterForTesting()->SetUpdateEngineClient(
-        std::unique_ptr<UpdateEngineClient>(fake_update_engine_client_));
+    fake_update_engine_client_ = UpdateEngineClient::InitializeFakeForTest();
 
     network_handler_test_helper_ =
         std::make_unique<chromeos::NetworkHandlerTestHelper>();
@@ -100,6 +98,7 @@
 
     network_portal_detector::Shutdown();
     network_handler_test_helper_.reset();
+    UpdateEngineClient::Shutdown();
     DBusThreadManager::Shutdown();
   }
 
diff --git a/chrome/browser/ash/login/screens/update_screen_unittest.cc b/chrome/browser/ash/login/screens/update_screen_unittest.cc
index f39adb6..a0e6f26c 100644
--- a/chrome/browser/ash/login/screens/update_screen_unittest.cc
+++ b/chrome/browser/ash/login/screens/update_screen_unittest.cc
@@ -76,10 +76,8 @@
     // Initialize objects needed by UpdateScreen.
     wizard_context_ = std::make_unique<WizardContext>();
     PowerManagerClient::InitializeFake();
-    fake_update_engine_client_ = new FakeUpdateEngineClient();
     DBusThreadManager::Initialize();
-    DBusThreadManager::GetSetterForTesting()->SetUpdateEngineClient(
-        std::unique_ptr<UpdateEngineClient>(fake_update_engine_client_));
+    fake_update_engine_client_ = UpdateEngineClient::InitializeFakeForTest();
     network_handler_test_helper_ = std::make_unique<NetworkHandlerTestHelper>();
     mock_network_portal_detector_ = new MockNetworkPortalDetector();
     network_portal_detector::SetNetworkPortalDetector(
@@ -104,6 +102,7 @@
     network_portal_detector::Shutdown();
     network_handler_test_helper_.reset();
     PowerManagerClient::Shutdown();
+    UpdateEngineClient::Shutdown();
     DBusThreadManager::Shutdown();
   }
 
diff --git a/chrome/browser/ash/login/test/oobe_base_test.cc b/chrome/browser/ash/login/test/oobe_base_test.cc
index d94af03..bd4a639 100644
--- a/chrome/browser/ash/login/test/oobe_base_test.cc
+++ b/chrome/browser/ash/login/test/oobe_base_test.cc
@@ -128,13 +128,11 @@
 void OobeBaseTest::SetUpInProcessBrowserTestFixture() {
   MixinBasedInProcessBrowserTest::SetUpInProcessBrowserTestFixture();
 
-  // UpdateEngineClientStubImpl have logic that simulates state changes
+  // UpdateEngineClientDesktopFake has logic that simulates state changes
   // based on timer. It is nice simulation for chromeos-on-linux, but
   // may lead to flakiness in debug/*SAN tests.
   // Set up FakeUpdateEngineClient that does not have any timer-based logic.
-  update_engine_client_ = new FakeUpdateEngineClient;
-  chromeos::DBusThreadManager::GetSetterForTesting()->SetUpdateEngineClient(
-      std::unique_ptr<UpdateEngineClient>(update_engine_client_));
+  update_engine_client_ = UpdateEngineClient::InitializeFakeForTest();
 }
 
 void OobeBaseTest::SetUpOnMainThread() {
diff --git a/chrome/browser/ash/login/version_updater/version_updater_unittest.cc b/chrome/browser/ash/login/version_updater/version_updater_unittest.cc
index 6e75825f..bbdb81e 100644
--- a/chrome/browser/ash/login/version_updater/version_updater_unittest.cc
+++ b/chrome/browser/ash/login/version_updater/version_updater_unittest.cc
@@ -92,10 +92,8 @@
   // testing::Test:
   void SetUp() override {
     // Initialize objects needed by VersionUpdater.
-    fake_update_engine_client_ = new FakeUpdateEngineClient();
     DBusThreadManager::Initialize();
-    DBusThreadManager::GetSetterForTesting()->SetUpdateEngineClient(
-        std::unique_ptr<UpdateEngineClient>(fake_update_engine_client_));
+    fake_update_engine_client_ = UpdateEngineClient::InitializeFakeForTest();
 
     network_handler_test_helper_ =
         std::make_unique<chromeos::NetworkHandlerTestHelper>();
@@ -127,7 +125,7 @@
     network_portal_detector::InitializeForTesting(nullptr);
     network_handler_test_helper_.reset();
 
-    // It will delete `fake_update_engine_client_`.
+    UpdateEngineClient::Shutdown();
     DBusThreadManager::Shutdown();
   }
 
diff --git a/chrome/browser/ash/notifications/update_required_notification_unittest.cc b/chrome/browser/ash/notifications/update_required_notification_unittest.cc
index aa88827..6c6863d 100644
--- a/chrome/browser/ash/notifications/update_required_notification_unittest.cc
+++ b/chrome/browser/ash/notifications/update_required_notification_unittest.cc
@@ -126,12 +126,8 @@
 }
 
 void UpdateRequiredNotificationTest::SetUp() {
-  auto fake_update_engine_client =
-      std::make_unique<chromeos::FakeUpdateEngineClient>();
-  fake_update_engine_client_ = fake_update_engine_client.get();
   chromeos::DBusThreadManager::Initialize();
-  chromeos::DBusThreadManager::GetSetterForTesting()->SetUpdateEngineClient(
-      std::move(fake_update_engine_client));
+  fake_update_engine_client_ = UpdateEngineClient::InitializeFakeForTest();
   network_handler_test_helper_ =
       std::make_unique<chromeos::NetworkHandlerTestHelper>();
 
@@ -157,6 +153,7 @@
 void UpdateRequiredNotificationTest::TearDown() {
   minimum_version_policy_handler_.reset();
   network_handler_test_helper_.reset();
+  UpdateEngineClient::Shutdown();
   chromeos::DBusThreadManager::Shutdown();
 }
 
diff --git a/chrome/browser/ash/policy/core/device_cloud_policy_manager_ash_unittest.cc b/chrome/browser/ash/policy/core/device_cloud_policy_manager_ash_unittest.cc
index 9479965..40b89fd 100644
--- a/chrome/browser/ash/policy/core/device_cloud_policy_manager_ash_unittest.cc
+++ b/chrome/browser/ash/policy/core/device_cloud_policy_manager_ash_unittest.cc
@@ -39,7 +39,6 @@
 #include "chrome/browser/prefs/browser_prefs.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
-#include "chromeos/dbus/common/dbus_client_implementation_type.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/session_manager/fake_session_manager_client.h"
 #include "chromeos/dbus/userdataauth/fake_cryptohome_misc_client.h"
diff --git a/chrome/browser/ash/policy/handlers/minimum_version_policy_handler_browsertest.cc b/chrome/browser/ash/policy/handlers/minimum_version_policy_handler_browsertest.cc
index a38e4669..7e834c4 100644
--- a/chrome/browser/ash/policy/handlers/minimum_version_policy_handler_browsertest.cc
+++ b/chrome/browser/ash/policy/handlers/minimum_version_policy_handler_browsertest.cc
@@ -54,7 +54,6 @@
 #include "chrome/browser/upgrade_detector/upgrade_detector.h"
 #include "chrome/common/pref_names.h"
 #include "chromeos/dbus/constants/dbus_switches.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/shill/shill_service_client.h"
 #include "chromeos/dbus/update_engine/fake_update_engine_client.h"
 #include "chromeos/network/network_state_test_helper.h"
@@ -113,11 +112,8 @@
 
   void SetUpInProcessBrowserTestFixture() override {
     LoginManagerTest::SetUpInProcessBrowserTestFixture();
-    auto fake_update_engine_client =
-        std::make_unique<chromeos::FakeUpdateEngineClient>();
-    fake_update_engine_client_ = fake_update_engine_client.get();
-    chromeos::DBusThreadManager::GetSetterForTesting()->SetUpdateEngineClient(
-        std::move(fake_update_engine_client));
+    fake_update_engine_client_ =
+        chromeos::UpdateEngineClient::InitializeFakeForTest();
     const std::string lsb_release =
         base::StringPrintf("CHROMEOS_RELEASE_VERSION=%s", kCurrentVersion);
     version_info_.emplace(lsb_release, base::Time::Now());
diff --git a/chrome/browser/ash/policy/handlers/minimum_version_policy_handler_unittest.cc b/chrome/browser/ash/policy/handlers/minimum_version_policy_handler_unittest.cc
index 83a2f6b4..532e84b 100644
--- a/chrome/browser/ash/policy/handlers/minimum_version_policy_handler_unittest.cc
+++ b/chrome/browser/ash/policy/handlers/minimum_version_policy_handler_unittest.cc
@@ -24,6 +24,7 @@
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/shill/shill_service_client.h"
 #include "chromeos/dbus/update_engine/fake_update_engine_client.h"
+#include "chromeos/dbus/update_engine/update_engine_client.h"
 #include "chromeos/network/network_handler_test_helper.h"
 #include "components/prefs/pref_service.h"
 #include "content/public/test/browser_task_environment.h"
@@ -108,12 +109,9 @@
 }
 
 void MinimumVersionPolicyHandlerTest::SetUp() {
-  auto fake_update_engine_client =
-      std::make_unique<chromeos::FakeUpdateEngineClient>();
-  fake_update_engine_client_ = fake_update_engine_client.get();
   chromeos::DBusThreadManager::Initialize();
-  chromeos::DBusThreadManager::GetSetterForTesting()->SetUpdateEngineClient(
-      std::move(fake_update_engine_client));
+  fake_update_engine_client_ =
+      chromeos::UpdateEngineClient::InitializeFakeForTest();
   network_handler_test_helper_ =
       std::make_unique<chromeos::NetworkHandlerTestHelper>();
 
@@ -134,6 +132,7 @@
 void MinimumVersionPolicyHandlerTest::TearDown() {
   minimum_version_policy_handler_.reset();
   network_handler_test_helper_.reset();
+  chromeos::UpdateEngineClient::Shutdown();
   chromeos::DBusThreadManager::Shutdown();
 }
 
diff --git a/chrome/browser/ash/policy/scheduled_task_handler/test/device_scheduled_update_checker_unittest.cc b/chrome/browser/ash/policy/scheduled_task_handler/test/device_scheduled_update_checker_unittest.cc
index e2d6979..cecae04 100644
--- a/chrome/browser/ash/policy/scheduled_task_handler/test/device_scheduled_update_checker_unittest.cc
+++ b/chrome/browser/ash/policy/scheduled_task_handler/test/device_scheduled_update_checker_unittest.cc
@@ -124,13 +124,9 @@
     ScopedWakeLock::OverrideWakeLockProviderBinderForTesting(
         base::BindRepeating(&device::TestWakeLockProvider::BindReceiver,
                             base::Unretained(&wake_lock_provider_)));
-    auto fake_update_engine_client =
-        std::make_unique<chromeos::FakeUpdateEngineClient>();
-    fake_update_engine_client_ = fake_update_engine_client.get();
     chromeos::DBusThreadManager::Initialize();
-    chromeos::DBusThreadManager::GetSetterForTesting()->SetUpdateEngineClient(
-        std::move(fake_update_engine_client));
-
+    fake_update_engine_client_ =
+        chromeos::UpdateEngineClient::InitializeFakeForTest();
     chromeos::PowerManagerClient::InitializeFake();
     chromeos::FakePowerManagerClient::Get()->set_tick_clock(
         task_environment_.GetMockTickClock());
@@ -158,6 +154,7 @@
     device_scheduled_update_checker_.reset();
     network_state_test_helper_.reset();
     chromeos::PowerManagerClient::Shutdown();
+    chromeos::UpdateEngineClient::Shutdown();
     chromeos::DBusThreadManager::Shutdown();
     ScopedWakeLock::OverrideWakeLockProviderBinderForTesting(
         base::NullCallback());
diff --git a/chrome/browser/ash/policy/status_collector/child_status_collector_browsertest.cc b/chrome/browser/ash/policy/status_collector/child_status_collector_browsertest.cc
index 0f19c8d..9648ac5 100644
--- a/chrome/browser/ash/policy/status_collector/child_status_collector_browsertest.cc
+++ b/chrome/browser/ash/policy/status_collector/child_status_collector_browsertest.cc
@@ -50,6 +50,7 @@
 #include "chromeos/dbus/power/fake_power_manager_client.h"
 #include "chromeos/dbus/power_manager/idle.pb.h"
 #include "chromeos/dbus/update_engine/fake_update_engine_client.h"
+#include "chromeos/dbus/update_engine/update_engine_client.h"
 #include "chromeos/login/login_state/login_state.h"
 #include "chromeos/system/fake_statistics_provider.h"
 #include "components/account_id/account_id.h"
@@ -173,8 +174,7 @@
   ChildStatusCollectorTest()
       : user_manager_(new ash::MockUserManager()),
         user_manager_enabler_(base::WrapUnique(user_manager_)),
-        user_data_dir_override_(chrome::DIR_USER_DATA),
-        update_engine_client_(new chromeos::FakeUpdateEngineClient) {
+        user_data_dir_override_(chrome::DIR_USER_DATA) {
     scoped_stub_install_attributes_.Get()->SetCloudManaged("managed.com",
                                                            "device_id");
     EXPECT_CALL(*user_manager_, Shutdown()).Times(1);
@@ -199,11 +199,9 @@
 
     TestingBrowserProcess::GetGlobal()->SetLocalState(&local_state_);
 
-    // Use FakeUpdateEngineClient.
     chromeos::DBusThreadManager::Initialize();
-    chromeos::DBusThreadManager::GetSetterForTesting()->SetUpdateEngineClient(
-        base::WrapUnique<chromeos::UpdateEngineClient>(update_engine_client_));
-
+    // Use FakeUpdateEngineClient.
+    chromeos::UpdateEngineClient::InitializeFakeForTest();
     ash::CiceroneClient::InitializeFake();
     ash::ConciergeClient::InitializeFake();
     ash::SeneschalClient::InitializeFake();
@@ -221,6 +219,7 @@
     testing_profile_.reset();
     ash::ConciergeClient::Shutdown();
     ash::CiceroneClient::Shutdown();
+    chromeos::UpdateEngineClient::Shutdown();
     TestingBrowserProcess::GetGlobal()->SetLocalState(nullptr);
 
     // Finish pending tasks.
@@ -434,7 +433,6 @@
   em::ChildStatusReportRequest child_status_;
   std::unique_ptr<TestingChildStatusCollector> status_collector_;
   base::ScopedPathOverride user_data_dir_override_;
-  chromeos::FakeUpdateEngineClient* const update_engine_client_;
   std::unique_ptr<base::RunLoop> run_loop_;
 
   // This property is required to instantiate the session manager, a singleton
diff --git a/chrome/browser/ash/policy/status_collector/device_status_collector_browsertest.cc b/chrome/browser/ash/policy/status_collector/device_status_collector_browsertest.cc
index 90b65969..ed5eeddd 100644
--- a/chrome/browser/ash/policy/status_collector/device_status_collector_browsertest.cc
+++ b/chrome/browser/ash/policy/status_collector/device_status_collector_browsertest.cc
@@ -78,6 +78,7 @@
 #include "chromeos/dbus/shill/shill_service_client.h"
 #include "chromeos/dbus/tpm_manager/tpm_manager_client.h"
 #include "chromeos/dbus/update_engine/fake_update_engine_client.h"
+#include "chromeos/dbus/update_engine/update_engine_client.h"
 #include "chromeos/dbus/userdataauth/userdataauth_client.h"
 #include "chromeos/dbus/vm_applications/apps.pb.h"
 #include "chromeos/login/login_state/login_state.h"
@@ -847,8 +848,7 @@
         fake_web_kiosk_device_local_account_(fake_web_kiosk_app_basic_info_,
                                              kWebKioskAccountId),
         user_data_dir_override_(chrome::DIR_USER_DATA),
-        crash_dumps_dir_override_(chrome::DIR_CRASH_DUMPS),
-        update_engine_client_(new chromeos::FakeUpdateEngineClient) {
+        crash_dumps_dir_override_(chrome::DIR_CRASH_DUMPS) {
     scoped_stub_install_attributes_.Get()->SetCloudManaged("managed.com",
                                                            "device_id");
     EXPECT_CALL(*user_manager_, Shutdown()).Times(1);
@@ -904,8 +904,8 @@
 
     // Use FakeUpdateEngineClient.
     chromeos::DBusThreadManager::Initialize();
-    chromeos::DBusThreadManager::GetSetterForTesting()->SetUpdateEngineClient(
-        base::WrapUnique<chromeos::UpdateEngineClient>(update_engine_client_));
+    update_engine_client_ =
+        chromeos::UpdateEngineClient::InitializeFakeForTest();
     // Async tasks posted when calling `chromeos::DBusThreadManager::Initialize`
     // need to be flushed.
     base::RunLoop().RunUntilIdle();
@@ -939,6 +939,7 @@
     chromeos::PowerManagerClient::Shutdown();
     chromeos::UserDataAuthClient::Shutdown();
     chromeos::CrasAudioHandler::Shutdown();
+    chromeos::UpdateEngineClient::Shutdown();
     ash::KioskAppManager::Shutdown();
     ash::cros_healthd::FakeCrosHealthd::Shutdown();
     TestingBrowserProcess::GetGlobal()->SetLocalState(nullptr);
@@ -1226,7 +1227,7 @@
   const DeviceLocalAccount fake_web_kiosk_device_local_account_;
   base::ScopedPathOverride user_data_dir_override_;
   base::ScopedPathOverride crash_dumps_dir_override_;
-  chromeos::FakeUpdateEngineClient* const update_engine_client_;
+  chromeos::FakeUpdateEngineClient* update_engine_client_;
   std::unique_ptr<base::RunLoop> run_loop_;
   base::test::ScopedFeatureList scoped_feature_list_;
   base::SimpleTestClock test_clock_;
diff --git a/chrome/browser/ash/policy/status_collector/legacy_device_status_collector_browsertest.cc b/chrome/browser/ash/policy/status_collector/legacy_device_status_collector_browsertest.cc
index 169651e..b26a1e7 100644
--- a/chrome/browser/ash/policy/status_collector/legacy_device_status_collector_browsertest.cc
+++ b/chrome/browser/ash/policy/status_collector/legacy_device_status_collector_browsertest.cc
@@ -76,6 +76,7 @@
 #include "chromeos/dbus/shill/shill_service_client.h"
 #include "chromeos/dbus/tpm_manager/tpm_manager_client.h"
 #include "chromeos/dbus/update_engine/fake_update_engine_client.h"
+#include "chromeos/dbus/update_engine/update_engine_client.h"
 #include "chromeos/dbus/userdataauth/userdataauth_client.h"
 #include "chromeos/dbus/vm_applications/apps.pb.h"
 #include "chromeos/login/login_state/login_state.h"
@@ -836,8 +837,7 @@
         fake_web_kiosk_device_local_account_(fake_web_kiosk_app_basic_info_,
                                              kWebKioskAccountId),
         user_data_dir_override_(chrome::DIR_USER_DATA),
-        crash_dumps_dir_override_(chrome::DIR_CRASH_DUMPS),
-        update_engine_client_(new chromeos::FakeUpdateEngineClient) {
+        crash_dumps_dir_override_(chrome::DIR_CRASH_DUMPS) {
     scoped_stub_install_attributes_.Get()->SetCloudManaged("managed.com",
                                                            "device_id");
     EXPECT_CALL(*user_manager_, Shutdown()).Times(1);
@@ -893,8 +893,8 @@
 
     // Use FakeUpdateEngineClient.
     chromeos::DBusThreadManager::Initialize();
-    chromeos::DBusThreadManager::GetSetterForTesting()->SetUpdateEngineClient(
-        base::WrapUnique<chromeos::UpdateEngineClient>(update_engine_client_));
+    update_engine_client_ =
+        chromeos::UpdateEngineClient::InitializeFakeForTest();
     // Async tasks posted when calling `chromeos::DBusThreadManager::Initialize`
     // need to be flushed.
     base::RunLoop().RunUntilIdle();
@@ -928,6 +928,7 @@
     chromeos::PowerManagerClient::Shutdown();
     chromeos::UserDataAuthClient::Shutdown();
     chromeos::CrasAudioHandler::Shutdown();
+    chromeos::UpdateEngineClient::Shutdown();
     ash::KioskAppManager::Shutdown();
     TestingBrowserProcess::GetGlobal()->SetLocalState(nullptr);
 
@@ -1188,7 +1189,7 @@
   const DeviceLocalAccount fake_web_kiosk_device_local_account_;
   base::ScopedPathOverride user_data_dir_override_;
   base::ScopedPathOverride crash_dumps_dir_override_;
-  chromeos::FakeUpdateEngineClient* const update_engine_client_;
+  chromeos::FakeUpdateEngineClient* update_engine_client_;
   std::unique_ptr<base::RunLoop> run_loop_;
   base::test::ScopedFeatureList scoped_feature_list_;
   base::SimpleTestClock test_clock_;
diff --git a/chrome/browser/ash/preferences_unittest.cc b/chrome/browser/ash/preferences_unittest.cc
index bdc06ac1..7a18dd0 100644
--- a/chrome/browser/ash/preferences_unittest.cc
+++ b/chrome/browser/ash/preferences_unittest.cc
@@ -182,18 +182,18 @@
         &previous_input_method_, &current_input_method_);
     input_method::InitializeForTesting(mock_manager_);
 
-    if (!chromeos::DBusThreadManager::IsInitialized()) {
-      chromeos::DBusThreadManager::Initialize();
-    }
-    fake_update_engine_client_ = new chromeos::FakeUpdateEngineClient();
-    chromeos::DBusThreadManager::GetSetterForTesting()->SetUpdateEngineClient(
-        std::unique_ptr<chromeos::UpdateEngineClient>(
-            fake_update_engine_client_));
+    chromeos::DBusThreadManager::Initialize();
+    fake_update_engine_client_ = UpdateEngineClient::InitializeFakeForTest();
 
     prefs_ = std::make_unique<Preferences>(mock_manager_);
   }
 
   void TearDown() override {
+    // `prefs_` accesses UpdateEngineClient in its destructor.
+    prefs_.reset();
+    UpdateEngineClient::Shutdown();
+    chromeos::DBusThreadManager::Shutdown();
+
     input_method::Shutdown();
     // UserSessionManager doesn't listen to profile destruction, so make sure
     // the default IME state isn't still cached in case test_profile_ is
diff --git a/chrome/browser/ash/system/automatic_reboot_manager_unittest.cc b/chrome/browser/ash/system/automatic_reboot_manager_unittest.cc
index d98ea10..65f4e7f 100644
--- a/chrome/browser/ash/system/automatic_reboot_manager_unittest.cc
+++ b/chrome/browser/ash/system/automatic_reboot_manager_unittest.cc
@@ -344,10 +344,8 @@
   TestingBrowserProcess::GetGlobal()->SetLocalState(&local_state_);
   AutomaticRebootManager::RegisterPrefs(local_state_.registry());
 
-  update_engine_client_ = new FakeUpdateEngineClient;
   DBusThreadManager::Initialize();
-  DBusThreadManager::GetSetterForTesting()->SetUpdateEngineClient(
-      std::unique_ptr<UpdateEngineClient>(update_engine_client_));
+  update_engine_client_ = UpdateEngineClient::InitializeFakeForTest();
   PowerManagerClient::InitializeFake();
 
   EXPECT_CALL(*mock_user_manager_, IsUserLoggedIn())
@@ -372,6 +370,7 @@
   }
 
   PowerManagerClient::Shutdown();
+  UpdateEngineClient::Shutdown();
   DBusThreadManager::Shutdown();
   TestingBrowserProcess::GetGlobal()->SetLocalState(NULL);
 }
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_keyboard_backlight_provider_impl.cc b/chrome/browser/ash/web_applications/personalization_app/personalization_app_keyboard_backlight_provider_impl.cc
index 8cf29824..96d563b 100644
--- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_keyboard_backlight_provider_impl.cc
+++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_keyboard_backlight_provider_impl.cc
@@ -15,6 +15,7 @@
 #include "ash/webui/personalization_app/mojom/personalization_app.mojom.h"
 #include "base/check.h"
 #include "base/logging.h"
+#include "chrome/browser/ash/web_applications/personalization_app/personalization_app_metrics.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/profiles/profile.h"
 #include "components/prefs/pref_service.h"
@@ -71,6 +72,7 @@
     return;
   }
   DVLOG(4) << __func__ << " backlight_color=" << backlight_color;
+  LogKeyboardBacklightColor(backlight_color);
   GetKeyboardBacklightColorController()->SetBacklightColor(backlight_color);
   GetKeyboardBacklightColorController()
       ->keyboard_backlight_color_nudge_controller()
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_keyboard_backlight_provider_impl_unittest.cc b/chrome/browser/ash/web_applications/personalization_app/personalization_app_keyboard_backlight_provider_impl_unittest.cc
index 0b660273..2bb15d42 100644
--- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_keyboard_backlight_provider_impl_unittest.cc
+++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_keyboard_backlight_provider_impl_unittest.cc
@@ -7,7 +7,9 @@
 #include "ash/constants/ash_features.h"
 #include "ash/constants/ash_pref_names.h"
 #include "ash/webui/personalization_app/mojom/personalization_app.mojom.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
+#include "chrome/browser/ash/web_applications/personalization_app/personalization_app_metrics.h"
 #include "chrome/test/base/chrome_ash_test_base.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile_manager.h"
@@ -104,6 +106,10 @@
     ChromeAshTestBase::TearDown();
   }
 
+  const base::HistogramTester& histogram_tester() const {
+    return histogram_tester_;
+  }
+
   TestingProfile* profile() { return profile_; }
 
   mojo::Remote<ash::personalization_app::mojom::KeyboardBacklightProvider>*
@@ -143,6 +149,7 @@
   std::unique_ptr<PersonalizationAppKeyboardBacklightProviderImpl>
       keyboard_backlight_provider_;
   TestKeyboardBacklightObserver test_keyboard_backlight_observer_;
+  base::HistogramTester histogram_tester_;
 };
 
 TEST_F(PersonalizationAppKeyboardBacklightProviderImplTest,
@@ -154,6 +161,9 @@
 
   // Verify JS side is notified.
   EXPECT_EQ(mojom::BacklightColor::kBlue, ObservedBacklightColor());
+  histogram_tester().ExpectBucketCount(
+      kPersonalizationKeyboardBacklightColorHistogramName,
+      mojom::BacklightColor::kBlue, 1);
 }
 
 TEST_F(PersonalizationAppKeyboardBacklightProviderImplTest,
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_metrics.cc b/chrome/browser/ash/web_applications/personalization_app/personalization_app_metrics.cc
index 77f38a7..3ea1cac 100644
--- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_metrics.cc
+++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_metrics.cc
@@ -24,5 +24,10 @@
                                 entry_point);
 }
 
+void LogKeyboardBacklightColor(mojom::BacklightColor backlight_color) {
+  base::UmaHistogramEnumeration(
+      kPersonalizationKeyboardBacklightColorHistogramName, backlight_color);
+}
+
 }  // namespace personalization_app
 }  // namespace ash
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_metrics.h b/chrome/browser/ash/web_applications/personalization_app/personalization_app_metrics.h
index 31436d40..e1a578e3 100644
--- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_metrics.h
+++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_metrics.h
@@ -7,6 +7,7 @@
 
 #include "ash/constants/ambient_animation_theme.h"
 #include "ash/constants/personalization_entry_point.h"
+#include "ash/webui/personalization_app/mojom/personalization_app.mojom-shared.h"
 
 namespace ash {
 namespace personalization_app {
@@ -29,6 +30,8 @@
     "Ash.Personalization.AmbientMode.AnimationTheme";
 constexpr char kPersonalizationThemeColorModeHistogramName[] =
     "Ash.Personalization.Theme.ColorMode";
+constexpr char kPersonalizationKeyboardBacklightColorHistogramName[] =
+    "Ash.Personalization.KeyboardBacklight.Color";
 
 // -----------------------------------------------------------------------------
 // Histograms
@@ -40,6 +43,8 @@
 
 void LogPersonalizationEntryPoint(ash::PersonalizationEntryPoint entry_point);
 
+void LogKeyboardBacklightColor(mojom::BacklightColor backlight_color);
+
 }  // namespace personalization_app
 }  // namespace ash
 
diff --git a/chrome/browser/autofill/captured_sites_test_utils.cc b/chrome/browser/autofill/captured_sites_test_utils.cc
index 2f68ab8..348a81c4 100644
--- a/chrome/browser/autofill/captured_sites_test_utils.cc
+++ b/chrome/browser/autofill/captured_sites_test_utils.cc
@@ -834,11 +834,6 @@
       network::switches::kIgnoreCertificateErrorsSPKIList,
       kWebPageReplayCertSPKI);
   command_line->AppendSwitch(switches::kStartMaximized);
-  // Tests are not expecting default field trials config, disable them by adding
-  // a fake field trial.
-  // TOOD(crbug/1212552) Remove this switch and either do this directly via gn
-  // args or not at all and update test expectations.
-  command_line->AppendSwitchASCII(::switches::kForceFieldTrials, "Foo/Bar");
 }
 
 void TestRecipeReplayer::Setup() {
diff --git a/chrome/browser/back_press/android/BUILD.gn b/chrome/browser/back_press/android/BUILD.gn
index 5e6a9b5..79be75dd 100644
--- a/chrome/browser/back_press/android/BUILD.gn
+++ b/chrome/browser/back_press/android/BUILD.gn
@@ -51,6 +51,7 @@
     ":java",
     "//base:base_java",
     "//base:base_java_test_support",
+    "//chrome/browser/flags:java",
     "//chrome/browser/tab:java",
     "//chrome/browser/tabmodel:java",
     "//components/browser_ui/widget/android:java",
diff --git a/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/MinimizeAppAndCloseTabBackPressHandler.java b/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/MinimizeAppAndCloseTabBackPressHandler.java
index eed1c23d..4d403844 100644
--- a/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/MinimizeAppAndCloseTabBackPressHandler.java
+++ b/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/MinimizeAppAndCloseTabBackPressHandler.java
@@ -4,16 +4,22 @@
 
 package org.chromium.chrome.browser.back_press;
 
+import android.os.Build.VERSION;
+import android.os.Build.VERSION_CODES;
+
 import androidx.annotation.IntDef;
 
 import org.chromium.base.Callback;
 import org.chromium.base.Predicate;
+import org.chromium.base.lifetime.Destroyable;
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.base.supplier.ObservableSupplier;
 import org.chromium.base.supplier.ObservableSupplierImpl;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tab.TabAssociatedApp;
 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
+import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabModelObserver;
 import org.chromium.chrome.browser.ui.native_page.NativePage;
 import org.chromium.components.browser_ui.widget.gesture.BackPressHandler;
 import org.chromium.content_public.browser.WebContents;
@@ -22,7 +28,7 @@
  * The back press handler as the final step of back press handling. This is always enabled in order
  * to manually minimize app and close tab if necessary.
  */
-public class MinimizeAppAndCloseTabBackPressHandler implements BackPressHandler {
+public class MinimizeAppAndCloseTabBackPressHandler implements BackPressHandler, Destroyable {
     static final String HISTOGRAM = "Android.BackPress.MinimizeAppAndCloseTab";
 
     // An always-enabled supplier since this handler is the final step of back press handling.
@@ -32,6 +38,8 @@
     private final Callback<TabModelSelector> mOnTabModelSelectorAvailableCallback;
     private final Predicate<Tab> mBackShouldCloseTab;
     private final Callback<Tab> mSendToBackground;
+    private TabModelSelectorTabModelObserver mTabModelObserver;
+    private static Integer sVersionForTesting;
 
     @IntDef({MinimizeAppAndCloseTabType.MINIMIZE_APP, MinimizeAppAndCloseTabType.CLOSE_TAB,
             MinimizeAppAndCloseTabType.MINIMIZE_APP_AND_CLOSE_TAB,
@@ -60,12 +68,15 @@
         mTabModelSelectorSupplier = tabModelSelectorSupplier;
         mOnTabModelSelectorAvailableCallback = this::onTabModelSelectorAvailable;
         tabModelSelectorSupplier.addObserver(mOnTabModelSelectorAvailableCallback);
-        mBackPressSupplier.set(true);
+        if (!shouldUseSystemBack()) {
+            mBackPressSupplier.set(true);
+        }
     }
 
     @Override
     public void handleBackPress() {
         if (mTabModelSelectorSupplier.get() == null) {
+            assert !shouldUseSystemBack();
             mSendToBackground.onResult(null);
             return;
         }
@@ -87,6 +98,9 @@
         if (minimizeApp) {
             record(shouldCloseTab ? MinimizeAppAndCloseTabType.MINIMIZE_APP_AND_CLOSE_TAB
                                   : MinimizeAppAndCloseTabType.MINIMIZE_APP);
+            // If system back is enabled, we should let system handle the back press when
+            // no tab is about to be closed.
+            assert shouldCloseTab || !shouldUseSystemBack();
             mSendToBackground.onResult(shouldCloseTab ? currentTab : null);
         } else { // shouldCloseTab is always true if minimizeApp is false.
             record(MinimizeAppAndCloseTabType.CLOSE_TAB);
@@ -100,7 +114,35 @@
         return mBackPressSupplier;
     }
 
+    @Override
+    public void destroy() {
+        if (mTabModelObserver != null) mTabModelObserver.destroy();
+    }
+
     private void onTabModelSelectorAvailable(TabModelSelector tabModelSelector) {
         mTabModelSelectorSupplier.removeObserver(mOnTabModelSelectorAvailableCallback);
+        if (shouldUseSystemBack()) {
+            mBackPressSupplier.set(mBackShouldCloseTab.test(tabModelSelector.getCurrentTab()));
+            mTabModelObserver = new TabModelSelectorTabModelObserver(tabModelSelector) {
+                @Override
+                public void didSelectTab(Tab tab, int type, int lastId) {
+                    mBackPressSupplier.set(mBackShouldCloseTab.test(tab));
+                }
+            };
+        }
+    }
+
+    private static boolean shouldUseSystemBack() {
+        // https://developer.android.com/about/versions/12/behavior-changes-all#back-press
+        // Starting from 12, root launcher activities are no longer finished on Back press.
+        boolean isAtLeastS = (sVersionForTesting == null ? VERSION.SDK_INT : sVersionForTesting)
+                >= VERSION_CODES.S;
+        return isAtLeastS
+                && ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean(
+                        ChromeFeatureList.BACK_GESTURE_REFACTOR, "system_back", false);
+    }
+
+    static void setVersionForTesting(Integer version) {
+        sVersionForTesting = version;
     }
 }
diff --git a/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/MinimizeAppAndCloseTabBackPressHandlerUnitTest.java b/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/MinimizeAppAndCloseTabBackPressHandlerUnitTest.java
index 23439161..5fb8e0c 100644
--- a/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/MinimizeAppAndCloseTabBackPressHandlerUnitTest.java
+++ b/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/MinimizeAppAndCloseTabBackPressHandlerUnitTest.java
@@ -4,8 +4,11 @@
 
 package org.chromium.chrome.browser.back_press;
 
+import android.os.Build.VERSION_CODES;
+
 import androidx.test.filters.SmallTest;
 
+import org.junit.After;
 import org.junit.AfterClass;
 import org.junit.Assert;
 import org.junit.Before;
@@ -19,6 +22,8 @@
 import org.mockito.junit.MockitoRule;
 
 import org.chromium.base.Callback;
+import org.chromium.base.FeatureList;
+import org.chromium.base.FeatureList.TestValues;
 import org.chromium.base.Predicate;
 import org.chromium.base.UserDataHost;
 import org.chromium.base.supplier.ObservableSupplierImpl;
@@ -27,6 +32,7 @@
 import org.chromium.base.test.util.Batch;
 import org.chromium.base.test.util.MetricsUtils.HistogramDelta;
 import org.chromium.chrome.browser.back_press.MinimizeAppAndCloseTabBackPressHandler.MinimizeAppAndCloseTabType;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tab.TabAssociatedApp;
 import org.chromium.chrome.browser.tab.TabLaunchType;
@@ -71,13 +77,12 @@
 
     @Before
     public void setUp() {
-        TestThreadUtils.runOnUiThreadBlocking(
-                () -> { mTabModelSelectorObservableSupplier = new ObservableSupplierImpl<>(); });
-        mHandler = TestThreadUtils.runOnUiThreadBlockingNoException(
-                ()
-                        -> new MinimizeAppAndCloseTabBackPressHandler(
-                                mTabModelSelectorObservableSupplier, mShouldCloseTab,
-                                mSendToBackground));
+        createBackPressHandler();
+    }
+
+    @After
+    public void tearDown() {
+        MinimizeAppAndCloseTabBackPressHandler.setVersionForTesting(null);
     }
 
     @Test
@@ -104,6 +109,14 @@
 
     @Test
     @SmallTest
+    public void testMinimizeAppAndCloseTab_SystemBack() {
+        createBackPressHandler(true);
+        // Expect no change.
+        testMinimizeAppAndCloseTab();
+    }
+
+    @Test
+    @SmallTest
     public void testCloseTab() {
         HistogramDelta d1 = new HistogramDelta(MinimizeAppAndCloseTabBackPressHandler.HISTOGRAM,
                 MinimizeAppAndCloseTabType.CLOSE_TAB);
@@ -127,6 +140,14 @@
 
     @Test
     @SmallTest
+    public void testCloseTab_SystemBack() {
+        createBackPressHandler(true);
+        // Expect no change.
+        testCloseTab();
+    }
+
+    @Test
+    @SmallTest
     public void testMinimizeApp() {
         HistogramDelta d1 = new HistogramDelta(MinimizeAppAndCloseTabBackPressHandler.HISTOGRAM,
                 MinimizeAppAndCloseTabType.MINIMIZE_APP);
@@ -142,4 +163,43 @@
                 .onResult(null);
         Assert.assertEquals(1, d1.getDelta());
     }
+
+    @Test
+    @SmallTest
+    public void testMinimizeApp_SystemBack() {
+        createBackPressHandler(true);
+
+        HistogramDelta d1 = new HistogramDelta(MinimizeAppAndCloseTabBackPressHandler.HISTOGRAM,
+                MinimizeAppAndCloseTabType.MINIMIZE_APP);
+        Tab tab = Mockito.mock(Tab.class);
+        Mockito.when(mTabModelSelector.getCurrentTab()).thenReturn(tab);
+        TestThreadUtils.runOnUiThreadBlocking(
+                () -> { mTabModelSelectorObservableSupplier.set(mTabModelSelector); });
+        Mockito.when(mShouldCloseTab.test(tab)).thenReturn(false);
+
+        Assert.assertFalse("Back press should be handled by OS.",
+                mHandler.getHandleBackPressChangedSupplier().get());
+    }
+
+    private void createBackPressHandler() {
+        createBackPressHandler(false);
+    }
+
+    private void createBackPressHandler(boolean systemBack) {
+        TestValues testValues = new TestValues();
+        testValues.addFeatureFlagOverride(ChromeFeatureList.BACK_GESTURE_REFACTOR, true);
+        testValues.addFieldTrialParamOverride(
+                ChromeFeatureList.BACK_GESTURE_REFACTOR, "system_back", systemBack + "");
+        FeatureList.setTestValues(testValues);
+        if (systemBack) {
+            MinimizeAppAndCloseTabBackPressHandler.setVersionForTesting(VERSION_CODES.S);
+        }
+        TestThreadUtils.runOnUiThreadBlocking(
+                () -> { mTabModelSelectorObservableSupplier = new ObservableSupplierImpl<>(); });
+        mHandler = TestThreadUtils.runOnUiThreadBlockingNoException(
+                ()
+                        -> new MinimizeAppAndCloseTabBackPressHandler(
+                                mTabModelSelectorObservableSupplier, mShouldCloseTab,
+                                mSendToBackground));
+    }
 }
diff --git a/chrome/browser/banners/android/java/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java b/chrome/browser/banners/android/java/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java
index cd5a626..5f13adba 100644
--- a/chrome/browser/banners/android/java/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java
+++ b/chrome/browser/banners/android/java/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java
@@ -65,7 +65,7 @@
 import org.chromium.chrome.browser.app.ChromeActivity;
 import org.chromium.chrome.browser.browserservices.intents.BitmapHelper;
 import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
+import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils;
 import org.chromium.chrome.browser.feature_engagement.TrackerFactory;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
@@ -529,7 +529,7 @@
         WebappDataStorage.setFactoryForTests(dataStorageFactory);
 
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(
-                CustomTabsTestUtils.createMinimalCustomTabIntent(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                         InstrumentationRegistry.getTargetContext(),
                         ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL));
         triggerModalWebAppBanner(mCustomTabActivityTestRule,
@@ -610,7 +610,7 @@
     @Feature({"AppBanners"})
     public void testAppInstalledModalNativeAppBannerCustomTab() throws Exception {
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(
-                CustomTabsTestUtils.createMinimalCustomTabIntent(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                         InstrumentationRegistry.getTargetContext(),
                         ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL));
 
@@ -690,7 +690,7 @@
     @Feature({"AppBanners"})
     public void testModalNativeAppBannerCanBeTriggeredMultipleTimesCustomTab() throws Exception {
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(
-                CustomTabsTestUtils.createMinimalCustomTabIntent(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                         InstrumentationRegistry.getTargetContext(),
                         ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL));
 
@@ -721,7 +721,7 @@
     @Feature({"AppBanners"})
     public void testModalWebAppBannerCanBeTriggeredMultipleTimesCustomTab() throws Exception {
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(
-                CustomTabsTestUtils.createMinimalCustomTabIntent(
+                CustomTabsIntentTestUtils.createMinimalCustomTabIntent(
                         InstrumentationRegistry.getTargetContext(),
                         ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL));
 
diff --git a/chrome/browser/capability_delegation_browsertest.cc b/chrome/browser/capability_delegation_browsertest.cc
index 6b058314..9029631 100644
--- a/chrome/browser/capability_delegation_browsertest.cc
+++ b/chrome/browser/capability_delegation_browsertest.cc
@@ -61,6 +61,9 @@
   EXPECT_TRUE(
       NavigateIframeToURL(active_web_contents, "iframe", cross_site_url));
 
+  const std::string subframe_origin =
+      https_server()->GetOrigin("b.com").Serialize();
+
   // Confirm that the subframe is cross-process depending on the process
   // model.
   content::RenderFrameHost* frame_host =
@@ -88,33 +91,34 @@
   EXPECT_EQ(
       "SecurityError",
       content::EvalJs(active_web_contents,
-                      content::JsReplace("sendRequestToSubframe(false, $1)",
-                                         payment_method),
+                      content::JsReplace("sendRequestToSubframe(false, $1, $2)",
+                                         payment_method, subframe_origin),
                       content::EXECUTE_SCRIPT_NO_USER_GESTURE));
 
-  // Without user activation but with the delegation option, PaymentRequest
-  // dialog is not allowed.
+  // Without user activation but with the delegation option, the delegation
+  // postMessage is not allowed.
   EXPECT_EQ(
-      "SecurityError",
-      content::EvalJs(
-          active_web_contents,
-          content::JsReplace("sendRequestToSubframe(true, $1)", payment_method),
-          content::EXECUTE_SCRIPT_NO_USER_GESTURE));
+      "NotAllowedError",
+      content::EvalJs(active_web_contents,
+                      content::JsReplace("sendRequestToSubframe(true, $1, $2)",
+                                         payment_method, subframe_origin),
+                      content::EXECUTE_SCRIPT_NO_USER_GESTURE));
 
   // With user activation but without the delegation option, PaymentRequest
   // dialog is not allowed.
   EXPECT_EQ(
       "SecurityError",
       content::EvalJs(active_web_contents,
-                      content::JsReplace("sendRequestToSubframe(false, $1)",
-                                         payment_method)));
+                      content::JsReplace("sendRequestToSubframe(false, $1, $2)",
+                                         payment_method, subframe_origin)));
 
   // With both user activation and the delegation option, PaymentRequest dialog
   // is shown and then successfully aborted by the script.
-  EXPECT_EQ("AbortError", content::EvalJs(active_web_contents,
-                                          content::JsReplace(
-                                              "sendRequestToSubframe(true, $1)",
-                                              payment_method)));
+  EXPECT_EQ(
+      "AbortError",
+      content::EvalJs(active_web_contents,
+                      content::JsReplace("sendRequestToSubframe(true, $1, $2)",
+                                         payment_method, subframe_origin)));
 }
 
 IN_PROC_BROWSER_TEST_F(CapabilityDelegationBrowserTest,
@@ -136,6 +140,8 @@
       https_server()->GetURL("a.com", "/payment_request_delegation_sub.html"));
   EXPECT_TRUE(NavigateIframeToURL(active_web_contents, "iframe", subframe_url));
 
+  const std::string subframe_origin = "/";
+
   // Confirm that the subframe is same-process.
   content::RenderFrameHost* frame_host =
       ChildFrameAt(active_web_contents->GetPrimaryMainFrame(), 0);
@@ -148,31 +154,32 @@
   EXPECT_EQ(
       "SecurityError",
       content::EvalJs(active_web_contents,
-                      content::JsReplace("sendRequestToSubframe(false, $1)",
-                                         payment_method),
+                      content::JsReplace("sendRequestToSubframe(false, $1, $2)",
+                                         payment_method, subframe_origin),
                       content::EXECUTE_SCRIPT_NO_USER_GESTURE));
 
-  // Without user activation but with the delegation option, PaymentRequest
-  // dialog is not allowed.
+  // Without user activation but with the delegation option, the delegation
+  // postMessage is not allowed.
   EXPECT_EQ(
-      "SecurityError",
-      content::EvalJs(
-          active_web_contents,
-          content::JsReplace("sendRequestToSubframe(true, $1)", payment_method),
-          content::EXECUTE_SCRIPT_NO_USER_GESTURE));
+      "NotAllowedError",
+      content::EvalJs(active_web_contents,
+                      content::JsReplace("sendRequestToSubframe(true, $1, $2)",
+                                         payment_method, subframe_origin),
+                      content::EXECUTE_SCRIPT_NO_USER_GESTURE));
 
   // With user activation but without the delegation option, PaymentRequest
   // dialog is shown and then successfully aborted by the script.
   EXPECT_EQ(
       "AbortError",
       content::EvalJs(active_web_contents,
-                      content::JsReplace("sendRequestToSubframe(false, $1)",
-                                         payment_method)));
+                      content::JsReplace("sendRequestToSubframe(false, $1, $2)",
+                                         payment_method, subframe_origin)));
 
   // With both user activation and the delegation option, PaymentRequest dialog
   // is shown and then successfully aborted by the script.
-  EXPECT_EQ("AbortError", content::EvalJs(active_web_contents,
-                                          content::JsReplace(
-                                              "sendRequestToSubframe(true, $1)",
-                                              payment_method)));
+  EXPECT_EQ(
+      "AbortError",
+      content::EvalJs(active_web_contents,
+                      content::JsReplace("sendRequestToSubframe(true, $1, $2)",
+                                         payment_method, subframe_origin)));
 }
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index eb26c51..1b8410f7 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -591,632 +591,6 @@
   ]
 
   sources = [
-    "../ash/language_preferences.cc",
-    "../ash/language_preferences.h",
-    "../ash/locale_change_guard.cc",
-    "../ash/locale_change_guard.h",
-    "../ash/lock_screen_apps/app_manager.h",
-    "../ash/lock_screen_apps/app_manager_impl.cc",
-    "../ash/lock_screen_apps/app_manager_impl.h",
-    "../ash/lock_screen_apps/app_window_metrics_tracker.cc",
-    "../ash/lock_screen_apps/app_window_metrics_tracker.h",
-    "../ash/lock_screen_apps/first_app_run_toast_manager.cc",
-    "../ash/lock_screen_apps/first_app_run_toast_manager.h",
-    "../ash/lock_screen_apps/focus_cycler_delegate.h",
-    "../ash/lock_screen_apps/lock_screen_helper.cc",
-    "../ash/lock_screen_apps/lock_screen_helper.h",
-    "../ash/lock_screen_apps/lock_screen_profile_creator.cc",
-    "../ash/lock_screen_apps/lock_screen_profile_creator.h",
-    "../ash/lock_screen_apps/lock_screen_profile_creator_impl.cc",
-    "../ash/lock_screen_apps/lock_screen_profile_creator_impl.h",
-    "../ash/lock_screen_apps/state_controller.cc",
-    "../ash/lock_screen_apps/state_controller.h",
-    "../ash/lock_screen_apps/state_observer.h",
-    "../ash/lock_screen_apps/toast_dialog_view.cc",
-    "../ash/lock_screen_apps/toast_dialog_view.h",
-    "../ash/logging.cc",
-    "../ash/logging.h",
-    "../ash/login/active_directory_migration_utils.cc",
-    "../ash/login/active_directory_migration_utils.h",
-    "../ash/login/app_mode/kiosk_launch_controller.cc",
-    "../ash/login/app_mode/kiosk_launch_controller.h",
-    "../ash/login/auth/chrome_cryptohome_authenticator.cc",
-    "../ash/login/auth/chrome_cryptohome_authenticator.h",
-    "../ash/login/auth/chrome_login_performer.cc",
-    "../ash/login/auth/chrome_login_performer.h",
-    "../ash/login/auth/chrome_safe_mode_delegate.cc",
-    "../ash/login/auth/chrome_safe_mode_delegate.h",
-    "../ash/login/challenge_response_auth_keys_loader.cc",
-    "../ash/login/challenge_response_auth_keys_loader.h",
-    "../ash/login/chrome_restart_request.cc",
-    "../ash/login/chrome_restart_request.h",
-    "../ash/login/configuration_keys.cc",
-    "../ash/login/configuration_keys.h",
-    "../ash/login/consolidated_consent_field_trial.cc",
-    "../ash/login/consolidated_consent_field_trial.h",
-    "../ash/login/demo_mode/demo_extensions_external_loader.cc",
-    "../ash/login/demo_mode/demo_extensions_external_loader.h",
-    "../ash/login/demo_mode/demo_mode_resources_remover.cc",
-    "../ash/login/demo_mode/demo_mode_resources_remover.h",
-    "../ash/login/demo_mode/demo_resources.cc",
-    "../ash/login/demo_mode/demo_resources.h",
-    "../ash/login/demo_mode/demo_session.cc",
-    "../ash/login/demo_mode/demo_session.h",
-    "../ash/login/demo_mode/demo_setup_controller.cc",
-    "../ash/login/demo_mode/demo_setup_controller.h",
-    "../ash/login/easy_unlock/chrome_proximity_auth_client.cc",
-    "../ash/login/easy_unlock/chrome_proximity_auth_client.h",
-    "../ash/login/easy_unlock/easy_unlock_auth_attempt.cc",
-    "../ash/login/easy_unlock/easy_unlock_auth_attempt.h",
-    "../ash/login/easy_unlock/easy_unlock_challenge_wrapper.cc",
-    "../ash/login/easy_unlock/easy_unlock_challenge_wrapper.h",
-    "../ash/login/easy_unlock/easy_unlock_create_keys_operation.cc",
-    "../ash/login/easy_unlock/easy_unlock_create_keys_operation.h",
-    "../ash/login/easy_unlock/easy_unlock_get_keys_operation.cc",
-    "../ash/login/easy_unlock/easy_unlock_get_keys_operation.h",
-    "../ash/login/easy_unlock/easy_unlock_key_manager.cc",
-    "../ash/login/easy_unlock/easy_unlock_key_manager.h",
-    "../ash/login/easy_unlock/easy_unlock_key_names.cc",
-    "../ash/login/easy_unlock/easy_unlock_key_names.h",
-    "../ash/login/easy_unlock/easy_unlock_metrics.cc",
-    "../ash/login/easy_unlock/easy_unlock_metrics.h",
-    "../ash/login/easy_unlock/easy_unlock_notification_controller.cc",
-    "../ash/login/easy_unlock/easy_unlock_notification_controller.h",
-    "../ash/login/easy_unlock/easy_unlock_refresh_keys_operation.cc",
-    "../ash/login/easy_unlock/easy_unlock_refresh_keys_operation.h",
-    "../ash/login/easy_unlock/easy_unlock_remove_keys_operation.cc",
-    "../ash/login/easy_unlock/easy_unlock_remove_keys_operation.h",
-    "../ash/login/easy_unlock/easy_unlock_service.cc",
-    "../ash/login/easy_unlock/easy_unlock_service.h",
-    "../ash/login/easy_unlock/easy_unlock_service_factory.cc",
-    "../ash/login/easy_unlock/easy_unlock_service_factory.h",
-    "../ash/login/easy_unlock/easy_unlock_service_regular.cc",
-    "../ash/login/easy_unlock/easy_unlock_service_regular.h",
-    "../ash/login/easy_unlock/easy_unlock_service_signin.cc",
-    "../ash/login/easy_unlock/easy_unlock_service_signin.h",
-    "../ash/login/easy_unlock/easy_unlock_tpm_key_manager.cc",
-    "../ash/login/easy_unlock/easy_unlock_tpm_key_manager.h",
-    "../ash/login/easy_unlock/easy_unlock_tpm_key_manager_factory.cc",
-    "../ash/login/easy_unlock/easy_unlock_tpm_key_manager_factory.h",
-    "../ash/login/easy_unlock/easy_unlock_types.cc",
-    "../ash/login/easy_unlock/easy_unlock_types.h",
-    "../ash/login/easy_unlock/easy_unlock_user_login_flow.cc",
-    "../ash/login/easy_unlock/easy_unlock_user_login_flow.h",
-    "../ash/login/easy_unlock/smartlock_feature_usage_metrics.cc",
-    "../ash/login/easy_unlock/smartlock_feature_usage_metrics.h",
-    "../ash/login/easy_unlock/smartlock_state_handler.cc",
-    "../ash/login/easy_unlock/smartlock_state_handler.h",
-    "../ash/login/enrollment/auto_enrollment_check_screen.cc",
-    "../ash/login/enrollment/auto_enrollment_check_screen.h",
-    "../ash/login/enrollment/auto_enrollment_check_screen_view.h",
-    "../ash/login/enrollment/auto_enrollment_controller.cc",
-    "../ash/login/enrollment/auto_enrollment_controller.h",
-    "../ash/login/enrollment/enrollment_screen.cc",
-    "../ash/login/enrollment/enrollment_screen.h",
-    "../ash/login/enrollment/enrollment_screen_view.h",
-    "../ash/login/enrollment/enrollment_uma.cc",
-    "../ash/login/enrollment/enrollment_uma.h",
-    "../ash/login/enrollment/enterprise_enrollment_helper.cc",
-    "../ash/login/enrollment/enterprise_enrollment_helper.h",
-    "../ash/login/enrollment/enterprise_enrollment_helper_impl.cc",
-    "../ash/login/enrollment/enterprise_enrollment_helper_impl.h",
-    "../ash/login/enterprise_user_session_metrics.cc",
-    "../ash/login/enterprise_user_session_metrics.h",
-    "../ash/login/error_screens_histogram_helper.cc",
-    "../ash/login/error_screens_histogram_helper.h",
-    "../ash/login/existing_user_controller.cc",
-    "../ash/login/existing_user_controller.h",
-    "../ash/login/gaia_reauth_token_fetcher.cc",
-    "../ash/login/gaia_reauth_token_fetcher.h",
-    "../ash/login/hats_unlock_survey_trigger.cc",
-    "../ash/login/hats_unlock_survey_trigger.h",
-    "../ash/login/help_app_launcher.cc",
-    "../ash/login/help_app_launcher.h",
-    "../ash/login/helper.cc",
-    "../ash/login/helper.h",
-    "../ash/login/hwid_checker.cc",
-    "../ash/login/hwid_checker.h",
-    "../ash/login/lock/screen_locker.cc",
-    "../ash/login/lock/screen_locker.h",
-    "../ash/login/lock/views_screen_locker.cc",
-    "../ash/login/lock/views_screen_locker.h",
-    "../ash/login/lock_screen_utils.cc",
-    "../ash/login/lock_screen_utils.h",
-    "../ash/login/login_auth_recorder.cc",
-    "../ash/login/login_auth_recorder.h",
-    "../ash/login/login_client_cert_usage_observer.cc",
-    "../ash/login/login_client_cert_usage_observer.h",
-    "../ash/login/login_pref_names.cc",
-    "../ash/login/login_pref_names.h",
-    "../ash/login/login_screen_extensions_lifetime_manager.cc",
-    "../ash/login/login_screen_extensions_lifetime_manager.h",
-    "../ash/login/login_screen_extensions_storage_cleaner.cc",
-    "../ash/login/login_screen_extensions_storage_cleaner.h",
-    "../ash/login/login_wizard.h",
-    "../ash/login/marketing_backend_connector.cc",
-    "../ash/login/marketing_backend_connector.h",
-    "../ash/login/mojo_system_info_dispatcher.cc",
-    "../ash/login/mojo_system_info_dispatcher.h",
-    "../ash/login/onboarding_user_activity_counter.cc",
-    "../ash/login/onboarding_user_activity_counter.h",
-    "../ash/login/oobe_configuration.cc",
-    "../ash/login/oobe_configuration.h",
-    "../ash/login/oobe_screen.cc",
-    "../ash/login/oobe_screen.h",
-    "../ash/login/profile_auth_data.cc",
-    "../ash/login/profile_auth_data.h",
-    "../ash/login/quick_unlock/auth_token.cc",
-    "../ash/login/quick_unlock/auth_token.h",
-    "../ash/login/quick_unlock/fake_pin_salt_storage.cc",
-    "../ash/login/quick_unlock/fake_pin_salt_storage.h",
-    "../ash/login/quick_unlock/fingerprint_power_button_race_detector.cc",
-    "../ash/login/quick_unlock/fingerprint_power_button_race_detector.h",
-    "../ash/login/quick_unlock/fingerprint_storage.cc",
-    "../ash/login/quick_unlock/fingerprint_storage.h",
-    "../ash/login/quick_unlock/fingerprint_utils.cc",
-    "../ash/login/quick_unlock/fingerprint_utils.h",
-    "../ash/login/quick_unlock/pin_backend.cc",
-    "../ash/login/quick_unlock/pin_backend.h",
-    "../ash/login/quick_unlock/pin_salt_storage.cc",
-    "../ash/login/quick_unlock/pin_salt_storage.h",
-    "../ash/login/quick_unlock/pin_storage_cryptohome.cc",
-    "../ash/login/quick_unlock/pin_storage_cryptohome.h",
-    "../ash/login/quick_unlock/pin_storage_prefs.cc",
-    "../ash/login/quick_unlock/pin_storage_prefs.h",
-    "../ash/login/quick_unlock/quick_unlock_factory.cc",
-    "../ash/login/quick_unlock/quick_unlock_factory.h",
-    "../ash/login/quick_unlock/quick_unlock_storage.cc",
-    "../ash/login/quick_unlock/quick_unlock_storage.h",
-    "../ash/login/quick_unlock/quick_unlock_utils.cc",
-    "../ash/login/quick_unlock/quick_unlock_utils.h",
-    "../ash/login/reauth_stats.cc",
-    "../ash/login/reauth_stats.h",
-    "../ash/login/reporting/login_logout_reporter.cc",
-    "../ash/login/reporting/login_logout_reporter.h",
-    "../ash/login/saml/in_session_password_change_manager.cc",
-    "../ash/login/saml/in_session_password_change_manager.h",
-    "../ash/login/saml/in_session_password_sync_manager.cc",
-    "../ash/login/saml/in_session_password_sync_manager.h",
-    "../ash/login/saml/in_session_password_sync_manager_factory.cc",
-    "../ash/login/saml/in_session_password_sync_manager_factory.h",
-    "../ash/login/saml/password_change_success_notification.cc",
-    "../ash/login/saml/password_change_success_notification.h",
-    "../ash/login/saml/password_expiry_notification.cc",
-    "../ash/login/saml/password_expiry_notification.h",
-    "../ash/login/saml/password_sync_token_checkers_collection.cc",
-    "../ash/login/saml/password_sync_token_checkers_collection.h",
-    "../ash/login/saml/password_sync_token_fetcher.cc",
-    "../ash/login/saml/password_sync_token_fetcher.h",
-    "../ash/login/saml/password_sync_token_login_checker.cc",
-    "../ash/login/saml/password_sync_token_login_checker.h",
-    "../ash/login/saml/password_sync_token_verifier.cc",
-    "../ash/login/saml/password_sync_token_verifier.h",
-    "../ash/login/saml/password_sync_token_verifier_factory.cc",
-    "../ash/login/saml/password_sync_token_verifier_factory.h",
-    "../ash/login/saml/public_saml_url_fetcher.cc",
-    "../ash/login/saml/public_saml_url_fetcher.h",
-    "../ash/login/saml/saml_metric_utils.cc",
-    "../ash/login/saml/saml_metric_utils.h",
-    "../ash/login/saml/saml_profile_prefs.cc",
-    "../ash/login/saml/saml_profile_prefs.h",
-    "../ash/login/screen_manager.cc",
-    "../ash/login/screen_manager.h",
-    "../ash/login/screens/active_directory_login_screen.cc",
-    "../ash/login/screens/active_directory_login_screen.h",
-    "../ash/login/screens/active_directory_password_change_screen.cc",
-    "../ash/login/screens/active_directory_password_change_screen.h",
-    "../ash/login/screens/app_downloading_screen.cc",
-    "../ash/login/screens/app_downloading_screen.h",
-    "../ash/login/screens/arc_terms_of_service_screen.cc",
-    "../ash/login/screens/arc_terms_of_service_screen.h",
-    "../ash/login/screens/assistant_optin_flow_screen.cc",
-    "../ash/login/screens/assistant_optin_flow_screen.h",
-    "../ash/login/screens/base_screen.cc",
-    "../ash/login/screens/base_screen.h",
-    "../ash/login/screens/chrome_user_selection_screen.cc",
-    "../ash/login/screens/chrome_user_selection_screen.h",
-    "../ash/login/screens/chromevox_hint/chromevox_hint_detector.cc",
-    "../ash/login/screens/chromevox_hint/chromevox_hint_detector.h",
-    "../ash/login/screens/consolidated_consent_screen.cc",
-    "../ash/login/screens/consolidated_consent_screen.h",
-    "../ash/login/screens/demo_preferences_screen.cc",
-    "../ash/login/screens/demo_preferences_screen.h",
-    "../ash/login/screens/demo_setup_screen.cc",
-    "../ash/login/screens/demo_setup_screen.h",
-    "../ash/login/screens/device_disabled_screen.cc",
-    "../ash/login/screens/device_disabled_screen.h",
-    "../ash/login/screens/edu_coexistence_login_screen.cc",
-    "../ash/login/screens/edu_coexistence_login_screen.h",
-    "../ash/login/screens/enable_adb_sideloading_screen.cc",
-    "../ash/login/screens/enable_adb_sideloading_screen.h",
-    "../ash/login/screens/enable_debugging_screen.cc",
-    "../ash/login/screens/enable_debugging_screen.h",
-    "../ash/login/screens/encryption_migration_mode.h",
-    "../ash/login/screens/encryption_migration_screen.cc",
-    "../ash/login/screens/encryption_migration_screen.h",
-    "../ash/login/screens/error_screen.cc",
-    "../ash/login/screens/error_screen.h",
-    "../ash/login/screens/eula_screen.cc",
-    "../ash/login/screens/eula_screen.h",
-    "../ash/login/screens/family_link_notice_screen.cc",
-    "../ash/login/screens/family_link_notice_screen.h",
-    "../ash/login/screens/fingerprint_setup_screen.cc",
-    "../ash/login/screens/fingerprint_setup_screen.h",
-    "../ash/login/screens/gaia_password_changed_screen.cc",
-    "../ash/login/screens/gaia_password_changed_screen.h",
-    "../ash/login/screens/gaia_screen.cc",
-    "../ash/login/screens/gaia_screen.h",
-    "../ash/login/screens/gesture_navigation_screen.cc",
-    "../ash/login/screens/gesture_navigation_screen.h",
-    "../ash/login/screens/guest_tos_screen.cc",
-    "../ash/login/screens/guest_tos_screen.h",
-    "../ash/login/screens/hardware_data_collection_screen.cc",
-    "../ash/login/screens/hardware_data_collection_screen.h",
-    "../ash/login/screens/hid_detection_screen.cc",
-    "../ash/login/screens/hid_detection_screen.h",
-    "../ash/login/screens/kiosk_autolaunch_screen.cc",
-    "../ash/login/screens/kiosk_autolaunch_screen.h",
-    "../ash/login/screens/kiosk_enable_screen.cc",
-    "../ash/login/screens/kiosk_enable_screen.h",
-    "../ash/login/screens/lacros_data_migration_screen.cc",
-    "../ash/login/screens/lacros_data_migration_screen.h",
-    "../ash/login/screens/locale_switch_screen.cc",
-    "../ash/login/screens/locale_switch_screen.h",
-    "../ash/login/screens/management_transition_screen.cc",
-    "../ash/login/screens/management_transition_screen.h",
-    "../ash/login/screens/marketing_opt_in_screen.cc",
-    "../ash/login/screens/marketing_opt_in_screen.h",
-    "../ash/login/screens/multidevice_setup_screen.cc",
-    "../ash/login/screens/multidevice_setup_screen.h",
-    "../ash/login/screens/network_error.cc",
-    "../ash/login/screens/network_error.h",
-    "../ash/login/screens/network_screen.cc",
-    "../ash/login/screens/network_screen.h",
-    "../ash/login/screens/offline_login_screen.cc",
-    "../ash/login/screens/offline_login_screen.h",
-    "../ash/login/screens/os_install_screen.cc",
-    "../ash/login/screens/os_install_screen.h",
-    "../ash/login/screens/os_trial_screen.cc",
-    "../ash/login/screens/os_trial_screen.h",
-    "../ash/login/screens/packaged_license_screen.cc",
-    "../ash/login/screens/packaged_license_screen.h",
-    "../ash/login/screens/parental_handoff_screen.cc",
-    "../ash/login/screens/parental_handoff_screen.h",
-    "../ash/login/screens/pin_setup_screen.cc",
-    "../ash/login/screens/pin_setup_screen.h",
-    "../ash/login/screens/quick_start_screen.cc",
-    "../ash/login/screens/quick_start_screen.h",
-    "../ash/login/screens/recommend_apps/fake_recommend_apps_fetcher.cc",
-    "../ash/login/screens/recommend_apps/fake_recommend_apps_fetcher.h",
-    "../ash/login/screens/recommend_apps/recommend_apps_fetcher.cc",
-    "../ash/login/screens/recommend_apps/recommend_apps_fetcher.h",
-    "../ash/login/screens/recommend_apps/recommend_apps_fetcher_delegate.h",
-    "../ash/login/screens/recommend_apps/recommend_apps_fetcher_impl.cc",
-    "../ash/login/screens/recommend_apps/recommend_apps_fetcher_impl.h",
-    "../ash/login/screens/recommend_apps_screen.cc",
-    "../ash/login/screens/recommend_apps_screen.h",
-    "../ash/login/screens/reset_screen.cc",
-    "../ash/login/screens/reset_screen.h",
-    "../ash/login/screens/saml_confirm_password_screen.cc",
-    "../ash/login/screens/saml_confirm_password_screen.h",
-    "../ash/login/screens/signin_fatal_error_screen.cc",
-    "../ash/login/screens/signin_fatal_error_screen.h",
-    "../ash/login/screens/smart_privacy_protection_screen.cc",
-    "../ash/login/screens/smart_privacy_protection_screen.h",
-    "../ash/login/screens/sync_consent_screen.cc",
-    "../ash/login/screens/sync_consent_screen.h",
-    "../ash/login/screens/terms_of_service_screen.cc",
-    "../ash/login/screens/terms_of_service_screen.h",
-    "../ash/login/screens/theme_selection_screen.cc",
-    "../ash/login/screens/theme_selection_screen.h",
-    "../ash/login/screens/tpm_error_screen.cc",
-    "../ash/login/screens/tpm_error_screen.h",
-    "../ash/login/screens/update_required_screen.cc",
-    "../ash/login/screens/update_required_screen.h",
-    "../ash/login/screens/update_screen.cc",
-    "../ash/login/screens/update_screen.h",
-    "../ash/login/screens/user_creation_screen.cc",
-    "../ash/login/screens/user_creation_screen.h",
-    "../ash/login/screens/user_selection_screen.cc",
-    "../ash/login/screens/user_selection_screen.h",
-    "../ash/login/screens/welcome_screen.cc",
-    "../ash/login/screens/welcome_screen.h",
-    "../ash/login/screens/wrong_hwid_screen.cc",
-    "../ash/login/screens/wrong_hwid_screen.h",
-    "../ash/login/security_token_pin_dialog_host_login_impl.cc",
-    "../ash/login/security_token_pin_dialog_host_login_impl.h",
-    "../ash/login/security_token_session_controller.cc",
-    "../ash/login/security_token_session_controller.h",
-    "../ash/login/security_token_session_controller_factory.cc",
-    "../ash/login/security_token_session_controller_factory.h",
-    "../ash/login/session/chrome_session_manager.cc",
-    "../ash/login/session/chrome_session_manager.h",
-    "../ash/login/session/user_session_initializer.cc",
-    "../ash/login/session/user_session_initializer.h",
-    "../ash/login/session/user_session_manager.cc",
-    "../ash/login/session/user_session_manager.h",
-    "../ash/login/signin/auth_error_observer.cc",
-    "../ash/login/signin/auth_error_observer.h",
-    "../ash/login/signin/auth_error_observer_factory.cc",
-    "../ash/login/signin/auth_error_observer_factory.h",
-    "../ash/login/signin/merge_session_navigation_throttle.cc",
-    "../ash/login/signin/merge_session_navigation_throttle.h",
-    "../ash/login/signin/merge_session_throttling_utils.cc",
-    "../ash/login/signin/merge_session_throttling_utils.h",
-    "../ash/login/signin/oauth2_login_manager.cc",
-    "../ash/login/signin/oauth2_login_manager.h",
-    "../ash/login/signin/oauth2_login_manager_factory.cc",
-    "../ash/login/signin/oauth2_login_manager_factory.h",
-    "../ash/login/signin/oauth2_login_verifier.cc",
-    "../ash/login/signin/oauth2_login_verifier.h",
-    "../ash/login/signin/oauth2_token_fetcher.cc",
-    "../ash/login/signin/oauth2_token_fetcher.h",
-    "../ash/login/signin/oauth2_token_initializer.cc",
-    "../ash/login/signin/oauth2_token_initializer.h",
-    "../ash/login/signin/offline_signin_limiter.cc",
-    "../ash/login/signin/offline_signin_limiter.h",
-    "../ash/login/signin/offline_signin_limiter_factory.cc",
-    "../ash/login/signin/offline_signin_limiter_factory.h",
-    "../ash/login/signin/signin_error_notifier.cc",
-    "../ash/login/signin/signin_error_notifier.h",
-    "../ash/login/signin/signin_error_notifier_factory.cc",
-    "../ash/login/signin/signin_error_notifier_factory.h",
-    "../ash/login/signin/token_handle_fetcher.cc",
-    "../ash/login/signin/token_handle_fetcher.h",
-    "../ash/login/signin/token_handle_util.cc",
-    "../ash/login/signin/token_handle_util.h",
-    "../ash/login/signin_partition_manager.cc",
-    "../ash/login/signin_partition_manager.h",
-    "../ash/login/signin_specifics.h",
-    "../ash/login/startup_utils.cc",
-    "../ash/login/startup_utils.h",
-    "../ash/login/ui/captive_portal_dialog_delegate.cc",
-    "../ash/login/ui/captive_portal_dialog_delegate.h",
-    "../ash/login/ui/captive_portal_view.cc",
-    "../ash/login/ui/captive_portal_view.h",
-    "../ash/login/ui/captive_portal_window_proxy.cc",
-    "../ash/login/ui/captive_portal_window_proxy.h",
-    "../ash/login/ui/input_events_blocker.cc",
-    "../ash/login/ui/input_events_blocker.h",
-    "../ash/login/ui/kiosk_app_menu_controller.cc",
-    "../ash/login/ui/kiosk_app_menu_controller.h",
-    "../ash/login/ui/login_display.cc",
-    "../ash/login/ui/login_display.h",
-    "../ash/login/ui/login_display_host.cc",
-    "../ash/login/ui/login_display_host.h",
-    "../ash/login/ui/login_display_host_common.cc",
-    "../ash/login/ui/login_display_host_common.h",
-    "../ash/login/ui/login_display_host_mojo.cc",
-    "../ash/login/ui/login_display_host_mojo.h",
-    "../ash/login/ui/login_display_host_webui.cc",
-    "../ash/login/ui/login_display_host_webui.h",
-    "../ash/login/ui/login_display_mojo.cc",
-    "../ash/login/ui/login_display_mojo.h",
-    "../ash/login/ui/login_display_webui.cc",
-    "../ash/login/ui/login_display_webui.h",
-    "../ash/login/ui/login_feedback.cc",
-    "../ash/login/ui/login_feedback.h",
-    "../ash/login/ui/login_screen_extension_ui/create_options.cc",
-    "../ash/login/ui/login_screen_extension_ui/create_options.h",
-    "../ash/login/ui/login_screen_extension_ui/dialog_delegate.cc",
-    "../ash/login/ui/login_screen_extension_ui/dialog_delegate.h",
-    "../ash/login/ui/login_screen_extension_ui/web_dialog_view.cc",
-    "../ash/login/ui/login_screen_extension_ui/web_dialog_view.h",
-    "../ash/login/ui/login_screen_extension_ui/window.cc",
-    "../ash/login/ui/login_screen_extension_ui/window.h",
-    "../ash/login/ui/login_web_dialog.cc",
-    "../ash/login/ui/login_web_dialog.h",
-    "../ash/login/ui/oobe_dialog_size_utils.cc",
-    "../ash/login/ui/oobe_dialog_size_utils.h",
-    "../ash/login/ui/oobe_ui_dialog_delegate.cc",
-    "../ash/login/ui/oobe_ui_dialog_delegate.h",
-    "../ash/login/ui/signin_ui.h",
-    "../ash/login/ui/simple_web_view_dialog.cc",
-    "../ash/login/ui/simple_web_view_dialog.h",
-    "../ash/login/ui/user_adding_screen.cc",
-    "../ash/login/ui/user_adding_screen.h",
-    "../ash/login/ui/user_adding_screen_input_methods_controller.cc",
-    "../ash/login/ui/user_adding_screen_input_methods_controller.h",
-    "../ash/login/ui/views/user_board_view.h",
-    "../ash/login/ui/web_contents_forced_title.cc",
-    "../ash/login/ui/web_contents_forced_title.h",
-    "../ash/login/ui/webui_login_view.cc",
-    "../ash/login/ui/webui_login_view.h",
-    "../ash/login/user_board_view_mojo.cc",
-    "../ash/login/user_board_view_mojo.h",
-    "../ash/login/user_flow.cc",
-    "../ash/login/user_flow.h",
-    "../ash/login/user_online_signin_notifier.cc",
-    "../ash/login/user_online_signin_notifier.h",
-    "../ash/login/users/affiliation.cc",
-    "../ash/login/users/affiliation.h",
-    "../ash/login/users/avatar/user_image_file_selector.cc",
-    "../ash/login/users/avatar/user_image_file_selector.h",
-    "../ash/login/users/avatar/user_image_loader.cc",
-    "../ash/login/users/avatar/user_image_loader.h",
-    "../ash/login/users/avatar/user_image_manager.cc",
-    "../ash/login/users/avatar/user_image_manager.h",
-    "../ash/login/users/avatar/user_image_manager_impl.cc",
-    "../ash/login/users/avatar/user_image_manager_impl.h",
-    "../ash/login/users/avatar/user_image_sync_observer.cc",
-    "../ash/login/users/avatar/user_image_sync_observer.h",
-    "../ash/login/users/chrome_user_manager.cc",
-    "../ash/login/users/chrome_user_manager.h",
-    "../ash/login/users/chrome_user_manager_impl.cc",
-    "../ash/login/users/chrome_user_manager_impl.h",
-    "../ash/login/users/chrome_user_manager_util.cc",
-    "../ash/login/users/chrome_user_manager_util.h",
-    "../ash/login/users/default_user_image/default_user_images.cc",
-    "../ash/login/users/default_user_image/default_user_images.h",
-    "../ash/login/users/multi_profile_user_controller.cc",
-    "../ash/login/users/multi_profile_user_controller.h",
-    "../ash/login/users/multi_profile_user_controller_delegate.h",
-    "../ash/login/users/scoped_test_user_manager.cc",
-    "../ash/login/users/scoped_test_user_manager.h",
-    "../ash/login/users/supervised_user_manager.h",
-    "../ash/login/users/supervised_user_manager_impl.cc",
-    "../ash/login/users/supervised_user_manager_impl.h",
-    "../ash/login/users/test_users.cc",
-    "../ash/login/users/test_users.h",
-    "../ash/login/users/user_manager_interface.h",
-    "../ash/login/version_info_updater.cc",
-    "../ash/login/version_info_updater.h",
-    "../ash/login/version_updater/update_time_estimator.cc",
-    "../ash/login/version_updater/update_time_estimator.h",
-    "../ash/login/version_updater/version_updater.cc",
-    "../ash/login/version_updater/version_updater.h",
-    "../ash/login/wizard_context.cc",
-    "../ash/login/wizard_context.h",
-    "../ash/login/wizard_controller.cc",
-    "../ash/login/wizard_controller.h",
-    "../ash/mobile/mobile_activator.cc",
-    "../ash/mobile/mobile_activator.h",
-    "../ash/multidevice_setup/auth_token_validator_factory.cc",
-    "../ash/multidevice_setup/auth_token_validator_factory.h",
-    "../ash/multidevice_setup/auth_token_validator_impl.cc",
-    "../ash/multidevice_setup/auth_token_validator_impl.h",
-    "../ash/multidevice_setup/multidevice_setup_client_factory.cc",
-    "../ash/multidevice_setup/multidevice_setup_client_factory.h",
-    "../ash/multidevice_setup/multidevice_setup_service_factory.cc",
-    "../ash/multidevice_setup/multidevice_setup_service_factory.h",
-    "../ash/multidevice_setup/oobe_completion_tracker_factory.cc",
-    "../ash/multidevice_setup/oobe_completion_tracker_factory.h",
-    "../ash/nearby/nearby_connections_dependencies_provider.cc",
-    "../ash/nearby/nearby_connections_dependencies_provider.h",
-    "../ash/nearby/nearby_connections_dependencies_provider_factory.cc",
-    "../ash/nearby/nearby_connections_dependencies_provider_factory.h",
-    "../ash/nearby/nearby_process_manager_factory.cc",
-    "../ash/nearby/nearby_process_manager_factory.h",
-    "../ash/nearby/nearby_process_manager_impl.cc",
-    "../ash/nearby/nearby_process_manager_impl.h",
-    "../ash/net/bluetooth_pref_state_observer.cc",
-    "../ash/net/bluetooth_pref_state_observer.h",
-    "../ash/net/client_cert_filter.cc",
-    "../ash/net/client_cert_filter.h",
-    "../ash/net/client_cert_store_ash.cc",
-    "../ash/net/client_cert_store_ash.h",
-    "../ash/net/delay_network_call.cc",
-    "../ash/net/delay_network_call.h",
-    "../ash/net/dhcp_wpad_url_client.cc",
-    "../ash/net/dhcp_wpad_url_client.h",
-    "../ash/net/network_diagnostics/arc_dns_resolution_routine.cc",
-    "../ash/net/network_diagnostics/arc_dns_resolution_routine.h",
-    "../ash/net/network_diagnostics/arc_http_routine.cc",
-    "../ash/net/network_diagnostics/arc_http_routine.h",
-    "../ash/net/network_diagnostics/arc_ping_routine.cc",
-    "../ash/net/network_diagnostics/arc_ping_routine.h",
-    "../ash/net/network_diagnostics/captive_portal_routine.cc",
-    "../ash/net/network_diagnostics/captive_portal_routine.h",
-    "../ash/net/network_diagnostics/dns_latency_routine.cc",
-    "../ash/net/network_diagnostics/dns_latency_routine.h",
-    "../ash/net/network_diagnostics/dns_resolution_routine.cc",
-    "../ash/net/network_diagnostics/dns_resolution_routine.h",
-    "../ash/net/network_diagnostics/dns_resolver_present_routine.cc",
-    "../ash/net/network_diagnostics/dns_resolver_present_routine.h",
-    "../ash/net/network_diagnostics/gateway_can_be_pinged_routine.cc",
-    "../ash/net/network_diagnostics/gateway_can_be_pinged_routine.h",
-    "../ash/net/network_diagnostics/has_secure_wifi_connection_routine.cc",
-    "../ash/net/network_diagnostics/has_secure_wifi_connection_routine.h",
-    "../ash/net/network_diagnostics/host_resolver.cc",
-    "../ash/net/network_diagnostics/host_resolver.h",
-    "../ash/net/network_diagnostics/http_firewall_routine.cc",
-    "../ash/net/network_diagnostics/http_firewall_routine.h",
-    "../ash/net/network_diagnostics/http_request_manager.cc",
-    "../ash/net/network_diagnostics/http_request_manager.h",
-    "../ash/net/network_diagnostics/https_firewall_routine.cc",
-    "../ash/net/network_diagnostics/https_firewall_routine.h",
-    "../ash/net/network_diagnostics/https_latency_routine.cc",
-    "../ash/net/network_diagnostics/https_latency_routine.h",
-    "../ash/net/network_diagnostics/lan_connectivity_routine.cc",
-    "../ash/net/network_diagnostics/lan_connectivity_routine.h",
-    "../ash/net/network_diagnostics/network_diagnostics.cc",
-    "../ash/net/network_diagnostics/network_diagnostics.h",
-    "../ash/net/network_diagnostics/network_diagnostics_routine.cc",
-    "../ash/net/network_diagnostics/network_diagnostics_routine.h",
-    "../ash/net/network_diagnostics/network_diagnostics_util.cc",
-    "../ash/net/network_diagnostics/network_diagnostics_util.h",
-    "../ash/net/network_diagnostics/signal_strength_routine.cc",
-    "../ash/net/network_diagnostics/signal_strength_routine.h",
-    "../ash/net/network_diagnostics/tls_prober.cc",
-    "../ash/net/network_diagnostics/tls_prober.h",
-    "../ash/net/network_diagnostics/udp_prober.cc",
-    "../ash/net/network_diagnostics/udp_prober.h",
-    "../ash/net/network_diagnostics/video_conferencing_routine.cc",
-    "../ash/net/network_diagnostics/video_conferencing_routine.h",
-    "../ash/net/network_health/network_health.cc",
-    "../ash/net/network_health/network_health.h",
-    "../ash/net/network_health/network_health_constants.h",
-    "../ash/net/network_health/network_health_service.cc",
-    "../ash/net/network_health/network_health_service.h",
-    "../ash/net/network_health/signal_strength_tracker.cc",
-    "../ash/net/network_health/signal_strength_tracker.h",
-    "../ash/net/network_portal_detector_impl.cc",
-    "../ash/net/network_portal_detector_impl.h",
-    "../ash/net/network_portal_detector_test_impl.cc",
-    "../ash/net/network_portal_detector_test_impl.h",
-    "../ash/net/network_portal_web_dialog.cc",
-    "../ash/net/network_portal_web_dialog.h",
-    "../ash/net/network_pref_state_observer.cc",
-    "../ash/net/network_pref_state_observer.h",
-    "../ash/net/network_throttling_observer.cc",
-    "../ash/net/network_throttling_observer.h",
-    "../ash/net/rollback_network_config/rollback_network_config.cc",
-    "../ash/net/rollback_network_config/rollback_network_config.h",
-    "../ash/net/rollback_network_config/rollback_network_config_service.cc",
-    "../ash/net/rollback_network_config/rollback_network_config_service.h",
-    "../ash/net/rollback_network_config/rollback_onc_util.cc",
-    "../ash/net/rollback_network_config/rollback_onc_util.h",
-    "../ash/net/secure_dns_manager.cc",
-    "../ash/net/secure_dns_manager.h",
-    "../ash/net/system_proxy_manager.cc",
-    "../ash/net/system_proxy_manager.h",
-    "../ash/net/traffic_counters_handler.cc",
-    "../ash/net/traffic_counters_handler.h",
-    "../ash/network_change_manager_client.cc",
-    "../ash/network_change_manager_client.h",
-    "../ash/night_light/night_light_client.cc",
-    "../ash/night_light/night_light_client.h",
-    "../ash/note_taking_controller_client.cc",
-    "../ash/note_taking_controller_client.h",
-    "../ash/note_taking_helper.cc",
-    "../ash/note_taking_helper.h",
-    "../ash/notifications/adb_sideloading_policy_change_notification.cc",
-    "../ash/notifications/adb_sideloading_policy_change_notification.h",
-    "../ash/notifications/debugd_notification_handler.cc",
-    "../ash/notifications/debugd_notification_handler.h",
-    "../ash/notifications/deprecation_notification_controller.cc",
-    "../ash/notifications/deprecation_notification_controller.h",
-    "../ash/notifications/echo_dialog_listener.h",
-    "../ash/notifications/echo_dialog_view.cc",
-    "../ash/notifications/echo_dialog_view.h",
-    "../ash/notifications/gnubby_notification.cc",
-    "../ash/notifications/gnubby_notification.h",
-    "../ash/notifications/idle_app_name_notification_view.cc",
-    "../ash/notifications/idle_app_name_notification_view.h",
-    "../ash/notifications/kiosk_external_update_notification.cc",
-    "../ash/notifications/kiosk_external_update_notification.h",
-    "../ash/notifications/low_disk_notification.cc",
-    "../ash/notifications/low_disk_notification.h",
-    "../ash/notifications/request_system_proxy_credentials_view.cc",
-    "../ash/notifications/request_system_proxy_credentials_view.h",
-    "../ash/notifications/screen_capture_notification_ui_ash.cc",
-    "../ash/notifications/screen_capture_notification_ui_ash.h",
-    "../ash/notifications/system_proxy_notification.cc",
-    "../ash/notifications/system_proxy_notification.h",
-    "../ash/notifications/tpm_auto_update_notification.cc",
-    "../ash/notifications/tpm_auto_update_notification.h",
-    "../ash/notifications/update_required_notification.cc",
-    "../ash/notifications/update_required_notification.h",
-    "../ash/os_feedback/chrome_os_feedback_delegate.cc",
-    "../ash/os_feedback/chrome_os_feedback_delegate.h",
-    "../ash/os_feedback/os_feedback_screenshot_manager.cc",
-    "../ash/os_feedback/os_feedback_screenshot_manager.h",
-    "../ash/ownership/fake_owner_settings_service.cc",
-    "../ash/ownership/fake_owner_settings_service.h",
-    "../ash/ownership/owner_settings_service_ash.cc",
-    "../ash/ownership/owner_settings_service_ash.h",
-    "../ash/ownership/owner_settings_service_ash_factory.cc",
-    "../ash/ownership/owner_settings_service_ash_factory.h",
     "../ash/pcie_peripheral/ash_usb_detector.cc",
     "../ash/pcie_peripheral/ash_usb_detector.h",
     "../ash/phonehub/browser_tabs_metadata_fetcher_impl.cc",
diff --git a/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/LightweightReactionsMediator.java b/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/LightweightReactionsMediator.java
index 816a83d..57cad328 100644
--- a/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/LightweightReactionsMediator.java
+++ b/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/LightweightReactionsMediator.java
@@ -12,6 +12,7 @@
 import org.chromium.base.Callback;
 import org.chromium.base.StreamUtil;
 import org.chromium.chrome.browser.content_creation.reactions.scene.SceneCoordinator;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.components.browser_ui.share.ShareImageFileUtils;
 import org.chromium.components.browser_ui.share.ShareImageFileUtils.FileOutputStreamWriter;
 import org.chromium.components.content_creation.reactions.ReactionMetadata;
@@ -44,6 +45,10 @@
         public void drawFrame(Canvas canvas);
     }
 
+    // Field trial params
+    private static final String SHOULD_LOAD_REACTIONS_ON_DEMAND_PARAM =
+            "should_load_reactions_on_demand";
+
     // GIF encoding constants
     private static final String GIF_FILE_EXT = ".gif";
     private static final int GIF_FPS = 24;
@@ -99,10 +104,17 @@
         }
 
         mAssetFetchCancelled = false;
+        boolean shouldLoadReactionsOnDemand =
+                ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean(
+                        ChromeFeatureList.LIGHTWEIGHT_REACTIONS,
+                        SHOULD_LOAD_REACTIONS_ON_DEMAND_PARAM, false);
 
-        // Keep track of the number of callbacks received (two per reaction expected). Need a
-        // final instance because the counter is updated from within a callback.
-        final Counter counter = new Counter(reactions.size() * 2);
+        // Keep track of the number of callbacks received. Need a final instance because the
+        // counter is updated from within a callback. If the full reactions are not loaded on
+        // demand (loaded here), multiply the number of reactions by 2 as both the thumbnails and
+        // full reactions are loaded.
+        int expectedCalls = shouldLoadReactionsOnDemand ? reactions.size() : reactions.size() * 2;
+        final Counter counter = new Counter(expectedCalls);
 
         // Also use a final array to keep track of the thumbnails fetched so far. Initialize it with
         // null refs so the fetched bitmaps can be inserted at the right index.
@@ -130,22 +142,24 @@
                     callback.onResult(thumbnails);
                 }
             });
-            getGifForUrl(reaction.assetUrl, gif -> {
-                if (mAssetFetchCancelled) {
-                    return;
-                }
-                if (gif == null) {
-                    mAssetFetchCancelled = true;
-                    callback.onResult(null);
-                    return;
-                }
+            if (!shouldLoadReactionsOnDemand) {
+                getGifForUrl(reaction.assetUrl, gif -> {
+                    if (mAssetFetchCancelled) {
+                        return;
+                    }
+                    if (gif == null) {
+                        mAssetFetchCancelled = true;
+                        callback.onResult(null);
+                        return;
+                    }
 
-                counter.increment();
+                    counter.increment();
 
-                if (counter.isDone()) {
-                    callback.onResult(thumbnails);
-                }
-            });
+                    if (counter.isDone()) {
+                        callback.onResult(thumbnails);
+                    }
+                });
+            }
         }
     }
 
diff --git a/chrome/browser/enterprise/connectors/analysis/content_analysis_dialog.cc b/chrome/browser/enterprise/connectors/analysis/content_analysis_dialog.cc
index d0e08fd..ff05b74 100644
--- a/chrome/browser/enterprise/connectors/analysis/content_analysis_dialog.cc
+++ b/chrome/browser/enterprise/connectors/analysis/content_analysis_dialog.cc
@@ -243,6 +243,14 @@
 
   constrained_window::ShowWebModalDialogViews(this, web_contents_);
 
+  // We need to UpdateDialog() right away if the dialog already has a result,
+  // because the dialog can only call UpdateDialog() after the dialog widget
+  // has been initialized by ShowWebModalDialogViews().
+  // We can't move it any earlier or it will crash when we try to get the
+  // color from the widget. (see b/232104687)
+  if (!is_pending())
+    UpdateDialog();
+
   if (observer_for_testing)
     observer_for_testing->ViewsFirstShown(this, first_shown_timestamp_);
 }
@@ -365,14 +373,6 @@
     message_->SetMultiLine(true);
     message_->SetVerticalAlignment(gfx::ALIGN_MIDDLE);
     message_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
-
-    // Add the Learn More link but hide it so it can only be displayed when
-    // required.
-
-    // If the dialog was started in a state other than pending, setup the views
-    // accordingly.
-    if (!is_pending())
-      UpdateViews();
   }
 
   return contents_view_;
@@ -866,12 +866,10 @@
       base::NumberToString16(0),
       base::NumberToString16(kMaxBypassJustificationLength)));
 
-  // Set the color to red initially because a 0 length message is invalid, but
-  // the label doesn't have a Color Provider yet when it's created.
-  // TODO(b/232104687): Re-enable once the bug is fixed
-  // bypass_justification_text_length_->SetEnabledColor(
-  //     bypass_justification_text_length_->GetColorProvider()->GetColor(
-  //         ui::kColorAlertHighSeverity));
+  // Set the color to red initially because a 0 length message is invalid
+  bypass_justification_text_length_->SetEnabledColor(
+      bypass_justification_text_length_->GetColorProvider()->GetColor(
+          ui::kColorAlertHighSeverity));
 }
 
 bool ContentAnalysisDialog::ShouldUseDarkTopImage() const {
diff --git a/chrome/browser/enterprise/connectors/analysis/content_analysis_dialog.h b/chrome/browser/enterprise/connectors/analysis/content_analysis_dialog.h
index a29c8d6..a073d62 100644
--- a/chrome/browser/enterprise/connectors/analysis/content_analysis_dialog.h
+++ b/chrome/browser/enterprise/connectors/analysis/content_analysis_dialog.h
@@ -200,6 +200,7 @@
   // Update the UI depending on `dialog_state_`. This also triggers resizes and
   // fires some events. It's meant to be called to update the entire dialog when
   // it's already showing.
+  // This function can only be called after the dialog widget is initialized.
   void UpdateDialog();
 
   // Resizes the already shown dialog to accommodate changes in its content.
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn
index 2aac1aa..9a37b59 100644
--- a/chrome/browser/extensions/BUILD.gn
+++ b/chrome/browser/extensions/BUILD.gn
@@ -141,6 +141,8 @@
     "api/downloads_internal/downloads_internal_api.h",
     "api/enterprise_hardware_platform/enterprise_hardware_platform_api.cc",
     "api/enterprise_hardware_platform/enterprise_hardware_platform_api.h",
+    "api/enterprise_reporting_private/conversion_utils.cc",
+    "api/enterprise_reporting_private/conversion_utils.h",
     "api/enterprise_reporting_private/enterprise_reporting_private_api.cc",
     "api/enterprise_reporting_private/enterprise_reporting_private_api.h",
     "api/extension_action/extension_action_api.cc",
@@ -810,6 +812,8 @@
     "//components/content_settings/core/browser",
     "//components/cookie_config:cookie_config",
     "//components/crx_file",
+    "//components/device_signals/core/browser",
+    "//components/device_signals/core/common",
     "//components/dom_distiller/core",
     "//components/download/content/public",
     "//components/download/public/common:public",
@@ -952,6 +956,8 @@
       "api/system_indicator/system_indicator_manager_factory.cc",
       "api/system_indicator/system_indicator_manager_factory.h",
     ]
+
+    deps += [ "//chrome/browser/enterprise/signals:features" ]
   }
 
   if (is_chromeos) {
@@ -1264,6 +1270,7 @@
       "system_display/display_info_provider_win.h",
     ]
     deps += [
+      "//components/device_signals/core/common/win",
       "//third_party/iaccessible2",
       "//third_party/isimpledom",
     ]
diff --git a/chrome/browser/extensions/api/enterprise_reporting_private/DEPS b/chrome/browser/extensions/api/enterprise_reporting_private/DEPS
new file mode 100644
index 0000000..3023fa8
--- /dev/null
+++ b/chrome/browser/extensions/api/enterprise_reporting_private/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  "+components/device_signals/core",
+]
diff --git a/chrome/browser/extensions/api/enterprise_reporting_private/conversion_utils.cc b/chrome/browser/extensions/api/enterprise_reporting_private/conversion_utils.cc
new file mode 100644
index 0000000..75597de
--- /dev/null
+++ b/chrome/browser/extensions/api/enterprise_reporting_private/conversion_utils.cc
@@ -0,0 +1,100 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/extensions/api/enterprise_reporting_private/conversion_utils.h"
+
+#if BUILDFLAG(IS_WIN)
+
+#include "components/device_signals/core/browser/signals_types.h"
+#include "components/device_signals/core/common/win/win_types.h"
+
+using SignalCollectionError = device_signals::SignalCollectionError;
+
+namespace extensions {
+
+namespace {
+
+absl::optional<SignalCollectionError> TryParseError(
+    const device_signals::SignalsAggregationResponse& response,
+    const absl::optional<device_signals::BaseSignalResponse>& bundle) {
+  absl::optional<std::string> error_string;
+  if (response.top_level_error.has_value()) {
+    return response.top_level_error.value();
+  }
+
+  if (!bundle.has_value()) {
+    return SignalCollectionError::kMissingBundle;
+  }
+
+  return bundle->collection_error;
+}
+
+}  // namespace
+
+absl::optional<SignalCollectionError> ConvertAvProductsResponse(
+    const device_signals::SignalsAggregationResponse& response,
+    std::vector<api::enterprise_reporting_private::AntiVirusSignal>* arg_list) {
+  auto error = TryParseError(response, response.av_signal_response);
+  if (error.has_value()) {
+    return error.value();
+  }
+
+  std::vector<api::enterprise_reporting_private::AntiVirusSignal>
+      api_av_signals;
+  const auto& av_response = response.av_signal_response.value();
+  for (const auto& av_product : av_response.av_products) {
+    api::enterprise_reporting_private::AntiVirusSignal api_av_signal;
+    api_av_signal.display_name = av_product.display_name;
+    api_av_signal.product_id = av_product.product_id;
+
+    switch (av_product.state) {
+      case device_signals::AvProductState::kOn:
+        api_av_signal.state = api::enterprise_reporting_private::
+            AntiVirusProductState::ANTI_VIRUS_PRODUCT_STATE_ON;
+        break;
+      case device_signals::AvProductState::kOff:
+        api_av_signal.state = api::enterprise_reporting_private::
+            AntiVirusProductState::ANTI_VIRUS_PRODUCT_STATE_OFF;
+        break;
+      case device_signals::AvProductState::kSnoozed:
+        api_av_signal.state = api::enterprise_reporting_private::
+            AntiVirusProductState::ANTI_VIRUS_PRODUCT_STATE_SNOOZED;
+        break;
+      case device_signals::AvProductState::kExpired:
+        api_av_signal.state = api::enterprise_reporting_private::
+            AntiVirusProductState::ANTI_VIRUS_PRODUCT_STATE_EXPIRED;
+        break;
+    }
+
+    api_av_signals.push_back(std::move(api_av_signal));
+  }
+
+  *arg_list = std::move(api_av_signals);
+  return absl::nullopt;
+}
+
+absl::optional<SignalCollectionError> ConvertHotfixesResponse(
+    const device_signals::SignalsAggregationResponse& response,
+    std::vector<api::enterprise_reporting_private::HotfixSignal>* arg_list) {
+  auto error = TryParseError(response, response.hotfix_signal_response);
+  if (error.has_value()) {
+    return error.value();
+  }
+
+  std::vector<api::enterprise_reporting_private::HotfixSignal>
+      api_hotfix_signals;
+  const auto& hotfix_response = response.hotfix_signal_response.value();
+  for (const auto& hotfix : hotfix_response.hotfixes) {
+    api::enterprise_reporting_private::HotfixSignal api_hotfix;
+    api_hotfix.hotfix_id = hotfix.hotfix_id;
+    api_hotfix_signals.push_back(std::move(api_hotfix));
+  }
+
+  *arg_list = std::move(api_hotfix_signals);
+  return absl::nullopt;
+}
+
+}  // namespace extensions
+
+#endif  // BUILDFLAG(IS_WIN)
diff --git a/chrome/browser/extensions/api/enterprise_reporting_private/conversion_utils.h b/chrome/browser/extensions/api/enterprise_reporting_private/conversion_utils.h
new file mode 100644
index 0000000..f83a10b
--- /dev/null
+++ b/chrome/browser/extensions/api/enterprise_reporting_private/conversion_utils.h
@@ -0,0 +1,42 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_API_ENTERPRISE_REPORTING_PRIVATE_CONVERSION_UTILS_H_
+#define CHROME_BROWSER_EXTENSIONS_API_ENTERPRISE_REPORTING_PRIVATE_CONVERSION_UTILS_H_
+
+#include "build/build_config.h"
+
+#if BUILDFLAG(IS_WIN)
+
+#include <vector>
+
+#include "chrome/common/extensions/api/enterprise_reporting_private.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace device_signals {
+struct SignalsAggregationResponse;
+enum class SignalCollectionError;
+}  // namespace device_signals
+
+namespace extensions {
+
+// Parses and converts the Antivirus signal values from `response` into
+// `arg_list`. If any error occurred during signal collection, it will be
+// returned and `arg_list` will remain unchanged.
+absl::optional<device_signals::SignalCollectionError> ConvertAvProductsResponse(
+    const device_signals::SignalsAggregationResponse& response,
+    std::vector<api::enterprise_reporting_private::AntiVirusSignal>* arg_list);
+
+// Parses and converts the Hotfix signal values from `response` into
+// `arg_list`. If any error occurred during signal collection,  it will be
+// returned and `arg_list` will remain unchanged.
+absl::optional<device_signals::SignalCollectionError> ConvertHotfixesResponse(
+    const device_signals::SignalsAggregationResponse& response,
+    std::vector<api::enterprise_reporting_private::HotfixSignal>* arg_list);
+
+}  // namespace extensions
+
+#endif  // BUILDFLAG(IS_WIN)
+
+#endif  // CHROME_BROWSER_EXTENSIONS_API_ENTERPRISE_REPORTING_PRIVATE_CONVERSION_UTILS_H_
diff --git a/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_api.cc b/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_api.cc
index 7caa584b..1efc6d6 100644
--- a/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_api.cc
+++ b/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_api.cc
@@ -8,6 +8,7 @@
 #include <utility>
 
 #include "base/bind.h"
+#include "base/callback.h"
 #include "base/strings/stringprintf.h"
 #include "base/task/thread_pool.h"
 #include "base/threading/thread_task_runner_handle.h"
@@ -30,6 +31,16 @@
 #include "components/reporting/util/statusor.h"
 #endif
 
+#if BUILDFLAG(IS_WIN)
+#include "chrome/browser/enterprise/signals/signals_aggregator_factory.h"
+#include "chrome/browser/enterprise/signals/signals_features.h"  // nogncheck
+#include "chrome/browser/extensions/api/enterprise_reporting_private/conversion_utils.h"
+#include "components/device_signals/core/browser/signals_aggregator.h"
+#include "components/device_signals/core/browser/signals_types.h"
+#include "components/device_signals/core/browser/user_context.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+#endif  // BUILDFLAG(IS_WIN)
+
 #include "components/content_settings/core/common/pref_names.h"
 #include "components/enterprise/browser/controller/browser_dm_token_storage.h"
 #include "net/cert/x509_util.h"
@@ -142,6 +153,36 @@
   return info;
 }
 
+#if BUILDFLAG(IS_WIN)
+
+device_signals::SignalsAggregationRequest CreateAggregationRequest(
+    const std::string& user_id,
+    device_signals::SignalName signal_name) {
+  device_signals::UserContext user_context;
+  user_context.user_id = user_id;
+
+  device_signals::SignalsAggregationRequest request;
+  request.user_context = std::move(user_context);
+  request.signal_names.emplace(signal_name);
+  return request;
+}
+
+void StartSignalCollection(
+    device_signals::SignalsAggregationRequest request,
+    content::BrowserContext* browser_context,
+    base::OnceCallback<void(device_signals::SignalsAggregationResponse)>
+        callback) {
+  DCHECK(browser_context);
+  auto* profile = Profile::FromBrowserContext(browser_context);
+  DCHECK(profile);
+  auto* signals_aggregator =
+      enterprise_signals::SignalsAggregatorFactory::GetForProfile(profile);
+  DCHECK(signals_aggregator);
+  signals_aggregator->GetSignals(std::move(request), std::move(callback));
+}
+
+#endif  // BUILDFLAG(IS_WIN)
+
 }  // namespace
 
 #if !BUILDFLAG(IS_CHROMEOS)
@@ -608,4 +649,98 @@
 }
 #endif
 
+#if BUILDFLAG(IS_WIN)
+
+// getAvInfo
+
+EnterpriseReportingPrivateGetAvInfoFunction::
+    EnterpriseReportingPrivateGetAvInfoFunction() = default;
+EnterpriseReportingPrivateGetAvInfoFunction::
+    ~EnterpriseReportingPrivateGetAvInfoFunction() = default;
+
+ExtensionFunction::ResponseAction
+EnterpriseReportingPrivateGetAvInfoFunction::Run() {
+  if (!IsNewFunctionEnabled(
+          enterprise_signals::features::NewEvFunction::kAntiVirus)) {
+    return RespondNow(Error(device_signals::ErrorToString(
+        device_signals::SignalCollectionError::kUnsupported)));
+  }
+
+  std::unique_ptr<api::enterprise_reporting_private::GetAvInfo::Params> params(
+      api::enterprise_reporting_private::GetAvInfo::Params::Create(args()));
+  EXTENSION_FUNCTION_VALIDATE(params.get());
+
+  StartSignalCollection(
+      CreateAggregationRequest(params->user_context.user_id,
+                               device_signals::SignalName::kAntiVirus),
+      browser_context(),
+      base::BindOnce(
+          &EnterpriseReportingPrivateGetAvInfoFunction::OnSignalRetrieved,
+          this));
+
+  return RespondLater();
+}
+
+void EnterpriseReportingPrivateGetAvInfoFunction::OnSignalRetrieved(
+    device_signals::SignalsAggregationResponse response) {
+  std::vector<api::enterprise_reporting_private::AntiVirusSignal> arg_list;
+  auto error = ConvertAvProductsResponse(response, &arg_list);
+
+  if (error.has_value()) {
+    Respond(Error(device_signals::ErrorToString(error.value())));
+    return;
+  }
+
+  Respond(ArgumentList(
+      api::enterprise_reporting_private::GetAvInfo::Results::Create(arg_list)));
+}
+
+// getHotfixes
+
+EnterpriseReportingPrivateGetHotfixesFunction::
+    EnterpriseReportingPrivateGetHotfixesFunction() = default;
+EnterpriseReportingPrivateGetHotfixesFunction::
+    ~EnterpriseReportingPrivateGetHotfixesFunction() = default;
+
+ExtensionFunction::ResponseAction
+EnterpriseReportingPrivateGetHotfixesFunction::Run() {
+  if (!IsNewFunctionEnabled(
+          enterprise_signals::features::NewEvFunction::kHotfix)) {
+    return RespondNow(Error(device_signals::ErrorToString(
+        device_signals::SignalCollectionError::kUnsupported)));
+  }
+
+  std::unique_ptr<api::enterprise_reporting_private::GetHotfixes::Params>
+      params(api::enterprise_reporting_private::GetHotfixes::Params::Create(
+          args()));
+  EXTENSION_FUNCTION_VALIDATE(params.get());
+
+  StartSignalCollection(
+      CreateAggregationRequest(params->user_context.user_id,
+                               device_signals::SignalName::kHotfixes),
+      browser_context(),
+      base::BindOnce(
+          &EnterpriseReportingPrivateGetHotfixesFunction::OnSignalRetrieved,
+          this));
+
+  return RespondLater();
+}
+
+void EnterpriseReportingPrivateGetHotfixesFunction::OnSignalRetrieved(
+    device_signals::SignalsAggregationResponse response) {
+  std::vector<api::enterprise_reporting_private::HotfixSignal> arg_list;
+  auto error = ConvertHotfixesResponse(response, &arg_list);
+
+  if (error.has_value()) {
+    Respond(Error(device_signals::ErrorToString(error.value())));
+    return;
+  }
+
+  Respond(ArgumentList(
+      api::enterprise_reporting_private::GetHotfixes::Results::Create(
+          arg_list)));
+}
+
+#endif  // BUILDFLAG(IS_WIN)
+
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_api.h b/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_api.h
index bc0a5a7e..dc2ae67 100644
--- a/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_api.h
+++ b/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_api.h
@@ -19,7 +19,9 @@
 #include "components/reporting/proto/synced/record.pb.h"
 #include "components/reporting/proto/synced/record_constants.pb.h"
 #include "components/reporting/util/statusor.h"
-#endif
+#elif BUILDFLAG(IS_WIN)
+#include "components/device_signals/core/browser/signals_types.h"
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
 #include "extensions/browser/extension_function.h"
 
@@ -262,6 +264,50 @@
 
 #endif
 
+#if BUILDFLAG(IS_WIN)
+
+class EnterpriseReportingPrivateGetAvInfoFunction : public ExtensionFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("enterprise.reportingPrivate.getAvInfo",
+                             ENTERPRISEREPORTINGPRIVATE_GETAVINFO)
+
+  EnterpriseReportingPrivateGetAvInfoFunction();
+  EnterpriseReportingPrivateGetAvInfoFunction(
+      const EnterpriseReportingPrivateGetAvInfoFunction&) = delete;
+  EnterpriseReportingPrivateGetAvInfoFunction& operator=(
+      const EnterpriseReportingPrivateGetAvInfoFunction&) = delete;
+
+ private:
+  ~EnterpriseReportingPrivateGetAvInfoFunction() override;
+
+  // ExtensionFunction
+  ExtensionFunction::ResponseAction Run() override;
+
+  void OnSignalRetrieved(device_signals::SignalsAggregationResponse response);
+};
+
+class EnterpriseReportingPrivateGetHotfixesFunction : public ExtensionFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("enterprise.reportingPrivate.getHotfixes",
+                             ENTERPRISEREPORTINGPRIVATE_GETHOTFIXES)
+
+  EnterpriseReportingPrivateGetHotfixesFunction();
+  EnterpriseReportingPrivateGetHotfixesFunction(
+      const EnterpriseReportingPrivateGetHotfixesFunction&) = delete;
+  EnterpriseReportingPrivateGetHotfixesFunction& operator=(
+      const EnterpriseReportingPrivateGetHotfixesFunction&) = delete;
+
+ private:
+  ~EnterpriseReportingPrivateGetHotfixesFunction() override;
+
+  // ExtensionFunction
+  ExtensionFunction::ResponseAction Run() override;
+
+  void OnSignalRetrieved(device_signals::SignalsAggregationResponse response);
+};
+
+#endif  // BUILDFLAG(IS_WIN)
+
 }  // namespace extensions
 
 #endif  // CHROME_BROWSER_EXTENSIONS_API_ENTERPRISE_REPORTING_PRIVATE_ENTERPRISE_REPORTING_PRIVATE_API_H_
diff --git a/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_unittest.cc b/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_unittest.cc
index 5a07332..0b25242 100644
--- a/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_unittest.cc
+++ b/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_unittest.cc
@@ -33,6 +33,7 @@
 #include "components/reporting/proto/synced/record.pb.h"
 #include "components/safe_browsing/core/common/safe_browsing_prefs.h"
 #include "components/version_info/version_info.h"
+#include "extensions/browser/api_test_utils.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -49,7 +50,13 @@
 #include <windows.h>
 #include <wrl/client.h>
 
+#include "base/test/scoped_feature_list.h"
 #include "base/test/test_reg_util_win.h"
+#include "chrome/browser/enterprise/signals/signals_aggregator_factory.h"
+#include "chrome/browser/enterprise/signals/signals_features.h"  // nogncheck
+#include "components/device_signals/core/browser/mock_signals_aggregator.h"  // nogncheck
+#include "components/device_signals/core/browser/signals_aggregator.h"  // nogncheck
+#include "components/device_signals/core/common/signals_constants.h"  // nogncheck
 #endif
 
 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
@@ -68,11 +75,17 @@
 
 namespace extensions {
 
+#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_WIN)
+
+constexpr char kNoError[] = "";
+
+#endif  // BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_WIN)
+
 #if !BUILDFLAG(IS_CHROMEOS)
 
 namespace {
 
-const char kFakeClientId[] = "fake-client-id";
+constexpr char kFakeClientId[] = "fake-client-id";
 
 }  // namespace
 
@@ -1059,7 +1072,6 @@
 class EnterpriseReportingPrivateEnqueueRecordFunctionTest
     : public ExtensionApiUnittest {
  protected:
-  static constexpr char kNoError[] = "";
   static constexpr char kTestDMTokenValue[] = "test_dm_token_value";
 
   EnterpriseReportingPrivateEnqueueRecordFunctionTest() = default;
@@ -1279,4 +1291,270 @@
 }
 #endif  // BUILDFLAG(IS_CHROMEOS)
 
+#if BUILDFLAG(IS_WIN)
+
+namespace {
+
+constexpr char kFakeUserId[] = "fake user id";
+
+enterprise_reporting_private::UserContext GetFakeUserContext() {
+  enterprise_reporting_private::UserContext user_context;
+  user_context.user_id = kFakeUserId;
+  return user_context;
+}
+
+std::string GetFakeUserContextJsonParams() {
+  auto user_context = GetFakeUserContext();
+  base::ListValue params;
+  params.Append(base::Value::FromUniquePtrValue(user_context.ToValue()));
+  std::string json_value;
+  base::JSONWriter::Write(params, &json_value);
+  return json_value;
+}
+
+std::unique_ptr<KeyedService> BuildMockAggregator(
+    content::BrowserContext* context) {
+  return std::make_unique<
+      testing::StrictMock<device_signals::MockSignalsAggregator>>();
+}
+
+}  // namespace
+
+// Base test class for APIs that require a UserContext parameter and which will
+// make use of the SignalsAggregator to retrieve device signals.
+class UserContextGatedTest : public ExtensionApiUnittest {
+ protected:
+  void SetUp() override {
+    ExtensionApiUnittest::SetUp();
+
+    auto* factory = enterprise_signals::SignalsAggregatorFactory::GetInstance();
+    mock_aggregator_ = static_cast<device_signals::MockSignalsAggregator*>(
+        factory->SetTestingFactoryAndUse(
+            browser()->profile(), base::BindRepeating(&BuildMockAggregator)));
+  }
+
+  void SetFakeResponse(
+      const device_signals::SignalsAggregationResponse& response) {
+    EXPECT_CALL(*mock_aggregator_, GetSignals(_, _))
+        .WillOnce(
+            Invoke([&](const device_signals::SignalsAggregationRequest& request,
+                       device_signals::SignalsAggregator::GetSignalsCallback
+                           callback) {
+              EXPECT_EQ(request.user_context.user_id, kFakeUserId);
+              EXPECT_EQ(request.signal_names.size(), 1U);
+              std::move(callback).Run(response);
+            }));
+  }
+
+  virtual void SetFeatureFlag() {
+    scoped_features_.InitAndEnableFeature(
+        enterprise_signals::features::kNewEvSignalsEnabled);
+  }
+
+  device_signals::MockSignalsAggregator* mock_aggregator_;
+  base::test::ScopedFeatureList scoped_features_;
+};
+
+// Tests for API enterprise.reportingPrivate.getAvInfo
+class EnterpriseReportingPrivateGetAvInfoTest : public UserContextGatedTest {
+ protected:
+  void SetUp() override {
+    UserContextGatedTest::SetUp();
+
+    SetFeatureFlag();
+
+    function_ =
+        base::MakeRefCounted<EnterpriseReportingPrivateGetAvInfoFunction>();
+  }
+
+  scoped_refptr<extensions::EnterpriseReportingPrivateGetAvInfoFunction>
+      function_;
+};
+
+TEST_F(EnterpriseReportingPrivateGetAvInfoTest, Success) {
+  device_signals::AvProduct fake_av_product;
+  fake_av_product.display_name = "Fake display name";
+  fake_av_product.state = device_signals::AvProductState::kOff;
+  fake_av_product.product_id = "fake product id";
+
+  device_signals::AntiVirusSignalResponse av_response;
+  av_response.av_products.push_back(fake_av_product);
+
+  device_signals::SignalsAggregationResponse expected_response;
+  expected_response.av_signal_response = av_response;
+
+  SetFakeResponse(expected_response);
+
+  auto response = api_test_utils::RunFunctionAndReturnSingleResult(
+      function_.get(), GetFakeUserContextJsonParams(), profile());
+
+  EXPECT_EQ(function_->GetError(), kNoError);
+
+  ASSERT_TRUE(response);
+  ASSERT_TRUE(response->is_list());
+  const base::Value::List& list_value = response->GetList();
+  ASSERT_EQ(list_value.size(), av_response.av_products.size());
+
+  const base::Value& av_value = list_value.front();
+  auto parsed_av_signal =
+      enterprise_reporting_private::AntiVirusSignal::FromValue(av_value);
+  ASSERT_TRUE(parsed_av_signal);
+  EXPECT_EQ(parsed_av_signal->display_name, fake_av_product.display_name);
+  EXPECT_EQ(parsed_av_signal->state,
+            enterprise_reporting_private::ANTI_VIRUS_PRODUCT_STATE_OFF);
+  EXPECT_EQ(parsed_av_signal->product_id, fake_av_product.product_id);
+}
+
+TEST_F(EnterpriseReportingPrivateGetAvInfoTest, TopLevelError) {
+  device_signals::SignalCollectionError expected_error =
+      device_signals::SignalCollectionError::kConsentRequired;
+
+  device_signals::SignalsAggregationResponse expected_response;
+  expected_response.top_level_error = expected_error;
+  SetFakeResponse(expected_response);
+
+  auto error = api_test_utils::RunFunctionAndReturnError(
+      function_.get(), GetFakeUserContextJsonParams(), profile());
+
+  EXPECT_EQ(error, function_->GetError());
+  EXPECT_EQ(error, device_signals::ErrorToString(expected_error));
+}
+
+TEST_F(EnterpriseReportingPrivateGetAvInfoTest, CollectionError) {
+  device_signals::SignalCollectionError expected_error =
+      device_signals::SignalCollectionError::kMissingSystemService;
+
+  device_signals::AntiVirusSignalResponse av_response;
+  av_response.collection_error = expected_error;
+
+  device_signals::SignalsAggregationResponse expected_response;
+  expected_response.av_signal_response = av_response;
+  SetFakeResponse(expected_response);
+
+  auto error = api_test_utils::RunFunctionAndReturnError(
+      function_.get(), GetFakeUserContextJsonParams(), profile());
+
+  EXPECT_EQ(error, function_->GetError());
+  EXPECT_EQ(error, device_signals::ErrorToString(expected_error));
+}
+
+class EnterpriseReportingPrivateGetAvInfoDisabledTest
+    : public EnterpriseReportingPrivateGetAvInfoTest {
+ protected:
+  // Overwrite this function to disable the feature flag for tests using this
+  // specific fixture.
+  void SetFeatureFlag() override {
+    scoped_features_.InitAndEnableFeatureWithParameters(
+        enterprise_signals::features::kNewEvSignalsEnabled,
+        {{"DisableAntiVirus", "true"}});
+  }
+};
+
+TEST_F(EnterpriseReportingPrivateGetAvInfoDisabledTest, FlagDisabled_Test) {
+  auto error = api_test_utils::RunFunctionAndReturnError(
+      function_.get(), GetFakeUserContextJsonParams(), profile());
+  EXPECT_EQ(error, function_->GetError());
+  EXPECT_EQ(error, device_signals::ErrorToString(
+                       device_signals::SignalCollectionError::kUnsupported));
+}
+
+// Tests for API enterprise.reportingPrivate.getHotfixes
+class EnterpriseReportingPrivateGetHotfixesTest : public UserContextGatedTest {
+ protected:
+  void SetUp() override {
+    UserContextGatedTest::SetUp();
+
+    SetFeatureFlag();
+
+    function_ =
+        base::MakeRefCounted<EnterpriseReportingPrivateGetHotfixesFunction>();
+  }
+
+  scoped_refptr<extensions::EnterpriseReportingPrivateGetHotfixesFunction>
+      function_;
+};
+
+TEST_F(EnterpriseReportingPrivateGetHotfixesTest, Success) {
+  static constexpr char kFakeHotfixId[] = "hotfix id";
+  device_signals::HotfixSignalResponse hotfix_response;
+  hotfix_response.hotfixes.push_back({kFakeHotfixId});
+
+  device_signals::SignalsAggregationResponse expected_response;
+  expected_response.hotfix_signal_response = hotfix_response;
+
+  SetFakeResponse(expected_response);
+
+  auto response = api_test_utils::RunFunctionAndReturnSingleResult(
+      function_.get(), GetFakeUserContextJsonParams(), profile());
+
+  EXPECT_EQ(function_->GetError(), kNoError);
+
+  ASSERT_TRUE(response);
+  ASSERT_TRUE(response->is_list());
+  const base::Value::List& list_value = response->GetList();
+  ASSERT_EQ(list_value.size(), hotfix_response.hotfixes.size());
+
+  const base::Value& hotfix_value = list_value.front();
+  auto parsed_hotfix =
+      enterprise_reporting_private::HotfixSignal::FromValue(hotfix_value);
+  ASSERT_TRUE(parsed_hotfix);
+  EXPECT_EQ(parsed_hotfix->hotfix_id, kFakeHotfixId);
+}
+
+TEST_F(EnterpriseReportingPrivateGetHotfixesTest, TopLevelError) {
+  device_signals::SignalCollectionError expected_error =
+      device_signals::SignalCollectionError::kConsentRequired;
+
+  device_signals::SignalsAggregationResponse expected_response;
+  expected_response.top_level_error = expected_error;
+  SetFakeResponse(expected_response);
+
+  auto error = api_test_utils::RunFunctionAndReturnError(
+      function_.get(), GetFakeUserContextJsonParams(), profile());
+
+  EXPECT_EQ(error, function_->GetError());
+  EXPECT_EQ(error, device_signals::ErrorToString(expected_error));
+}
+
+TEST_F(EnterpriseReportingPrivateGetHotfixesTest, CollectionError) {
+  device_signals::SignalCollectionError expected_error =
+      device_signals::SignalCollectionError::kMissingSystemService;
+
+  device_signals::HotfixSignalResponse hotfix_response;
+  hotfix_response.collection_error = expected_error;
+
+  device_signals::SignalsAggregationResponse expected_response;
+  expected_response.hotfix_signal_response = hotfix_response;
+  SetFakeResponse(expected_response);
+
+  auto error = api_test_utils::RunFunctionAndReturnError(
+      function_.get(), GetFakeUserContextJsonParams(), profile());
+
+  EXPECT_EQ(error, function_->GetError());
+  EXPECT_EQ(error, device_signals::ErrorToString(expected_error));
+}
+
+class EnterpriseReportingPrivateGetHotfixesInfoDisabledTest
+    : public EnterpriseReportingPrivateGetHotfixesTest {
+ protected:
+  // Overwrite this function to disable the feature flag for tests using this
+  // specific fixture.
+  void SetFeatureFlag() override {
+    scoped_features_.InitAndEnableFeatureWithParameters(
+        enterprise_signals::features::kNewEvSignalsEnabled,
+        {{"DisableHotfix", "true"}});
+  }
+};
+
+TEST_F(EnterpriseReportingPrivateGetHotfixesInfoDisabledTest,
+       FlagDisabled_Test) {
+  auto error = api_test_utils::RunFunctionAndReturnError(
+      function_.get(), GetFakeUserContextJsonParams(), profile());
+  EXPECT_EQ(error, function_->GetError());
+  EXPECT_EQ(error, device_signals::ErrorToString(
+                       device_signals::SignalCollectionError::kUnsupported));
+}
+
+#endif  // BUILDFLAG(IS_WIN)
+
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/system_private/system_private_apitest.cc b/chrome/browser/extensions/api/system_private/system_private_apitest.cc
index ce8416d6..f7f7c1f 100644
--- a/chrome/browser/extensions/api/system_private/system_private_apitest.cc
+++ b/chrome/browser/extensions/api/system_private/system_private_apitest.cc
@@ -12,8 +12,8 @@
 #include "content/public/test/browser_test.h"
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-#include "chromeos/dbus/dbus_thread_manager.h"  // nogncheck
 #include "chromeos/dbus/update_engine/fake_update_engine_client.h"
+#include "chromeos/dbus/update_engine/update_engine_client.h"
 
 using chromeos::UpdateEngineClient;
 #endif
@@ -33,16 +33,14 @@
 
 class GetUpdateStatusApiTest : public ExtensionApiTest {
  public:
-  GetUpdateStatusApiTest() : fake_update_engine_client_(NULL) {}
+  GetUpdateStatusApiTest() = default;
 
   GetUpdateStatusApiTest(const GetUpdateStatusApiTest&) = delete;
   GetUpdateStatusApiTest& operator=(const GetUpdateStatusApiTest&) = delete;
 
   void SetUpInProcessBrowserTestFixture() override {
     ExtensionApiTest::SetUpInProcessBrowserTestFixture();
-    fake_update_engine_client_ = new chromeos::FakeUpdateEngineClient;
-    chromeos::DBusThreadManager::GetSetterForTesting()->SetUpdateEngineClient(
-        std::unique_ptr<UpdateEngineClient>(fake_update_engine_client_));
+    fake_update_engine_client_ = UpdateEngineClient::InitializeFakeForTest();
   }
 
   void TearDownInProcessBrowserTestFixture() override {
@@ -50,7 +48,7 @@
   }
 
  protected:
-  chromeos::FakeUpdateEngineClient* fake_update_engine_client_;
+  chromeos::FakeUpdateEngineClient* fake_update_engine_client_ = nullptr;
 };
 
 IN_PROC_BROWSER_TEST_F(GetUpdateStatusApiTest, Progress) {
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedSwipeRefreshLayout.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedSwipeRefreshLayout.java
index a5e1e2db..29c6b8b 100644
--- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedSwipeRefreshLayout.java
+++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedSwipeRefreshLayout.java
@@ -258,7 +258,8 @@
                 final float yDiff = y - mLastMotionY;
                 if (yDiff > mTouchSlop && !mIsBeingDragged) {
                     mIsBeingDragged = true;
-                    start();
+                    // TODO(1335416): Update this to |true| if experiment is successful
+                    start(false);
                 }
                 break;
             }
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index 9806c09..46f1046 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -1432,7 +1432,7 @@
   {
     "name": "edit-context",
     "owners": [ "shihken@microsoft.com", "snianu@microsoft.com", "yosin" ],
-    "expiry_milestone": 104
+    "expiry_milestone": 110
   },
   {
     "name": "elastic-overscroll",
@@ -5528,6 +5528,11 @@
     "expiry_milestone": 105
   },
   {
+    "name": "shimless-rma-disable-dark-mode",
+    "owners": [ "zentaro", "gavinwill", "cros-peripherals@google.com" ],
+    "expiry_milestone": 116
+  },
+  {
     "name": "shimless-rma-enable-standalone",
     "owners": [ "zentaro", "gavinwill", "cros-peripherals@google.com" ],
     "expiry_milestone": 108
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index d4b714a5..1087083f 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -5400,6 +5400,11 @@
 const char kShimlessRMAOsUpdateDescription[] =
     "Turns on OS updating in Shimless RMA";
 
+const char kShimlessRMADisableDarkModeName[] =
+    "Disable dark mode in Shimless RMA";
+const char kShimlessRMADisableDarkModeDescription[] =
+    "Disable dark mode and only allow light mode in Shimless RMA";
+
 const char kSchedulerConfigurationName[] = "Scheduler Configuration";
 const char kSchedulerConfigurationDescription[] =
     "Instructs the OS to use a specific scheduler configuration setting.";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 0eab04c..6a33cd7 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -3094,6 +3094,9 @@
 extern const char kShimlessRMAOsUpdateName[];
 extern const char kShimlessRMAOsUpdateDescription[];
 
+extern const char kShimlessRMADisableDarkModeName[];
+extern const char kShimlessRMADisableDarkModeDescription[];
+
 extern const char kSchedulerConfigurationName[];
 extern const char kSchedulerConfigurationDescription[];
 extern const char kSchedulerConfigurationConservative[];
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc
index d078026dc..4570fde 100644
--- a/chrome/browser/flags/android/chrome_feature_list.cc
+++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -250,6 +250,7 @@
     &kBookmarksImprovedSaveFlow,
     &kBookmarksRefresh,
     &kBackGestureRefactorAndroid,
+    &kOptimizeLayoutsForPullRefresh,
     &kPostTaskFocusTab,
     &kProbabilisticCryptidRenderer,
     &kReachedCodeProfiler,
@@ -714,6 +715,9 @@
 const base::Feature kBackGestureRefactorAndroid{
     "BackGestureRefactorAndroid", base::FEATURE_DISABLED_BY_DEFAULT};
 
+const base::Feature kOptimizeLayoutsForPullRefresh{
+    "OptimizeLayoutsForPullRefresh", base::FEATURE_DISABLED_BY_DEFAULT};
+
 const base::Feature kPostTaskFocusTab{"PostTaskFocusTab",
                                       base::FEATURE_DISABLED_BY_DEFAULT};
 
diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser/flags/android/chrome_feature_list.h
index 53d9d25..33221554 100644
--- a/chrome/browser/flags/android/chrome_feature_list.h
+++ b/chrome/browser/flags/android/chrome_feature_list.h
@@ -114,6 +114,7 @@
 extern const base::Feature kBookmarksImprovedSaveFlow;
 extern const base::Feature kBookmarksRefresh;
 extern const base::Feature kBackGestureRefactorAndroid;
+extern const base::Feature kOptimizeLayoutsForPullRefresh;
 extern const base::Feature kPostTaskFocusTab;
 extern const base::Feature kProbabilisticCryptidRenderer;
 extern const base::Feature kReachedCodeProfiler;
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
index 9e7aee65..8531f10b 100644
--- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
+++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -430,6 +430,7 @@
             "OmniboxUpdatedConnectionSecurityIndicators";
     public static final String OPTIMIZATION_GUIDE_PUSH_NOTIFICATIONS =
             "OptimizationGuidePushNotifications";
+    public static final String OPTIMIZE_LAYOUTS_FOR_PULL_REFRESH = "OptimizeLayoutsForPullRefresh";
     public static final String OVERLAY_NEW_LAYOUT = "OverlayNewLayout";
     public static final String PAGE_ANNOTATIONS_SERVICE = "PageAnnotationsService";
     public static final String PAGE_INFO_ABOUT_THIS_SITE_EN = "PageInfoAboutThisSiteEn";
diff --git a/chrome/browser/fuchsia/element_manager_impl.cc b/chrome/browser/fuchsia/element_manager_impl.cc
index a809e6bb..646b525 100644
--- a/chrome/browser/fuchsia/element_manager_impl.cc
+++ b/chrome/browser/fuchsia/element_manager_impl.cc
@@ -8,6 +8,7 @@
 #include "base/command_line.h"
 #include "base/files/file_path.h"
 #include "base/logging.h"
+#include "base/strings/string_util.h"
 #include "chrome/browser/chrome_browser_main.h"
 #include "chrome/browser/ui/browser_list.h"
 
@@ -48,8 +49,8 @@
     fuchsia::element::Spec spec,
     fidl::InterfaceRequest<fuchsia::element::Controller> element_controller,
     ProposeElementCallback callback) {
-  if (spec.component_url() !=
-      "fuchsia-pkg://fuchsia.com/chrome#meta/chrome.cm") {
+  if (!spec.has_component_url() ||
+      !base::EndsWith(spec.component_url(), "/chrome#meta/chrome.cm")) {
     callback(fuchsia::element::Manager_ProposeElement_Result::WithErr(
         fuchsia::element::ProposeElementError::INVALID_ARGS));
     return;
diff --git a/chrome/browser/fuchsia/element_manager_impl_unittest.cc b/chrome/browser/fuchsia/element_manager_impl_unittest.cc
index 8ee4ead..73ccb20f 100644
--- a/chrome/browser/fuchsia/element_manager_impl_unittest.cc
+++ b/chrome/browser/fuchsia/element_manager_impl_unittest.cc
@@ -97,43 +97,59 @@
 };
 
 TEST_F(TestElementManagerImpl, TestCorrectSpec) {
-  fuchsia::element::Spec spec;
-  spec.set_component_url("fuchsia-pkg://fuchsia.com/chrome#meta/chrome.cm");
-
   auto element_manager = GetElementManagerPtr();
-  base::RunLoop run_loop;
-  absl::optional<fuchsia::element::Manager_ProposeElement_Result>
-      received_result;
-  element_manager->ProposeElement(
-      std::move(spec), {},
-      [&](fuchsia::element::Manager_ProposeElement_Result result) {
-        received_result = std::move(result);
-        run_loop.Quit();
-      });
-  run_loop.Run();
-  ASSERT_TRUE(received_result);
-  EXPECT_FALSE(received_result->is_err());
-  EXPECT_TRUE(received_command_line_);
+  for (const char* url : {
+           "fuchsia-pkg://fuchsia.com/chrome#meta/chrome.cm",
+           "fuchsia-pkg://chromium.org/chrome#meta/chrome.cm",
+           "fuchsia-pkg://chrome.com/chrome#meta/chrome.cm",
+       }) {
+    fuchsia::element::Spec spec;
+    spec.set_component_url(url);
+
+    base::RunLoop run_loop;
+    absl::optional<fuchsia::element::Manager_ProposeElement_Result>
+        received_result;
+    element_manager->ProposeElement(
+        std::move(spec), {},
+        [&](fuchsia::element::Manager_ProposeElement_Result result) {
+          received_result = std::move(result);
+          run_loop.Quit();
+        });
+    run_loop.Run();
+    ASSERT_TRUE(received_result);
+    EXPECT_FALSE(received_result->is_err()) << url;
+    EXPECT_TRUE(received_command_line_);
+  }
 }
 
 TEST_F(TestElementManagerImpl, TestIncorrectSpec) {
-  fuchsia::element::Spec spec;
-  spec.set_component_url("foobar");
-
   auto element_manager = GetElementManagerPtr();
-  base::RunLoop run_loop;
-  absl::optional<fuchsia::element::Manager_ProposeElement_Result>
-      received_result;
-  element_manager->ProposeElement(
-      std::move(spec), {},
-      [&](fuchsia::element::Manager_ProposeElement_Result result) {
-        received_result = std::move(result);
-        run_loop.Quit();
-      });
-  run_loop.Run();
-  ASSERT_TRUE(received_result);
-  EXPECT_TRUE(received_result->is_err());
-  EXPECT_FALSE(received_command_line_);
+  for (const char* url : {
+           "foobar",
+           "fuchsia-pkg://chromium.org/web_engine#meta/chrome.cm",
+           "fuchsia-pkg://chromium.org/chrome#meta/web_engine.cm",
+           "fuchsia-pkg://chromium.org/chrome",
+           "fuchsia-pkg://chromium.org/#meta/chrome.cm",
+           "fuchsia-pkg://chromium.org/mychrome#meta/chrome.cm",
+           "chrome#meta/chrome.cm",
+       }) {
+    fuchsia::element::Spec spec;
+    spec.set_component_url(url);
+
+    base::RunLoop run_loop;
+    absl::optional<fuchsia::element::Manager_ProposeElement_Result>
+        received_result;
+    element_manager->ProposeElement(
+        std::move(spec), {},
+        [&](fuchsia::element::Manager_ProposeElement_Result result) {
+          received_result = std::move(result);
+          run_loop.Quit();
+        });
+    run_loop.Run();
+    ASSERT_TRUE(received_result);
+    EXPECT_TRUE(received_result->is_err()) << url;
+    EXPECT_FALSE(received_command_line_);
+  }
 }
 
 TEST_F(TestElementManagerImpl, TestController) {
@@ -142,7 +158,7 @@
   fuchsia::element::ControllerPtr controller;
   fuchsia::element::Spec valid_spec;
   valid_spec.set_component_url(
-      "fuchsia-pkg://fuchsia.com/chrome#meta/chrome.cm");
+      "fuchsia-pkg://chromium.org/chrome#meta/chrome.cm");
 
   element_manager->ProposeElement(
       std::move(valid_spec), controller.NewRequest(),
@@ -172,7 +188,7 @@
     base::RunLoop run_loop;
     fuchsia::element::Spec valid_spec;
     valid_spec.set_component_url(
-        "fuchsia-pkg://fuchsia.com/chrome#meta/chrome.cm");
+        "fuchsia-pkg://chromium.org/chrome#meta/chrome.cm");
     *valid_spec.mutable_annotations() = TestAnnotations(
         {{"key1", "value1"}, {"key2", "value2"}, {"key3", "value3"}});
     element_manager->ProposeElement(std::move(valid_spec),
@@ -236,7 +252,7 @@
   fuchsia::element::ControllerPtr controller;
   fuchsia::element::Spec valid_spec;
   valid_spec.set_component_url(
-      "fuchsia-pkg://fuchsia.com/chrome#meta/chrome.cm");
+      "fuchsia-pkg://chromium.org/chrome#meta/chrome.cm");
 
   element_manager->ProposeElement(
       std::move(valid_spec), controller.NewRequest(),
@@ -262,7 +278,7 @@
 
   // A new connection to the manager should allow a new controller to be bounded
   valid_spec.set_component_url(
-      "fuchsia-pkg://fuchsia.com/chrome#meta/chrome.cm");
+      "fuchsia-pkg://chromium.org/chrome#meta/chrome.cm");
 
   element_manager->ProposeElement(
       std::move(valid_spec), controller.NewRequest(),
diff --git a/chrome/browser/incognito/BUILD.gn b/chrome/browser/incognito/BUILD.gn
index 6662eea..95fec97 100644
--- a/chrome/browser/incognito/BUILD.gn
+++ b/chrome/browser/incognito/BUILD.gn
@@ -86,11 +86,11 @@
     "//base:base_java_test_support",
     "//chrome/android:chrome_java",
     "//chrome/browser/flags:java",
-    "//chrome/browser/settings:javatests",
     "//chrome/browser/settings:test_support_java",
     "//chrome/browser/tabmodel:java",
     "//chrome/test/android:chrome_java_integration_test_support",
     "//components/browser_ui/settings/android:java",
+    "//components/browser_ui/settings/android:test_support_java",
     "//components/browser_ui/widget/android:java",
     "//content/public/test/android:content_java_test_support",
     "//third_party/android_deps:espresso_java",
diff --git a/chrome/browser/incognito/android/javatests/src/org/chromium/chrome/browser/incognito/reauth/IncognitoReauthSettingSwitchPreferenceTest.java b/chrome/browser/incognito/android/javatests/src/org/chromium/chrome/browser/incognito/reauth/IncognitoReauthSettingSwitchPreferenceTest.java
index 6d23ae66..973be6e 100644
--- a/chrome/browser/incognito/android/javatests/src/org/chromium/chrome/browser/incognito/reauth/IncognitoReauthSettingSwitchPreferenceTest.java
+++ b/chrome/browser/incognito/android/javatests/src/org/chromium/chrome/browser/incognito/reauth/IncognitoReauthSettingSwitchPreferenceTest.java
@@ -25,9 +25,9 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
-import org.chromium.chrome.browser.settings.PlaceholderSettingsForTest;
 import org.chromium.chrome.browser.settings.SettingsActivityTestRule;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
+import org.chromium.components.browser_ui.settings.PlaceholderSettingsForTest;
 
 /**
  * Tests of {@link IncognitoReauthSettingSwitchPreference}.
diff --git a/chrome/browser/lifetime/application_lifetime_chromeos_browsertest.cc b/chrome/browser/lifetime/application_lifetime_chromeos_browsertest.cc
index f29dc7a..5c7daac 100644
--- a/chrome/browser/lifetime/application_lifetime_chromeos_browsertest.cc
+++ b/chrome/browser/lifetime/application_lifetime_chromeos_browsertest.cc
@@ -11,10 +11,10 @@
 #include "chrome/browser/ui/browser_list_observer.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/in_process_browser_test.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/power/fake_power_manager_client.h"
 #include "chromeos/dbus/session_manager/fake_session_manager_client.h"
 #include "chromeos/dbus/update_engine/fake_update_engine_client.h"
+#include "chromeos/dbus/update_engine/update_engine_client.h"
 #include "components/keep_alive_registry/keep_alive_registry.h"
 #include "components/prefs/pref_service.h"
 #include "content/public/test/browser_test.h"
@@ -27,11 +27,14 @@
 class ApplicationLifetimeTest : public InProcessBrowserTest,
                                 public BrowserListObserver {
  public:
+  void SetUpInProcessBrowserTestFixture() override {
+    InProcessBrowserTest::SetUpInProcessBrowserTestFixture();
+    fake_update_engine_client_ =
+        chromeos::UpdateEngineClient::InitializeFakeForTest();
+  }
+
   void SetUpOnMainThread() override {
     InProcessBrowserTest::SetUpOnMainThread();
-    fake_update_engine_client_ = new chromeos::FakeUpdateEngineClient;
-    chromeos::DBusThreadManager::GetSetterForTesting()->SetUpdateEngineClient(
-        std::unique_ptr<ash::UpdateEngineClient>(fake_update_engine_client_));
     BrowserList::AddObserver(this);
   }
 
diff --git a/chrome/browser/media/webrtc/region_capture_browsertest.cc b/chrome/browser/media/webrtc/region_capture_browsertest.cc
index 70b12bfc..9deb416 100644
--- a/chrome/browser/media/webrtc/region_capture_browsertest.cc
+++ b/chrome/browser/media/webrtc/region_capture_browsertest.cc
@@ -620,9 +620,16 @@
       CropTo(kCropTarget0, Frame::kTopLevelDocument, Track::kOriginal));
 }
 
+// TODO(crbug.com/1336974): Re-enable this test.
+#if BUILDFLAG(IS_LINUX)
+#define MAYBE_CannotRecropTrackThatHasClone \
+  DISABLED_CannotRecropTrackThatHasClone
+#else
+#define MAYBE_CannotRecropTrackThatHasClone CannotRecropTrackThatHasClone
+#endif  //  BUILDFLAG(IS_LINUX)
 // Restrictions on original track that has a clone 2/3.
 IN_PROC_BROWSER_TEST_F(RegionCaptureClonesBrowserTest,
-                       CannotRecropTrackThatHasClone) {
+                       MAYBE_CannotRecropTrackThatHasClone) {
   ManualSetUp();
 
   ASSERT_TRUE(CropTo(kCropTarget0, Frame::kTopLevelDocument, Track::kOriginal));
@@ -769,8 +776,9 @@
   EXPECT_TRUE(StartSecondCapture());
 }
 
+// TODO(crbug.com/1336503): Re-enable this test
 IN_PROC_BROWSER_TEST_P(RegionCaptureMultiCaptureBrowserTest,
-                       CannotSelfCaptureAgainIfCropped) {
+                       DISABLED_CannotSelfCaptureAgainIfCropped) {
   ManualSetUp();
 
   ASSERT_TRUE(CropTo(kCropTarget1, Frame::kTopLevelDocument, Track::kOriginal));
diff --git a/chrome/browser/metrics/usage_scenario/tab_usage_scenario_tracker.cc b/chrome/browser/metrics/usage_scenario/tab_usage_scenario_tracker.cc
index f573aaec..8737530 100644
--- a/chrome/browser/metrics/usage_scenario/tab_usage_scenario_tracker.cc
+++ b/chrome/browser/metrics/usage_scenario/tab_usage_scenario_tracker.cc
@@ -131,19 +131,24 @@
     bool is_fullscreen) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
+  const int num_displays = GetNumDisplays();
+
   if (is_fullscreen) {
     auto [it, inserted] =
         contents_playing_video_fullscreen_.insert(web_contents);
     if (inserted && contents_playing_video_fullscreen_.size() == 1U &&
-        GetNumDisplays() == 1)
+        num_displays == 1) {
       usage_scenario_data_store_->OnFullScreenVideoStartsOnSingleMonitor();
+    }
   } else {
     auto num_removed = contents_playing_video_fullscreen_.erase(web_contents);
     if (num_removed == 1U && contents_playing_video_fullscreen_.empty() &&
-        GetNumDisplays() == 1) {
+        num_displays == 1) {
       usage_scenario_data_store_->OnFullScreenVideoEndsOnSingleMonitor();
     }
   }
+
+  last_num_displays_ = num_displays;
 }
 
 void TabUsageScenarioTracker::OnMediaDestroyed(
@@ -201,28 +206,12 @@
 
 void TabUsageScenarioTracker::OnDisplayAdded(const display::Display&) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-  if (!contents_playing_video_fullscreen_.empty()) {
-    const size_t num_displays = GetNumDisplays();
-
-    if (num_displays == 1)
-      usage_scenario_data_store_->OnFullScreenVideoStartsOnSingleMonitor();
-    else if (num_displays == 2)
-      usage_scenario_data_store_->OnFullScreenVideoEndsOnSingleMonitor();
-  }
+  OnNumDisplaysChanged();
 }
 
-void TabUsageScenarioTracker::OnDisplayRemoved(const display::Display&) {
+void TabUsageScenarioTracker::OnDidRemoveDisplays() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-  if (!contents_playing_video_fullscreen_.empty()) {
-    const size_t num_displays = GetNumDisplays();
-
-    if (num_displays == 1)
-      usage_scenario_data_store_->OnFullScreenVideoStartsOnSingleMonitor();
-    else if (num_displays == 0)
-      usage_scenario_data_store_->OnFullScreenVideoEndsOnSingleMonitor();
-  }
+  OnNumDisplaysChanged();
 }
 
 void TabUsageScenarioTracker::OnTabBecameHidden(
@@ -289,4 +278,32 @@
   }
 }
 
+void TabUsageScenarioTracker::OnNumDisplaysChanged() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  if (contents_playing_video_fullscreen_.empty())
+    return;
+
+  // Multiple displays can be added or removed before OnDisplayAdded and
+  // OnDidRemoveDisplays are dispatched. It is therefore impossible to make any
+  // assumption about the new number of displays when this is invoked.
+
+  // `last_num_displays_` is set when `contents_playing_video_fullscreen_`
+  // becomes non-empty.
+  //
+  // TODO(crbug.com/1273251): Change CHECK to DCHECK in September 2022 after
+  // confirming that there are no crash reports.
+  CHECK(last_num_displays_.has_value());
+
+  const int num_displays = GetNumDisplays();
+
+  if (num_displays == 1 && last_num_displays_ != 1) {
+    usage_scenario_data_store_->OnFullScreenVideoStartsOnSingleMonitor();
+  } else if (num_displays != 1 && last_num_displays_ == 1) {
+    usage_scenario_data_store_->OnFullScreenVideoEndsOnSingleMonitor();
+  }
+
+  last_num_displays_ = num_displays;
+}
+
 }  // namespace metrics
diff --git a/chrome/browser/metrics/usage_scenario/tab_usage_scenario_tracker.h b/chrome/browser/metrics/usage_scenario/tab_usage_scenario_tracker.h
index a235484..722d72b4 100644
--- a/chrome/browser/metrics/usage_scenario/tab_usage_scenario_tracker.h
+++ b/chrome/browser/metrics/usage_scenario/tab_usage_scenario_tracker.h
@@ -11,6 +11,7 @@
 #include "chrome/browser/metrics/usage_scenario/usage_scenario_data_store.h"
 #include "content/public/browser/visibility.h"
 #include "services/metrics/public/cpp/ukm_source_id.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/display/display_observer.h"
 #include "url/origin.h"
 
@@ -52,7 +53,10 @@
 
   // display::DisplayObserver:
   void OnDisplayAdded(const display::Display& new_display) override;
-  void OnDisplayRemoved(const display::Display& new_display) override;
+  // Note: It would be incorrect to override OnDisplayRemoved() instead of
+  // OnDidRemoveDisplays() because the former may be invoked *before* the number
+  // of displays is updated.
+  void OnDidRemoveDisplays() override;
 
  private:
   using VisibleTabsMap = base::flat_map<content::WebContents*,
@@ -70,6 +74,9 @@
 
   void InsertContentsInMapOfVisibleTabs(content::WebContents* web_contents);
 
+  // Invoked when displays are added or removed.
+  void OnNumDisplaysChanged();
+
   // Non-owning. Needs to outlive this class.
   raw_ptr<UsageScenarioDataStoreImpl> usage_scenario_data_store_
       GUARDED_BY_CONTEXT(sequence_checker_);
@@ -78,6 +85,9 @@
   base::flat_set<content::WebContents*> contents_playing_video_
       GUARDED_BY_CONTEXT(sequence_checker_);
 
+  // The last reading of the number of displays.
+  absl::optional<int> last_num_displays_;
+
   // Keep track of the visible WebContents and the navigation data associated to
   // them. The associated sourceID for tabs that don't have committed a main
   // frame navigation is ukm::kInvalidSourceID and the origin is empty.
diff --git a/chrome/browser/net/OWNERS b/chrome/browser/net/OWNERS
index a5c1a4be..a6910a5 100644
--- a/chrome/browser/net/OWNERS
+++ b/chrome/browser/net/OWNERS
@@ -1,4 +1,5 @@
 file://net/OWNERS
 
+per-file android_network_service_browsertest.cc=wfh@chromium.org
 per-file network_quality*=file://net/nqe/OWNERS
 per-file private_network_access_browsertest*=titouan@chromium.org
diff --git a/chrome/browser/net/android_network_service_browsertest.cc b/chrome/browser/net/android_network_service_browsertest.cc
new file mode 100644
index 0000000..aae6a831
--- /dev/null
+++ b/chrome/browser/net/android_network_service_browsertest.cc
@@ -0,0 +1,149 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/bind.h"
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/metrics/statistics_recorder.h"
+#include "base/test/metrics/histogram_tester.h"
+#include "base/threading/scoped_blocking_call.h"
+#include "chrome/common/chrome_constants.h"
+#include "chrome/common/chrome_paths.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/test/base/android/android_browser_test.h"
+#include "chrome/test/base/chrome_test_utils.h"
+#include "content/public/test/browser_test.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+
+namespace {
+
+class AndroidChromeNetworkContextCleanupBrowserTest
+    : public AndroidBrowserTest {
+ public:
+  AndroidChromeNetworkContextCleanupBrowserTest() = default;
+  ~AndroidChromeNetworkContextCleanupBrowserTest() override = default;
+
+  void SetUpOnMainThread() override {
+    ASSERT_TRUE(embedded_test_server()->Start());
+
+    PlatformBrowserTest::SetUpOnMainThread();
+  }
+
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    // Create a new directory that serves as a user data dir. Enlist it as a
+    // command line option. This way the SetUp() does not override it.
+    ASSERT_TRUE(user_data_dir_.CreateUniqueTempDir());
+    ASSERT_TRUE(base::IsDirectoryEmpty(user_data_dir()));
+    command_line->AppendSwitchPath(switches::kUserDataDir, user_data_dir());
+
+    // Create directories with the default profile and the network context data
+    // corresponding to `NetworkContextFilePaths.data_directory`. The test will
+    // check that the network service initialization deletes this directory.
+    base::FilePath profile_dir =
+        user_data_dir().AppendASCII(chrome::kInitialProfile);
+    base::FilePath data_directory =
+        profile_dir.AppendASCII(chrome::kNetworkDataDirname);
+    ASSERT_TRUE(base::CreateDirectory(data_directory));
+
+    // Create a temporary file in the profile directory that should _not_ be
+    // removed.
+    ASSERT_TRUE(base::CreateTemporaryFileInDir(profile_dir, &profile_file_));
+    ASSERT_TRUE(base::PathExists(profile_file_));
+
+    // Create a temporary file in the `data_directory` to check that it is
+    // deleted recursively.
+    ASSERT_TRUE(
+        base::CreateTemporaryFileInDir(data_directory, &network_context_file_));
+    ASSERT_TRUE(base::PathExists(network_context_file_));
+  }
+
+ protected:
+  const base::FilePath& user_data_dir() const {
+    return user_data_dir_.GetPath();
+  }
+
+  content::WebContents* GetActiveWebContents() {
+    return chrome_test_utils::GetActiveWebContents(this);
+  }
+
+  // A file in the stale network context directory. Should be wiped by
+  // initialization.
+  base::FilePath network_context_file_;
+
+  // A file in the profile directory that should remain present after
+  // initialization of the network service.
+  base::FilePath profile_file_;
+
+  // The histogram tester snapshots the state at construction time to avoid race
+  // conditions. The network context initialization (being tested) starts
+  // running during AndroidBrowserTest::SetUp().
+  base::HistogramTester histogram_tester_;
+
+ private:
+  base::ScopedTempDir user_data_dir_;
+};
+
+constexpr char kClearHistogramName[] =
+    "NetworkService.ClearStaleDataDirectoryResult";
+
+bool HasSample(const base::HistogramTester& histogram_tester,
+               base::HistogramBase::Sample sample) {
+  if (histogram_tester.GetBucketCount(kClearHistogramName, sample) > 0)
+    return true;
+  return false;
+}
+
+void QuitLoopIfHasSample(const base::HistogramTester& histogram_tester,
+                         base::HistogramBase::Sample expected_sample,
+                         base::RunLoop& run_loop,
+                         const char* histogram_name_ignored,
+                         uint64_t name_hash_ignored,
+                         base::HistogramBase::Sample arrived_sample_ignored) {
+  if (HasSample(histogram_tester, expected_sample))
+    run_loop.Quit();
+}
+
+void WaitForSample(const base::HistogramTester& histogram_tester,
+                   base::HistogramBase::Sample sample) {
+  if (HasSample(histogram_tester, sample))
+    return;
+
+  base::RunLoop run_loop;
+  base::StatisticsRecorder::ScopedHistogramSampleObserver observer(
+      kClearHistogramName,
+      base::BindRepeating(&QuitLoopIfHasSample, std::ref(histogram_tester),
+                          sample, std::ref(run_loop)));
+
+  run_loop.Run();
+}
+
+}  // namespace
+
+// Check that the network service context initialization code deleted the stale
+// storage directory.
+IN_PROC_BROWSER_TEST_F(AndroidChromeNetworkContextCleanupBrowserTest,
+                       TestStaleCookiesDeleted) {
+  // Navigate.
+  ASSERT_TRUE(content::NavigateToURL(
+      GetActiveWebContents(),
+      embedded_test_server()->GetURL("/android/google.html")));
+
+  // Enable blocking calls to inspect files on disk.
+  base::ScopedAllowBlockingForTesting allow_blocking;
+
+  // Wait for the histogram to record successful deletion of the directory.
+  // The Safebrowsing context cleanup could not succeed because the stale
+  // directory was not created for it. Hence after the waiting is done here the
+  // state of the files inside and outside of the stale directory must be
+  // deterministic.
+  // DeleteResult::kDeleted == 1.
+  WaitForSample(histogram_tester_, base::HistogramBase::Sample(1));
+
+  // Expect no delete errors. DeleteResult::kDeleteError == 2.
+  histogram_tester_.ExpectBucketCount(kClearHistogramName,
+                                      base::HistogramBase::Sample(2), 0);
+
+  EXPECT_FALSE(base::PathExists(network_context_file_));
+  EXPECT_TRUE(base::PathExists(profile_file_));
+}
diff --git a/chrome/browser/page_load_metrics/integration_tests/layout_instability_browsertest.cc b/chrome/browser/page_load_metrics/integration_tests/layout_instability_browsertest.cc
index 76fba0d..f4e35b8 100644
--- a/chrome/browser/page_load_metrics/integration_tests/layout_instability_browsertest.cc
+++ b/chrome/browser/page_load_metrics/integration_tests/layout_instability_browsertest.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/page_load_metrics/integration_tests/metric_integration_test.h"
 
 #include "base/test/trace_event_analyzer.h"
+#include "build/build_config.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/page_load_metrics/browser/page_load_metrics_util.h"
 #include "content/public/test/browser_test.h"
@@ -114,7 +115,13 @@
   }
 }
 
-IN_PROC_BROWSER_TEST_F(LayoutInstabilityTest, SimpleBlockMovement) {
+// TODO(crbug.com/1336973): Re-enable this test.
+#if BUILDFLAG(IS_LINUX)
+#define MAYBE_SimpleBlockMovement DISABLED_SimpleBlockMovement
+#else
+#define MAYBE_SimpleBlockMovement SimpleBlockMovement
+#endif  //  BUILDFLAG(IS_LINUX)
+IN_PROC_BROWSER_TEST_F(LayoutInstabilityTest, MAYBE_SimpleBlockMovement) {
   RunWPT("simple-block-movement.html");
 }
 
diff --git a/chrome/browser/password_manager/password_manager_captured_sites_interactive_uitest.cc b/chrome/browser/password_manager/password_manager_captured_sites_interactive_uitest.cc
index 7a0d3d4..6f77dcb 100644
--- a/chrome/browser/password_manager/password_manager_captured_sites_interactive_uitest.cc
+++ b/chrome/browser/password_manager/password_manager_captured_sites_interactive_uitest.cc
@@ -214,9 +214,10 @@
   }
 
   void SetUpCommandLine(base::CommandLine* command_line) override {
-    feature_list_.InitWithFeatures(
-        /*enabled_features=*/{autofill::features::kAutofillShowTypePredictions,
-                              features::kUsernameFirstFlow},
+    feature_list_.InitWithFeaturesAndParameters(
+        /*enabled_features=*/{{autofill::features::kAutofillShowTypePredictions,
+                               {}},
+                              {features::kUsernameFirstFlow, {}}},
         {});
     command_line->AppendSwitch(autofill::switches::kShowAutofillSignatures);
     captured_sites_test_utils::TestRecipeReplayer::SetUpHostResolverRules(
diff --git a/chrome/browser/settings/BUILD.gn b/chrome/browser/settings/BUILD.gn
index 5956efc2..1ec6282 100644
--- a/chrome/browser/settings/BUILD.gn
+++ b/chrome/browser/settings/BUILD.gn
@@ -22,36 +22,6 @@
   ]
 }
 
-android_library("javatests") {
-  testonly = true
-
-  sources = [
-    "android/java/src/org/chromium/chrome/browser/settings/ChromeBasePreferenceTest.java",
-    "android/java/src/org/chromium/chrome/browser/settings/ChromeImageViewPreferenceTest.java",
-    "android/java/src/org/chromium/chrome/browser/settings/ManagedPreferencesUtilsTest.java",
-    "android/java/src/org/chromium/chrome/browser/settings/PlaceholderSettingsForTest.java",
-  ]
-
-  deps = [
-    ":java",
-    ":test_support_java",
-    "//base:base_java_test_support",
-    "//chrome/android:chrome_java",
-    "//chrome/test/android:chrome_java_integration_test_support",
-    "//components/browser_ui/settings/android:java",
-    "//content/public/test/android:content_java_test_support",
-    "//third_party/android_deps:espresso_java",
-    "//third_party/android_deps:guava_android_java",
-    "//third_party/android_support_test_runner:rules_java",
-    "//third_party/android_support_test_runner:runner_java",
-    "//third_party/androidx:androidx_preference_preference_java",
-    "//third_party/androidx:androidx_test_runner_java",
-    "//third_party/hamcrest:hamcrest_java",
-    "//third_party/junit",
-    "//ui/android:ui_java_test_support",
-  ]
-}
-
 android_library("test_support_java") {
   testonly = true
 
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 33bc72f..3366bab7 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/i18n/message_formatter.h"
+#include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
@@ -39,6 +40,7 @@
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/receiver.h"
 #include "mojo/public/cpp/bindings/remote.h"
+#include "third_party/blink/public/common/features.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/text/bytes_formatting.h"
 #include "ui/events/event_constants.h"
@@ -353,8 +355,13 @@
 
 void AppManagementPageHandler::SetFileHandlingEnabled(const std::string& app_id,
                                                       bool enabled) {
-  web_app::PersistFileHandlersUserChoice(profile_, app_id, enabled,
-                                         base::DoNothing());
+  auto mojom_permission = apps::mojom::Permission::New();
+  mojom_permission->permission_type =
+      apps::mojom::PermissionType::kFileHandling;
+  mojom_permission->value = apps::mojom::PermissionValue::NewBoolValue(enabled);
+  mojom_permission->is_managed = false;
+  apps::AppServiceProxyFactory::GetForProfile(profile_)->SetPermission(
+      app_id, std::move(mojom_permission));
 }
 
 void AppManagementPageHandler::ShowDefaultAppAssociationsUi() {
@@ -441,55 +448,87 @@
         std::move(run_on_os_login.value()));
   }
 
-  if (update.AppType() == apps::AppType::kWeb) {
+  if (update.AppType() == apps::AppType::kWeb ||
+      update.AppType() == apps::AppType::kSystemWeb) {
     std::string file_handling_types;
     std::string file_handling_types_label;
     bool fh_enabled = false;
-// Speculative fix for crbug.com/1315958
-#if !BUILDFLAG(IS_CHROMEOS)
-    auto* provider =
-        web_app::WebAppProvider::GetForLocalAppsUnchecked(profile_);
-    fh_enabled =
-        !provider->registrar().IsAppFileHandlerPermissionBlocked(app->id);
-    if (provider->os_integration_manager().IsFileHandlingAPIAvailable(
-            app->id) &&
-        !provider->registrar().IsSystemApp(app->id) &&
-        !provider->registrar().GetAppFileHandlers(app->id)->empty()) {
-      auto [file_handling_types16, count] =
-          web_app::GetFileTypeAssociationsHandledByWebAppForDisplay(profile_,
-                                                                    app->id);
-      file_handling_types = base::UTF16ToUTF8(file_handling_types16);
+    const bool is_system_web_app =
+        update.InstallReason() == apps::InstallReason::kSystem;
+    if (!is_system_web_app &&
+        base::FeatureList::IsEnabled(blink::features::kFileHandlingAPI)) {
+      apps::IntentFilters filters = update.IntentFilters();
+      if (!filters.empty()) {
+        std::set<std::string> file_extensions;
+        // Mime types are ignored.
+        std::set<std::string> mime_types;
+        for (auto& filter : filters) {
+          bool is_potential_file_handler_action = base::ranges::any_of(
+              filter->conditions.begin(), filter->conditions.end(),
+              [](const std::unique_ptr<apps::Condition>& condition) {
+                if (condition->condition_type != apps::ConditionType::kAction)
+                  return false;
 
-      const std::vector<std::string> all_extensions =
-          web_app::GetFileTypeAssociationsHandledByWebAppForDisplayAsList(
-              profile_, app->id);
-      std::vector<std::string> truncated_extensions = all_extensions;
-      // Only show at most 4 extensions.
-      truncated_extensions.resize(4);
-      file_handling_types_label =
-          base::UTF16ToUTF8(base::i18n::MessageFormatter::FormatWithNamedArgs(
-              l10n_util::GetStringUTF16(IDS_APP_MANAGEMENT_FILE_HANDLING_TYPES),
-              "FILE_TYPE_COUNT", static_cast<int>(all_extensions.size()),
-              "FILE_TYPE1", truncated_extensions[0], "FILE_TYPE2",
-              truncated_extensions[1], "FILE_TYPE3", truncated_extensions[2],
-              "FILE_TYPE4", truncated_extensions[3], "OVERFLOW_COUNT",
-              static_cast<int>(all_extensions.size()) -
-                  static_cast<int>(truncated_extensions.size()),
-              "LINK", "#"));
+                if (condition->condition_values.size() != 1U)
+                  return false;
+
+                return condition->condition_values[0]->value ==
+                       apps_util::kIntentActionPotentialFileHandler;
+              });
+          if (is_potential_file_handler_action) {
+            filter->GetMimeTypesAndExtensions(mime_types, file_extensions);
+            break;
+          }
+        }
+
+        for (const auto& permission : update.Permissions()) {
+          if (permission->permission_type ==
+              apps::PermissionType::kFileHandling) {
+            fh_enabled = permission->IsPermissionEnabled();
+            break;
+          }
+        }
+
+        std::vector<std::u16string> extensions_for_display =
+            web_app::TransformFileExtensionsForDisplay(file_extensions);
+        file_handling_types = base::UTF16ToUTF8(
+            base::JoinString(extensions_for_display,
+                             l10n_util::GetStringUTF16(
+                                 IDS_WEB_APP_FILE_HANDLING_LIST_SEPARATOR)));
+
+        std::vector<std::u16string> truncated_extensions =
+            extensions_for_display;
+        // Only show at most 4 extensions.
+        truncated_extensions.resize(4);
+        file_handling_types_label =
+            base::UTF16ToUTF8(base::i18n::MessageFormatter::FormatWithNamedArgs(
+                l10n_util::GetStringUTF16(
+                    IDS_APP_MANAGEMENT_FILE_HANDLING_TYPES),
+                "FILE_TYPE_COUNT",
+                static_cast<int>(extensions_for_display.size()), "FILE_TYPE1",
+                truncated_extensions[0], "FILE_TYPE2", truncated_extensions[1],
+                "FILE_TYPE3", truncated_extensions[2], "FILE_TYPE4",
+                truncated_extensions[3], "OVERFLOW_COUNT",
+                static_cast<int>(extensions_for_display.size()) -
+                    static_cast<int>(truncated_extensions.size()),
+                "LINK", "#"));
+      }
+
+      absl::optional<GURL> learn_more_url;
+      if (!CanShowDefaultAppAssociationsUi())
+        learn_more_url = GURL(kFileHandlingLearnMore);
+      // TODO(crbug/1252505): add file handling policy support.
+      app->file_handling_state = app_management::mojom::FileHandlingState::New(
+          fh_enabled, /*is_managed=*/false, file_handling_types,
+          file_handling_types_label, learn_more_url);
     }
-
-    app->hide_window_mode = provider->registrar().IsIsolated(app->id);
-#endif
-
-    absl::optional<GURL> learn_more_url;
-    if (!CanShowDefaultAppAssociationsUi())
-      learn_more_url = GURL(kFileHandlingLearnMore);
-    // TODO(crbug/1252505): add file handling policy support.
-    app->file_handling_state = app_management::mojom::FileHandlingState::New(
-        fh_enabled, /*is_managed=*/false, file_handling_types,
-        file_handling_types_label, learn_more_url);
   }
 
+#if !BUILDFLAG(IS_CHROMEOS)
+  auto* provider = web_app::WebAppProvider::GetForLocalAppsUnchecked(profile_);
+  app->hide_window_mode = provider->registrar().IsIsolated(app->id);
+#endif
+
   app->publisher_id = update.PublisherId();
 
   return app;
diff --git a/chrome/browser/ui/webui/help/version_updater_chromeos_unittest.cc b/chrome/browser/ui/webui/help/version_updater_chromeos_unittest.cc
index 4fc3fc9..3e8dda3 100644
--- a/chrome/browser/ui/webui/help/version_updater_chromeos_unittest.cc
+++ b/chrome/browser/ui/webui/help/version_updater_chromeos_unittest.cc
@@ -60,10 +60,8 @@
   ~VersionUpdaterCrosTest() override {}
 
   void SetUp() override {
-    fake_update_engine_client_ = new FakeUpdateEngineClient();
     DBusThreadManager::Initialize();
-    DBusThreadManager::GetSetterForTesting()->SetUpdateEngineClient(
-        std::unique_ptr<UpdateEngineClient>(fake_update_engine_client_));
+    fake_update_engine_client_ = UpdateEngineClient::InitializeFakeForTest();
 
     EXPECT_CALL(*mock_user_manager_, IsCurrentUserOwner())
         .WillRepeatedly(Return(false));
@@ -98,6 +96,7 @@
   void TearDown() override {
     network_handler_test_helper_.reset();
     version_updater_.reset();
+    UpdateEngineClient::Shutdown();
     DBusThreadManager::Shutdown();
   }
 
diff --git a/chrome/browser/ui/webui/settings/about_handler_unittest.cc b/chrome/browser/ui/webui/settings/about_handler_unittest.cc
index 603ebd5..45e6ac45 100644
--- a/chrome/browser/ui/webui/settings/about_handler_unittest.cc
+++ b/chrome/browser/ui/webui/settings/about_handler_unittest.cc
@@ -10,6 +10,7 @@
 #include "chromeos/ash/components/dbus/concierge/concierge_client.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/update_engine/fake_update_engine_client.h"
+#include "chromeos/dbus/update_engine/update_engine_client.h"
 #include "content/public/test/browser_task_environment.h"
 #include "content/public/test/test_web_ui.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -39,10 +40,8 @@
   AboutHandlerTest& operator=(const AboutHandlerTest&) = delete;
 
   void SetUp() override {
-    fake_update_engine_client_ = new FakeUpdateEngineClient();
     DBusThreadManager::Initialize();
-    DBusThreadManager::GetSetterForTesting()->SetUpdateEngineClient(
-        base::WrapUnique<UpdateEngineClient>(fake_update_engine_client_));
+    fake_update_engine_client_ = UpdateEngineClient::InitializeFakeForTest();
     ConciergeClient::InitializeFake(/*fake_cicerone_client=*/nullptr);
 
     handler_ = std::make_unique<TestAboutHandler>(&profile_);
@@ -58,6 +57,7 @@
     handler_.reset();
     TestingBrowserProcess::GetGlobal()->SetLocalState(nullptr);
     ConciergeClient::Shutdown();
+    UpdateEngineClient::Shutdown();
     DBusThreadManager::Shutdown();
   }
 
diff --git a/chrome/browser/upgrade_detector/installed_version_updater_chromeos_unittest.cc b/chrome/browser/upgrade_detector/installed_version_updater_chromeos_unittest.cc
index f106c59..2e577815 100644
--- a/chrome/browser/upgrade_detector/installed_version_updater_chromeos_unittest.cc
+++ b/chrome/browser/upgrade_detector/installed_version_updater_chromeos_unittest.cc
@@ -13,6 +13,7 @@
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/update_engine/fake_update_engine_client.h"
 #include "chromeos/dbus/update_engine/update_engine.pb.h"
+#include "chromeos/dbus/update_engine/update_engine_client.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -25,14 +26,9 @@
 class InstalledVersionUpdaterTest : public ::testing::Test {
  protected:
   InstalledVersionUpdaterTest() {
-    // Create the fake update engine client, hold a pointer to it, and hand
-    // ownership of it off to the DBus thread manager.
-    auto fake_update_engine_client =
-        std::make_unique<chromeos::FakeUpdateEngineClient>();
-    fake_update_engine_client_ = fake_update_engine_client.get();
     chromeos::DBusThreadManager::Initialize();
-    chromeos::DBusThreadManager::GetSetterForTesting()->SetUpdateEngineClient(
-        std::move(fake_update_engine_client));
+    fake_update_engine_client_ =
+        chromeos::UpdateEngineClient::InitializeFakeForTest();
 
     build_state_.AddObserver(&mock_observer_);
   }
@@ -41,6 +37,7 @@
     build_state_.RemoveObserver(&mock_observer_);
 
     // Be kind; rewind.
+    chromeos::UpdateEngineClient::Shutdown();
     chromeos::DBusThreadManager::Shutdown();
   }
 
diff --git a/chrome/browser/upgrade_detector/upgrade_detector_chromeos_unittest.cc b/chrome/browser/upgrade_detector/upgrade_detector_chromeos_unittest.cc
index 19c918fe..7ec1880 100644
--- a/chrome/browser/upgrade_detector/upgrade_detector_chromeos_unittest.cc
+++ b/chrome/browser/upgrade_detector/upgrade_detector_chromeos_unittest.cc
@@ -21,6 +21,7 @@
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/update_engine/fake_update_engine_client.h"
+#include "chromeos/dbus/update_engine/update_engine_client.h"
 #include "components/prefs/testing_pref_service.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -97,11 +98,9 @@
     scoped_local_state_.Get()->SetUserPref(prefs::kAttemptedToEnableAutoupdate,
                                            std::make_unique<base::Value>(true));
 
-    fake_update_engine_client_ = new chromeos::FakeUpdateEngineClient();
     chromeos::DBusThreadManager::Initialize();
-    chromeos::DBusThreadManager::GetSetterForTesting()->SetUpdateEngineClient(
-        std::unique_ptr<chromeos::UpdateEngineClient>(
-            fake_update_engine_client_));
+    fake_update_engine_client_ =
+        chromeos::UpdateEngineClient::InitializeFakeForTest();
 
     // Fast forward to set current time to local 2am . This is done to align the
     // relaunch deadline within the default relaunch window of 2am to 4am so
@@ -123,6 +122,7 @@
     }
     tzset();
 
+    chromeos::UpdateEngineClient::Shutdown();
     chromeos::DBusThreadManager::Shutdown();
   }
 
diff --git a/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc b/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc
index 556af552..f12626c 100644
--- a/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc
+++ b/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc
@@ -135,6 +135,7 @@
     case apps::mojom::PermissionType::kContacts:
     case apps::mojom::PermissionType::kStorage:
     case apps::mojom::PermissionType::kPrinting:
+    case apps::mojom::PermissionType::kFileHandling:
       return false;
   }
 }
@@ -433,6 +434,14 @@
 
     target->push_back(std::move(permission));
   }
+
+  // File handling permission.
+  auto permission = apps::mojom::Permission::New();
+  permission->permission_type = apps::mojom::PermissionType::kFileHandling;
+  permission->value = apps::mojom::PermissionValue::NewBoolValue(
+      !registrar().IsAppFileHandlerPermissionBlocked(web_app->app_id()));
+  permission->is_managed = false;
+  target->push_back(std::move(permission));
 }
 
 apps::Permissions WebAppPublisherHelper::CreatePermissions(
@@ -474,6 +483,14 @@
         /*is_managed=*/setting_info.source ==
             content_settings::SETTING_SOURCE_POLICY));
   }
+
+  // File handling permission.
+  permissions.push_back(std::make_unique<apps::Permission>(
+      apps::PermissionType::kFileHandling,
+      std::make_unique<apps::PermissionValue>(
+          !registrar().IsAppFileHandlerPermissionBlocked(web_app->app_id())),
+      /*is_managed=*/false));
+
   return permissions;
 }
 
@@ -547,6 +564,23 @@
   if (IsNoteTakingWebApp(*web_app))
     app->intent_filters.push_back(apps_util::CreateNoteTakingFilter());
 
+  // These filters are used by the settings page to display would-be-handled
+  // extensions even when the feature is not enabled for the app, whereas
+  // `GetEnabledFileHandlers` above only returns the ones that currently are
+  // enabled.
+  const apps::FileHandlers* all_file_handlers =
+      registrar().GetAppFileHandlers(web_app->app_id());
+  if (all_file_handlers && !all_file_handlers->empty()) {
+    std::set<std::string> extensions_set =
+        apps::GetFileExtensionsFromFileHandlers(*all_file_handlers);
+    app->intent_filters.push_back(apps::ConvertMojomIntentFilterToIntentFilter(
+        apps_util::CreateFileFilter(
+            {apps_util::kIntentActionPotentialFileHandler},
+            /*mime_types=*/{},
+            /*file_extensions=*/
+            {extensions_set.begin(), extensions_set.end()})));
+  }
+
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   if (web_app->app_id() == crostini::kCrostiniTerminalSystemAppId) {
     app->intent_filters.push_back(apps::ConvertMojomIntentFilterToIntentFilter(
@@ -1014,6 +1048,14 @@
     return;
   }
 
+  if (permission->permission_type ==
+      apps::mojom::PermissionType::kFileHandling) {
+    web_app::PersistFileHandlersUserChoice(profile_, app_id,
+                                           permission->value->get_bool_value(),
+                                           base::DoNothing());
+    return;
+  }
+
   auto* host_content_settings_map =
       HostContentSettingsMapFactory::GetForProfile(profile_);
   DCHECK(host_content_settings_map);
diff --git a/chrome/browser/web_applications/externally_managed_app_manager_impl_browsertest.cc b/chrome/browser/web_applications/externally_managed_app_manager_impl_browsertest.cc
index 5f343688..791a05c 100644
--- a/chrome/browser/web_applications/externally_managed_app_manager_impl_browsertest.cc
+++ b/chrome/browser/web_applications/externally_managed_app_manager_impl_browsertest.cc
@@ -549,17 +549,8 @@
       .AwaitNextRegistration(url, RegistrationResultCode::kTimeout);
 }
 
-// crbug.com/1334849: All/ExternallyManagedBrowserTestWithPrefMigrationRead.
-// ReinstallPolicyAppWithLocallyInstalledApp/1 is failing on Mac builders.
-#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
-#define MAYBE_ReinstallPolicyAppWithLocallyInstalledApp \
-  DISABLED_ReinstallPolicyAppWithLocallyInstalledApp
-#else
-#define MAYBE_ReinstallPolicyAppWithLocallyInstalledApp \
-  ReinstallPolicyAppWithLocallyInstalledApp
-#endif
 IN_PROC_BROWSER_TEST_P(ExternallyManagedBrowserTestWithPrefMigrationRead,
-                       MAYBE_ReinstallPolicyAppWithLocallyInstalledApp) {
+                       ReinstallPolicyAppWithLocallyInstalledApp) {
   ASSERT_TRUE(embedded_test_server()->Start());
   GURL url(embedded_test_server()->GetURL("/banners/manifest_test_page.html"));
 
diff --git a/chrome/browser/web_applications/proto/web_app.proto b/chrome/browser/web_applications/proto/web_app.proto
index 3161cbb..3580801e 100644
--- a/chrome/browser/web_applications/proto/web_app.proto
+++ b/chrome/browser/web_applications/proto/web_app.proto
@@ -126,8 +126,6 @@
 // app_id is the storage key in ModelTypeStore.
 message WebAppProto {
   reserved "is_in_sync_install", "is_placeholder";
-  reserved 53;
-
   // Synced data. It is replicated across all devices with WEB_APPS.
   //
   // |sync_data.name| and |sync_data.theme_color| are read by a device to
@@ -343,8 +341,7 @@
   repeated ManagementToExternalConfigInfo management_to_external_config_info =
       52;
 
-  // Stores whether the app is a placeholder app or not.
-  // optional bool is_placeholder = 53;
+  reserved 53;
 
   // The amount of storage (in bytes) used by the app and its related data.
   optional uint64 app_size_in_bytes = 54;
diff --git a/chrome/browser/web_applications/web_app_url_loader.cc b/chrome/browser/web_applications/web_app_url_loader.cc
index c6be9e3..8a7825b 100644
--- a/chrome/browser/web_applications/web_app_url_loader.cc
+++ b/chrome/browser/web_applications/web_app_url_loader.cc
@@ -85,8 +85,10 @@
     }
 
     // Flush all DidFinishLoad events until about:blank loaded.
-    if (url_.IsAboutBlank() && !validated_url.IsAboutBlank())
+    if ((url_.IsAboutBlank() && !validated_url.IsAboutBlank()) ||
+        (!url_.IsAboutBlank() && validated_url.IsAboutBlank())) {
       return;
+    }
 
     timer_.Stop();
 
diff --git a/chrome/browser/web_applications/web_app_utils.cc b/chrome/browser/web_applications/web_app_utils.cc
index 6c54194b..017efdba 100644
--- a/chrome/browser/web_applications/web_app_utils.cc
+++ b/chrome/browser/web_applications/web_app_utils.cc
@@ -324,17 +324,6 @@
 std::tuple<std::u16string, size_t>
 GetFileTypeAssociationsHandledByWebAppForDisplay(Profile* profile,
                                                  const AppId& app_id) {
-  auto extensions =
-      GetFileTypeAssociationsHandledByWebAppForDisplayAsList(profile, app_id);
-  return {base::UTF8ToUTF16(base::JoinString(
-              extensions, l10n_util::GetStringUTF8(
-                              IDS_WEB_APP_FILE_HANDLING_LIST_SEPARATOR))),
-          extensions.size()};
-}
-
-std::vector<std::string> GetFileTypeAssociationsHandledByWebAppForDisplayAsList(
-    Profile* profile,
-    const AppId& app_id) {
   auto* provider = WebAppProvider::GetForLocalAppsUnchecked(profile);
   if (!provider)
     return {};
@@ -342,17 +331,26 @@
   const apps::FileHandlers* file_handlers =
       provider->registrar().GetAppFileHandlers(app_id);
 
-  std::set<std::string> extensions_set =
-      apps::GetFileExtensionsFromFileHandlers(*file_handlers);
-  std::vector<std::string> extensions_for_display;
-  extensions_for_display.reserve(extensions_set.size());
+  std::vector<std::u16string> extensions_for_display =
+      TransformFileExtensionsForDisplay(
+          apps::GetFileExtensionsFromFileHandlers(*file_handlers));
 
-  // Convert file types from formats like ".txt" to "TXT".
-  std::transform(extensions_set.begin(), extensions_set.end(),
-                 std::back_inserter(extensions_for_display),
-                 [](const std::string& extension) {
-                   return base::ToUpperASCII(extension.substr(1));
-                 });
+  return {base::JoinString(extensions_for_display,
+                           l10n_util::GetStringUTF16(
+                               IDS_WEB_APP_FILE_HANDLING_LIST_SEPARATOR)),
+          extensions_for_display.size()};
+}
+
+std::vector<std::u16string> TransformFileExtensionsForDisplay(
+    const std::set<std::string>& extensions) {
+  std::vector<std::u16string> extensions_for_display;
+  extensions_for_display.reserve(extensions.size());
+  std::transform(
+      extensions.begin(), extensions.end(),
+      std::back_inserter(extensions_for_display),
+      [](const std::string& extension) {
+        return base::UTF8ToUTF16(base::ToUpperASCII(extension.substr(1)));
+      });
   return extensions_for_display;
 }
 
diff --git a/chrome/browser/web_applications/web_app_utils.h b/chrome/browser/web_applications/web_app_utils.h
index 50900bb2..467e01c 100644
--- a/chrome/browser/web_applications/web_app_utils.h
+++ b/chrome/browser/web_applications/web_app_utils.h
@@ -117,9 +117,8 @@
 
 // As above, but returns the extensions handled by the app as a vector of
 // strings.
-std::vector<std::string> GetFileTypeAssociationsHandledByWebAppForDisplayAsList(
-    Profile* profile,
-    const AppId& app_id);
+std::vector<std::u16string> TransformFileExtensionsForDisplay(
+    const std::set<std::string>& extensions);
 
 // Updates the approved or disallowed protocol list for the given app. If
 // necessary, it also updates the protocol registration with the OS.
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt
index b4e5cab..8224b34 100644
--- a/chrome/build/mac-arm.pgo.txt
+++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@
-chrome-mac-arm-main-1655358157-81844b66eb6471b1e2d2a67fee844f852e20c00a.profdata
+chrome-mac-arm-main-1655380258-18cc3367bda96400f0ba7a8ce4a9083c7ec53858.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index 9a5d47f..6b73559a9 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-main-1655358157-24489213207d60ff1ac2d3a8ba44150b2b81e69d.profdata
+chrome-mac-main-1655380258-467aa2b7dffb13b2dec2d4827bfd049b603c7f14.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index 21e2579..857cb34 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1655337558-1ada0e53f07ce62ba7cc2a9bbecfd62d15d846d1.profdata
+chrome-win32-main-1655369557-80a8c6aeb7eca767df3b7bd3c6367ee132b16405.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 1c8c6f1..cacffa5 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1655369557-6779c2fbea517a70c62f8572468ec9b10a6ec504.profdata
+chrome-win64-main-1655380258-ca23d6d03401849200d91d4ebcd56cd4fdbd7e0c.profdata
diff --git a/chrome/common/extensions/api/enterprise_reporting_private.idl b/chrome/common/extensions/api/enterprise_reporting_private.idl
index 71f03a7..4a4fc4c 100644
--- a/chrome/common/extensions/api/enterprise_reporting_private.idl
+++ b/chrome/common/extensions/api/enterprise_reporting_private.idl
@@ -125,6 +125,43 @@
     EventType eventType;
   };
 
+  // Context object containing the content-area user's ID for whom the signals
+  // collection request is for. This will be used to identify the organization
+  // in which the user is, and can then be used to determine their affiliation
+  // with the current browser management state.
+  [platforms = ("win")]
+  dictionary UserContext {
+    DOMString userId;
+  };
+
+  // Enumeration of the various states an AntiVirus software product can be in.
+  [platforms = ("win")]
+  enum AntiVirusProductState { ON, OFF, SNOOZED, EXPIRED };
+
+  // Metadata about a specific AntiVirus software product.
+  [platforms = ("win")]
+  dictionary AntiVirusSignal {
+    DOMString displayName;
+    DOMString productId;
+    AntiVirusProductState state;
+  };
+
+  // Invoked by <code>getAvInfo</code> to return information about installed
+  // AntiVirus software.
+  [platforms = ("win")]
+  callback AvInfoCallback = void(AntiVirusSignal[] avSignals);
+
+  // ID of an installed hotfix system update.
+  [platforms = ("win")]
+  dictionary HotfixSignal {
+    DOMString hotfixId;
+  };
+
+  // Invoked by <code>getHotfixes</code> to return the IDs of installed hotfix
+  // system updates.
+  [platforms = ("win")]
+  callback HotfixesCallback = void(HotfixSignal[] hotfixSignals);
+
   interface Functions {
     // Gets the identity of device that Chrome browser is running on. The ID is
     // retrieved from the local device and used by the Google admin console.
@@ -176,6 +213,22 @@
     static void enqueueRecord(
         EnqueueRecordRequest request,
         optional DoneCallback callback);
+
+    // Gets information about AntiVirus software installed on the current
+    // device. <code>userContext</code> is used to verify the affiliation
+    // between the user's organization and the organization managing the
+    // browser. If the management, or affiliation, state is not suitable, no
+    // results will be returned.
+    [platforms = ("win"), supportsPromises]
+    static void getAvInfo(UserContext userContext, AvInfoCallback callback);
+
+    // Gets information about hotfix system updates installed on the current
+    // device. <code>userContext</code> is used to verify the affiliation
+    // between the user's organization and the organization managing the
+    // browser. If the management, or affiliation, state is not suitable, no
+    // results will be returned.
+    [platforms = ("win"), supportsPromises]
+    static void getHotfixes(UserContext userContext, HotfixesCallback callback);
   };
 
 };
diff --git a/chrome/installer/util/l10n_string_util.cc b/chrome/installer/util/l10n_string_util.cc
index 4555379..12b9fd2b 100644
--- a/chrome/installer/util/l10n_string_util.cc
+++ b/chrome/installer/util/l10n_string_util.cc
@@ -17,6 +17,7 @@
 #include "base/check.h"
 #include "base/no_destructor.h"
 #include "base/notreached.h"
+#include "base/numerics/safe_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
@@ -62,7 +63,7 @@
   g_translation_delegate = delegate;
 }
 
-std::wstring GetLocalizedString(UINT base_message_id) {
+std::wstring GetLocalizedString(int base_message_id) {
   // Map |base_message_id| to the base id for the current install mode.
   base_message_id = GetBaseMessageIdForMode(base_message_id);
 
@@ -71,8 +72,8 @@
 
   std::wstring localized_string;
 
-  UINT message_id =
-      static_cast<UINT>(base_message_id + GetLanguageSelector().offset());
+  UINT message_id = base::checked_cast<UINT>(base_message_id +
+                                             GetLanguageSelector().offset());
   const ATLSTRINGRESOURCEIMAGE* image =
       AtlGetStringResourceImage(_AtlBaseModule.GetModuleInstance(), message_id);
   if (image) {
diff --git a/chrome/installer/util/l10n_string_util.h b/chrome/installer/util/l10n_string_util.h
index 5a22dac..4b5d737 100644
--- a/chrome/installer/util/l10n_string_util.h
+++ b/chrome/installer/util/l10n_string_util.h
@@ -15,8 +15,6 @@
 
 #include <string>
 
-using UINT = unsigned int;
-
 namespace installer {
 
 class TranslationDelegate {
@@ -38,11 +36,11 @@
 // mapped to a variant that is specific to the current install mode (e.g.,
 // IDS_INBOUND_MDNS_RULE_NAME is mapped to IDS_INBOUND_MDNS_RULE_NAME_CANARY for
 // canary Chrome).
-std::wstring GetLocalizedString(UINT base_message_id);
+std::wstring GetLocalizedString(int base_message_id);
 
 // Returns the localized version of a string (obtained from GetLocalizedString)
 // with $1 replaced with |a|. Additionally, $$ is replaced by $.
-std::wstring GetLocalizedStringF(UINT base_message_id, const std::wstring& a);
+std::wstring GetLocalizedStringF(int base_message_id, const std::wstring& a);
 
 // Given the system language, return a url that points to the localized eula.
 // The empty string is returned on failure.
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 391a6bc..83a8c8e 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -839,6 +839,7 @@
       "../browser/metrics/sampled_out_client_id_saved_browsertest.cc",
       "../browser/metrics/startup_metrics_browsertest.cc",
       "../browser/metrics/ukm_browsertest.cc",
+      "../browser/net/android_network_service_browsertest.cc",
       "../browser/net/cert_verify_proc_browsertest.cc",
       "../browser/page_load_metrics/observers/ad_metrics/ad_density_intervention_android_browsertest.cc",
       "../browser/password_manager/android/password_manager_android_browsertest.cc",
@@ -7265,7 +7266,6 @@
       "//components/app_restore:unit_tests",
       "//components/arc:arc_test_support",
       "//components/arc/common",
-      "//components/device_signals/core/common",
       "//components/services/app_service/public/cpp:app_update",
       "//components/services/app_service/public/cpp:instance_update",
       "//components/services/app_service/public/cpp:preferred_apps",
@@ -8138,7 +8138,10 @@
       "../browser/enterprise/connectors/device_trust/key_management/core/persistence:test_support",
       "../browser/enterprise/connectors/device_trust/key_management/installer:unit_tests",
       "../browser/enterprise/connectors/device_trust/signals/decorators/browser:unit_tests",
+      "../browser/enterprise/signals:features",
       "../browser/enterprise/signals:unit_tests",
+      "//components/device_signals/core/browser",
+      "//components/device_signals/core/browser:test_support",
     ]
   }
 
diff --git a/chrome/test/android/BUILD.gn b/chrome/test/android/BUILD.gn
index 3521184..ebbb0a3 100644
--- a/chrome/test/android/BUILD.gn
+++ b/chrome/test/android/BUILD.gn
@@ -274,8 +274,6 @@
     "javatests/src/org/chromium/chrome/test/batch/BlankCTATabInitialStateRule.java",
     "javatests/src/org/chromium/chrome/test/gcore/MockChromeGoogleApiClient.java",
     "javatests/src/org/chromium/chrome/test/invalidation/IntentSavingContext.java",
-    "javatests/src/org/chromium/chrome/test/omaha/AttributeFinder.java",
-    "javatests/src/org/chromium/chrome/test/omaha/MockRequestGenerator.java",
     "javatests/src/org/chromium/chrome/test/util/BookmarkTestRule.java",
     "javatests/src/org/chromium/chrome/test/util/BookmarkTestUtil.java",
     "javatests/src/org/chromium/chrome/test/util/ChromeApplicationTestUtils.java",
diff --git a/chrome/test/data/capability_delegation/payment_request_delegation.html b/chrome/test/data/capability_delegation/payment_request_delegation.html
index e50326a..7989b3a 100644
--- a/chrome/test/data/capability_delegation/payment_request_delegation.html
+++ b/chrome/test/data/capability_delegation/payment_request_delegation.html
@@ -14,15 +14,20 @@
   let resolve_promise = null;
   window.addEventListener("message", e => resolve_promise(e.data));
 
-  async function sendRequestToSubframe(delegate, paymentMethod) {
+  async function sendRequestToSubframe(delegate, paymentMethod, targetOrigin) {
       const promise = new Promise(resolve => { resolve_promise = resolve; });
 
       let post_message_options = {};
-      post_message_options["targetOrigin"] = "*";
       if (delegate) {
           post_message_options["delegate"] = "payment";
       }
-      frames[0].postMessage(paymentMethod, post_message_options);
+      post_message_options["targetOrigin"] = targetOrigin;
+      try {
+          frames[0].postMessage(paymentMethod, post_message_options);
+      } catch (exception) {
+          resolve_promise(exception.name);
+      }
+
       return promise;
   }
 </script>
diff --git a/chrome/test/data/webui/chromeos/os_feedback_ui/search_page_test.js b/chrome/test/data/webui/chromeos/os_feedback_ui/search_page_test.js
index 1660b52..7c8a7027 100644
--- a/chrome/test/data/webui/chromeos/os_feedback_ui/search_page_test.js
+++ b/chrome/test/data/webui/chromeos/os_feedback_ui/search_page_test.js
@@ -7,6 +7,7 @@
 import {FeedbackFlowState} from 'chrome://os-feedback/feedback_flow.js';
 import {setHelpContentProviderForTesting} from 'chrome://os-feedback/mojo_interface_provider.js';
 import {OS_FEEDBACK_UNTRUSTED_ORIGIN, SearchPageElement} from 'chrome://os-feedback/search_page.js';
+import {getDeepActiveElement} from 'chrome://resources/js/util.m.js';
 
 import {assertEquals, assertFalse, assertNotEquals, assertTrue} from '../../chai_assert.js';
 import {eventToPromise, flushTasks} from '../../test_util.js';
@@ -41,26 +42,41 @@
             document.createElement('search-page'));
     assertTrue(!!page);
     document.body.appendChild(page);
+
     return flushTasks();
   }
 
-  /** Test that expected html elements are in the page after loaded. */
+  /**
+   * @param {string} selector
+   * @returns {!Element}
+   */
+  function getElement(selector) {
+    const element = page.shadowRoot.querySelector(selector);
+    assertTrue(!!element);
+    return /** @type {!Element} */ (element);
+  }
+
+  /**
+   * Test that expected html elements are in the page after loaded.
+   */
   test('SearchPageLoaded', async () => {
     await initializePage();
     // Verify the title is in the page.
     const title = page.shadowRoot.querySelector('.page-title');
-    assertTrue(!!title);
     assertEquals('Send feedback', title.textContent.trim());
 
+    // Verify the iframe is in the page.
+    const untrustedFrame = getElement('iframe');
+    assertEquals(
+        'chrome-untrusted://os-feedback/untrusted_index.html',
+        untrustedFrame.src);
+
     // Verify the descriptionTitle is in the page.
-    const descriptionTitle = page.shadowRoot.querySelector('#descriptionTitle');
-    assertTrue(!!descriptionTitle);
+    const descriptionTitle = getElement('#descriptionTitle');
     assertEquals('Description', descriptionTitle.textContent.trim());
 
     // Verify the feedback writing guidance link is in the page.
-    const writingGuidanceLink =
-        page.shadowRoot.querySelector('#feedbackWritingGuidance');
-    assertTrue(!!writingGuidanceLink);
+    const writingGuidanceLink = getElement('#feedbackWritingGuidance');
     assertEquals(
         'Tips on writing feedback', writingGuidanceLink.textContent.trim());
     assertEquals('_blank', writingGuidanceLink.target);
@@ -73,16 +89,8 @@
     const helpContent = page.shadowRoot.querySelector('help-content');
     assertFalse(!!helpContent);
 
-    // Verify the iframe is in the page.
-    const untrustedFrame = page.shadowRoot.querySelector('iframe');
-    assertTrue(!!untrustedFrame);
-    assertEquals(
-        'chrome-untrusted://os-feedback/untrusted_index.html',
-        untrustedFrame.src);
-
     // Verify the continue button is in the page.
-    const buttonContinue = page.shadowRoot.querySelector('#buttonContinue');
-    assertTrue(!!buttonContinue);
+    const buttonContinue = getElement('#buttonContinue');
     assertEquals('Continue', buttonContinue.textContent.trim());
   });
 
@@ -99,8 +107,7 @@
     let textAreaElement = null;
 
     await initializePage();
-    textAreaElement = page.shadowRoot.querySelector('#descriptionText');
-    assertTrue(!!textAreaElement);
+    textAreaElement = getElement('#descriptionText');
     // Verify the textarea is empty and hint is showing.
     assertEquals('', textAreaElement.value);
     assertEquals(
@@ -148,8 +155,7 @@
 
     await initializePage();
 
-    const iframe = /** @type {!HTMLIFrameElement} */ (
-        page.shadowRoot.querySelector('iframe'));
+    const iframe = /** @type {!HTMLIFrameElement} */ (getElement('iframe'));
     assertTrue(!!iframe);
     // Wait for the iframe completes loading.
     await eventToPromise('load', iframe);
@@ -186,24 +192,24 @@
   test('DescriptionEmptyError', async () => {
     await initializePage();
 
-    const errorMsg = page.shadowRoot.querySelector('#descriptionEmptyError');
+    const errorMsg = getElement('#descriptionEmptyError');
     // Verify that the error message is hidden in the beginning.
     assertTrue(errorMsg.hidden);
 
-    const textInput = page.shadowRoot.querySelector('#descriptionText');
+    const textInput = getElement('#descriptionText');
     assertTrue(textInput.value.length === 0);
     // Remove focus on the textarea.
     textInput.blur();
-    assertNotEquals(page.shadowRoot.activeElement, textInput);
+    assertNotEquals(getDeepActiveElement(), textInput);
 
-    const buttonContinue = page.shadowRoot.querySelector('#buttonContinue');
+    const buttonContinue = getElement('#buttonContinue');
     buttonContinue.click();
     // Verify that the message is not hidden now.
     assertFalse(errorMsg.hidden);
     assertEquals('Description is required', errorMsg.textContent.trim());
 
     // Verify that the textarea received focus again.
-    assertEquals(page.shadowRoot.activeElement, textInput);
+    assertEquals(getDeepActiveElement(), textInput);
 
     // Now enter some text. The error message should be hidden again.
     textInput.value = 'hello';
@@ -219,17 +225,18 @@
   test('Continue', async () => {
     await initializePage();
 
-    const textInput = page.shadowRoot.querySelector('#descriptionText');
+    const textInput = getElement('#descriptionText');
     textInput.value = 'hello';
 
-    const clickPromise = eventToPromise('continue-click', page);
+    const clickPromise =
+        eventToPromise('continue-click', /** @type {!Element} */ (page));
     let actualCurrentState;
 
     page.addEventListener('continue-click', (event) => {
       actualCurrentState = event.detail.currentState;
     });
 
-    const buttonContinue = page.shadowRoot.querySelector('#buttonContinue');
+    const buttonContinue = getElement('#buttonContinue');
     buttonContinue.click();
 
     await clickPromise;
diff --git a/chrome/updater/app/server/win/com_classes_legacy_unittest.cc b/chrome/updater/app/server/win/com_classes_legacy_unittest.cc
index 252c824..7135aa8b 100644
--- a/chrome/updater/app/server/win/com_classes_legacy_unittest.cc
+++ b/chrome/updater/app/server/win/com_classes_legacy_unittest.cc
@@ -53,10 +53,10 @@
   ~LegacyAppCommandWebImplTest() override = default;
 
   void SetUp() override {
-    SetupCmdExe(cmd_exe_command_line_, temp_programfiles_dir_);
+    SetupCmdExe(GetTestScope(), cmd_exe_command_line_, temp_programfiles_dir_);
   }
 
-  void TearDown() override { DeleteAppClientKey(kAppId1); }
+  void TearDown() override { DeleteAppClientKey(GetTestScope(), kAppId1); }
 
   template <typename T>
   absl::optional<std::wstring> MakeCommandLine(
@@ -91,8 +91,8 @@
       const std::wstring& command_id,
       const std::wstring& command_line_format,
       const std::vector<std::wstring>& parameters) {
-    CreateAppClientKey(app_id);
-    CreateAppCommandRegistry(app_id, command_id, command_line_format);
+    CreateAppCommandRegistry(GetTestScope(), app_id, command_id,
+                             command_line_format);
 
     Microsoft::WRL::ComPtr<LegacyAppCommandWebImpl> app_command_web;
     if (HRESULT hr = LegacyAppCommandWebImpl::CreateLegacyAppCommandWebImpl(
@@ -109,8 +109,8 @@
       const std::wstring& command_id,
       const std::wstring& command_line_format,
       Microsoft::WRL::ComPtr<LegacyAppCommandWebImpl>& app_command_web) {
-    CreateAppClientKey(app_id);
-    CreateAppCommandRegistry(app_id, command_id, command_line_format);
+    CreateAppCommandRegistry(GetTestScope(), app_id, command_id,
+                             command_line_format);
 
     return LegacyAppCommandWebImpl::CreateLegacyAppCommandWebImpl(
         GetTestScope(), app_id, command_id, app_command_web);
@@ -125,8 +125,7 @@
 
   void NoCmdTest() {
     Microsoft::WRL::ComPtr<LegacyAppCommandWebImpl> app_command_web;
-    CreateAppClientKey(kAppId1);
-    CreateAppCommandRegistry(kAppId1, kCmdId1, kCmdLineValid);
+    CreateAppCommandRegistry(GetTestScope(), kAppId1, kCmdId1, kCmdLineValid);
 
     EXPECT_HRESULT_FAILED(
         LegacyAppCommandWebImpl::CreateLegacyAppCommandWebImpl(
diff --git a/chrome/updater/test/integration_tests_win.cc b/chrome/updater/test/integration_tests_win.cc
index 73ae43d7..3254241 100644
--- a/chrome/updater/test/integration_tests_win.cc
+++ b/chrome/updater/test/integration_tests_win.cc
@@ -48,6 +48,7 @@
 #include "chrome/updater/persisted_data.h"
 #include "chrome/updater/prefs.h"
 #include "chrome/updater/test/integration_tests_impl.h"
+#include "chrome/updater/unittest_util_win.h"
 #include "chrome/updater/updater_branding.h"
 #include "chrome/updater/updater_scope.h"
 #include "chrome/updater/updater_version.h"
@@ -344,39 +345,12 @@
                      const std::wstring& app_id,
                      const std::wstring& command_id,
                      base::ScopedTempDir& temp_dir) {
-  base::FilePath system_path;
-  ASSERT_TRUE(base::PathService::Get(base::DIR_SYSTEM, &system_path));
-
-  const wchar_t kCmdExe[] = L"cmd.exe";
-  const base::FilePath from_test_process = system_path.Append(kCmdExe);
-  base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
-
-  if (scope == UpdaterScope::kUser) {
-    command_line = base::CommandLine(from_test_process);
-  } else {
-    base::FilePath programfiles_path;
-    ASSERT_TRUE(
-        base::PathService::Get(base::DIR_PROGRAM_FILES, &programfiles_path));
-    ASSERT_TRUE(temp_dir.CreateUniqueTempDirUnderPath(programfiles_path));
-    base::FilePath test_process_path = temp_dir.GetPath().Append(kCmdExe);
-
-    ASSERT_TRUE(base::CopyFile(from_test_process, test_process_path));
-    command_line = base::CommandLine(test_process_path);
-  }
-
-  base::win::RegKey command_key;
-  ASSERT_EQ(command_key.Create(UpdaterScopeToHKeyRoot(scope),
-                               base::StrCat({CLIENTS_KEY, app_id, L"\\",
-                                             kRegKeyCommands, command_id})
-                                   .c_str(),
-                               Wow6432(KEY_WRITE)),
-            ERROR_SUCCESS);
-  ASSERT_EQ(
-      command_key.WriteValue(kRegValueCommandLine,
-                             base::StrCat({command_line.GetCommandLineString(),
-                                           L" /c \"exit %1\""})
-                                 .c_str()),
-      ERROR_SUCCESS);
+  base::CommandLine cmd_exe_command_line(base::CommandLine::NO_PROGRAM);
+  SetupCmdExe(scope, cmd_exe_command_line, temp_dir);
+  CreateAppCommandRegistry(
+      scope, app_id, command_id,
+      base::StrCat(
+          {cmd_exe_command_line.GetCommandLineString(), L" /c \"exit %1\""}));
 }
 
 class WindowEnumerator {
@@ -956,6 +930,8 @@
   DWORD exit_code = 0;
   EXPECT_HRESULT_SUCCEEDED(app_command_web->get_exitCode(&exit_code));
   EXPECT_EQ(exit_code, static_cast<DWORD>(expected_exit_code));
+
+  DeleteAppClientKey(scope, appid);
 }
 
 int RunVPythonCommand(const base::CommandLine& command_line) {
diff --git a/chrome/updater/unittest_util_win.cc b/chrome/updater/unittest_util_win.cc
index beb5dea2..535f407 100644
--- a/chrome/updater/unittest_util_win.cc
+++ b/chrome/updater/unittest_util_win.cc
@@ -15,7 +15,7 @@
 #include "base/path_service.h"
 #include "base/strings/strcat.h"
 #include "base/win/registry.h"
-#include "chrome/updater/test_scope.h"
+#include "chrome/updater/updater_scope.h"
 #include "chrome/updater/win/win_constants.h"
 #include "chrome/updater/win/win_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -29,28 +29,29 @@
 std::wstring GetAppCommandKeyName(const std::wstring& app_id,
                                   const std::wstring& command_id) {
   return base::StrCat(
-      {CLIENTS_KEY, app_id, L"\\", kRegKeyCommands, L"\\", command_id});
+      {GetClientKeyName(app_id), L"\\", kRegKeyCommands, L"\\", command_id});
 }
 
-void CreateAppClientKey(const std::wstring& app_id) {
+void CreateAppClientKey(UpdaterScope scope, const std::wstring& app_id) {
   base::win::RegKey client_key;
   EXPECT_EQ(
-      client_key.Create(UpdaterScopeToHKeyRoot(GetTestScope()),
+      client_key.Create(UpdaterScopeToHKeyRoot(scope),
                         GetClientKeyName(app_id).c_str(), Wow6432(KEY_WRITE)),
       ERROR_SUCCESS);
 }
 
-void DeleteAppClientKey(const std::wstring& app_id) {
-  base::win::RegKey(UpdaterScopeToHKeyRoot(GetTestScope()), L"",
-                    Wow6432(DELETE))
+void DeleteAppClientKey(UpdaterScope scope, const std::wstring& app_id) {
+  base::win::RegKey(UpdaterScopeToHKeyRoot(scope), L"", Wow6432(DELETE))
       .DeleteKey(GetClientKeyName(app_id).c_str());
 }
 
-void CreateAppCommandRegistry(const std::wstring& app_id,
+void CreateAppCommandRegistry(UpdaterScope scope,
+                              const std::wstring& app_id,
                               const std::wstring& cmd_id,
                               const std::wstring& cmd_line) {
+  CreateAppClientKey(scope, app_id);
   base::win::RegKey command_key;
-  EXPECT_EQ(command_key.Create(UpdaterScopeToHKeyRoot(GetTestScope()),
+  EXPECT_EQ(command_key.Create(UpdaterScopeToHKeyRoot(scope),
                                GetAppCommandKeyName(app_id, cmd_id).c_str(),
                                Wow6432(KEY_WRITE)),
             ERROR_SUCCESS);
@@ -58,7 +59,8 @@
             ERROR_SUCCESS);
 }
 
-void SetupCmdExe(base::CommandLine& cmd_exe_command_line,
+void SetupCmdExe(UpdaterScope scope,
+                 base::CommandLine& cmd_exe_command_line,
                  base::ScopedTempDir& temp_programfiles_dir) {
   constexpr wchar_t kCmdExe[] = L"cmd.exe";
 
@@ -66,7 +68,7 @@
   ASSERT_TRUE(base::PathService::Get(base::DIR_SYSTEM, &system_path));
 
   const base::FilePath cmd_exe_system_path = system_path.Append(kCmdExe);
-  if (GetTestScope() == UpdaterScope::kUser) {
+  if (scope == UpdaterScope::kUser) {
     cmd_exe_command_line = base::CommandLine(cmd_exe_system_path);
     return;
   }
diff --git a/chrome/updater/unittest_util_win.h b/chrome/updater/unittest_util_win.h
index 1a84dadb..b49f511 100644
--- a/chrome/updater/unittest_util_win.h
+++ b/chrome/updater/unittest_util_win.h
@@ -9,6 +9,7 @@
 
 #include "base/command_line.h"
 #include "base/files/scoped_temp_dir.h"
+#include "chrome/updater/updater_scope.h"
 
 namespace updater {
 
@@ -21,27 +22,29 @@
                                   const std::wstring& command_id);
 
 // Creates the key `{HKLM\HKCU}\Software\{CompanyName}\Update\Clients\{app_id}`.
-// `{HKLM\HKCU}` is determined by the current test scope.
-void CreateAppClientKey(const std::wstring& app_id);
+// `{HKLM\HKCU}` is determined by `scope`.
+void CreateAppClientKey(UpdaterScope scope, const std::wstring& app_id);
 
 // Deletes the key `{HKLM\HKCU}\Software\{CompanyName}\Update\Clients\{app_id}`.
-// `{HKLM\HKCU}` is determined by the current test scope.
-void DeleteAppClientKey(const std::wstring& app_id);
+// `{HKLM\HKCU}` is determined by `scope`.
+void DeleteAppClientKey(UpdaterScope scope, const std::wstring& app_id);
 
 // Creates the key
 // `{HKRoot}\Software\{CompanyName}\Update\Clients\{app_id}\Commands\{cmd_id}`,
 // and adds a `CommandLine` REG_SZ entry with the value `cmd_line`. `{HKRoot}`
-// is determined by the current test scope.
-void CreateAppCommandRegistry(const std::wstring& app_id,
+// is determined by `scope`.
+void CreateAppCommandRegistry(UpdaterScope scope,
+                              const std::wstring& app_id,
                               const std::wstring& cmd_id,
                               const std::wstring& cmd_line);
 
 // Returns the path to "cmd.exe" in `cmd_exe_command_line` based on the current
 // test scope:
-// * "%systemroot%\system32\cmd.exe" for user test scope.
-// * "%programfiles%\`temp_parent_dir`\cmd.exe" for system test scope.
+// * "%systemroot%\system32\cmd.exe" for user `scope`.
+// * "%programfiles%\`temp_parent_dir`\cmd.exe" for system `scope`.
 // `temp_parent_dir` is owned by the caller.
-void SetupCmdExe(base::CommandLine& cmd_exe_command_line,
+void SetupCmdExe(UpdaterScope scope,
+                 base::CommandLine& cmd_exe_command_line,
                  base::ScopedTempDir& temp_parent_dir);
 
 }  // namespace updater
diff --git a/chromecast/browser/BUILD.gn b/chromecast/browser/BUILD.gn
index 2d0bb29d..821f8e0ff 100644
--- a/chromecast/browser/BUILD.gn
+++ b/chromecast/browser/BUILD.gn
@@ -293,6 +293,7 @@
     "//ipc",
     "//media",
     "//media/gpu:buildflags",
+    "//media/mojo/mojom",
     "//media/mojo/mojom:remoting",
     "//media/mojo/services",
     "//mojo/public/cpp/bindings",
diff --git a/chromecast/cast_core/OWNERS b/chromecast/cast_core/OWNERS
index 6fb1227..1e8ca59 100644
--- a/chromecast/cast_core/OWNERS
+++ b/chromecast/cast_core/OWNERS
@@ -1,2 +1,3 @@
 mfoltz@chromium.org
 rwkeane@google.com
+vigeni@google.com
diff --git a/chromecast/media/audio/cast_audio_output_device.cc b/chromecast/media/audio/cast_audio_output_device.cc
index 80158ef1..6c67b6e 100644
--- a/chromecast/media/audio/cast_audio_output_device.cc
+++ b/chromecast/media/audio/cast_audio_output_device.cc
@@ -103,7 +103,7 @@
     media_pos_frames_ = 0;
     playback_started_ = false;
     paused_ = false;
-    push_timer_.AbandonAndStop();
+    push_timer_.Stop();
     output_connection_->StopPlayback();
   }
 
@@ -233,8 +233,9 @@
     }
 
     // No frames filled, schedule read immediately with a small delay.
-    push_timer_.Start(FROM_HERE, kNoBufferReadDelay, this,
-                      &Internal::TryPushBuffer);
+    push_timer_.Start(FROM_HERE, base::TimeTicks::Now() + kNoBufferReadDelay,
+                      this, &Internal::TryPushBuffer,
+                      base::ExactDeadline(true));
   }
 
   scoped_refptr<CastAudioOutputDevice> output_device_;
@@ -252,7 +253,7 @@
   bool paused_ = false;
   bool playback_started_ = false;
   bool backend_initialized_ = false;
-  base::OneShotTimer push_timer_;
+  base::DeadlineTimer push_timer_;
   std::unique_ptr<::media::AudioBus> audio_bus_;
 };
 
diff --git a/chromeos/crosapi/mojom/app_service_types.mojom b/chromeos/crosapi/mojom/app_service_types.mojom
index 470417d..8f9924e 100644
--- a/chromeos/crosapi/mojom/app_service_types.mojom
+++ b/chromeos/crosapi/mojom/app_service_types.mojom
@@ -445,6 +445,7 @@
   kNotifications                  = 4,
   [MinVersion=9] kContacts        = 5,
   [MinVersion=9] kStorage         = 6,
+  [MinVersion=10] kFileHandling   = 7,
 };
 
 [Stable]
diff --git a/chromeos/crosapi/mojom/app_service_types_mojom_traits.cc b/chromeos/crosapi/mojom/app_service_types_mojom_traits.cc
index 054c3bb..c46fada 100644
--- a/chromeos/crosapi/mojom/app_service_types_mojom_traits.cc
+++ b/chromeos/crosapi/mojom/app_service_types_mojom_traits.cc
@@ -1038,6 +1038,8 @@
       return crosapi::mojom::PermissionType::kContacts;
     case apps::PermissionType::kStorage:
       return crosapi::mojom::PermissionType::kStorage;
+    case apps::PermissionType::kFileHandling:
+      return crosapi::mojom::PermissionType::kFileHandling;
     case apps::PermissionType::kPrinting:
       NOTREACHED();
       return crosapi::mojom::PermissionType::kUnknown;
@@ -1070,6 +1072,9 @@
     case crosapi::mojom::PermissionType::kStorage:
       *output = apps::PermissionType::kStorage;
       return true;
+    case crosapi::mojom::PermissionType::kFileHandling:
+      *output = apps::PermissionType::kFileHandling;
+      return true;
   }
 
   NOTREACHED();
diff --git a/chromeos/crosapi/mojom/app_service_types_mojom_traits_unittest.cc b/chromeos/crosapi/mojom/app_service_types_mojom_traits_unittest.cc
index 68f3ca9a..a7caea9 100644
--- a/chromeos/crosapi/mojom/app_service_types_mojom_traits_unittest.cc
+++ b/chromeos/crosapi/mojom/app_service_types_mojom_traits_unittest.cc
@@ -1099,6 +1099,16 @@
         permission, output));
     EXPECT_EQ(*permission, *output);
   }
+  {
+    auto permission = std::make_unique<apps::Permission>(
+        apps::PermissionType::kFileHandling,
+        std::make_unique<apps::PermissionValue>(true),
+        /*is_managed=*/false);
+    apps::PermissionPtr output;
+    ASSERT_TRUE(mojo::test::SerializeAndDeserialize<crosapi::mojom::Permission>(
+        permission, output));
+    EXPECT_EQ(*permission, *output);
+  }
 }
 
 // Test that serialization and deserialization works with updating
diff --git a/chromeos/dbus/common/BUILD.gn b/chromeos/dbus/common/BUILD.gn
index 3b71144..5c58057 100644
--- a/chromeos/dbus/common/BUILD.gn
+++ b/chromeos/dbus/common/BUILD.gn
@@ -20,7 +20,6 @@
     "blocking_method_caller.cc",
     "blocking_method_caller.h",
     "dbus_client.h",
-    "dbus_client_implementation_type.h",
     "dbus_method_call_status.h",
     "pipe_reader.cc",
     "pipe_reader.h",
diff --git a/chromeos/dbus/common/dbus_client_implementation_type.h b/chromeos/dbus/common/dbus_client_implementation_type.h
deleted file mode 100644
index f123bb3..0000000
--- a/chromeos/dbus/common/dbus_client_implementation_type.h
+++ /dev/null
@@ -1,18 +0,0 @@
-// 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.
-
-#ifndef CHROMEOS_DBUS_COMMON_DBUS_CLIENT_IMPLEMENTATION_TYPE_H_
-#define CHROMEOS_DBUS_COMMON_DBUS_CLIENT_IMPLEMENTATION_TYPE_H_
-
-namespace chromeos {
-
-// An enum to describe the desired type of D-Bus client implemenation.
-enum DBusClientImplementationType {
-  REAL_DBUS_CLIENT_IMPLEMENTATION,
-  FAKE_DBUS_CLIENT_IMPLEMENTATION,
-};
-
-}  // namespace chromeos
-
-#endif  // CHROMEOS_DBUS_COMMON_DBUS_CLIENT_IMPLEMENTATION_TYPE_H_
diff --git a/chromeos/dbus/dbus_clients_browser.cc b/chromeos/dbus/dbus_clients_browser.cc
index 3821c6cb..8fd5ad5 100644
--- a/chromeos/dbus/dbus_clients_browser.cc
+++ b/chromeos/dbus/dbus_clients_browser.cc
@@ -19,7 +19,6 @@
 #include "chromeos/dbus/cec_service/fake_cec_service_client.h"
 #include "chromeos/dbus/chunneld/chunneld_client.h"
 #include "chromeos/dbus/chunneld/fake_chunneld_client.h"
-#include "chromeos/dbus/common/dbus_client_implementation_type.h"
 #include "chromeos/dbus/cros_disks/cros_disks_client.h"
 #include "chromeos/dbus/cros_disks/fake_cros_disks_client.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
@@ -41,7 +40,6 @@
 #include "chromeos/dbus/runtime_probe/runtime_probe_client.h"
 #include "chromeos/dbus/smbprovider/fake_smb_provider_client.h"
 #include "chromeos/dbus/smbprovider/smb_provider_client.h"
-#include "chromeos/dbus/update_engine/update_engine_client.h"
 #include "chromeos/dbus/virtual_file_provider/fake_virtual_file_provider_client.h"
 #include "chromeos/dbus/virtual_file_provider/virtual_file_provider_client.h"
 
@@ -60,13 +58,6 @@
 #endif  // USE_REAL_DBUS_CLIENTS
 
 DBusClientsBrowser::DBusClientsBrowser(bool use_real_clients) {
-  // TODO(hashimoto): Use CREATE_DBUS_CLIENT for all clients after removing
-  // DBusClientImplementationType and converting all Create() methods to return
-  // std::unique_ptr. crbug.com/952745
-  const DBusClientImplementationType client_impl_type =
-      use_real_clients ? REAL_DBUS_CLIENT_IMPLEMENTATION
-                       : FAKE_DBUS_CLIENT_IMPLEMENTATION;
-
   arc_data_snapshotd_client_ =
       CREATE_DBUS_CLIENT(ArcDataSnapshotdClient, use_real_clients);
   arc_keymaster_client_ =
@@ -92,12 +83,6 @@
       CREATE_DBUS_CLIENT(RuntimeProbeClient, use_real_clients);
   smb_provider_client_ =
       CREATE_DBUS_CLIENT(SmbProviderClient, use_real_clients);
-
-  // TODO(crbug.com/1229048): Resolve among the 3 implementations of
-  // UpdateEngineClient and use CREATE_DBUS_CLIENT, or comment on why this
-  // special case (that doesn't use CREATE_DBUS_CLIENT) exists.
-  update_engine_client_.reset(UpdateEngineClient::Create(client_impl_type));
-
   virtual_file_provider_client_ =
       CREATE_DBUS_CLIENT(VirtualFileProviderClient, use_real_clients);
 }
@@ -123,7 +108,6 @@
   oobe_configuration_client_->Init(system_bus);
   runtime_probe_client_->Init(system_bus);
   smb_provider_client_->Init(system_bus);
-  update_engine_client_->Init(system_bus);
   virtual_file_provider_client_->Init(system_bus);
 }
 
diff --git a/chromeos/dbus/dbus_clients_browser.h b/chromeos/dbus/dbus_clients_browser.h
index e4b16b2e..23703a3 100644
--- a/chromeos/dbus/dbus_clients_browser.h
+++ b/chromeos/dbus/dbus_clients_browser.h
@@ -31,7 +31,6 @@
 class OobeConfigurationClient;
 class RuntimeProbeClient;
 class SmbProviderClient;
-class UpdateEngineClient;
 class VirtualFileProviderClient;
 
 // Owns D-Bus clients.
@@ -71,7 +70,6 @@
   std::unique_ptr<OobeConfigurationClient> oobe_configuration_client_;
   std::unique_ptr<RuntimeProbeClient> runtime_probe_client_;
   std::unique_ptr<SmbProviderClient> smb_provider_client_;
-  std::unique_ptr<UpdateEngineClient> update_engine_client_;
   std::unique_ptr<VirtualFileProviderClient> virtual_file_provider_client_;
 };
 
diff --git a/chromeos/dbus/dbus_thread_manager.cc b/chromeos/dbus/dbus_thread_manager.cc
index 2500105..209854d9 100644
--- a/chromeos/dbus/dbus_thread_manager.cc
+++ b/chromeos/dbus/dbus_thread_manager.cc
@@ -117,7 +117,7 @@
 }
 
 UpdateEngineClient* DBusThreadManager::GetUpdateEngineClient() {
-  RETURN_DBUS_CLIENT(update_engine_client_);
+  return UpdateEngineClient::Get();
 }
 
 VirtualFileProviderClient* DBusThreadManager::GetVirtualFileProviderClient() {
@@ -223,9 +223,4 @@
   smb_provider_client_ = std::move(client);
 }
 
-void DBusThreadManagerSetter::SetUpdateEngineClient(
-    std::unique_ptr<UpdateEngineClient> client) {
-  update_engine_client_ = std::move(client);
-}
-
 }  // namespace chromeos
diff --git a/chromeos/dbus/dbus_thread_manager.h b/chromeos/dbus/dbus_thread_manager.h
index b5f02e7..4178014 100644
--- a/chromeos/dbus/dbus_thread_manager.h
+++ b/chromeos/dbus/dbus_thread_manager.h
@@ -111,7 +111,6 @@
   void SetImageBurnerClient(std::unique_ptr<ImageBurnerClient> client);
   void SetImageLoaderClient(std::unique_ptr<ImageLoaderClient> client);
   void SetSmbProviderClient(std::unique_ptr<SmbProviderClient> client);
-  void SetUpdateEngineClient(std::unique_ptr<UpdateEngineClient> client);
 
  private:
   friend class DBusThreadManager;
@@ -128,7 +127,6 @@
   std::unique_ptr<ImageBurnerClient> image_burner_client_;
   std::unique_ptr<ImageLoaderClient> image_loader_client_;
   std::unique_ptr<SmbProviderClient> smb_provider_client_;
-  std::unique_ptr<UpdateEngineClient> update_engine_client_;
 };
 
 }  // namespace chromeos
diff --git a/chromeos/dbus/dbus_thread_manager_unittest.cc b/chromeos/dbus/dbus_thread_manager_unittest.cc
index a518edd..987b6534 100644
--- a/chromeos/dbus/dbus_thread_manager_unittest.cc
+++ b/chromeos/dbus/dbus_thread_manager_unittest.cc
@@ -26,7 +26,6 @@
   EXPECT_TRUE(manager->GetDebugDaemonClient());
   EXPECT_TRUE(manager->GetEasyUnlockClient());
   EXPECT_TRUE(manager->GetImageBurnerClient());
-  EXPECT_TRUE(manager->GetUpdateEngineClient());
 
   DBusThreadManager::Shutdown();
   EXPECT_FALSE(DBusThreadManager::IsInitialized());
diff --git a/chromeos/dbus/dlcservice/dlcservice_client.h b/chromeos/dbus/dlcservice/dlcservice_client.h
index 0a7e62d..a0bc5bc 100644
--- a/chromeos/dbus/dlcservice/dlcservice_client.h
+++ b/chromeos/dbus/dlcservice/dlcservice_client.h
@@ -14,7 +14,6 @@
 #include "base/component_export.h"
 #include "base/observer_list_types.h"
 #include "chromeos/dbus/common/dbus_client.h"
-#include "chromeos/dbus/common/dbus_client_implementation_type.h"
 #include "chromeos/dbus/dlcservice/dlcservice.pb.h"
 #include "dbus/message.h"
 #include "third_party/cros_system_api/dbus/dlcservice/dbus-constants.h"
diff --git a/chromeos/dbus/update_engine/update_engine_client.cc b/chromeos/dbus/update_engine/update_engine_client.cc
index 0f79ed13..1e637209 100644
--- a/chromeos/dbus/update_engine/update_engine_client.cc
+++ b/chromeos/dbus/update_engine/update_engine_client.cc
@@ -20,6 +20,7 @@
 #include "base/task/single_thread_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "chromeos/dbus/constants/dbus_switches.h"
+#include "chromeos/dbus/update_engine/fake_update_engine_client.h"
 #include "chromeos/dbus/util/version_loader.h"
 #include "dbus/bus.h"
 #include "dbus/message.h"
@@ -55,13 +56,13 @@
 // Version number of the image being installed during fake AU.
 const char kStubVersion[] = "1234.0.0.0";
 
+UpdateEngineClient* g_instance = nullptr;
+
 bool IsValidChannel(const std::string& channel) {
   return channel == kReleaseChannelDev || channel == kReleaseChannelBeta ||
          channel == kReleaseChannelStable;
 }
 
-}  // namespace
-
 // The UpdateEngineClient implementation used in production.
 class UpdateEngineClientImpl : public UpdateEngineClient {
  public:
@@ -264,7 +265,6 @@
                        std::move(callback)));
   }
 
- protected:
   void Init(dbus::Bus* bus) override {
     update_engine_proxy_ = bus->GetObjectProxy(
         update_engine::kUpdateEngineServiceName,
@@ -573,15 +573,15 @@
 
 // The UpdateEngineClient implementation used on Linux desktop,
 // which does nothing.
-class UpdateEngineClientStubImpl : public UpdateEngineClient {
+class UpdateEngineClientDesktopFake : public UpdateEngineClient {
  public:
-  UpdateEngineClientStubImpl()
+  UpdateEngineClientDesktopFake()
       : current_channel_(kReleaseChannelBeta),
         target_channel_(kReleaseChannelBeta) {}
 
-  UpdateEngineClientStubImpl(const UpdateEngineClientStubImpl&) = delete;
-  UpdateEngineClientStubImpl& operator=(const UpdateEngineClientStubImpl&) =
-      delete;
+  UpdateEngineClientDesktopFake(const UpdateEngineClientDesktopFake&) = delete;
+  UpdateEngineClientDesktopFake& operator=(
+      const UpdateEngineClientDesktopFake&) = delete;
 
   // UpdateEngineClient implementation:
   void Init(dbus::Bus* bus) override {}
@@ -614,7 +614,7 @@
     last_status_.set_is_enterprise_rollback(false);
     base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
         FROM_HERE,
-        base::BindOnce(&UpdateEngineClientStubImpl::StateTransition,
+        base::BindOnce(&UpdateEngineClientDesktopFake::StateTransition,
                        weak_factory_.GetWeakPtr(), apply_update),
         base::Milliseconds(kStateTransitionDefaultDelayMs));
   }
@@ -726,7 +726,7 @@
     if (last_status_.current_operation() != update_engine::Operation::IDLE) {
       base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
           FROM_HERE,
-          base::BindOnce(&UpdateEngineClientStubImpl::StateTransition,
+          base::BindOnce(&UpdateEngineClientDesktopFake::StateTransition,
                          weak_factory_.GetWeakPtr(), apply_update),
           base::Milliseconds(delay_ms));
     }
@@ -739,20 +739,43 @@
 
   update_engine::StatusResult last_status_;
 
-  base::WeakPtrFactory<UpdateEngineClientStubImpl> weak_factory_{this};
+  base::WeakPtrFactory<UpdateEngineClientDesktopFake> weak_factory_{this};
 };
 
-UpdateEngineClient::UpdateEngineClient() = default;
-
-UpdateEngineClient::~UpdateEngineClient() = default;
+}  // namespace
 
 // static
-UpdateEngineClient* UpdateEngineClient::Create(
-    DBusClientImplementationType type) {
-  if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
-    return new UpdateEngineClientImpl();
-  DCHECK_EQ(FAKE_DBUS_CLIENT_IMPLEMENTATION, type);
-  return new UpdateEngineClientStubImpl();
+UpdateEngineClient* UpdateEngineClient::Get() {
+  return g_instance;
+}
+
+// static
+void UpdateEngineClient::Initialize(dbus::Bus* bus) {
+  CHECK(bus);
+  (new UpdateEngineClientImpl())->Init(bus);
+}
+
+// static
+void UpdateEngineClient::InitializeFake() {
+  // Do not create a new fake if it was initialized early in a browser test to
+  // allow the test to set its own client.
+  if (g_instance)
+    return;
+
+  (new UpdateEngineClientDesktopFake())->Init(nullptr);
+}
+
+// static
+FakeUpdateEngineClient* UpdateEngineClient::InitializeFakeForTest() {
+  auto* client = new FakeUpdateEngineClient();
+  client->Init(nullptr);
+  return client;
+}
+
+// static
+void UpdateEngineClient::Shutdown() {
+  CHECK(g_instance);
+  delete g_instance;
 }
 
 // static
@@ -768,4 +791,14 @@
   return tix > cix;
 }
 
+UpdateEngineClient::UpdateEngineClient() {
+  CHECK(!g_instance);
+  g_instance = this;
+}
+
+UpdateEngineClient::~UpdateEngineClient() {
+  CHECK_EQ(g_instance, this);
+  g_instance = nullptr;
+}
+
 }  // namespace chromeos
diff --git a/chromeos/dbus/update_engine/update_engine_client.h b/chromeos/dbus/update_engine/update_engine_client.h
index f295cbe..c168d60 100644
--- a/chromeos/dbus/update_engine/update_engine_client.h
+++ b/chromeos/dbus/update_engine/update_engine_client.h
@@ -13,7 +13,6 @@
 #include "base/component_export.h"
 #include "base/time/time.h"
 #include "chromeos/dbus/common/dbus_client.h"
-#include "chromeos/dbus/common/dbus_client_implementation_type.h"
 #include "chromeos/dbus/update_engine/update_engine.pb.h"
 #include "dbus/message.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -21,6 +20,8 @@
 
 namespace chromeos {
 
+class FakeUpdateEngineClient;
+
 // UpdateEngineClient is used to communicate with the update engine.
 class COMPONENT_EXPORT(CHROMEOS_DBUS_UPDATE_ENGINE) UpdateEngineClient
     : public DBusClient {
@@ -56,11 +57,25 @@
     virtual void OnUpdateOverCellularOneTimePermissionGranted() {}
   };
 
+  // Returns the global instance if initialized. May return null.
+  static UpdateEngineClient* Get();
+
+  // Creates and initializes the global instance. |bus| must not be null.
+  static void Initialize(dbus::Bus* bus);
+
+  // Creates and initializes a fake global instance used on Linux desktop, if
+  // no instance already exists.
+  static void InitializeFake();
+
+  // Creates and initializes a fake global instance for unit tests.
+  static FakeUpdateEngineClient* InitializeFakeForTest();
+
+  // Destroys the global instance if it has been initialized.
+  static void Shutdown();
+
   UpdateEngineClient(const UpdateEngineClient&) = delete;
   UpdateEngineClient& operator=(const UpdateEngineClient&) = delete;
 
-  ~UpdateEngineClient() override;
-
   // Adds and removes the observer.
   virtual void AddObserver(Observer* observer) = 0;
   virtual void RemoveObserver(Observer* observer) = 0;
@@ -161,9 +176,6 @@
       int64_t update_size,
       UpdateOverCellularOneTimePermissionCallback callback) = 0;
 
-  // Creates the instance.
-  static UpdateEngineClient* Create(DBusClientImplementationType type);
-
   // Returns true if |target_channel| is more stable than |current_channel|.
   static bool IsTargetChannelMoreStable(const std::string& current_channel,
                                         const std::string& target_channel);
@@ -178,8 +190,9 @@
                                 IsFeatureEnabledCallback callback) = 0;
 
  protected:
-  // Create() should be used instead.
+  // Initialize() should be used instead.
   UpdateEngineClient();
+  ~UpdateEngineClient() override;
 };
 
 }  // namespace chromeos
diff --git a/chromeos/tast_control.gni b/chromeos/tast_control.gni
index 0e86afc..e163f0c6 100644
--- a/chromeos/tast_control.gni
+++ b/chromeos/tast_control.gni
@@ -229,9 +229,6 @@
   # https://crbug.com/1329761
   "policy.DefaultSerialGuardSetting",
 
-  # https://crbug.com/1335176
-  "policy.ScreenBrightnessPercent",
-
   # https://crbug.com/1334354
   "arc.Boot.vm",
   "arc.ChromeCrash.vm_logged_in",
diff --git a/components/BUILD.gn b/components/BUILD.gn
index a4577d7..758f9822 100644
--- a/components/BUILD.gn
+++ b/components/BUILD.gn
@@ -1047,6 +1047,7 @@
       "//components/browser_ui/widget/android:junit",
       "//components/content_capture/android/junit:components_content_capture_junit_tests",
       "//components/crash/android:junit",
+      "//components/download/network:junit",
       "//components/embedder_support/android:components_embedder_support_junit_tests",
       "//components/gcm_driver/android:components_gcm_driver_junit_tests",
       "//components/image_fetcher:junit",
diff --git a/components/autofill_assistant/browser/actions/action.cc b/components/autofill_assistant/browser/actions/action.cc
index 8103f5a..681b7d9 100644
--- a/components/autofill_assistant/browser/actions/action.cc
+++ b/components/autofill_assistant/browser/actions/action.cc
@@ -282,6 +282,9 @@
     case ActionProto::ActionInfoCase::kSetNativeValue:
       out << "SetNativeValue";
       break;
+    case ActionProto::ActionInfoCase::kSetNativeChecked:
+      out << "SetNativeChecked";
+      break;
     case ActionProto::ActionInfoCase::ACTION_INFO_NOT_SET:
       out << "ACTION_INFO_NOT_SET";
       break;
diff --git a/components/autofill_assistant/browser/dom_action.proto b/components/autofill_assistant/browser/dom_action.proto
index c3c8805e..f58f8484 100644
--- a/components/autofill_assistant/browser/dom_action.proto
+++ b/components/autofill_assistant/browser/dom_action.proto
@@ -229,3 +229,12 @@
   // The value to set.
   optional TextValue value = 2;
 }
+
+// Set the |checked| property of a checkbox or radio button.
+message SetNativeCheckedProto {
+  // The target element. Must be an instance of a |WebInputElement|, and must
+  // have a settable |checked| property, otherwise the action will fail.
+  optional ClientIdProto client_id = 1;
+  // The value to set.
+  optional bool checked = 2;
+}
\ No newline at end of file
diff --git a/components/autofill_assistant/browser/protocol_utils.cc b/components/autofill_assistant/browser/protocol_utils.cc
index 30fc7f0..58b946b 100644
--- a/components/autofill_assistant/browser/protocol_utils.cc
+++ b/components/autofill_assistant/browser/protocol_utils.cc
@@ -469,6 +469,12 @@
               action.set_native_value().value(),
               base::BindOnce(&WebController::SetNativeValue,
                              delegate->GetWebController()->GetWeakPtr())));
+    case ActionProto::ActionInfoCase::kSetNativeChecked:
+      return PerformOnSingleElementAction::WithClientId(
+          delegate, action, action.set_native_checked().client_id(),
+          base::BindOnce(&WebController::SetNativeChecked,
+                         delegate->GetWebController()->GetWeakPtr(),
+                         action.set_native_checked().checked()));
     case ActionProto::ActionInfoCase::ACTION_INFO_NOT_SET: {
       VLOG(1) << "Encountered action with ACTION_INFO_NOT_SET";
       return std::make_unique<UnsupportedAction>(delegate, action);
@@ -741,6 +747,10 @@
       success = ParseActionFromString(action_id, bytes, error_message,
                                       proto.mutable_set_native_value());
       break;
+    case ActionProto::ActionInfoCase::kSetNativeChecked:
+      success = ParseActionFromString(action_id, bytes, error_message,
+                                      proto.mutable_set_native_checked());
+      break;
     case ActionProto::ActionInfoCase::kRegisterPasswordResetRequest:
       success = ParseActionFromString(
           action_id, bytes, error_message,
diff --git a/components/autofill_assistant/browser/service.proto b/components/autofill_assistant/browser/service.proto
index 4ddaacf..ddd4d21 100644
--- a/components/autofill_assistant/browser/service.proto
+++ b/components/autofill_assistant/browser/service.proto
@@ -1062,6 +1062,7 @@
     RegisterPasswordResetRequestProto register_password_reset_request = 94;
     ExternalActionProto external_action = 95;
     SetNativeValueProto set_native_value = 96;
+    SetNativeCheckedProto set_native_checked = 97;
   }
 
   // Set to true to make the client remove any contextual information if the
diff --git a/components/autofill_assistant/browser/web/mock_autofill_assistant_agent.h b/components/autofill_assistant/browser/web/mock_autofill_assistant_agent.h
index 4b3fca57..2da117a 100644
--- a/components/autofill_assistant/browser/web/mock_autofill_assistant_agent.h
+++ b/components/autofill_assistant/browser/web/mock_autofill_assistant_agent.h
@@ -41,6 +41,13 @@
                bool send_events,
                base::OnceCallback<void(bool)> callback),
               (override));
+  MOCK_METHOD(void,
+              SetElementChecked,
+              (int32_t backend_node_id,
+               bool checked,
+               bool send_events,
+               base::OnceCallback<void(bool)> callback),
+              (override));
 
  private:
   mojo::AssociatedReceiverSet<mojom::AutofillAssistantAgent> receivers_;
diff --git a/components/autofill_assistant/browser/web/web_controller.cc b/components/autofill_assistant/browser/web/web_controller.cc
index 3a06cd59..ad663f0 100644
--- a/components/autofill_assistant/browser/web/web_controller.cc
+++ b/components/autofill_assistant/browser/web/web_controller.cc
@@ -1625,21 +1625,26 @@
       WebControllerErrorInfoProto::EXECUTE_JS, std::move(callback));
 }
 
-void WebController::SetNativeValue(
-    const std::string& value,
-    const ElementFinderResult& element,
-    base::OnceCallback<void(const ClientStatus&)> callback) {
+ContentAutofillAssistantDriver* WebController::GetDriverForElement(
+    const ElementFinderResult& element) const {
   if (!element.backend_node_id()) {
     DVLOG(1) << __func__
              << "No backend node id on element intended for native execution.";
-    std::move(callback).Run(UnexpectedErrorStatus(__FILE__, __LINE__));
-    return;
+    return nullptr;
   }
 
   auto* render_frame_host = element.render_frame_host();
   DCHECK(render_frame_host);
-  auto* driver = ContentAutofillAssistantDriver::GetOrCreateForRenderFrameHost(
+
+  return ContentAutofillAssistantDriver::GetOrCreateForRenderFrameHost(
       render_frame_host, annotate_dom_model_service_);
+}
+
+void WebController::SetNativeValue(
+    const std::string& value,
+    const ElementFinderResult& element,
+    base::OnceCallback<void(const ClientStatus&)> callback) {
+  ContentAutofillAssistantDriver* driver = GetDriverForElement(element);
   if (!driver) {
     std::move(callback).Run(UnexpectedErrorStatus(__FILE__, __LINE__));
     return;
@@ -1647,11 +1652,27 @@
   driver->GetAutofillAssistantAgent()->SetElementValue(
       *element.backend_node_id(), base::UTF8ToUTF16(value),
       /* send_events= */ true,
-      base::BindOnce(&WebController::OnSetElementValue,
+      base::BindOnce(&WebController::OnSetNativeExecution,
                      weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
 }
 
-void WebController::OnSetElementValue(
+void WebController::SetNativeChecked(
+    bool checked,
+    const ElementFinderResult& element,
+    base::OnceCallback<void(const ClientStatus&)> callback) {
+  ContentAutofillAssistantDriver* driver = GetDriverForElement(element);
+  if (!driver) {
+    std::move(callback).Run(UnexpectedErrorStatus(__FILE__, __LINE__));
+    return;
+  }
+  driver->GetAutofillAssistantAgent()->SetElementChecked(
+      *element.backend_node_id(), checked,
+      /* send_events= */ true,
+      base::BindOnce(&WebController::OnSetNativeExecution,
+                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
+}
+
+void WebController::OnSetNativeExecution(
     base::OnceCallback<void(const ClientStatus&)> callback,
     bool success) const {
   std::move(callback).Run(success ? OkClientStatus()
diff --git a/components/autofill_assistant/browser/web/web_controller.h b/components/autofill_assistant/browser/web/web_controller.h
index 7914f7e5..fc76b970d9 100644
--- a/components/autofill_assistant/browser/web/web_controller.h
+++ b/components/autofill_assistant/browser/web/web_controller.h
@@ -52,6 +52,7 @@
 }  // namespace content
 
 namespace autofill_assistant {
+class ContentAutofillAssistantDriver;
 class ElementFinderResult;
 enum class ElementFinderResultType;
 
@@ -390,6 +391,11 @@
       const ElementFinderResult& element,
       base::OnceCallback<void(const ClientStatus&)> callback);
 
+  virtual void SetNativeChecked(
+      bool checked,
+      const ElementFinderResult& element,
+      base::OnceCallback<void(const ClientStatus&)> callback);
+
   virtual base::WeakPtr<WebController> GetWeakPtr() const;
 
  private:
@@ -530,8 +536,14 @@
   void OnDispatchJsEvent(base::OnceCallback<void(const ClientStatus&)> callback,
                          const DevtoolsClient::ReplyStatus& reply_status,
                          std::unique_ptr<runtime::EvaluateResult> result) const;
-  void OnSetElementValue(base::OnceCallback<void(const ClientStatus&)> callback,
-                         bool success) const;
+  void OnSetNativeExecution(
+      base::OnceCallback<void(const ClientStatus&)> callback,
+      bool success) const;
+  // Get the driver for the given element finder results. Will return a nullptr
+  // if the driver is not available. Requires that the element has a backend
+  // node id.
+  autofill_assistant::ContentAutofillAssistantDriver* GetDriverForElement(
+      const ElementFinderResult& element) const;
 
   // Weak pointer is fine here since it must outlive this web controller, which
   // is guaranteed by the owner of this object.
diff --git a/components/autofill_assistant/browser/web/web_controller_browsertest.cc b/components/autofill_assistant/browser/web/web_controller_browsertest.cc
index 36f400f..09e5f825 100644
--- a/components/autofill_assistant/browser/web/web_controller_browsertest.cc
+++ b/components/autofill_assistant/browser/web/web_controller_browsertest.cc
@@ -3628,4 +3628,32 @@
   EXPECT_EQ(ACTION_APPLIED, fill_status.proto_status());
 }
 
+IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest,
+                       SetElementCheckedThroughNative) {
+  ClientStatus element_status;
+  ElementFinderResult input;
+  FindElement(Selector({"#option1"}), &element_status, &input);
+  ASSERT_EQ(ACTION_APPLIED, element_status.proto_status());
+
+  int backend_node_id;
+  ASSERT_EQ(ACTION_APPLIED,
+            GetBackendNodeId(input, &backend_node_id).proto_status());
+
+  EXPECT_CALL(autofill_assistant_agent_,
+              SetElementChecked(backend_node_id, true,
+                                /* send_events= */ true, _))
+      .WillOnce(RunOnceCallback<3>(true));
+
+  ClientStatus fill_status;
+  base::RunLoop run_loop;
+  web_controller_->SetNativeChecked(
+      true, input,
+      base::BindOnce(&WebControllerBrowserTest::OnClientStatus,
+                     base::Unretained(this), run_loop.QuitClosure(),
+                     &fill_status));
+  run_loop.Run();
+
+  EXPECT_EQ(ACTION_APPLIED, fill_status.proto_status());
+}
+
 }  // namespace autofill_assistant
diff --git a/components/autofill_assistant/content/common/autofill_assistant_agent.mojom b/components/autofill_assistant/content/common/autofill_assistant_agent.mojom
index 9c1c9160..2816b95 100644
--- a/components/autofill_assistant/content/common/autofill_assistant_agent.mojom
+++ b/components/autofill_assistant/content/common/autofill_assistant_agent.mojom
@@ -25,4 +25,10 @@
   SetElementValue(int32 backend_node_id, mojo_base.mojom.String16 value,
                   bool send_events)
       => (bool success);
+
+  // Set the checked property on a web input element.
+  // The element should be a checkable WebInputElement: a checkbox or a
+  // radio button.
+  SetElementChecked(int32 backend_node_id, bool checked, bool send_events)
+      => (bool success);
 };
diff --git a/components/autofill_assistant/content/renderer/autofill_assistant_agent.cc b/components/autofill_assistant/content/renderer/autofill_assistant_agent.cc
index cdf09d9..682c36e 100644
--- a/components/autofill_assistant/content/renderer/autofill_assistant_agent.cc
+++ b/components/autofill_assistant/content/renderer/autofill_assistant_agent.cc
@@ -16,6 +16,7 @@
 #include "third_party/blink/public/web/modules/autofill_assistant/node_signals.h"
 #include "third_party/blink/public/web/web_element.h"
 #include "third_party/blink/public/web/web_form_control_element.h"
+#include "third_party/blink/public/web/web_input_element.h"
 #include "third_party/blink/public/web/web_local_frame.h"
 #include "third_party/protobuf/src/google/protobuf/repeated_field.h"
 
@@ -266,4 +267,44 @@
   std::move(callback).Run(true);
 }
 
+void AutofillAssistantAgent::SetElementChecked(
+    const int32_t backend_node_id,
+    bool checked,
+    bool send_events,
+    SetElementCheckedCallback callback) {
+  blink::WebLocalFrame* frame = render_frame()->GetWebFrame();
+  if (!frame) {
+    VLOG(1) << "Failed to set Element checked state, no frame.";
+    std::move(callback).Run(false);
+    return;
+  }
+
+  blink::WebElement target_element =
+      frame->GetDocument().GetElementByDevToolsNodeId(backend_node_id);
+  if (target_element.IsNull()) {
+    VLOG(3) << "Failed to set Element checked state, invalid target.";
+    std::move(callback).Run(false);
+    return;
+  }
+
+  blink::WebInputElement web_input_element =
+      target_element.DynamicTo<blink::WebInputElement>();
+  if (web_input_element.IsNull()) {
+    VLOG(3) << "Failed to set Element checked state, target is not an input "
+               "element.";
+    std::move(callback).Run(false);
+    return;
+  }
+
+  if (!web_input_element.IsCheckbox() && !web_input_element.IsRadioButton()) {
+    VLOG(3) << "Failed to set Element checked state, target is not a checkbox "
+               "or a radio button.";
+    std::move(callback).Run(false);
+    return;
+  }
+
+  web_input_element.SetChecked(checked, send_events);
+  std::move(callback).Run(true);
+}
+
 }  // namespace autofill_assistant
diff --git a/components/autofill_assistant/content/renderer/autofill_assistant_agent.h b/components/autofill_assistant/content/renderer/autofill_assistant_agent.h
index 41773f1..c5257116 100644
--- a/components/autofill_assistant/content/renderer/autofill_assistant_agent.h
+++ b/components/autofill_assistant/content/renderer/autofill_assistant_agent.h
@@ -51,6 +51,10 @@
                        const std::u16string& value,
                        bool send_events,
                        SetElementValueCallback callback) override;
+  void SetElementChecked(int32_t backend_node_id,
+                         bool checked,
+                         bool send_events,
+                         SetElementCheckedCallback callback) override;
 
  private:
   // content::RenderFrameObserver:
diff --git a/components/autofill_assistant/content/renderer/autofill_assistant_agent_browsertest.cc b/components/autofill_assistant/content/renderer/autofill_assistant_agent_browsertest.cc
index 690a33a..0343121 100644
--- a/components/autofill_assistant/content/renderer/autofill_assistant_agent_browsertest.cc
+++ b/components/autofill_assistant/content/renderer/autofill_assistant_agent_browsertest.cc
@@ -23,6 +23,7 @@
 #include "third_party/blink/public/web/web_document.h"
 #include "third_party/blink/public/web/web_element.h"
 #include "third_party/blink/public/web/web_form_control_element.h"
+#include "third_party/blink/public/web/web_input_element.h"
 #include "third_party/blink/public/web/web_local_frame.h"
 
 namespace autofill_assistant {
@@ -244,6 +245,60 @@
   base::RunLoop().RunUntilIdle();
 }
 
+TEST_F(AutofillAssistantAgentBrowserTest, SetElementCheckedForCheckbox) {
+  LoadHTML(R"(<input type="checkbox" id="checkbox">)");
+
+  base::MockCallback<base::OnceCallback<void(bool)>> callback;
+  EXPECT_CALL(callback, Run(true));
+
+  const auto web_element =
+      GetMainRenderFrame()
+          ->GetWebFrame()
+          ->GetDocument()
+          .GetElementById(blink::WebString::FromUTF8("checkbox"))
+          .To<blink::WebInputElement>();
+  autofill_assistant_agent_->SetElementChecked(
+      web_element.GetDevToolsNodeIdForTest(), true,
+      /* send_events= */ true, callback.Get());
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(web_element.IsChecked(), true);
+}
+
+TEST_F(AutofillAssistantAgentBrowserTest, SetElementCheckedForRadioButton) {
+  LoadHTML(R"(<input type="radio" id="radio_button">)");
+
+  base::MockCallback<base::OnceCallback<void(bool)>> callback;
+  EXPECT_CALL(callback, Run(true));
+
+  const auto web_element =
+      GetMainRenderFrame()
+          ->GetWebFrame()
+          ->GetDocument()
+          .GetElementById(blink::WebString::FromUTF8("radio_button"))
+          .To<blink::WebInputElement>();
+  autofill_assistant_agent_->SetElementChecked(
+      web_element.GetDevToolsNodeIdForTest(), true,
+      /* send_events= */ true, callback.Get());
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(web_element.IsChecked(), true);
+}
+
+TEST_F(AutofillAssistantAgentBrowserTest, SetCheckedFailsForNonCheckableInput) {
+  LoadHTML(R"(<input type="text" id="text_input">)");
+
+  base::MockCallback<base::OnceCallback<void(bool)>> callback;
+  EXPECT_CALL(callback, Run(false));
+
+  const auto web_element =
+      GetMainRenderFrame()->GetWebFrame()->GetDocument().GetElementById(
+          blink::WebString::FromUTF8("text_input"));
+
+  autofill_assistant_agent_->SetElementChecked(
+      web_element.GetDevToolsNodeIdForTest(), true,
+      /* send_events= */ true, callback.Get());
+  base::RunLoop().RunUntilIdle();
+}
+
 TEST_F(AutofillAssistantAgentBrowserTest, SetElementValueForInput) {
   LoadHTML(R"(<input id="id">)");
 
diff --git a/components/browser_ui/client_certificate/OWNERS b/components/browser_ui/client_certificate/OWNERS
index d6f39100..f05dc1c 100644
--- a/components/browser_ui/client_certificate/OWNERS
+++ b/components/browser_ui/client_certificate/OWNERS
@@ -1,5 +1,5 @@
 # Primary:
-dmcardle@chromium.org
+davidben@chromium.org
 
 # Secondary:
 file://chrome/android/OWNERS
diff --git a/components/browser_ui/settings/DEPS b/components/browser_ui/settings/DEPS
index d21e072..421591cd 100644
--- a/components/browser_ui/settings/DEPS
+++ b/components/browser_ui/settings/DEPS
@@ -1,3 +1,4 @@
 include_rules = [
+  "+content/public/test/android/javatests",
   "+ui/android",
 ]
diff --git a/components/browser_ui/settings/android/BUILD.gn b/components/browser_ui/settings/android/BUILD.gn
index 967a91bc..5ffce69 100644
--- a/components/browser_ui/settings/android/BUILD.gn
+++ b/components/browser_ui/settings/android/BUILD.gn
@@ -76,3 +76,37 @@
     "java/res/values/styles.xml",
   ]
 }
+
+android_library("unit_device_javatests") {
+  testonly = true
+  sources = [
+    "widget/java/src/org/chromium/components/browser_ui/settings/ChromeBasePreferenceTest.java",
+    "widget/java/src/org/chromium/components/browser_ui/settings/ChromeImageViewPreferenceTest.java",
+    "widget/java/src/org/chromium/components/browser_ui/settings/ManagedPreferencesUtilsTest.java",
+  ]
+  deps = [
+    ":java",
+    ":test_support_java",
+    "//base:base_java_test_support",
+    "//content/public/test/android:content_java_test_support",
+    "//third_party/android_deps:espresso_java",
+    "//third_party/android_deps:guava_android_java",
+    "//third_party/android_support_test_runner:rules_java",
+    "//third_party/android_support_test_runner:runner_java",
+    "//third_party/androidx:androidx_fragment_fragment_java",
+    "//third_party/androidx:androidx_preference_preference_java",
+    "//third_party/androidx:androidx_test_runner_java",
+    "//third_party/hamcrest:hamcrest_java",
+    "//third_party/junit",
+    "//ui/android:ui_java_test_support",
+    "//ui/android:ui_no_recycler_view_java",
+  ]
+}
+
+android_library("test_support_java") {
+  testonly = true
+
+  sources = [ "widget/java/src/org/chromium/components/browser_ui/settings/PlaceholderSettingsForTest.java" ]
+
+  deps = [ "//third_party/androidx:androidx_preference_preference_java" ]
+}
diff --git a/components/browser_ui/settings/android/java/src/org/chromium/components/browser_ui/settings/ManagedPreferencesUtils.java b/components/browser_ui/settings/android/java/src/org/chromium/components/browser_ui/settings/ManagedPreferencesUtils.java
index 8386b0b6..472ad85 100644
--- a/components/browser_ui/settings/android/java/src/org/chromium/components/browser_ui/settings/ManagedPreferencesUtils.java
+++ b/components/browser_ui/settings/android/java/src/org/chromium/components/browser_ui/settings/ManagedPreferencesUtils.java
@@ -26,6 +26,12 @@
  * Utilities and common methods to handle settings managed by policies.
  */
 public class ManagedPreferencesUtils {
+    private static Toast showToastWithResourceId(Context context, @StringRes int resId) {
+        Toast toast = Toast.makeText(context, context.getString(resId), Toast.LENGTH_LONG);
+        toast.show();
+        return toast;
+    }
+
     /**
      * Shows a toast indicating that the previous action is managed by the system administrator.
      *
@@ -33,10 +39,8 @@
      *
      * @param context The context where the Toast will be shown.
      */
-    public static void showManagedByAdministratorToast(Context context) {
-        Toast.makeText(context, context.getString(R.string.managed_by_your_organization),
-                     Toast.LENGTH_LONG)
-                .show();
+    public static Toast showManagedByAdministratorToast(Context context) {
+        return showToastWithResourceId(context, R.string.managed_by_your_organization);
     }
 
     /**
@@ -46,11 +50,9 @@
      *
      * @param context The context where the Toast will be shown.
      */
-    public static void showManagedByParentToast(
+    public static Toast showManagedByParentToast(
             Context context, @Nullable ManagedPreferenceDelegate delegate) {
-        Toast.makeText(context, context.getString(getManagedByParentStringRes(delegate)),
-                     Toast.LENGTH_LONG)
-                .show();
+        return showToastWithResourceId(context, getManagedByParentStringRes(delegate));
     }
 
     /**
@@ -59,10 +61,8 @@
      *
      * @param context The context where the Toast will be shown.
      */
-    public static void showManagedSettingsCannotBeResetToast(Context context) {
-        Toast.makeText(context, context.getString(R.string.managed_settings_cannot_be_reset),
-                     Toast.LENGTH_LONG)
-                .show();
+    public static Toast showManagedSettingsCannotBeResetToast(Context context) {
+        return showToastWithResourceId(context, R.string.managed_settings_cannot_be_reset);
     }
 
     /**
diff --git a/chrome/browser/settings/android/java/src/org/chromium/chrome/browser/settings/ChromeBasePreferenceTest.java b/components/browser_ui/settings/android/widget/java/src/org/chromium/components/browser_ui/settings/ChromeBasePreferenceTest.java
similarity index 75%
rename from chrome/browser/settings/android/java/src/org/chromium/chrome/browser/settings/ChromeBasePreferenceTest.java
rename to components/browser_ui/settings/android/widget/java/src/org/chromium/components/browser_ui/settings/ChromeBasePreferenceTest.java
index df2c257..9afd531c 100644
--- a/chrome/browser/settings/android/java/src/org/chromium/chrome/browser/settings/ChromeBasePreferenceTest.java
+++ b/components/browser_ui/settings/android/widget/java/src/org/chromium/components/browser_ui/settings/ChromeBasePreferenceTest.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.settings;
+package org.chromium.components.browser_ui.settings;
 
 import static androidx.test.espresso.Espresso.onView;
 import static androidx.test.espresso.assertion.ViewAssertions.matches;
@@ -14,8 +14,6 @@
 import static org.hamcrest.Matchers.not;
 import static org.hamcrest.Matchers.stringContainsInOrder;
 
-import android.content.Context;
-
 import androidx.preference.PreferenceFragmentCompat;
 import androidx.preference.PreferenceScreen;
 import androidx.test.espresso.ViewInteraction;
@@ -23,47 +21,53 @@
 
 import com.google.common.collect.ImmutableList;
 
+import org.hamcrest.Matchers;
 import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
-import org.chromium.components.browser_ui.settings.ChromeBasePreference;
-import org.chromium.components.browser_ui.settings.R;
+import org.chromium.base.test.BaseJUnit4ClassRunner;
+import org.chromium.base.test.util.Criteria;
+import org.chromium.base.test.util.CriteriaHelper;
+import org.chromium.content_public.browser.test.util.TestThreadUtils;
+import org.chromium.ui.test.util.BlankUiTestActivityTestCase;
 
 import java.util.List;
 
 /**
  * Tests of {@link ChromeBasePreference}.
- *
- * TODO(crbug.com/1166810): Move these tests to //components/browser_ui/settings/.
  */
-@RunWith(ChromeJUnit4ClassRunner.class)
-public class ChromeBasePreferenceTest {
-    @Rule
-    public SettingsActivityTestRule<PlaceholderSettingsForTest> mActivityRule =
-            new SettingsActivityTestRule<>(PlaceholderSettingsForTest.class);
-
-    private PreferenceScreen mPreferenceScreen;
-    private Context mContext;
-
+@RunWith(BaseJUnit4ClassRunner.class)
+public class ChromeBasePreferenceTest extends BlankUiTestActivityTestCase {
     private static final String TITLE = "Preference Title";
     private static final String SUMMARY = "This is a summary.";
 
-    @Before
-    public void setUp() {
-        mActivityRule.startSettingsActivity();
-        PreferenceFragmentCompat fragment = mActivityRule.getFragment();
-        mPreferenceScreen = fragment.getPreferenceScreen();
-        mContext = fragment.getPreferenceManager().getContext();
+    private PreferenceFragmentCompat mPreferenceFragment;
+    private PreferenceScreen mPreferenceScreen;
+
+    @Override
+    public void setUpTest() throws Exception {
+        super.setUpTest();
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            mPreferenceFragment = new PlaceholderSettingsForTest();
+            getActivity()
+                    .getSupportFragmentManager()
+                    .beginTransaction()
+                    .replace(android.R.id.content, mPreferenceFragment)
+                    .commit();
+        });
+        CriteriaHelper.pollUiThread(() -> {
+            Criteria.checkThat(mPreferenceFragment.getPreferenceManager(), Matchers.notNullValue());
+            Criteria.checkThat(mPreferenceFragment.getPreferenceScreen(), Matchers.notNullValue());
+        });
+        TestThreadUtils.runOnUiThreadBlocking(
+                () -> { mPreferenceScreen = mPreferenceFragment.getPreferenceScreen(); });
     }
 
     @Test
     @SmallTest
     public void testUnmanagedPreference() {
-        ChromeBasePreference preference = new ChromeBasePreference(mContext);
+        ChromeBasePreference preference = new ChromeBasePreference(getActivity());
         preference.setTitle(TITLE);
         preference.setSummary(SUMMARY);
         preference.setManagedPreferenceDelegate(ManagedPreferencesUtilsTest.UNMANAGED_DELEGATE);
@@ -79,7 +83,7 @@
     @Test
     @SmallTest
     public void testPolicyManagedPreferenceWithoutSummary() {
-        ChromeBasePreference preference = new ChromeBasePreference(mContext);
+        ChromeBasePreference preference = new ChromeBasePreference(getActivity());
         preference.setTitle(TITLE);
         preference.setManagedPreferenceDelegate(ManagedPreferencesUtilsTest.POLICY_DELEGATE);
         mPreferenceScreen.addPreference(preference);
@@ -95,14 +99,14 @@
     @Test
     @SmallTest
     public void testPolicyManagedPreferenceWithSummary() {
-        ChromeBasePreference preference = new ChromeBasePreference(mContext);
+        ChromeBasePreference preference = new ChromeBasePreference(getActivity());
         preference.setTitle(TITLE);
         preference.setSummary(SUMMARY);
         preference.setManagedPreferenceDelegate(ManagedPreferencesUtilsTest.POLICY_DELEGATE);
         mPreferenceScreen.addPreference(preference);
 
         List<String> expectedSummaryContains = ImmutableList.of(
-                SUMMARY, mContext.getString(R.string.managed_by_your_organization));
+                SUMMARY, getActivity().getString(R.string.managed_by_your_organization));
 
         Assert.assertFalse(preference.isEnabled());
 
@@ -115,7 +119,7 @@
     @Test
     @SmallTest
     public void testSingleCustodianManagedPreference() {
-        ChromeBasePreference preference = new ChromeBasePreference(mContext);
+        ChromeBasePreference preference = new ChromeBasePreference(getActivity());
         preference.setTitle(TITLE);
         preference.setManagedPreferenceDelegate(
                 ManagedPreferencesUtilsTest.SINGLE_CUSTODIAN_DELEGATE);
@@ -132,7 +136,7 @@
     @Test
     @SmallTest
     public void testMultipleCustodianManagedPreference() {
-        ChromeBasePreference preference = new ChromeBasePreference(mContext);
+        ChromeBasePreference preference = new ChromeBasePreference(getActivity());
         preference.setTitle(TITLE);
         preference.setManagedPreferenceDelegate(
                 ManagedPreferencesUtilsTest.MULTI_CUSTODIAN_DELEGATE);
diff --git a/chrome/browser/settings/android/java/src/org/chromium/chrome/browser/settings/ChromeImageViewPreferenceTest.java b/components/browser_ui/settings/android/widget/java/src/org/chromium/components/browser_ui/settings/ChromeImageViewPreferenceTest.java
similarity index 65%
rename from chrome/browser/settings/android/java/src/org/chromium/chrome/browser/settings/ChromeImageViewPreferenceTest.java
rename to components/browser_ui/settings/android/widget/java/src/org/chromium/components/browser_ui/settings/ChromeImageViewPreferenceTest.java
index d0aa751f..cd044ecd 100644
--- a/chrome/browser/settings/android/java/src/org/chromium/chrome/browser/settings/ChromeImageViewPreferenceTest.java
+++ b/components/browser_ui/settings/android/widget/java/src/org/chromium/components/browser_ui/settings/ChromeImageViewPreferenceTest.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.settings;
+package org.chromium.components.browser_ui.settings;
 
 import static androidx.test.espresso.Espresso.onView;
 import static androidx.test.espresso.assertion.ViewAssertions.matches;
@@ -12,64 +12,59 @@
 
 import static org.hamcrest.Matchers.allOf;
 
-import android.content.Context;
-import android.content.Intent;
-import android.support.test.InstrumentationRegistry;
-
 import androidx.preference.PreferenceFragmentCompat;
 import androidx.preference.PreferenceScreen;
 import androidx.test.espresso.ViewInteraction;
 import androidx.test.filters.SmallTest;
 
+import org.hamcrest.Matchers;
 import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import org.chromium.base.test.BaseActivityTestRule;
-import org.chromium.chrome.R;
-import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
-import org.chromium.components.browser_ui.settings.ChromeImageViewPreference;
-import org.chromium.components.browser_ui.settings.SettingsLauncher;
+import org.chromium.base.test.BaseJUnit4ClassRunner;
+import org.chromium.base.test.util.Criteria;
+import org.chromium.base.test.util.CriteriaHelper;
+import org.chromium.content_public.browser.test.util.TestThreadUtils;
+import org.chromium.ui.test.util.BlankUiTestActivityTestCase;
 
 /**
  * Tests of {@link ChromeImageViewPreference}.
- *
- * TODO(crbug.com/1166810): Move these tests to //components/browser_ui/settings/.
  */
-@RunWith(ChromeJUnit4ClassRunner.class)
-public class ChromeImageViewPreferenceTest {
-    @Rule
-    public BaseActivityTestRule<SettingsActivity> mRule =
-            new BaseActivityTestRule<>(SettingsActivity.class);
-
-    private PreferenceScreen mPreferenceScreen;
-    private Context mContext;
-
+@RunWith(BaseJUnit4ClassRunner.class)
+public class ChromeImageViewPreferenceTest extends BlankUiTestActivityTestCase {
     private static final String TITLE = "Preference Title";
     private static final String SUMMARY = "This is a summary.";
     private static final int DRAWABLE_RES = R.drawable.ic_folder_blue_24dp;
     private static final int CONTENT_DESCRIPTION_RES = R.string.ok;
 
-    @Before
-    public void setUp() {
-        SettingsLauncher settingsLauncher = new SettingsLauncherImpl();
-        Intent intent = settingsLauncher.createSettingsActivityIntent(
-                InstrumentationRegistry.getInstrumentation().getContext(),
-                PlaceholderSettingsForTest.class.getName());
-        mRule.launchActivity(intent);
+    private PreferenceFragmentCompat mPreferenceFragment;
+    private PreferenceScreen mPreferenceScreen;
 
-        PreferenceFragmentCompat fragment =
-                (PreferenceFragmentCompat) mRule.getActivity().getMainFragment();
-        mPreferenceScreen = fragment.getPreferenceScreen();
-        mContext = fragment.getPreferenceManager().getContext();
+    @Override
+    public void setUpTest() throws Exception {
+        super.setUpTest();
+
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            mPreferenceFragment = new PlaceholderSettingsForTest();
+            getActivity()
+                    .getSupportFragmentManager()
+                    .beginTransaction()
+                    .replace(android.R.id.content, mPreferenceFragment)
+                    .commit();
+        });
+        CriteriaHelper.pollUiThread(() -> {
+            Criteria.checkThat(mPreferenceFragment.getPreferenceManager(), Matchers.notNullValue());
+            Criteria.checkThat(mPreferenceFragment.getPreferenceScreen(), Matchers.notNullValue());
+        });
+        TestThreadUtils.runOnUiThreadBlocking(
+                () -> { mPreferenceScreen = mPreferenceFragment.getPreferenceScreen(); });
     }
 
     @Test
     @SmallTest
     public void testChromeImageViewPreference() {
-        ChromeImageViewPreference preference = new ChromeImageViewPreference(mContext);
+        ChromeImageViewPreference preference = new ChromeImageViewPreference(getActivity());
         preference.setTitle(TITLE);
         preference.setSummary(SUMMARY);
         preference.setImageView(DRAWABLE_RES, CONTENT_DESCRIPTION_RES, null);
@@ -85,7 +80,7 @@
     @Test
     @SmallTest
     public void testChromeImageViewPreferenceManaged() {
-        ChromeImageViewPreference preference = new ChromeImageViewPreference(mContext);
+        ChromeImageViewPreference preference = new ChromeImageViewPreference(getActivity());
         preference.setTitle(TITLE);
         preference.setImageView(DRAWABLE_RES, CONTENT_DESCRIPTION_RES, null);
         preference.setManagedPreferenceDelegate(ManagedPreferencesUtilsTest.POLICY_DELEGATE);
diff --git a/chrome/browser/settings/android/java/src/org/chromium/chrome/browser/settings/ManagedPreferencesUtilsTest.java b/components/browser_ui/settings/android/widget/java/src/org/chromium/components/browser_ui/settings/ManagedPreferencesUtilsTest.java
similarity index 65%
rename from chrome/browser/settings/android/java/src/org/chromium/chrome/browser/settings/ManagedPreferencesUtilsTest.java
rename to components/browser_ui/settings/android/widget/java/src/org/chromium/components/browser_ui/settings/ManagedPreferencesUtilsTest.java
index 979a7dd5..5840024 100644
--- a/chrome/browser/settings/android/java/src/org/chromium/chrome/browser/settings/ManagedPreferencesUtilsTest.java
+++ b/components/browser_ui/settings/android/widget/java/src/org/chromium/components/browser_ui/settings/ManagedPreferencesUtilsTest.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.settings;
+package org.chromium.components.browser_ui.settings;
 
 import static androidx.test.espresso.Espresso.onView;
 import static androidx.test.espresso.assertion.ViewAssertions.matches;
@@ -12,41 +12,25 @@
 
 import static org.hamcrest.Matchers.not;
 
-import android.content.Context;
-import android.content.Intent;
 import android.support.test.InstrumentationRegistry;
 
 import androidx.preference.Preference;
-import androidx.preference.PreferenceFragmentCompat;
 import androidx.test.filters.SmallTest;
 
 import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import org.chromium.base.test.BaseActivityTestRule;
-import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
-import org.chromium.components.browser_ui.settings.ManagedPreferenceDelegate;
-import org.chromium.components.browser_ui.settings.ManagedPreferencesUtils;
-import org.chromium.components.browser_ui.settings.R;
-import org.chromium.components.browser_ui.settings.SettingsLauncher;
+import org.chromium.base.test.BaseJUnit4ClassRunner;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
+import org.chromium.ui.test.util.BlankUiTestActivityTestCase;
+import org.chromium.ui.widget.Toast;
 
 /**
  * Tests of {@link ManagedPreferencesUtils}.
- *
- * TODO(crbug.com/1166810): Move these tests to //components/browser_ui/settings/.
  */
-@RunWith(ChromeJUnit4ClassRunner.class)
-public class ManagedPreferencesUtilsTest {
-    @Rule
-    public BaseActivityTestRule<SettingsActivity> mRule =
-            new BaseActivityTestRule<>(SettingsActivity.class);
-
-    private Context mContext;
-
+@RunWith(BaseJUnit4ClassRunner.class)
+public class ManagedPreferencesUtilsTest extends BlankUiTestActivityTestCase {
     public static final ManagedPreferenceDelegate UNMANAGED_DELEGATE =
             new ManagedPreferenceDelegate() {
                 @Override
@@ -119,85 +103,80 @@
                 }
             };
 
-    @Before
-    public void setUp() {
-        SettingsLauncher settingsLauncher = new SettingsLauncherImpl();
-        Intent intent = settingsLauncher.createSettingsActivityIntent(
-                InstrumentationRegistry.getInstrumentation().getContext(),
-                PlaceholderSettingsForTest.class.getName());
-        mRule.launchActivity(intent);
-
-        PreferenceFragmentCompat fragment =
-                (PreferenceFragmentCompat) mRule.getActivity().getMainFragment();
-        mContext = fragment.getPreferenceScreen().getContext();
-    }
-
     @Test
     @SmallTest
     public void testShowManagedByAdministratorToast() {
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            ManagedPreferencesUtils.showManagedByAdministratorToast(mRule.getActivity());
+        Toast toast = TestThreadUtils.runOnUiThreadBlockingNoException(() -> {
+            return ManagedPreferencesUtils.showManagedByAdministratorToast(getActivity());
         });
 
         onView(withText(R.string.managed_by_your_organization))
-                .inRoot(withDecorView(not(mRule.getActivity().getWindow().getDecorView())))
+                .inRoot(withDecorView(not(getActivity().getWindow().getDecorView())))
                 .check(matches(isDisplayed()));
+
+        TestThreadUtils.runOnUiThreadBlocking(() -> toast.cancel());
     }
 
     @Test
     @SmallTest
     public void testShowManagedByParentToastNullDelegate() {
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            ManagedPreferencesUtils.showManagedByParentToast(mRule.getActivity(), null);
+        Toast toast = TestThreadUtils.runOnUiThreadBlockingNoException(() -> {
+            return ManagedPreferencesUtils.showManagedByParentToast(getActivity(), null);
         });
 
         onView(withText(R.string.managed_by_your_parent))
-                .inRoot(withDecorView(not(mRule.getActivity().getWindow().getDecorView())))
+                .inRoot(withDecorView(not(getActivity().getWindow().getDecorView())))
                 .check(matches(isDisplayed()));
+
+        TestThreadUtils.runOnUiThreadBlocking(() -> toast.cancel());
     }
 
     @Test
     @SmallTest
     public void testShowManagedByParentToastSingleCustodian() {
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            ManagedPreferencesUtils.showManagedByParentToast(
-                    mRule.getActivity(), SINGLE_CUSTODIAN_DELEGATE);
+        Toast toast = TestThreadUtils.runOnUiThreadBlockingNoException(() -> {
+            return ManagedPreferencesUtils.showManagedByParentToast(
+                    getActivity(), SINGLE_CUSTODIAN_DELEGATE);
         });
 
         onView(withText(R.string.managed_by_your_parent))
-                .inRoot(withDecorView(not(mRule.getActivity().getWindow().getDecorView())))
+                .inRoot(withDecorView(not(getActivity().getWindow().getDecorView())))
                 .check(matches(isDisplayed()));
+
+        TestThreadUtils.runOnUiThreadBlocking(() -> toast.cancel());
     }
 
     @Test
     @SmallTest
     public void testShowManagedByParentToastMultipleCustodians() {
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            ManagedPreferencesUtils.showManagedByParentToast(
-                    mRule.getActivity(), MULTI_CUSTODIAN_DELEGATE);
+        Toast toast = TestThreadUtils.runOnUiThreadBlockingNoException(() -> {
+            return ManagedPreferencesUtils.showManagedByParentToast(
+                    getActivity(), MULTI_CUSTODIAN_DELEGATE);
         });
 
         onView(withText(R.string.managed_by_your_parents))
-                .inRoot(withDecorView(not(mRule.getActivity().getWindow().getDecorView())))
+                .inRoot(withDecorView(not(getActivity().getWindow().getDecorView())))
                 .check(matches(isDisplayed()));
+
+        TestThreadUtils.runOnUiThreadBlocking(() -> toast.cancel());
     }
 
     @Test
     @SmallTest
     public void testShowManagedSettingsCannotBeResetToast() {
         TestThreadUtils.runOnUiThreadBlocking(() -> {
-            ManagedPreferencesUtils.showManagedSettingsCannotBeResetToast(mRule.getActivity());
+            ManagedPreferencesUtils.showManagedSettingsCannotBeResetToast(getActivity());
         });
 
         onView(withText(R.string.managed_settings_cannot_be_reset))
-                .inRoot(withDecorView(not(mRule.getActivity().getWindow().getDecorView())))
+                .inRoot(withDecorView(not(getActivity().getWindow().getDecorView())))
                 .check(matches(isDisplayed()));
     }
 
     @Test
     @SmallTest
     public void testGetManagedIconIdNull() {
-        Preference pref = new Preference(mContext);
+        Preference pref = new Preference(InstrumentationRegistry.getTargetContext());
         int actual = ManagedPreferencesUtils.getManagedIconResId(null, pref);
         Assert.assertEquals(0, actual);
     }
@@ -205,7 +184,7 @@
     @Test
     @SmallTest
     public void testGetManagedIconIdPolicy() {
-        Preference pref = new Preference(mContext);
+        Preference pref = new Preference(InstrumentationRegistry.getTargetContext());
         int expected = ManagedPreferencesUtils.getManagedByEnterpriseIconId();
         int actual = ManagedPreferencesUtils.getManagedIconResId(POLICY_DELEGATE, pref);
         Assert.assertEquals(expected, actual);
@@ -214,7 +193,7 @@
     @Test
     @SmallTest
     public void testGetManagedIconIdCustodian() {
-        Preference pref = new Preference(mContext);
+        Preference pref = new Preference(InstrumentationRegistry.getTargetContext());
         int expected = ManagedPreferencesUtils.getManagedByCustodianIconId();
         int actual = ManagedPreferencesUtils.getManagedIconResId(SINGLE_CUSTODIAN_DELEGATE, pref);
         Assert.assertEquals(expected, actual);
diff --git a/chrome/browser/settings/android/java/src/org/chromium/chrome/browser/settings/PlaceholderSettingsForTest.java b/components/browser_ui/settings/android/widget/java/src/org/chromium/components/browser_ui/settings/PlaceholderSettingsForTest.java
similarity index 93%
rename from chrome/browser/settings/android/java/src/org/chromium/chrome/browser/settings/PlaceholderSettingsForTest.java
rename to components/browser_ui/settings/android/widget/java/src/org/chromium/components/browser_ui/settings/PlaceholderSettingsForTest.java
index e535a6d..e96783a 100644
--- a/chrome/browser/settings/android/java/src/org/chromium/chrome/browser/settings/PlaceholderSettingsForTest.java
+++ b/components/browser_ui/settings/android/widget/java/src/org/chromium/components/browser_ui/settings/PlaceholderSettingsForTest.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.settings;
+package org.chromium.components.browser_ui.settings;
 
 import android.content.Context;
 import android.os.Bundle;
diff --git a/components/certificate_transparency/data/log_list.json b/components/certificate_transparency/data/log_list.json
index 1642f68..ee65b76 100644
--- a/components/certificate_transparency/data/log_list.json
+++ b/components/certificate_transparency/data/log_list.json
@@ -1,6 +1,6 @@
 {
-  "version": "10.13",
-  "log_list_timestamp": "2022-06-15T12:55:48Z",
+  "version": "10.14",
+  "log_list_timestamp": "2022-06-16T12:56:33Z",
   "operators": [
     {
       "name": "Google",
diff --git a/components/device_signals/core/browser/BUILD.gn b/components/device_signals/core/browser/BUILD.gn
index a1286a6..25de60c 100644
--- a/components/device_signals/core/browser/BUILD.gn
+++ b/components/device_signals/core/browser/BUILD.gn
@@ -43,6 +43,8 @@
 static_library("test_support") {
   testonly = true
   sources = [
+    "mock_signals_aggregator.cc",
+    "mock_signals_aggregator.h",
     "mock_signals_collector.cc",
     "mock_signals_collector.h",
     "mock_system_signals_service_host.cc",
diff --git a/components/device_signals/core/browser/mock_signals_aggregator.cc b/components/device_signals/core/browser/mock_signals_aggregator.cc
new file mode 100644
index 0000000..46db9f5
--- /dev/null
+++ b/components/device_signals/core/browser/mock_signals_aggregator.cc
@@ -0,0 +1,12 @@
+// 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/device_signals/core/browser/mock_signals_aggregator.h"
+
+namespace device_signals {
+
+MockSignalsAggregator::MockSignalsAggregator() = default;
+MockSignalsAggregator::~MockSignalsAggregator() = default;
+
+}  // namespace device_signals
diff --git a/components/device_signals/core/browser/mock_signals_aggregator.h b/components/device_signals/core/browser/mock_signals_aggregator.h
new file mode 100644
index 0000000..77284d91
--- /dev/null
+++ b/components/device_signals/core/browser/mock_signals_aggregator.h
@@ -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.
+
+#ifndef COMPONENTS_DEVICE_SIGNALS_CORE_BROWSER_MOCK_SIGNALS_AGGREGATOR_H_
+#define COMPONENTS_DEVICE_SIGNALS_CORE_BROWSER_MOCK_SIGNALS_AGGREGATOR_H_
+
+#include "base/callback.h"
+#include "components/device_signals/core/browser/signals_aggregator.h"
+#include "components/device_signals/core/browser/signals_types.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace device_signals {
+
+class MockSignalsAggregator : public SignalsAggregator {
+ public:
+  MockSignalsAggregator();
+  ~MockSignalsAggregator() override;
+
+  MOCK_METHOD(void,
+              GetSignals,
+              (const SignalsAggregationRequest&,
+               SignalsAggregator::GetSignalsCallback),
+              (override));
+};
+
+}  // namespace device_signals
+
+#endif  // COMPONENTS_DEVICE_SIGNALS_CORE_BROWSER_MOCK_SIGNALS_AGGREGATOR_H_
diff --git a/components/device_signals/core/browser/signals_types.cc b/components/device_signals/core/browser/signals_types.cc
index 67c7a5e8..6608668 100644
--- a/components/device_signals/core/browser/signals_types.cc
+++ b/components/device_signals/core/browser/signals_types.cc
@@ -4,8 +4,25 @@
 
 #include "components/device_signals/core/browser/signals_types.h"
 
+#include "components/device_signals/core/common/signals_constants.h"
+
 namespace device_signals {
 
+const std::string ErrorToString(SignalCollectionError error) {
+  switch (error) {
+    case SignalCollectionError::kConsentRequired:
+      return errors::kConsentRequired;
+    case SignalCollectionError::kUnaffiliatedUser:
+      return errors::kUnaffiliatedUser;
+    case SignalCollectionError::kUnsupported:
+      return errors::kUnsupported;
+    case SignalCollectionError::kMissingSystemService:
+      return errors::kMissingSystemService;
+    case SignalCollectionError::kMissingBundle:
+      return errors::kMissingBundle;
+  }
+}
+
 BaseSignalResponse::~BaseSignalResponse() = default;
 
 #if BUILDFLAG(IS_WIN)
diff --git a/components/device_signals/core/browser/signals_types.h b/components/device_signals/core/browser/signals_types.h
index b8e629b2..784ebb6 100644
--- a/components/device_signals/core/browser/signals_types.h
+++ b/components/device_signals/core/browser/signals_types.h
@@ -34,9 +34,12 @@
   kUnaffiliatedUser,
   kUnsupported,
   kMissingSystemService,
-  kMaxValue = kMissingSystemService
+  kMissingBundle,
+  kMaxValue = kMissingBundle
 };
 
+const std::string ErrorToString(SignalCollectionError error);
+
 // Base struct type that each specific signal bundle types should extend. The
 // derived signal bundles/responses should group a set of signals that
 // cohesively belong together (e.g. device-level signals, policy values
diff --git a/components/device_signals/core/common/signals_constants.cc b/components/device_signals/core/common/signals_constants.cc
index 021c7b7..fcb4ab0d 100644
--- a/components/device_signals/core/common/signals_constants.cc
+++ b/components/device_signals/core/common/signals_constants.cc
@@ -155,6 +155,10 @@
 // the SystemSignalsService.
 const char kMissingSystemService[] = "MISSING_SYSTEM_SERVICE";
 
+// Returned when the signals aggregation response is missing a
+// bundle/sub-response struct that was expected by a specific use-case.
+const char kMissingBundle[] = "MISSING_BUNDLE";
+
 }  // namespace errors
 
 }  // namespace device_signals
diff --git a/components/device_signals/core/common/signals_constants.h b/components/device_signals/core/common/signals_constants.h
index b78cdba4..3615186 100644
--- a/components/device_signals/core/common/signals_constants.h
+++ b/components/device_signals/core/common/signals_constants.h
@@ -54,6 +54,7 @@
 extern const char kUnaffiliatedUser[];
 extern const char kUnsupported[];
 extern const char kMissingSystemService[];
+extern const char kMissingBundle[];
 
 }  // namespace errors
 
diff --git a/components/download/network/BUILD.gn b/components/download/network/BUILD.gn
index 81df40f6..564d845 100644
--- a/components/download/network/BUILD.gn
+++ b/components/download/network/BUILD.gn
@@ -66,16 +66,18 @@
     sources = [ "android/java/src/org/chromium/components/download/NetworkStatusListenerAndroid.java" ]
   }
 
-  android_library("javatests") {
+  robolectric_library("junit") {
     testonly = true
 
-    sources = [ "android/java/src/org/chromium/components/download/NetworkStatusListenerAndroidTest.java" ]
+    sources = [ "android/junit/src/org/chromium/components/download/NetworkStatusListenerAndroidTest.java" ]
 
     deps = [
       ":network_java",
       "//base:base_java",
       "//base:base_java_test_support",
+      "//base:base_junit_test_support",
       "//net/android:net_java",
+      "//third_party/android_deps:robolectric_all_java",
       "//third_party/androidx:androidx_test_runner_java",
       "//third_party/junit",
       "//third_party/mockito:mockito_java",
diff --git a/components/download/network/android/java/src/org/chromium/components/download/NetworkStatusListenerAndroid.java b/components/download/network/android/java/src/org/chromium/components/download/NetworkStatusListenerAndroid.java
index e4d97c69..dc88925 100644
--- a/components/download/network/android/java/src/org/chromium/components/download/NetworkStatusListenerAndroid.java
+++ b/components/download/network/android/java/src/org/chromium/components/download/NetworkStatusListenerAndroid.java
@@ -96,6 +96,11 @@
                 observer.onConnectionTypeChanged(newConnectionType);
             }
         }
+
+        @VisibleForTesting
+        public Handler getHandlerForTesting() {
+            return mNetworkThreadHandler;
+        }
     }
 
     @VisibleForTesting
diff --git a/components/download/network/android/java/src/org/chromium/components/download/NetworkStatusListenerAndroidTest.java b/components/download/network/android/junit/src/org/chromium/components/download/NetworkStatusListenerAndroidTest.java
similarity index 72%
rename from components/download/network/android/java/src/org/chromium/components/download/NetworkStatusListenerAndroidTest.java
rename to components/download/network/android/junit/src/org/chromium/components/download/NetworkStatusListenerAndroidTest.java
index 7e488802..1dc7d94 100644
--- a/components/download/network/android/java/src/org/chromium/components/download/NetworkStatusListenerAndroidTest.java
+++ b/components/download/network/android/junit/src/org/chromium/components/download/NetworkStatusListenerAndroidTest.java
@@ -15,10 +15,12 @@
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.robolectric.Shadows;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowLooper;
 
 import org.chromium.base.ThreadUtils;
-import org.chromium.base.test.BaseJUnit4ClassRunner;
-import org.chromium.base.test.util.CriteriaHelper;
+import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.base.test.util.JniMocker;
 import org.chromium.net.ConnectionType;
 import org.chromium.net.NetworkChangeNotifierAutoDetect;
@@ -26,7 +28,8 @@
 /**
  * Unit test for {@link NetworkStatusListenerAndroid} and {@link BackgroundNetworkStatusListener}.
  */
-@RunWith(BaseJUnit4ClassRunner.class)
+@RunWith(BaseRobolectricTestRunner.class)
+@Config(manifest = Config.NONE)
 public class NetworkStatusListenerAndroidTest {
     private static final int NATIVE_PTR = 1;
 
@@ -65,6 +68,21 @@
         mJniMocker.mock(NetworkStatusListenerAndroidJni.TEST_HOOKS, mNativeMock);
     }
 
+    private void runBackgroundThread() {
+        // Flush any UI thread tasks first.
+        ShadowLooper.runUiThreadTasks();
+
+        // Run the background thread.
+        ShadowLooper shadowLooper =
+                Shadows.shadowOf(NetworkStatusListenerAndroid.getHelperForTesting()
+                                         .getHandlerForTesting()
+                                         .getLooper());
+        shadowLooper.runToEndOfTasks();
+
+        // Flush any UI thread tasks created by the background thread.
+        ShadowLooper.runUiThreadTasks();
+    }
+
     private void initWithConnectionType(@ConnectionType int connectionType) {
         when(mAutoDetect.getCurrentNetworkState()).thenReturn(mNetworkState);
         when(mNetworkState.getConnectionType()).thenReturn(connectionType);
@@ -77,24 +95,30 @@
     public void testGetCurrentConnectionType() {
         initWithConnectionType(ConnectionType.CONNECTION_3G);
 
+        runBackgroundThread();
+
         // The background thread should set the connection type correctly and update the main
         // thread.
-        CriteriaHelper.pollUiThread(
-                () -> mListener.getCurrentConnectionType() == ConnectionType.CONNECTION_3G);
+        Assert.assertEquals(ConnectionType.CONNECTION_3G, mListener.getCurrentConnectionType());
     }
 
     @Test
     @SmallTest
     public void testOnConnectionTypeChanged() {
         initWithConnectionType(ConnectionType.CONNECTION_3G);
-        CriteriaHelper.pollUiThread(
-                () -> mListener.getCurrentConnectionType() == ConnectionType.CONNECTION_3G);
+
+        runBackgroundThread();
+
+        Assert.assertEquals(ConnectionType.CONNECTION_3G, mListener.getCurrentConnectionType());
 
         // Change the connection type on main thread, the connection type should be updated.
         ThreadUtils.runOnUiThreadBlocking(() -> {
             NetworkStatusListenerAndroid.getHelperForTesting().onConnectionTypeChanged(
                     ConnectionType.CONNECTION_5G);
-            Assert.assertEquals(ConnectionType.CONNECTION_5G, mListener.getCurrentConnectionType());
         });
+
+        runBackgroundThread();
+
+        Assert.assertEquals(ConnectionType.CONNECTION_5G, mListener.getCurrentConnectionType());
     }
 }
diff --git a/components/external_intents/android/BUILD.gn b/components/external_intents/android/BUILD.gn
index 054e7ab4..9b3d692 100644
--- a/components/external_intents/android/BUILD.gn
+++ b/components/external_intents/android/BUILD.gn
@@ -60,7 +60,7 @@
   ]
 }
 
-android_library("javatests") {
+android_library("unit_device_javatests") {
   testonly = true
 
   sources = [
diff --git a/components/omnibox/common/omnibox_features.cc b/components/omnibox/common/omnibox_features.cc
index c4fd7c9..440dd13 100644
--- a/components/omnibox/common/omnibox_features.cc
+++ b/components/omnibox/common/omnibox_features.cc
@@ -221,6 +221,13 @@
 const base::Feature kBookmarkPaths{"OmniboxBookmarkPaths",
                                    base::FEATURE_DISABLED_BY_DEFAULT};
 
+// If enabled, the relevant AutocompleteProviders will store "title" data in
+// AutocompleteMatch::contents and "URL" data in AutocompleteMatch::description
+// for URL-based omnibox suggestions (see crbug.com/1202964 for more details).
+const base::Feature kStoreTitleInContentsAndUrlInDescription{
+    "OmniboxStoreTitleInContentsAndUrlInDescription",
+    base::FEATURE_DISABLED_BY_DEFAULT};
+
 // Feature used to fetch document suggestions.
 const base::Feature kDocumentProvider{"OmniboxDocumentProvider",
                                       enabled_by_default_desktop_only};
diff --git a/components/omnibox/common/omnibox_features.h b/components/omnibox/common/omnibox_features.h
index bfa6d0e..5806233 100644
--- a/components/omnibox/common/omnibox_features.h
+++ b/components/omnibox/common/omnibox_features.h
@@ -62,6 +62,9 @@
 extern const base::Feature kAggregateShortcuts;
 extern const base::Feature kShortcutExpanding;
 extern const base::Feature kBookmarkPaths;
+// TODO(crbug.com/1202964): Clean up feature flag used in staged roll-out of
+// various CLs related to the contents/description clean-up work.
+extern const base::Feature kStoreTitleInContentsAndUrlInDescription;
 
 // Document provider
 extern const base::Feature kDocumentProvider;
diff --git a/components/page_load_metrics/browser/metrics_web_contents_observer.cc b/components/page_load_metrics/browser/metrics_web_contents_observer.cc
index 6b076d8c..ea0285d 100644
--- a/components/page_load_metrics/browser/metrics_web_contents_observer.cc
+++ b/components/page_load_metrics/browser/metrics_web_contents_observer.cc
@@ -181,7 +181,7 @@
   if (!rfh || !rfh->GetParent())
     return;
   if (PageLoadTracker* tracker = GetPageLoadTracker(rfh))
-    tracker->SubFrameDeleted(frame_tree_node_id);
+    tracker->FrameTreeNodeDeleted(frame_tree_node_id);
 }
 
 void MetricsWebContentsObserver::RenderFrameDeleted(
@@ -1191,6 +1191,21 @@
     map_pair.first->OnV8MemoryChanged(map_pair.second);
 }
 
+// This contains some bugs. RenderFrameHost::IsActive is not relevant to
+// determine what members we have to search.
+//
+// There are some known wrong cases:
+//
+// 1. rfh->GetLifecycleState() == kReadyToBeDeleted && rfh is in active_pages_.
+//    In this case, this method returns null. This case can occur, e.g.
+//    navigation on a FF root node.
+// 2. rfh->GetLifecycleState() == kActive && rfh is already deleted via
+//    RenderFrameDeleted.
+//    In this case, this method returns primary_page's PageLeadTracker. This
+//    case can occur if the caller is FrameDeleted and, e.g. deletion of a FF
+//    root node.
+//
+// TODO(https://crbug.com/1301880): Fix it.
 PageLoadTracker* MetricsWebContentsObserver::GetPageLoadTracker(
     content::RenderFrameHost* rfh) {
   if (!rfh)
diff --git a/components/page_load_metrics/browser/observers/ad_metrics/ads_page_load_metrics_observer.cc b/components/page_load_metrics/browser/observers/ad_metrics/ads_page_load_metrics_observer.cc
index d68306d1..35302f0 100644
--- a/components/page_load_metrics/browser/observers/ad_metrics/ads_page_load_metrics_observer.cc
+++ b/components/page_load_metrics/browser/observers/ad_metrics/ads_page_load_metrics_observer.cc
@@ -669,6 +669,18 @@
 #endif
 }
 
+// OnSubFrameDeleted is not called for main frames, including fenced frames.
+// As an approximation, we regard deletion of RenderFrameHost as one of
+// FrameTreeNode for non primary main frames.
+// TODO(https://crbug.com/1301880): Verify that this is legitimate.
+void AdsPageLoadMetricsObserver::OnRenderFrameDeleted(
+    content::RenderFrameHost* rfh) {
+  if (rfh->IsInPrimaryMainFrame() || rfh->GetParent())
+    return;
+
+  OnSubFrameDeleted(rfh->GetFrameTreeNodeId());
+}
+
 void AdsPageLoadMetricsObserver::OnSubFrameDeleted(int frame_tree_node_id) {
   const auto& id_and_data = ad_frames_data_.find(frame_tree_node_id);
   if (id_and_data == ad_frames_data_.end())
diff --git a/components/page_load_metrics/browser/observers/ad_metrics/ads_page_load_metrics_observer.h b/components/page_load_metrics/browser/observers/ad_metrics/ads_page_load_metrics_observer.h
index 0aec57f6..2cbe27f 100644
--- a/components/page_load_metrics/browser/observers/ad_metrics/ads_page_load_metrics_observer.h
+++ b/components/page_load_metrics/browser/observers/ad_metrics/ads_page_load_metrics_observer.h
@@ -137,6 +137,7 @@
       const gfx::Rect& main_frame_intersection_rect) override;
   void OnMainFrameViewportRectChanged(
       const gfx::Rect& main_frame_viewport_rect) override;
+  void OnRenderFrameDeleted(content::RenderFrameHost* rfh) override;
   void OnSubFrameDeleted(int frame_tree_node_id) override;
 
   void SetHeavyAdThresholdNoiseProviderForTesting(
diff --git a/components/page_load_metrics/browser/page_load_metrics_observer_interface.h b/components/page_load_metrics/browser/page_load_metrics_observer_interface.h
index 9f31d28..2030e371 100644
--- a/components/page_load_metrics/browser/page_load_metrics_observer_interface.h
+++ b/components/page_load_metrics/browser/page_load_metrics_observer_interface.h
@@ -486,6 +486,22 @@
   virtual void FrameSizeChanged(content::RenderFrameHost* render_frame_host,
                                 const gfx::Size& frame_size) = 0;
 
+  // OnRenderFrameDeleted is called when RenderFrameHost for a frame is deleted.
+  // OnSubFrameDeleted is called when FrameTreeNode for a subframe is deleted.
+  // The differences are:
+  //
+  // - OnRenderFrameDeleted is called for all frames. OnSubFrameDeleted is not
+  //   called for main frames. This is because PageLoadTracker is bound with
+  //   RenderFrameHost of the main frame and destruction of PageLoadTracker is
+  //   earlier than one of FrameTreeNode in some cases.
+  // - OnRenderFrameDeleted can be called in navigation commit to discard the
+  //   previous RenderFrameHost. At that timing, there are two RenderFrameHost
+  //   that have the same RenderFrameHost::GetFrameNodeId.
+  //
+  // TODO(https://crbug.com/1301880): Make it clear when
+  // MetricsWebContentsObserver::FrameDeleted is not called and make
+  // PageLoadMetricsObserverInterface::OnSubFrameDeleted called for fenced
+  // frame's root if possible.
   virtual void OnRenderFrameDeleted(
       content::RenderFrameHost* render_frame_host) = 0;
   virtual void OnSubFrameDeleted(int frame_tree_node_id) = 0;
diff --git a/components/page_load_metrics/browser/page_load_tracker.cc b/components/page_load_metrics/browser/page_load_tracker.cc
index 028162c..4b6d193 100644
--- a/components/page_load_metrics/browser/page_load_tracker.cc
+++ b/components/page_load_metrics/browser/page_load_tracker.cc
@@ -371,23 +371,10 @@
       /*permit_forwarding=*/false);
 }
 
-void PageLoadTracker::SubFrameDeleted(int frame_tree_node_id) {
-  if (parent_tracker_) {
-    // Notify the parent of inner subframe deletions.
-    parent_tracker_->SubFrameDeleted(frame_tree_node_id);
-  }
-  metrics_update_dispatcher_.OnSubFrameDeleted(frame_tree_node_id);
-  largest_contentful_paint_handler_.OnSubFrameDeleted(frame_tree_node_id);
-  for (const auto& observer : observers_) {
-    observer->OnSubFrameDeleted(frame_tree_node_id);
-  }
-}
-
 void PageLoadTracker::RenderFrameDeleted(content::RenderFrameHost* rfh) {
   if (parent_tracker_) {
-    // Notify the parent of the inner main frame deletion as a sub-frame
-    // deletion.
-    parent_tracker_->SubFrameDeleted(rfh->GetFrameTreeNodeId());
+    // Notify the parent of a deletion of RenderFrameHost of a subframe.
+    parent_tracker_->RenderFrameDeleted(rfh);
   }
 
   for (const auto& observer : observers_) {
@@ -395,6 +382,19 @@
   }
 }
 
+void PageLoadTracker::FrameTreeNodeDeleted(int frame_tree_node_id) {
+  if (parent_tracker_) {
+    // Notify the parent of a deletion of FrameTreeNode of a subframe.
+    parent_tracker_->FrameTreeNodeDeleted(frame_tree_node_id);
+  }
+
+  metrics_update_dispatcher_.OnSubFrameDeleted(frame_tree_node_id);
+  largest_contentful_paint_handler_.OnSubFrameDeleted(frame_tree_node_id);
+  for (const auto& observer : observers_) {
+    observer->OnSubFrameDeleted(frame_tree_node_id);
+  }
+}
+
 void PageLoadTracker::WillProcessNavigationResponse(
     content::NavigationHandle* navigation_handle) {
   DCHECK(!navigation_request_id_.has_value());
diff --git a/components/page_load_metrics/browser/page_load_tracker.h b/components/page_load_metrics/browser/page_load_tracker.h
index feb81268..055c61d2 100644
--- a/components/page_load_metrics/browser/page_load_tracker.h
+++ b/components/page_load_metrics/browser/page_load_tracker.h
@@ -283,7 +283,7 @@
   void PageHidden();
   void PageShown();
   void RenderFrameDeleted(content::RenderFrameHost* rfh);
-  void SubFrameDeleted(int frame_tree_node_id);
+  void FrameTreeNodeDeleted(int frame_tree_node_id);
 
   void OnInputEvent(const blink::WebInputEvent& event);
 
diff --git a/components/page_load_metrics/browser/page_load_tracker_unittest.cc b/components/page_load_metrics/browser/page_load_tracker_unittest.cc
index 0a3f8a4..7d84f53 100644
--- a/components/page_load_metrics/browser/page_load_tracker_unittest.cc
+++ b/components/page_load_metrics/browser/page_load_tracker_unittest.cc
@@ -18,12 +18,13 @@
 const char kTestUrl[] = "https://a.test/";
 
 struct PageLoadMetricsObserverEvents final {
-  bool was_ready_to_commit_next_navigation = false;
+  size_t ready_to_commit_next_navigation_count = 0;
   bool was_started = false;
   bool was_fenced_frames_started = false;
   bool was_prerender_started = false;
   bool was_committed = false;
-  bool was_sub_frame_deleted = false;
+  size_t render_frame_deleted_count = 0;
+  size_t sub_frame_deleted_count = 0;
   bool was_prerendered_page_activated = false;
   size_t sub_frame_navigation_count = 0;
 };
@@ -39,8 +40,7 @@
  private:
   void ReadyToCommitNextNavigation(
       content::NavigationHandle* navigation_handle) override {
-    EXPECT_FALSE(events_->was_ready_to_commit_next_navigation);
-    events_->was_ready_to_commit_next_navigation = true;
+    events_->ready_to_commit_next_navigation_count++;
   }
   ObservePolicy OnStart(content::NavigationHandle* navigation_handle,
                         const GURL& currently_committed_url,
@@ -72,8 +72,11 @@
       content::NavigationHandle* navigation_handle) override {
     events_->sub_frame_navigation_count++;
   }
+  void OnRenderFrameDeleted(content::RenderFrameHost* rfh) override {
+    events_->render_frame_deleted_count++;
+  }
   void OnSubFrameDeleted(int frame_tree_node_id) override {
-    events_->was_sub_frame_deleted = true;
+    events_->sub_frame_deleted_count++;
   }
   void DidActivatePrerenderedPage(
       content::NavigationHandle* navigation_handle) override {
@@ -152,28 +155,36 @@
   tester()->NavigateToUntrackedUrl();
 
   // Check observer behaviors.
-  EXPECT_TRUE(GetEvents().was_ready_to_commit_next_navigation);
+  EXPECT_EQ(1u, GetEvents().ready_to_commit_next_navigation_count);
 
   // Check ukm::SourceId.
   EXPECT_NE(ukm::kInvalidSourceId, GetObservedUkmSourceIdFor(kTestUrl));
 }
 
 TEST_F(PageLoadTrackerTest, EventForwarding) {
+  // In the end, we'll construct frame trees as the following:
+  //
+  //   A     : primary main frame
+  //   +- B' : outer dummy node of B
+  //
+  //   B     : fenced frame
+  //   +- C  : iframe
+
   // Target URL to monitor the tracker via the test observer.
   SetTargetUrl(kTestUrl);
   StopObservingOnFencedFrames();
 
-  // Navigate in.
+  // A: Navigate in.
   NavigateAndCommit(GURL(kTestUrl));
 
-  // Add a fenced frame.
-  content::RenderFrameHost* fenced_frame_root =
+  // B: Add and navigate in.
+  content::RenderFrameHost* rfh_b =
       content::RenderFrameHostTester::For(web_contents()->GetPrimaryMainFrame())
           ->AppendFencedFrame();
   {
-    const char kFencedFramesUrl[] = "https://a.test/fenced_frames";
+    const char kURL[] = "https://a.test/fenced_frames";
     auto simulator = content::NavigationSimulator::CreateRendererInitiated(
-        GURL(kFencedFramesUrl), fenced_frame_root);
+        GURL(kURL), rfh_b);
     ASSERT_NE(nullptr, simulator);
     simulator->Commit();
   }
@@ -185,24 +196,87 @@
   EXPECT_FALSE(GetEvents().was_fenced_frames_started);
   EXPECT_FALSE(GetEvents().was_prerender_started);
   EXPECT_TRUE(GetEvents().was_committed);
-  EXPECT_FALSE(GetEvents().was_sub_frame_deleted);
   EXPECT_EQ(1u, GetEvents().sub_frame_navigation_count);
+  // MetricsWebContentsObserver::RenderFrameDeleted is called in the first
+  // navigation for iframes but not for fenced frames.
+  // TODO(https://crbug.com/1301880): Make a reason clear.
+  EXPECT_EQ(0u, GetEvents().render_frame_deleted_count);
+  EXPECT_EQ(0u, GetEvents().sub_frame_deleted_count);
 
-  // Navigate out.
+  // B: Navigate out.
+  content::RenderFrameHost* rfh_b_last = nullptr;
   {
-    const char kFencedFramesNavigationUrl[] = "https://b.test/fenced_frames";
+    const char kURL[] = "https://b.test/fenced_frames";
     auto simulator = content::NavigationSimulator::CreateRendererInitiated(
-        GURL(kFencedFramesNavigationUrl), fenced_frame_root);
+        GURL(kURL), rfh_b);
     ASSERT_NE(nullptr, simulator);
     simulator->Commit();
+
+    rfh_b_last = simulator->GetFinalRenderFrameHost();
   }
 
-  // Check observer behaviors again after the render frame's deletion.
-  // TODO(https://crbug.com/1301880): RenderFrameDeleted() doesn't seem called
-  // and following check fails. Revisit this issue later to clarify the
-  // expectations.
-  // EXPECT_TRUE(GetEvents().was_sub_frame_deleted);
-  EXPECT_EQ(2u, GetEvents().sub_frame_navigation_count);
+  // "0" is wrong, "1" is correct.
+  // See comment of MetricsWebContentsObserver::GetPageLoadTracker.
+  EXPECT_EQ(0u, GetEvents().render_frame_deleted_count);
+  EXPECT_EQ(0u, GetEvents().sub_frame_deleted_count);
+
+  // C: Add and navigate in.
+  content::RenderFrameHost* rfh_c =
+      content::RenderFrameHostTester::For(rfh_b_last)->AppendChild("c");
+  content::RenderFrameHost* rfh_c_last = nullptr;
+  {
+    const char kURL[] = "https://a.test/iframe";
+    auto simulator = content::NavigationSimulator::CreateRendererInitiated(
+        GURL(kURL), rfh_c);
+    ASSERT_NE(nullptr, simulator);
+    simulator->Commit();
+
+    rfh_c_last = simulator->GetFinalRenderFrameHost();
+  }
+
+  // Note that deletion of RenderFrameHost depends on some conditions, e.g. Site
+  // Isolation and Back/Forward Cache. In unit tests, NavigationSimulator does
+  // delete them when a navigation commits. On Android, the two RenderFrameHost
+  // has same SiteInstance and the old one will be not deleted.
+#if BUILDFLAG(IS_ANDROID)
+  EXPECT_EQ(0u, GetEvents().render_frame_deleted_count);
+#else
+  EXPECT_EQ(1u, GetEvents().render_frame_deleted_count);
+#endif
+  EXPECT_EQ(0u, GetEvents().sub_frame_deleted_count);
+
+  // Remove C.
+  content::RenderFrameHostTester::For(rfh_c_last)->Detach();
+
+#if BUILDFLAG(IS_ANDROID)
+  EXPECT_EQ(1u, GetEvents().render_frame_deleted_count);
+#else
+  EXPECT_EQ(2u, GetEvents().render_frame_deleted_count);
+#endif
+  EXPECT_EQ(1u, GetEvents().sub_frame_deleted_count);
+
+  // Remove B.
+  content::RenderFrameHostTester::For(rfh_b_last)->Detach();
+
+#if BUILDFLAG(IS_ANDROID)
+  EXPECT_EQ(2u, GetEvents().render_frame_deleted_count);
+#else
+  EXPECT_EQ(3u, GetEvents().render_frame_deleted_count);
+#endif
+  // "2" may look good, but it is wrong, indeed. "1" is correct.
+  //
+  // When deleting a FF root node, methods of MetricsWebContentsObserver will be
+  // called in the order RenderFrameDeleted -> FrameDeleted. The former
+  // unregister PageLoadTracker corresponding to the given RenderFrameHost. The
+  // later shouldn't trigger an event because the target PageLoadTracker has
+  // gone already. Although, `sub_frame_deleted_count` is incremented because
+  // the logic of MetricsWebContentsObserver::GetPageLoadTracker is wrong: See
+  // comment of the method. (This behavior can be observerved by putting printf
+  // in PageLoadTracker::FrameTreeNodeDeleted and inspecting forwarding doesn't
+  // occur.)
+  // TODO(https://crbug.com/1301880): Fix
+  // MetricsWebContentsObserver::GetPageLoadTracker
+  EXPECT_EQ(2u, GetEvents().sub_frame_deleted_count);
 }
 
 TEST_F(PageLoadTrackerTest, PrerenderPageType) {
@@ -284,7 +358,7 @@
   }
 
   // Check observer behaviors.
-  EXPECT_TRUE(GetEvents().was_ready_to_commit_next_navigation);
+  EXPECT_EQ(1u, GetEvents().ready_to_commit_next_navigation_count);
 }
 
 TEST_F(PageLoadTrackerTest, StopObservingOnPrerender) {
diff --git a/components/paint_preview/player/android/BUILD.gn b/components/paint_preview/player/android/BUILD.gn
index f573976..82b047b 100644
--- a/components/paint_preview/player/android/BUILD.gn
+++ b/components/paint_preview/player/android/BUILD.gn
@@ -92,6 +92,7 @@
     "//base:base_java",
     "//base:jni_java",
     "//build/android:build_java",
+    "//chrome/browser/flags:java",
     "//components/browser_ui/styles/android:java",
     "//components/paint_preview/browser/android:java",
     "//content/public/android:content_java",
diff --git a/components/paint_preview/player/android/java/src/org/chromium/components/paintpreview/player/PlayerSwipeRefreshHandler.java b/components/paint_preview/player/android/java/src/org/chromium/components/paintpreview/player/PlayerSwipeRefreshHandler.java
index 7bf3cb6b..8b04788 100644
--- a/components/paint_preview/player/android/java/src/org/chromium/components/paintpreview/player/PlayerSwipeRefreshHandler.java
+++ b/components/paint_preview/player/android/java/src/org/chromium/components/paintpreview/player/PlayerSwipeRefreshHandler.java
@@ -67,7 +67,8 @@
 
     @Override
     public boolean start() {
-        return mSwipeRefreshLayout.start();
+        // TODO(1335416): Update this to |true| if experiment is successful
+        return mSwipeRefreshLayout.start(false);
     }
 
     @Override
diff --git a/components/services/app_service/public/cpp/intent_util.cc b/components/services/app_service/public/cpp/intent_util.cc
index 1de9866..62e85c5 100644
--- a/components/services/app_service/public/cpp/intent_util.cc
+++ b/components/services/app_service/public/cpp/intent_util.cc
@@ -92,6 +92,7 @@
 const char kIntentActionSendMultiple[] = "send_multiple";
 const char kIntentActionCreateNote[] = "create_note";
 const char kIntentActionEdit[] = "edit";
+const char kIntentActionPotentialFileHandler[] = "potential_file_handler";
 
 const char kUseBrowserForLink[] = "use_browser";
 
diff --git a/components/services/app_service/public/cpp/intent_util.h b/components/services/app_service/public/cpp/intent_util.h
index a673b8b..59daf1db 100644
--- a/components/services/app_service/public/cpp/intent_util.h
+++ b/components/services/app_service/public/cpp/intent_util.h
@@ -29,6 +29,7 @@
 extern const char kIntentActionCreateNote[];
 // A request to edit a file in an app. Must include an attached file.
 extern const char kIntentActionEdit[];
+extern const char kIntentActionPotentialFileHandler[];
 
 // App ID value which can be used as a Preferred App to denote that the browser
 // will open the link, and that we should not prompt the user about it.
diff --git a/components/services/app_service/public/cpp/permission.cc b/components/services/app_service/public/cpp/permission.cc
index fd22820a..ab57974 100644
--- a/components/services/app_service/public/cpp/permission.cc
+++ b/components/services/app_service/public/cpp/permission.cc
@@ -14,7 +14,8 @@
                    kNotifications,
                    kContacts,
                    kStorage,
-                   kPrinting)
+                   kPrinting,
+                   kFileHandling)
 APP_ENUM_TO_STRING(TriState, kAllow, kBlock, kAsk)
 
 PermissionValue::PermissionValue(bool bool_value) : bool_value(bool_value) {}
@@ -143,6 +144,8 @@
       return PermissionType::kStorage;
     case apps::mojom::PermissionType::kPrinting:
       return PermissionType::kPrinting;
+    case apps::mojom::PermissionType::kFileHandling:
+      return PermissionType::kFileHandling;
   }
 }
 
@@ -165,6 +168,8 @@
       return apps::mojom::PermissionType::kStorage;
     case PermissionType::kPrinting:
       return apps::mojom::PermissionType::kPrinting;
+    case PermissionType::kFileHandling:
+      return apps::mojom::PermissionType::kFileHandling;
   }
 }
 
diff --git a/components/services/app_service/public/cpp/permission.h b/components/services/app_service/public/cpp/permission.h
index 173d28c1..c65b2ce 100644
--- a/components/services/app_service/public/cpp/permission.h
+++ b/components/services/app_service/public/cpp/permission.h
@@ -24,7 +24,8 @@
      kNotifications,
      kContacts,
      kStorage,
-     kPrinting)
+     kPrinting,
+     kFileHandling)
 
 ENUM(TriState, kAllow, kBlock, kAsk)
 
diff --git a/components/services/app_service/public/mojom/types.mojom b/components/services/app_service/public/mojom/types.mojom
index c59aa337..fe129f1 100644
--- a/components/services/app_service/public/mojom/types.mojom
+++ b/components/services/app_service/public/mojom/types.mojom
@@ -118,6 +118,7 @@
   kContacts        = 5,
   kStorage         = 6,
   kPrinting        = 7,
+  kFileHandling    = 8,
 };
 
 // The types of apps available in the registry.
diff --git a/components/services/screen_ai/BUILD.gn b/components/services/screen_ai/BUILD.gn
index 789decb..a420bc3c 100644
--- a/components/services/screen_ai/BUILD.gn
+++ b/components/services/screen_ai/BUILD.gn
@@ -16,6 +16,7 @@
     "//components/services/screen_ai/public/cpp:utilities",
     "//components/services/screen_ai/public/mojom",
     "//mojo/public/cpp/bindings",
+    "//sandbox/policy",
     "//ui/accessibility:ax_base",
   ]
 }
diff --git a/components/services/screen_ai/DEPS b/components/services/screen_ai/DEPS
index 30107b9..3b50a0e 100644
--- a/components/services/screen_ai/DEPS
+++ b/components/services/screen_ai/DEPS
@@ -6,4 +6,5 @@
   "+ui/accessibility/ax_role_properties.h",
   "+ui/accessibility/ax_tree_update.h",
   "+ui/gfx/geometry",
+  "+sandbox/policy"
 ]
diff --git a/components/services/screen_ai/screen_ai_service_impl.cc b/components/services/screen_ai/screen_ai_service_impl.cc
index b5833f72..0e30a898 100644
--- a/components/services/screen_ai/screen_ai_service_impl.cc
+++ b/components/services/screen_ai/screen_ai_service_impl.cc
@@ -4,17 +4,34 @@
 
 #include "components/services/screen_ai/screen_ai_service_impl.h"
 
+#include "base/command_line.h"
+#include "base/files/file_path.h"
 #include "base/process/process.h"
 #include "components/services/screen_ai/proto/proto_convertor.h"
 #include "components/services/screen_ai/public/cpp/utilities.h"
+#include "sandbox/policy/switches.h"
 #include "ui/accessibility/accessibility_features.h"
 #include "ui/gfx/geometry/rect_f.h"
 
 namespace screen_ai {
 
+namespace {
+
+base::FilePath GetLibraryFilePath() {
+  base::FilePath library_path = GetPreloadedLibraryFilePath();
+  if (library_path.empty() && base::CommandLine::ForCurrentProcess()->HasSwitch(
+                                  sandbox::policy::switches::kNoSandbox)) {
+    library_path = GetLatestLibraryFilePath();
+    SetPreloadedLibraryFilePath(library_path);
+  }
+  return library_path;
+}
+
+}  // namespace
+
 ScreenAIService::ScreenAIService(
     mojo::PendingReceiver<mojom::ScreenAIService> receiver)
-    : library_(GetPreloadedLibraryFilePath()),
+    : library_(GetLibraryFilePath()),
       init_function_(
           reinterpret_cast<InitFunction>(library_.GetFunctionPointer("Init"))),
       annotate_function_(reinterpret_cast<AnnotateFunction>(
@@ -28,7 +45,7 @@
   if (!init_function_(features::IsScreenAIVisualAnnotationsEnabled(),
                       features::IsReadAnythingWithScreen2xEnabled(),
                       features::IsScreenAIDebugModeEnabled(),
-                      GetPreloadedLibraryFilePath().DirName().MaybeAsASCII())) {
+                      GetLibraryFilePath().DirName().MaybeAsASCII())) {
     // TODO(https://crbug.com/1278249): Add UMA metrics to monitor failures.
     VLOG(0) << "Screen AI library initialization failed.";
     base::Process::TerminateCurrentProcessImmediately(-1);
diff --git a/components/test/data/autofill_assistant/html/autofill_assistant_target_website.html b/components/test/data/autofill_assistant/html/autofill_assistant_target_website.html
index adace33..8c308b32 100644
--- a/components/test/data/autofill_assistant/html/autofill_assistant_target_website.html
+++ b/components/test/data/autofill_assistant/html/autofill_assistant_target_website.html
@@ -346,6 +346,7 @@
       Option <b>2</b>
       <input id="option2" type="checkbox" name="option2">
     </label>
+    <input id="option3" type="checkbox" name="option3" checked="true">
     <label id="bad_label1" for="doesnotexist">A label without an element</label>
     <label id="bad_label2">Another label without an element</label>
 
@@ -458,5 +459,12 @@
 
     <textarea id="textarea1">Initial textarea value.</textarea>
 
+    <label for="radio_red">Red
+      <input type="radio" id="radio_red" name="color_choice" value="red">
+    </label>
+    <label for="radio_blue">Blue
+      <input type="radio" id="radio_blue" name="color_choice" value="blue">
+    </label>
+
   </body>
 </html>
diff --git a/components/url_param_filter/core/url_param_classifications_loader.cc b/components/url_param_filter/core/url_param_classifications_loader.cc
index 04c168e71..de405a7 100644
--- a/components/url_param_filter/core/url_param_classifications_loader.cc
+++ b/components/url_param_filter/core/url_param_classifications_loader.cc
@@ -4,6 +4,7 @@
 
 #include "components/url_param_filter/core/url_param_classifications_loader.h"
 
+#include <optional>
 #include <string>
 #include <utility>
 
@@ -85,14 +86,10 @@
   return map;
 }
 
-// If this is called before `ReadClassifications` has read classifications from
-// the component, returns an empty map.
 ClassificationMap GetClassificationMap(
-    const absl::optional<std::vector<FilterClassification>>& classifications) {
-  if (!classifications.has_value())
-    return ClassificationMap();
+    const std::vector<FilterClassification>& classifications) {
   ClassificationMap map;
-  for (const FilterClassification& classification : classifications.value()) {
+  for (const FilterClassification& classification : classifications) {
     ProcessClassification(map, classification);
   }
   return map;
@@ -153,9 +150,10 @@
     }
   }
 
-  component_source_classifications_ = std::move(source_classifications);
-  component_destination_classifications_ =
-      std::move(destination_classifications);
+  component_source_classification_map_ =
+      GetClassificationMap(source_classifications);
+  component_destination_classification_map_ =
+      GetClassificationMap(destination_classifications);
 
   base::UmaHistogramCounts10000(
       "Navigation.UrlParamFilter.ApplicableClassificationCount.Source",
@@ -167,8 +165,8 @@
 
 void ClassificationsLoader::ResetListsForTesting() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  component_source_classifications_.reset();
-  component_destination_classifications_.reset();
+  component_source_classification_map_.reset();
+  component_destination_classification_map_.reset();
 }
 
 ClassificationsLoader::ClassificationsLoader() = default;
@@ -192,10 +190,14 @@
   // classifications.
   switch (role) {
     case FilterClassification_SiteRole::FilterClassification_SiteRole_SOURCE:
-      return GetClassificationMap(component_source_classifications_);
+      return component_source_classification_map_.has_value()
+                 ? component_source_classification_map_.value()
+                 : ClassificationMap();
     case FilterClassification_SiteRole::
         FilterClassification_SiteRole_DESTINATION:
-      return GetClassificationMap(component_destination_classifications_);
+      return component_destination_classification_map_.has_value()
+                 ? component_destination_classification_map_.value()
+                 : ClassificationMap();
     case FilterClassification_SiteRole_SITE_ROLE_UNKNOWN:
       return ClassificationMap();
   }
diff --git a/components/url_param_filter/core/url_param_classifications_loader.h b/components/url_param_filter/core/url_param_classifications_loader.h
index d696019..7f431f20 100644
--- a/components/url_param_filter/core/url_param_classifications_loader.h
+++ b/components/url_param_filter/core/url_param_classifications_loader.h
@@ -62,12 +62,10 @@
   ClassificationMap GetClassificationsInternal(
       FilterClassification_SiteRole role);
 
-  absl::optional<std::vector<FilterClassification>>
-      component_source_classifications_ GUARDED_BY_CONTEXT(sequence_checker_) =
-          absl::nullopt;
-  absl::optional<std::vector<FilterClassification>>
-      component_destination_classifications_
-          GUARDED_BY_CONTEXT(sequence_checker_) = absl::nullopt;
+  absl::optional<ClassificationMap> component_source_classification_map_
+      GUARDED_BY_CONTEXT(sequence_checker_) = absl::nullopt;
+  absl::optional<ClassificationMap> component_destination_classification_map_
+      GUARDED_BY_CONTEXT(sequence_checker_) = absl::nullopt;
 
   SEQUENCE_CHECKER(sequence_checker_);
 };
diff --git a/content/browser/navigation_browsertest.cc b/content/browser/navigation_browsertest.cc
index 8850a34c..66c9f58 100644
--- a/content/browser/navigation_browsertest.cc
+++ b/content/browser/navigation_browsertest.cc
@@ -5870,7 +5870,7 @@
   FrameTreeNode* child = main_frame()->child_at(0);
   EXPECT_EQ(iframe_url_1, child->current_url());
   EXPECT_FALSE(child->anonymous());
-  EXPECT_FALSE(child->current_frame_host()->anonymous());
+  EXPECT_FALSE(child->current_frame_host()->IsAnonymous());
   EXPECT_EQ(false,
             EvalJs(child->current_frame_host(), "window.isAnonymouslyFramed"));
 
@@ -5880,7 +5880,7 @@
       ExecJs(main_frame(),
              "document.getElementById('test_iframe').anonymous = true;"));
   EXPECT_TRUE(child->anonymous());
-  EXPECT_FALSE(child->current_frame_host()->anonymous());
+  EXPECT_FALSE(child->current_frame_host()->IsAnonymous());
   EXPECT_EQ(false,
             EvalJs(child->current_frame_host(), "window.isAnonymouslyFramed"));
 
@@ -5898,7 +5898,7 @@
   // attribute. The grandchild RenderFrameHost is not anonymous, since its
   // parent RenderFrameHost is not anonymous.
   EXPECT_FALSE(grandchild->anonymous());
-  EXPECT_FALSE(grandchild->current_frame_host()->anonymous());
+  EXPECT_FALSE(grandchild->current_frame_host()->IsAnonymous());
   EXPECT_EQ(false, EvalJs(grandchild->current_frame_host(),
                           "window.isAnonymouslyFramed"));
 
@@ -5909,7 +5909,7 @@
                                iframe_url_1.Resolve("#here").spec())));
   WaitForLoadStop(web_contents());
   EXPECT_TRUE(child->anonymous());
-  EXPECT_FALSE(child->current_frame_host()->anonymous());
+  EXPECT_FALSE(child->current_frame_host()->IsAnonymous());
   EXPECT_EQ(false,
             EvalJs(child->current_frame_host(), "window.isAnonymouslyFramed"));
 
@@ -5919,7 +5919,7 @@
                               iframe_url_2)));
   WaitForLoadStop(web_contents());
   EXPECT_TRUE(child->anonymous());
-  EXPECT_TRUE(child->current_frame_host()->anonymous());
+  EXPECT_TRUE(child->current_frame_host()->IsAnonymous());
   EXPECT_EQ(true,
             EvalJs(child->current_frame_host(), "window.isAnonymouslyFramed"));
   // An anonymous document has a storage key with a nonce.
@@ -5941,7 +5941,7 @@
   // The grandchild does not set the 'anonymous' attribute, but the grandchild
   // document is anonymous.
   EXPECT_FALSE(grandchild->anonymous());
-  EXPECT_TRUE(grandchild->current_frame_host()->anonymous());
+  EXPECT_TRUE(grandchild->current_frame_host()->IsAnonymous());
   EXPECT_EQ(true, EvalJs(grandchild->current_frame_host(),
                          "window.isAnonymouslyFramed"));
 
@@ -5956,7 +5956,7 @@
       child, JsReplace("document.getElementById('grandchild_iframe').src = $1",
                        iframe_url_2)));
   WaitForLoadStop(web_contents());
-  EXPECT_TRUE(grandchild->current_frame_host()->anonymous());
+  EXPECT_TRUE(grandchild->current_frame_host()->IsAnonymous());
   EXPECT_EQ(true, EvalJs(grandchild->current_frame_host(),
                          "window.isAnonymouslyFramed"));
 
@@ -5971,7 +5971,7 @@
       ExecJs(main_frame(),
              "document.getElementById('test_iframe').anonymous = false;"));
   EXPECT_FALSE(child->anonymous());
-  EXPECT_TRUE(child->current_frame_host()->anonymous());
+  EXPECT_TRUE(child->current_frame_host()->IsAnonymous());
   EXPECT_EQ(true,
             EvalJs(child->current_frame_host(), "window.isAnonymouslyFramed"));
   EXPECT_TRUE(child->current_frame_host()->storage_key().nonce().has_value());
@@ -5989,7 +5989,7 @@
   EXPECT_EQ(2U, child->child_count());
   FrameTreeNode* grandchild2 = child->child_at(1);
   EXPECT_FALSE(grandchild2->anonymous());
-  EXPECT_TRUE(grandchild2->current_frame_host()->anonymous());
+  EXPECT_TRUE(grandchild2->current_frame_host()->IsAnonymous());
   EXPECT_EQ(true, EvalJs(grandchild2->current_frame_host(),
                          "window.isAnonymouslyFramed"));
   EXPECT_TRUE(
@@ -6005,7 +6005,7 @@
                        iframe_url_2)));
   WaitForLoadStop(web_contents());
   EXPECT_FALSE(child->anonymous());
-  EXPECT_FALSE(child->current_frame_host()->anonymous());
+  EXPECT_FALSE(child->current_frame_host()->IsAnonymous());
   EXPECT_EQ(false,
             EvalJs(child->current_frame_host(), "window.isAnonymouslyFramed"));
   EXPECT_FALSE(child->current_frame_host()->storage_key().nonce().has_value());
@@ -6021,7 +6021,7 @@
   FrameTreeNode* child_b = main_frame()->child_at(0);
   EXPECT_EQ(iframe_url_b, child_b->current_url());
   EXPECT_TRUE(child_b->anonymous());
-  EXPECT_TRUE(child_b->current_frame_host()->anonymous());
+  EXPECT_TRUE(child_b->current_frame_host()->IsAnonymous());
   EXPECT_EQ(true, EvalJs(child_b->current_frame_host(),
                          "window.isAnonymouslyFramed"));
 
diff --git a/content/browser/renderer_host/cross_origin_opener_policy_status.cc b/content/browser/renderer_host/cross_origin_opener_policy_status.cc
index 596bc8d..8608333 100644
--- a/content/browser/renderer_host/cross_origin_opener_policy_status.cc
+++ b/content/browser/renderer_host/cross_origin_opener_policy_status.cc
@@ -204,7 +204,7 @@
   net::IsolationInfo isolation_info_for_subresources =
       frame_tree_node_->current_frame_host()
           ->ComputeIsolationInfoForSubresourcesForPendingCommit(
-              response_origin, navigation_request_->anonymous());
+              response_origin, navigation_request_->is_anonymous());
   DCHECK(!isolation_info_for_subresources.IsEmpty());
 
   // Set up endpoint if response contains Reporting-Endpoints header.
diff --git a/content/browser/renderer_host/navigation_controller_impl.cc b/content/browser/renderer_host/navigation_controller_impl.cc
index 32fa963..722942ea 100644
--- a/content/browser/renderer_host/navigation_controller_impl.cc
+++ b/content/browser/renderer_host/navigation_controller_impl.cc
@@ -3798,8 +3798,8 @@
           absl::nullopt /* ad_auction_components */,
           /*fenced_frame_reporting_metadata=*/nullptr,
           // This timestamp will be populated when the commit IPC is sent.
-          base::TimeTicks() /* commit_sent */, false /* anonymous */,
-          std::string() /* srcdoc_value */, false /* should_load_data_url */);
+          base::TimeTicks() /* commit_sent */, std::string() /* srcdoc_value */,
+          false /* should_load_data_url */);
 #if BUILDFLAG(IS_ANDROID)
   if (ValidateDataURLAsString(params.data_url_as_string)) {
     commit_params->data_url_as_string = params.data_url_as_string->data();
diff --git a/content/browser/renderer_host/navigation_entry_impl.cc b/content/browser/renderer_host/navigation_entry_impl.cc
index c2ac46a..0529006 100644
--- a/content/browser/renderer_host/navigation_entry_impl.cc
+++ b/content/browser/renderer_host/navigation_entry_impl.cc
@@ -922,8 +922,8 @@
           absl::nullopt /* ad_auction_components */,
           /*fenced_frame_reporting_metadata=*/nullptr,
           // This timestamp will be populated when the commit IPC is sent.
-          base::TimeTicks() /* commit_sent */, false /* anonymous */,
-          std::string() /* srcdoc_value */, false /* should_load_data_url */);
+          base::TimeTicks() /* commit_sent */, std::string() /* srcdoc_value */,
+          false /* should_load_data_url */);
 #if BUILDFLAG(IS_ANDROID)
   // `data_url_as_string` is saved in NavigationEntry but should only be used by
   // main frames, because loadData* navigations can only happen on the main
diff --git a/content/browser/renderer_host/navigation_policy_container_builder.cc b/content/browser/renderer_host/navigation_policy_container_builder.cc
index bb19a178..37c96fe 100644
--- a/content/browser/renderer_host/navigation_policy_container_builder.cc
+++ b/content/browser/renderer_host/navigation_policy_container_builder.cc
@@ -241,7 +241,8 @@
 PolicyContainerPolicies NavigationPolicyContainerBuilder::ComputeFinalPolicies(
     const GURL& url,
     bool is_inside_mhtml,
-    network::mojom::WebSandboxFlags frame_sandbox_flags) {
+    network::mojom::WebSandboxFlags frame_sandbox_flags,
+    bool is_anonymous) {
   PolicyContainerPolicies policies;
 
   // Policies are either inherited from another document for local scheme, or
@@ -262,17 +263,19 @@
   }
 
   ComputeSandboxFlags(is_inside_mhtml, frame_sandbox_flags, policies);
+  policies.is_anonymous = is_anonymous;
   return policies;
 }
 
 void NavigationPolicyContainerBuilder::ComputePolicies(
     const GURL& url,
     bool is_inside_mhtml,
-    network::mojom::WebSandboxFlags frame_sandbox_flags) {
+    network::mojom::WebSandboxFlags frame_sandbox_flags,
+    bool is_anonymous) {
   DCHECK(!HasComputedPolicies());
   ComputeIsWebSecureContext();
-  SetFinalPolicies(
-      ComputeFinalPolicies(url, is_inside_mhtml, frame_sandbox_flags));
+  SetFinalPolicies(ComputeFinalPolicies(url, is_inside_mhtml,
+                                        frame_sandbox_flags, is_anonymous));
 }
 
 bool NavigationPolicyContainerBuilder::HasComputedPolicies() const {
diff --git a/content/browser/renderer_host/navigation_policy_container_builder.h b/content/browser/renderer_host/navigation_policy_container_builder.h
index 5782eea..f7da9d5 100644
--- a/content/browser/renderer_host/navigation_policy_container_builder.h
+++ b/content/browser/renderer_host/navigation_policy_container_builder.h
@@ -149,7 +149,8 @@
   // called later, in which case it overrides the final policies.
   void ComputePolicies(const GURL& url,
                        bool is_inside_mhtml,
-                       network::mojom::WebSandboxFlags frame_sandbox_flags);
+                       network::mojom::WebSandboxFlags frame_sandbox_flags,
+                       bool is_anonymous);
 
   // Returns a reference to the policies of the new document, i.e. the policies
   // in the policy container host to be committed.
@@ -220,7 +221,8 @@
   PolicyContainerPolicies ComputeFinalPolicies(
       const GURL& url,
       bool is_inside_mhtml,
-      network::mojom::WebSandboxFlags frame_sandbox_flags);
+      network::mojom::WebSandboxFlags frame_sandbox_flags,
+      bool is_anonymous);
 
   // The policies of the parent document, if any.
   const std::unique_ptr<PolicyContainerPolicies> parent_policies_;
diff --git a/content/browser/renderer_host/navigation_policy_container_builder_browsertest.cc b/content/browser/renderer_host/navigation_policy_container_builder_browsertest.cc
index 1dfee339..1558fdd 100644
--- a/content/browser/renderer_host/navigation_policy_container_builder_browsertest.cc
+++ b/content/browser/renderer_host/navigation_policy_container_builder_browsertest.cc
@@ -182,8 +182,8 @@
   NavigationPolicyContainerBuilder builder(nullptr, nullptr, nullptr);
   builder.SetIPAddressSpace(network::mojom::IPAddressSpace::kPublic);
 
-  builder.ComputePolicies(GURL(), false,
-                          network::mojom::WebSandboxFlags::kNone);
+  builder.ComputePolicies(GURL(), false, network::mojom::WebSandboxFlags::kNone,
+                          /*anonymous=*/false);
 
   // This must be called on a task runner, hence the need for this test to be
   // a browser test and not a simple unit test.
@@ -232,7 +232,8 @@
   builder.AddContentSecurityPolicy(MakeTestCSP());
 
   builder.ComputePolicies(AboutBlankUrl(), false,
-                          network::mojom::WebSandboxFlags::kNone);
+                          network::mojom::WebSandboxFlags::kNone,
+                          /*anonymous=*/false);
 
   EXPECT_EQ(builder.FinalPolicies(), history_policies);
 }
@@ -276,7 +277,8 @@
   builder.AddContentSecurityPolicy(MakeTestCSP());
 
   builder.ComputePolicies(AboutSrcdocUrl(), false,
-                          network::mojom::WebSandboxFlags::kNone);
+                          network::mojom::WebSandboxFlags::kNone,
+                          /*anonymous=*/false);
 
   EXPECT_EQ(builder.FinalPolicies(), history_policies);
 }
@@ -320,7 +322,8 @@
   PolicyContainerPolicies history_policies = builder.HistoryPolicies()->Clone();
 
   builder.ComputePolicies(AboutBlankUrl(), false,
-                          network::mojom::WebSandboxFlags::kNone);
+                          network::mojom::WebSandboxFlags::kNone,
+                          /*anonymous=*/false);
   EXPECT_THAT(builder.HistoryPolicies(), Pointee(Eq(ByRef(history_policies))));
 
   builder.ComputePoliciesForError(false,
@@ -416,7 +419,8 @@
   PolicyContainerPolicies history_policies = builder.HistoryPolicies()->Clone();
 
   builder.ComputePolicies(GURL("http://foo.test"), false,
-                          network::mojom::WebSandboxFlags::kNone);
+                          network::mojom::WebSandboxFlags::kNone,
+                          /*anonymous=*/false);
 
   EXPECT_EQ(builder.FinalPolicies(), PolicyContainerPolicies());
 
@@ -424,7 +428,8 @@
   EXPECT_THAT(builder.HistoryPolicies(), Pointee(Eq(ByRef(history_policies))));
 
   builder.ComputePolicies(AboutBlankUrl(), false,
-                          network::mojom::WebSandboxFlags::kNone);
+                          network::mojom::WebSandboxFlags::kNone,
+                          /*anonymous=*/false);
 
   EXPECT_EQ(builder.FinalPolicies(), history_policies);
 }
diff --git a/content/browser/renderer_host/navigation_policy_container_builder_unittest.cc b/content/browser/renderer_host/navigation_policy_container_builder_unittest.cc
index 58cf2e8..b04d5c4 100644
--- a/content/browser/renderer_host/navigation_policy_container_builder_unittest.cc
+++ b/content/browser/renderer_host/navigation_policy_container_builder_unittest.cc
@@ -47,7 +47,8 @@
       network::mojom::IPAddressSpace::kPublic,
       /*is_web_secure_context=*/true, std::move(csp_list),
       network::CrossOriginOpenerPolicy(), network::CrossOriginEmbedderPolicy(),
-      network::mojom::WebSandboxFlags::kNone);
+      network::mojom::WebSandboxFlags::kNone,
+      /*is_anonymous=*/false);
 }
 
 // Shorthand.
@@ -141,8 +142,8 @@
 // container host.
 TEST_F(NavigationPolicyContainerBuilderTest, DefaultFinalPolicies) {
   NavigationPolicyContainerBuilder builder(nullptr, nullptr, nullptr);
-  builder.ComputePolicies(GURL(), false,
-                          network::mojom::WebSandboxFlags::kNone);
+  builder.ComputePolicies(GURL(), false, network::mojom::WebSandboxFlags::kNone,
+                          /*is_anonymous=*/false);
 
   PolicyContainerPolicies expected_policies;
   EXPECT_EQ(builder.FinalPolicies(), expected_policies);
@@ -163,7 +164,8 @@
   PolicyContainerPolicies delivered_policies =
       builder.DeliveredPoliciesForTesting().Clone();
   builder.ComputePolicies(GURL("https://foo.test"), false,
-                          network::mojom::WebSandboxFlags::kNone);
+                          network::mojom::WebSandboxFlags::kNone,
+                          /*is_anonymous=*/false);
 
   EXPECT_EQ(builder.FinalPolicies(), delivered_policies);
 }
@@ -177,7 +179,8 @@
   PolicyContainerPolicies delivered_policies =
       builder.DeliveredPoliciesForTesting().Clone();
   builder.ComputePolicies(AboutBlankUrl(), false,
-                          network::mojom::WebSandboxFlags::kNone);
+                          network::mojom::WebSandboxFlags::kNone,
+                          /*is_anonymous=*/false);
 
   EXPECT_EQ(builder.FinalPolicies(), delivered_policies);
 }
@@ -192,7 +195,8 @@
   PolicyContainerPolicies delivered_policies =
       builder.DeliveredPoliciesForTesting().Clone();
   builder.ComputePolicies(AboutBlankUrl(), false,
-                          network::mojom::WebSandboxFlags::kNone);
+                          network::mojom::WebSandboxFlags::kNone,
+                          /*is_anonymous=*/false);
 
   EXPECT_EQ(builder.FinalPolicies(), delivered_policies);
 }
@@ -234,7 +238,8 @@
   expected_policies.ip_address_space = network::mojom::IPAddressSpace::kPrivate;
 
   builder.ComputePolicies(GURL("https://foo.test"), false,
-                          network::mojom::WebSandboxFlags::kNone);
+                          network::mojom::WebSandboxFlags::kNone,
+                          /*is_anonymous=*/false);
   EXPECT_EQ(builder.FinalPolicies(), expected_policies);
 
   builder.ComputePoliciesForError(false,
@@ -250,7 +255,8 @@
       network::mojom::ContentSecurityPolicy::New());
 
   builder.ComputePolicies(GURL("https://foo.test"), false,
-                          network::mojom::WebSandboxFlags::kNone);
+                          network::mojom::WebSandboxFlags::kNone,
+                          /*is_anonymous=*/false);
   EXPECT_THAT(builder.FinalPolicies().content_security_policies, SizeIs(1));
 
   builder.ComputePoliciesForError(false,
@@ -301,7 +307,8 @@
   const blink::LocalFrameToken& token = initiator->GetFrameToken();
   NavigationPolicyContainerBuilder builder(nullptr, &token, nullptr);
   builder.ComputePolicies(AboutBlankUrl(), false,
-                          network::mojom::WebSandboxFlags::kNone);
+                          network::mojom::WebSandboxFlags::kNone,
+                          /*is_anonymous=*/false);
 
   EXPECT_EQ(builder.FinalPolicies(), initiator_policies);
 }
@@ -319,7 +326,8 @@
 
   builder.ComputePolicies(
       GURL("blob:https://example.com/016ece86-b7f9-4b07-88c2-a0e36b7f1dd6"),
-      false, network::mojom::WebSandboxFlags::kNone);
+      false, network::mojom::WebSandboxFlags::kNone,
+      /*is_anonymous=*/false);
 
   EXPECT_EQ(builder.FinalPolicies(), initiator_policies);
 }
@@ -342,7 +350,8 @@
   network::mojom::ContentSecurityPolicyPtr test_csp = MakeTestCSP();
   builder.AddContentSecurityPolicy(test_csp.Clone());
   builder.ComputePolicies(AboutBlankUrl(), false,
-                          network::mojom::WebSandboxFlags::kNone);
+                          network::mojom::WebSandboxFlags::kNone,
+                          /*is_anonymous=*/false);
 
   initiator_policies.content_security_policies.push_back(std::move(test_csp));
   EXPECT_EQ(builder.FinalPolicies(), initiator_policies);
@@ -379,7 +388,8 @@
 
   NavigationPolicyContainerBuilder builder(parent, nullptr, nullptr);
   builder.ComputePolicies(AboutSrcdocUrl(), false,
-                          network::mojom::WebSandboxFlags::kNone);
+                          network::mojom::WebSandboxFlags::kNone,
+                          /*is_anonymous=*/false);
 
   EXPECT_EQ(builder.FinalPolicies(), parent_policies);
 }
@@ -396,8 +406,8 @@
       builder.DeliveredPoliciesForTesting().Clone();
   EXPECT_TRUE(delivered_policies.is_web_secure_context);
 
-  builder.ComputePolicies(GURL(), false,
-                          network::mojom::WebSandboxFlags::kNone);
+  builder.ComputePolicies(GURL(), false, network::mojom::WebSandboxFlags::kNone,
+                          /*is_anonymous=*/false);
 
   EXPECT_EQ(builder.FinalPolicies(), delivered_policies);
 }
@@ -414,8 +424,8 @@
       builder.DeliveredPoliciesForTesting().Clone();
   EXPECT_FALSE(delivered_policies.is_web_secure_context);
 
-  builder.ComputePolicies(GURL(), false,
-                          network::mojom::WebSandboxFlags::kNone);
+  builder.ComputePolicies(GURL(), false, network::mojom::WebSandboxFlags::kNone,
+                          /*is_anonymous=*/false);
 
   EXPECT_EQ(builder.FinalPolicies(), delivered_policies);
 }
@@ -435,7 +445,8 @@
   builder.SetIsOriginPotentiallyTrustworthy(true);
 
   builder.ComputePolicies(GURL("https://foo.test"), false,
-                          network::mojom::WebSandboxFlags::kNone);
+                          network::mojom::WebSandboxFlags::kNone,
+                          /*is_anonymous=*/false);
 
   EXPECT_FALSE(builder.FinalPolicies().is_web_secure_context);
 }
@@ -459,7 +470,8 @@
   EXPECT_FALSE(delivered_policies.is_web_secure_context);
 
   builder.ComputePolicies(GURL("http://foo.test"), false,
-                          network::mojom::WebSandboxFlags::kNone);
+                          network::mojom::WebSandboxFlags::kNone,
+                          /*is_anonymous=*/false);
 
   EXPECT_EQ(builder.FinalPolicies(), delivered_policies);
 }
@@ -483,7 +495,8 @@
   EXPECT_TRUE(delivered_policies.is_web_secure_context);
 
   builder.ComputePolicies(GURL("https://foo.test"), false,
-                          network::mojom::WebSandboxFlags::kNone);
+                          network::mojom::WebSandboxFlags::kNone,
+                          /*is_anonymous=*/false);
 
   EXPECT_EQ(builder.FinalPolicies(), delivered_policies);
 }
@@ -504,7 +517,8 @@
   network::mojom::ContentSecurityPolicyPtr test_csp = MakeTestCSP();
   builder.AddContentSecurityPolicy(test_csp.Clone());
   builder.ComputePolicies(AboutSrcdocUrl(), false,
-                          network::mojom::WebSandboxFlags::kNone);
+                          network::mojom::WebSandboxFlags::kNone,
+                          /*is_anonymous=*/false);
 
   parent_policies.content_security_policies.push_back(std::move(test_csp));
   EXPECT_EQ(builder.FinalPolicies(), parent_policies);
@@ -514,16 +528,19 @@
 TEST_F(NavigationPolicyContainerBuilderTest, ComputePoliciesTwiceDCHECK) {
   NavigationPolicyContainerBuilder builder(nullptr, nullptr, nullptr);
   GURL url("https://foo.test");
-  builder.ComputePolicies(url, false, network::mojom::WebSandboxFlags::kNone);
+  builder.ComputePolicies(url, false, network::mojom::WebSandboxFlags::kNone,
+                          /*is_anonymous=*/false);
   EXPECT_DCHECK_DEATH(builder.ComputePolicies(
-      url, false, network::mojom::WebSandboxFlags::kNone));
+      url, false, network::mojom::WebSandboxFlags::kNone,
+      /*is_anonymous=*/false));
 }
 
 // Calling ComputePolicies() followed by ComputePoliciesForError() is supported.
 TEST_F(NavigationPolicyContainerBuilderTest, ComputePoliciesThenError) {
   NavigationPolicyContainerBuilder builder(nullptr, nullptr, nullptr);
   builder.ComputePolicies(GURL("https://foo.test"), false,
-                          network::mojom::WebSandboxFlags::kNone);
+                          network::mojom::WebSandboxFlags::kNone,
+                          /*is_anonymous=*/false);
   builder.ComputePoliciesForError(false,
                                   network::mojom::WebSandboxFlags::kNone);
 }
@@ -542,7 +559,8 @@
               Pointee(Eq(ByRef(initiator_policies))));
 
   builder.ComputePolicies(GURL("https://foo.test"), false,
-                          network::mojom::WebSandboxFlags::kNone);
+                          network::mojom::WebSandboxFlags::kNone,
+                          /*is_anonymous=*/false);
   EXPECT_THAT(builder.InitiatorPolicies(),
               Pointee(Eq(ByRef(initiator_policies))));
 
@@ -564,7 +582,8 @@
   EXPECT_THAT(builder.ParentPolicies(), Pointee(Eq(ByRef(parent_policies))));
 
   builder.ComputePolicies(GURL("https://foo.test"), false,
-                          network::mojom::WebSandboxFlags::kNone);
+                          network::mojom::WebSandboxFlags::kNone,
+                          /*is_anonymous=*/false);
   EXPECT_THAT(builder.ParentPolicies(), Pointee(Eq(ByRef(parent_policies))));
 
   builder.ComputePoliciesForError(false,
@@ -583,14 +602,16 @@
 
   NavigationPolicyContainerBuilder builder(parent, nullptr, nullptr);
   builder.ComputePolicies(GURL("https://foo.test"), false,
-                          network::mojom::WebSandboxFlags::kNone);
+                          network::mojom::WebSandboxFlags::kNone,
+                          /*is_anonymous=*/false);
   EXPECT_EQ(builder.FinalPolicies(), PolicyContainerPolicies());
 
   builder.ResetForCrossDocumentRestart();
   EXPECT_THAT(builder.ParentPolicies(), Pointee(Eq(ByRef(parent_policies))));
 
   builder.ComputePolicies(AboutSrcdocUrl(), false,
-                          network::mojom::WebSandboxFlags::kNone);
+                          network::mojom::WebSandboxFlags::kNone,
+                          /*is_anonymous=*/false);
   EXPECT_EQ(builder.FinalPolicies(), parent_policies);
 }
 
@@ -608,14 +629,16 @@
   NavigationPolicyContainerBuilder builder(nullptr, &token, nullptr);
 
   builder.ComputePolicies(GURL("https://foo.test"), false,
-                          network::mojom::WebSandboxFlags::kNone);
+                          network::mojom::WebSandboxFlags::kNone,
+                          /*is_anonymous=*/false);
   EXPECT_EQ(builder.FinalPolicies(), PolicyContainerPolicies());
 
   builder.ResetForCrossDocumentRestart();
   EXPECT_THAT(builder.InitiatorPolicies(),
               Pointee(Eq(ByRef(initiator_policies))));
   builder.ComputePolicies(AboutBlankUrl(), false,
-                          network::mojom::WebSandboxFlags::kNone);
+                          network::mojom::WebSandboxFlags::kNone,
+                          /*is_anonymous=*/false);
 
   EXPECT_EQ(builder.FinalPolicies(), initiator_policies);
 }
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc
index b19c9cb..dccbf4d 100644
--- a/content/browser/renderer_host/navigation_request.cc
+++ b/content/browser/renderer_host/navigation_request.cc
@@ -844,12 +844,12 @@
 }
 
 // Returns true if the parent's COEP policy `parent_coep` should block a child
-// embedded in an <iframe> loaded with `child_coep` policy. The `anonymous`
+// embedded in an <iframe> loaded with `child_coep` policy. The `is_anonymous`
 // parameter reflects whether the child will be loaded as an anonymous document.
 bool CoepBlockIframe(network::mojom::CrossOriginEmbedderPolicyValue parent_coep,
                      network::mojom::CrossOriginEmbedderPolicyValue child_coep,
-                     bool anonymous) {
-  return !anonymous &&
+                     bool is_anonymous) {
+  return !is_anonymous &&
          (network::CompatibleWithCrossOriginIsolated(parent_coep) &&
           !network::CompatibleWithCrossOriginIsolated(child_coep));
 }
@@ -885,12 +885,12 @@
   // TODO(https://github.com/whatwg/html/issues/6863): Remove the synchronous
   // about:blank navigation.
   if (is_synchronous_about_blank_navigation)
-    return current_document->anonymous();
+    return current_document->IsAnonymous();
 
   // The document to commit will be anonymous if either the iframe element
   // has the 'anonymous' attribute set or the parent document is anonymous.
-  bool parent_anonymous = parent_document && parent_document->anonymous();
-  return parent_anonymous || frame->anonymous();
+  bool parent_is_anonymous = parent_document && parent_document->IsAnonymous();
+  return parent_is_anonymous || frame->anonymous();
 }
 
 // This returns the navigation request's `is_fenced_frame_opaque_url` attribute.
@@ -1227,8 +1227,8 @@
           std::vector<GURL>(), absl::nullopt /* ad_auction_components */,
           /*fenced_frame_reporting_metadata=*/nullptr,
           // This timestamp will be populated when the commit IPC is sent.
-          base::TimeTicks() /* commit_sent */, false /* anonymous */,
-          std::string() /* srcdoc_value */, false /* should_load_data_url */);
+          base::TimeTicks() /* commit_sent */, std::string() /* srcdoc_value */,
+          false /* should_load_data_url */);
 
   // CreateRendererInitiated() should only be triggered when the navigation is
   // initiated by a frame in the same process.
@@ -1352,8 +1352,8 @@
           absl::nullopt /* ad_auction_components */,
           /*fenced_frame_reporting_metadata=*/nullptr,
           // This timestamp will be populated when the commit IPC is sent.
-          base::TimeTicks() /* commit_sent */, false /* anonymous */,
-          std::string() /* srcdoc_value */, false /* should_load_data_url */);
+          base::TimeTicks() /* commit_sent */, std::string() /* srcdoc_value */,
+          false /* should_load_data_url */);
   blink::mojom::BeginNavigationParamsPtr begin_params =
       blink::mojom::BeginNavigationParams::New();
   std::unique_ptr<NavigationRequest> navigation_request(new NavigationRequest(
@@ -1371,7 +1371,7 @@
       false /* was_opener_suppressed */, false /* is_pdf */));
 
   absl::optional<base::UnguessableToken> nonce =
-      render_frame_host->ComputeNonce(navigation_request->anonymous());
+      render_frame_host->ComputeNonce(navigation_request->is_anonymous());
   url::Origin top_level_origin =
       render_frame_host->ComputeTopFrameOrigin(origin);
   navigation_request->commit_params_->storage_key =
@@ -1460,8 +1460,9 @@
       initiator_frame_token_(begin_params_->initiator_frame_token),
       initiator_process_id_(initiator_process_id),
       was_opener_suppressed_(was_opener_suppressed),
-      anonymous_(IsDocumentToCommitAnonymous(frame_tree_node,
-                                             is_synchronous_renderer_commit)),
+      is_anonymous_(
+          IsDocumentToCommitAnonymous(frame_tree_node,
+                                      is_synchronous_renderer_commit)),
       previous_page_ukm_source_id_(
           frame_tree_node_->current_frame_host()->GetPageUkmSourceId()),
       is_pdf_(is_pdf),
@@ -4686,14 +4687,14 @@
   // instead of creating one from a URL which lacks opacity information.
   isolation_info_for_subresources_ =
       render_frame_host_->ComputeIsolationInfoForSubresourcesForPendingCommit(
-          origin, anonymous());
+          origin, is_anonymous());
   DCHECK(!isolation_info_for_subresources_.IsEmpty());
 
   // TODO(https://crbug.com/888079): The storage key's origin is ignored at the
   // moment. We will be able to use it once the browser can compute the origin
   // to commit.
   absl::optional<base::UnguessableToken> nonce =
-      render_frame_host_->ComputeNonce(anonymous());
+      render_frame_host_->ComputeNonce(is_anonymous());
   url::Origin top_level_origin =
       render_frame_host_->ComputeTopFrameOrigin(GetOriginToCommit());
   commit_params_->storage_key = blink::StorageKey::CreateWithOptionalNonce(
@@ -6826,7 +6827,7 @@
   // TODO(crbug.com/979296): Consider changing this code to copy an origin
   // instead of creating one from a URL which lacks opacity information.
   return frame_tree_node_->current_frame_host()
-      ->ComputeIsolationInfoForNavigation(common_params_->url, anonymous());
+      ->ComputeIsolationInfoForNavigation(common_params_->url, is_anonymous());
 }
 
 bool NavigationRequest::HasSubframeNavigationEntryCommitted() {
@@ -7186,7 +7187,8 @@
   // [spec]: 3. If parentPolicy's report-only value is compatible with
   // cross-origin isolation and responsePolicy's value is not, then queue a
   // cross-origin embedder policy inheritance violation [...].
-  if (CoepBlockIframe(parent_coep.report_only_value, coep.value, anonymous())) {
+  if (CoepBlockIframe(parent_coep.report_only_value, coep.value,
+                      is_anonymous())) {
     if (parent_coep_reporter) {
       parent_coep_reporter->QueueNavigationReport(redirect_chain_[0],
                                                   /*report_only=*/true);
@@ -7196,7 +7198,7 @@
   // [spec]: 4. If parentPolicy's value is not compatible with cross-origin
   // isolation or responsePolicy's value is compatible with cross-origin
   // isolation, then return true.
-  if (!CoepBlockIframe(parent_coep.value, coep.value, anonymous()))
+  if (!CoepBlockIframe(parent_coep.value, coep.value, is_anonymous()))
     return true;
 
   // [spec]: 5 Queue a cross-origin embedder policy inheritance violation with
@@ -7228,7 +7230,7 @@
   if (!parent_frame) {
     return absl::nullopt;
   }
-  if (anonymous()) {
+  if (is_anonymous()) {
     return absl::nullopt;
   }
   const auto& url = common_params_->url;
@@ -7262,7 +7264,7 @@
           network::mojom::CrossOriginOpenerPolicyValue::kSameOriginPlusCoep &&
       !CompatibleWithCrossOriginIsolated(
           policies.cross_origin_embedder_policy) &&
-      !anonymous_) {
+      !is_anonymous_) {
     NOTREACHED();
     base::debug::DumpWithoutCrashing();
     return false;
@@ -7450,7 +7452,8 @@
   DCHECK(!IsErrorPage());
 
   policy_container_builder_->ComputePolicies(
-      url, IsMhtmlOrSubframe(), commit_params_->frame_policy.sandbox_flags);
+      url, IsMhtmlOrSubframe(), commit_params_->frame_policy.sandbox_flags,
+      is_anonymous());
 
   commit_params_->sandbox_flags =
       policy_container_builder_->FinalPolicies().sandbox_flags;
diff --git a/content/browser/renderer_host/navigation_request.h b/content/browser/renderer_host/navigation_request.h
index 1f1af6f3..614cecd1 100644
--- a/content/browser/renderer_host/navigation_request.h
+++ b/content/browser/renderer_host/navigation_request.h
@@ -692,7 +692,7 @@
   void SetRequiredCSP(network::mojom::ContentSecurityPolicyPtr csp);
   network::mojom::ContentSecurityPolicyPtr TakeRequiredCSP();
 
-  bool anonymous() const { return anonymous_; }
+  bool is_anonymous() const { return is_anonymous_; }
 
   bool is_fenced_frame_opaque_url() const {
     return is_fenced_frame_opaque_url_;
@@ -1891,7 +1891,7 @@
   // Whether the document loaded by this navigation will be committed inside an
   // anonymous iframe. Documents loaded inside anonymous iframes get partitioned
   // storage and use a transient NetworkIsolationKey.
-  const bool anonymous_;
+  const bool is_anonymous_;
 
   // Non-nullopt from construction until |TakePolicyContainerHost()| is called.
   absl::optional<NavigationPolicyContainerBuilder> policy_container_builder_;
diff --git a/content/browser/renderer_host/navigation_request_unittest.cc b/content/browser/renderer_host/navigation_request_unittest.cc
index 3ff5d8a..5710b68 100644
--- a/content/browser/renderer_host/navigation_request_unittest.cc
+++ b/content/browser/renderer_host/navigation_request_unittest.cc
@@ -717,7 +717,7 @@
   navigation->Commit();
   child_document =
       static_cast<TestRenderFrameHost*>(navigation->GetFinalRenderFrameHost());
-  EXPECT_TRUE(child_document->anonymous());
+  EXPECT_TRUE(child_document->IsAnonymous());
   EXPECT_EQ(
       blink::StorageKey::CreateWithNonce(
           url::Origin::Create(kUrl),
diff --git a/content/browser/renderer_host/policy_container_host.cc b/content/browser/renderer_host/policy_container_host.cc
index 9e03ed3..e3c544f 100644
--- a/content/browser/renderer_host/policy_container_host.cc
+++ b/content/browser/renderer_host/policy_container_host.cc
@@ -49,7 +49,8 @@
                     rhs.content_security_policies.end()) &&
          lhs.cross_origin_opener_policy == rhs.cross_origin_opener_policy &&
          lhs.cross_origin_embedder_policy == rhs.cross_origin_embedder_policy &&
-         lhs.sandbox_flags == rhs.sandbox_flags;
+         lhs.sandbox_flags == rhs.sandbox_flags &&
+         lhs.is_anonymous == rhs.is_anonymous;
 }
 
 bool operator!=(const PolicyContainerPolicies& lhs,
@@ -101,6 +102,7 @@
       << " }";
 
   out << ", sandbox_flags: " << policies.sandbox_flags;
+  out << ", is_anonymous: " << policies.is_anonymous;
 
   return out << " }";
 }
@@ -115,14 +117,16 @@
         content_security_policies,
     const network::CrossOriginOpenerPolicy& cross_origin_opener_policy,
     const network::CrossOriginEmbedderPolicy& cross_origin_embedder_policy,
-    network::mojom::WebSandboxFlags sandbox_flags)
+    network::mojom::WebSandboxFlags sandbox_flags,
+    bool is_anonymous)
     : referrer_policy(referrer_policy),
       ip_address_space(ip_address_space),
       is_web_secure_context(is_web_secure_context),
       content_security_policies(std::move(content_security_policies)),
       cross_origin_opener_policy(cross_origin_opener_policy),
       cross_origin_embedder_policy(cross_origin_embedder_policy),
-      sandbox_flags(sandbox_flags) {}
+      sandbox_flags(sandbox_flags),
+      is_anonymous(is_anonymous) {}
 
 PolicyContainerPolicies::PolicyContainerPolicies(PolicyContainerPolicies&&) =
     default;
@@ -136,7 +140,7 @@
   return PolicyContainerPolicies(
       referrer_policy, ip_address_space, is_web_secure_context,
       mojo::Clone(content_security_policies), cross_origin_opener_policy,
-      cross_origin_embedder_policy, sandbox_flags);
+      cross_origin_embedder_policy, sandbox_flags, is_anonymous);
 }
 
 std::unique_ptr<PolicyContainerPolicies> PolicyContainerPolicies::ClonePtr()
@@ -218,7 +222,8 @@
       blink::mojom::PolicyContainerPolicies::New(
           policies_.cross_origin_embedder_policy.value,
           policies_.referrer_policy,
-          mojo::Clone(policies_.content_security_policies)),
+          mojo::Clone(policies_.content_security_policies),
+          policies_.is_anonymous),
       std::move(remote));
 }
 
diff --git a/content/browser/renderer_host/policy_container_host.h b/content/browser/renderer_host/policy_container_host.h
index f79fb3f..49d7fd66 100644
--- a/content/browser/renderer_host/policy_container_host.h
+++ b/content/browser/renderer_host/policy_container_host.h
@@ -35,7 +35,8 @@
           content_security_policies,
       const network::CrossOriginOpenerPolicy& cross_origin_opener_policy,
       const network::CrossOriginEmbedderPolicy& cross_origin_embedder_policy,
-      network::mojom::WebSandboxFlags sandbox_flags);
+      network::mojom::WebSandboxFlags sandbox_flags,
+      bool is_anonymous);
 
   // Instances of this type are move-only.
   PolicyContainerPolicies(const PolicyContainerPolicies&) = delete;
@@ -96,6 +97,11 @@
   // in addition to those which are set by the embedding frame.
   network::mojom::WebSandboxFlags sandbox_flags =
       network::mojom::WebSandboxFlags::kNone;
+
+  // https://wicg.github.io/anonymous-iframe/#spec-window-attribute
+  // True for window framed inside an anonymous iframe, directly or indirectly
+  // by one of its ancestors
+  bool is_anonymous = false;
 };
 
 // PolicyContainerPolicies structs are comparable for equality.
@@ -196,6 +202,8 @@
     policies_.sandbox_flags = sandbox_flags;
   }
 
+  void SetIsAnonymous() { policies_.is_anonymous = true; }
+
   // Return a PolicyContainer containing copies of the policies and a pending
   // mojo remote that can be used to update policies in this object. If called a
   // second time, it resets the receiver and creates a new PolicyContainer,
diff --git a/content/browser/renderer_host/policy_container_host_unittest.cc b/content/browser/renderer_host/policy_container_host_unittest.cc
index 0f597134..ed4437f 100644
--- a/content/browser/renderer_host/policy_container_host_unittest.cc
+++ b/content/browser/renderer_host/policy_container_host_unittest.cc
@@ -30,6 +30,7 @@
   network::CrossOriginOpenerPolicy cross_origin_opener_policy;
   network::CrossOriginEmbedderPolicy cross_origin_embedder_policy;
   network::mojom::WebSandboxFlags sandbox_flags;
+  bool is_anonymous;
 };
 
 }  // namespace
@@ -70,7 +71,8 @@
   PolicyContainerPolicies policies(network::mojom::ReferrerPolicy::kAlways,
                                    network::mojom::IPAddressSpace::kUnknown,
                                    /*is_web_secure_context=*/true,
-                                   std::move(csps), coop, coep, sandbox_flags);
+                                   std::move(csps), coop, coep, sandbox_flags,
+                                   /*is_anonymous=*/true);
 
   EXPECT_THAT(policies.Clone(), Eq(ByRef(policies)));
 }
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
index 651fb0c..381bb7d 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -1572,8 +1572,6 @@
       lifecycle_state_(lifecycle_state),
       inner_tree_main_frame_tree_node_id_(
           FrameTreeNode::kFrameTreeNodeInvalidId),
-      anonymous_(parent_ ? parent_->anonymous() || frame_tree_node_->anonymous()
-                         : false),
       code_cache_host_receivers_(
           GetProcess()->GetStoragePartition()->GetGeneratedCodeCacheContext()),
       fenced_frame_status_(
@@ -2989,6 +2987,12 @@
     sandbox_flags_to_commit |= csp->sandbox;
   }
   policy_container_host_->set_sandbox_flags(sandbox_flags_to_commit);
+
+  // The initial empty document's anonymous bit was inherited from the parent
+  // document. The frame's anonymous bit can also turn it one.
+  if (frame_tree_node_->anonymous()) {
+    policy_container_host_->SetIsAnonymous();
+  }
 }
 
 void RenderFrameHostImpl::SetPolicyContainerHost(
@@ -2996,6 +3000,10 @@
   policy_container_host_ = std::move(policy_container_host);
   policy_container_host_->AssociateWithFrameToken(GetFrameToken(),
                                                   GetProcess()->GetID());
+  // Top-level document are never anonymous.
+  // Note: It is never inherited from the opener, because they are forced to
+  // open windows using noopener.
+  CHECK(parent_ || !IsAnonymous());
 }
 
 void RenderFrameHostImpl::InitializePrivateNetworkRequestPolicy() {
@@ -3604,6 +3612,10 @@
   coop_access_report_manager_.set_coop_reporter(std::move(coop_reporter));
 }
 
+bool RenderFrameHostImpl::IsAnonymous() const {
+  return policy_container_host_->policies().is_anonymous;
+}
+
 void RenderFrameHostImpl::OnCreateChildFrame(
     int new_routing_id,
     mojo::PendingAssociatedRemote<mojom::Frame> frame_remote,
@@ -3736,8 +3748,9 @@
           ? url::Origin::Create(navigation_request->GetWebBundleURL())
           : GetLastCommittedOrigin();
 
-  isolation_info_ = ComputeIsolationInfoInternal(
-      origin, isolation_info_.request_type(), navigation_request->anonymous());
+  isolation_info_ =
+      ComputeIsolationInfoInternal(origin, isolation_info_.request_type(),
+                                   navigation_request->is_anonymous());
 
   // Separately, update the frame's last successful URL except for net error
   // pages, since those do not end up in the correct process after transfers
@@ -3834,25 +3847,25 @@
 
 net::IsolationInfo RenderFrameHostImpl::ComputeIsolationInfoForNavigation(
     const GURL& destination) {
-  return ComputeIsolationInfoForNavigation(destination, anonymous());
+  return ComputeIsolationInfoForNavigation(destination, IsAnonymous());
 }
 
 net::IsolationInfo RenderFrameHostImpl::ComputeIsolationInfoForNavigation(
     const GURL& destination,
-    bool anonymous) {
+    bool is_anonymous) {
   net::IsolationInfo::RequestType request_type =
       is_main_frame() ? net::IsolationInfo::RequestType::kMainFrame
                       : net::IsolationInfo::RequestType::kSubFrame;
   return ComputeIsolationInfoInternal(url::Origin::Create(destination),
-                                      request_type, anonymous);
+                                      request_type, is_anonymous);
 }
 
 net::IsolationInfo
 RenderFrameHostImpl::ComputeIsolationInfoForSubresourcesForPendingCommit(
     const url::Origin& main_world_origin,
-    bool anonymous) {
+    bool is_anonymous) {
   return ComputeIsolationInfoInternal(
-      main_world_origin, net::IsolationInfo::RequestType::kOther, anonymous);
+      main_world_origin, net::IsolationInfo::RequestType::kOther, is_anonymous);
 }
 
 net::SiteForCookies RenderFrameHostImpl::ComputeSiteForCookies() {
@@ -3862,7 +3875,7 @@
 net::IsolationInfo RenderFrameHostImpl::ComputeIsolationInfoInternal(
     const url::Origin& frame_origin,
     net::IsolationInfo::RequestType request_type,
-    bool anonymous) {
+    bool is_anonymous) {
   url::Origin top_frame_origin = ComputeTopFrameOrigin(frame_origin);
   net::SchemefulSite top_frame_site = net::SchemefulSite(top_frame_origin);
 
@@ -3905,25 +3918,25 @@
     candidate_site_for_cookies = net::SiteForCookies(top_frame_site);
   }
 
-  absl::optional<base::UnguessableToken> nonce = ComputeNonce(anonymous);
+  absl::optional<base::UnguessableToken> nonce = ComputeNonce(is_anonymous);
   return net::IsolationInfo::Create(
       request_type, top_frame_origin, frame_origin, candidate_site_for_cookies,
       std::move(party_context), nonce ? &nonce.value() : nullptr);
 }
 
 absl::optional<base::UnguessableToken> RenderFrameHostImpl::ComputeNonce(
-    bool anonymous) {
+    bool is_anonymous) {
   absl::optional<base::UnguessableToken> nonce;
 
   // If it's an anonymous frame tree, use its nonce even if it's within a fenced
   // frame tree to maintain the guarantee that an anonymous frame tree has
   // a unique nonce. Otherwise, use the fenced frame nonce for fenced frames.
   // Note that MPArch will ensure that fenced frame tree within an anonymous
-  // iframe does not have `anonymous` set to true. The ShadowDOM architecture
+  // iframe does not have `is_anonymous` set to true. The ShadowDOM architecture
   // cannot make the same guarantee that MPArch will, and therefore the shadow
   // DOM version and will lead to the anonymous iframe nonce being used
   // (crbug.com/1249865).
-  if (anonymous) {
+  if (is_anonymous) {
     nonce = GetPage().anonymous_iframes_nonce();
   } else {
     nonce = frame_tree_node_->fenced_frame_nonce();
@@ -4003,7 +4016,7 @@
                                      ? new_frame_creator.DeriveNewOpaqueOrigin()
                                      : new_frame_creator;
   isolation_info_ = ComputeIsolationInfoInternal(
-      new_frame_origin, net::IsolationInfo::RequestType::kOther, anonymous());
+      new_frame_origin, net::IsolationInfo::RequestType::kOther, IsAnonymous());
   SetLastCommittedOrigin(new_frame_origin);
 
   SetStorageKey(CalculateStorageKey(
@@ -7167,7 +7180,7 @@
   }
 
   RenderFrameHostImpl* top_level_opener = GetMainFrame();
-  if (anonymous_ || IsNestedWithinFencedFrame()) {
+  if (IsAnonymous() || IsNestedWithinFencedFrame()) {
     params->opener_suppressed = true;
     params->frame_name.clear();
   } else {
@@ -8481,7 +8494,6 @@
   DCHECK(navigation_request);
   DCHECK_EQ(this, navigation_request->GetRenderFrameHost());
 
-  commit_params->anonymous = navigation_request->anonymous();
   bool is_same_document =
       NavigationTypeUtils::IsSameDocument(common_params->navigation_type);
   bool is_mhtml_subframe = navigation_request->IsForMhtmlSubframe();
@@ -10651,7 +10663,7 @@
   DCHECK(!is_same_document_history_api_navigation || is_same_document);
 
   net::IsolationInfo isolation_info = ComputeIsolationInfoInternal(
-      origin, net::IsolationInfo::RequestType::kOther, anonymous());
+      origin, net::IsolationInfo::RequestType::kOther, IsAnonymous());
 
   std::unique_ptr<CrossOriginEmbedderPolicyReporter> coep_reporter;
   // We don't switch the COEP reporter on same-document navigations, so create
@@ -11620,7 +11632,6 @@
   // Store the required CSP (it will be used by the AncestorThrottle if
   // this frame embeds a subframe when that subframe navigates).
   required_csp_ = navigation_request->TakeRequiredCSP();
-  anonymous_ = navigation_request->anonymous();
 
   is_fenced_frame_opaque_url_ =
       navigation_request->is_fenced_frame_opaque_url();
diff --git a/content/browser/renderer_host/render_frame_host_impl.h b/content/browser/renderer_host/render_frame_host_impl.h
index 39e4e47..5a249a7 100644
--- a/content/browser/renderer_host/render_frame_host_impl.h
+++ b/content/browser/renderer_host/render_frame_host_impl.h
@@ -730,23 +730,24 @@
   const url::Origin& ComputeTopFrameOrigin(
       const url::Origin& frame_origin) const;
 
-  // Computes the IsolationInfo for this frame to `destination`. Set `anonymous`
-  // to true if the navigation will be loaded as anonymous document (note that
-  // the navigation might be committing an anonymous document even if the
-  // document currently loaded in this RFH is not anonymous, and vice versa).
+  // Computes the IsolationInfo for this frame to `destination`. Set
+  // `is_anonymous` to true if the navigation will be loaded as anonymous
+  // document (note that the navigation might be committing an anonymous
+  // document even if the document currently loaded in this RFH is not
+  // anonymous, and vice versa).
   net::IsolationInfo ComputeIsolationInfoForNavigation(const GURL& destination,
-                                                       bool anonymous);
+                                                       bool is_anonymous);
 
   // Computes the IsolationInfo for this frame to |destination|.
   net::IsolationInfo ComputeIsolationInfoForNavigation(const GURL& destination);
 
   // Computes the IsolationInfo that should be used for subresources, if
   // |main_world_origin_for_url_loader_factory| is committed to this frame. The
-  // boolean `anonymous` specifies whether this frame will commit an anonymous
-  // document.
+  // boolean `is_anonymous` specifies whether this frame will commit an
+  // anonymous document.
   net::IsolationInfo ComputeIsolationInfoForSubresourcesForPendingCommit(
       const url::Origin& main_world_origin_for_url_loader_factory,
-      bool anonymous);
+      bool is_anonymous);
 
   // Computes site_for_cookies for this frame. A non-empty result denotes which
   // domains are considered first-party to the top-level site when resources are
@@ -1868,7 +1869,7 @@
     return required_csp_.get();
   }
 
-  bool anonymous() const { return anonymous_; }
+  bool IsAnonymous() const;
 
   bool is_fenced_frame_opaque_url() const {
     return is_fenced_frame_opaque_url_;
@@ -2406,7 +2407,7 @@
   RenderFrameHostImpl* GetParentOrOuterDocumentOrEmbedder() const;
 
   // Computes the nonce to be used for isolation info and storage key.
-  absl::optional<base::UnguessableToken> ComputeNonce(bool anonymous);
+  absl::optional<base::UnguessableToken> ComputeNonce(bool is_anonymous);
 
   // Return the frame immediately preceding this RenderFrameHost in its parent's
   // children, or nullptr if there is no such node.
@@ -2695,7 +2696,7 @@
   net::IsolationInfo ComputeIsolationInfoInternal(
       const url::Origin& frame_origin,
       net::IsolationInfo::RequestType request_type,
-      bool anonymous);
+      bool is_anonymous);
 
   // Returns whether or not this RenderFrameHost is a descendant of |ancestor|.
   // This is equivalent to check that |ancestor| is reached by iterating on
@@ -4177,10 +4178,6 @@
   // stored when the frame commits the navigation.
   network::mojom::ContentSecurityPolicyPtr required_csp_;
 
-  // Whether the current document is loaded inside an anonymous iframe. Updated
-  // on every cross-document navigation.
-  bool anonymous_ = false;
-
   // Indicates whether the fenced frame is navigated to an opaque url. This flag
   // can only change when the embedder navigates the fenced frame. Any
   // subsequent navigation from the fenced frame root will keep the same flag.
diff --git a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
index a8c12e40..6e1a105 100644
--- a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
+++ b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
@@ -6433,13 +6433,13 @@
                      "document.body.appendChild(child);"));
   WaitForLoadStop(web_contents());
 
-  EXPECT_FALSE(main_rfh->anonymous());
+  EXPECT_FALSE(main_rfh->IsAnonymous());
   EXPECT_EQ(false, EvalJs(main_rfh, "window.isAnonymouslyFramed"));
   EXPECT_FALSE(main_rfh->storage_key().nonce().has_value());
 
   EXPECT_EQ(1U, main_rfh->child_count());
   EXPECT_TRUE(main_rfh->child_at(0)->anonymous());
-  EXPECT_FALSE(main_rfh->child_at(0)->current_frame_host()->anonymous());
+  EXPECT_FALSE(main_rfh->child_at(0)->current_frame_host()->IsAnonymous());
   EXPECT_EQ(true, EvalJs(main_rfh->child_at(0)->current_frame_host(),
                          "window.isAnonymouslyFramed"));
   EXPECT_FALSE(main_rfh->child_at(0)
@@ -6552,7 +6552,7 @@
     WaitForLoadStop(web_contents());
     EXPECT_EQ(1U, main_rfh->child_count());
     RenderFrameHostImpl* iframe = main_rfh->child_at(0)->current_frame_host();
-    EXPECT_EQ(anonymous, iframe->anonymous());
+    EXPECT_EQ(anonymous, iframe->IsAnonymous());
     EXPECT_EQ(anonymous, EvalJs(iframe, "window.isAnonymouslyFramed"));
 
     ResetNetworkState();
diff --git a/content/browser/renderer_host/render_frame_host_impl_unittest.cc b/content/browser/renderer_host/render_frame_host_impl_unittest.cc
index 724205a..c01b44c9 100644
--- a/content/browser/renderer_host/render_frame_host_impl_unittest.cc
+++ b/content/browser/renderer_host/render_frame_host_impl_unittest.cc
@@ -364,16 +364,16 @@
 }
 
 TEST_F(RenderFrameHostImplTest, ChildOfAnonymousIsAnonymous) {
-  EXPECT_FALSE(main_test_rfh()->anonymous());
+  EXPECT_FALSE(main_test_rfh()->IsAnonymous());
 
   auto* child_frame = static_cast<TestRenderFrameHost*>(
       content::RenderFrameHostTester::For(main_test_rfh())
           ->AppendChild("child"));
-  EXPECT_FALSE(child_frame->anonymous());
+  EXPECT_FALSE(child_frame->IsAnonymous());
   EXPECT_FALSE(child_frame->storage_key().nonce().has_value());
 
   child_frame->frame_tree_node()->SetAnonymous(true);
-  EXPECT_FALSE(child_frame->anonymous());
+  EXPECT_FALSE(child_frame->IsAnonymous());
   EXPECT_FALSE(child_frame->storage_key().nonce().has_value());
 
   // A navigation in the anonymous iframe commits an anonymous RFH.
@@ -383,7 +383,7 @@
   navigation->Commit();
   child_frame =
       static_cast<TestRenderFrameHost*>(navigation->GetFinalRenderFrameHost());
-  EXPECT_TRUE(child_frame->anonymous());
+  EXPECT_TRUE(child_frame->IsAnonymous());
   EXPECT_TRUE(child_frame->storage_key().nonce().has_value());
 
   // An anonymous document sets a nonce on its network isolation key.
@@ -395,7 +395,7 @@
   auto* grandchild_frame = static_cast<TestRenderFrameHost*>(
       content::RenderFrameHostTester::For(child_frame)
           ->AppendChild("grandchild"));
-  EXPECT_TRUE(grandchild_frame->anonymous());
+  EXPECT_TRUE(grandchild_frame->IsAnonymous());
   EXPECT_TRUE(child_frame->storage_key().nonce().has_value());
 
   // The two anonymous RFH's storage keys should have the same nonce.
diff --git a/content/browser/renderer_host/unassigned_site_instance_browsertest.cc b/content/browser/renderer_host/unassigned_site_instance_browsertest.cc
index 5cf1fc6..f322e047 100644
--- a/content/browser/renderer_host/unassigned_site_instance_browsertest.cc
+++ b/content/browser/renderer_host/unassigned_site_instance_browsertest.cc
@@ -20,6 +20,7 @@
 #include "content/public/test/commit_message_delayer.h"
 #include "content/public/test/content_browser_test.h"
 #include "content/public/test/content_browser_test_utils.h"
+#include "content/public/test/content_mock_cert_verifier.h"
 #include "content/public/test/test_navigation_observer.h"
 #include "content/public/test/test_utils.h"
 #include "content/shell/browser/shell.h"
@@ -51,6 +52,7 @@
 // - Initial empty document in iframes.
 // - Navigation in an iframe, to about:blank, renderer initiated.
 // - Navigation in an iframe, to embedder defined url, renderer initiated.
+// - Interactions with crossOriginIsolated pages.
 // - Some bug reproducers, testing things like races and history navigations.
 
 namespace content {
@@ -114,7 +116,8 @@
     : public ContentBrowserTest,
       public ::testing::WithParamInterface<std::tuple<std::string, bool>> {
  public:
-  UnassignedSiteInstanceBrowserTest() {
+  UnassignedSiteInstanceBrowserTest()
+      : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {
     InitAndEnableRenderDocumentFeature(&feature_list_for_render_document_,
                                        std::get<0>(GetParam()));
     InitBackForwardCacheFeature(&feature_list_for_back_forward_cache_,
@@ -133,15 +136,27 @@
   }
 
   void SetUpOnMainThread() override {
+    // Allow all hosts on HTTPS.
+    mock_cert_verifier_.mock_cert_verifier()->set_default_result(net::OK);
     // Support multiple sites on the test server.
     host_resolver()->AddRule("*", "127.0.0.1");
+    https_server_.AddDefaultHandlers(GetTestDataFilePath());
     ASSERT_TRUE(embedded_test_server()->Start());
+    ASSERT_TRUE(https_server_.Start());
 
-    regular_url_ = embedded_test_server()->GetURL("a.test", "/title1.html");
+    regular_url_ = https_server_.GetURL("a.test", "/title1.html");
+    cross_origin_isolated_url_ =
+        https_server_.GetURL("a.test",
+                             "/set-header?"
+                             "Cross-Origin-Opener-Policy: same-origin&"
+                             "Cross-Origin-Embedder-Policy: require-corp");
     unassigned_url_ = GURL("about:blank");
     embedder_defined_unassigned_url_ = GURL(kEmptySchemeForTesting + "://test");
     embedder_defined_nonempty_unassigned_url_ =
-        embedded_test_server()->GetURL("b.test", "/title1.html");
+        https_server_.GetURL("b.test", "/title1.html");
+
+    regular_http_url_ =
+        embedded_test_server()->GetURL("a.test", "/title1.html");
 
     // Set up a URL for which ShouldAssignSiteForURL will return false. The
     // corresponding SiteInstance's site will be left unassigned, and its
@@ -160,10 +175,24 @@
       SetBrowserClientForTesting(old_content_browser_client_);
   }
 
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    mock_cert_verifier_.SetUpCommandLine(command_line);
+  }
+
+  void SetUpInProcessBrowserTestFixture() override {
+    mock_cert_verifier_.SetUpInProcessBrowserTestFixture();
+  }
+
+  void TearDownInProcessBrowserTestFixture() override {
+    mock_cert_verifier_.TearDownInProcessBrowserTestFixture();
+  }
+
   WebContentsImpl* web_contents() {
     return static_cast<WebContentsImpl*>(shell()->web_contents());
   }
 
+  net::EmbeddedTestServer* https_server() { return &https_server_; }
+
   void DisableBackForwardCache(
       BackForwardCacheImpl::DisableForTestingReason reason) const {
     return static_cast<WebContentsImpl*>(shell()->web_contents())
@@ -175,6 +204,12 @@
   // Returns an url that assigns a site to the SiteInstance it lives in.
   const GURL& regular_url() const { return regular_url_; }
 
+  // Returns an url that assigns a site to the SiteInstance it lives in and is
+  // crossOriginIsolated.
+  const GURL& cross_origin_isolated_url() const {
+    return cross_origin_isolated_url_;
+  }
+
   // Returns an url that does not assign a site to the SiteInstance it lives in.
   const GURL& unassigned_url() const { return unassigned_url_; }
 
@@ -192,12 +227,25 @@
     return embedder_defined_nonempty_unassigned_url_;
   }
 
+  // Returns an url that assigns a site to the SiteInstance it lives in, and
+  // that is served using HTTP.
+  const GURL& regular_http_url() const { return regular_http_url_; }
+
  private:
+  net::EmbeddedTestServer https_server_;
+  content::ContentMockCertVerifier mock_cert_verifier_;
+
   GURL regular_url_;
+  GURL cross_origin_isolated_url_;
   GURL unassigned_url_;
   GURL embedder_defined_unassigned_url_;
   GURL embedder_defined_nonempty_unassigned_url_;
 
+  // This is the only URL that uses HTTP instead of HTTPS, because
+  // IsolateOriginsForTesting() has a hardcoded HTTP filter in it. It should
+  // only be used for that specific purpose.
+  GURL regular_http_url_;
+
   std::unique_ptr<DontAssignSiteContentBrowserClient>
       content_browser_client_override_;
   raw_ptr<ContentBrowserClient> old_content_browser_client_ = nullptr;
@@ -585,6 +633,48 @@
   EXPECT_FALSE(post_navigation_si->IsRelatedSiteInstance(original_si.get()));
 }
 
+IN_PROC_BROWSER_TEST_P(UnassignedSiteInstanceBrowserTest,
+                       CrossOriginIsolated_BrowserInitiatedNavigationTo) {
+  // Get a base crossOriginIsolated page with a site.
+  EXPECT_TRUE(NavigateToURL(web_contents(), cross_origin_isolated_url()));
+  scoped_refptr<SiteInstanceImpl> initial_si =
+      web_contents()->GetPrimaryMainFrame()->GetSiteInstance();
+  EXPECT_TRUE(initial_si->HasSite());
+  EXPECT_TRUE(initial_si->IsCrossOriginIsolated());
+
+  // Do a browser initiated navigation to an unassigned url.
+  EXPECT_TRUE(NavigateToURL(shell(), unassigned_url()));
+  scoped_refptr<SiteInstanceImpl> unassigned_si =
+      web_contents()->GetPrimaryMainFrame()->GetSiteInstance();
+
+  // We explicitly disable SiteInstance reuse for now. Restricting which custom
+  // sites are allowed to be described by the embedder as unassigned might
+  // change that in the future.
+  EXPECT_FALSE(unassigned_si->HasSite());
+  EXPECT_FALSE(unassigned_si->IsRelatedSiteInstance(initial_si.get()));
+}
+
+IN_PROC_BROWSER_TEST_P(UnassignedSiteInstanceBrowserTest,
+                       CrossOriginIsolated_BrowserInitiatedNavigationFrom) {
+  // Get a base page without a site.
+  EXPECT_TRUE(NavigateToURL(web_contents(), unassigned_url()));
+  scoped_refptr<SiteInstanceImpl> unassigned_si =
+      web_contents()->GetPrimaryMainFrame()->GetSiteInstance();
+  EXPECT_FALSE(unassigned_si->HasSite());
+
+  // Do a browser-initiated navigation to a crossOriginIsolated assigned url. We
+  // should not reuse the unassigned SiteInstance currently, because we have no
+  // guarantee that the unassigned page won't load content in the process.
+  // Restricting which custom sites are allowed to be described by the embedder
+  // as unassigned might change that in the future.
+  EXPECT_TRUE(NavigateToURL(shell(), cross_origin_isolated_url()));
+  scoped_refptr<SiteInstanceImpl> initial_si =
+      web_contents()->GetPrimaryMainFrame()->GetSiteInstance();
+  EXPECT_TRUE(initial_si->HasSite());
+  EXPECT_TRUE(initial_si->IsCrossOriginIsolated());
+  EXPECT_FALSE(initial_si->IsRelatedSiteInstance(unassigned_si.get()));
+}
+
 // Regression test for https://crbug.com/1324407.
 // TODO(https://crbug.com/1296173): Require unassigned SiteInstances to have
 // empty document schemes, making the bug exercised in this test impossible.
@@ -596,8 +686,7 @@
     // Isolate a.test so that regular_url() is expected to be in a dedicated
     // process, but also so that embedder_defined_nonempty_unassigned_url
     // (i.e., b.test) does not expect a dedicated process on Android.
-    IsolateOriginsForTesting(embedded_test_server(), web_contents(),
-                             {"a.test"});
+    IsolateOriginsForTesting(https_server(), web_contents(), {"a.test"});
   }
 
   // Get a base page with an embedder-defined non-empty unassigned url.
@@ -627,7 +716,7 @@
   // This used to reuse the unassigned SiteInstance, even though the process had
   // already loaded a real page and the new URL requires a dedicated process.
   EXPECT_TRUE(NavigateToURLFromRenderer(
-      popup_web_contents->GetPrimaryMainFrame(), regular_url()));
+      popup_web_contents->GetPrimaryMainFrame(), regular_http_url()));
   scoped_refptr<SiteInstanceImpl> post_navigation_si =
       popup_web_contents->GetPrimaryMainFrame()->GetSiteInstance();
   EXPECT_NE(original_si, post_navigation_si);
@@ -682,7 +771,7 @@
   // In the popup, do a browser-initiated navigation to a regular url. This used
   // to reuse the unassigned SiteInstance, even though the process had already
   // loaded a real page and the new URL requires a dedicated process.
-  EXPECT_TRUE(NavigateToURL(popup_web_contents, regular_url()));
+  EXPECT_TRUE(NavigateToURL(popup_web_contents, regular_http_url()));
   scoped_refptr<SiteInstanceImpl> post_navigation_si =
       popup_web_contents->GetPrimaryMainFrame()->GetSiteInstance();
   EXPECT_NE(original_si, post_navigation_si);
@@ -821,7 +910,7 @@
   if (AreDefaultSiteInstancesEnabled()) {
     EXPECT_TRUE(instance1->IsDefaultSiteInstance());
   } else {
-    EXPECT_EQ(GURL("http://a.test"), instance1->GetSiteURL());
+    EXPECT_EQ(GURL("https://a.test"), instance1->GetSiteURL());
   }
 
   // The previously committed entry should get a new, related instance to avoid
@@ -840,7 +929,7 @@
 
   // Navigate to bar.com, which destroys the previous RenderProcessHost.
   GURL other_regular_url(
-      embedded_test_server()->GetURL("another.test", "/title1.html"));
+      https_server()->GetURL("another.test", "/title1.html"));
   RenderProcessHostWatcher exit_observer(
       process1, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
 
@@ -937,7 +1026,7 @@
   auto& current_isolation_context =
       root->current_frame_host()->GetSiteInstance()->GetIsolationContext();
   auto site_info = SiteInfo::CreateForTesting(current_isolation_context,
-                                              GURL("http://a.test"));
+                                              GURL("https://a.test"));
   EXPECT_TRUE(site_info.RequiresDedicatedProcess(current_isolation_context));
 
   // Set up the work to be done after the renderer is asked to commit
@@ -1020,11 +1109,11 @@
       web_contents->GetPrimaryMainFrame()->GetProcess();
   EXPECT_NE(process1, process2);
   EXPECT_EQ(
-      GURL("http://a.test"),
+      GURL("https://a.test"),
       web_contents->GetPrimaryMainFrame()->GetSiteInstance()->GetSiteURL());
   EXPECT_EQ(
       ProcessLock::FromSiteInfo(SiteInfo(
-          GURL("http://a.test"), GURL("http://a.test"),
+          GURL("https://a.test"), GURL("https://a.test"),
           false /* requires_origin_keyed_process */, false /* is_sandboxed */,
           StoragePartitionConfig::CreateDefault(browser_context),
           WebExposedIsolationInfo::CreateNonIsolated(), false /* is_guest */,
diff --git a/content/browser/security_exploit_browsertest.cc b/content/browser/security_exploit_browsertest.cc
index 3056011e..5ab6113 100644
--- a/content/browser/security_exploit_browsertest.cc
+++ b/content/browser/security_exploit_browsertest.cc
@@ -1971,6 +1971,7 @@
   GURL main_frame_url("http://foo.com/simple_page.html");
   std::vector<GURL> invalid_urls = {
       GURL("http://example.com"),
+      GURL("http://example.com?<\n=block"),
       GURL("about:srcdoc"),
       GURL("data:text/html,<p>foo"),
       GURL("blob:https://example.com/a9400bf5-aaa8-4166-86e4-492c50f4ca2b"),
diff --git a/content/browser/worker_host/worker_browsertest.cc b/content/browser/worker_host/worker_browsertest.cc
index a2a50f66..d1cbfd2 100644
--- a/content/browser/worker_host/worker_browsertest.cc
+++ b/content/browser/worker_host/worker_browsertest.cc
@@ -946,7 +946,7 @@
     WaitForLoadStop(shell()->web_contents());
     EXPECT_EQ(1U, main_rfh->child_count());
     RenderFrameHostImpl* iframe = main_rfh->child_at(0)->current_frame_host();
-    EXPECT_EQ(anonymous, iframe->anonymous());
+    EXPECT_EQ(anonymous, iframe->IsAnonymous());
     EXPECT_EQ(anonymous, EvalJs(iframe, "window.isAnonymouslyFramed"));
     ResetNetworkState();
 
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 5031ec5..27d727f2 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -1008,7 +1008,6 @@
   navigation_params->origin_agent_cluster_left_as_default =
       commit_params.origin_agent_cluster_left_as_default;
 
-  navigation_params->anonymous = commit_params.anonymous;
   navigation_params->enabled_client_hints.reserve(
       commit_params.enabled_client_hints.size());
   for (auto enabled_hint : commit_params.enabled_client_hints)
@@ -1104,6 +1103,7 @@
           in->policies->referrer_policy,
           ToWebContentSecurityPolicies(
               std::move(in->policies->content_security_policies)),
+          in->policies->is_anonymous,
       },
       std::move(in->remote));
 }
diff --git a/content/test/data/accessibility/aria/aria-level-expected-android.txt b/content/test/data/accessibility/aria/aria-level-expected-android.txt
index 8ee65fed..beaf438 100644
--- a/content/test/data/accessibility/aria/aria-level-expected-android.txt
+++ b/content/test/data/accessibility/aria/aria-level-expected-android.txt
@@ -7,6 +7,10 @@
 ++++++android.view.View clickable collection_item name='Tree item at level 1'
 ++++++android.view.View clickable collection_item name='Tree item at level 2'
 ++++android.view.View clickable name='Tree item at level 3'
+++++android.view.View clickable name='Tree item at level 20'
+++++android.view.View clickable name='Tree item at level 1'
+++++android.view.View clickable name='Tree item at level 1'
+++++android.view.View clickable name='Tree item at level 1'
 ++android.widget.GridView collection row_count=2 column_count=1
 ++++android.view.View
 ++++++android.view.View clickable collection_item name='Cell at level 1' row_span=1 column_span=1
diff --git a/content/test/data/accessibility/aria/aria-level-expected-auralinux.txt b/content/test/data/accessibility/aria/aria-level-expected-auralinux.txt
index 56c0cb1..43b9ddc 100644
--- a/content/test/data/accessibility/aria/aria-level-expected-auralinux.txt
+++ b/content/test/data/accessibility/aria/aria-level-expected-auralinux.txt
@@ -19,8 +19,18 @@
 ++++++[panel]
 ++++++++[tree item] name='Tree item at level 2' selectable level:2
 ++++++++++[static] name='Tree item at level 2'
+++++++++[tree item] name='Tree item at level 2, aria-level is 0' selectable level:2
+++++++++++[static] name='Tree item at level 2, aria-level is 0'
 ++++[tree item] name='Tree item at level 3' selectable level:3
 ++++++[static] name='Tree item at level 3'
+++++[tree item] name='Tree item at level 20' selectable level:20
+++++++[static] name='Tree item at level 20'
+++++[tree item] name='Tree item at level 1' selectable level:1
+++++++[static] name='Tree item at level 1'
+++++[tree item] name='Tree item at level 1' selectable level:1
+++++++[static] name='Tree item at level 1'
+++++[tree item] name='Tree item at level 1' selectable level:1
+++++++[static] name='Tree item at level 1'
 ++[tree table] cols=1 headers=(NONE); rows=2 headers=(NONE); caption=false; spans=(all: 1x1)
 ++++[table row] level:1
 ++++++[table cell] name='Cell at level 1' (row=0, col=0, row_span=1, col_span=1, n_row_headers=0, n_col_headers=0)
diff --git a/content/test/data/accessibility/aria/aria-level-expected-blink.txt b/content/test/data/accessibility/aria/aria-level-expected-blink.txt
index 6613093..de12be7 100644
--- a/content/test/data/accessibility/aria/aria-level-expected-blink.txt
+++ b/content/test/data/accessibility/aria/aria-level-expected-blink.txt
@@ -30,9 +30,24 @@
 ++++++++++++treeItem name='Tree item at level 2' hierarchicalLevel=2 selected=false
 ++++++++++++++staticText name='Tree item at level 2'
 ++++++++++++++++inlineTextBox name='Tree item at level 2'
+++++++++++++treeItem name='Tree item at level 2, aria-level is 0' hierarchicalLevel=2 selected=false
+++++++++++++++staticText name='Tree item at level 2, aria-level is 0'
+++++++++++++++++inlineTextBox name='Tree item at level 2, aria-level is 0'
 ++++++++treeItem name='Tree item at level 3' hierarchicalLevel=3 selected=false
 ++++++++++staticText name='Tree item at level 3'
 ++++++++++++inlineTextBox name='Tree item at level 3'
+++++++++treeItem name='Tree item at level 20' hierarchicalLevel=20 selected=false
+++++++++++staticText name='Tree item at level 20'
+++++++++++++inlineTextBox name='Tree item at level 20'
+++++++++treeItem name='Tree item at level 1' hierarchicalLevel=1 selected=false
+++++++++++staticText name='Tree item at level 1'
+++++++++++++inlineTextBox name='Tree item at level 1'
+++++++++treeItem name='Tree item at level 1' hierarchicalLevel=1 selected=false
+++++++++++staticText name='Tree item at level 1'
+++++++++++++inlineTextBox name='Tree item at level 1'
+++++++++treeItem name='Tree item at level 1' hierarchicalLevel=1 selected=false
+++++++++++staticText name='Tree item at level 1'
+++++++++++++inlineTextBox name='Tree item at level 1'
 ++++++treeGrid
 ++++++++rowGroup ignored
 ++++++++++row hierarchicalLevel=1
diff --git a/content/test/data/accessibility/aria/aria-level-expected-mac.txt b/content/test/data/accessibility/aria/aria-level-expected-mac.txt
index 74247bf0..b00a4ed 100644
--- a/content/test/data/accessibility/aria/aria-level-expected-mac.txt
+++ b/content/test/data/accessibility/aria/aria-level-expected-mac.txt
@@ -19,8 +19,18 @@
 ++++++AXGroup AXSubrole=AXApplicationGroup
 ++++++++AXRow AXSubrole=AXOutlineRow AXDisclosing=0 AXDisclosureLevel=1 AXIndex=1 AXTitle='Tree item at level 2'
 ++++++++++AXStaticText AXValue='Tree item at level 2'
-++++AXRow AXSubrole=AXOutlineRow AXDisclosing=0 AXDisclosureLevel=2 AXIndex=2 AXTitle='Tree item at level 3'
+++++++++AXRow AXSubrole=AXOutlineRow AXDisclosing=0 AXDisclosureLevel=1 AXIndex=2 AXTitle='Tree item at level 2, aria-level is 0'
+++++++++++AXStaticText AXValue='Tree item at level 2, aria-level is 0'
+++++AXRow AXSubrole=AXOutlineRow AXDisclosing=0 AXDisclosureLevel=2 AXIndex=3 AXTitle='Tree item at level 3'
 ++++++AXStaticText AXValue='Tree item at level 3'
+++++AXRow AXSubrole=AXOutlineRow AXDisclosing=0 AXDisclosureLevel=19 AXIndex=4 AXTitle='Tree item at level 20'
+++++++AXStaticText AXValue='Tree item at level 20'
+++++AXRow AXSubrole=AXOutlineRow AXDisclosing=0 AXDisclosureLevel=0 AXIndex=5 AXTitle='Tree item at level 1'
+++++++AXStaticText AXValue='Tree item at level 1'
+++++AXRow AXSubrole=AXOutlineRow AXDisclosing=0 AXDisclosureLevel=0 AXIndex=6 AXTitle='Tree item at level 1'
+++++++AXStaticText AXValue='Tree item at level 1'
+++++AXRow AXSubrole=AXOutlineRow AXDisclosing=0 AXDisclosureLevel=0 AXIndex=7 AXTitle='Tree item at level 1'
+++++++AXStaticText AXValue='Tree item at level 1'
 ++AXTable
 ++++AXRow AXDisclosureLevel=0 AXIndex=0
 ++++++AXCell
diff --git a/content/test/data/accessibility/aria/aria-level-expected-uia-win.txt b/content/test/data/accessibility/aria/aria-level-expected-uia-win.txt
new file mode 100644
index 0000000..3e3e784
--- /dev/null
+++ b/content/test/data/accessibility/aria/aria-level-expected-uia-win.txt
@@ -0,0 +1,52 @@
+Document
+++Text Name='Level 2'
+++++Text Name='Level 2' IsControlElement=false
+++Text Name='Level 9'
+++++Text Name='Level 9' IsControlElement=false
+++Text Name='Level 1'
+++++Text Name='Level 1' IsControlElement=false
+++Text Name='Level 3'
+++++Text Name='Level 3' IsControlElement=false
+++Text Name='Level 3'
+++++Text Name='Level 3' IsControlElement=false
+++Text Name='Level 4'
+++++Text Name='Level 4' IsControlElement=false
+++Text Name='Level 5'
+++++Text Name='Level 5' IsControlElement=false
+++Tree Selection.CanSelectMultiple=false Selection.IsSelectionRequired=false
+++++TreeItem Name='Tree item at level 1' ExpandCollapse.ExpandCollapseState='Expanded' SelectionItem.IsSelected=false
+++++++Text Name='Tree item at level 1' IsControlElement=false
+++++++Group
+++++++++TreeItem Name='Tree item at level 2' ExpandCollapse.ExpandCollapseState='LeafNode' SelectionItem.IsSelected=false
+++++++++++Text Name='Tree item at level 2' IsControlElement=false
+++++++++TreeItem Name='Tree item at level 2, aria-level is 0' ExpandCollapse.ExpandCollapseState='LeafNode' SelectionItem.IsSelected=false
+++++++++++Text Name='Tree item at level 2, aria-level is 0' IsControlElement=false
+++++TreeItem Name='Tree item at level 3' ExpandCollapse.ExpandCollapseState='LeafNode' SelectionItem.IsSelected=false
+++++++Text Name='Tree item at level 3' IsControlElement=false
+++++TreeItem Name='Tree item at level 20' ExpandCollapse.ExpandCollapseState='LeafNode' SelectionItem.IsSelected=false
+++++++Text Name='Tree item at level 20' IsControlElement=false
+++++TreeItem Name='Tree item at level 1' ExpandCollapse.ExpandCollapseState='LeafNode' SelectionItem.IsSelected=false
+++++++Text Name='Tree item at level 1' IsControlElement=false
+++++TreeItem Name='Tree item at level 1' ExpandCollapse.ExpandCollapseState='LeafNode' SelectionItem.IsSelected=false
+++++++Text Name='Tree item at level 1' IsControlElement=false
+++++TreeItem Name='Tree item at level 1' ExpandCollapse.ExpandCollapseState='LeafNode' SelectionItem.IsSelected=false
+++++++Text Name='Tree item at level 1' IsControlElement=false
+++DataGrid Grid.ColumnCount=1 Grid.RowCount=2 Selection.CanSelectMultiple=false Selection.IsSelectionRequired=false Table.RowOrColumnMajor='RowMajor'
+++++TreeItem
+++++++DataItem Name='Cell at level 1' GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=0 GridItem.RowSpan=1
+++++++++Text Name='Cell at level 1' IsControlElement=false
+++++TreeItem
+++++++DataItem Name='Cell at level 2' GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=1 GridItem.RowSpan=1
+++++++++Text Name='Cell at level 2' IsControlElement=false
+++ListItem Name='List item at level 1'
+++++Text Name='List item at level 1' IsControlElement=false
+++ListItem Name='List item at level 3'
+++++Text Name='List item at level 3' IsControlElement=false
+++List
+++++ListItem Name='List item at level 2'
+++++++Text Name='List item at level 2' IsControlElement=false
+++++List
+++++++ListItem Name='List item at level 2'
+++++++++Text Name='List item at level 2' IsControlElement=false
+++++++ListItem Name='List item at level 7'
+++++++++Text Name='List item at level 7' IsControlElement=false
diff --git a/content/test/data/accessibility/aria/aria-level-expected-win.txt b/content/test/data/accessibility/aria/aria-level-expected-win.txt
index 001ce894..94cefc9 100644
--- a/content/test/data/accessibility/aria/aria-level-expected-win.txt
+++ b/content/test/data/accessibility/aria/aria-level-expected-win.txt
@@ -19,8 +19,18 @@
 ++++++ROLE_SYSTEM_GROUPING
 ++++++++ROLE_SYSTEM_OUTLINEITEM name='Tree item at level 2' level:2
 ++++++++++ROLE_SYSTEM_STATICTEXT name='Tree item at level 2'
+++++++++ROLE_SYSTEM_OUTLINEITEM name='Tree item at level 2, aria-level is 0' level:2
+++++++++++ROLE_SYSTEM_STATICTEXT name='Tree item at level 2, aria-level is 0'
 ++++ROLE_SYSTEM_OUTLINEITEM name='Tree item at level 3' level:3
 ++++++ROLE_SYSTEM_STATICTEXT name='Tree item at level 3'
+++++ROLE_SYSTEM_OUTLINEITEM name='Tree item at level 20' level:20
+++++++ROLE_SYSTEM_STATICTEXT name='Tree item at level 20'
+++++ROLE_SYSTEM_OUTLINEITEM name='Tree item at level 1' level:1
+++++++ROLE_SYSTEM_STATICTEXT name='Tree item at level 1'
+++++ROLE_SYSTEM_OUTLINEITEM name='Tree item at level 1' level:1
+++++++ROLE_SYSTEM_STATICTEXT name='Tree item at level 1'
+++++ROLE_SYSTEM_OUTLINEITEM name='Tree item at level 1' level:1
+++++++ROLE_SYSTEM_STATICTEXT name='Tree item at level 1'
 ++ROLE_SYSTEM_OUTLINE
 ++++ROLE_SYSTEM_OUTLINEITEM level:1
 ++++++ROLE_SYSTEM_CELL name='Cell at level 1'
diff --git a/content/test/data/accessibility/aria/aria-level.html b/content/test/data/accessibility/aria/aria-level.html
index e6b18c3..0f72a6a9 100644
--- a/content/test/data/accessibility/aria/aria-level.html
+++ b/content/test/data/accessibility/aria/aria-level.html
@@ -28,11 +28,26 @@
     Tree item at level 1
     <div role="group">
       <div role="treeitem">Tree item at level 2</div>
+      <div role="treeitem" aria-level="0">
+        Tree item at level 2, aria-level is 0
+      </div>
     </div>
   </div>
   <div role="treeitem" aria-level="3">
     Tree item at level 3
   </div>
+  <div role="treeitem" aria-level="20">
+    Tree item at level 20
+  </div>
+  <div role="treeitem" aria-level="1">
+    Tree item at level 1
+  </div>
+  <div role="treeitem" aria-level="0">
+    Tree item at level 1
+  </div>
+  <div role="treeitem" aria-level="-1">
+    Tree item at level 1
+  </div>
 </div>
 
 <table role="treegrid">
diff --git a/docs/contributing.md b/docs/contributing.md
index ff02437..971f760 100644
--- a/docs/contributing.md
+++ b/docs/contributing.md
@@ -338,7 +338,8 @@
   that do not increase the cost of maintaining Chromium's supported
   architectures / platforms (e.g., adding one ifdef branch for an unsupported
   architecture / platform is fine but introducing new abstractions in the
-  codebase is problematic).
+  codebase is problematic). See the [new port policy](new_port_policy.md) for
+  further guidance.
 
 - **Code should only be moved to a central location (e.g., //base) when
   multiple consumers would benefit.** We should resist the temptation to
diff --git a/docs/debugging_with_crash_keys.md b/docs/debugging_with_crash_keys.md
index eeb6f20d..cda8f697 100644
--- a/docs/debugging_with_crash_keys.md
+++ b/docs/debugging_with_crash_keys.md
@@ -70,6 +70,9 @@
 crash key, and it is what you will use to identify your data in uploaded
 crash reports.
 
+Note that crash key names are global and must not conflict with the
+name of any other crash key in Chrome.
+
 If you need to declare an array of crash keys (e.g., for recording N values
 of an array), you can use a constructor tag to avoid warnings about `explicit`:
 
@@ -146,7 +149,8 @@
 function in crash_logging.h:
 
     Usemeafterfree::~Usemeafterfree() {
-      static crash_reporter::CrashKeyString<1024> trace_key("uaf-dtor-trace");
+      static crash_reporter::CrashKeyString<1024> trace_key(
+          "useme-after-free-uaf-dtor-trace");
       crash_reporter::SetCrashKeyStringToStackTrace(&trace_key,
                                                     base::debug::StackTrace());
     }
diff --git a/docs/new_port_policy.md b/docs/new_port_policy.md
index 1ac6281..e61bf02 100644
--- a/docs/new_port_policy.md
+++ b/docs/new_port_policy.md
@@ -1,6 +1,12 @@
 # Policy for Adding a New Port
 
-Since every new port for Chromium has a maintenance cost, here are some guidelines for when the project will accept a new port.
+**Before the Chromium project first starts accepting patches for new ports, the
+new port/platform must be approved by project leadership.** See the
+[contributing guidelines](contributing.md#Code-guidelines) for how to get
+approval for new architectures, platforms, or sub-projects.
+
+Since every new port for Chromium has a maintenance cost, here are some
+expectations of new ports that the project accepts:
 
 ## Expectations
 
@@ -9,4 +15,3 @@
 *   Chromium engineers are not expected to maintain them.
 *   As much as possible, try to use existing branches/ifdefs.
 *   While changes in src/base are unavoidable, higher level directories shouldn't have to change. i.e. existing porting APIs should be used. We would not accept new rendering pipelines as an example.
-*   Send an email to [src/OWNERS](https://chromium.googlesource.com/chromium/src/+/main/ENG_REVIEW_OWNERS) for approval.
diff --git a/docs/speed/binary_size/optimization_advice.md b/docs/speed/binary_size/optimization_advice.md
index 1956dcc..083b1c7 100644
--- a/docs/speed/binary_size/optimization_advice.md
+++ b/docs/speed/binary_size/optimization_advice.md
@@ -125,8 +125,7 @@
      stored as vectors.
    * For images used in native code: [VectorIcon](https://chromium.googlesource.com/chromium/src/+/HEAD/components/vector_icons/README.md).
    * For Android drawables: [VectorDrawable](https://developer.android.com/guide/topics/graphics/vector-drawable-resources).
-     * Convert from `.svg` online using https://inloop.github.io/svg2android/.
-     * Optimize vector drawables with [avocado](https://bugs.chromium.org/p/chromium/issues/detail?id=982302).
+     * Convert from `.svg` following [this guide](https://developer.android.com/studio/write/vector-asset-studio.html#svg).
      * (Googlers): Find most icons as .svg at [go/icons](https://goto.google.com/icons).
  * Would **lossy** compression make sense (often true for large images)?
    * If so, [use lossy webp](https://codereview.chromium.org/2615243002/).
diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h
index 81cdcfb..c0ce996 100644
--- a/extensions/browser/extension_function_histogram_value.h
+++ b/extensions/browser/extension_function_histogram_value.h
@@ -1732,6 +1732,8 @@
   ENTERPRISE_REMOTEAPPS_ADDFOLDER = 1669,
   ENTERPRISE_REMOTEAPPS_ADDAPP = 1670,
   ENTERPRISE_REMOTEAPPS_DELETEAPP = 1671,
+  ENTERPRISEREPORTINGPRIVATE_GETAVINFO = 1672,
+  ENTERPRISEREPORTINGPRIVATE_GETHOTFIXES = 1673,
   // Last entry: Add new entries above, then run:
   // tools/metrics/histograms/update_extension_histograms.py
   ENUM_BOUNDARY
diff --git a/extensions/renderer/bindings/api_response_validator.cc b/extensions/renderer/bindings/api_response_validator.cc
index 8022d06..59cdb2e 100644
--- a/extensions/renderer/bindings/api_response_validator.cc
+++ b/extensions/renderer/bindings/api_response_validator.cc
@@ -119,6 +119,7 @@
   static constexpr char const* kBrokenSignaturesToIgnore[] = {
       "automationInternal.onAccessibilityEvent",
       "chromeWebViewInternal.onClicked",
+      "inputMethodPrivate.onFocus",
       "test.onMessage",
   };
 
@@ -137,13 +138,8 @@
   if (g_handler_for_testing) {
     g_handler_for_testing->HandleFailure(event_name, error);
   } else {
-    // TODO(https://crbug.com/1329587): There are a few more lingering events
-    // that violate their signature, but they only show up on certain builds
-    // that aren't part of our normal CQ. Avoid a hard crash for now in order
-    // to land the bulk of this implementation before enabling the hard crash
-    // to make reverts less painful.
-    // NOTREACHED() << "Error validating event arguments to `" << event_name
-    //              << "`: " << error;
+    NOTREACHED() << "Error validating event arguments to `" << event_name
+                 << "`: " << error;
   }
 }
 
diff --git a/fuchsia_web/runners/BUILD.gn b/fuchsia_web/runners/BUILD.gn
index 1e9207b..9496f4c 100644
--- a/fuchsia_web/runners/BUILD.gn
+++ b/fuchsia_web/runners/BUILD.gn
@@ -221,7 +221,7 @@
   data_deps = [ ":cast_runner_core" ]
 }
 
-test("cast_runner_integration_tests_cfv1") {
+test("cast_runner_integration_tests") {
   sources = [
     "cast/cast_runner_integration_test.cc",
     "cast/fake_component_context.cc",
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_ozone.cc b/gpu/command_buffer/service/shared_image_backing_factory_ozone.cc
index c495fb8..8c0dcb045 100644
--- a/gpu/command_buffer/service/shared_image_backing_factory_ozone.cc
+++ b/gpu/command_buffer/service/shared_image_backing_factory_ozone.cc
@@ -220,8 +220,7 @@
       !CanImportGpuMemoryBufferToVulkan(gmb_type)) {
     return false;
   }
-#elif BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS_ASH) && \
-    !BUILDFLAG(IS_CHROMEOS_LACROS) && !BUILDFLAG(IS_CHROMECAST)
+#elif BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CASTOS)
   bool used_by_skia = (usage & SHARED_IMAGE_USAGE_RASTER) ||
                       (usage & SHARED_IMAGE_USAGE_DISPLAY);
   bool used_by_vulkan =
diff --git a/gpu/config/gpu_info_collector_win.cc b/gpu/config/gpu_info_collector_win.cc
index b0f6e56..7d63f56 100644
--- a/gpu/config/gpu_info_collector_win.cc
+++ b/gpu/config/gpu_info_collector_win.cc
@@ -398,14 +398,25 @@
 
   // Query the maximum supported shader model version.
   if (d3d12_device) {
-    D3D12_FEATURE_DATA_SHADER_MODEL shader_model_data = {};
-    // TODO(crbug.com/1312519): Setting the HighestShaderModel to 6_7 will cause
-    // failure in CheckFeatureSupport(). Use D3D_SHADER_MODEL_6_6 for now.
-    shader_model_data.HighestShaderModel = D3D_SHADER_MODEL_6_6;
-    if (SUCCEEDED(d3d12_device->CheckFeatureSupport(
-            D3D12_FEATURE_SHADER_MODEL, &shader_model_data,
-            sizeof(shader_model_data)))) {
-      highest_shader_model_version = shader_model_data.HighestShaderModel;
+    // As per the documentation, CheckFeatureSupport will return E_INVALIDARG if
+    // the shader model is not known by the current runtime, so we loop in
+    // decreasing shader model version to determine the highest supported model:
+    // https://docs.microsoft.com/en-us/windows/win32/api/d3d12/ns-d3d12-d3d12_feature_data_shader_model.
+    const D3D_SHADER_MODEL shader_models[] = {
+        D3D_SHADER_MODEL_6_7, D3D_SHADER_MODEL_6_6, D3D_SHADER_MODEL_6_5,
+        D3D_SHADER_MODEL_6_4, D3D_SHADER_MODEL_6_3, D3D_SHADER_MODEL_6_2,
+        D3D_SHADER_MODEL_6_1, D3D_SHADER_MODEL_6_0, D3D_SHADER_MODEL_5_1,
+    };
+
+    for (auto model : shader_models) {
+      D3D12_FEATURE_DATA_SHADER_MODEL shader_model_data = {};
+      shader_model_data.HighestShaderModel = model;
+      if (SUCCEEDED(d3d12_device->CheckFeatureSupport(
+              D3D12_FEATURE_SHADER_MODEL, &shader_model_data,
+              sizeof(shader_model_data)))) {
+        highest_shader_model_version = shader_model_data.HighestShaderModel;
+        break;
+      }
     }
   }
 }
@@ -638,7 +649,7 @@
       ConvertToHistogramFeatureLevel(d3d12_feature_level));
 
   UMA_HISTOGRAM_ENUMERATION(
-      "GPU.D3D12HighestShaderModel",
+      "GPU.D3D12HighestShaderModel2",
       ConvertToHistogramShaderVersion(highest_shader_model_version));
 }
 
diff --git a/gpu/ipc/service/gpu_watchdog_thread.cc b/gpu/ipc/service/gpu_watchdog_thread.cc
index 9a31f97..31e98e2 100644
--- a/gpu/ipc/service/gpu_watchdog_thread.cc
+++ b/gpu/ipc/service/gpu_watchdog_thread.cc
@@ -106,7 +106,7 @@
   }
 #endif
 
-#if BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMECAST)
+#if BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CASTOS)
   tty_file_ = base::OpenFile(
       base::FilePath(FILE_PATH_LITERAL("/sys/class/tty/tty0/active")), "r");
   UpdateActiveTTY();
@@ -134,7 +134,7 @@
     CloseHandle(watched_thread_handle_);
 #endif
 
-#if BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMECAST)
+#if BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CASTOS)
   if (tty_file_)
     fclose(tty_file_);
 #endif
@@ -468,7 +468,7 @@
   if (foregrounded_event_)
     num_of_timeout_after_foregrounded_++;
 
-#if BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMECAST)
+#if BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CASTOS)
   UpdateActiveTTY();
 #endif
 
@@ -793,7 +793,7 @@
   return foregrounded_event_ && num_of_timeout_after_foregrounded_ <= count;
 }
 
-#if BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMECAST)
+#if BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CASTOS)
 void GpuWatchdogThread::UpdateActiveTTY() {
   last_active_tty_ = active_tty_;
 
@@ -810,7 +810,7 @@
 #endif
 
 bool GpuWatchdogThread::ContinueOnNonHostX11ServerTty() {
-#if BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMECAST)
+#if BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CASTOS)
   if (host_tty_ == -1 || active_tty_ == -1)
     return false;
 
diff --git a/gpu/ipc/service/gpu_watchdog_thread.h b/gpu/ipc/service/gpu_watchdog_thread.h
index 65bc1c7..1dd01705 100644
--- a/gpu/ipc/service/gpu_watchdog_thread.h
+++ b/gpu/ipc/service/gpu_watchdog_thread.h
@@ -201,7 +201,7 @@
   bool WithinOneMinFromPowerResumed();
   bool WithinOneMinFromForegrounded();
 
-#if BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMECAST)
+#if BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CASTOS)
   void UpdateActiveTTY();
 #endif
   // The watchdog continues when it's not on the TTY of our host X11 server.
@@ -269,7 +269,7 @@
   bool less_than_full_thread_time_after_capped_ = false;
 #endif
 
-#if BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMECAST)
+#if BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CASTOS)
   FILE* tty_file_ = nullptr;
   int host_tty_ = -1;
   int active_tty_ = -1;
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg
index 1330296..32760f2c 100644
--- a/infra/config/generated/luci/cr-buildbucket.cfg
+++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -41716,7 +41716,7 @@
         '  "led_builder_is_bootstrapped": true,'
         '  "recipe": "chromium"'
         '}'
-      execution_timeout_secs: 10800
+      execution_timeout_secs: 21600
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
@@ -74004,7 +74004,7 @@
         '  "led_builder_is_bootstrapped": true,'
         '  "recipe": "chromium_trybot"'
         '}'
-      execution_timeout_secs: 18000
+      execution_timeout_secs: 21600
       expiration_secs: 7200
       grace_period {
         seconds: 120
diff --git a/infra/config/subprojects/chromium/ci/chromium.updater.star b/infra/config/subprojects/chromium/ci/chromium.updater.star
index 9c983683..02b1282 100644
--- a/infra/config/subprojects/chromium/ci/chromium.updater.star
+++ b/infra/config/subprojects/chromium/ci/chromium.updater.star
@@ -414,6 +414,7 @@
         category = "debug|win (32)",
         short_name = "bld",
     ),
+    execution_timeout = ci.DEFAULT_EXECUTION_TIMEOUT * 2,
     os = os.WINDOWS_DEFAULT,
     goma_backend = None,
     reclient_jobs = rbe_jobs.LOW_JOBS_FOR_CI,
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.win.star b/infra/config/subprojects/chromium/try/tryserver.chromium.win.star
index 7ff5d7a3..a61f97db 100644
--- a/infra/config/subprojects/chromium/try/tryserver.chromium.win.star
+++ b/infra/config/subprojects/chromium/try/tryserver.chromium.win.star
@@ -39,7 +39,7 @@
         "ci/win-asan",
     ],
     goma_jobs = goma.jobs.J150,
-    execution_timeout = 5 * time.hour,
+    execution_timeout = 6 * time.hour,
 )
 
 try_.builder(
diff --git a/ios/chrome/browser/ui/browser_view/BUILD.gn b/ios/chrome/browser/ui/browser_view/BUILD.gn
index 5067fc8..83ef9d44 100644
--- a/ios/chrome/browser/ui/browser_view/BUILD.gn
+++ b/ios/chrome/browser/ui/browser_view/BUILD.gn
@@ -275,7 +275,9 @@
     "//ios/chrome/browser/ui/fullscreen/test",
     "//ios/chrome/browser/ui/incognito_reauth:incognito_reauth_scene_agent",
     "//ios/chrome/browser/ui/main:scene_state_header",
+    "//ios/chrome/browser/ui/popup_menu",
     "//ios/chrome/browser/ui/sharing",
+    "//ios/chrome/browser/ui/side_swipe",
     "//ios/chrome/browser/ui/tab_switcher/tab_strip",
     "//ios/chrome/browser/ui/tabs:coordinator",
     "//ios/chrome/browser/ui/toolbar",
diff --git a/ios/chrome/browser/ui/browser_view/browser_coordinator.mm b/ios/chrome/browser/ui/browser_view/browser_coordinator.mm
index 35ab368..fb9cb6c12 100644
--- a/ios/chrome/browser/ui/browser_view/browser_coordinator.mm
+++ b/ios/chrome/browser/ui/browser_view/browser_coordinator.mm
@@ -93,6 +93,7 @@
 #import "ios/chrome/browser/ui/passwords/password_breach_coordinator.h"
 #import "ios/chrome/browser/ui/passwords/password_protection_coordinator.h"
 #import "ios/chrome/browser/ui/passwords/password_suggestion_coordinator.h"
+#import "ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.h"
 #import "ios/chrome/browser/ui/presenters/vertical_animation_container.h"
 #import "ios/chrome/browser/ui/print/print_controller.h"
 #import "ios/chrome/browser/ui/qr_generator/qr_generator_coordinator.h"
@@ -103,6 +104,7 @@
 #import "ios/chrome/browser/ui/safe_browsing/safe_browsing_coordinator.h"
 #import "ios/chrome/browser/ui/settings/autofill/autofill_add_credit_card_coordinator.h"
 #import "ios/chrome/browser/ui/sharing/sharing_coordinator.h"
+#import "ios/chrome/browser/ui/side_swipe/side_swipe_controller.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_coordinator.h"
 #import "ios/chrome/browser/ui/tabs/tab_strip_legacy_coordinator.h"
 #import "ios/chrome/browser/ui/text_fragments/text_fragments_coordinator.h"
@@ -308,6 +310,10 @@
 
 // The coordinator used for the Text Fragments feature.
 @property(nonatomic, strong) TextFragmentsCoordinator* textFragmentsCoordinator;
+
+// The coordinator for the popup menu.
+@property(nonatomic, strong) PopupMenuCoordinator* popupMenuCoordinator;
+
 @end
 
 @implementation BrowserCoordinator {
@@ -322,6 +328,7 @@
   SecondaryToolbarCoordinator* _secondaryToolbarCoordinator;
   TabStripCoordinator* _tabStripCoordinator;
   TabStripLegacyCoordinator* _legacyTabStripCoordinator;
+  SideSwipeController* _sideSwipeController;
 }
 
 #pragma mark - ChromeCoordinator
@@ -358,6 +365,14 @@
     [_toolbarCoordinatorAdaptor
         addToolbarCoordinator:_secondaryToolbarCoordinator];
 
+    _sideSwipeController =
+        [[SideSwipeController alloc] initWithBrowser:browser];
+    _sideSwipeController.toolbarInteractionHandler = _toolbarCoordinatorAdaptor;
+    _sideSwipeController.primaryToolbarSnapshotProvider =
+        _primaryToolbarCoordinator;
+    _sideSwipeController.secondaryToolbarSnapshotProvider =
+        _secondaryToolbarCoordinator;
+
     if (ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_TABLET) {
       if (base::FeatureList::IsEnabled(kModernTabStrip)) {
         _tabStripCoordinator =
@@ -367,6 +382,8 @@
             [[TabStripLegacyCoordinator alloc] initWithBrowser:browser];
         _legacyTabStripCoordinator.animationWaitDuration =
             kLegacyFullscreenControllerToolbarAnimationDuration.InSecondsF();
+
+        [_sideSwipeController setTabStripDelegate:_legacyTabStripCoordinator];
       }
     }
   }
@@ -594,6 +611,16 @@
   // coordinators.
   DCHECK(self.dispatcher);
 
+  self.popupMenuCoordinator = [[PopupMenuCoordinator alloc]
+      initWithBaseViewController:self.viewController
+                         browser:self.browser];
+  self.popupMenuCoordinator.bubblePresenter = _bubblePresenter;
+  self.popupMenuCoordinator.UIUpdater = _toolbarCoordinatorAdaptor;
+  self.popupMenuCoordinator.popupMenuAppearanceDelegate = self.viewController;
+  [self.popupMenuCoordinator start];
+
+  _legacyTabStripCoordinator.longPressDelegate = self.popupMenuCoordinator;
+
   self.ARQuickLookCoordinator = [[ARQuickLookCoordinator alloc]
       initWithBaseViewController:self.viewController
                          browser:self.browser];
@@ -807,6 +834,9 @@
 
   [self.netExportCoordinator stop];
   self.netExportCoordinator = nil;
+
+  [self.popupMenuCoordinator stop];
+  self.popupMenuCoordinator = nil;
 }
 
 // Starts mediators owned by this coordinator.
@@ -818,7 +848,7 @@
   TabLifecycleDependencies dependencies;
   dependencies.prerenderService =
       PrerenderServiceFactory::GetForBrowserState(browserState);
-  dependencies.sideSwipeController = browserViewController.sideSwipeController;
+  dependencies.sideSwipeController = _sideSwipeController;
   dependencies.downloadManagerCoordinator = self.downloadManagerCoordinator;
   dependencies.baseViewController = browserViewController;
   dependencies.commandDispatcher = self.browser->GetCommandDispatcher();
@@ -855,11 +885,11 @@
   dependencies.bubblePresenter = _bubblePresenter;
   dependencies.downloadManagerCoordinator = self.downloadManagerCoordinator;
   dependencies.toolbarInterface = _toolbarCoordinatorAdaptor;
-  dependencies.UIUpdater = _toolbarCoordinatorAdaptor;
   dependencies.primaryToolbarCoordinator = _primaryToolbarCoordinator;
   dependencies.secondaryToolbarCoordinator = _secondaryToolbarCoordinator;
   dependencies.tabStripCoordinator = _tabStripCoordinator;
   dependencies.legacyTabStripCoordinator = _legacyTabStripCoordinator;
+  dependencies.sideSwipeController = _sideSwipeController;
 
   return dependencies;
 }
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller.h b/ios/chrome/browser/ui/browser_view/browser_view_controller.h
index 068d1335..6d23338 100644
--- a/ios/chrome/browser/ui/browser_view/browser_view_controller.h
+++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.h
@@ -13,6 +13,7 @@
 #import "ios/chrome/browser/ui/incognito_reauth/incognito_reauth_consumer.h"
 #import "ios/chrome/browser/ui/ntp/logo_animation_controller.h"
 #import "ios/chrome/browser/ui/page_info/requirements/page_info_presentation.h"
+#import "ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.h"
 #import "ios/chrome/browser/ui/print/print_controller.h"
 #import "ios/chrome/browser/ui/settings/sync/utils/sync_presenter.h"
 #import "ios/chrome/browser/ui/thumb_strip/thumb_strip_supporting.h"
@@ -34,10 +35,10 @@
 @class DownloadManagerCoordinator;
 @class KeyCommandsProvider;
 // TODO(crbug.com/1328039): Remove all use of the prerender service from BVC
-@protocol PopupMenuUIUpdating;
 class PrerenderService;
 @class PrimaryToolbarCoordinator;
 @class SecondaryToolbarCoordinator;
+@class SideSwipeController;
 @class TabStripCoordinator;
 @class TabStripLegacyCoordinator;
 @class ToolbarAccessoryPresenter;
@@ -52,11 +53,11 @@
   BubblePresenter* bubblePresenter;
   DownloadManagerCoordinator* downloadManagerCoordinator;
   id<ToolbarCoordinating> toolbarInterface;
-  id<PopupMenuUIUpdating> UIUpdater;
   PrimaryToolbarCoordinator* primaryToolbarCoordinator;
   SecondaryToolbarCoordinator* secondaryToolbarCoordinator;
   TabStripCoordinator* tabStripCoordinator;
   TabStripLegacyCoordinator* legacyTabStripCoordinator;
+  SideSwipeController* sideSwipeController;
 } BrowserViewControllerDependencies;
 
 // The top-level view controller for the browser UI. Manages other controllers
@@ -67,6 +68,7 @@
                         LogoAnimationControllerOwnerOwner,
                         PageInfoPresentation,
                         PrintControllerDelegate,
+                        PopupMenuAppearanceDelegate,
                         SigninPresenter,
                         SyncPresenter,
                         ThumbStripSupporting,
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
index 1ab3d74..696e97b1f 100644
--- a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
@@ -95,7 +95,6 @@
 #import "ios/chrome/browser/ui/ntp/new_tab_page_coordinator.h"
 #import "ios/chrome/browser/ui/ntp/ntp_util.h"
 #import "ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.h"
-#import "ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.h"
 #import "ios/chrome/browser/ui/send_tab_to_self/send_tab_to_self_coordinator.h"
 #import "ios/chrome/browser/ui/settings/sync/utils/sync_util.h"
 #import "ios/chrome/browser/ui/side_swipe/side_swipe_controller.h"
@@ -338,9 +337,6 @@
   // The updater that adjusts the toolbar's layout for fullscreen events.
   std::unique_ptr<FullscreenUIUpdater> _fullscreenUIUpdater;
 
-  // Popup Menu UI Updater.
-  id<PopupMenuUIUpdating> _UIUpdater;
-
   // TODO(crbug.com/1331229): Remove all use of the download manager coordinator
   // from BVC Coordinator for the Download Manager UI.
   DownloadManagerCoordinator* _downloadManagerCoordinator;
@@ -370,6 +366,8 @@
   // one single drag gesture.  When NO, full screen disabler is reset when
   // the thumb strip animation ends.
   BOOL _deferEndFullscreenDisabler;
+
+  BOOL _isShowingPopupMenu;
 }
 
 // Activates/deactivates the object. This will enable/disable the ability for
@@ -430,9 +428,6 @@
 // ones that cannot be scrolled off screen by full screen.
 @property(nonatomic, strong, readonly) NSArray<HeaderDefinition*>* headerViews;
 
-// Coordinator for the popup menus.
-@property(nonatomic, strong) PopupMenuCoordinator* popupMenuCoordinator;
-
 @property(nonatomic, strong) BubblePresenter* bubblePresenter;
 
 // Command handler for text zoom commands
@@ -534,7 +529,9 @@
     // TODO(crbug.com/1331229): Remove all use of the download manager
     // coordinator from BVC
     _downloadManagerCoordinator = dependencies.downloadManagerCoordinator;
-    _UIUpdater = dependencies.UIUpdater;
+    _sideSwipeController = dependencies.sideSwipeController;
+    [_sideSwipeController setSnapshotDelegate:self];
+    [_sideSwipeController setSwipeDelegate:self];
     self.toolbarInterface = dependencies.toolbarInterface;
     self.primaryToolbarCoordinator = dependencies.primaryToolbarCoordinator;
     self.secondaryToolbarCoordinator = dependencies.secondaryToolbarCoordinator;
@@ -642,27 +639,6 @@
   [self updateOverlayContainerOrder];
 }
 
-#pragma mark - Delegates Category Properties
-
-// Lazily creates the SideSwipeController on first access.
-- (SideSwipeController*)sideSwipeController {
-  if (!_sideSwipeController) {
-    _sideSwipeController =
-        [[SideSwipeController alloc] initWithBrowser:self.browser];
-    [_sideSwipeController setSnapshotDelegate:self];
-    _sideSwipeController.toolbarInteractionHandler = self.toolbarInterface;
-    _sideSwipeController.primaryToolbarSnapshotProvider =
-        self.primaryToolbarCoordinator;
-    _sideSwipeController.secondaryToolbarSnapshotProvider =
-        self.secondaryToolbarCoordinator;
-    [_sideSwipeController setSwipeDelegate:self];
-    if (!base::FeatureList::IsEnabled(kModernTabStrip)) {
-      [_sideSwipeController setTabStripDelegate:self.legacyTabStripCoordinator];
-    }
-  }
-  return _sideSwipeController;
-}
-
 #pragma mark - Private Properties
 
 - (BOOL)canShowTabStrip {
@@ -1112,8 +1088,6 @@
   for (int index = 0; index < webStateList->count(); ++index)
     [self uninstallDelegatesForWebState:webStateList->GetWebStateAt(index)];
 
-  // Disconnect child coordinators.
-  [self.popupMenuCoordinator stop];
   if (base::FeatureList::IsEnabled(kModernTabStrip)) {
     [self.tabStripCoordinator stop];
     self.tabStripCoordinator = nil;
@@ -1605,8 +1579,8 @@
     }
   }
 
-  if ([self.sideSwipeController inSwipe]) {
-    [self.sideSwipeController resetContentView];
+  if ([_sideSwipeController inSwipe]) {
+    [_sideSwipeController resetContentView];
   }
 
   void (^superCall)() = ^{
@@ -1633,8 +1607,7 @@
       self.presentedViewController.beingDismissed) {
     // Don't rotate while a presentation or dismissal animation is occurring.
     return NO;
-  } else if (_sideSwipeController &&
-             ![self.sideSwipeController shouldAutorotate]) {
+  } else if (_sideSwipeController && ![_sideSwipeController shouldAutorotate]) {
     // Don't auto rotate if side swipe controller view says not to.
     return NO;
   } else {
@@ -1763,22 +1736,10 @@
   _locationBarModel = std::make_unique<LocationBarModelImpl>(
       _locationBarModelDelegate.get(), kMaxURLDisplayChars);
 
-  // TODO(crbug.com/1329094): Move this coordinator to BrowserCoordinator
-  self.popupMenuCoordinator =
-      [[PopupMenuCoordinator alloc] initWithBaseViewController:self
-                                                       browser:self.browser];
-  self.popupMenuCoordinator.bubblePresenter = _bubblePresenter;
-  self.popupMenuCoordinator.UIUpdater = _UIUpdater;
-  [self.popupMenuCoordinator start];
-
   self.primaryToolbarCoordinator.delegate = self;
   self.primaryToolbarCoordinator.popupPresenterDelegate = self;
-  self.primaryToolbarCoordinator.longPressDelegate = self.popupMenuCoordinator;
   [self.primaryToolbarCoordinator start];
 
-  self.secondaryToolbarCoordinator.longPressDelegate =
-      self.popupMenuCoordinator;
-
   // TODO(crbug.com/880672): Finish ToolbarContainer work.
   if (base::FeatureList::IsEnabled(
           toolbar_container::kToolbarContainerEnabled)) {
@@ -1793,12 +1754,6 @@
     [self.secondaryToolbarCoordinator start];
   }
 
-  self.sideSwipeController.toolbarInteractionHandler = self.toolbarInterface;
-  self.sideSwipeController.primaryToolbarSnapshotProvider =
-      self.primaryToolbarCoordinator;
-  self.sideSwipeController.secondaryToolbarSnapshotProvider =
-      self.secondaryToolbarCoordinator;
-
   [self updateBroadcastState];
   if (_voiceSearchController) {
     // TODO(crbug.com/1329089): Inject LoadQueryCommands as a handler and pass
@@ -1814,8 +1769,6 @@
       [self.tabStripCoordinator start];
     } else {
       self.legacyTabStripCoordinator.presentationProvider = self;
-      self.legacyTabStripCoordinator.longPressDelegate =
-          self.popupMenuCoordinator;
 
       [self.legacyTabStripCoordinator start];
     }
@@ -1993,7 +1946,7 @@
   DCHECK(self.browser);
   DCHECK([self isViewLoaded]);
 
-  [self.sideSwipeController addHorizontalGesturesToView:self.view];
+  [_sideSwipeController addHorizontalGesturesToView:self.view];
 
   // TODO(crbug.com/1331229): Remove all use of the download manager coordinator
   // from BVC
@@ -2007,13 +1960,6 @@
   self.helpHandler =
       HandlerForProtocol(self.browser->GetCommandDispatcher(), HelpCommands);
 
-  // TODO(crbug.com/1329098): Assuming all of the coordinators are in
-  // BrowserCoordinator, move this setup there as well.
-  if (!base::FeatureList::IsEnabled(kModernTabStrip)) {
-    self.legacyTabStripCoordinator.longPressDelegate =
-        self.popupMenuCoordinator;
-  }
-
   // TODO(crbug.com/1329089): Inject this handler.
   self.omniboxHandler =
       HandlerForProtocol(self.browser->GetCommandDispatcher(), OmniboxCommands);
@@ -3687,7 +3633,7 @@
   if (self.isNTPActiveForCurrentWebState) {
     [_ntpCoordinator locationBarDidBecomeFirstResponder];
   }
-  [self.sideSwipeController setEnabled:NO];
+  [_sideSwipeController setEnabled:NO];
 
   if (!IsVisibleURLNewTabPage(self.currentWebState)) {
     // Tapping on web content area should dismiss the keyboard. Tapping on NTP
@@ -3708,7 +3654,7 @@
 
 - (void)locationBarDidResignFirstResponder {
   _keyCommandsProvider.canDismissModals = NO;
-  [self.sideSwipeController setEnabled:YES];
+  [_sideSwipeController setEnabled:YES];
 
   if (self.isNTPActiveForCurrentWebState) {
     [_ntpCoordinator locationBarDidResignFirstResponder];
@@ -4260,7 +4206,7 @@
 
   // Reset horizontal stack view.
   [sideSwipeView removeFromSuperview];
-  [self.sideSwipeController setInSwipe:NO];
+  [_sideSwipeController setInSwipe:NO];
 }
 
 - (UIView*)sideSwipeContentView {
@@ -4273,7 +4219,7 @@
 
 // TODO(crbug.com/1329105): Federate side swipe logic.
 - (BOOL)preventSideSwipe {
-  if ([self.popupMenuCoordinator isShowingPopupMenu])
+  if (_isShowingPopupMenu)
     return YES;
 
   if (_voiceSearchController.visible)
@@ -4496,6 +4442,16 @@
   return self;
 }
 
+#pragma mark - PopupMenuAppearanceDelegate
+
+- (void)popupMenuDidAppear {
+  _isShowingPopupMenu = YES;
+}
+
+- (void)popupMenuDidDisappear {
+  _isShowingPopupMenu = NO;
+}
+
 #pragma mark - Getters
 
 - (NewTabPageCoordinator*)ntpCoordinator {
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm
index 762d479c..34a41ab 100644
--- a/ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm
@@ -37,6 +37,7 @@
 #import "ios/chrome/browser/ui/download/download_manager_coordinator.h"
 #import "ios/chrome/browser/ui/main/scene_state.h"
 #import "ios/chrome/browser/ui/main/scene_state_browser_agent.h"
+#import "ios/chrome/browser/ui/side_swipe/side_swipe_controller.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_coordinator.h"
 #import "ios/chrome/browser/ui/tabs/tab_strip_legacy_coordinator.h"
 #import "ios/chrome/browser/ui/toolbar/primary_toolbar_coordinator.h"
@@ -206,6 +207,9 @@
     legacy_tab_strip_coordinator_ =
         [[TabStripLegacyCoordinator alloc] initWithBrowser:browser_.get()];
 
+    side_swipe_controller_ =
+        [[SideSwipeController alloc] initWithBrowser:browser_.get()];
+
     BrowserViewControllerDependencies dependencies;
     dependencies.prerenderService = fake_prerender_service_.get();
     dependencies.bubblePresenter = bubble_presenter_;
@@ -215,6 +219,7 @@
     dependencies.secondaryToolbarCoordinator = secondary_toolbar_coordinator_;
     dependencies.tabStripCoordinator = tab_strip_coordinator_;
     dependencies.legacyTabStripCoordinator = legacy_tab_strip_coordinator_;
+    dependencies.sideSwipeController = side_swipe_controller_;
 
     bvc_ = [[BrowserViewController alloc]
                        initWithBrowser:browser_.get()
@@ -224,6 +229,11 @@
                    keyCommandsProvider:key_commands_provider_
                           dependencies:dependencies];
 
+    popup_menu_coordinator_ = [[PopupMenuCoordinator alloc]
+        initWithBaseViewController:bvc_
+                           browser:browser_.get()];
+    [popup_menu_coordinator_ start];
+
     // Force the view to load.
     UIWindow* window = [[UIWindow alloc] initWithFrame:CGRectZero];
     [window addSubview:[bvc_ view]];
@@ -266,6 +276,8 @@
   SecondaryToolbarCoordinator* secondary_toolbar_coordinator_;
   TabStripCoordinator* tab_strip_coordinator_;
   TabStripLegacyCoordinator* legacy_tab_strip_coordinator_;
+  PopupMenuCoordinator* popup_menu_coordinator_;
+  SideSwipeController* side_swipe_controller_;
 };
 
 TEST_F(BrowserViewControllerTest, TestWebStateSelected) {
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.h b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.h
index 60a7cc5..696cded 100644
--- a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.h
+++ b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.h
@@ -13,6 +13,16 @@
 @class BubblePresenter;
 @protocol PopupMenuUIUpdating;
 
+// Delegate that noitfies about pop up menu appearance change.
+@protocol PopupMenuAppearanceDelegate
+
+// Noitfies delegate that pop up menu did appear.
+- (void)popupMenuDidAppear;
+// Noitfies delegate that pop up menu did disappear.
+- (void)popupMenuDidDisappear;
+
+@end
+
 // Coordinator for the popup menu, handling the commands.
 @interface PopupMenuCoordinator : ChromeCoordinator<PopupMenuLongPressDelegate>
 
@@ -21,8 +31,8 @@
 // Bubble view presenter for the incognito tip.
 @property(nonatomic, weak) BubblePresenter* bubblePresenter;
 
-// Returns whether this coordinator is showing a popup menu.
-- (BOOL)isShowingPopupMenu;
+@property(nonatomic, weak) id<PopupMenuAppearanceDelegate>
+    popupMenuAppearanceDelegate;
 
 @end
 
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm
index 638d8f6c..9dbe5ed 100644
--- a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm
+++ b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm
@@ -134,12 +134,6 @@
   self.viewController = nil;
 }
 
-#pragma mark - Public
-
-- (BOOL)isShowingPopupMenu {
-  return self.presenter != nil;
-}
-
 #pragma mark - PopupMenuCommands
 
 - (void)showNavigationHistoryBackPopupMenu {
@@ -212,6 +206,7 @@
   }
   [self.presenter dismissAnimated:animated];
   self.presenter = nil;
+  [self.popupMenuAppearanceDelegate popupMenuDidDisappear];
   [self.mediator disconnect];
   self.mediator = nil;
   self.viewController = nil;
@@ -487,6 +482,8 @@
   [self.presenter prepareForPresentation];
   [self.presenter presentAnimated:YES];
 
+  [self.popupMenuAppearanceDelegate popupMenuDidAppear];
+
   // Scrolls happen during prepareForPresentation, so only attach the metrics
   // handler after presentation is done.
   if (type == PopupMenuTypeToolsMenu) {
diff --git a/media/audio/BUILD.gn b/media/audio/BUILD.gn
index bf0142f..f8b5193b 100644
--- a/media/audio/BUILD.gn
+++ b/media/audio/BUILD.gn
@@ -442,18 +442,18 @@
     ]
   }
 
-  if (is_chromeos_ash || is_castos || is_cast_android) {
+  if (is_chromeos_ash || is_chromecast) {
     sources += [
       "test_data.h",
       "wav_audio_handler_unittest.cc",
     ]
-  }
 
-  if (is_chromeos_ash) {
-    deps += [
-      "//ash/components/audio",
-      "//chromeos/dbus/audio",
-    ]
+    if (!is_chromecast) {
+      deps += [
+        "//ash/components/audio",
+        "//chromeos/dbus/audio",
+      ]
+    }
 
     if (use_cras) {
       sources += [
diff --git a/media/audio/audio_device_description.cc b/media/audio/audio_device_description.cc
index a2d515b8..2feaa22 100644
--- a/media/audio/audio_device_description.cc
+++ b/media/audio/audio_device_description.cc
@@ -58,9 +58,7 @@
 std::string AudioDeviceDescription::GetCommunicationsDeviceName() {
 #if BUILDFLAG(IS_WIN)
   return GetLocalizedStringUTF8(COMMUNICATIONS_AUDIO_DEVICE_NAME);
-#elif BUILDFLAG(IS_CASTOS) || BUILDFLAG(IS_CAST_ANDROID)
-  // TODO(crbug.com/1336055): Re-evaluate if this is still needed now that CMA
-  // is deprecated.
+#elif BUILDFLAG(IS_CHROMECAST)
   return "";
 #else
   NOTREACHED();
diff --git a/media/base/BUILD.gn b/media/base/BUILD.gn
index 2485c8e..1b14b44 100644
--- a/media/base/BUILD.gn
+++ b/media/base/BUILD.gn
@@ -407,7 +407,7 @@
     deps += [ "//third_party/libvpx" ]
   }
 
-  if (is_linux && !is_castos) {
+  if (is_linux && !is_chromecast) {
     sources += [ "user_input_monitor_linux.cc" ]
   } else if (is_mac) {
     sources += [ "user_input_monitor_mac.cc" ]
@@ -446,9 +446,11 @@
     ]
   }
 
+  # TODO(ziyangch): Check |is_chromecast| first when using cast media pipeline
+  # on Android cast devices.
   if (is_android) {
     sources += [ "demuxer_memory_limit_android.cc" ]
-  } else if (is_castos) {
+  } else if (is_chromecast) {
     sources += [ "demuxer_memory_limit_cast.cc" ]
   } else if (is_fuchsia) {
     sources += [ "demuxer_memory_limit_low.cc" ]
@@ -661,7 +663,7 @@
     ]
   }
 
-  if (is_castos) {
+  if (is_chromecast && !is_android) {
     sources += [ "demuxer_memory_limit_cast_unittest.cc" ]
   }
 }
diff --git a/media/cast/BUILD.gn b/media/cast/BUILD.gn
index 02b5b2f2..7298d8b 100644
--- a/media/cast/BUILD.gn
+++ b/media/cast/BUILD.gn
@@ -316,7 +316,7 @@
 
   # FFMPEG software video decoders are not available on Android and/or
   # Chromecast content_shell builds.
-  if (!is_android && !is_castos) {
+  if (!is_android && !is_chromecast) {
     sources += [
       "test/fake_media_source.cc",
       "test/fake_media_source.h",
diff --git a/media/filters/BUILD.gn b/media/filters/BUILD.gn
index 9677fa2..a4cd06a 100644
--- a/media/filters/BUILD.gn
+++ b/media/filters/BUILD.gn
@@ -326,8 +326,8 @@
   }
 
   # libvpx for running vpx test on chromecast doesn't support high bit depth.
-  # This may cause some unit tests failure. See b/65382374 for further context.
-  if (is_castos) {
+  # This may cause some unit tests failure.
+  if (is_chromecast) {
     defines = [ "LIBVPX_NO_HIGH_BIT_DEPTH" ]
   }
 
diff --git a/media/formats/mp4/track_run_iterator.cc b/media/formats/mp4/track_run_iterator.cc
index ee3e0ab0..30329b4f 100644
--- a/media/formats/mp4/track_run_iterator.cc
+++ b/media/formats/mp4/track_run_iterator.cc
@@ -500,10 +500,7 @@
           // If we don't have a per-sample IV, get the constant IV.
           bool is_encrypted = index == 0 ? track_encryption->is_encrypted
                                          : info_entry->is_encrypted;
-
-          // TODO(crbug.com/1336055): Investigate if this is a hardware or
-          // cast-related limitation.
-#if BUILDFLAG(IS_CASTOS)
+#if BUILDFLAG(IS_CHROMECAST)
           // On Chromecast, we only support setting the pattern values in the
           // 'tenc' box for the track (not varying on per sample group basis).
           // Thus we need to verify that the settings in the sample group
@@ -522,7 +519,7 @@
                                 "sample group does not match that in the tenc "
                                 "box . This is not currently supported.");
           }
-#endif  // BUILDFLAG(IS_CASTOS)
+#endif  // BUILDFLAG(IS_CHROMECAST)
           if (is_encrypted && !iv_size) {
             const uint8_t constant_iv_size =
                 index == 0 ? track_encryption->default_constant_iv_size
diff --git a/media/gpu/args.gni b/media/gpu/args.gni
index da3ea5a..bb2ff07 100644
--- a/media/gpu/args.gni
+++ b/media/gpu/args.gni
@@ -8,8 +8,9 @@
 declare_args() {
   # Indicates if X11 VA-API-based hardware acceleration is to be used.
   # See also the comment near the |use_vaapi| arg.
-  use_vaapi_x11 = is_linux && ozone_platform_x11 &&
-                  (target_cpu == "x86" || target_cpu == "x64") && !is_castos
+  use_vaapi_x11 =
+      is_linux && ozone_platform_x11 && !is_chromecast && !is_chromeos_lacros &&
+      (target_cpu == "x86" || target_cpu == "x64")
 }
 
 declare_args() {
diff --git a/media/mojo/mojom/BUILD.gn b/media/mojo/mojom/BUILD.gn
index f65c4b2..d36f580c 100644
--- a/media/mojo/mojom/BUILD.gn
+++ b/media/mojo/mojom/BUILD.gn
@@ -61,9 +61,7 @@
     sources += [ "speech_recognition_service.mojom" ]
   }
 
-  # TODO(crbug.com/1293520): Revisit this after the cast renderer has been
-  # deprecated and removed.
-  if (is_castos || is_cast_android) {
+  if (is_chromecast) {
     sources += [ "cast_application_media_info_manager.mojom" ]
   }
 
diff --git a/media/mojo/services/media_metrics_provider.cc b/media/mojo/services/media_metrics_provider.cc
index e98ae88..62d2f6a 100644
--- a/media/mojo/services/media_metrics_provider.cc
+++ b/media/mojo/services/media_metrics_provider.cc
@@ -22,9 +22,9 @@
 
 #if !BUILDFLAG(IS_ANDROID)
 #include "media/filters/decrypting_video_decoder.h"
-#endif
+#endif  // !BUILDFLAG(IS_ANDROID)
 
-#if BUILDFLAG(IS_FUCHSIA) || BUILDFLAG(IS_CAST_ANDROID)
+#if BUILDFLAG(IS_FUCHSIA) || (BUILDFLAG(IS_CHROMECAST) && BUILDFLAG(IS_ANDROID))
 #include "media/mojo/services/playback_events_recorder.h"
 #endif
 
@@ -350,7 +350,7 @@
 
 void MediaMetricsProvider::AcquirePlaybackEventsRecorder(
     mojo::PendingReceiver<mojom::PlaybackEventsRecorder> receiver) {
-#if BUILDFLAG(IS_FUCHSIA) || BUILDFLAG(IS_CAST_ANDROID)
+#if BUILDFLAG(IS_FUCHSIA) || (BUILDFLAG(IS_CHROMECAST) && BUILDFLAG(IS_ANDROID))
   PlaybackEventsRecorder::Create(std::move(receiver));
 #endif
 }
diff --git a/media/renderers/paint_canvas_video_renderer.cc b/media/renderers/paint_canvas_video_renderer.cc
index 534f9e9..fa31f7d 100644
--- a/media/renderers/paint_canvas_video_renderer.cc
+++ b/media/renderers/paint_canvas_video_renderer.cc
@@ -747,7 +747,8 @@
 
   bool GetYUVAPlanes(const SkYUVAPixmaps& pixmaps,
                      size_t frame_index,
-                     uint32_t lazy_pixel_ref) override {
+                     uint32_t lazy_pixel_ref,
+                     cc::PaintImage::GeneratorClientId client_id) override {
     DCHECK_EQ(frame_index, 0u);
     DCHECK_EQ(pixmaps.numPlanes(), 3);
 
diff --git a/media/webrtc/audio_processor.cc b/media/webrtc/audio_processor.cc
index 24d694d0..586fea2 100644
--- a/media/webrtc/audio_processor.cc
+++ b/media/webrtc/audio_processor.cc
@@ -39,7 +39,7 @@
 
 int GetCaptureBufferSize(bool need_webrtc_processing,
                          const AudioParameters device_format) {
-#if BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CAST_ANDROID)
+#if BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMECAST)
   // TODO(henrika): Re-evaluate whether to use same logic as other platforms.
   // https://crbug.com/638081
   return 2 * device_format.sample_rate() / 100;
@@ -579,16 +579,14 @@
     const AudioProcessingSettings& settings) {
   const bool need_webrtc_audio_processing =
       settings.NeedWebrtcAudioProcessing();
-  // TODO(crbug.com/1336055): Investigate why chromecast devices need special
-  // logic here.
   const int output_sample_rate =
       need_webrtc_audio_processing ?
-#if BUILDFLAG(IS_CASTOS) || BUILDFLAG(IS_CAST_ANDROID)
+#if BUILDFLAG(IS_CHROMECAST)
                                    std::min(media::kAudioProcessingSampleRateHz,
                                             input_format.sample_rate())
 #else
                                    media::kAudioProcessingSampleRateHz
-#endif
+#endif  // BUILDFLAG(IS_CHROMECAST)
                                    : input_format.sample_rate();
 
   media::ChannelLayout output_channel_layout;
diff --git a/media/webrtc/audio_processor_test.cc b/media/webrtc/audio_processor_test.cc
index 941443d..ed020a0 100644
--- a/media/webrtc/audio_processor_test.cc
+++ b/media/webrtc/audio_processor_test.cc
@@ -38,18 +38,16 @@
 namespace media {
 namespace {
 
-// TODO(crbug.com/1334991): Clarify WebRTC audio processing support for 96 kHz
-// input.
 static const int kSupportedSampleRates[] = {8000,
                                             16000,
                                             22050,
                                             32000,
                                             44100,
                                             48000
-#if BUILDFLAG(IS_CASTOS) || BUILDFLAG(IS_CAST_ANDROID)
+#if BUILDFLAG(IS_CHROMECAST)
                                             ,
                                             96000
-#endif
+#endif  // BUILDFLAG(IS_CHROMECAST)
 };
 
 using MockProcessedCaptureCallback =
diff --git a/media/webrtc/helpers.cc b/media/webrtc/helpers.cc
index e2c2bc9..57a50bb 100644
--- a/media/webrtc/helpers.cc
+++ b/media/webrtc/helpers.cc
@@ -25,14 +25,11 @@
 #endif  // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS)
 
 // The analog gain controller can only be disabled on Chromecast.
-//
-// TODO(crbug.com/1336055): kAllowToDisableAnalogAgc should be removed once AGC2
-// is fully launched.
-#if BUILDFLAG(IS_CASTOS) || BUILDFLAG(IS_CAST_ANDROID)
+#if BUILDFLAG(IS_CHROMECAST)
 constexpr bool kAllowToDisableAnalogAgc = true;
 #else
 constexpr bool kAllowToDisableAnalogAgc = false;
-#endif
+#endif  // BUILDFLAG(IS_CHROMECAST)
 
 // AGC1 mode.
 using Agc1Mode = webrtc::AudioProcessing::Config::GainController1::Mode;
diff --git a/media/webrtc/helpers_unittests.cc b/media/webrtc/helpers_unittests.cc
index 1d8970e6..4b3bd1a 100644
--- a/media/webrtc/helpers_unittests.cc
+++ b/media/webrtc/helpers_unittests.cc
@@ -117,10 +117,7 @@
   auto config = CreateApmGetConfig(
       /*settings=*/{.automatic_gain_control = false,
                     .experimental_automatic_gain_control = false});
-
-// TODO(crbug.com/1336055): Make this check non-conditional following the launch
-// of AGC2.
-#if BUILDFLAG(IS_CASTOS) || BUILDFLAG(IS_CAST_ANDROID)
+#if BUILDFLAG(IS_CHROMECAST)
   // Override the default config since on Chromecast AGC1 is explicitly
   // disabled.
   auto expected_config = kDefaultApmConfig.gain_controller1;
@@ -128,7 +125,7 @@
   EXPECT_EQ(config.gain_controller1, expected_config);
 #else
   EXPECT_EQ(config.gain_controller1, kDefaultApmConfig.gain_controller1);
-#endif  // BUILDFLAG(IS_CASTOS) || BUILDFLAG(IS_CAST_ANDROID)
+#endif
 }
 
 TEST(CreateWebRtcAudioProcessingModuleTest,
diff --git a/pdf/features.gni b/pdf/features.gni
index 45d167e..b6853b2 100644
--- a/pdf/features.gni
+++ b/pdf/features.gni
@@ -17,5 +17,5 @@
   # feature is enabled for the PDF viewer.
   enable_ink = enable_cros_media_app
 
-  enable_pdf = !is_android && !is_ios && !is_chromecast
+  enable_pdf = !is_android && !is_ios && !is_castos
 }
diff --git a/pdf/pdf_view_plugin_base.cc b/pdf/pdf_view_plugin_base.cc
index 0c34de4..5a8d576 100644
--- a/pdf/pdf_view_plugin_base.cc
+++ b/pdf/pdf_view_plugin_base.cc
@@ -42,8 +42,6 @@
 #include "pdf/pdf_features.h"
 #include "pdf/pdfium/pdfium_engine.h"
 #include "pdf/pdfium/pdfium_form_filler.h"
-#include "pdf/ppapi_migration/result_codes.h"
-#include "pdf/ppapi_migration/url_loader.h"
 #include "pdf/ui/file_name.h"
 #include "pdf/ui/thumbnail.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -850,18 +848,6 @@
       kAccessibilityPageDelay);
 }
 
-void PdfViewPluginBase::DidOpen(std::unique_ptr<UrlLoader> loader,
-                                int32_t result) {
-  if (result == kSuccess) {
-    if (!engine()->HandleDocumentLoad(std::move(loader), GetURL())) {
-      document_load_state_ = DocumentLoadState::kLoading;
-      DocumentLoadFailed();
-    }
-  } else if (result != kErrorAborted) {
-    DocumentLoadFailed();
-  }
-}
-
 gfx::Point PdfViewPluginBase::FrameToPdfCoordinates(
     const gfx::PointF& frame_coordinates) const {
   // TODO(crbug.com/1288847): Use methods on `blink::WebPluginContainer`.
diff --git a/pdf/pdf_view_plugin_base.h b/pdf/pdf_view_plugin_base.h
index d9125394..809f3dc 100644
--- a/pdf/pdf_view_plugin_base.h
+++ b/pdf/pdf_view_plugin_base.h
@@ -42,7 +42,6 @@
 class PDFiumEngine;
 class PaintReadyRect;
 class Thumbnail;
-class UrlLoader;
 struct AccessibilityActionData;
 struct AccessibilityCharInfo;
 struct AccessibilityDocInfo;
@@ -128,12 +127,6 @@
   }
 
  protected:
-  // Callback that runs after `LoadUrl()`. The `loader` is the loader used to
-  // load the URL, and `result` is the result code for the load.
-  using LoadUrlCallback =
-      base::OnceCallback<void(std::unique_ptr<UrlLoader> loader,
-                              int32_t result)>;
-
   struct BackgroundPart {
     gfx::Rect location;
     uint32_t color;
@@ -150,9 +143,6 @@
   virtual const PDFiumEngine* engine() const = 0;
   virtual PDFiumEngine* engine() = 0;
 
-  // Loads `url`, invoking `callback` on receiving the initial response.
-  virtual void LoadUrl(base::StringPiece url, LoadUrlCallback callback) = 0;
-
   // Gets a weak pointer with a lifetime matching the derived class.
   virtual base::WeakPtr<PdfViewPluginBase> GetWeakPtr() = 0;
 
@@ -320,9 +310,6 @@
     return size > 0 && size <= kMaximumSavedFileSize;
   }
 
-  // Handles `LoadUrl()` result.
-  void DidOpen(std::unique_ptr<UrlLoader> loader, int32_t result);
-
   // Converts a scroll offset (which is relative to a UI direction-dependent
   // scroll origin) to a scroll position (which is always relative to the
   // top-left corner).
diff --git a/pdf/pdf_view_web_plugin.cc b/pdf/pdf_view_web_plugin.cc
index 2b3bcafa..534f9e0 100644
--- a/pdf/pdf_view_web_plugin.cc
+++ b/pdf/pdf_view_web_plugin.cc
@@ -14,6 +14,7 @@
 #include <vector>
 
 #include "base/bind.h"
+#include "base/callback.h"
 #include "base/check_op.h"
 #include "base/containers/fixed_flat_map.h"
 #include "base/containers/queue.h"
@@ -336,8 +337,8 @@
     return true;
 
   set_last_progress_sent(0);
-  LoadUrl(params->src_url,
-          base::BindOnce(&PdfViewWebPlugin::DidOpen, GetWeakPtr()));
+  LoadUrl(params->src_url, base::BindOnce(&PdfViewWebPlugin::DidOpen,
+                                          weak_factory_.GetWeakPtr()));
   url_ = params->original_url;
 
   // Not all edits go through the PDF plugin's form filler. The plugin instance
@@ -360,6 +361,18 @@
   SendMessage(std::move(message));
 }
 
+void PdfViewWebPlugin::DidOpen(std::unique_ptr<UrlLoader> loader,
+                               int32_t result) {
+  if (result == kSuccess) {
+    if (!engine_->HandleDocumentLoad(std::move(loader), url_)) {
+      set_document_load_state(DocumentLoadState::kLoading);
+      DocumentLoadFailed();
+    }
+  } else if (result != kErrorAborted) {
+    DocumentLoadFailed();
+  }
+}
+
 void PdfViewWebPlugin::Destroy() {
   if (client_->PluginContainer()) {
     // Explicitly destroy the PDFEngine during destruction as it may call back
@@ -1632,7 +1645,8 @@
   preview_document_load_state_ = DocumentLoadState::kComplete;
   set_document_load_state(DocumentLoadState::kLoading);
   set_last_progress_sent(0);
-  LoadUrl(url_, base::BindOnce(&PdfViewWebPlugin::DidOpen, GetWeakPtr()));
+  LoadUrl(url_, base::BindOnce(&PdfViewWebPlugin::DidOpen,
+                               weak_factory_.GetWeakPtr()));
   preview_engine_.reset();
 
   // TODO(crbug.com/1237952): Figure out a more consistent way to preserve
diff --git a/pdf/pdf_view_web_plugin.h b/pdf/pdf_view_web_plugin.h
index fdbe8cf8..e644810 100644
--- a/pdf/pdf_view_web_plugin.h
+++ b/pdf/pdf_view_web_plugin.h
@@ -11,11 +11,13 @@
 #include <string>
 #include <vector>
 
+#include "base/callback_forward.h"
 #include "base/containers/flat_set.h"
 #include "base/containers/queue.h"
 #include "base/i18n/rtl.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
+#include "base/strings/string_piece_forward.h"
 #include "base/values.h"
 #include "cc/paint/paint_image.h"
 #include "mojo/public/cpp/bindings/associated_remote.h"
@@ -340,7 +342,6 @@
       PDFiumFormFiller::ScriptOption script_option) override;
   const PDFiumEngine* engine() const override;
   PDFiumEngine* engine() override;
-  void LoadUrl(base::StringPiece url, LoadUrlCallback callback) override;
   base::WeakPtr<PdfViewPluginBase> GetWeakPtr() override;
   void OnPrintPreviewLoaded() override;
   void OnDocumentLoadComplete() override;
@@ -372,6 +373,12 @@
   void PrepareForFirstPaint(std::vector<PaintReadyRect>& ready) override;
 
  private:
+  // Callback that runs after `LoadUrl()`. The `loader` is the loader used to
+  // load the URL, and `result` is the result code for the load.
+  using LoadUrlCallback =
+      base::OnceCallback<void(std::unique_ptr<UrlLoader> loader,
+                              int32_t result)>;
+
   // Metadata about an available preview page.
   struct PreviewPageInfo {
     // Data source URL.
@@ -389,10 +396,16 @@
   // Sends whether to do smooth scrolling.
   void SendSetSmoothScrolling();
 
+  // Handles `LoadUrl()` result for the main document.
+  void DidOpen(std::unique_ptr<UrlLoader> loader, int32_t result);
+
   // Updates the scroll position, which is in CSS pixels relative to the
   // top-left corner.
   void UpdateScroll(const gfx::PointF& scroll_position);
 
+  // Loads `url`, invoking `callback` on receiving the initial response.
+  void LoadUrl(base::StringPiece url, LoadUrlCallback callback);
+
   // Handles `Open()` result for `form_loader_`.
   void DidFormOpen(int32_t result);
 
diff --git a/ppapi/buildflags/buildflags.gni b/ppapi/buildflags/buildflags.gni
index 560d1ec..2e3f0b9 100644
--- a/ppapi/buildflags/buildflags.gni
+++ b/ppapi/buildflags/buildflags.gni
@@ -7,5 +7,5 @@
 import("//build/config/features.gni")
 
 declare_args() {
-  enable_plugins = !is_android && !is_ios && !is_chromecast && !is_fuchsia
+  enable_plugins = !is_android && !is_ios && !is_castos && !is_fuchsia
 }
diff --git a/printing/buildflags/buildflags.gni b/printing/buildflags/buildflags.gni
index 559ac76d..1d2b24ad 100644
--- a/printing/buildflags/buildflags.gni
+++ b/printing/buildflags/buildflags.gni
@@ -11,7 +11,7 @@
 
 declare_args() {
   # Enables basic printing support and UI.
-  enable_basic_printing = !is_chromecast && !is_ios
+  enable_basic_printing = !is_ios && !is_castos && !is_cast_android
 }
 
 declare_args() {
@@ -24,8 +24,8 @@
     # For fuzzing, just restrict to chromeos and linux.
     use_cups = true
   } else {
-    use_cups = (is_chromeos_device || is_linux || is_chromeos_lacros ||
-                is_mac) && !is_chromecast && !is_fuchsia
+    use_cups = (is_chromeos_device || (is_linux && !is_castos) ||
+                is_chromeos_lacros || is_mac) && !is_fuchsia
   }
 
   # Enables out-of-process printing. While this definition matches
diff --git a/remoting/remoting_enable.gni b/remoting/remoting_enable.gni
index 879214d..707404d 100644
--- a/remoting/remoting_enable.gni
+++ b/remoting/remoting_enable.gni
@@ -9,5 +9,5 @@
 }
 
 declare_args() {
-  enable_remoting = !is_chromecast && !is_fuchsia
+  enable_remoting = !is_castos && !is_cast_android && !is_fuchsia
 }
diff --git a/remoting/remoting_options.gni b/remoting/remoting_options.gni
index b81fd31..d840a07 100644
--- a/remoting/remoting_options.gni
+++ b/remoting/remoting_options.gni
@@ -8,10 +8,8 @@
 import("//build/config/ui.gni")
 import("//remoting/build/config/remoting_features.gni")
 
-# TODO(crbug.com/1052397): Remove is_chromeos_lacros once the target_os switch
-# is completed.
-remoting_use_x11 = ozone_platform_x11 && is_linux && !is_chromecast &&
-                   !is_chromeos_lacros && !remoting_use_wayland
+remoting_use_x11 =
+    ozone_platform_x11 && (is_linux && !is_castos) && !remoting_use_wayland
 
 enable_remoting_host = is_win || is_mac || is_chromeos_ash ||
                        remoting_use_x11 || (is_linux && remoting_use_wayland)
diff --git a/sandbox/policy/linux/bpf_screen_ai_policy_linux.cc b/sandbox/policy/linux/bpf_screen_ai_policy_linux.cc
index d10fb1a2..496cb1e 100644
--- a/sandbox/policy/linux/bpf_screen_ai_policy_linux.cc
+++ b/sandbox/policy/linux/bpf_screen_ai_policy_linux.cc
@@ -6,6 +6,7 @@
 
 #include "sandbox/linux/bpf_dsl/bpf_dsl.h"
 #include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h"
+#include "sandbox/linux/system_headers/linux_futex.h"
 #include "sandbox/linux/system_headers/linux_syscalls.h"
 #include "sandbox/policy/linux/sandbox_linux.h"
 
@@ -27,15 +28,36 @@
     return sandbox_linux->HandleViaBroker(system_call_number);
 
   switch (system_call_number) {
+    case __NR_futex:
+#if defined(__NR_futex_time64)
+    case __NR_futex_time64:
+#endif
+    {
+      const Arg<int> op(1);
+      return Switch(op & FUTEX_CMD_MASK)
+          .SANDBOX_BPF_DSL_CASES(
+              (FUTEX_CMP_REQUEUE, FUTEX_LOCK_PI, FUTEX_UNLOCK_PI, FUTEX_WAIT,
+               FUTEX_WAIT_BITSET, FUTEX_WAKE),
+              Allow())
+          // Sending ENOSYS tells the Futex backend to use another approach if
+          // this fails.
+          .Default(Error(ENOSYS));
+    }
+
     case __NR_getitimer:
     case __NR_setitimer: {
       const Arg<int> which(0);
       return If(which == ITIMER_PROF, Allow()).Else(Error(EPERM));
     }
+
     case __NR_get_mempolicy: {
       const Arg<unsigned long> which(4);
       return If(which == 0, Allow()).Else(Error(EPERM));
     }
+
+    case __NR_prlimit64:
+      return RestrictPrlimitToGetrlimit(GetPolicyPid());
+
     case __NR_sched_getaffinity:
       return RestrictSchedTarget(GetPolicyPid(), system_call_number);
 
diff --git a/services/audio/BUILD.gn b/services/audio/BUILD.gn
index 80db1c46..6427c7e 100644
--- a/services/audio/BUILD.gn
+++ b/services/audio/BUILD.gn
@@ -204,7 +204,7 @@
     "//testing/gtest",
   ]
 
-  if (is_chromeos_ash || is_chromecast) {
+  if (is_chromeos_ash || is_castos || is_cast_android) {
     sources += [
       "public/cpp/sounds/audio_stream_handler_unittest.cc",
       "public/cpp/sounds/sounds_manager_unittest.cc",
diff --git a/services/audio/stream_factory.cc b/services/audio/stream_factory.cc
index 48152cb..1282b1d 100644
--- a/services/audio/stream_factory.cc
+++ b/services/audio/stream_factory.cc
@@ -133,8 +133,11 @@
 
   // This is required for multizone audio playback on Cast devices.
   // See //chromecast/media/cast_audio_manager.h for more information.
+  //
+  // TODO(crbug.com/1336055): Determine if this condition should instead be
+  // ENABLE_CAST_RECEIVER && !IS_FUCHSIA.
   const std::string device_id_or_group_id =
-#if BUILDFLAG(IS_CHROMECAST)
+#if BUILDFLAG(IS_CASTOS) || BUILDFLAG(IS_CAST_ANDROID)
       (::media::AudioDeviceDescription::IsCommunicationsDevice(
            output_device_id) ||
        group_id.is_empty())
diff --git a/services/device/time_zone_monitor/time_zone_monitor_linux.cc b/services/device/time_zone_monitor/time_zone_monitor_linux.cc
index b7c267b..b76f4db 100644
--- a/services/device/time_zone_monitor/time_zone_monitor_linux.cc
+++ b/services/device/time_zone_monitor/time_zone_monitor_linux.cc
@@ -45,8 +45,8 @@
   ~TimeZoneMonitorLinux() override;
 
   void NotifyClientsFromImpl() {
-#if BUILDFLAG(IS_CHROMECAST)
-    // On Chromecast, ICU's default time zone is already set to a new zone. No
+#if BUILDFLAG(IS_CASTOS)
+    // On CastOS, ICU's default time zone is already set to a new zone. No
     // need to redetect it with detectHostTimeZone() or to update ICU.
     // See http://b/112498903 and http://b/113344065.
     std::unique_ptr<icu::TimeZone> new_zone(icu::TimeZone::createDefault());
@@ -64,7 +64,7 @@
     }
 
     UpdateIcuAndNotifyClients(std::move(new_zone));
-#endif  // defined(IS_CHROMECAST)
+#endif  // defined(IS_CASTOS)
   }
 
  private:
diff --git a/services/network/network_service.cc b/services/network/network_service.cc
index 0516443..a1adc043 100644
--- a/services/network/network_service.cc
+++ b/services/network/network_service.cc
@@ -82,8 +82,9 @@
 #include "third_party/boringssl/src/include/openssl/cpu.h"
 #endif
 
-#if (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) && \
-    !BUILDFLAG(IS_CHROMECAST)
+#if (BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CASTOS)) || \
+    BUILDFLAG(IS_CHROMEOS_LACROS)
+
 #include "components/os_crypt/key_storage_config_linux.h"
 #endif
 
diff --git a/services/network/public/cpp/features.cc b/services/network/public/cpp/features.cc
index 1b6687f..0570c37 100644
--- a/services/network/public/cpp/features.cc
+++ b/services/network/public/cpp/features.cc
@@ -288,9 +288,12 @@
     &kPervasivePayloadsList, "pervasive-payloads", ""};
 
 // Read as much of the net::URLRequest as there is space in the Mojo data pipe.
-const base::Feature kOptimizeNetworkBuffers{"OptimizeNetworkBuffers",
+const base::Feature kOptimizeNetworkBuffers{"OptimizeNetworkBuffers2",
                                             base::FEATURE_DISABLED_BY_DEFAULT};
 
+const base::FeatureParam<int> kOptimizeNetworkBuffersBytesReadLimit{
+    &kOptimizeNetworkBuffers, "bytes_read_limit", 64 * 1024};
+
 // Enables support for the `Variants` response header and reduce
 // accept-language. https://github.com/Tanych/accept-language
 const base::Feature kReduceAcceptLanguage{"ReduceAcceptLanguage",
diff --git a/services/network/public/cpp/features.h b/services/network/public/cpp/features.h
index b5599ca..61119ad4 100644
--- a/services/network/public/cpp/features.h
+++ b/services/network/public/cpp/features.h
@@ -113,6 +113,9 @@
 extern const base::Feature kOptimizeNetworkBuffers;
 
 COMPONENT_EXPORT(NETWORK_CPP)
+extern const base::FeatureParam<int> kOptimizeNetworkBuffersBytesReadLimit;
+
+COMPONENT_EXPORT(NETWORK_CPP)
 extern const base::Feature kCacheTransparency;
 
 COMPONENT_EXPORT(NETWORK_CPP)
diff --git a/services/network/public/cpp/net_adapters.cc b/services/network/public/cpp/net_adapters.cc
index c94221d..a0fdfc1 100644
--- a/services/network/public/cpp/net_adapters.cc
+++ b/services/network/public/cpp/net_adapters.cc
@@ -32,10 +32,14 @@
   MojoResult result =
       (*handle)->BeginWriteData(&buf, num_bytes, MOJO_WRITE_DATA_FLAG_NONE);
   if (result == MOJO_RESULT_OK) {
-    if (!base::FeatureList::IsEnabled(features::kOptimizeNetworkBuffers) &&
-        *num_bytes > kMaxBufSize) {
-      *num_bytes = kMaxBufSize;
+    uint32_t max_bytes = kMaxBufSize;
+    if (base::FeatureList::IsEnabled(features::kOptimizeNetworkBuffers)) {
+      max_bytes = features::kOptimizeNetworkBuffersBytesReadLimit.Get();
     }
+
+    if (*num_bytes > max_bytes)
+      *num_bytes = max_bytes;
+
     *pending = new NetToMojoPendingBuffer(std::move(*handle), buf);
   }
   return result;
diff --git a/services/tracing/public/cpp/perfetto/perfetto_config.cc b/services/tracing/public/cpp/perfetto/perfetto_config.cc
index 890ec1d..ed84fbec 100644
--- a/services/tracing/public/cpp/perfetto/perfetto_config.cc
+++ b/services/tracing/public/cpp/perfetto/perfetto_config.cc
@@ -124,8 +124,7 @@
   if (!privacy_filtering_enabled) {
 // TODO(crbug.com/1052397): Revisit once build flag switch of lacros-chrome is
 // complete.
-#if BUILDFLAG(IS_CHROMEOS_ASH) || \
-    (BUILDFLAG(IS_CHROMECAST) && BUILDFLAG(IS_LINUX))
+#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CASTOS)
     if (source_names.empty() ||
         source_names.count(tracing::mojom::kSystemTraceDataSourceName) == 1) {
       AddDataSourceConfig(
diff --git a/services/tracing/public/cpp/tracing_features.cc b/services/tracing/public/cpp/tracing_features.cc
index 7099279..50d8148f 100644
--- a/services/tracing/public/cpp/tracing_features.cc
+++ b/services/tracing/public/cpp/tracing_features.cc
@@ -23,7 +23,7 @@
 // Runs the tracing service as an in-process browser service.
 const base::Feature kTracingServiceInProcess {
   "TracingServiceInProcess",
-#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMECAST)
+#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CASTOS)
       base::FEATURE_ENABLED_BY_DEFAULT
 #else
       base::FEATURE_DISABLED_BY_DEFAULT
diff --git a/testing/buildbot/chromium.clang.json b/testing/buildbot/chromium.clang.json
index 71a1301..ebec43d 100644
--- a/testing/buildbot/chromium.clang.json
+++ b/testing/buildbot/chromium.clang.json
@@ -8959,8 +8959,8 @@
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
-        "test": "cast_runner_integration_tests_cfv1",
-        "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_integration_tests_cfv1/"
+        "test": "cast_runner_integration_tests",
+        "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_integration_tests/"
       },
       {
         "merge": {
@@ -10528,8 +10528,8 @@
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
-        "test": "cast_runner_integration_tests_cfv1",
-        "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_integration_tests_cfv1/"
+        "test": "cast_runner_integration_tests",
+        "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_integration_tests/"
       },
       {
         "merge": {
diff --git a/testing/buildbot/chromium.fuchsia.fyi.json b/testing/buildbot/chromium.fuchsia.fyi.json
index a89953d..629e15f 100644
--- a/testing/buildbot/chromium.fuchsia.fyi.json
+++ b/testing/buildbot/chromium.fuchsia.fyi.json
@@ -269,8 +269,8 @@
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
-        "test": "cast_runner_integration_tests_cfv1",
-        "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_integration_tests_cfv1/"
+        "test": "cast_runner_integration_tests",
+        "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_integration_tests/"
       },
       {
         "merge": {
@@ -1441,8 +1441,8 @@
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
-        "test": "cast_runner_integration_tests_cfv1",
-        "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_integration_tests_cfv1/"
+        "test": "cast_runner_integration_tests",
+        "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_integration_tests/"
       },
       {
         "merge": {
@@ -2755,8 +2755,8 @@
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
-        "test": "cast_runner_integration_tests_cfv1",
-        "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_integration_tests_cfv1/"
+        "test": "cast_runner_integration_tests",
+        "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_integration_tests/"
       },
       {
         "merge": {
diff --git a/testing/buildbot/chromium.fuchsia.json b/testing/buildbot/chromium.fuchsia.json
index d1bec75..2aa393c 100644
--- a/testing/buildbot/chromium.fuchsia.json
+++ b/testing/buildbot/chromium.fuchsia.json
@@ -269,8 +269,8 @@
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
-        "test": "cast_runner_integration_tests_cfv1",
-        "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_integration_tests_cfv1/"
+        "test": "cast_runner_integration_tests",
+        "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_integration_tests/"
       },
       {
         "merge": {
@@ -1452,8 +1452,8 @@
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
-        "test": "cast_runner_integration_tests_cfv1",
-        "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_integration_tests_cfv1/"
+        "test": "cast_runner_integration_tests",
+        "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_integration_tests/"
       },
       {
         "merge": {
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 4809b3e08..5604941c 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -19845,8 +19845,8 @@
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
-        "test": "cast_runner_integration_tests_cfv1",
-        "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_integration_tests_cfv1/"
+        "test": "cast_runner_integration_tests",
+        "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_integration_tests/"
       },
       {
         "args": [
@@ -21502,8 +21502,8 @@
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
-        "test": "cast_runner_integration_tests_cfv1",
-        "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_integration_tests_cfv1/"
+        "test": "cast_runner_integration_tests",
+        "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_integration_tests/"
       },
       {
         "merge": {
@@ -22968,8 +22968,8 @@
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
-        "test": "cast_runner_integration_tests_cfv1",
-        "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_integration_tests_cfv1/"
+        "test": "cast_runner_integration_tests",
+        "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_integration_tests/"
       },
       {
         "merge": {
@@ -101027,24 +101027,6 @@
         "test_id_prefix": "ninja://third_party/abseil-cpp:absl_hardening_tests/"
       },
       {
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "cpu": "x86-64",
-              "os": "Mac-10.15"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "angle_end2end_tests",
-        "test_id_prefix": "ninja://third_party/angle/src/tests:angle_end2end_tests/"
-      },
-      {
         "args": [
           "angle_unittests"
         ],
@@ -101856,7 +101838,8 @@
               "os": "Mac-10.15"
             }
           ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 4
         },
         "test": "unit_tests",
         "test_id_prefix": "ninja://chrome/test:unit_tests/"
@@ -101980,24 +101963,6 @@
         "test_id_prefix": "ninja://third_party/abseil-cpp:absl_hardening_tests/"
       },
       {
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "cpu": "x86-64",
-              "os": "Mac-10.15"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "angle_end2end_tests",
-        "test_id_prefix": "ninja://third_party/angle/src/tests:angle_end2end_tests/"
-      },
-      {
         "args": [
           "angle_unittests"
         ],
@@ -102809,7 +102774,8 @@
               "os": "Mac-10.15"
             }
           ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 4
         },
         "test": "unit_tests",
         "test_id_prefix": "ninja://chrome/test:unit_tests/"
diff --git a/testing/buildbot/filters/fuchsia.browser_tests.filter b/testing/buildbot/filters/fuchsia.browser_tests.filter
index 474f387e..5255e6dd 100644
--- a/testing/buildbot/filters/fuchsia.browser_tests.filter
+++ b/testing/buildbot/filters/fuchsia.browser_tests.filter
@@ -101,10 +101,6 @@
 # TODO(crbug.com/1326678): Dialog not focused as expected
 -ExternalProtocolDialogBrowserTest.TestFocus
 
-# TODO(crbug.com/1326682): Failed to read file to string
--I18nProcessTest.All
-
-
 # TODO(crbug.com/1326681):
 # ../../chrome/browser/infobars/infobars_browsertest.cc:215: Failure
 # Unexpected infobar hung_plugin
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl
index e1ef5c44..cfee10e6 100644
--- a/testing/buildbot/gn_isolate_map.pyl
+++ b/testing/buildbot/gn_isolate_map.pyl
@@ -334,8 +334,8 @@
     "label": "//fuchsia_web/runners:cast_runner_browsertests",
     "type": "console_test_launcher",
   },
-  "cast_runner_integration_tests_cfv1": {
-    "label": "//fuchsia_web/runners:cast_runner_integration_tests_cfv1",
+  "cast_runner_integration_tests": {
+    "label": "//fuchsia_web/runners:cast_runner_integration_tests",
     "type": "console_test_launcher",
   },
   "cast_runner_pkg":{
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl
index 131064d..6fd6ce6 100644
--- a/testing/buildbot/test_suites.pyl
+++ b/testing/buildbot/test_suites.pyl
@@ -4430,7 +4430,6 @@
       # Run popular tests other than capture_unittests, crashpad_tests,
       # content_browsertests, and perfetto_unittests because they fail.
       'absl_hardening_tests': {},
-      'angle_end2end_tests': {},
       'angle_unittests': {
         'args': [
           'angle_unittests',
@@ -4499,7 +4498,11 @@
       'storage_unittests': {},
       'ui_base_unittests': {},
       'ui_touch_selection_unittests': {},
-      'unit_tests': {},
+      'unit_tests': {
+        'swarming': {
+          'shards': 4,
+        },
+      },
       'url_unittests': {},
       'webkit_unit_tests': {
         'test': 'blink_unittests',
@@ -5135,7 +5138,7 @@
 
     'web_engine_gtests': {
       'cast_runner_browsertests': {},
-      'cast_runner_integration_tests_cfv1': {},
+      'cast_runner_integration_tests': {},
       'cast_runner_unittests': {},
       'cr_fuchsia_base_unittests': {},
       'web_engine_browsertests': {},
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 092d5ea6..9fca827 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -6010,7 +6010,7 @@
             ]
         }
     ],
-    "OptimizeNetworkBuffers": [
+    "OptimizeNetworkBuffers2": [
         {
             "platforms": [
                 "android",
@@ -6026,7 +6026,7 @@
                 {
                     "name": "Enabled",
                     "enable_features": [
-                        "OptimizeNetworkBuffers"
+                        "OptimizeNetworkBuffers2"
                     ]
                 }
             ]
diff --git a/third_party/android_swipe_refresh/README.chromium b/third_party/android_swipe_refresh/README.chromium
index 057fd8e8..1744524 100644
--- a/third_party/android_swipe_refresh/README.chromium
+++ b/third_party/android_swipe_refresh/README.chromium
@@ -28,3 +28,5 @@
   * All ViewCompat and MotionEventCompat dependencies removed.
   * Added OnResetListener interface to notify SwipeRefreshHandler to detach
     this view.
+  * Add a flag to minimze the number of z-order changes, thereby minimizing
+    relayouts of the UI.
diff --git a/third_party/android_swipe_refresh/java/src/org/chromium/third_party/android/swiperefresh/SwipeRefreshLayout.java b/third_party/android_swipe_refresh/java/src/org/chromium/third_party/android/swiperefresh/SwipeRefreshLayout.java
index abca452..09d92a7 100644
--- a/third_party/android_swipe_refresh/java/src/org/chromium/third_party/android/swiperefresh/SwipeRefreshLayout.java
+++ b/third_party/android_swipe_refresh/java/src/org/chromium/third_party/android/swiperefresh/SwipeRefreshLayout.java
@@ -136,6 +136,12 @@
 
     private boolean mNotify;
 
+    /**
+     * Flag used during duration of pull-refresh animation to reduce the number of calls to
+     * |bringToFront|, and therefore requested layouts. crbug/1335416
+     */
+    private boolean mOptimizeLayouts;
+
     private int mCircleWidth;
 
     private int mCircleHeight;
@@ -564,10 +570,11 @@
      * is currently active, the request will be ignored.
      * @return whether a new pull sequence has started.
      */
-    public boolean start() {
+    public boolean start(boolean optimizeLayouts) {
         if (!isEnabled()) return false;
         if (mRefreshing) return false;
         mCircleView.clearAnimation();
+        mOptimizeLayouts = optimizeLayouts;
         mProgress.stop();
         // See ACTION_DOWN handling in {@link #onTouchEvent(...)}.
         setTargetOffsetTopAndBottom(mOriginalOffsetTop - mCircleView.getTop(), true);
@@ -636,6 +643,12 @@
                 true /* requires update */);
     }
 
+    @Override
+    public void bringChildToFront(View child) {
+        if (mOptimizeLayouts && indexOfChild(child) == getChildCount() - 1) return;
+        super.bringChildToFront(child);
+    }
+
     /**
      * Release the active pull. If no pull has started, the release will be
      * ignored. If the pull was sufficiently large, the refresh sequence will
diff --git a/third_party/blink/common/fenced_frame/fenced_frame_utils.cc b/third_party/blink/common/fenced_frame/fenced_frame_utils.cc
index 0b2f939..1932339d 100644
--- a/third_party/blink/common/fenced_frame/fenced_frame_utils.cc
+++ b/third_party/blink/common/fenced_frame/fenced_frame_utils.cc
@@ -16,8 +16,9 @@
 bool IsValidFencedFrameURL(const GURL& url) {
   if (!url.is_valid())
     return false;
-  return url.SchemeIs(url::kHttpsScheme) || url.IsAboutBlank() ||
-         net::IsLocalhost(url);
+  return (url.SchemeIs(url::kHttpsScheme) || url.IsAboutBlank() ||
+          net::IsLocalhost(url)) &&
+         !url.parsed_for_possibly_invalid_spec().potentially_dangling_markup;
 }
 
 const char kURNUUIDprefix[] = "urn:uuid:";
diff --git a/third_party/blink/public/mojom/frame/policy_container.mojom b/third_party/blink/public/mojom/frame/policy_container.mojom
index accbeb1..e772879 100644
--- a/third_party/blink/public/mojom/frame/policy_container.mojom
+++ b/third_party/blink/public/mojom/frame/policy_container.mojom
@@ -14,6 +14,7 @@
   network.mojom.ReferrerPolicy referrer_policy =
     network.mojom.ReferrerPolicy.kDefault;
   array<network.mojom.ContentSecurityPolicy> content_security_policies;
+  bool is_anonymous = false;
 };
 
 // This interface is implemented in the browser process. It defines methods to
diff --git a/third_party/blink/public/mojom/navigation/navigation_params.mojom b/third_party/blink/public/mojom/navigation/navigation_params.mojom
index 3400ac2..a6d247ca 100644
--- a/third_party/blink/public/mojom/navigation/navigation_params.mojom
+++ b/third_party/blink/public/mojom/navigation/navigation_params.mojom
@@ -484,9 +484,6 @@
   // The time the commit was sent from the browser.
   mojo_base.mojom.TimeTicks commit_sent;
 
-  // Whether or not this navigation will commit in an anonymous frame.
-  bool anonymous = false;
-
   // When URL is about:srcdoc, this carries the srcdoc attribute's value.
   string srcdoc_value;
 
diff --git a/third_party/blink/public/platform/web_policy_container.h b/third_party/blink/public/platform/web_policy_container.h
index c8b957a..9cacdbbf 100644
--- a/third_party/blink/public/platform/web_policy_container.h
+++ b/third_party/blink/public/platform/web_policy_container.h
@@ -20,6 +20,7 @@
   network::mojom::CrossOriginEmbedderPolicyValue cross_origin_embedder_policy;
   network::mojom::ReferrerPolicy referrer_policy;
   WebVector<WebContentSecurityPolicy> content_security_policies;
+  bool is_anonymous;
 };
 
 // TODO(antoniosartori): Remove this when CommitNavigation IPC will be handled
diff --git a/third_party/blink/public/web/web_navigation_params.h b/third_party/blink/public/web/web_navigation_params.h
index f8f5c15..be6379d 100644
--- a/third_party/blink/public/web/web_navigation_params.h
+++ b/third_party/blink/public/web/web_navigation_params.h
@@ -461,9 +461,6 @@
   // reporting url. Null, otherwise.
   // https://github.com/WICG/turtledove/blob/main/Fenced_Frames_Ads_Reporting.md
   absl::optional<WebFencedFrameReporting> fenced_frame_reporting;
-
-  // Whether or not this navigation will commit in an anonymous frame.
-  bool anonymous = false;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/animation/animation_timeline.cc b/third_party/blink/renderer/core/animation/animation_timeline.cc
index fac55dc..2cf36bd 100644
--- a/third_party/blink/renderer/core/animation/animation_timeline.cc
+++ b/third_party/blink/renderer/core/animation/animation_timeline.cc
@@ -70,19 +70,6 @@
   return nullptr;
 }
 
-String AnimationTimeline::phase() {
-  switch (CurrentPhaseAndTime().phase) {
-    case TimelinePhase::kInactive:
-      return "inactive";
-    case TimelinePhase::kBefore:
-      return "before";
-    case TimelinePhase::kActive:
-      return "active";
-    case TimelinePhase::kAfter:
-      return "after";
-  }
-}
-
 void AnimationTimeline::ClearOutdatedAnimation(Animation* animation) {
   DCHECK(!animation->Outdated());
   outdated_animation_count_--;
diff --git a/third_party/blink/renderer/core/animation/animation_timeline.h b/third_party/blink/renderer/core/animation/animation_timeline.h
index 1bac1675..0153316c 100644
--- a/third_party/blink/renderer/core/animation/animation_timeline.h
+++ b/third_party/blink/renderer/core/animation/animation_timeline.h
@@ -46,7 +46,6 @@
 
   virtual V8CSSNumberish* duration();
 
-  String phase();
   TimelinePhase Phase() { return CurrentPhaseAndTime().phase; }
 
   virtual bool IsDocumentTimeline() const { return false; }
diff --git a/third_party/blink/renderer/core/animation/animation_timeline.idl b/third_party/blink/renderer/core/animation/animation_timeline.idl
index 2af171a..6ad1aa5 100644
--- a/third_party/blink/renderer/core/animation/animation_timeline.idl
+++ b/third_party/blink/renderer/core/animation/animation_timeline.idl
@@ -11,5 +11,4 @@
 ] interface AnimationTimeline {
     readonly attribute CSSNumberish? currentTime;
     [RuntimeEnabled=ScrollTimeline] readonly attribute CSSNumberish? duration;
-    [RuntimeEnabled=ScrollTimeline] readonly attribute TimelinePhase phase;
 };
diff --git a/third_party/blink/renderer/core/animation/scroll_timeline_test.cc b/third_party/blink/renderer/core/animation/scroll_timeline_test.cc
index 8bdc3d8..92360515 100644
--- a/third_party/blink/renderer/core/animation/scroll_timeline_test.cc
+++ b/third_party/blink/renderer/core/animation/scroll_timeline_test.cc
@@ -176,31 +176,26 @@
   // current time.
   SimulateFrame();
   EXPECT_EQ(scroll_timeline->CurrentTimeSeconds(), 0);
-  EXPECT_EQ("before", scroll_timeline->phase());
 
   scrollable_area->SetScrollOffset(ScrollOffset(0, 10),
                                    mojom::blink::ScrollType::kProgrammatic);
   SimulateFrame();
   EXPECT_EQ(scroll_timeline->CurrentTimeSeconds(), 0);
-  EXPECT_EQ("active", scroll_timeline->phase());
 
   scrollable_area->SetScrollOffset(ScrollOffset(0, 50),
                                    mojom::blink::ScrollType::kProgrammatic);
   SimulateFrame();
   EXPECT_EQ(scroll_timeline->CurrentTimeSeconds(), 50);
-  EXPECT_EQ("active", scroll_timeline->phase());
 
   scrollable_area->SetScrollOffset(ScrollOffset(0, 90),
                                    mojom::blink::ScrollType::kProgrammatic);
   SimulateFrame();
   EXPECT_EQ(scroll_timeline->CurrentTime(), scroll_timeline->GetDuration());
-  EXPECT_EQ("after", scroll_timeline->phase());
 
   scrollable_area->SetScrollOffset(ScrollOffset(0, 100),
                                    mojom::blink::ScrollType::kProgrammatic);
   SimulateFrame();
   EXPECT_EQ(scroll_timeline->CurrentTime(), scroll_timeline->GetDuration());
-  EXPECT_EQ("after", scroll_timeline->phase());
   EXPECT_TRUE(scroll_timeline->IsActive());
 }
 
@@ -235,71 +230,19 @@
   // current time.
   SimulateFrame();
   EXPECT_EQ(0, scroll_timeline->CurrentTimeSeconds());
-  EXPECT_EQ("before", scroll_timeline->phase());
 
   scrollable_area->SetScrollOffset(ScrollOffset(0, 60),
                                    mojom::blink::ScrollType::kProgrammatic);
   SimulateFrame();
   EXPECT_EQ(0, scroll_timeline->CurrentTimeSeconds());
-  EXPECT_EQ("before", scroll_timeline->phase());
 
   scrollable_area->SetScrollOffset(ScrollOffset(0, 100),
                                    mojom::blink::ScrollType::kProgrammatic);
   SimulateFrame();
   EXPECT_EQ(scroll_timeline->CurrentTime(), scroll_timeline->GetDuration());
-  EXPECT_EQ("after", scroll_timeline->phase());
   EXPECT_TRUE(scroll_timeline->IsActive());
 }
 
-TEST_F(ScrollTimelineTest, PhasesAreCorrectWhenUsingOffsets) {
-  SetBodyInnerHTML(R"HTML(
-    <style>
-      #scroller { overflow: scroll; width: 100px; height: 100px; }
-      #spacer { height: 1000px; }
-    </style>
-    <div id='scroller'>
-      <div id ='spacer'></div>
-    </div>
-  )HTML");
-
-  auto* scroller =
-      To<LayoutBoxModelObject>(GetLayoutObjectByElementId("scroller"));
-  ASSERT_TRUE(scroller);
-  ASSERT_TRUE(scroller->IsScrollContainer());
-  PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea();
-  ASSERT_TRUE(scrollable_area);
-  ScrollTimelineOptions* options = ScrollTimelineOptions::Create();
-  options->setSource(GetElementById("scroller"));
-  options->setScrollOffsets(
-      {OffsetFromString("10px"), OffsetFromString("90px")});
-  ScrollTimeline* scroll_timeline =
-      ScrollTimeline::Create(GetDocument(), options, ASSERT_NO_EXCEPTION);
-
-  EXPECT_EQ(scroll_timeline->phase(), "before");
-
-  scrollable_area->SetScrollOffset(ScrollOffset(0, 10),
-                                   mojom::blink::ScrollType::kProgrammatic);
-  // Simulate a new animation frame  which allows the timeline to compute new
-  // current phase and time.
-  SimulateFrame();
-  EXPECT_EQ(scroll_timeline->phase(), "active");
-
-  scrollable_area->SetScrollOffset(ScrollOffset(0, 50),
-                                   mojom::blink::ScrollType::kProgrammatic);
-  SimulateFrame();
-  EXPECT_EQ(scroll_timeline->phase(), "active");
-
-  scrollable_area->SetScrollOffset(ScrollOffset(0, 90),
-                                   mojom::blink::ScrollType::kProgrammatic);
-  SimulateFrame();
-  EXPECT_EQ(scroll_timeline->phase(), "after");
-
-  scrollable_area->SetScrollOffset(ScrollOffset(0, 100),
-                                   mojom::blink::ScrollType::kProgrammatic);
-  SimulateFrame();
-  EXPECT_EQ(scroll_timeline->phase(), "after");
-}
-
 TEST_F(ScrollTimelineTest,
        UsingDocumentScrollingElementShouldCorrectlyResolveToDocument) {
   SetBodyInnerHTML(R"HTML(
diff --git a/third_party/blink/renderer/core/frame/dom_window.cc b/third_party/blink/renderer/core/frame/dom_window.cc
index f8cffe4b..c2a2b41 100644
--- a/third_party/blink/renderer/core/frame/dom_window.cc
+++ b/third_party/blink/renderer/core/frame/dom_window.cc
@@ -770,18 +770,39 @@
   // TODO(mustaq): Explore use cases for delegating multiple capabilities.
   mojom::blink::DelegatedCapability delegated_capability =
       mojom::blink::DelegatedCapability::kNone;
-  if (LocalFrame::HasTransientUserActivation(source_frame) &&
-      options->hasDelegate()) {
+  if (options->hasDelegate()) {
     Vector<String> capability_list;
     options->delegate().Split(' ', capability_list);
     if (capability_list.Contains("payment")) {
       delegated_capability = mojom::blink::DelegatedCapability::kPaymentRequest;
-      LocalFrame::ConsumeTransientUserActivation(source_frame);
     } else if (capability_list.Contains("fullscreen")) {
       delegated_capability =
           mojom::blink::DelegatedCapability::kFullscreenRequest;
-      LocalFrame::ConsumeTransientUserActivation(source_frame);
+    } else {
+      exception_state.ThrowDOMException(
+          DOMExceptionCode::kNotSupportedError,
+          "Delegation of \'" + options->delegate() + "\' is not supported.");
+      return;
     }
+
+    // TODO(mustaq): Add checks for allowed-to-use policy as proposed here:
+    // https://wicg.github.io/capability-delegation/spec.html#monkey-patch-to-html-initiating-delegation
+
+    if (!target) {
+      exception_state.ThrowDOMException(
+          DOMExceptionCode::kNotAllowedError,
+          "Delegation to target origin '*' is not allowed.");
+      return;
+    }
+
+    if (!LocalFrame::HasTransientUserActivation(source_frame)) {
+      exception_state.ThrowDOMException(
+          DOMExceptionCode::kNotAllowedError,
+          "Delegation is not allowed without transient user activation.");
+      return;
+    }
+
+    LocalFrame::ConsumeTransientUserActivation(source_frame);
   }
 
   PostedMessage* posted_message = MakeGarbageCollected<PostedMessage>();
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc
index e335fdc..bb00559a 100644
--- a/third_party/blink/renderer/core/frame/local_dom_window.cc
+++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -179,9 +179,7 @@
       online_observer_handle_;
 };
 
-LocalDOMWindow::LocalDOMWindow(LocalFrame& frame,
-                               WindowAgent* agent,
-                               bool anonymous)
+LocalDOMWindow::LocalDOMWindow(LocalFrame& frame, WindowAgent* agent)
     : DOMWindow(frame),
       ExecutionContext(V8PerIsolateData::MainThreadIsolate(), agent),
       script_controller_(MakeGarbageCollected<ScriptController>(
@@ -201,7 +199,6 @@
       token_(frame.GetLocalFrameToken()),
       post_message_counter_(PostMessagePartition::kSameProcess),
       network_state_observer_(MakeGarbageCollected<NetworkStateObserver>(this)),
-      isAnonymouslyFramed_(anonymous),
       closewatcher_stack_(
           MakeGarbageCollected<CloseWatcher::WatcherStack>(this)) {}
 
@@ -2312,6 +2309,13 @@
   BackForwardCacheBufferLimitTracker::Get().DidBufferBytes(num_bytes);
 }
 
+bool LocalDOMWindow::isAnonymouslyFramed() const {
+  return GetExecutionContext()
+      ->GetPolicyContainer()
+      ->GetPolicies()
+      .is_anonymous;
+}
+
 bool LocalDOMWindow::IsInFencedFrame() const {
   return GetFrame() && GetFrame()->IsInFencedFrameTree();
 }
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.h b/third_party/blink/renderer/core/frame/local_dom_window.h
index fa87ef7..bf7d225 100644
--- a/third_party/blink/renderer/core/frame/local_dom_window.h
+++ b/third_party/blink/renderer/core/frame/local_dom_window.h
@@ -117,7 +117,7 @@
 
   static LocalDOMWindow* From(const ScriptState*);
 
-  LocalDOMWindow(LocalFrame&, WindowAgent*, bool anonymous);
+  LocalDOMWindow(LocalFrame&, WindowAgent*);
   ~LocalDOMWindow() override;
 
   // Returns the token identifying the frame that this ExecutionContext was
@@ -470,7 +470,7 @@
   void DidBufferLoadWhileInBackForwardCache(size_t num_bytes);
 
   // Whether the window is anonymous or not.
-  bool isAnonymouslyFramed() const { return isAnonymouslyFramed_; }
+  bool isAnonymouslyFramed() const;
 
   bool IsInFencedFrame() const override;
 
@@ -603,10 +603,6 @@
   // of the back-forward cache.
   size_t total_bytes_buffered_while_in_back_forward_cache_ = 0;
 
-  // Anonymous Iframe:
-  // https://github.com/camillelamy/explainers/blob/main/anonymous_iframes.md
-  const bool isAnonymouslyFramed_;
-
   // Collection of fenced frame APIs.
   // https://github.com/shivanigithub/fenced-frame/issues/14
   Member<Fence> fence_;
diff --git a/third_party/blink/renderer/core/frame/policy_container.cc b/third_party/blink/renderer/core/frame/policy_container.cc
index a161d1c8..40be4c9a 100644
--- a/third_party/blink/renderer/core/frame/policy_container.cc
+++ b/third_party/blink/renderer/core/frame/policy_container.cc
@@ -37,7 +37,8 @@
           container->policies.cross_origin_embedder_policy,
           container->policies.referrer_policy,
           ConvertToMojoBlink(
-              std::move(container->policies.content_security_policies)));
+              std::move(container->policies.content_security_policies)),
+          container->policies.is_anonymous);
   return std::make_unique<PolicyContainer>(std::move(container->remote),
                                            std::move(policies));
 }
diff --git a/third_party/blink/renderer/core/frame/policy_container_test.cc b/third_party/blink/renderer/core/frame/policy_container_test.cc
index 1275d667..9571fbf 100644
--- a/third_party/blink/renderer/core/frame/policy_container_test.cc
+++ b/third_party/blink/renderer/core/frame/policy_container_test.cc
@@ -17,7 +17,8 @@
   auto policies = mojom::blink::PolicyContainerPolicies::New(
       network::mojom::blink::CrossOriginEmbedderPolicyValue::kNone,
       network::mojom::blink::ReferrerPolicy::kNever,
-      Vector<network::mojom::blink::ContentSecurityPolicyPtr>());
+      Vector<network::mojom::blink::ContentSecurityPolicyPtr>(),
+      /*anonymous=*/false);
   PolicyContainer policy_container(host.BindNewEndpointAndPassDedicatedRemote(),
                                    std::move(policies));
 
@@ -30,7 +31,8 @@
   auto policies = mojom::blink::PolicyContainerPolicies::New(
       network::mojom::blink::CrossOriginEmbedderPolicyValue::kNone,
       network::mojom::blink::ReferrerPolicy::kAlways,
-      Vector<network::mojom::blink::ContentSecurityPolicyPtr>());
+      Vector<network::mojom::blink::ContentSecurityPolicyPtr>(),
+      /*anonymous=*/false);
   PolicyContainer policy_container(host.BindNewEndpointAndPassDedicatedRemote(),
                                    std::move(policies));
 
diff --git a/third_party/blink/renderer/core/frame/web_frame_test.cc b/third_party/blink/renderer/core/frame/web_frame_test.cc
index 99e2e5c..209c1fdd 100644
--- a/third_party/blink/renderer/core/frame/web_frame_test.cc
+++ b/third_party/blink/renderer/core/frame/web_frame_test.cc
@@ -996,69 +996,79 @@
   ScriptExecutionCallbackHelper callback_helper(
       web_view_helper.LocalMainFrame()->MainWorldScriptContext());
 
-  String post_message_wo_request(
-      "window.frames[0].postMessage('0', {targetOrigin: '*'});");
-  String post_message_w_payment_request(
-      "window.frames[0].postMessage("
-      "'1', {targetOrigin: '*', delegate: 'payment'});");
-  String post_message_w_fullscreen_request(
-      "window.frames[0].postMessage("
-      "'1', {targetOrigin: '*', delegate: 'fullscreen'});");
-  String post_message_w_unknown_request(
-      "window.frames[0].postMessage("
-      "'1', {targetOrigin: '*', delegate: 'foo'});");
+  {
+    String post_message_wo_request(
+        "window.frames[0].postMessage('0', {targetOrigin: '/'});");
+    String post_message_w_payment_request(
+        "window.frames[0].postMessage("
+        "'1', {targetOrigin: '/', delegate: 'payment'});");
 
-  // The delegation info is not passed through a postMessage that is sent
-  // without either user activation or the delegation option.
-  ExecuteScriptInMainWorld(web_view_helper.GetWebView()->MainFrameImpl(),
-                           post_message_wo_request, &callback_helper);
-  RunPendingTasks();
-  EXPECT_TRUE(callback_helper.DidComplete());
-  EXPECT_FALSE(message_event_listener->DelegateCapability());
+    // The delegation info is not passed through a postMessage that is sent
+    // without either user activation or the delegation option.
+    ExecuteScriptInMainWorld(web_view_helper.GetWebView()->MainFrameImpl(),
+                             post_message_wo_request, &callback_helper);
+    RunPendingTasks();
+    EXPECT_TRUE(callback_helper.DidComplete());
+    EXPECT_FALSE(message_event_listener->DelegateCapability());
 
-  // The delegation info is not passed through a postMessage that is sent
-  // without user activation but with the delegation option.
-  ExecuteScriptInMainWorld(web_view_helper.GetWebView()->MainFrameImpl(),
-                           post_message_w_payment_request, &callback_helper);
-  RunPendingTasks();
-  EXPECT_TRUE(callback_helper.DidComplete());
-  EXPECT_FALSE(message_event_listener->DelegateCapability());
+    // The delegation info is not passed through a postMessage that is sent
+    // without user activation but with the delegation option.
+    ExecuteScriptInMainWorld(web_view_helper.GetWebView()->MainFrameImpl(),
+                             post_message_w_payment_request, &callback_helper);
+    RunPendingTasks();
+    EXPECT_TRUE(callback_helper.DidComplete());
+    EXPECT_FALSE(message_event_listener->DelegateCapability());
 
-  // The delegation info is not passed through a postMessage that is sent with
-  // user activation but without the delegation option.
-  ExecuteScriptInMainWorld(web_view_helper.GetWebView()->MainFrameImpl(),
-                           post_message_wo_request, &callback_helper,
-                           /*wait_for_promise=*/true, /*user_gesture=*/true);
-  RunPendingTasks();
-  EXPECT_TRUE(callback_helper.DidComplete());
-  EXPECT_FALSE(message_event_listener->DelegateCapability());
+    // The delegation info is not passed through a postMessage that is sent with
+    // user activation but without the delegation option.
+    ExecuteScriptInMainWorld(web_view_helper.GetWebView()->MainFrameImpl(),
+                             post_message_wo_request, &callback_helper,
+                             /*wait_for_promise=*/true, /*user_gesture=*/true);
+    RunPendingTasks();
+    EXPECT_TRUE(callback_helper.DidComplete());
+    EXPECT_FALSE(message_event_listener->DelegateCapability());
 
-  // The delegation info is passed through a postMessage that is sent with both
-  // user activation and the delegation option.
-  ExecuteScriptInMainWorld(web_view_helper.GetWebView()->MainFrameImpl(),
-                           post_message_w_payment_request, &callback_helper,
-                           /*wait_for_promise=*/true, /*user_gesture=*/true);
-  RunPendingTasks();
-  EXPECT_TRUE(callback_helper.DidComplete());
-  EXPECT_TRUE(message_event_listener->DelegateCapability());
+    // The delegation info is passed through a postMessage that is sent with
+    // both user activation and the delegation option.
+    ExecuteScriptInMainWorld(web_view_helper.GetWebView()->MainFrameImpl(),
+                             post_message_w_payment_request, &callback_helper,
+                             /*wait_for_promise=*/true, /*user_gesture=*/true);
+    RunPendingTasks();
+    EXPECT_TRUE(callback_helper.DidComplete());
+    EXPECT_TRUE(message_event_listener->DelegateCapability());
+  }
 
-  // The delegation info is passed through a postMessage that is sent with both
-  // user activation and the delegation option for another known capability.
-  ExecuteScriptInMainWorld(web_view_helper.GetWebView()->MainFrameImpl(),
-                           post_message_w_fullscreen_request, &callback_helper,
-                           /*wait_for_promise=*/true, /*user_gesture=*/true);
-  RunPendingTasks();
-  EXPECT_TRUE(callback_helper.DidComplete());
-  EXPECT_TRUE(message_event_listener->DelegateCapability());
+  {
+    String post_message_w_fullscreen_request(
+        "window.frames[0].postMessage("
+        "'1', {targetOrigin: '/', delegate: 'fullscreen'});");
 
-  // The delegation info is not passed through a postMessage that is sent with
-  // user activation and the delegation option for an unknown capability.
-  ExecuteScriptInMainWorld(web_view_helper.GetWebView()->MainFrameImpl(),
-                           post_message_w_unknown_request, &callback_helper,
-                           /*wait_for_promise=*/true, /*user_gesture=*/true);
-  RunPendingTasks();
-  EXPECT_TRUE(callback_helper.DidComplete());
-  EXPECT_FALSE(message_event_listener->DelegateCapability());
+    // The delegation info is passed through a postMessage that is sent with
+    // both user activation and the delegation option for another known
+    // capability.
+    ExecuteScriptInMainWorld(web_view_helper.GetWebView()->MainFrameImpl(),
+                             post_message_w_fullscreen_request,
+                             &callback_helper,
+                             /*wait_for_promise=*/true, /*user_gesture=*/true);
+    RunPendingTasks();
+    EXPECT_TRUE(callback_helper.DidComplete());
+    EXPECT_TRUE(message_event_listener->DelegateCapability());
+  }
+
+  {
+    String post_message_w_unknown_request(
+        "window.frames[0].postMessage("
+        "'1', {targetOrigin: '/', delegate: 'foo'});");
+
+    // The delegation info is not passed through a postMessage that is sent with
+    // user activation and the delegation option for an unknown capability.
+    ExecuteScriptInMainWorld(web_view_helper.GetWebView()->MainFrameImpl(),
+                             post_message_w_unknown_request, &callback_helper,
+                             /*wait_for_promise=*/true, /*user_gesture=*/true);
+    RunPendingTasks();
+    EXPECT_TRUE(callback_helper.DidComplete());
+    EXPECT_FALSE(message_event_listener->DelegateCapability());
+  }
 }
 
 TEST_F(WebFrameTest, FormWithNullFrame) {
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 9dcc4bcc..840b54f 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
@@ -2198,6 +2198,12 @@
   // Inherit policy container from parent.
   mojom::blink::PolicyContainerPoliciesPtr policy_container_data =
       GetFrame()->DomWindow()->GetPolicyContainer()->GetPolicies().Clone();
+
+  // The initial empty document's anonymous bit is the union of:
+  // - its parent's anonymous bit.
+  // - its frame's anonymous attribute.
+  policy_container_data->is_anonymous |= owner_element->Anonymous();
+
   std::unique_ptr<PolicyContainer> policy_container =
       std::make_unique<PolicyContainer>(std::move(policy_container_remote),
                                         std::move(policy_container_data));
diff --git a/third_party/blink/renderer/core/frame/window_post_message_options.idl b/third_party/blink/renderer/core/frame/window_post_message_options.idl
index 5898dc6..ba3251c4 100644
--- a/third_party/blink/renderer/core/frame/window_post_message_options.idl
+++ b/third_party/blink/renderer/core/frame/window_post_message_options.idl
@@ -6,5 +6,5 @@
 
 dictionary WindowPostMessageOptions : PostMessageOptions {
     USVString targetOrigin = "/";
-    DOMString delegate = "";
+    DOMString? delegate;
 };
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc
index a75c5509..95a1e5e 100644
--- a/third_party/blink/renderer/core/loader/document_loader.cc
+++ b/third_party/blink/renderer/core/loader/document_loader.cc
@@ -336,7 +336,6 @@
   HashMap<KURL, EarlyHintsPreloadEntry> early_hints_preloaded_resources;
   absl::optional<Vector<KURL>> ad_auction_components;
   mojom::blink::FencedFrameReportingPtr fenced_frame_reporting;
-  bool anonymous;
   bool waiting_for_document_loader;
   bool waiting_for_code_cache;
   std::unique_ptr<ExtraData> extra_data;
@@ -438,7 +437,6 @@
           params_->is_cross_site_cross_browsing_context_group),
       navigation_api_back_entries_(params_->navigation_api_back_entries),
       navigation_api_forward_entries_(params_->navigation_api_forward_entries),
-      anonymous_(params_->anonymous),
       extra_data_(std::move(extra_data)) {
   DCHECK(frame_);
 
@@ -587,7 +585,6 @@
       CopyInitiatorOriginTrials(initiator_origin_trial_features_);
   params->force_enabled_origin_trials =
       CopyForceEnabledOriginTrials(force_enabled_origin_trials_);
-  params->anonymous = anonymous_;
   for (const auto& pair : early_hints_preloaded_resources_)
     params->early_hints_preloaded_resources.push_back(pair.key);
   if (ad_auction_components_) {
@@ -2067,13 +2064,13 @@
 
 bool ShouldReuseDOMWindow(LocalDOMWindow* window,
                           SecurityOrigin* security_origin,
-                          bool anonymous) {
+                          bool window_anonymous_matching) {
   if (!window) {
     return false;
   }
 
   // Anonymous is tracked per-Window, so if it does not match, do not reuse it.
-  if (anonymous != window->isAnonymouslyFramed()) {
+  if (!window_anonymous_matching) {
     return false;
   }
 
@@ -2127,6 +2124,12 @@
 
   bool did_have_policy_container = (policy_container_ != nullptr);
 
+  // The old window's PolicyContainer must be accessed before being potentially
+  // extracted below.
+  const bool old_window_is_anonymous =
+      frame_->DomWindow() &&
+      frame_->DomWindow()->GetPolicyContainer()->GetPolicies().is_anonymous;
+
   // DocumentLoader::InitializeWindow is called either on FrameLoader::Init or
   // on FrameLoader::CommitNavigation. FrameLoader::Init always initializes a
   // non null |policy_container_|. If |policy_container_| is null, this is
@@ -2147,6 +2150,9 @@
   // Every window must have a policy container.
   DCHECK(policy_container_);
 
+  const bool window_anonymous_matching =
+      old_window_is_anonymous == policy_container_->GetPolicies().is_anonymous;
+
   ContentSecurityPolicy* csp = CreateCSP();
 
   // Provisional frames shouldn't be doing anything other than act as a
@@ -2197,12 +2203,11 @@
   // LocalDOMWindow to the Document that results from the network load. See also
   // Document::IsSecureTransitionTo.
   if (!ShouldReuseDOMWindow(frame_->DomWindow(), security_origin.get(),
-                            anonymous_)) {
+                            window_anonymous_matching)) {
     auto* agent = GetWindowAgentForOrigin(
         frame_.Get(), security_origin.get(), origin_agent_cluster,
         origin_agent_cluster_left_as_default_);
-    frame_->SetDOMWindow(
-        MakeGarbageCollected<LocalDOMWindow>(*frame_, agent, anonymous_));
+    frame_->SetDOMWindow(MakeGarbageCollected<LocalDOMWindow>(*frame_, agent));
 
     if (origin_policy_.has_value()) {
       // Convert from WebVector<WebString> to WTF::Vector<WTF::String>
diff --git a/third_party/blink/renderer/core/loader/document_loader.h b/third_party/blink/renderer/core/loader/document_loader.h
index 5d860215..13e00cb 100644
--- a/third_party/blink/renderer/core/loader/document_loader.h
+++ b/third_party/blink/renderer/core/loader/document_loader.h
@@ -697,9 +697,6 @@
   // https://github.com/WICG/turtledove/blob/main/Fenced_Frames_Ads_Reporting.md
   mojom::blink::FencedFrameReportingPtr fenced_frame_reporting_;
 
-  // Whether the document should be anonymous or not.
-  const bool anonymous_ = false;
-
   // Both of these bits must be true to commit preloaded data to the parser when
   // features::kEarlyBodyLoad is enabled.
   bool waiting_for_document_loader_ = false;
diff --git a/third_party/blink/renderer/core/loader/frame_loader.cc b/third_party/blink/renderer/core/loader/frame_loader.cc
index 7bea677a..0f2ea24 100644
--- a/third_party/blink/renderer/core/loader/frame_loader.cc
+++ b/third_party/blink/renderer/core/loader/frame_loader.cc
@@ -257,7 +257,6 @@
   navigation_params->url = KURL(g_empty_string);
   navigation_params->frame_policy =
       frame_->Owner() ? frame_->Owner()->GetFramePolicy() : FramePolicy();
-  navigation_params->anonymous = InitialEmptyDocumentAnonymous();
 
   // An interesting edge case to consider: A document has:
   // CSP: sandbox allow-popups allow-popups-to-escape-sandbox
@@ -1158,12 +1157,6 @@
     policy_container = PolicyContainer::CreateFromWebPolicyContainer(
         std::move(navigation_params->policy_container));
   }
-  // Synchronous navigation to about:blank is not driven by the browser process
-  // and happens after committing an initial empty document. Here, we make sure
-  // it is computed the same way as it was when creating the initial empty
-  // document.
-  if (navigation_params->is_synchronous_commit_for_bug_778318)
-    navigation_params->anonymous = InitialEmptyDocumentAnonymous();
   // TODO(dgozman): get rid of provisional document loader and most of the code
   // below. We should probably call DocumentLoader::CommitNavigation directly.
   DocumentLoader* new_document_loader = MakeGarbageCollected<DocumentLoader>(
@@ -1717,40 +1710,6 @@
   }
 }
 
-bool FrameLoader::InitialEmptyDocumentAnonymous() const {
-  Frame* parent = frame_->Tree().Parent();
-  // Top-level FrameTreeNode is never anonymous.
-  if (!parent)
-    return false;
-  // Provisional frame may be created under a remote parent. The value doesn't
-  // really matter, because the provisional frame is an implementation artifact.
-  // It is not visible. This could be removed after provisional frames being
-  // cleaned up. See https://crbug.com/578349.
-  if (frame_->IsProvisional()) {
-    return true;
-  }
-  // During a navigation inside a crashed frame, the browser process may create
-  // a speculative RenderFrame. This will commit an initial empty document under
-  // a remote frame. The real navigation will commit immediately after it.
-  // See https://crbug.com/756790
-  // There are no good way to determine whether this artifact document should be
-  // considered anonymous or not. The "anonymous" flag is pushed by the browser
-  // process during navigation and there are no local/remote replication.
-  // This is used only to reflect `window.isAnonymouslyFramed`.
-  //
-  // TODO(https://crbug.com/1325733) Adding "anonymous" inside
-  // PolicyContainerPolicies would allow the browser process to push a value
-  // here. Consider doing it, if this is worth it.
-  if (!parent->IsLocalFrame()) {
-    return true;
-  }
-
-  // An document should be anonymous when its parent is anonymous. See:
-  // https://wicg.github.io/anonymous-iframe/#initial-window-anonymous
-  return parent->DomWindow()->ToLocalDOMWindow()->isAnonymouslyFramed() ||
-         frame_->Owner()->Anonymous();
-}
-
 void FrameLoader::ModifyRequestForCSP(
     ResourceRequest& resource_request,
     const FetchClientSettingsObject* fetch_client_settings_object,
diff --git a/third_party/blink/renderer/core/loader/frame_loader.h b/third_party/blink/renderer/core/loader/frame_loader.h
index 66b3645..83dc69b0 100644
--- a/third_party/blink/renderer/core/loader/frame_loader.h
+++ b/third_party/blink/renderer/core/loader/frame_loader.h
@@ -314,10 +314,6 @@
 
   String ApplyUserAgentOverrideAndLog(const String& user_agent) const;
 
-  // Return the anonymous attribute to use for the initial empty document.
-  // [spec] https://wicg.github.io/anonymous-iframe/#initial-window-anonymous
-  bool InitialEmptyDocumentAnonymous() const;
-
   Member<LocalFrame> frame_;
 
   Member<ProgressTracker> progress_tracker_;
diff --git a/third_party/blink/renderer/core/loader/frame_loader_test.cc b/third_party/blink/renderer/core/loader/frame_loader_test.cc
index cd0a5db6..1535c79c 100644
--- a/third_party/blink/renderer/core/loader/frame_loader_test.cc
+++ b/third_party/blink/renderer/core/loader/frame_loader_test.cc
@@ -166,7 +166,8 @@
   EXPECT_EQ(*mojom::blink::PolicyContainerPolicies::New(
                 network::mojom::CrossOriginEmbedderPolicyValue::kNone,
                 network::mojom::ReferrerPolicy::kAlways,
-                Vector<network::mojom::blink::ContentSecurityPolicyPtr>()),
+                Vector<network::mojom::blink::ContentSecurityPolicyPtr>(),
+                /*anonymous=*/false),
             local_frame->DomWindow()->GetPolicyContainer()->GetPolicies());
 }
 
diff --git a/third_party/blink/renderer/core/paint/box_border_painter.cc b/third_party/blink/renderer/core/paint/box_border_painter.cc
index 916128b2..4282dd7 100644
--- a/third_party/blink/renderer/core/paint/box_border_painter.cc
+++ b/third_party/blink/renderer/core/paint/box_border_painter.cc
@@ -793,8 +793,7 @@
   // When painting outlines, we ignore outer/inner radii.
   const auto force_rectangular = !outer_.IsRounded() && !inner_.IsRounded();
 
-  AutoDarkMode auto_dark_mode(
-      PaintAutoDarkMode(style_, DarkModeFilter::ElementRole::kBackground));
+  AutoDarkMode auto_dark_mode(BorderPaintAutoDarkMode(style_, color));
 
   // outer stripe
   const LayoutRectOutsets outer_third_outsets =
@@ -826,20 +825,18 @@
       FirstEdge().BorderStyle() != EBorderStyle::kDouble)
     return false;
 
+  AutoDarkMode auto_dark_mode(
+      BorderPaintAutoDarkMode(style_, FirstEdge().color));
   if (visible_edge_set_ == kAllBorderEdges) {
     if (FirstEdge().BorderStyle() == EBorderStyle::kSolid) {
       if (is_uniform_width_ && !outer_.IsRounded()) {
         // 4-side, solid, uniform-width, rectangular border => one drawRect()
-        DrawSolidBorderRect(
-            context_, outer_.Rect(), FirstEdge().Width(), FirstEdge().color,
-            PaintAutoDarkMode(style_,
-                              DarkModeFilter::ElementRole::kBackground));
+        DrawSolidBorderRect(context_, outer_.Rect(), FirstEdge().Width(),
+                            FirstEdge().color, auto_dark_mode);
       } else {
         // 4-side, solid border => one drawDRRect()
-        DrawBleedAdjustedDRRect(
-            context_, bleed_avoidance_, outer_, inner_, FirstEdge().color,
-            PaintAutoDarkMode(style_,
-                              DarkModeFilter::ElementRole::kBackground));
+        DrawBleedAdjustedDRRect(context_, bleed_avoidance_, outer_, inner_,
+                                FirstEdge().color, auto_dark_mode);
       }
     } else {
       // 4-side, double border => 2x drawDRRect()
@@ -867,9 +864,7 @@
     }
 
     context_.SetFillColor(FirstEdge().color);
-    context_.FillPath(
-        path,
-        PaintAutoDarkMode(style_, DarkModeFilter::ElementRole::kBackground));
+    context_.FillPath(path, auto_dark_mode);
     return true;
   }
 
@@ -1281,8 +1276,7 @@
         side_rect.bottom(), side, color, edge_to_render.BorderStyle(),
         miter1 != kNoMiter ? floorf(adjacent_edge1.Width()) : 0,
         miter2 != kNoMiter ? floorf(adjacent_edge2.Width()) : 0,
-        /*antialias*/ true,
-        PaintAutoDarkMode(style_, DarkModeFilter::ElementRole::kBackground));
+        /*antialias*/ true, BorderPaintAutoDarkMode(style_, color));
   }
 }
 
@@ -1334,9 +1328,8 @@
 
   context_.SetStrokeStyle(kNoStroke);
   context_.SetFillColor(color);
-  context_.DrawRect(
-      gfx::ToRoundedRect(outer_.Rect()),
-      PaintAutoDarkMode(style_, DarkModeFilter::ElementRole::kBackground));
+  context_.DrawRect(gfx::ToRoundedRect(outer_.Rect()),
+                    BorderPaintAutoDarkMode(style_, color));
 }
 
 void BoxBorderPainter::DrawDashedDottedBoxSideFromPath(
@@ -1371,10 +1364,8 @@
 
   // TODO(schenney): stroking the border path causes issues with tight corners:
   // https://bugs.chromium.org/p/chromium/issues/detail?id=344234
-  context_.StrokePath(
-      centerline_path,
-      PaintAutoDarkMode(style_, DarkModeFilter::ElementRole::kBackground),
-      centerline_path.length(), border_thickness);
+  context_.StrokePath(centerline_path, BorderPaintAutoDarkMode(style_, color),
+                      centerline_path.length(), border_thickness);
 }
 
 void BoxBorderPainter::DrawWideDottedBoxSideFromPath(
@@ -1386,10 +1377,9 @@
 
   // TODO(schenney): stroking the border path causes issues with tight corners:
   // https://bugs.webkit.org/show_bug.cgi?id=58711
-  context_.StrokePath(
-      border_path,
-      PaintAutoDarkMode(style_, DarkModeFilter::ElementRole::kBackground),
-      border_path.length(), border_thickness);
+  context_.StrokePath(border_path,
+                      BorderPaintAutoDarkMode(style_, context_.StrokeColor()),
+                      border_path.length(), border_thickness);
 }
 
 void BoxBorderPainter::DrawDoubleBoxSideFromPath(
diff --git a/third_party/blink/renderer/core/paint/collapsed_border_painter.cc b/third_party/blink/renderer/core/paint/collapsed_border_painter.cc
index 3de6cad..ee3d51a5 100644
--- a/third_party/blink/renderer/core/paint/collapsed_border_painter.cc
+++ b/third_party/blink/renderer/core/paint/collapsed_border_painter.cc
@@ -357,9 +357,6 @@
       TableCellPainter(cell_).PaintRectNotIncludingVisualOverflow(
           paint_state.PaintOffset()));
 
-  AutoDarkMode auto_dark_mode(PaintAutoDarkMode(
-      cell_.StyleRef(), DarkModeFilter::ElementRole::kBackground));
-
   // We never paint diagonals at the joins.  We simply let the border with the
   // highest precedence paint on top of borders with lower precedence.
   if (before_.value) {
@@ -369,7 +366,8 @@
         before_.outer_width + before_.inner_width);
     BoxBorderPainter::DrawBoxSide(
         context, edge_rect, BoxSide::kTop, before_.value->GetColor(),
-        CollapsedBorderStyle(before_.value->Style()), auto_dark_mode);
+        CollapsedBorderStyle(before_.value->Style()),
+        BorderPaintAutoDarkMode(cell_.StyleRef(), before_.value->GetColor()));
   }
   if (after_.value) {
     gfx::Rect edge_rect(rect.x() - after_.begin_outset,
@@ -378,7 +376,8 @@
                         after_.inner_width + after_.outer_width);
     BoxBorderPainter::DrawBoxSide(
         context, edge_rect, BoxSide::kBottom, after_.value->GetColor(),
-        CollapsedBorderStyle(after_.value->Style()), auto_dark_mode);
+        CollapsedBorderStyle(after_.value->Style()),
+        BorderPaintAutoDarkMode(cell_.StyleRef(), after_.value->GetColor()));
   }
   if (start_.value) {
     gfx::Rect edge_rect(
@@ -387,7 +386,8 @@
         rect.height() + start_.begin_outset + start_.end_outset);
     BoxBorderPainter::DrawBoxSide(
         context, edge_rect, BoxSide::kLeft, start_.value->GetColor(),
-        CollapsedBorderStyle(start_.value->Style()), auto_dark_mode);
+        CollapsedBorderStyle(start_.value->Style()),
+        BorderPaintAutoDarkMode(cell_.StyleRef(), start_.value->GetColor()));
   }
   if (end_.value) {
     gfx::Rect edge_rect(rect.right() - end_.inner_width,
@@ -396,7 +396,8 @@
                         rect.height() + end_.begin_outset + end_.end_outset);
     BoxBorderPainter::DrawBoxSide(
         context, edge_rect, BoxSide::kRight, end_.value->GetColor(),
-        CollapsedBorderStyle(end_.value->Style()), auto_dark_mode);
+        CollapsedBorderStyle(end_.value->Style()),
+        BorderPaintAutoDarkMode(cell_.StyleRef(), end_.value->GetColor()));
   }
 }
 
diff --git a/third_party/blink/renderer/core/paint/frame_set_painter.cc b/third_party/blink/renderer/core/paint/frame_set_painter.cc
index fa38f69..e753683 100644
--- a/third_party/blink/renderer/core/paint/frame_set_painter.cc
+++ b/third_party/blink/renderer/core/paint/frame_set_painter.cc
@@ -35,28 +35,30 @@
   // FIXME: We should do something clever when borders from distinct framesets
   // meet at a join.
 
-  AutoDarkMode auto_dark_mode(PaintAutoDarkMode(
-      layout_frame_set_.StyleRef(), DarkModeFilter::ElementRole::kBackground));
-
   // Fill first.
   GraphicsContext& context = paint_info.context;
-  context.FillRect(
-      border_rect,
+  Color border_color =
       layout_frame_set_.FrameSet()->HasBorderColor()
           ? layout_frame_set_.ResolveColor(GetCSSPropertyBorderLeftColor())
-          : BorderFillColor(),
-      auto_dark_mode);
+          : BorderFillColor();
+  context.FillRect(
+      border_rect, border_color,
+      BorderPaintAutoDarkMode(layout_frame_set_.StyleRef(), border_color));
 
   // Now stroke the edges but only if we have enough room to paint both edges
   // with a little bit of the fill color showing through.
   if (border_rect.width() >= 3) {
     context.FillRect(
         gfx::Rect(border_rect.origin(), gfx::Size(1, border_rect.height())),
-        BorderStartEdgeColor(), auto_dark_mode);
+        BorderStartEdgeColor(),
+        BorderPaintAutoDarkMode(layout_frame_set_.StyleRef(),
+                                BorderStartEdgeColor()));
     context.FillRect(
         gfx::Rect(gfx::Point(border_rect.right() - 1, border_rect.y()),
                   gfx::Size(1, border_rect.height())),
-        BorderEndEdgeColor(), auto_dark_mode);
+        BorderEndEdgeColor(),
+        BorderPaintAutoDarkMode(layout_frame_set_.StyleRef(),
+                                BorderEndEdgeColor()));
   }
 }
 
@@ -65,28 +67,30 @@
   // FIXME: We should do something clever when borders from distinct framesets
   // meet at a join.
 
-  AutoDarkMode auto_dark_mode(PaintAutoDarkMode(
-      layout_frame_set_.StyleRef(), DarkModeFilter::ElementRole::kBackground));
-
   // Fill first.
   GraphicsContext& context = paint_info.context;
-  context.FillRect(
-      border_rect,
+  Color border_color =
       layout_frame_set_.FrameSet()->HasBorderColor()
           ? layout_frame_set_.ResolveColor(GetCSSPropertyBorderLeftColor())
-          : BorderFillColor(),
-      auto_dark_mode);
+          : BorderFillColor();
+  context.FillRect(
+      border_rect, border_color,
+      BorderPaintAutoDarkMode(layout_frame_set_.StyleRef(), border_color));
 
   // Now stroke the edges but only if we have enough room to paint both edges
   // with a little bit of the fill color showing through.
   if (border_rect.height() >= 3) {
     context.FillRect(
         gfx::Rect(border_rect.origin(), gfx::Size(border_rect.width(), 1)),
-        BorderStartEdgeColor(), auto_dark_mode);
+        BorderStartEdgeColor(),
+        BorderPaintAutoDarkMode(layout_frame_set_.StyleRef(),
+                                BorderStartEdgeColor()));
     context.FillRect(
         gfx::Rect(gfx::Point(border_rect.x(), border_rect.bottom() - 1),
                   gfx::Size(border_rect.width(), 1)),
-        BorderEndEdgeColor(), auto_dark_mode);
+        BorderEndEdgeColor(),
+        BorderPaintAutoDarkMode(layout_frame_set_.StyleRef(),
+                                BorderEndEdgeColor()));
   }
 }
 
diff --git a/third_party/blink/renderer/core/paint/multi_column_set_painter.cc b/third_party/blink/renderer/core/paint/multi_column_set_painter.cc
index b32609c..0477e01 100644
--- a/third_party/blink/renderer/core/paint/multi_column_set_painter.cc
+++ b/third_party/blink/renderer/core/paint/multi_column_set_painter.cc
@@ -67,9 +67,7 @@
     gfx::Rect pixel_snapped_rule_rect = ToPixelSnappedRect(bound);
     BoxBorderPainter::DrawBoxSide(
         paint_info.context, pixel_snapped_rule_rect, box_side, rule_color,
-        rule_style,
-        PaintAutoDarkMode(block_style,
-                          DarkModeFilter::ElementRole::kBackground));
+        rule_style, BorderPaintAutoDarkMode(block_style, rule_color));
   }
 }
 
diff --git a/third_party/blink/renderer/core/paint/ng/ng_table_painters.cc b/third_party/blink/renderer/core/paint/ng/ng_table_painters.cc
index b5d6a6d6..641a2a7c2 100644
--- a/third_party/blink/renderer/core/paint/ng/ng_table_painters.cc
+++ b/third_party/blink/renderer/core/paint/ng/ng_table_painters.cc
@@ -523,8 +523,6 @@
     return;
   DrawingRecorder recorder(paint_info.context, layout_table, paint_info.phase,
                            visual_rect);
-  AutoDarkMode auto_dark_mode(PaintAutoDarkMode(
-      fragment_.Style(), DarkModeFilter::ElementRole::kBackground));
 
   const wtf_size_t edges_per_row = collapsed_borders->EdgesPerRow();
   const wtf_size_t total_row_count =
@@ -713,7 +711,8 @@
       }
       BoxBorderPainter::DrawBoxSide(
           paint_info.context, ToPixelSnappedRect(physical_border_rect),
-          box_side, edge.BorderColor(), edge.BorderStyle(), auto_dark_mode);
+          box_side, edge.BorderColor(), edge.BorderStyle(),
+          BorderPaintAutoDarkMode(fragment_.Style(), edge.BorderColor()));
     }
   }
 }
diff --git a/third_party/blink/renderer/core/paint/paint_auto_dark_mode.h b/third_party/blink/renderer/core/paint/paint_auto_dark_mode.h
index 9e84771c..9cc8acb 100644
--- a/third_party/blink/renderer/core/paint/paint_auto_dark_mode.h
+++ b/third_party/blink/renderer/core/paint/paint_auto_dark_mode.h
@@ -23,6 +23,15 @@
   return AutoDarkMode(role, auto_dark_mode_enabled);
 }
 
+inline AutoDarkMode BorderPaintAutoDarkMode(const ComputedStyle& style,
+                                            Color border_color) {
+  SkColor background_color =
+      style.VisitedDependentColor(GetCSSPropertyBackgroundColor()).Rgb();
+  return PaintAutoDarkMode(style,
+                           DarkModeFilter::DarkModeFilter::BorderElementRole(
+                               border_color.Rgb(), background_color));
+}
+
 class ImageClassifierHelper {
  public:
   CORE_EXPORT static ImageAutoDarkMode GetImageAutoDarkMode(
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 2eb4b07..c6b10bcf 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
@@ -1933,7 +1933,7 @@
 
   uint32_t level;
   if (HasAOMPropertyOrARIAAttribute(AOMUIntProperty::kLevel, level)) {
-    if (level >= 1 && level <= 9)
+    if (level >= 1)
       return level;
   }
 
diff --git a/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.cc b/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.cc
index e7386e45..5ea7418 100644
--- a/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.cc
+++ b/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.cc
@@ -42,22 +42,10 @@
 }
 
 #if !BUILDFLAG(IS_ANDROID)
-// Allow resolving the Promise returned by cropTo() in:
-// 1. ASAN tests, where it is known to be flaky.
-// 2. In production too, remotely, if that turns out to be necessary.
-//
-// This will likely stop being necessary once we add a separate signal
-// from the capturer to the render process, marking that all subsequent
-// frames will be cropped-to the new target, even if no additional
-// frames are produced.
-const base::Feature kCropTopPromiseWaitsForFirstFrame {
-  "CropTopPromiseWaitsForFirstFrame",
-#if defined(ADDRESS_SANITIZER)
-      base::FEATURE_DISABLED_BY_DEFAULT
-#else
-      base::FEATURE_ENABLED_BY_DEFAULT
-#endif
-};
+
+// TODO(crbug.com/1332628): Turn on by default.
+const base::Feature kCropTopPromiseWaitsForFirstFrame{
+    "CropTopPromiseWaitsForFirstFrame", base::FEATURE_DISABLED_BY_DEFAULT};
 
 // If crop_id is the empty string, returns an empty base::Token.
 // If crop_id is a valid UUID, returns a base::Token representing the ID.
diff --git a/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc b/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc
index f0144d9c..91b29dff 100644
--- a/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc
+++ b/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc
@@ -208,6 +208,16 @@
   return immutable_.image_filter;
 }
 
+DarkModeFilter::ElementRole DarkModeFilter::BorderElementRole(
+    SkColor border_color,
+    SkColor background_color) {
+  if (background_color == 0 ||
+      DarkModeColorClassifier::CalculateColorBrightness(border_color) <
+          DarkModeColorClassifier::CalculateColorBrightness(background_color))
+    return ElementRole::kForeground;
+  return ElementRole::kBackground;
+}
+
 absl::optional<cc::PaintFlags> DarkModeFilter::ApplyToFlagsIfNeeded(
     const cc::PaintFlags& flags,
     ElementRole role) {
diff --git a/third_party/blink/renderer/platform/graphics/dark_mode_filter.h b/third_party/blink/renderer/platform/graphics/dark_mode_filter.h
index c3f7111..1e5cb9f 100644
--- a/third_party/blink/renderer/platform/graphics/dark_mode_filter.h
+++ b/third_party/blink/renderer/platform/graphics/dark_mode_filter.h
@@ -34,6 +34,9 @@
   enum class ElementRole { kForeground, kListSymbol, kBackground, kSVG };
   enum class ImageType { kNone, kIcon, kSeparator, kPhoto };
 
+  static ElementRole BorderElementRole(SkColor border_color,
+                                       SkColor background_color);
+
   SkColor InvertColorIfNeeded(SkColor color, ElementRole element_role);
 
   absl::optional<cc::PaintFlags> ApplyToFlagsIfNeeded(
diff --git a/third_party/blink/renderer/platform/graphics/decoding_image_generator.cc b/third_party/blink/renderer/platform/graphics/decoding_image_generator.cc
index f149e628..d0e90ff 100644
--- a/third_party/blink/renderer/platform/graphics/decoding_image_generator.cc
+++ b/third_party/blink/renderer/platform/graphics/decoding_image_generator.cc
@@ -251,9 +251,11 @@
                                        yuva_pixmap_info);
 }
 
-bool DecodingImageGenerator::GetYUVAPlanes(const SkYUVAPixmaps& pixmaps,
-                                           size_t frame_index,
-                                           uint32_t lazy_pixel_ref) {
+bool DecodingImageGenerator::GetYUVAPlanes(
+    const SkYUVAPixmaps& pixmaps,
+    size_t frame_index,
+    uint32_t lazy_pixel_ref,
+    PaintImage::GeneratorClientId client_id) {
   // TODO(crbug.com/943519): YUV decoding does not currently support incremental
   // decoding. See comment in image_frame_generator.h.
   DCHECK(can_yuv_decode_);
@@ -285,7 +287,8 @@
   ScopedSegmentReaderDataLocker lock_data(data_.get());
   return frame_generator_->DecodeToYUV(
       data_.get(), static_cast<wtf_size_t>(frame_index),
-      pixmaps.plane(0).colorType(), plane_sizes, plane_addrs, plane_row_bytes);
+      pixmaps.plane(0).colorType(), plane_sizes, plane_addrs, plane_row_bytes,
+      client_id);
 }
 
 SkISize DecodingImageGenerator::GetSupportedDecodeSize(
diff --git a/third_party/blink/renderer/platform/graphics/decoding_image_generator.h b/third_party/blink/renderer/platform/graphics/decoding_image_generator.h
index 2950c0f..a2f52b7 100644
--- a/third_party/blink/renderer/platform/graphics/decoding_image_generator.h
+++ b/third_party/blink/renderer/platform/graphics/decoding_image_generator.h
@@ -84,7 +84,8 @@
 
   bool GetYUVAPlanes(const SkYUVAPixmaps& pixmaps,
                      size_t frame_index,
-                     uint32_t lazy_pixel_ref) override;
+                     uint32_t lazy_pixel_ref,
+                     PaintImage::GeneratorClientId client_id) override;
 
   SkISize GetSupportedDecodeSize(const SkISize& requested_size) const override;
   PaintImage::ContentId GetContentIdForFrame(size_t frame_index) const override;
diff --git a/third_party/blink/renderer/platform/graphics/image_frame_generator.cc b/third_party/blink/renderer/platform/graphics/image_frame_generator.cc
index 9d34608..6042138 100644
--- a/third_party/blink/renderer/platform/graphics/image_frame_generator.cc
+++ b/third_party/blink/renderer/platform/graphics/image_frame_generator.cc
@@ -32,6 +32,7 @@
 #include "third_party/blink/renderer/platform/graphics/image_decoder_wrapper.h"
 #include "third_party/blink/renderer/platform/graphics/image_decoding_store.h"
 #include "third_party/blink/renderer/platform/image-decoders/image_decoder.h"
+#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
 #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
 #include "third_party/skia/include/core/SkData.h"
 
@@ -112,6 +113,7 @@
     base::AutoLock lock(generator_lock_);
     if (decode_failed_)
       return false;
+    RecordWhetherMultiDecoded(client_id);
   }
 
   TRACE_EVENT1("blink", "ImageFrameGenerator::decodeAndScale", "generator",
@@ -172,10 +174,13 @@
     SkColorType color_type,
     const SkISize component_sizes[cc::kNumYUVPlanes],
     void* planes[cc::kNumYUVPlanes],
-    const wtf_size_t row_bytes[cc::kNumYUVPlanes]) {
+    const wtf_size_t row_bytes[cc::kNumYUVPlanes],
+    cc::PaintImage::GeneratorClientId client_id) {
   base::AutoLock lock(generator_lock_);
   DCHECK_EQ(index, 0u);
 
+  RecordWhetherMultiDecoded(client_id);
+
   // TODO (scroggo): The only interesting thing this uses from the
   // ImageFrameGenerator is |decode_failed_|. Move this into
   // DecodingImageGenerator, which is the only class that calls it.
@@ -237,6 +242,27 @@
   has_alpha_[index] = has_alpha;
 }
 
+void ImageFrameGenerator::RecordWhetherMultiDecoded(
+    cc::PaintImage::GeneratorClientId client_id) {
+  generator_lock_.AssertAcquired();
+
+  if (client_id == cc::PaintImage::kDefaultGeneratorClientId)
+    return;
+
+  if (last_client_id_ == cc::PaintImage::kDefaultGeneratorClientId) {
+    DCHECK(!has_logged_multi_clients_);
+    last_client_id_ = client_id;
+    UMA_HISTOGRAM_ENUMERATION(
+        "Blink.ImageDecoders.ImageHasMultipleGeneratorClientIds",
+        DecodeTimesType::kRequestByAtLeastOneClient);
+  } else if (last_client_id_ != client_id && !has_logged_multi_clients_) {
+    has_logged_multi_clients_ = true;
+    UMA_HISTOGRAM_ENUMERATION(
+        "Blink.ImageDecoders.ImageHasMultipleGeneratorClientIds",
+        DecodeTimesType::kRequestByMoreThanOneClient);
+  }
+}
+
 bool ImageFrameGenerator::HasAlpha(wtf_size_t index) {
   base::AutoLock lock(generator_lock_);
 
diff --git a/third_party/blink/renderer/platform/graphics/image_frame_generator.h b/third_party/blink/renderer/platform/graphics/image_frame_generator.h
index ca0217d..e86583a 100644
--- a/third_party/blink/renderer/platform/graphics/image_frame_generator.h
+++ b/third_party/blink/renderer/platform/graphics/image_frame_generator.h
@@ -101,7 +101,8 @@
                    SkColorType color_type,
                    const SkISize component_sizes[cc::kNumYUVPlanes],
                    void* planes[cc::kNumYUVPlanes],
-                   const wtf_size_t row_bytes[cc::kNumYUVPlanes]);
+                   const wtf_size_t row_bytes[cc::kNumYUVPlanes],
+                   cc::PaintImage::GeneratorClientId);
 
   const SkISize& GetFullSize() const { return full_size_; }
 
@@ -122,6 +123,13 @@
       SkYUVAPixmapInfo* info);
 
  private:
+  // Used in UMA histogram, please do not remove or re-order entries.
+  enum class DecodeTimesType {
+    kRequestByAtLeastOneClient = 0,
+    kRequestByMoreThanOneClient = 1,
+    kMaxValue = kRequestByMoreThanOneClient,
+  };
+
   class ClientAutoLock {
     STACK_ALLOCATED();
 
@@ -151,6 +159,10 @@
 
   void SetHasAlpha(wtf_size_t index, bool has_alpha);
 
+  // Records in UMA whether an image has been decoded by a single client or
+  // by multiple clients (determined by `GeneratorClientId`).
+  void RecordWhetherMultiDecoded(cc::PaintImage::GeneratorClientId client_id);
+
   const SkISize full_size_;
   // Parameters used to create internal ImageDecoder objects.
   const ColorBehavior decoder_color_behavior_;
@@ -178,6 +190,10 @@
       lock_map_ GUARDED_BY(generator_lock_);
 
   std::unique_ptr<ImageDecoderFactory> image_decoder_factory_;
+
+  cc::PaintImage::GeneratorClientId last_client_id_
+      GUARDED_BY(generator_lock_) = cc::PaintImage::kDefaultGeneratorClientId;
+  bool has_logged_multi_clients_ GUARDED_BY(generator_lock_) = false;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/image_frame_generator_test.cc b/third_party/blink/renderer/platform/graphics/image_frame_generator_test.cc
index f8b7580..b8ea40a 100644
--- a/third_party/blink/renderer/platform/graphics/image_frame_generator_test.cc
+++ b/third_party/blink/renderer/platform/graphics/image_frame_generator_test.cc
@@ -27,6 +27,7 @@
 
 #include <memory>
 #include "base/location.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "build/build_config.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/renderer/platform/graphics/image_decoding_store.h"
@@ -139,6 +140,45 @@
   wtf_size_t requested_clear_except_frame_;
 };
 
+// Test the UMA(ImageHasMultipleGeneratorClientIds) is recorded correctly.
+TEST_F(ImageFrameGeneratorTest, DecodeByMultipleClients) {
+  SetFrameStatus(ImageFrame::kFrameComplete);
+  base::HistogramTester histogram_tester;
+  histogram_tester.ExpectTotalCount(
+      "Blink.ImageDecoders.ImageHasMultipleGeneratorClientIds", 0);
+
+  char buffer[100 * 100 * 4];
+  cc::PaintImage::GeneratorClientId client_id_0 =
+      cc::PaintImage::GetNextGeneratorClientId();
+  generator_->DecodeAndScale(segment_reader_.get(), true, 0, ImageInfo(),
+                             buffer, 100 * 4, ImageDecoder::kAlphaPremultiplied,
+                             client_id_0);
+  histogram_tester.ExpectUniqueSample(
+      "Blink.ImageDecoders.ImageHasMultipleGeneratorClientIds",
+      0 /* kRequestByAtLeastOneClient */, 1);
+
+  generator_->DecodeAndScale(segment_reader_.get(), true, 0, ImageInfo(),
+                             buffer, 100 * 4, ImageDecoder::kAlphaPremultiplied,
+                             cc::PaintImage::kDefaultGeneratorClientId);
+  histogram_tester.ExpectUniqueSample(
+      "Blink.ImageDecoders.ImageHasMultipleGeneratorClientIds",
+      0 /* kRequestByAtLeastOneClient */, 1);
+
+  cc::PaintImage::GeneratorClientId client_id_1 =
+      cc::PaintImage::GetNextGeneratorClientId();
+  generator_->DecodeAndScale(segment_reader_.get(), true, 0, ImageInfo(),
+                             buffer, 100 * 4, ImageDecoder::kAlphaPremultiplied,
+                             client_id_1);
+  histogram_tester.ExpectTotalCount(
+      "Blink.ImageDecoders.ImageHasMultipleGeneratorClientIds", 2);
+  histogram_tester.ExpectBucketCount(
+      "Blink.ImageDecoders.ImageHasMultipleGeneratorClientIds",
+      0 /* kRequestByAtLeastOneClient */, 1);
+  histogram_tester.ExpectBucketCount(
+      "Blink.ImageDecoders.ImageHasMultipleGeneratorClientIds",
+      1 /* kRequestByMoreThanOneClient */, 1);
+}
+
 TEST_F(ImageFrameGeneratorTest, GetSupportedSizes) {
   ASSERT_TRUE(FullSize() == SkISize::Make(100, 100));
 
diff --git a/third_party/blink/tools/blinkpy/style/checker.py b/third_party/blink/tools/blinkpy/style/checker.py
index 20a313a..037f6e9c 100644
--- a/third_party/blink/tools/blinkpy/style/checker.py
+++ b/third_party/blink/tools/blinkpy/style/checker.py
@@ -42,7 +42,6 @@
 from blinkpy.style.checkers.png import PNGChecker
 from blinkpy.style.checkers.python import PythonChecker
 from blinkpy.style.checkers.text import TextChecker
-from blinkpy.style.checkers.xcodeproj import XcodeProjectFileChecker
 from blinkpy.style.checkers.xml import XMLChecker
 from blinkpy.style.error_handlers import DefaultStyleErrorHandler
 from blinkpy.style.filter import FilterConfiguration
@@ -159,8 +158,6 @@
     'y',
 ]
 
-_XCODEPROJ_FILE_EXTENSION = 'pbxproj'
-
 _XML_FILE_EXTENSIONS = [
     'vcproj',
     'vsprops',
@@ -333,7 +330,6 @@
     TEXT = 6
     # WATCHLIST = 7
     XML = 8
-    XCODEPROJ = 9
 
 
 class CheckerDispatcher(object):
@@ -385,8 +381,6 @@
             return FileType.PYTHON
         elif file_extension in _XML_FILE_EXTENSIONS:
             return FileType.XML
-        elif file_extension == _XCODEPROJ_FILE_EXTENSION:
-            return FileType.XCODEPROJ
         elif file_extension == _PNG_FILE_EXTENSION:
             return FileType.PNG
         elif (file_extension in _TEXT_FILE_EXTENSIONS):
@@ -409,8 +403,6 @@
             checker = PythonChecker(file_path, handle_style_error)
         elif file_type == FileType.XML:
             checker = XMLChecker(file_path, handle_style_error)
-        elif file_type == FileType.XCODEPROJ:
-            checker = XcodeProjectFileChecker(file_path, handle_style_error)
         elif file_type == FileType.PNG:
             checker = PNGChecker(file_path, handle_style_error)
         elif file_type == FileType.TEXT:
diff --git a/third_party/blink/tools/blinkpy/style/checkers/xcodeproj.py b/third_party/blink/tools/blinkpy/style/checkers/xcodeproj.py
deleted file mode 100644
index 879c2e73..0000000
--- a/third_party/blink/tools/blinkpy/style/checkers/xcodeproj.py
+++ /dev/null
@@ -1,57 +0,0 @@
-# Copyright (C) 2011 Google Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-# 1.  Redistributions of source code must retain the above copyright
-#     notice, this list of conditions and the following disclaimer.
-# 2.  Redistributions in binary form must reproduce the above copyright
-#     notice, this list of conditions and the following disclaimer in the
-#     documentation and/or other materials provided with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-"""Checks Xcode project files."""
-
-import re
-
-
-class XcodeProjectFileChecker(object):
-    """Processes Xcode project file lines for checking style."""
-
-    def __init__(self, file_path, handle_style_error):
-        self.file_path = file_path
-        self.handle_style_error = handle_style_error
-        self.handle_style_error.turn_off_line_filtering()
-        self._development_region_regex = re.compile(
-            'developmentRegion = (?P<region>.+);')
-
-    def _check_development_region(self, line_index, line):
-        """Returns True when developmentRegion is detected."""
-        matched = self._development_region_regex.search(line)
-        if not matched:
-            return False
-        if matched.group('region') != 'English':
-            self.handle_style_error(line_index, 'xcodeproj/settings', 5,
-                                    'developmentRegion is not English.')
-        return True
-
-    def check(self, lines):
-        development_region_is_detected = False
-        for line_index, line in enumerate(lines):
-            if self._check_development_region(line_index, line):
-                development_region_is_detected = True
-
-        if not development_region_is_detected:
-            self.handle_style_error(
-                len(lines), 'xcodeproj/settings', 5,
-                'Missing "developmentRegion = English".')
diff --git a/third_party/blink/tools/blinkpy/style/checkers/xcodeproj_unittest.py b/third_party/blink/tools/blinkpy/style/checkers/xcodeproj_unittest.py
deleted file mode 100644
index ec3b9595..0000000
--- a/third_party/blink/tools/blinkpy/style/checkers/xcodeproj_unittest.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# Copyright (C) 2011 Google Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-# 1.  Redistributions of source code must retain the above copyright
-#     notice, this list of conditions and the following disclaimer.
-# 2.  Redistributions in binary form must reproduce the above copyright
-#     notice, this list of conditions and the following disclaimer in the
-#     documentation and/or other materials provided with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-"""Unit test for xcodeproj.py."""
-
-import unittest
-
-from blinkpy.style.checkers import xcodeproj
-
-
-class TestErrorHandler(object):
-    """Error handler for XcodeProjectFileChecker unittests"""
-
-    def __init__(self, handler):
-        self.handler = handler
-
-    def turn_off_line_filtering(self):
-        pass
-
-    def __call__(self, line_number, category, confidence, message):
-        self.handler(self, line_number, category, confidence, message)
-        return True
-
-
-class XcodeProjectFileCheckerTest(unittest.TestCase):
-    """Tests XcodeProjectFileChecker class."""
-
-    def assert_no_error(self, lines):
-        def handler(error_handler, line_number, category, confidence, message):
-            self.fail('Unexpected error: %d %s %d %s' % (line_number, category,
-                                                         confidence, message))
-
-        error_handler = TestErrorHandler(handler)
-        checker = xcodeproj.XcodeProjectFileChecker('', error_handler)
-        checker.check(lines)
-
-    def assert_error(self, lines, expected_message):
-        self.had_error = False
-
-        def handler(error_handler, line_number, category, confidence, message):
-            self.assertEqual(expected_message, message)
-            self.had_error = True
-
-        error_handler = TestErrorHandler(handler)
-        checker = xcodeproj.XcodeProjectFileChecker('', error_handler)
-        checker.check(lines)
-        self.assertTrue(
-            self.had_error,
-            '%s should have error: %s.' % (lines, expected_message))
-
-    def test_detect_development_region(self):
-        self.assert_no_error(['developmentRegion = English;'])
-        self.assert_error([''], 'Missing "developmentRegion = English".')
-        self.assert_error(['developmentRegion = Japanese;'],
-                          'developmentRegion is not English.')
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 97bc295..4390f3f 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -6827,6 +6827,11 @@
 crbug.com/1285275 virtual/fenced-frame-mparch/external/wpt/html/anonymous-iframe/cache-storage.tentative.https.window.html [ Pass Timeout ]
 crbug.com/1285275 virtual/fenced-frame-shadow-dom/external/wpt/html/anonymous-iframe/cache-storage.tentative.https.window.html [ Pass Timeout ]
 crbug.com/1285275 virtual/partitioned-cookies/external/wpt/html/anonymous-iframe/cache-storage.tentative.https.window.html [ Pass Timeout ]
+#
+# The PolicyContainer's anonymous bit is unintendedly inherited toward the
+# fenced frame with the MPArch implementation. It causes:
+# Check failed: parent_ || !IsAnonymous().
+crbug.com/1287458 virtual/fenced-frame-mparch/external/wpt/html/anonymous-iframe/fenced-frame.tentative.https.window.html [ Crash ]
 
 # Sheriff 2022-03-10
 crbug.com/1304956 storage/indexeddb/dont-wedge.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/dark-mode/colors/border.html b/third_party/blink/web_tests/dark-mode/colors/border.html
new file mode 100644
index 0000000..06c9155
--- /dev/null
+++ b/third_party/blink/web_tests/dark-mode/colors/border.html
@@ -0,0 +1,45 @@
+<!doctype html>
+<!-- crbug.com/1263545: light contrast input border should still be visible -->
+<div style="width: 150px; background: #fff; border: 1px solid #dfe1e5;">light contrast border</div>
+<br>
+
+<!-- crbug.com/1263545: buttons with a visible border should still have a visible border -->
+<div style="width: 150px; background: #f8f9fa; border: 1px solid #dadce0;">light contrast border 2</div>
+<br>
+
+<!-- crbug.com/1263545: buttons with no contrast border should still have no visible border -->
+<!-- TODO(Lin) -->
+<div style="width: 150px; background: #f8f9fa; border: 1px solid #f8f9fa;">no contrast border</div>
+<br>
+
+<!-- crbug.com/1057723: tables with contrasting borders should still have contrasting borders -->
+<table>
+    <tr>
+        <td style="border: 1px solid black; background: white;">a</td>
+        <td style="border: 1px solid black; background: white;">b</td>
+    </tr>
+</table>
+<br>
+<table style="border-collapse: collapse;">
+    <tr>
+        <td style="border: 1px solid black; background: white;">c</td>
+        <td style="border: 1px solid black; background: white;">d</td>
+    </tr>
+</table>
+<br>
+
+<!-- crbug.com/1271977: svg with contrasting strokes should still have contrasting strokes -->
+<!-- TODO(Lin) -->
+<svg width="50" height="50">
+    <rect x="5" y="5" width="40" height="40" fill="white" stroke="black" stroke-width="1"></rect>
+</svg>
+<br>
+
+<!-- crbug.com/992137: heavy contrast input border should still be visible -->
+<div style="width: 150px; background: #fff; border: 1px solid black;">heavy contrast border</div>
+<br>
+
+<!-- crbug.com/992137: borders with transparent backgrounds and contrasting borders should still have contrasting borders -->
+<div style="background: white;">
+    <div style="width: 150px; background: transparent; border: 1px solid black;">border</div>
+</div>
diff --git a/third_party/blink/web_tests/external/Version b/third_party/blink/web_tests/external/Version
index 9e349789..85f1d713 100644
--- a/third_party/blink/web_tests/external/Version
+++ b/third_party/blink/web_tests/external/Version
@@ -1 +1 @@
-Version: 3f4defa10692e126bb0e4d44a419ba17ff77c74b
+Version: 644aba8746b83668d5d9033cda16ae3f8bba0b3d
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
index 1bf1280e..6ccf418 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -320538,15 +320538,23 @@
     ],
     "dedicated-worker": {
      "mediasource-message-util.js": [
-      "247071db4f13f33f99f8db4c1ca201648d51554c",
+      "c62eb8e3f7dc9ab4f00977db2e52ba98dd02d6ee",
       []
      ],
      "mediasource-worker-detach-element.js": [
-      "a4df32e532ec131593323476bd113b7e0ae1d153",
+      "10c2f84db89c2a16985e5d65c18232bfc238b0d9",
       []
      ],
      "mediasource-worker-duration.js": [
-      "80605945ee967f9135900574c8e1a7283b62fcd3",
+      "e4901345fc4da09ebf16fb6b74504a100491398d",
+      []
+     ],
+     "mediasource-worker-get-objecturl.js": [
+      "e9a5af6c81295ae4577cd2d8a4c01cfebe1a15ba",
+      []
+     ],
+     "mediasource-worker-handle.js": [
+      "577b1facbc9fcd04f6bcc3ce711504912ae5ba69",
       []
      ],
      "mediasource-worker-must-fail-if-unsupported.js": [
@@ -320554,7 +320562,7 @@
       []
      ],
      "mediasource-worker-objecturl.js": [
-      "9a7195fc5bda04e4de95ba43bd2123a79685449a",
+      "2e70d99418173d5ade9347c38e1a77ed0e44709a",
       []
      ],
      "mediasource-worker-play-terminate-worker.js": [
@@ -320562,11 +320570,11 @@
       []
      ],
      "mediasource-worker-play.js": [
-      "0312f16fd99e7ac3bbe3164df5814ebb875e3b8c",
+      "e29b1b8de6397b98f95b8241676274d06be0a633",
       []
      ],
      "mediasource-worker-util.js": [
-      "695d1179d39b18130012bcac2f0aeb34ab029547",
+      "7adaf82508d0d132423c74463b9a4e93bf59a0e1",
       []
      ]
     },
@@ -391588,7 +391596,7 @@
       ]
      },
      "before-load-001.html": [
-      "009260eea430721971053f6d98330f9a9ed56d6d",
+      "fe9fb97681260f6dec3fc0a74a94542aa8d2cf5d",
       [
        null,
        {}
@@ -422236,7 +422244,7 @@
        ]
       ],
       "request-upload.any.js": [
-       "6da2c8a38c3cbc325c23cd2cc9609f2275cd20f6",
+       "24f7c5b432caac58117dbeda5844ba5d3d99bc0e",
        [
         "fetch/api/basic/request-upload.any.html",
         {
@@ -422331,7 +422339,7 @@
        ]
       ],
       "request-upload.h2.any.js": [
-       "00b54150d6f2d9dd4e61fc8b6cc9e20489db7979",
+       "355a331c9d630cdcae3f7fb7b197f08c10c12bc5",
        [
         "fetch/api/basic/request-upload.h2.any.html",
         {
@@ -470601,6 +470609,13 @@
          {}
         ]
        ],
+       "delay-load-event-until-move-to-empty-source.html": [
+        "7b61606c4707e45553f8f5d4c112a0bd5d38f03a",
+        [
+         null,
+         {}
+        ]
+       ],
        "delay-load-event.html": [
         "ac0cf29d3fd04793ed66b7b36415ce1fecf8d764",
         [
@@ -489290,35 +489305,42 @@
     ],
     "dedicated-worker": {
      "mediasource-worker-detach-element.html": [
-      "7b00c59a07be9f2b7599ad2efcb1de22f509cd10",
+      "0f74d953723a40f5ff7087fdea4c4cc396f8ccad",
       [
        null,
        {}
       ]
      ],
      "mediasource-worker-duration.html": [
-      "2cb834a54ef6d6a36d5d1197e0e6eda50b1b98af",
+      "c195775bebb23b17971c9ff3bea6d3acd1b5b9f0",
+      [
+       null,
+       {}
+      ]
+     ],
+     "mediasource-worker-handle.html": [
+      "b084fb6d5bb9cb5b66ddc1536c2bf0719348e1ff",
       [
        null,
        {}
       ]
      ],
      "mediasource-worker-objecturl.html": [
-      "5553b5c631e8919f1159c605b4ae3fadbe11ff7c",
+      "ae6019967252e5ccda2e3e7c5e45aaab7f29e6ea",
       [
        null,
        {}
       ]
      ],
      "mediasource-worker-play-terminate-worker.html": [
-      "ca8b6970f89576a508a7b7ac5e9d6232f4d76963",
+      "d6496afd6f4b29c3866b11f5d9df5694c1f41597",
       [
        null,
        {}
       ]
      ],
      "mediasource-worker-play.html": [
-      "07317e6d0c9f0b4def138e93cabf83e7f511c5a6",
+      "0292b13d09ff6aa9fd11c626c278d658d2763e43",
       [
        null,
        {}
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transitions/before-load-001.html b/third_party/blink/web_tests/external/wpt/css/css-transitions/before-load-001.html
index 009260e..fe9fb97 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-transitions/before-load-001.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-transitions/before-load-001.html
@@ -41,6 +41,6 @@
 });
 </script>
 
-<img src="support/cat.png?pipe=trickle(d100)" id="cat">
+<img src="support/cat.png?pipe=trickle(d1)" id="cat">
 </body>
 </html>
diff --git a/third_party/blink/web_tests/external/wpt/html/capability-delegation/delegate-fullscreen-request-popup-cross-origin.https.sub.tentative.html b/third_party/blink/web_tests/external/wpt/html/capability-delegation/delegate-fullscreen-request-popup-cross-origin.https.sub.tentative.html
index 2d531a5..837fa43 100644
--- a/third_party/blink/web_tests/external/wpt/html/capability-delegation/delegate-fullscreen-request-popup-cross-origin.https.sub.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/html/capability-delegation/delegate-fullscreen-request-popup-cross-origin.https.sub.tentative.html
@@ -42,7 +42,6 @@
   });
 
   testCrossOriginPopupFullscreenDelegation(/*capability=*/"", /*activate=*/false, /*expectation=*/false);
-  testCrossOriginPopupFullscreenDelegation(/*capability=*/"fullscreen", /*activate=*/false, /*expectation=*/false);
   testCrossOriginPopupFullscreenDelegation(/*capability=*/"", /*activate=*/true, /*expectation=*/false);
   testCrossOriginPopupFullscreenDelegation(/*capability=*/"fullscreen", /*activate=*/true, /*expectation=*/true);
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/capability-delegation/delegate-fullscreen-request-popup-same-origin.https.tentative.html b/third_party/blink/web_tests/external/wpt/html/capability-delegation/delegate-fullscreen-request-popup-same-origin.https.tentative.html
index d429095..42bb870 100644
--- a/third_party/blink/web_tests/external/wpt/html/capability-delegation/delegate-fullscreen-request-popup-same-origin.https.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/html/capability-delegation/delegate-fullscreen-request-popup-same-origin.https.tentative.html
@@ -41,7 +41,6 @@
   });
 
   testSameOriginPopupFullscreenDelegation(/*capability=*/"", /*activate=*/false, /*expectation=*/false);
-  testSameOriginPopupFullscreenDelegation(/*capability=*/"fullscreen", /*activate=*/false, /*expectation=*/false);
   testSameOriginPopupFullscreenDelegation(/*capability=*/"", /*activate=*/true, /*expectation=*/false);
   testSameOriginPopupFullscreenDelegation(/*capability=*/"fullscreen", /*activate=*/true, /*expectation=*/true);
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/capability-delegation/delegate-fullscreen-request-subframe-cross-origin.https.sub.tentative.html b/third_party/blink/web_tests/external/wpt/html/capability-delegation/delegate-fullscreen-request-subframe-cross-origin.https.sub.tentative.html
index 5f2d2f61..d61f0dd8 100644
--- a/third_party/blink/web_tests/external/wpt/html/capability-delegation/delegate-fullscreen-request-subframe-cross-origin.https.sub.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/html/capability-delegation/delegate-fullscreen-request-subframe-cross-origin.https.sub.tentative.html
@@ -44,7 +44,6 @@
   });
 
   testCrossOriginSubframeFullscreenDelegation(/*capability=*/"", /*activate=*/false, /*expectation=*/false);
-  testCrossOriginSubframeFullscreenDelegation(/*capability=*/"fullscreen", /*activate=*/false, /*expectation=*/false);
   testCrossOriginSubframeFullscreenDelegation(/*capability=*/"", /*activate=*/true, /*expectation=*/false);
   testCrossOriginSubframeFullscreenDelegation(/*capability=*/"fullscreen", /*activate=*/true, /*expectation=*/true);
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/capability-delegation/delegate-fullscreen-request-subframe-same-origin.https.tentative.html b/third_party/blink/web_tests/external/wpt/html/capability-delegation/delegate-fullscreen-request-subframe-same-origin.https.tentative.html
index 9e5482d..16cbbfd3 100644
--- a/third_party/blink/web_tests/external/wpt/html/capability-delegation/delegate-fullscreen-request-subframe-same-origin.https.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/html/capability-delegation/delegate-fullscreen-request-subframe-same-origin.https.tentative.html
@@ -44,7 +44,6 @@
   });
 
   testSameOriginSubframeFullscreenDelegation(/*capability=*/"", /*activate=*/false, /*expectation=*/false);
-  testSameOriginSubframeFullscreenDelegation(/*capability=*/"fullscreen", /*activate=*/false, /*expectation=*/false);
   testSameOriginSubframeFullscreenDelegation(/*capability=*/"", /*activate=*/true, /*expectation=*/true);
   testSameOriginSubframeFullscreenDelegation(/*capability=*/"fullscreen", /*activate=*/true, /*expectation=*/true);
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/capability-delegation/delegation-consumes-activation.https.tentative.html b/third_party/blink/web_tests/external/wpt/html/capability-delegation/delegation-consumes-activation.https.tentative.html
index 1a8805d..a538f29 100644
--- a/third_party/blink/web_tests/external/wpt/html/capability-delegation/delegation-consumes-activation.https.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/html/capability-delegation/delegation-consumes-activation.https.tentative.html
@@ -17,16 +17,39 @@
   https://wicg.github.io/capability-delegation/spec.html
 </div>
 
-<iframe allow="payment" width="300px" height="50px" src="about:blank"></iframe>
+<iframe width="300px" height="50px"></iframe>
 
 <script>
+  function sendCapabilityDelegationMessageIgnoringException(origin, capability) {
+      try {
+          frames[0].postMessage("any_message", {targetOrigin: origin, delegate: capability});
+      } catch (e) {}
+  }
+
+  let capability_to_delegate;
+
+  promise_setup(async () => {
+      capability_to_delegate = await findOneCapabilitySupportingDelegation();
+      assert_true(!!capability_to_delegate, "The user agent supports delegating at least one capability");
+  });
+
   promise_test(async () => {
       assert_false(navigator.userActivation.isActive);
+
       await test_driver.bless();
-      assert_true(navigator.userActivation.isActive);
-      frames[0].postMessage({"type": "none"}, {targetOrigin: location.origin, delegate: ""});
-      assert_true(navigator.userActivation.isActive);
-      frames[0].postMessage({"type": "none"}, {targetOrigin: location.origin, delegate: "payment"});
-      assert_false(navigator.userActivation.isActive);
-  }, `capability delegation consumes transient user activation`);
+      assert_true(navigator.userActivation.isActive, "User activation is available initially");
+
+      sendCapabilityDelegationMessageIgnoringException("/", "blah");
+      assert_true(navigator.userActivation.isActive,
+                  "User activation is not consumed by delegation of an unknown delegation");
+
+      sendCapabilityDelegationMessageIgnoringException("*", capability_to_delegate);
+      assert_true(navigator.userActivation.isActive,
+                  "User activation is not consumed by known delegation to disallowed targetOrigin");
+
+      sendCapabilityDelegationMessageIgnoringException("/", capability_to_delegate);
+      assert_false(navigator.userActivation.isActive,
+                   "User activation is consumed by supported delegation");
+
+  }, "Capability delegation consumes transient user activation");
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/capability-delegation/delegation-sender-checks.tentative.html b/third_party/blink/web_tests/external/wpt/html/capability-delegation/delegation-sender-checks.tentative.html
new file mode 100644
index 0000000..4fa8a2d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/capability-delegation/delegation-sender-checks.tentative.html
@@ -0,0 +1,60 @@
+!DOCTYPE html>
+<!--
+   Tentative due to:
+     https://github.com/WICG/capability-delegation
+-->
+<title>Capability Delegation sender checks</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-actions.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script src="resources/utils.js"></script>
+
+<div>
+  Verifies that capability delegation related error checks in <a
+  href="https://wicg.github.io/capability-delegation/spec.html#monkey-patch-to-html-initiating-delegation">HTML
+  postMessage algorithm</a> are enforced correctly.
+</div>
+
+<iframe width="300px" height="50px"></iframe>
+
+<script>
+  const frame = frames[0];
+  const message = "any_message";
+  const activate = false;
+
+  let capability_to_delegate;
+
+  promise_setup(async () => {
+      capability_to_delegate = await findOneCapabilitySupportingDelegation();
+      assert_true(!!capability_to_delegate, "The user agent supports delegating at least one capability");
+  });
+
+  promise_test(async () => {
+      try {
+          await postCapabilityDelegationMessage(frame, message, "/", "blah", activate);
+          assert_unreached();
+      } catch (exception) {
+          assert_equals(exception.name, "NotSupportedError");
+      }
+  }, "Delegating an unsupported capability throws an exception");
+
+  promise_test(async () => {
+      try {
+          await postCapabilityDelegationMessage(frame, message, "*", capability_to_delegate, activate);
+          assert_unreached();
+      } catch (exception) {
+          assert_equals(exception.name, "NotAllowedError");
+      }
+  }, "Delegating to targetOrigin='*' throws an exception");
+
+  promise_test(async () => {
+      try {
+          await postCapabilityDelegationMessage(frame, message, "/", capability_to_delegate, activate);
+          assert_unreached();
+      } catch (exception) {
+          assert_equals(exception.name, "NotAllowedError");
+      }
+  }, "Delegating without user activation throws an exception");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/capability-delegation/resources/utils.js b/third_party/blink/web_tests/external/wpt/html/capability-delegation/resources/utils.js
index 3add3eb6..37c0226 100644
--- a/third_party/blink/web_tests/external/wpt/html/capability-delegation/resources/utils.js
+++ b/third_party/blink/web_tests/external/wpt/html/capability-delegation/resources/utils.js
@@ -14,11 +14,42 @@
 
 // A helper that simulates user activation on the current frame if `activate` is true, then posts
 // `message` to `frame` with the target `origin` and specified `capability` to delegate. This helper
-// awaits and returns the result message sent in reply from `frame`.
+// awaits and returns a Promise fulfilled with the result message sent in reply from `frame`.
+// However, if the `postMessage` call fails, the helper returns a Promise rejected with the
+// exception.
 async function postCapabilityDelegationMessage(frame, message, origin, capability, activate) {
     let result_promise = getMessageData("result", frame);
+
     if (activate)
         await test_driver.bless();
-    frame.postMessage(message, {targetOrigin: origin, delegate: capability});
+
+    let postMessageOptions = {targetOrigin: origin};
+    if (capability)
+        postMessageOptions["delegate"] = capability;
+    try {
+        frame.postMessage(message, postMessageOptions);
+    } catch (exception) {
+        return Promise.reject(exception);
+    }
+
     return await result_promise;
 }
+
+// Returns the name of a capability for which `postMessage` delegation is supported by the user
+// agent, or undefined if no such capability is found.
+async function findOneCapabilitySupportingDelegation() {
+  const capabilities = ["fullscreen", "payment"];
+
+  for (let i = 0; i < capabilities.length; i++) {
+    try {
+      await postCapabilityDelegationMessage(window, "any_message", "/", capabilities[i], false);
+      assert_unreached();
+    } catch (exception) {
+      if (exception.name != "NotSupportedError")
+          return capabilities[i];
+      // Ignore all other exceptions to continue searching through the list.
+    }
+  };
+
+  return undefined;
+}
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/delay-load-event-until-move-to-empty-source.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/delay-load-event-until-move-to-empty-source.html
new file mode 100644
index 0000000..7b61606
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/delay-load-event-until-move-to-empty-source.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Inline image element blocks load until source is changed to empty source</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<img src="/images/blue.png?pipe=trickle(d100)">
+<script>
+
+async_test(t => {
+  const image = document.querySelector("img");
+
+  assert_false(image.complete, "The image is loading initially");
+
+  // Complete the test as soon as we obtained the window "load" event,
+  // which should happen as soon as the image stops loading by moving
+  // to an empty source.
+  window.addEventListener("load", t.step_func_done(() => {
+      assert_true(image.complete, "The image is no longer loading once the window 'load' event is dispatched");
+  }));
+
+  // Stop loading the image.
+  image.src = "";
+}, "Image element delays window's load event until the image changes to empty source");
+
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-form-element/form-autocomplete.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-form-element/form-autocomplete.html
index ec79bac..fcd93ce2 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-form-element/form-autocomplete.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-form-element/form-autocomplete.html
@@ -47,7 +47,7 @@
   autocompletetest(document.forms.autocomplete_off, ["off", "", "on", "off", ""], "form autocomplete attribute off");
   autocompletetest(document.forms.autocomplete_invalid, ["on", "", "on", "off", ""], "form autocomplete attribute invalid");
 
-  var keywords = [ "on", "off", "name", "honorific-prefix", "given-name", "additional-name", "family-name", "honorific-suffix", "nickname", "username", "new-password", "current-password", "one-time-code", "organization-title", "organization", "street-address", "address-line1", "address-line2", "address-line3", "address-level4", "address-level3", "address-level2", "address-level1", "country", "country-name", "postal-code", "cc-name", "cc-given-name", "cc-additional-name", "cc-family-name", "cc-number", "cc-exp", "cc-exp-month", "cc-exp-year", "cc-csc", "cc-type", "transaction-currency", "transaction-amount", "language", "bday", "bday-day", "bday-month", "bday-year", "sex", "url", "photo", "tel", "tel-country-code", "tel-national", "tel-area-code", "tel-local", "tel-local-prefix", "tel-local-suffix", "tel-extension", "email", "impp" ];
+  var keywords = [ "on", "off", "name", "honorific-prefix", "given-name", "additional-name", "family-name", "honorific-suffix", "nickname", "username", "new-password", "current-password", "one-time-code", "organization-title", "organization", "street-address", "address-line1", "address-line2", "address-line3", "address-level4", "address-level3", "address-level2", "address-level1", "country", "country-name", "postal-code", "cc-name", "cc-given-name", "cc-additional-name", "cc-family-name", "cc-number", "cc-exp", "cc-exp-month", "cc-exp-year", "cc-csc", "cc-type", "transaction-currency", "transaction-amount", "language", "bday", "bday-day", "bday-month", "bday-year", "sex", "url", "photo", "tel", "tel-country-code", "tel-national", "tel-area-code", "tel-local", "tel-local-prefix", "tel-local-suffix", "tel-extension", "email", "impp", "webauthn" ];
 
   keywords.forEach(function(keyword) {
     test(function(){
@@ -77,7 +77,11 @@
   assert_equals(select.autocomplete, "");
 
   // Contact category; max=4
-  select.setAttribute("autocomplete", "foo section-bar billing work name");
+  select.setAttribute("autocomplete", "foo section-bar billing work tel");
+  assert_equals(select.autocomplete, "");
+
+  // Credential category; max=5
+  select.setAttribute("autocomplete", "foo section-bar billing work tel webauthn");
   assert_equals(select.autocomplete, "");
 }, "Test maximum number of tokens");
 
@@ -113,4 +117,14 @@
   assert_equals(textarea.autocomplete, "section-foo bday");
 }, "Serialize combinations of section, mode, contact, and field");
 
+test(() => {
+  const textarea = document.createElement("textarea");
+
+  textarea.setAttribute("autocomplete", "\tusername webauthn");
+  assert_equals(textarea.autocomplete, "username webauthn");
+
+  textarea.setAttribute("autocomplete", "  section-LOGIN  shipping work tel webauthn ");
+  assert_equals(textarea.autocomplete, "section-login shipping work tel webauthn");
+}, "Serialize combinations of section, mode, contact, field, and credential");
+
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-responsiveness-from-endpoint.html b/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-responsiveness-from-endpoint.html
index 3eafe2f..883f94b 100644
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-responsiveness-from-endpoint.html
+++ b/third_party/blink/web_tests/external/wpt/scroll-animations/css/at-scroll-timeline-responsiveness-from-endpoint.html
@@ -6,6 +6,8 @@
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/css/css-animations/support/testcommon.js"></script>
+<script src="/scroll-animations/scroll-timelines/testcommon.js"></script>
+
 <style>
   @keyframes anim {
     from { width: 100px; }
@@ -15,7 +17,6 @@
   @scroll-timeline timeline {
     source: auto;
     orientation: auto;
-    scroll-offsets: none;
   }
 
   .fill-vh {
@@ -28,21 +29,32 @@
 <script>
 'use strict';
 
-test(t => {
+promise_test(async t => {
   const div = addDiv(t, { style: 'width: 50px; height: 100px;' });
   const filling = addDiv(t, { class: 'fill-vh' });
   const scroller = document.scrollingElement;
-  getComputedStyle(document.scrollingElement).height;
+  scroller.scrollTop = 0;
+  await waitForNextFrame();
 
   div.style.animation = 'anim 100s linear timeline';
-  assert_equals(getComputedStyle(div).width, '100px');
+  const anim = div.getAnimations()[0];
+  await anim.ready;
+  assert_percents_equal(anim.timeline.currentTime, 0,
+                        'Timeline time when animation is ready');
+  assert_equals(getComputedStyle(div).width, '100px',
+                'Width at animation start');
 
+  await waitForNextFrame();
   const maxScroll = scroller.scrollHeight - scroller.clientHeight;
   scroller.scrollTop = maxScroll;
-  assert_equals(getComputedStyle(div).width, '200px');
+  await waitForNextFrame();
+  assert_equals(getComputedStyle(div).width, '200px',
+                'Width at scroll limit');
 
   document.scrollingElement.scrollTop = 0;
-  assert_equals(getComputedStyle(div).width, '100px');
+  await waitForNextFrame();
+  assert_equals(getComputedStyle(div).width, '100px',
+                'Width after reset to scroll top');
 }, 'Test that the scroll animation is still responsive after moving from 100%');
 
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/scroll-timelines/current-time.html b/third_party/blink/web_tests/external/wpt/scroll-animations/scroll-timelines/current-time.html
index be564cfc..f011b40c1 100644
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/scroll-timelines/current-time.html
+++ b/third_party/blink/web_tests/external/wpt/scroll-animations/scroll-timelines/current-time.html
@@ -110,16 +110,10 @@
   // current offset (0) will be less than the startScrollOffset.
   assert_percents_equal(lengthScrollTimeline.currentTime, 0,
                         'Unscrolled length-based timeline current time');
-  assert_equals(lengthScrollTimeline.phase, "before",
-                'Unscrolled length-based timeline phase');
   assert_percents_equal(percentageScrollTimeline.currentTime, 0,
                         'Unscrolled percentage-based timeline current time');
-  assert_equals(percentageScrollTimeline.phase, "before",
-                'Unscrolled percentage-based timeline phase');
   assert_percents_equal(calcScrollTimeline.currentTime, 0,
                         'Unscrolled calc-based timeline current time');
-  assert_equals(calcScrollTimeline.phase, "before",
-                'Unscrolled calc-based timeline phase');
 
   // Check the length-based ScrollTimeline.
   scroller.scrollTop = 19;
@@ -128,22 +122,16 @@
   await waitForNextFrame();
   assert_percents_equal(lengthScrollTimeline.currentTime, 0,
       'Length-based timeline current time before the startScrollOffset point');
-  assert_equals(lengthScrollTimeline.phase, "before",
-      'Length-based timeline phase before the startScrollOffset point');
   scroller.scrollTop = 20;
   await waitForNextFrame();
   assert_percents_equal(lengthScrollTimeline.currentTime, 0,
       'Length-based timeline current time at the startScrollOffset point');
-  assert_equals(lengthScrollTimeline.phase, "active",
-      'Length-based timeline phase at the startScrollOffset point');
   scroller.scrollTop = 50;
   await waitForNextFrame();
   assert_percents_equal(
       lengthScrollTimeline.currentTime,
       calculateCurrentTime(50, 20, scrollerSize),
       'Length-based timeline current time after the startScrollOffset point');
-  assert_equals(lengthScrollTimeline.phase, "active",
-      'Length-based timeline phase after the startScrollOffset point');
 
   // Check the percentage-based ScrollTimeline.
   scroller.scrollTop = 0.19 * scrollerSize;
@@ -151,14 +139,10 @@
   assert_percents_equal(percentageScrollTimeline.currentTime, 0,
       'Percentage-based timeline current time before the startScrollOffset ' +
       'point');
-  assert_equals(percentageScrollTimeline.phase, "before",
-      'Percentage-based timeline phase before the startScrollOffset point');
   scroller.scrollTop = 0.20 * scrollerSize;
   await waitForNextFrame();
   assert_percents_equal(percentageScrollTimeline.currentTime, 0,
       'Percentage-based timeline current time at the startScrollOffset point');
-  assert_equals(percentageScrollTimeline.phase, "active",
-      'Percentage-based timeline phase at the startScrollOffset point');
   scroller.scrollTop = 0.50 * scrollerSize;
   await waitForNextFrame();
   assert_percents_equal(
@@ -167,22 +151,16 @@
           scroller.scrollTop, 0.2 * scrollerSize, scrollerSize),
       'Percentage-based timeline current time after the startScrollOffset ' +
       'point');
-  assert_equals(percentageScrollTimeline.phase, "active",
-      'Percentage-based timeline phase after the startScrollOffset point');
 
   // Check the calc-based ScrollTimeline.
   scroller.scrollTop = 0.2 * scrollerSize - 10;
   await waitForNextFrame();
   assert_percents_equal(calcScrollTimeline.currentTime, 0,
       'Calc-based timeline current time before the startScrollOffset point');
-  assert_equals(calcScrollTimeline.phase, "before",
-      'Calc-based timeline phase at the startScrollOffset point');
   scroller.scrollTop = 0.2 * scrollerSize - 5;
   await waitForNextFrame();
   assert_percents_equal(calcScrollTimeline.currentTime, 0,
       'Calc-based timeline current time at the startScrollOffset point');
-  assert_equals(calcScrollTimeline.phase, "active",
-      'Calc-based timeline phase at the startScrollOffset point');
   scroller.scrollTop = 0.2 * scrollerSize;
   await waitForNextFrame();
   assert_percents_equal(
@@ -190,8 +168,6 @@
       calculateCurrentTime(
           scroller.scrollTop, 0.2 * scrollerSize - 5, scrollerSize),
       'Calc-based timeline current time after the startScrollOffset point');
-  assert_equals(calcScrollTimeline.phase, "active",
-      'Calc-based timeline phase at the startScrollOffset point');
 }, 'currentTime handles startScrollOffset correctly');
 
 promise_test(async t => {
@@ -269,36 +245,26 @@
   await waitForNextFrame();
   assert_percents_equal(lengthScrollTimeline.currentTime, 100,
       'Length-based timeline current time after the endScrollOffset point');
-  assert_equals(lengthScrollTimeline.phase, "after",
-      'Length-based timeline phase after the endScrollOffset point');
   scroller.scrollTop = scrollerSize - 20;
   await waitForNextFrame();
   assert_percents_equal(lengthScrollTimeline.currentTime, 100,
       'Length-based timeline current time at the endScrollOffset point');
-  assert_equals(lengthScrollTimeline.phase, "after",
-      'Length-based timeline phase at the endScrollOffset point');
   scroller.scrollTop = scrollerSize - 50;
   await waitForNextFrame();
   assert_percents_equal(
       lengthScrollTimeline.currentTime,
       calculateCurrentTime(scrollerSize - 50, 0, scrollerSize - 20),
       'Length-based timeline current time before the endScrollOffset point');
-  assert_equals(lengthScrollTimeline.phase, "active",
-      'Length-based timeline phase before the endScrollOffset point');
 
   // Check the percentage-based ScrollTimeline.
   scroller.scrollTop = 0.81 * scrollerSize;
   await waitForNextFrame();
   assert_percents_equal(percentageScrollTimeline.currentTime, 100,
       'Percentage-based timeline current time after the endScrollOffset point');
-  assert_equals(percentageScrollTimeline.phase, "after",
-      'Percentage-based timeline phase after the endScrollOffset point');
   scroller.scrollTop = 0.80 * scrollerSize;
   await waitForNextFrame();
   assert_percents_equal(percentageScrollTimeline.currentTime, 100,
       'Percentage-based timeline current time at the endScrollOffset point');
-  assert_equals(percentageScrollTimeline.phase, "after",
-      'Percentage-based timeline phase at the endScrollOffset point');
   scroller.scrollTop = 0.50 * scrollerSize;
   await waitForNextFrame();
   assert_percents_equal(
@@ -306,30 +272,22 @@
       calculateCurrentTime(scroller.scrollTop, 0, 0.8 * scrollerSize),
       'Percentage-based timeline current time before the endScrollOffset ' +
       'point');
-  assert_equals(percentageScrollTimeline.phase, "active",
-      'Percentage-based timeline phase before the endScrollOffset point');
 
   // Check the calc-based ScrollTimeline.
   scroller.scrollTop = 0.8 * scrollerSize + 6;
   await waitForNextFrame();
   assert_percents_equal(calcScrollTimeline.currentTime, 100,
       'Calc-based timeline current time after the endScrollOffset point');
-  assert_equals(calcScrollTimeline.phase, "after",
-      'Calc-based timeline phase after the endScrollOffset point');
   scroller.scrollTop = 0.8 * scrollerSize + 5;
   await waitForNextFrame();
   assert_percents_equal(calcScrollTimeline.currentTime, 100,
       'Calc-based timeline current time at the endScrollOffset point');
-  assert_equals(calcScrollTimeline.phase, "after",
-      'Calc-based timeline phase at the endScrollOffset point');
   scroller.scrollTop = 0.5 * scrollerSize;
   await waitForNextFrame();
   assert_percents_equal(
       calcScrollTimeline.currentTime,
       calculateCurrentTime(scroller.scrollTop, 0, 0.8 * scrollerSize + 5),
       'Calc-based timeline current time before the endScrollOffset point');
-  assert_equals(calcScrollTimeline.phase, "active",
-      'Calc-based timeline phase before the endScrollOffset point');
 }, 'currentTime handles endScrollOffset correctly');
 
 promise_test(async t => {
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/scroll-timelines/scroll-animation-effect-phases.tentative.html b/third_party/blink/web_tests/external/wpt/scroll-animations/scroll-timelines/scroll-animation-effect-phases.tentative.html
index dfd3868e..5ded56b 100644
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/scroll-timelines/scroll-animation-effect-phases.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/scroll-animations/scroll-timelines/scroll-animation-effect-phases.tentative.html
@@ -21,130 +21,130 @@
 <div id="log"></div>
 <script>
   'use strict';
-  // Test cases are included where effect delay causes the effect iteration to
-  // overlap with the timeline start time and also the timeline end time.
-  //                  Timeline
-  //   BEFORE   +-----------------+     AFTER
-  //   time:    0                 timeline.duration
-  //   1)       +-----------------+
-  //   2)            +------------+
-  //   3)   +---------------------+
-  //   4)       +---------------------+
-  //   5)       +-------------+
-  //   6)           +---------+
-  //   7)           +-----------------+
-  //   8)   +-----------------+
-  //   9)   +-------------------------+
-
-  // Note: effects are scaled to fill the timeline so that the start of the
-  // effect is after the start offset of the timeline, and that the end of the
-  // effect is at the beginning of the end offset of the timeline.
+ // Note: effects are scaled to fill the timeline.
 
   // Each entry is [[test input], [test expectations]]
   // test input = ["description", delay, end_delay, scroll percent]
   // test expectations = [timeline time, animation current time,
-  //                      effect local time, effect progress, effect phase]
+  //                      effect local time, effect progress, effect phase,
+  //                      opacity]
 
   /* All interesting transitions:
-      before timeline start
       at timeline start
       before effect delay
       at effect start
-      in timeline range
+      in active range
       at effect end
-      after effect endDelay
+      after effect end
       at timeline end
-      after timeline end
   */
   const test_cases = [
-    // Case 1: No delays. Effect starts at the same time as the timeline.
-    [["before timeline start", 0, 0, 0.10], [0, 0, 0, null, "before"]],
-    [["at timeline start",     0, 0, 0.25], [0, 0, 0, 0, "active"]],
-    [["in timeline range",     0, 0, 0.50], [50, 50, 50, 0.5, "active"]],
-    [["at timeline end",       0, 0, 0.75], [100, 100, 100, null, "after"]],
-    [["after timeline end",    0, 0, 0.90], [100, 100, 100, null, "after"]],
+    // Case 1: No delays.
+    // Boundary at end of active phase is inclusive.
+    [
+      ["at start", 0, 0, 0],
+      [0, 0, 0, 0, "active", 0.3]
+    ],
+    [
+      ["in active range", 0, 0, 0.50],
+      [50, 50, 50, 0.5, "active", 0.5]
+    ],
+    [
+      ["at effect end time", 0, 0, 1.0],
+      [100, 100, 100, 1.0, "active", 0.7]
+    ],
 
-    // Case 2: Positive delay, no endDelay.
-    // effect start = 100% * start / (start + duration + end)
-    //              = 100% * 500 / (500 + 500 + 0) = 50%
-    [["before timeline start", 500, 0, 0.10], [0, 0, 0, null, "before"]],
-    [["at timeline start",     500, 0, 0.25], [0, 0, 0, null, "before"]],
-    [["before effect delay",   500, 0, 0.30], [10, 10, 10, null, "before"]],
-    [["at effect start",       500, 0, 0.50], [50, 50, 50, 0, "active"]],
-    [["in timeline range",     500, 0, 0.65], [80, 80, 80, 0.6, "active"]],
-    [["at timeline end",       500, 0, 0.75], [100, 100, 100, null, "after"]],
-    [["after timeline end",    500, 0, 0.90], [100, 100, 100, null, "after"]],
+    // Case 2: Positive start delay and no end delay.
+    // Boundary at end of active phase is inclusive.
+    [
+      ["at timeline start", 500, 0, 0],
+      [0, 0, 0, null, "before", 1]
+    ],
+    [
+      ["before start delay", 500, 0, 0.25],
+      [25, 25, 25, null, "before", 1]
+    ],
+    [
+      ["at start delay", 500, 0, 0.5],
+      [50, 50, 50, 0, "active", 0.3]
+    ],
+    [
+      ["in active range", 500, 0, 0.75],
+      [75, 75, 75, 0.5, "active", 0.5]
+    ],
+    [
+      ["at effect end time", 500, 0, 1.0],
+      [100, 100, 100, 1.0, "active", 0.7]
+    ],
 
-    // Case 3: Negative delay, no endDelay.
-    [["before timeline start", -250, 0, 0.10], [0, 0, 0, null, "before"]],
-    [["at timeline start",     -250, 0, 0.25], [0, 0, 0, 0.5, "active"]],
-    [["in timeline range",     -250, 0, 0.50], [50, 50, 50, 0.75, "active"]],
-    [["at timeline end",       -250, 0, 0.75], [100, 100, 100, null, "after"]],
-    [["after timeline end",    -250, 0, 0.90], [100, 100, 100, null,  "after"]],
+    // case 3: No start delay, Positive end delay.
+    // Boundary at end of active phase is exclusive.
+    [
+      ["at timeline start", 0, 500, 0],
+      [0, 0, 0, 0, "active", 0.3]
+    ],
+    [
+      ["in active range", 0, 500, 0.25],
+      [25, 25, 25, 0.5, "active", 0.5]
+    ],
+    [
+      ["at effect end time", 0, 500, 0.5],
+      [50, 50, 50, null, "after", 1.0]
+    ],
+    [
+      ["after effect end time", 0, 500, 0.75],
+      [75, 75, 75, null, "after", 1.0]
+    ],
+    [
+      ["at timeline boundary", 0, 500, 1.0],
+      [100, 100, 100, null, "after", 1.0]
+    ],
 
-    // Case 4: No delay, negative endDelay. Effect will never progress to 100%
-    [["before timeline start", 0, -250, 0.10], [0, 0, 0, null, "before"]],
-    [["at timeline start",     0, -250, 0.25], [0, 0, 0, 0, "active"]],
-    [["in timeline range",     0, -250, 0.50], [50, 50, 50, 0.25, "active"]],
-    [["at timeline end",       0, -250, 0.75], [100, 100, 100, null, "after"]],
-    [["after timeline end",    0, -250, 0.90], [100, 100, 100, null, "after"]],
+    // case 4: Positive start and end delays.
+    // Boundary at end of active phase is exclusive.
+    [
+      ["at timeline start", 250, 250, 0],
+      [0, 0, 0, null, "before", 1]
+    ],
+    [
+      ["before start delay", 250, 250, 0.1],
+      [10, 10, 10, null, "before", 1]
+    ],
+    [
+      ["at start delay", 250, 250, 0.25],
+      [25, 25, 25, 0, "active", 0.3]
+    ],
+    [
+      ["in active range", 250, 250, 0.5],
+      [50, 50, 50, 0.5, "active", 0.5]
+    ],
+    [
+      ["at effect end time", 250, 250, 0.75],
+      [75, 75, 75, null, "after", 1.0]
+    ],
+    [
+      ["after effect end time", 250, 250, 0.9],
+      [90, 90, 90, null, "after", 1.0]
+    ],
+    [
+      ["at timeline boundary", 250, 250, 1.0],
+      [100, 100, 100, null, "after", 1.0]
+    ],
 
-    // Case 5: No delay, positive endDelay.
-    // effect end = 100% * (start + duration) / (start + duration + end)
-    //            = 100% * (0 + 500) / (0 + 500 + 500) = 50%
-    [["before timeline start", 0, 500, 0.10], [0, 0, 0, null, "before"]],
-    [["at timeline start",     0, 500, 0.25], [0, 0, 0, 0, "active"]],
-    [["in timeline range",     0, 500, 0.40], [30, 30, 30, 0.6, "active"]],
-    [["at effect end",         0, 500, 0.50], [50, 50, 50, null, "after"]],
-    [["after effect endDelay", 0, 500, 0.60], [70, 70, 70, null, "after"]],
-    [["at timeline end",       0, 500, 0.75], [100, 100, 100, null,"after"]],
-    [["after timeline end",    0, 500, 0.90], [100, 100, 100, null, "after"]],
-
-    // Case 6: Positive delay, positive endDelay.
-    // Delays chosen to make timeline an integer percentage at the effect start
-    // and end boundaries.
-    // effect start = 100% * start / (start + duration + end)
-    //              = 100% * 375 / (375 + 500 + 375) = 30%
-    // effect end = 100% * (start + duration) / (start + duration + end)
-    //            = 100% * (375 + 500) / (375 + 500 + 375) = 70%
-    [["before timeline start", 375, 375, 0.10], [0, 0, 0, null, "before"]],
-    [["at timeline start",     375, 375, 0.25], [0, 0, 0, null, "before"]],
-    [["before effect delay",   375, 375, 0.27], [4, 4, 4, null, "before"]],
-    [["at effect start",       375, 375, 0.40], [30, 30, 30, 0, "active"]],
-    [["in timeline range",     375, 375, 0.50], [50, 50, 50, 0.5,  "active"]],
-    [["at effect end",         375, 375, 0.60], [70, 70, 70, null, "after"]],
-    [["after effect endDelay", 375, 375, 0.70], [90, 90, 90, null, "after"]],
-    [["at timeline end",       375, 375, 0.75], [100, 100, 100, null, "after"]],
-    [["after timeline end",    375, 375, 0.90], [100, 100, 100, null, "after"]],
-
-    // Case 7: Positive delay, negative endDelay.
-    // effect start = 100% * start / (start + duration + end)
-    //              = 100% * 600 / (600 + 500 - 100) = 60%
-    [["before timeline start", 600, -100, 0.10], [0, 0, 0, null, "before"]],
-    [["at timeline start",     600, -100, 0.25], [0, 0, 0, null, "before"]],
-    [["before effect delay",   600, -100, 0.40], [30, 30, 30, null, "before"]],
-    [["at effect start",       600, -100, 0.55], [60, 60, 60, 0, "active"]],
-    [["in timeline range",     600, -100, 0.70], [90, 90, 90, 0.6, "active"]],
-    [["at timeline end",       600, -100, 0.75], [100, 100, 100, null, "after"]],
-    [["after timeline end",    600, -100, 0.90], [100, 100, 100, null, "after"]],
-
-    // Case 8: Negative delay, positive endDelay.
-    // effect end = 100% * (start + duration) / (start + duration + end)
-    //            = (-100 + 500) / (-100 + 500 + 600) = 40%
-    [["before timeline start", -100, 600, 0.10], [0, 0, 0, null, "before"]],
-    [["at timeline start",     -100, 600, 0.25], [0, 0, 0, 0.2,  "active"]],
-    [["in timeline range",     -100, 600, 0.30], [10, 10, 10, 0.4, "active"]],
-    [["at effect end",         -100, 600, 0.45], [40, 40, 40, null, "after"]],
-    [["after effect endDelay", -100, 600, 0.70], [90, 90, 90, null, "after"]],
-    [["at timeline end",       -100, 600, 0.75], [100, 100, 100, null, "after"]],
-    [["after timeline end",    -100, 600, 0.90], [100, 100, 100, null, "after"]],
-
-    // Case 9: Negative delay, negative endDelay.
-    [["before timeline start", -200, -200, 0.10], [0, 0, 0, null, "before"]],
-    [["at timeline start",     -200, -200, 0.25], [0, 0, 0, 0.4,  "active"]],
-    [["in timeline range",     -200, -200, 0.50], [50, 50, 50, 0.5,  "active"]],
-    [["at timeline end",       -200, -200, 0.75], [100, 100, 100, null, "after"]],
-    [["after timeline end",    -200, -200, 0.90], [100, 100, 100, null, "after"]],
+    // Case 5: Negative start and end delays.
+    // Effect boundaries are not reachable.
+    [
+      ["at timeline start", -125, -125, 0],
+      [0, 0, 0, 0.25, "active", 0.4]
+    ],
+    [
+      ["in active range", -125, -125, 0.5],
+      [50, 50, 50, 0.5, "active", 0.5]
+    ],
+    [
+      ["at timeline end", -125, -125, 1.0],
+      [100, 100, 100, 0.75, "active", 0.6]
+    ]
   ];
 
   for (const test_case of test_cases) {
@@ -164,13 +164,7 @@
       delay, end_delay, scroll_percentage, expected){
     return async t => {
       const target = createDiv(t);
-      // timetime time is:
-      // 100% * (scroll - start)/(end - start)  if (start <= scroll <= end).
-      // Choose convenient offsets to avoid fractional percentages with timeline
-      // time. Choosing the offset range [25%, 75%] results in:
-      // timeline time = 2 * (scroll% - start%) when 25% < scroll% < 75%.
-      const timeline =
-          createScrollTimelineWithOffsets(t, CSS.percent(25), CSS.percent(75));
+      const timeline = createScrollTimeline(t);
       const effect = new KeyframeEffect(
         target,
         {
@@ -183,6 +177,9 @@
         }
       );
       const animation = new Animation(effect, timeline);
+      t.add_cleanup(() => {
+        animation.cancel();
+      });
       const scroller = timeline.source;
       const maxScroll = scroller.scrollHeight - scroller.clientHeight;
 
@@ -200,7 +197,8 @@
           expected_animation_current_time,
           expected_effect_local_time,
           expected_effect_progress,
-          expected_effect_phase] = expected;
+          expected_effect_phase,
+          expected_opacity] = expected;
 
       assert_percents_equal(
           animation.timeline.currentTime,
@@ -221,6 +219,10 @@
           "animation effect progress");
       assert_phase_at_time(
           animation, expected_effect_phase, animation.currentTime);
+      assert_approx_equals(
+          parseFloat(getComputedStyle(target).opacity), expected_opacity,
+          0.001,
+          'target opacity');
     }
   }
 
@@ -236,70 +238,83 @@
     );
   }
 
-  function verifyTimelineBeforePhase(animation){
-    assert_equals(animation.timeline.phase, "before");
-    assert_percents_equal(animation.timeline.currentTime, 0);
-    assert_percents_equal(animation.currentTime, 0);
-    assert_percents_equal(animation.effect.getComputedTiming().localTime, 0,
-        "effect local time in timeline before phase");
-  }
+  function verifyEffectBeforePhase(animation) {
+    // If currentTime is null, we are either idle, or running with an
+    // inactive timeline. Either way, the animation is not in effect and cannot
+    // be in the before phase.
+    assert_true(animation.currentTime != null,
+                'Animation is not in effect');
 
-  function verifyEffectBeforePhase(animation){
+    const fillMode = animation.effect.getTiming().fill;
+    animation.effect.updateTiming({ fill: 'none' });
+
     // progress == null AND opacity == 1 implies we are in the effect before
-    // phase
+    // or after phase.
     assert_equals(animation.effect.getComputedTiming().progress, null);
     assert_equals(
         window.getComputedStyle(animation.effect.target)
             .getPropertyValue("opacity"),
         "1");
+
+    // If the progress is no longer null after adding fill: backwards, then we
+    // are in the before phase.
+    animation.effect.updateTiming({ fill: 'backwards' });
+    assert_true(animation.effect.getComputedTiming().progress != null);
+    assert_equals(
+        window.getComputedStyle(animation.effect.target)
+            .getPropertyValue("opacity"),
+        "0.3");
+
+    // Reset fill mode to avoid side-effects.
+    animation.effect.updateTiming({ fill: fillMode });
+  }
+
+  function createScrollLinkedOpacityAnimationWithDelays(t) {
+    const animation = new Animation(
+      createKeyframeEffectOpacity(t),
+      createScrollTimeline(t)
+    );
+    t.add_cleanup(() => {
+      animation.cancel();
+    });
+    animation.effect.updateTiming({
+       duration: 1000,
+       delay: 500,
+       endDelay: 500
+    });
+    return animation;
   }
 
   promise_test(async t => {
-    const animation = new Animation(
-      createKeyframeEffectOpacity(t),
-      createScrollTimelineWithOffsets(t, CSS.percent(20), CSS.percent(80))
-    );
-
+    const animation = createScrollLinkedOpacityAnimationWithDelays(t);
     const scroller = animation.timeline.source;
     const maxScroll = scroller.scrollHeight - scroller.clientHeight;
 
     animation.play();
     await animation.ready;
-
-    verifyTimelineBeforePhase(animation);
     verifyEffectBeforePhase(animation);
 
     animation.pause();
     await waitForNextFrame();
-
-    verifyTimelineBeforePhase(animation);
     verifyEffectBeforePhase(animation);
 
     animation.play();
     await waitForNextFrame();
 
-    verifyTimelineBeforePhase(animation);
     verifyEffectBeforePhase(animation);
   }, 'Verify that (play -> pause -> play) doesn\'t change phase/progress.');
 
   promise_test(async t => {
-    const animation = new Animation(
-        createKeyframeEffectOpacity(t),
-        createScrollTimelineWithOffsets(t, CSS.percent(20), CSS.percent(80)));
-
+    const animation = createScrollLinkedOpacityAnimationWithDelays(t);
     const scroller = animation.timeline.source;
     const maxScroll = scroller.scrollHeight - scroller.clientHeight;
 
     animation.play();
     await animation.ready;
-
-    verifyTimelineBeforePhase(animation);
     verifyEffectBeforePhase(animation);
 
     animation.pause();
     await waitForNextFrame();
-
-    verifyTimelineBeforePhase(animation);
     verifyEffectBeforePhase(animation);
 
     // Scrolling should not cause the animation effect to change.
@@ -307,7 +322,6 @@
     await waitForNextFrame();
 
     // Check timeline phase
-    assert_equals(animation.timeline.phase, "active");
     assert_percents_equal(animation.timeline.currentTime, 50);
     assert_percents_equal(animation.currentTime, 0);
     assert_percents_equal(animation.effect.getComputedTiming().localTime, 0,
@@ -320,73 +334,59 @@
      'should remain in the before phase');
 
   promise_test(async t => {
-    const animation = new Animation(
-        createKeyframeEffectOpacity(t),
-        createScrollTimelineWithOffsets(t, CSS.percent(20), CSS.percent(80)));
-
+    const animation = createScrollLinkedOpacityAnimationWithDelays(t);
     const scroller = animation.timeline.source;
     const maxScroll = scroller.scrollHeight - scroller.clientHeight;
 
     animation.play();
     await animation.ready;
-
-    verifyTimelineBeforePhase(animation);
     verifyEffectBeforePhase(animation);
 
     animation.pause();
     await waitForNextFrame();
-
-    verifyTimelineBeforePhase(animation);
     verifyEffectBeforePhase(animation);
 
     // Setting the current time should force the animation into effect.
     const expected_time = 50;
     animation.currentTime = CSS.percent(expected_time);
     await waitForNextFrame();
-
-    // Check timeline phase
-    assert_equals(animation.timeline.phase, "before");
     assert_percents_equal(animation.timeline.currentTime, 0);
-
-    // Make sure the effect is in the active phase even though the timeline is
-    // still in the before phase.
-    assert_percents_equal(animation.currentTime, expected_time);
+    assert_percents_equal(animation.currentTime, expected_time,
+                          'Current time matches set value');
     assert_percents_equal(
         animation.effect.getComputedTiming().localTime,
-        expected_time,
-        "effect local time in timeline before phase");
-
-    assert_equals(animation.effect.getComputedTiming().progress, 0.5);
+        expected_time, "Effect local time after setting animation.currentTime");
+    assert_equals(animation.effect.getComputedTiming().progress, 0.5,
+                  "Progress after setting animation.currentTime");
     assert_equals(
         window.getComputedStyle(animation.effect.target)
             .getPropertyValue("opacity"),
-        "0.5");
+        "0.5", "Opacity after setting animation.currentTime");
 
-    // Scrolling should not cause the animation effect to change.
-    scroller.scrollTop = 0.65 * maxScroll; // scroll so that timeline is 75%
+    // Scrolling should not cause the animation effect to change since
+    // paused.
+    scroller.scrollTop = 0.75 * maxScroll; // scroll so that timeline is 75%
     await waitForNextFrame();
-
-    assert_equals(animation.timeline.phase, "active");
     assert_percents_equal(animation.timeline.currentTime, 75);
 
     // animation and effect timings are unchanged.
-    assert_percents_equal(animation.currentTime, expected_time);
+    assert_percents_equal(animation.currentTime, expected_time,
+                          "Current time after scrolling while paused");
     assert_percents_equal(
         animation.effect.getComputedTiming().localTime,
         expected_time,
-        "effect local time");
-    assert_equals(animation.effect.getComputedTiming().progress, 0.5);
+        "Effect local time after scrolling while paused");
+    assert_equals(animation.effect.getComputedTiming().progress, 0.5,
+                  "Progress after scrolling while paused");
     assert_equals(
         window.getComputedStyle(animation.effect.target)
             .getPropertyValue("opacity"),
-        "0.5");
+        "0.5", "Opacity after scrolling while paused");
   }, 'Pause in before phase, set animation current time to be in active ' +
      'range, animation should become active. Scrolling should have no effect.');
 
   promise_test(async t => {
-    const animation = new Animation(
-        createKeyframeEffectOpacity(t),
-        createScrollTimelineWithOffsets(t, CSS.percent(20), CSS.percent(80)));
+    const animation = createScrollLinkedOpacityAnimationWithDelays(t);
     const scroller = animation.timeline.source;
     const maxScroll = scroller.scrollHeight - scroller.clientHeight;
 
@@ -398,32 +398,33 @@
     await waitForNextFrame();
     await waitForNextFrame();
 
-    // Check timeline phase
-    assert_equals(animation.timeline.phase, "inactive");
-    assert_equals(animation.timeline.currentTime, null);
-    assert_equals(animation.currentTime, null);
+    // Verify that he timeline is inactive
+    assert_equals(animation.timeline.currentTime, null,
+                  "Timeline is inactive");
+    assert_equals(
+        animation.currentTime, null,
+        "Current time for running animation with an inactive timeline");
     assert_equals(animation.effect.getComputedTiming().localTime, null,
         "effect local time with inactive timeline");
 
-    verifyEffectBeforePhase(animation);
-
-    // Setting the current time while timeline is inactive should cause hold phase
-    // and hold time to be populated
+    // Setting the current time while timeline is inactive should pause the
+    // animation at the specified time.
     animation.currentTime = CSS.percent(50);
     await waitForNextFrame();
     await waitForNextFrame();
 
-    // Check timeline phase
-    assert_equals(animation.timeline.phase, "inactive");
+    // Verify that animation currentTime is properly set despite the inactive
+    // timeline.
     assert_equals(animation.timeline.currentTime, null);
     assert_percents_equal(animation.currentTime, 50);
     assert_percents_equal(animation.effect.getComputedTiming().localTime, 50,
         "effect local time after setting animation current time");
 
     // Check effect phase
-    // progress == 0.5 AND opacity == 0.5 shows we are in the effect active phase
+    // progress == 0.5 AND opacity == 0.5 shows we are in the effect active
+    // phase.
     assert_equals(animation.effect.getComputedTiming().progress, 0.5,
-        "effect progress");
+                  "effect progress");
     assert_equals(
         window.getComputedStyle(animation.effect.target)
             .getPropertyValue("opacity"),
@@ -432,13 +433,11 @@
   }, 'Make scroller inactive, then set current time to an in range time');
 
   promise_test(async t => {
-    const animation = new Animation(
-        createKeyframeEffectOpacity(t),
-        createScrollTimelineWithOffsets(t, CSS.percent(20), CSS.percent(80)));
+    const animation = createScrollLinkedOpacityAnimationWithDelays(t);
     const scroller = animation.timeline.source;
     const maxScroll = scroller.scrollHeight - scroller.clientHeight;
     scroller.scrollTop = 0.5 * maxScroll;
-    // allow the scroll to finish.
+    // Update timeline.currentTime.
     await waitForNextFrame();
 
     animation.pause();
@@ -462,11 +461,8 @@
   }, 'Animation effect is still applied after pausing and making timeline ' +
      'inactive.');
 
-    promise_test(async t => {
-    const animation = new Animation(
-        createKeyframeEffectOpacity(t),
-        createScrollTimelineWithOffsets(t, CSS.percent(20), CSS.percent(80)));
-
+  promise_test(async t => {
+    const animation = createScrollLinkedOpacityAnimationWithDelays(t);
     const scroller = animation.timeline.source;
     const maxScroll = scroller.scrollHeight - scroller.clientHeight;
 
@@ -481,48 +477,4 @@
     animation.pause();
   }, 'Make timeline inactive, force style update then pause the animation. ' +
      'No crashing indicates test success.');
-
-  /* Scroll Animations have a special inclusive end so that when using default
-     timing settings if you scroll to the bottom of a scroller, its animation
-     will remain in effect. This is only true if there are no effect delays
-     and no timeline offsets being used. */
-  promise_test(async t => {
-    const animation = new Animation(
-        createKeyframeEffectOpacity(t),
-        createScrollTimeline(t));
-
-    const scroller = animation.timeline.source;
-    const maxScroll = scroller.scrollHeight - scroller.clientHeight;
-
-    animation.play();
-    await animation.ready;
-    scroller.scrollTop = maxScroll;
-
-    // Wait for new animation frame which allows the timeline to compute
-    // new current time.
-    await waitForNextFrame();
-
-    assert_percents_equal(
-        animation.timeline.currentTime,
-        100,
-        "timeline current time");
-    assert_percents_equal(
-        animation.currentTime,
-        100,
-        "animation current time");
-    assert_percents_equal(
-        animation.effect.getComputedTiming().localTime,
-        100,
-        "animation effect local time");
-    assert_approx_equals_or_null(
-        animation.effect.getComputedTiming().progress,
-        1,
-        0.001,
-        "animation effect progress");
-    assert_phase_at_time(
-        animation, "active", animation.currentTime);
-
-  }, 'If no timeline offsets are specified and no effect delays, when ' +
-     'reaching the end of the scroll animation, effect should still be ' +
-     'applied.');
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/scroll-timelines/scroll-timeline-phases.tentative.html b/third_party/blink/web_tests/external/wpt/scroll-animations/scroll-timelines/scroll-timeline-phases.tentative.html
deleted file mode 100644
index 651f0ed1..0000000
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/scroll-timelines/scroll-timeline-phases.tentative.html
+++ /dev/null
@@ -1,217 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<title>Test basic functionality of scroll timeline phases.</title>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/web-animations/testcommon.js"></script>
-<script src="testcommon.js"></script>
-<style>
-  .scroller {
-    overflow: auto;
-    height: 100px;
-    width: 100px;
-  }
-  .contents {
-    height: 1000px;
-    width: 100%;
-  }
-</style>
-<div id="log"></div>
-<script>
-  'use strict';
-
-  promise_test(async t => {
-    const timeline = createScrollTimeline(t);
-    assert_throws_js(TypeError, () => {
-      timeline.phase = "after";
-    });
-  }, 'Setting scroll timeline phase (which is readonly) throws TypeError.');
-
-  const test_cases = {
-    before_start: {
-      name: "before start",
-      scroll_percent: 0.1,
-      timeline_phase: "before"
-    },
-    at_start: {
-      name: "at start",
-      scroll_percent: 0.2,
-      timeline_phase: "active"
-    },
-    in_range: {
-      name: "in range",
-      scroll_percent: 0.5,
-      timeline_phase: "active"
-    },
-    at_end: {
-      name: "at end",
-      scroll_percent: 0.8,
-      timeline_phase: "after"
-    },
-    after_end: {
-      name: "after end",
-      scroll_percent: 0.9,
-      timeline_phase: "after"
-    }
-  }
-
-  for (const test_case_key in test_cases){
-    const test_case = test_cases[test_case_key];
-    promise_test(async t => {
-      const timeline = createScrollTimelineWithOffsets(t, CSS.percent(20), CSS.percent(80));
-      const scroller = timeline.source;
-      const maxScroll = scroller.scrollHeight - scroller.clientHeight;
-
-      scroller.scrollTop = test_case.scroll_percent * maxScroll;
-      // Wait for new animation frame which allows the timeline to compute new
-      // current time.
-      await waitForNextFrame();
-
-      assert_equals(
-        timeline.phase,
-        test_case.timeline_phase,
-        "timeline.phase"
-      );
-    }, "Timeline phase while scroll offset is " + test_case.name);
-  }
-
-  // TODO(crbug.com/1060384): Spec is unclear in this case, revisit this when
-  // desired results have been established.
-  // These test cases are worded strangely because they test an edge case
-  // where startScrollOffset is GREATER THAN endScrollOffset
-  const test_cases_start_offset_greater_than_end_offset = {
-    before_end: {
-      name: "before end",
-      scroll_percent: 0.1,
-      timeline_phase: "before"
-    },
-    at_end: {
-      name: "at end",
-      scroll_percent: 0.2,
-      timeline_phase: "before"
-    },
-    before_start: {
-      name: "before start",
-      scroll_percent: 0.5,
-      timeline_phase: "before"
-    },
-    at_start: {
-      name: "at start",
-      scroll_percent: 0.8,
-      timeline_phase: "after"
-    },
-    after_start: {
-      name: "after start",
-      scroll_percent: 0.9,
-      timeline_phase: "after"
-    }
-  }
-
-  for (const test_case_key in test_cases_start_offset_greater_than_end_offset){
-    const test_case =
-      test_cases_start_offset_greater_than_end_offset[test_case_key];
-    promise_test(async t => {
-      const timeline = createScrollTimelineWithOffsets(t, CSS.percent(80), CSS.percent(20));
-      const scroller = timeline.source;
-      const maxScroll = scroller.scrollHeight - scroller.clientHeight;
-
-      scroller.scrollTop = test_case.scroll_percent * maxScroll;
-      // Wait for new animation frame which allows the timeline to compute new
-      // current time.
-      await waitForNextFrame();
-
-      assert_equals(
-        timeline.phase,
-        test_case.timeline_phase,
-        "timeline.phase"
-      );
-    }, "Timeline phase while start offset is greater than end offset and" +
-    " scroll offset is " + test_case.name);
-  }
-
-  // TODO(crbug.com/1060384): Spec is unclear in this case, revisit this when
-  // desired results have been established.
-  // Test cases where startScrollOffset is EQUAL TO endScrollOffset
-  const test_cases_start_offset_equal_to_end_offset = {
-    before_end: {
-      name: "before start",
-      scroll_percent: 0.3,
-      timeline_phase: "before"
-    },
-    at_end: {
-      name: "at both",
-      scroll_percent: 0.5,
-      timeline_phase: "after"
-    },
-    before_start: {
-      name: "after end",
-      scroll_percent: 0.7,
-      timeline_phase: "after"
-    }
-  }
-
-  for (const test_case_key in test_cases_start_offset_equal_to_end_offset){
-    const test_case =
-      test_cases_start_offset_equal_to_end_offset[test_case_key];
-    promise_test(async t => {
-      const timeline = createScrollTimelineWithOffsets(t, CSS.percent(50), CSS.percent(50));
-      const scroller = timeline.source;
-      const maxScroll = scroller.scrollHeight - scroller.clientHeight;
-
-      scroller.scrollTop = test_case.scroll_percent * maxScroll;
-      // Wait for new animation frame which allows the timeline to compute new
-      // current time.
-      await waitForNextFrame();
-
-      assert_equals(
-        timeline.phase,
-        test_case.timeline_phase,
-        "timeline.phase"
-      );
-    }, "Timeline phase while start offset is equal to end offset and scroll" +
-    " offset is " + test_case.name);
-  }
-
-  promise_test(async t => {
-    const timeline = createScrollTimeline(t);
-    const scroller = timeline.source;
-    const maxScroll = scroller.scrollHeight - scroller.clientHeight;
-
-    scroller.scrollTop = maxScroll;
-
-    // Wait for new animation frame which allows the timeline to compute new
-    // current time.
-    await waitForNextFrame();
-
-    // When the endScrollOffset is equal to the maximum scroll offset, the
-    // endScrollOffset is treated as inclusive so the phase should remain
-    // active.
-    assert_equals(timeline.phase, "active");
-  }, 'Scroll timeline phase should be active when at scroll maximum and ' +
-    'endScrollOffset is equal to maximum scroll offset.');
-
-  promise_test(async t => {
-    const timeline = createScrollTimeline(t);
-    const scroller = timeline.source;
-    // Setting the scroller to display none should make the timeline inactive
-    scroller.style.display = "none";
-    scroller.scrollTop;
-    await waitForNextFrame();
-    assert_equals(timeline.phase, "inactive");
-
-    // Setting the scroller to display "block" should make the timeline active
-    scroller.style.display = "block";
-    scroller.scrollTop;
-    await waitForNextFrame();
-    assert_equals(timeline.phase, "active");
-
-    // Setting the scroller to display none should make the timeline inactive
-    scroller.style.display = "none";
-    scroller.scrollTop;
-    await waitForNextFrame();
-
-    assert_equals(timeline.phase, "inactive");
-  }, 'Scroll timeline starts inactive, can transition to active, and then' +
-  ' back to inactive.');
-
-</script>
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/interfaces/DocumentTimeline/document-timeline-phases.tentative.html b/third_party/blink/web_tests/external/wpt/web-animations/interfaces/DocumentTimeline/document-timeline-phases.tentative.html
deleted file mode 100644
index 9b86a7105..0000000
--- a/third_party/blink/web_tests/external/wpt/web-animations/interfaces/DocumentTimeline/document-timeline-phases.tentative.html
+++ /dev/null
@@ -1,19 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<title>Test basic functionality of document timeline phases.</title>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script>
-  'use strict';
-  promise_test(async t => {
-    const timeline = new DocumentTimeline();
-    assert_equals(timeline.phase, "active");
-  }, 'Document timeline starts in "active" phase.');
-
-  promise_test(async t => {
-    const timeline = new DocumentTimeline();
-    assert_throws_js(TypeError, () => {
-      timeline.phase = "after";
-    });
-  }, 'Setting document timeline phase (which is readonly) throws TypeError.');
-</script>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/testcommon.js b/third_party/blink/web_tests/external/wpt/web-animations/testcommon.js
index 5831c75..f5ea0a8 100644
--- a/third_party/blink/web_tests/external/wpt/web-animations/testcommon.js
+++ b/third_party/blink/web_tests/external/wpt/web-animations/testcommon.js
@@ -280,6 +280,7 @@
 
 function assert_phase_at_time(animation, phase, currentTime) {
   animation.currentTime = currentTime;
+  const fillMode = animation.effect.getTiming().fill;
 
   if (phase === 'active') {
     // If the fill mode is 'none', then progress will only be non-null if we
@@ -306,4 +307,7 @@
                       `time is ${currentTime} (progress is non-null with ` +
                       `appropriate fill mode)`);
   }
+
+  // Reset fill mode to avoid side-effects.
+  animation.effect.updateTiming({ fill: fillMode });
 }
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/dark-mode/colors/border-expected.png b/third_party/blink/web_tests/flag-specific/disable-layout-ng/dark-mode/colors/border-expected.png
new file mode 100644
index 0000000..44fe71d
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/dark-mode/colors/border-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/dark-mode-default/dark-mode/colors/border-expected.png b/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/dark-mode-default/dark-mode/colors/border-expected.png
new file mode 100644
index 0000000..5a0ee9b
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/dark-mode-default/dark-mode/colors/border-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/dark-mode-default/dark-mode/colors/select-popup-expected.png b/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/dark-mode-default/dark-mode/colors/select-popup-expected.png
index 802c42d9..66e4f66 100644
--- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/dark-mode-default/dark-mode/colors/select-popup-expected.png
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/dark-mode-default/dark-mode/colors/select-popup-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/dark-mode-default/dark-mode/colors/selection-expected.png b/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/dark-mode-default/dark-mode/colors/selection-expected.png
index 34c8029..ae5c3fa4 100644
--- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/dark-mode-default/dark-mode/colors/selection-expected.png
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/dark-mode-default/dark-mode/colors/selection-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/dark-mode-default/dark-mode/colors/text-on-backgrounds-expected.png b/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/dark-mode-default/dark-mode/colors/text-on-backgrounds-expected.png
new file mode 100644
index 0000000..e62aa23
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/dark-mode-default/dark-mode/colors/text-on-backgrounds-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/dark-mode-default/dark-mode/colors/web-theme-expected.png b/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/dark-mode-default/dark-mode/colors/web-theme-expected.png
new file mode 100644
index 0000000..7da1797
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/dark-mode-default/dark-mode/colors/web-theme-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/dark-mode-increase-text-contrast/dark-mode/colors/select-popup-expected.png b/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/dark-mode-increase-text-contrast/dark-mode/colors/select-popup-expected.png
index 802c42d9..66e4f66 100644
--- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/dark-mode-increase-text-contrast/dark-mode/colors/select-popup-expected.png
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/dark-mode-increase-text-contrast/dark-mode/colors/select-popup-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/dark-mode-increase-text-contrast/dark-mode/colors/selection-expected.png b/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/dark-mode-increase-text-contrast/dark-mode/colors/selection-expected.png
index ea62a5c..7598e40 100644
--- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/dark-mode-increase-text-contrast/dark-mode/colors/selection-expected.png
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/dark-mode-increase-text-contrast/dark-mode/colors/selection-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/dark-mode-increase-text-contrast/dark-mode/colors/text-on-backgrounds-expected.png b/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/dark-mode-increase-text-contrast/dark-mode/colors/text-on-backgrounds-expected.png
new file mode 100644
index 0000000..32fcec3
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/dark-mode-increase-text-contrast/dark-mode/colors/text-on-backgrounds-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/dark-mode-increase-text-contrast/dark-mode/colors/web-theme-expected.png b/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/dark-mode-increase-text-contrast/dark-mode/colors/web-theme-expected.png
new file mode 100644
index 0000000..7da1797
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/dark-mode-increase-text-contrast/dark-mode/colors/web-theme-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/dark-mode/colors/border-expected.png b/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/dark-mode/colors/border-expected.png
new file mode 100644
index 0000000..44fe71d
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/dark-mode/colors/border-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/virtual/dark-mode-default/dark-mode/colors/border-expected.png b/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/virtual/dark-mode-default/dark-mode/colors/border-expected.png
new file mode 100644
index 0000000..5a0ee9b
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/virtual/dark-mode-default/dark-mode/colors/border-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/virtual/dark-mode-default/dark-mode/colors/select-popup-expected.png b/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/virtual/dark-mode-default/dark-mode/colors/select-popup-expected.png
new file mode 100644
index 0000000..66e4f66
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/virtual/dark-mode-default/dark-mode/colors/select-popup-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/virtual/dark-mode-default/dark-mode/colors/selection-expected.png b/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/virtual/dark-mode-default/dark-mode/colors/selection-expected.png
new file mode 100644
index 0000000..14bb7bc
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/virtual/dark-mode-default/dark-mode/colors/selection-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/virtual/dark-mode-default/dark-mode/colors/text-on-backgrounds-expected.png b/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/virtual/dark-mode-default/dark-mode/colors/text-on-backgrounds-expected.png
new file mode 100644
index 0000000..e62aa23
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/virtual/dark-mode-default/dark-mode/colors/text-on-backgrounds-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/virtual/dark-mode-default/dark-mode/colors/web-theme-expected.png b/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/virtual/dark-mode-default/dark-mode/colors/web-theme-expected.png
new file mode 100644
index 0000000..7da1797
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/virtual/dark-mode-default/dark-mode/colors/web-theme-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/virtual/dark-mode-increase-text-contrast/dark-mode/colors/select-popup-expected.png b/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/virtual/dark-mode-increase-text-contrast/dark-mode/colors/select-popup-expected.png
new file mode 100644
index 0000000..66e4f66
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/virtual/dark-mode-increase-text-contrast/dark-mode/colors/select-popup-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/virtual/dark-mode-increase-text-contrast/dark-mode/colors/selection-expected.png b/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/virtual/dark-mode-increase-text-contrast/dark-mode/colors/selection-expected.png
new file mode 100644
index 0000000..b495bc3
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/virtual/dark-mode-increase-text-contrast/dark-mode/colors/selection-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/virtual/dark-mode-increase-text-contrast/dark-mode/colors/text-on-backgrounds-expected.png b/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/virtual/dark-mode-increase-text-contrast/dark-mode/colors/text-on-backgrounds-expected.png
new file mode 100644
index 0000000..32fcec3
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/virtual/dark-mode-increase-text-contrast/dark-mode/colors/text-on-backgrounds-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/virtual/dark-mode-increase-text-contrast/dark-mode/colors/web-theme-expected.png b/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/virtual/dark-mode-increase-text-contrast/dark-mode/colors/web-theme-expected.png
new file mode 100644
index 0000000..7da1797
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/virtual/dark-mode-increase-text-contrast/dark-mode/colors/web-theme-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/html/semantics/forms/the-form-element/form-autocomplete-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/html/semantics/forms/the-form-element/form-autocomplete-expected.txt
index 25900f61..0eb0d62d 100644
--- a/third_party/blink/web_tests/platform/generic/external/wpt/html/semantics/forms/the-form-element/form-autocomplete-expected.txt
+++ b/third_party/blink/web_tests/platform/generic/external/wpt/html/semantics/forms/the-form-element/form-autocomplete-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 65 tests; 64 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 67 tests; 64 PASS, 3 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS form autocomplete attribute missing
 PASS form autocomplete attribute on
 PASS form autocomplete attribute off
@@ -60,10 +60,12 @@
 PASS tel-extension is an allowed autocomplete field name
 PASS email is an allowed autocomplete field name
 PASS impp is an allowed autocomplete field name
+FAIL webauthn is an allowed autocomplete field name assert_equals: expected "webauthn" but got ""
 PASS Test whitespace-only attribute value
 PASS Test maximum number of tokens
 PASS Unknown field
 PASS Test 'wearing the autofill anchor mantle' with off/on
 PASS Serialize combinations of section, mode, contact, and field
+FAIL Serialize combinations of section, mode, contact, field, and credential assert_equals: expected "username webauthn" but got ""
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/scroll-animations/css/at-scroll-timeline-responsiveness-from-endpoint-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/scroll-animations/css/at-scroll-timeline-responsiveness-from-endpoint-expected.txt
deleted file mode 100644
index 898f1cf..0000000
--- a/third_party/blink/web_tests/platform/generic/external/wpt/scroll-animations/css/at-scroll-timeline-responsiveness-from-endpoint-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Test that the scroll animation is still responsive after moving from 100% assert_equals: expected "100px" but got "50px"
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/web-animations/idlharness.window-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/web-animations/idlharness.window-expected.txt
index 411b4dcb..36c42904 100644
--- a/third_party/blink/web_tests/platform/generic/external/wpt/web-animations/idlharness.window-expected.txt
+++ b/third_party/blink/web_tests/platform/generic/external/wpt/web-animations/idlharness.window-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 215 tests; 166 PASS, 49 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 215 tests; 164 PASS, 51 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS idl_test setup
 PASS idl_test validation
 PASS Partial interface Document: original interface defined
@@ -48,7 +48,7 @@
 PASS AnimationTimeline interface: existence and properties of interface prototype object's "constructor" property
 PASS AnimationTimeline interface: existence and properties of interface prototype object's @@unscopables property
 PASS AnimationTimeline interface: attribute currentTime
-PASS AnimationTimeline interface: attribute phase
+FAIL AnimationTimeline interface: attribute phase assert_true: The prototype object must have a property "phase" expected true got false
 PASS AnimationTimeline interface: attribute duration
 FAIL AnimationTimeline interface: operation play(optional AnimationEffect?) assert_own_property: interface prototype object missing non-static operation expected property "play" missing
 PASS DocumentTimeline interface: existence and properties of interface object
@@ -60,7 +60,7 @@
 PASS DocumentTimeline must be primary interface of document.timeline
 PASS Stringification of document.timeline
 PASS AnimationTimeline interface: document.timeline must inherit property "currentTime" with the proper type
-PASS AnimationTimeline interface: document.timeline must inherit property "phase" with the proper type
+FAIL AnimationTimeline interface: document.timeline must inherit property "phase" with the proper type assert_inherits: property "phase" not found in prototype chain
 PASS AnimationTimeline interface: document.timeline must inherit property "duration" with the proper type
 FAIL AnimationTimeline interface: document.timeline must inherit property "play(optional AnimationEffect?)" with the proper type assert_inherits: property "play" not found in prototype chain
 FAIL AnimationTimeline interface: calling play(optional AnimationEffect?) on document.timeline with too few arguments must throw TypeError assert_inherits: property "play" not found in prototype chain
diff --git a/third_party/blink/web_tests/platform/generic/virtual/dark-mode-default/dark-mode/colors/text-on-backgrounds-expected.png b/third_party/blink/web_tests/platform/generic/virtual/dark-mode-default/dark-mode/colors/text-on-backgrounds-expected.png
index fe5fe105..c6cd040f 100644
--- a/third_party/blink/web_tests/platform/generic/virtual/dark-mode-default/dark-mode/colors/text-on-backgrounds-expected.png
+++ b/third_party/blink/web_tests/platform/generic/virtual/dark-mode-default/dark-mode/colors/text-on-backgrounds-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/generic/virtual/dark-mode-increase-text-contrast/dark-mode/colors/text-on-backgrounds-expected.png b/third_party/blink/web_tests/platform/generic/virtual/dark-mode-increase-text-contrast/dark-mode/colors/text-on-backgrounds-expected.png
index e5414a3..d22fa23cb 100644
--- a/third_party/blink/web_tests/platform/generic/virtual/dark-mode-increase-text-contrast/dark-mode/colors/text-on-backgrounds-expected.png
+++ b/third_party/blink/web_tests/platform/generic/virtual/dark-mode-increase-text-contrast/dark-mode/colors/text-on-backgrounds-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/generic/virtual/fenced-frame-mparch/wpt_internal/fenced_frame/disallowed-navigations.https-expected.txt b/third_party/blink/web_tests/platform/generic/virtual/fenced-frame-mparch/wpt_internal/fenced_frame/disallowed-navigations.https-expected.txt
new file mode 100644
index 0000000..130205a2
--- /dev/null
+++ b/third_party/blink/web_tests/platform/generic/virtual/fenced-frame-mparch/wpt_internal/fenced_frame/disallowed-navigations.https-expected.txt
@@ -0,0 +1,42 @@
+This is a testharness.js-based test.
+PASS iframe data: URL
+PASS iframe blob: URL
+PASS iframe javascript: URL
+PASS fenced frame mode=opaque-ads data: URL
+PASS fenced frame mode=opaque-ads blob: URL
+PASS fenced frame mode=opaque-ads javascript: URL
+PASS fenced frame mode=opaque-ads http: URL
+PASS fenced frame mode=opaque-ads dangling-markup URL with 'blo
+ck<ed'
+PASS fenced frame mode=opaque-ads dangling-markup URL with 'blo\rck<ed'
+PASS fenced frame mode=opaque-ads dangling-markup URL with 'blo	ck<ed'
+PASS fenced frame mode=opaque-ads dangling-markup URL with 'blo<ck
+ed'
+PASS fenced frame mode=opaque-ads dangling-markup URL with 'blo<ck\red'
+PASS fenced frame mode=opaque-ads dangling-markup URL with 'blo<ck	ed'
+PASS fenced frame mode=default data: URL
+PASS fenced frame mode=default blob: URL
+PASS fenced frame mode=default javascript: URL
+PASS fenced frame mode=default http: URL
+PASS fenced frame mode=default dangling-markup URL with 'blo
+ck<ed'
+PASS fenced frame mode=default dangling-markup URL with 'blo\rck<ed'
+PASS fenced frame mode=default dangling-markup URL with 'blo	ck<ed'
+PASS fenced frame mode=default dangling-markup URL with 'blo<ck
+ed'
+PASS fenced frame mode=default dangling-markup URL with 'blo<ck\red'
+PASS fenced frame mode=default dangling-markup URL with 'blo<ck	ed'
+PASS fenced frame opaque URN => data: URL
+PASS fenced frame opaque URN => blob: URL
+PASS fenced frame opaque URN => javascript: URL
+PASS fenced frame opaque URN => http: URL
+FAIL fenced frame opaque URN => https: URL with dangling markup 'blo
+ck<ed' assert_equals: expected "NOT LOADED" but got "https://web-platform.test:8444/wpt_internal/fenced_frame/resources/report-url.html?blo<cked="
+FAIL fenced frame opaque URN => https: URL with dangling markup 'blo\rck<ed' assert_equals: expected "NOT LOADED" but got "https://web-platform.test:8444/wpt_internal/fenced_frame/resources/report-url.html?blo<cked="
+FAIL fenced frame opaque URN => https: URL with dangling markup 'blo	ck<ed' assert_equals: expected "NOT LOADED" but got "https://web-platform.test:8444/wpt_internal/fenced_frame/resources/report-url.html?blo<cked="
+FAIL fenced frame opaque URN => https: URL with dangling markup 'blo<ck
+ed' assert_equals: expected "NOT LOADED" but got "https://web-platform.test:8444/wpt_internal/fenced_frame/resources/report-url.html?blo<cked="
+FAIL fenced frame opaque URN => https: URL with dangling markup 'blo<ck\red' assert_equals: expected "NOT LOADED" but got "https://web-platform.test:8444/wpt_internal/fenced_frame/resources/report-url.html?blo<cked="
+FAIL fenced frame opaque URN => https: URL with dangling markup 'blo<ck	ed' assert_equals: expected "NOT LOADED" but got "https://web-platform.test:8444/wpt_internal/fenced_frame/resources/report-url.html?blo<cked="
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/generic/virtual/fenced-frame-shadow-dom/wpt_internal/fenced_frame/disallowed-navigations.https-expected.txt b/third_party/blink/web_tests/platform/generic/virtual/fenced-frame-shadow-dom/wpt_internal/fenced_frame/disallowed-navigations.https-expected.txt
index 39f0fb8..b907bde 100644
--- a/third_party/blink/web_tests/platform/generic/virtual/fenced-frame-shadow-dom/wpt_internal/fenced_frame/disallowed-navigations.https-expected.txt
+++ b/third_party/blink/web_tests/platform/generic/virtual/fenced-frame-shadow-dom/wpt_internal/fenced_frame/disallowed-navigations.https-expected.txt
@@ -7,13 +7,37 @@
 PASS fenced frame mode=opaque-ads blob: URL
 PASS fenced frame mode=opaque-ads javascript: URL
 PASS fenced frame mode=opaque-ads http: URL
+PASS fenced frame mode=opaque-ads dangling-markup URL with 'blo
+ck<ed'
+PASS fenced frame mode=opaque-ads dangling-markup URL with 'blo\rck<ed'
+PASS fenced frame mode=opaque-ads dangling-markup URL with 'blo	ck<ed'
+PASS fenced frame mode=opaque-ads dangling-markup URL with 'blo<ck
+ed'
+PASS fenced frame mode=opaque-ads dangling-markup URL with 'blo<ck\red'
+PASS fenced frame mode=opaque-ads dangling-markup URL with 'blo<ck	ed'
 PASS fenced frame mode=default data: URL
 PASS fenced frame mode=default blob: URL
 PASS fenced frame mode=default javascript: URL
 PASS fenced frame mode=default http: URL
+PASS fenced frame mode=default dangling-markup URL with 'blo
+ck<ed'
+PASS fenced frame mode=default dangling-markup URL with 'blo\rck<ed'
+PASS fenced frame mode=default dangling-markup URL with 'blo	ck<ed'
+PASS fenced frame mode=default dangling-markup URL with 'blo<ck
+ed'
+PASS fenced frame mode=default dangling-markup URL with 'blo<ck\red'
+PASS fenced frame mode=default dangling-markup URL with 'blo<ck	ed'
 PASS fenced frame opaque URN => data: URL
 PASS fenced frame opaque URN => blob: URL
 PASS fenced frame opaque URN => javascript: URL
 PASS fenced frame opaque URN => http: URL
+FAIL fenced frame opaque URN => https: URL with dangling markup 'blo
+ck<ed' assert_equals: expected "NOT LOADED" but got "https://web-platform.test:8444/wpt_internal/fenced_frame/resources/report-url.html?blo<cked="
+FAIL fenced frame opaque URN => https: URL with dangling markup 'blo\rck<ed' assert_equals: expected "NOT LOADED" but got "https://web-platform.test:8444/wpt_internal/fenced_frame/resources/report-url.html?blo<cked="
+FAIL fenced frame opaque URN => https: URL with dangling markup 'blo	ck<ed' assert_equals: expected "NOT LOADED" but got "https://web-platform.test:8444/wpt_internal/fenced_frame/resources/report-url.html?blo<cked="
+FAIL fenced frame opaque URN => https: URL with dangling markup 'blo<ck
+ed' assert_equals: expected "NOT LOADED" but got "https://web-platform.test:8444/wpt_internal/fenced_frame/resources/report-url.html?blo<cked="
+FAIL fenced frame opaque URN => https: URL with dangling markup 'blo<ck\red' assert_equals: expected "NOT LOADED" but got "https://web-platform.test:8444/wpt_internal/fenced_frame/resources/report-url.html?blo<cked="
+FAIL fenced frame opaque URN => https: URL with dangling markup 'blo<ck	ed' assert_equals: expected "NOT LOADED" but got "https://web-platform.test:8444/wpt_internal/fenced_frame/resources/report-url.html?blo<cked="
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/platform/generic/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/platform/generic/webexposed/global-interface-listing-expected.txt
index 3b917283..9b1c74a 100644
--- a/third_party/blink/web_tests/platform/generic/webexposed/global-interface-listing-expected.txt
+++ b/third_party/blink/web_tests/platform/generic/webexposed/global-interface-listing-expected.txt
@@ -231,7 +231,6 @@
     attribute @@toStringTag
     getter currentTime
     getter duration
-    getter phase
     method constructor
 interface Attr : Node
     attribute @@toStringTag
diff --git a/third_party/blink/web_tests/platform/linux/dark-mode/colors/border-expected.png b/third_party/blink/web_tests/platform/linux/dark-mode/colors/border-expected.png
new file mode 100644
index 0000000..44fe71d
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/dark-mode/colors/border-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/dark-mode-default/dark-mode/colors/border-expected.png b/third_party/blink/web_tests/platform/linux/virtual/dark-mode-default/dark-mode/colors/border-expected.png
new file mode 100644
index 0000000..5a0ee9b
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/virtual/dark-mode-default/dark-mode/colors/border-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/dark-mode-default/dark-mode/colors/select-popup-expected.png b/third_party/blink/web_tests/platform/linux/virtual/dark-mode-default/dark-mode/colors/select-popup-expected.png
index 802c42d9..66e4f66 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/dark-mode-default/dark-mode/colors/select-popup-expected.png
+++ b/third_party/blink/web_tests/platform/linux/virtual/dark-mode-default/dark-mode/colors/select-popup-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/dark-mode-default/dark-mode/colors/selection-expected.png b/third_party/blink/web_tests/platform/linux/virtual/dark-mode-default/dark-mode/colors/selection-expected.png
index a488bdd9..14bb7bc 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/dark-mode-default/dark-mode/colors/selection-expected.png
+++ b/third_party/blink/web_tests/platform/linux/virtual/dark-mode-default/dark-mode/colors/selection-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/dark-mode-default/dark-mode/colors/text-on-backgrounds-expected.png b/third_party/blink/web_tests/platform/linux/virtual/dark-mode-default/dark-mode/colors/text-on-backgrounds-expected.png
new file mode 100644
index 0000000..e62aa23
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/virtual/dark-mode-default/dark-mode/colors/text-on-backgrounds-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/dark-mode-increase-text-contrast/dark-mode/colors/border-expected.png b/third_party/blink/web_tests/platform/linux/virtual/dark-mode-increase-text-contrast/dark-mode/colors/border-expected.png
new file mode 100644
index 0000000..5a0ee9b
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/virtual/dark-mode-increase-text-contrast/dark-mode/colors/border-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/dark-mode-increase-text-contrast/dark-mode/colors/select-popup-expected.png b/third_party/blink/web_tests/platform/linux/virtual/dark-mode-increase-text-contrast/dark-mode/colors/select-popup-expected.png
index 802c42d9..66e4f66 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/dark-mode-increase-text-contrast/dark-mode/colors/select-popup-expected.png
+++ b/third_party/blink/web_tests/platform/linux/virtual/dark-mode-increase-text-contrast/dark-mode/colors/select-popup-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/dark-mode-increase-text-contrast/dark-mode/colors/selection-expected.png b/third_party/blink/web_tests/platform/linux/virtual/dark-mode-increase-text-contrast/dark-mode/colors/selection-expected.png
index 6d51f1d5..b495bc3 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/dark-mode-increase-text-contrast/dark-mode/colors/selection-expected.png
+++ b/third_party/blink/web_tests/platform/linux/virtual/dark-mode-increase-text-contrast/dark-mode/colors/selection-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/dark-mode-increase-text-contrast/dark-mode/colors/text-on-backgrounds-expected.png b/third_party/blink/web_tests/platform/linux/virtual/dark-mode-increase-text-contrast/dark-mode/colors/text-on-backgrounds-expected.png
index 8b5a1b9..32fcec3 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/dark-mode-increase-text-contrast/dark-mode/colors/text-on-backgrounds-expected.png
+++ b/third_party/blink/web_tests/platform/linux/virtual/dark-mode-increase-text-contrast/dark-mode/colors/text-on-backgrounds-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.15/virtual/dark-mode-default/dark-mode/colors/border-expected.png b/third_party/blink/web_tests/platform/mac-mac10.15/virtual/dark-mode-default/dark-mode/colors/border-expected.png
new file mode 100644
index 0000000..2e9bc2ee
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.15/virtual/dark-mode-default/dark-mode/colors/border-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.15/virtual/dark-mode-default/dark-mode/colors/selection-expected.png b/third_party/blink/web_tests/platform/mac-mac10.15/virtual/dark-mode-default/dark-mode/colors/selection-expected.png
new file mode 100644
index 0000000..a931abf
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.15/virtual/dark-mode-default/dark-mode/colors/selection-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.15/virtual/dark-mode-default/dark-mode/colors/text-on-backgrounds-expected.png b/third_party/blink/web_tests/platform/mac-mac10.15/virtual/dark-mode-default/dark-mode/colors/text-on-backgrounds-expected.png
new file mode 100644
index 0000000..e62aa23
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.15/virtual/dark-mode-default/dark-mode/colors/text-on-backgrounds-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.15/virtual/dark-mode-default/dark-mode/colors/web-theme-expected.png b/third_party/blink/web_tests/platform/mac-mac10.15/virtual/dark-mode-default/dark-mode/colors/web-theme-expected.png
new file mode 100644
index 0000000..6b7bf79f
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.15/virtual/dark-mode-default/dark-mode/colors/web-theme-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.15/virtual/dark-mode-increase-text-contrast/dark-mode/colors/border-expected.png b/third_party/blink/web_tests/platform/mac-mac10.15/virtual/dark-mode-increase-text-contrast/dark-mode/colors/border-expected.png
new file mode 100644
index 0000000..2e9bc2ee
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.15/virtual/dark-mode-increase-text-contrast/dark-mode/colors/border-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.15/virtual/dark-mode-increase-text-contrast/dark-mode/colors/selection-expected.png b/third_party/blink/web_tests/platform/mac-mac10.15/virtual/dark-mode-increase-text-contrast/dark-mode/colors/selection-expected.png
new file mode 100644
index 0000000..3678f88
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.15/virtual/dark-mode-increase-text-contrast/dark-mode/colors/selection-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.15/virtual/dark-mode-increase-text-contrast/dark-mode/colors/text-on-backgrounds-expected.png b/third_party/blink/web_tests/platform/mac-mac10.15/virtual/dark-mode-increase-text-contrast/dark-mode/colors/text-on-backgrounds-expected.png
new file mode 100644
index 0000000..7e04575a
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.15/virtual/dark-mode-increase-text-contrast/dark-mode/colors/text-on-backgrounds-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.15/virtual/dark-mode-increase-text-contrast/dark-mode/colors/web-theme-expected.png b/third_party/blink/web_tests/platform/mac-mac10.15/virtual/dark-mode-increase-text-contrast/dark-mode/colors/web-theme-expected.png
new file mode 100644
index 0000000..6b7bf79f
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.15/virtual/dark-mode-increase-text-contrast/dark-mode/colors/web-theme-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/dark-mode-default/dark-mode/colors/border-expected.png b/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/dark-mode-default/dark-mode/colors/border-expected.png
new file mode 100644
index 0000000..2e9bc2ee
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/dark-mode-default/dark-mode/colors/border-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/dark-mode-default/dark-mode/colors/selection-expected.png b/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/dark-mode-default/dark-mode/colors/selection-expected.png
new file mode 100644
index 0000000..a931abf
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/dark-mode-default/dark-mode/colors/selection-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/dark-mode-default/dark-mode/colors/text-on-backgrounds-expected.png b/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/dark-mode-default/dark-mode/colors/text-on-backgrounds-expected.png
new file mode 100644
index 0000000..e62aa23
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/dark-mode-default/dark-mode/colors/text-on-backgrounds-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/dark-mode-default/dark-mode/colors/web-theme-expected.png b/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/dark-mode-default/dark-mode/colors/web-theme-expected.png
new file mode 100644
index 0000000..6b7bf79f
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/dark-mode-default/dark-mode/colors/web-theme-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/dark-mode-increase-text-contrast/dark-mode/colors/border-expected.png b/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/dark-mode-increase-text-contrast/dark-mode/colors/border-expected.png
new file mode 100644
index 0000000..2e9bc2ee
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/dark-mode-increase-text-contrast/dark-mode/colors/border-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/dark-mode-increase-text-contrast/dark-mode/colors/selection-expected.png b/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/dark-mode-increase-text-contrast/dark-mode/colors/selection-expected.png
new file mode 100644
index 0000000..3678f88
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/dark-mode-increase-text-contrast/dark-mode/colors/selection-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/dark-mode-increase-text-contrast/dark-mode/colors/text-on-backgrounds-expected.png b/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/dark-mode-increase-text-contrast/dark-mode/colors/text-on-backgrounds-expected.png
new file mode 100644
index 0000000..7e04575a
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/dark-mode-increase-text-contrast/dark-mode/colors/text-on-backgrounds-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/dark-mode-increase-text-contrast/dark-mode/colors/web-theme-expected.png b/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/dark-mode-increase-text-contrast/dark-mode/colors/web-theme-expected.png
new file mode 100644
index 0000000..6b7bf79f
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/dark-mode-increase-text-contrast/dark-mode/colors/web-theme-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac11/virtual/dark-mode-default/dark-mode/colors/border-expected.png b/third_party/blink/web_tests/platform/mac-mac11/virtual/dark-mode-default/dark-mode/colors/border-expected.png
new file mode 100644
index 0000000..2e9bc2ee
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac11/virtual/dark-mode-default/dark-mode/colors/border-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac11/virtual/dark-mode-default/dark-mode/colors/selection-expected.png b/third_party/blink/web_tests/platform/mac-mac11/virtual/dark-mode-default/dark-mode/colors/selection-expected.png
new file mode 100644
index 0000000..a931abf
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac11/virtual/dark-mode-default/dark-mode/colors/selection-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac11/virtual/dark-mode-default/dark-mode/colors/text-on-backgrounds-expected.png b/third_party/blink/web_tests/platform/mac-mac11/virtual/dark-mode-default/dark-mode/colors/text-on-backgrounds-expected.png
new file mode 100644
index 0000000..e62aa23
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac11/virtual/dark-mode-default/dark-mode/colors/text-on-backgrounds-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac11/virtual/dark-mode-default/dark-mode/colors/web-theme-expected.png b/third_party/blink/web_tests/platform/mac-mac11/virtual/dark-mode-default/dark-mode/colors/web-theme-expected.png
new file mode 100644
index 0000000..6b7bf79f
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac11/virtual/dark-mode-default/dark-mode/colors/web-theme-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac11/virtual/dark-mode-increase-text-contrast/dark-mode/colors/border-expected.png b/third_party/blink/web_tests/platform/mac-mac11/virtual/dark-mode-increase-text-contrast/dark-mode/colors/border-expected.png
new file mode 100644
index 0000000..2e9bc2ee
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac11/virtual/dark-mode-increase-text-contrast/dark-mode/colors/border-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac11/virtual/dark-mode-increase-text-contrast/dark-mode/colors/selection-expected.png b/third_party/blink/web_tests/platform/mac-mac11/virtual/dark-mode-increase-text-contrast/dark-mode/colors/selection-expected.png
new file mode 100644
index 0000000..3678f88
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac11/virtual/dark-mode-increase-text-contrast/dark-mode/colors/selection-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac11/virtual/dark-mode-increase-text-contrast/dark-mode/colors/text-on-backgrounds-expected.png b/third_party/blink/web_tests/platform/mac-mac11/virtual/dark-mode-increase-text-contrast/dark-mode/colors/text-on-backgrounds-expected.png
new file mode 100644
index 0000000..7e04575a
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac11/virtual/dark-mode-increase-text-contrast/dark-mode/colors/text-on-backgrounds-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac11/virtual/dark-mode-increase-text-contrast/dark-mode/colors/web-theme-expected.png b/third_party/blink/web_tests/platform/mac-mac11/virtual/dark-mode-increase-text-contrast/dark-mode/colors/web-theme-expected.png
new file mode 100644
index 0000000..6b7bf79f
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac11/virtual/dark-mode-increase-text-contrast/dark-mode/colors/web-theme-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/dark-mode-default/dark-mode/colors/border-expected.png b/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/dark-mode-default/dark-mode/colors/border-expected.png
new file mode 100644
index 0000000..2e9bc2ee
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/dark-mode-default/dark-mode/colors/border-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/dark-mode-default/dark-mode/colors/selection-expected.png b/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/dark-mode-default/dark-mode/colors/selection-expected.png
new file mode 100644
index 0000000..a931abf
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/dark-mode-default/dark-mode/colors/selection-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/dark-mode-default/dark-mode/colors/text-on-backgrounds-expected.png b/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/dark-mode-default/dark-mode/colors/text-on-backgrounds-expected.png
new file mode 100644
index 0000000..e62aa23
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/dark-mode-default/dark-mode/colors/text-on-backgrounds-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/dark-mode-default/dark-mode/colors/web-theme-expected.png b/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/dark-mode-default/dark-mode/colors/web-theme-expected.png
new file mode 100644
index 0000000..6b7bf79f
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/dark-mode-default/dark-mode/colors/web-theme-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/dark-mode-increase-text-contrast/dark-mode/colors/border-expected.png b/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/dark-mode-increase-text-contrast/dark-mode/colors/border-expected.png
new file mode 100644
index 0000000..2e9bc2ee
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/dark-mode-increase-text-contrast/dark-mode/colors/border-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/dark-mode-increase-text-contrast/dark-mode/colors/selection-expected.png b/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/dark-mode-increase-text-contrast/dark-mode/colors/selection-expected.png
new file mode 100644
index 0000000..3678f88
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/dark-mode-increase-text-contrast/dark-mode/colors/selection-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/dark-mode-increase-text-contrast/dark-mode/colors/text-on-backgrounds-expected.png b/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/dark-mode-increase-text-contrast/dark-mode/colors/text-on-backgrounds-expected.png
new file mode 100644
index 0000000..7e04575a
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/dark-mode-increase-text-contrast/dark-mode/colors/text-on-backgrounds-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/dark-mode-increase-text-contrast/dark-mode/colors/web-theme-expected.png b/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/dark-mode-increase-text-contrast/dark-mode/colors/web-theme-expected.png
new file mode 100644
index 0000000..6b7bf79f
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/dark-mode-increase-text-contrast/dark-mode/colors/web-theme-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/dark-mode/colors/border-expected.png b/third_party/blink/web_tests/platform/mac/dark-mode/colors/border-expected.png
new file mode 100644
index 0000000..09462e1
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/dark-mode/colors/border-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/dark-mode-default/dark-mode/colors/border-expected.png b/third_party/blink/web_tests/platform/mac/virtual/dark-mode-default/dark-mode/colors/border-expected.png
new file mode 100644
index 0000000..2e9bc2ee
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/virtual/dark-mode-default/dark-mode/colors/border-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/dark-mode-default/dark-mode/colors/selection-expected.png b/third_party/blink/web_tests/platform/mac/virtual/dark-mode-default/dark-mode/colors/selection-expected.png
index 6a473e1..a931abf 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/dark-mode-default/dark-mode/colors/selection-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/dark-mode-default/dark-mode/colors/selection-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/dark-mode-default/dark-mode/colors/text-on-backgrounds-expected.png b/third_party/blink/web_tests/platform/mac/virtual/dark-mode-default/dark-mode/colors/text-on-backgrounds-expected.png
new file mode 100644
index 0000000..e62aa23
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/virtual/dark-mode-default/dark-mode/colors/text-on-backgrounds-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/dark-mode-increase-text-contrast/dark-mode/colors/border-expected.png b/third_party/blink/web_tests/platform/mac/virtual/dark-mode-increase-text-contrast/dark-mode/colors/border-expected.png
new file mode 100644
index 0000000..2e9bc2ee
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/virtual/dark-mode-increase-text-contrast/dark-mode/colors/border-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/dark-mode-increase-text-contrast/dark-mode/colors/selection-expected.png b/third_party/blink/web_tests/platform/mac/virtual/dark-mode-increase-text-contrast/dark-mode/colors/selection-expected.png
index 00bab45..3678f88 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/dark-mode-increase-text-contrast/dark-mode/colors/selection-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/dark-mode-increase-text-contrast/dark-mode/colors/selection-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/dark-mode-increase-text-contrast/dark-mode/colors/text-on-backgrounds-expected.png b/third_party/blink/web_tests/platform/mac/virtual/dark-mode-increase-text-contrast/dark-mode/colors/text-on-backgrounds-expected.png
new file mode 100644
index 0000000..7e04575a
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/virtual/dark-mode-increase-text-contrast/dark-mode/colors/text-on-backgrounds-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/dark-mode/colors/border-expected.png b/third_party/blink/web_tests/platform/win/dark-mode/colors/border-expected.png
new file mode 100644
index 0000000..4bbf6f6
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/dark-mode/colors/border-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/dark-mode-default/dark-mode/colors/border-expected.png b/third_party/blink/web_tests/platform/win/virtual/dark-mode-default/dark-mode/colors/border-expected.png
new file mode 100644
index 0000000..5e9a5f0
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/virtual/dark-mode-default/dark-mode/colors/border-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/dark-mode-default/dark-mode/colors/select-popup-expected.png b/third_party/blink/web_tests/platform/win/virtual/dark-mode-default/dark-mode/colors/select-popup-expected.png
index dd9929d..310db56 100644
--- a/third_party/blink/web_tests/platform/win/virtual/dark-mode-default/dark-mode/colors/select-popup-expected.png
+++ b/third_party/blink/web_tests/platform/win/virtual/dark-mode-default/dark-mode/colors/select-popup-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/dark-mode-default/dark-mode/colors/selection-expected.png b/third_party/blink/web_tests/platform/win/virtual/dark-mode-default/dark-mode/colors/selection-expected.png
index ef75e312..77442b4f 100644
--- a/third_party/blink/web_tests/platform/win/virtual/dark-mode-default/dark-mode/colors/selection-expected.png
+++ b/third_party/blink/web_tests/platform/win/virtual/dark-mode-default/dark-mode/colors/selection-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/dark-mode-default/dark-mode/colors/text-on-backgrounds-expected.png b/third_party/blink/web_tests/platform/win/virtual/dark-mode-default/dark-mode/colors/text-on-backgrounds-expected.png
new file mode 100644
index 0000000..e62aa23
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/virtual/dark-mode-default/dark-mode/colors/text-on-backgrounds-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/dark-mode-increase-text-contrast/dark-mode/colors/border-expected.png b/third_party/blink/web_tests/platform/win/virtual/dark-mode-increase-text-contrast/dark-mode/colors/border-expected.png
new file mode 100644
index 0000000..5e9a5f0
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/virtual/dark-mode-increase-text-contrast/dark-mode/colors/border-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/dark-mode-increase-text-contrast/dark-mode/colors/select-popup-expected.png b/third_party/blink/web_tests/platform/win/virtual/dark-mode-increase-text-contrast/dark-mode/colors/select-popup-expected.png
index dd9929d..310db56 100644
--- a/third_party/blink/web_tests/platform/win/virtual/dark-mode-increase-text-contrast/dark-mode/colors/select-popup-expected.png
+++ b/third_party/blink/web_tests/platform/win/virtual/dark-mode-increase-text-contrast/dark-mode/colors/select-popup-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/dark-mode-increase-text-contrast/dark-mode/colors/selection-expected.png b/third_party/blink/web_tests/platform/win/virtual/dark-mode-increase-text-contrast/dark-mode/colors/selection-expected.png
index 142754c..ad31d17 100644
--- a/third_party/blink/web_tests/platform/win/virtual/dark-mode-increase-text-contrast/dark-mode/colors/selection-expected.png
+++ b/third_party/blink/web_tests/platform/win/virtual/dark-mode-increase-text-contrast/dark-mode/colors/selection-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/dark-mode-increase-text-contrast/dark-mode/colors/text-on-backgrounds-expected.png b/third_party/blink/web_tests/platform/win/virtual/dark-mode-increase-text-contrast/dark-mode/colors/text-on-backgrounds-expected.png
new file mode 100644
index 0000000..7e04575a
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/virtual/dark-mode-increase-text-contrast/dark-mode/colors/text-on-backgrounds-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win10/virtual/dark-mode-default/dark-mode/colors/border-expected.png b/third_party/blink/web_tests/platform/win10/virtual/dark-mode-default/dark-mode/colors/border-expected.png
new file mode 100644
index 0000000..5e9a5f0
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win10/virtual/dark-mode-default/dark-mode/colors/border-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win10/virtual/dark-mode-default/dark-mode/colors/select-popup-expected.png b/third_party/blink/web_tests/platform/win10/virtual/dark-mode-default/dark-mode/colors/select-popup-expected.png
new file mode 100644
index 0000000..310db56
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win10/virtual/dark-mode-default/dark-mode/colors/select-popup-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win10/virtual/dark-mode-default/dark-mode/colors/selection-expected.png b/third_party/blink/web_tests/platform/win10/virtual/dark-mode-default/dark-mode/colors/selection-expected.png
new file mode 100644
index 0000000..77442b4f
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win10/virtual/dark-mode-default/dark-mode/colors/selection-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win10/virtual/dark-mode-default/dark-mode/colors/text-on-backgrounds-expected.png b/third_party/blink/web_tests/platform/win10/virtual/dark-mode-default/dark-mode/colors/text-on-backgrounds-expected.png
new file mode 100644
index 0000000..e62aa23
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win10/virtual/dark-mode-default/dark-mode/colors/text-on-backgrounds-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win10/virtual/dark-mode-default/dark-mode/colors/web-theme-expected.png b/third_party/blink/web_tests/platform/win10/virtual/dark-mode-default/dark-mode/colors/web-theme-expected.png
new file mode 100644
index 0000000..592c4ea4
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win10/virtual/dark-mode-default/dark-mode/colors/web-theme-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win10/virtual/dark-mode-increase-text-contrast/dark-mode/colors/border-expected.png b/third_party/blink/web_tests/platform/win10/virtual/dark-mode-increase-text-contrast/dark-mode/colors/border-expected.png
new file mode 100644
index 0000000..5e9a5f0
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win10/virtual/dark-mode-increase-text-contrast/dark-mode/colors/border-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win10/virtual/dark-mode-increase-text-contrast/dark-mode/colors/select-popup-expected.png b/third_party/blink/web_tests/platform/win10/virtual/dark-mode-increase-text-contrast/dark-mode/colors/select-popup-expected.png
new file mode 100644
index 0000000..310db56
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win10/virtual/dark-mode-increase-text-contrast/dark-mode/colors/select-popup-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win10/virtual/dark-mode-increase-text-contrast/dark-mode/colors/selection-expected.png b/third_party/blink/web_tests/platform/win10/virtual/dark-mode-increase-text-contrast/dark-mode/colors/selection-expected.png
new file mode 100644
index 0000000..ad31d17
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win10/virtual/dark-mode-increase-text-contrast/dark-mode/colors/selection-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win10/virtual/dark-mode-increase-text-contrast/dark-mode/colors/text-on-backgrounds-expected.png b/third_party/blink/web_tests/platform/win10/virtual/dark-mode-increase-text-contrast/dark-mode/colors/text-on-backgrounds-expected.png
new file mode 100644
index 0000000..7e04575a
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win10/virtual/dark-mode-increase-text-contrast/dark-mode/colors/text-on-backgrounds-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win10/virtual/dark-mode-increase-text-contrast/dark-mode/colors/web-theme-expected.png b/third_party/blink/web_tests/platform/win10/virtual/dark-mode-increase-text-contrast/dark-mode/colors/web-theme-expected.png
new file mode 100644
index 0000000..592c4ea4
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win10/virtual/dark-mode-increase-text-contrast/dark-mode/colors/web-theme-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/wpt_internal/attribution-reporting/resources/helpers.js b/third_party/blink/web_tests/wpt_internal/attribution-reporting/resources/helpers.js
index 5437ec7..660e2d99 100644
--- a/third_party/blink/web_tests/wpt_internal/attribution-reporting/resources/helpers.js
+++ b/third_party/blink/web_tests/wpt_internal/attribution-reporting/resources/helpers.js
@@ -49,7 +49,7 @@
  * Method that polls a particular URL every interval for reports. Once reports
  * are received, returns the payload as promise.
  */
-const pollAttributionReports = async (url, interval) => {
+const pollAttributionReports = async (url, interval = 100) => {
   const resp = await fetch(url);
   const payload = await resp.json();
   if (payload.reports.length === 0) {
diff --git a/third_party/blink/web_tests/wpt_internal/attribution-reporting/simple-aggregatable-report-test.sub.https.html b/third_party/blink/web_tests/wpt_internal/attribution-reporting/simple-aggregatable-report-test.sub.https.html
index 358d321..f02e4f1 100644
--- a/third_party/blink/web_tests/wpt_internal/attribution-reporting/simple-aggregatable-report-test.sub.https.html
+++ b/third_party/blink/web_tests/wpt_internal/attribution-reporting/simple-aggregatable-report-test.sub.https.html
@@ -5,7 +5,6 @@
 <script src="resources/helpers.js"></script>
 <script>
 promise_test(async t => {
-  const interval = 100;
   const source = {
     source_event_id: '9153495207648170476',
     destination: `https://{{host}}`,
@@ -32,11 +31,8 @@
   };
   await resetAggregatableReports();
   registerAttributionSrc('Attribution-Reporting-Register-Source', source);
-  // Adds delay to reduce chance of race condition between source registration and
-  await delay(interval);
-  // trigger registration.
   registerAttributionSrc('Attribution-Reporting-Register-Trigger', trigger);
-  const payload = await pollAggregatableReports(interval);
+  const payload = await pollAggregatableReports();
   assert_equals(payload.reports.length, 1);
   const report = JSON.parse(payload.reports[0].body);
   const headers = payload.reports[0].headers;
diff --git a/third_party/blink/web_tests/wpt_internal/attribution-reporting/simple-event-level-report-test.sub.https.html b/third_party/blink/web_tests/wpt_internal/attribution-reporting/simple-event-level-report-test.sub.https.html
index 60052daa..062ec59 100644
--- a/third_party/blink/web_tests/wpt_internal/attribution-reporting/simple-event-level-report-test.sub.https.html
+++ b/third_party/blink/web_tests/wpt_internal/attribution-reporting/simple-event-level-report-test.sub.https.html
@@ -5,7 +5,6 @@
 <script src="resources/helpers.js"></script>
 <script>
 promise_test(async t => {
-  const interval = 100;
   const sourceEvent = {
     source_event_id: '9153495207648170476',
     destination: `https://{{host}}`,
@@ -13,12 +12,8 @@
   const trigger = {event_trigger_data: [{'trigger_data': '2'}]};
   await resetEventLevelReports();
   registerAttributionSrc('Attribution-Reporting-Register-Source', sourceEvent);
-  // Adds delay to reduce chance of race condition between source registration and
-  // trigger registration.
-  await delay(interval);
-  registerAttributionSrc(
-      'Attribution-Reporting-Register-Trigger', trigger);
-  const payload = await pollEventLevelReports(interval);
+  registerAttributionSrc('Attribution-Reporting-Register-Trigger', trigger);
+  const payload = await pollEventLevelReports();
   assert_equals(payload.reports.length, 1);
   const report = JSON.parse(payload.reports[0].body);
   const headers = payload.reports[0].headers;
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/disallowed-navigations.https.html b/third_party/blink/web_tests/wpt_internal/fenced_frame/disallowed-navigations.https.html
index 581b494b..034765f 100644
--- a/third_party/blink/web_tests/wpt_internal/fenced_frame/disallowed-navigations.https.html
+++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/disallowed-navigations.https.html
@@ -45,6 +45,17 @@
   `;
 }
 
+// These are used in tests that rely on URLs containing dangling markup. See
+// https://github.com/whatwg/fetch/pull/519.
+const kDanglingMarkupSubstrings = [
+  "blo\nck<ed",
+  "blo\rck<ed",
+  "blo\tck<ed",
+  "blo<ck\ned",
+  "blo<ck\red",
+  "blo<ck\ted",
+];
+
 // These are just baseline tests asserting that this test's machinery to load
 // blob:, data:, and javascript: URLs work properly in contexts where they are
 // expected to.
@@ -72,17 +83,18 @@
   });
 }, "iframe javascript: URL");
 
+function getTimeoutPromise(t) {
+  return new Promise(resolve =>
+      t.step_timeout(() => resolve("NOT LOADED"), 2000));
+}
+
 // The following tests ensure that an embedder cannot navigate a fenced frame
 // (with different modes) to:
 //   - data: URLs
 //   - blob: URLs
 //   - javascript: URLs
 //   - http: URLs
-function getTimeoutPromise(t) {
-  return new Promise(resolve =>
-      t.step_timeout(() => resolve("NOT LOADED"), 2000));
-}
-
+//   - https: URLs with dangling markup
 for (const mode of ['opaque-ads', 'default']) {
 
   promise_test(async t => {
@@ -126,6 +138,19 @@
     assert_equals(result, "NOT LOADED");
   }, `fenced frame mode=${mode} http: URL`);
 
+  // These tests assert that fenced frames cannot be navigated to HTTPs URLs
+  // with dangling markup.
+  for (substring of kDanglingMarkupSubstrings) {
+    promise_test(async t => {
+      const key = token();
+      let url_string = generateURL("resources/embeddee.html?blocked", [key]).toString();
+      url_string = url_string.replace("blocked", substring);
+      const fencedframe = attachFencedFrame(url_string, /*mode=*/mode);
+      const loaded_promise = nextValueFromServer(key);
+      const result = await Promise.any([loaded_promise, getTimeoutPromise(t)]);
+      assert_equals(result, "NOT LOADED");
+    }, `fenced frame mode=${mode} dangling-markup URL with '${substring}'`);
+  }
 } // end for.
 
 // The following tests ensure that an embedder cannot navigate a
@@ -134,6 +159,7 @@
 //   - blob: URL
 //   - javascript: URL
 //   - http: URL
+//   - https: URL with dangling markup
 promise_test(async t => {
   const key = token();
   const urn = await generateURN(`data:text/html,${createLocalSource(key)}`);
@@ -175,6 +201,36 @@
   const result = await Promise.any([loaded_promise, getTimeoutPromise(t)]);
   assert_equals(result, "NOT LOADED");
 }, "fenced frame opaque URN => http: URL");
+
+// These tests assert that fenced frames cannot be navigated to a urn:uuid URL
+// that represents an HTTPS URLs with dangling markup.
+for (substring of kDanglingMarkupSubstrings) {
+  promise_test(async t => {
+    const key = token();
+
+    // Copied from from `generateURN()`, since we have to modify the final URL
+    // that goes into `selectURL`.
+    try {
+      await sharedStorage.worklet.addModule(
+        "/wpt_internal/shared_storage/resources/simple-module.js");
+    } catch (e) {
+      // See documentation in `generateURN()`.
+    }
+
+    let url_string = generateURL("resources/report-url.html?blocked", [key]).toString();
+    url_string = url_string.replace("blocked", substring);
+
+    const urn = await sharedStorage.selectURL(
+      "test-url-selection-operation", [url_string], {data: {'mockResult': 0}}
+    );
+
+    const fencedframe = attachFencedFrame(urn, /*mode=*/'opaque-ads');
+    const loaded_promise = nextValueFromServer(key);
+    const result = await Promise.any([loaded_promise, getTimeoutPromise(t)]);
+    assert_equals(result, "NOT LOADED");
+  }, `fenced frame opaque URN => https: URL with dangling markup '${substring}'`);
+}
+
 </script>
 
 </body>
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/report-url.html b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/report-url.html
new file mode 100644
index 0000000..e0b7d09
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/report-url.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<script src="utils.js"></script>
+<title>A page embedded as a fenced frame that reports the document URL</title>
+<script>
+const [uuid] = parseKeylist();
+writeValueToServer(uuid, location.href);
+</script>
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/report-url.html.headers b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/report-url.html.headers
new file mode 100644
index 0000000..6247f6d
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/report-url.html.headers
@@ -0,0 +1 @@
+Supports-Loading-Mode: fenced-frame
\ No newline at end of file
diff --git a/third_party/freetype/README.chromium b/third_party/freetype/README.chromium
index 7273b64..4cc16d6 100644
--- a/third_party/freetype/README.chromium
+++ b/third_party/freetype/README.chromium
@@ -1,7 +1,7 @@
 Name: FreeType
 URL: http://www.freetype.org/
-Version: VER-2-12-1-21-g8bb7722a5
-Revision: 8bb7722a5315fe9f176821242fd453fadb3004da
+Version: VER-2-12-1-22-gd6fc8c6ba
+Revision: d6fc8c6ba02b3c0e4260b5d309e6a6a0fac9541c
 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/leveldatabase/env_chromium.cc b/third_party/leveldatabase/env_chromium.cc
index dd491bc..5784ede 100644
--- a/third_party/leveldatabase/env_chromium.cc
+++ b/third_party/leveldatabase/env_chromium.cc
@@ -25,7 +25,6 @@
 #include "base/system/sys_info.h"
 #include "base/task/task_traits.h"
 #include "base/task/thread_pool.h"
-#include "base/threading/scoped_blocking_call.h"
 #include "base/time/time.h"
 #include "base/time/time_override.h"
 #include "base/trace_event/memory_dump_manager.h"
@@ -37,6 +36,7 @@
 #include "components/services/storage/public/cpp/filesystem/filesystem_proxy.h"
 #include "third_party/leveldatabase/chromium_logger.h"
 #include "third_party/leveldatabase/leveldb_chrome.h"
+#include "third_party/leveldatabase/port/port_chromium.h"
 #include "third_party/leveldatabase/src/include/leveldb/options.h"
 #include "third_party/re2/src/re2/re2.h"
 
@@ -1111,7 +1111,7 @@
 
   ~TrackedDBImpl() override {
     tracker_->DatabaseDestroyed(this, shared_read_cache_use_);
-    base::ScopedAllowBaseSyncPrimitives allow_base_sync_primitives;
+    leveldb::port::ScopedAllowWait scoped_allow_wait;
     db_.reset();
   }
 
diff --git a/third_party/leveldatabase/port/port_chromium.h b/third_party/leveldatabase/port/port_chromium.h
index 9dcf30b..a0940b0 100644
--- a/third_party/leveldatabase/port/port_chromium.h
+++ b/third_party/leveldatabase/port/port_chromium.h
@@ -15,6 +15,7 @@
 #include "base/synchronization/condition_variable.h"
 #include "base/synchronization/lock.h"
 #include "base/thread_annotations.h"
+#include "base/threading/thread_restrictions.h"
 
 namespace leveldb {
 namespace port {
@@ -36,7 +37,7 @@
   base::Lock lock_;
 };
 
-// Thinly wraps std::condition_variable.
+// Thinly wraps base::ConditionVariable.
 class CondVar {
  public:
   explicit CondVar(Mutex* mu) : cv_(&mu->lock_) { DCHECK(mu); }
@@ -50,9 +51,14 @@
   void SignalAll() { cv_.Broadcast(); }
 
  private:
+  // The ConditionVariable is used to coordinate a batch write for efficiency.
+  // This is an allowed use of base-sync-primitives.
   base::ConditionVariable cv_;
 };
 
+// Thinly wraps base::ScopedAllowBaseSyncPrimitives.
+class ScopedAllowWait : base::ScopedAllowBaseSyncPrimitives {};
+
 bool Snappy_Compress(const char* input, size_t input_length,
                      std::string* output);
 bool Snappy_GetUncompressedLength(const char* input, size_t length,
diff --git a/tools/ipc_fuzzer/ipc_fuzzer.gni b/tools/ipc_fuzzer/ipc_fuzzer.gni
index f3619e3..b99d37f3 100644
--- a/tools/ipc_fuzzer/ipc_fuzzer.gni
+++ b/tools/ipc_fuzzer/ipc_fuzzer.gni
@@ -11,7 +11,8 @@
   # Build IPC fuzzer by default if it's a supported configuration. For
   # sanitizer builds, this needs to be enabled explicitly as they can be slow
   # (especially MSan).
-  enable_ipc_fuzzer =
-      is_clang && !is_component_build && !is_official_build && !is_chromecast &&
-      !using_sanitizer && (is_linux || is_chromeos || is_mac || is_win) && !use_ozone
+  enable_ipc_fuzzer = is_clang && !is_component_build && !is_official_build &&
+                      !using_sanitizer &&
+                      ((is_linux && !is_castos) || is_chromeos || is_mac ||
+                       is_win) && !use_ozone
 }
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 2862da78..82998a2 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -34767,6 +34767,8 @@
   <int value="1669" label="ENTERPRISE_REMOTEAPPS_ADDFOLDER"/>
   <int value="1670" label="ENTERPRISE_REMOTEAPPS_ADDAPP"/>
   <int value="1671" label="ENTERPRISE_REMOTEAPPS_DELETEAPP"/>
+  <int value="1672" label="ENTERPRISEREPORTINGPRIVATE_GETAVINFO"/>
+  <int value="1673" label="ENTERPRISEREPORTINGPRIVATE_GETHOTFIXES"/>
 </enum>
 
 <enum name="ExtensionIconState">
@@ -49160,6 +49162,11 @@
   <int value="12" label="Load image metadata"/>
 </enum>
 
+<enum name="ImageHasMultipleGeneratorClientIds">
+  <int value="0" label="Image decode is requested by at least one client"/>
+  <int value="1" label="Image decode is requested by more than one client"/>
+</enum>
+
 <enum name="ImageSelectionOutcome">
   <int value="0" label="Image node was the topmost node."/>
   <int value="1" label="Image node was below topmost node"/>
@@ -55108,6 +55115,7 @@
   <int value="-1961071650" label="InterestFeedV2Autoplay:disabled"/>
   <int value="-1961062505" label="VrBrowsingInCustomTab:disabled"/>
   <int value="-1960567385" label="KeepPrefetchedContentSuggestions:enabled"/>
+  <int value="-1959602781" label="ShimlessRMADisableDarkMode:disabled"/>
   <int value="-1959563554" label="ChromeOSAccountManager:enabled"/>
   <int value="-1958364669" label="QueryTilesSegmentation:enabled"/>
   <int value="-1958315092" label="EnableGamepadButtonAxisEvents:disabled"/>
@@ -57612,6 +57620,7 @@
   <int value="-351127770" label="enable-offline-pages-as-bookmarks"/>
   <int value="-350336634"
       label="ExperimentalAccessibilityDictationExtension:enabled"/>
+  <int value="-349505266" label="ShimlessRMADisableDarkMode:enabled"/>
   <int value="-349437334" label="UseDdljsonApi:disabled"/>
   <int value="-349380607" label="AndroidNightMode:disabled"/>
   <int value="-349057743" label="extensions-on-chrome-urls"/>
@@ -75694,6 +75703,18 @@
   <int value="5" label="Keyboard brightness slider"/>
 </enum>
 
+<enum name="PersonalizationKeyboardBacklightColor">
+  <int value="0" label="kWallpaper"/>
+  <int value="1" label="kWhite"/>
+  <int value="2" label="kRed"/>
+  <int value="3" label="kYellow"/>
+  <int value="4" label="kGreen"/>
+  <int value="5" label="kBlue"/>
+  <int value="6" label="kIndigo"/>
+  <int value="7" label="kPurple"/>
+  <int value="100" label="kRainbow"/>
+</enum>
+
 <enum name="PersonalizationPath">
   <int value="0" label="Screensaver"/>
   <int value="1" label="Screensaver Albums"/>
diff --git a/tools/metrics/histograms/metadata/android/histograms.xml b/tools/metrics/histograms/metadata/android/histograms.xml
index ed09185..80c6a1e7 100644
--- a/tools/metrics/histograms/metadata/android/histograms.xml
+++ b/tools/metrics/histograms/metadata/android/histograms.xml
@@ -1831,7 +1831,7 @@
 </histogram>
 
 <histogram base="true" name="Android.IsolatedSplits.ClassLoaderReplaced"
-    enum="BooleanYesNo" expires_after="2022-08-10">
+    enum="BooleanYesNo" expires_after="2023-06-26">
 <!-- Name completed by histogram_suffixes name="AndroidFeatureModuleName" -->
 
   <owner>cduvall@chromium.org</owner>
@@ -1843,7 +1843,7 @@
 </histogram>
 
 <histogram base="true" name="Android.IsolatedSplits.ContextCreateTime"
-    units="ms" expires_after="2022-06-26">
+    units="ms" expires_after="2023-06-26">
 <!-- Name completed by histogram_suffixes name="AndroidFeatureModuleName" -->
 
   <owner>cduvall@chromium.org</owner>
@@ -1855,7 +1855,7 @@
 </histogram>
 
 <histogram base="true" name="Android.IsolatedSplits.PreloadWaitTime" units="ms"
-    expires_after="2022-08-06">
+    expires_after="2023-06-26">
 <!-- Name completed by histogram_suffixes name="AndroidFeatureModuleName" -->
 
   <owner>cduvall@chromium.org</owner>
@@ -4371,13 +4371,14 @@
 </histogram>
 
 <histogram name="Android.WebView.SingleOrMultiProcess"
-    enum="AndroidWebViewSingleOrMultiProcess" expires_after="2022-07-22">
+    enum="AndroidWebViewSingleOrMultiProcess" expires_after="never">
   <owner>alexmitra@chromium.org</owner>
   <owner>nator@chromium.org</owner>
   <owner>src/android_webview/OWNERS</owner>
   <summary>
     Records whether WebView is being run in a single process or multi-process.
-    This is recorded each time logs are uploaded.
+    This is recorded each time logs are uploaded. This is used as a dashboard
+    filter.
   </summary>
 </histogram>
 
diff --git a/tools/metrics/histograms/metadata/ash/histograms.xml b/tools/metrics/histograms/metadata/ash/histograms.xml
index 347efd0..0558398 100644
--- a/tools/metrics/histograms/metadata/ash/histograms.xml
+++ b/tools/metrics/histograms/metadata/ash/histograms.xml
@@ -3387,6 +3387,16 @@
   </summary>
 </histogram>
 
+<histogram name="Ash.Personalization.KeyboardBacklight.Color"
+    enum="PersonalizationKeyboardBacklightColor" expires_after="2023-06-15">
+  <owner>jasontt@chromium.org</owner>
+  <owner>assistive-eng@google.com</owner>
+  <summary>
+    Emitted when a user selects a keyboard backlight color in personalization
+    hub.
+  </summary>
+</histogram>
+
 <histogram name="Ash.Personalization.Path" enum="PersonalizationPath"
     expires_after="2023-04-15">
   <owner>jasontt@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/blink/histograms.xml b/tools/metrics/histograms/metadata/blink/histograms.xml
index fdb5993b..f5c1dc6 100644
--- a/tools/metrics/histograms/metadata/blink/histograms.xml
+++ b/tools/metrics/histograms/metadata/blink/histograms.xml
@@ -1471,6 +1471,22 @@
   </summary>
 </histogram>
 
+<histogram name="Blink.ImageDecoders.ImageHasMultipleGeneratorClientIds"
+    enum="ImageHasMultipleGeneratorClientIds" expires_after="2022-09-30">
+  <owner>vmpstr@chromium.org</owner>
+  <owner>khushalsagar@chromium.org</owner>
+  <summary>
+    This histogram records whether an image has been decoded by a single client
+    or by multiple clients during decoding. For an image to be decoded, it is
+    always requested by a client with a client_id. If an image has been
+    requested by multiple clients, it would be decoded more than once. The
+    histogram value is recorded at most two times per image (once per bucket).
+    There will be overlap for two buckets, but we can get the the number of an
+    image decodeded by only one client with the difference between two buckets.
+    This helps us to know how often images get duplicated decoding in real life.
+  </summary>
+</histogram>
+
 <histogram name="Blink.ImageDecoders.IncrementalDecodeNeeded"
     enum="IncrementalDecodeNeeded" expires_after="2022-09-15">
   <owner>andrescj@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/gpu/histograms.xml b/tools/metrics/histograms/metadata/gpu/histograms.xml
index 782fe88..420dbce 100644
--- a/tools/metrics/histograms/metadata/gpu/histograms.xml
+++ b/tools/metrics/histograms/metadata/gpu/histograms.xml
@@ -537,13 +537,19 @@
   </summary>
 </histogram>
 
-<histogram name="GPU.D3D12HighestShaderModel" enum="D3DShaderModel"
+<histogram name="GPU.D3D12HighestShaderModel2" enum="D3DShaderModel"
     expires_after="2022-12-11">
   <owner>magchen@chromium.org</owner>
   <owner>zmo@chromium.org</owner>
+  <owner>amaiorano@google.com</owner>
   <summary>
     The maximum supported D3D shader model version on a D3D12 device. It is
-    recorded in the browser process 120 seconds after the browser launch.
+    recorded in the browser process 120 seconds after the browser launch. Note
+    that the &quot;2&quot; suffix was added when a fix was made in how this stat
+    is collected: the previous unsuffixed version would store
+    &quot;unknown/unsupported&quot; on systems that supported shader model 5.1
+    to 6.5, but were unaware of 6.6. The suffixed version correctly stores the
+    highest supported shader model.
   </summary>
 </histogram>
 
diff --git a/tools/perf/benchmarks/rendering.py b/tools/perf/benchmarks/rendering.py
index 7ac8648..75bd5ca6 100644
--- a/tools/perf/benchmarks/rendering.py
+++ b/tools/perf/benchmarks/rendering.py
@@ -22,6 +22,9 @@
     'Event.Latency.ScrollUpdate.Touch.TimeToScrollUpdateSwapBegin4',
     'Event.Latency.ScrollBegin.Wheel.TimeToScrollUpdateSwapBegin4',
     'Event.Latency.ScrollUpdate.Wheel.TimeToScrollUpdateSwapBegin4',
+    'Graphics.Smoothness.Checkerboarding.AllAnimations',
+    'Graphics.Smoothness.Checkerboarding.AllInteractions',
+    'Graphics.Smoothness.Checkerboarding.AllSequences',
     'Graphics.Smoothness.Checkerboarding.TouchScroll',
     'Graphics.Smoothness.Checkerboarding.WheelScroll',
     'Graphics.Smoothness.Jank.AllAnimations',
diff --git a/tools/v8_context_snapshot/v8_context_snapshot.gni b/tools/v8_context_snapshot/v8_context_snapshot.gni
index f3b1b78..8ed4482 100644
--- a/tools/v8_context_snapshot/v8_context_snapshot.gni
+++ b/tools/v8_context_snapshot/v8_context_snapshot.gni
@@ -16,7 +16,7 @@
   # TODO(crbug.com/764576): Enable the feature on more environments.
   # Disable in mac and win cross builds since building Blink twice is slow.
   use_v8_context_snapshot =
-      !is_chromeos && !is_android && !is_chromecast && !is_fuchsia &&
+      !is_chromeos && !is_android && !is_castos && !is_fuchsia &&
       !(host_os == "mac" && current_cpu == "x86") &&
       # Android may build for both 64 bit and 32bit. When this happens, the
       # v8_target_cpu will not equal the target_cpu (for example,
diff --git a/ui/accessibility/BUILD.gn b/ui/accessibility/BUILD.gn
index a98305b4..09ea1ca 100644
--- a/ui/accessibility/BUILD.gn
+++ b/ui/accessibility/BUILD.gn
@@ -218,6 +218,8 @@
 static_library("test_support") {
   testonly = true
   sources = [
+    "platform/test_ax_tree_update.cc",
+    "platform/test_ax_tree_update.h",
     "test_ax_node_helper.cc",
     "test_ax_node_helper.h",
     "tree_generator.cc",
diff --git a/ui/accessibility/platform/ax_platform_node_base_unittest.cc b/ui/accessibility/platform/ax_platform_node_base_unittest.cc
index 4072a27b..1d094de 100644
--- a/ui/accessibility/platform/ax_platform_node_base_unittest.cc
+++ b/ui/accessibility/platform/ax_platform_node_base_unittest.cc
@@ -7,22 +7,14 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/accessibility/platform/ax_platform_node_unittest.h"
 #include "ui/accessibility/platform/test_ax_node_wrapper.h"
+#include "ui/accessibility/platform/test_ax_tree_update.h"
+
+using ax::mojom::Role;
+using ax::mojom::State;
 
 namespace ui {
 namespace {
 
-void MakeStaticText(AXNodeData* node, int id, const std::string& text) {
-  node->id = id;
-  node->role = ax::mojom::Role::kStaticText;
-  node->SetName(text);
-}
-
-void MakeGroup(AXNodeData* node, int id, std::vector<int> child_ids) {
-  node->id = id;
-  node->role = ax::mojom::Role::kGroup;
-  node->child_ids = child_ids;
-}
-
 void SetIsInvisible(AXTree* tree, int id, bool invisible) {
   AXTreeUpdate update;
   update.nodes.resize(1);
@@ -45,33 +37,18 @@
 }  // namespace
 
 TEST_F(AXPlatformNodeTest, GetHypertext) {
-  AXTreeUpdate update;
-
   // RootWebArea #1
   // ++++StaticText "text1" #2
   // ++++StaticText "text2" #3
   // ++++StaticText "text3" #4
-
-  update.root_id = 1;
-  update.nodes.resize(4);
-
-  update.nodes[0].id = 1;
-  update.nodes[0].role = ax::mojom::Role::kRootWebArea;
-  update.nodes[0].child_ids = {2, 3, 4};
-
-  MakeStaticText(&update.nodes[1], 2, "text1");
-  MakeStaticText(&update.nodes[2], 3, "text2");
-  MakeStaticText(&update.nodes[3], 4, "text3");
-
-  Init(update);
-  AXTree& tree = *GetTree();
+  AXTree* tree = Init({Role::kRootWebArea, {{"text1"}, {"text2"}, {"text3"}}});
 
   // Set an AXMode on the AXPlatformNode as some platforms (auralinux) use it to
   // determine if it should enable accessibility.
   testing::ScopedAxModeSetter ax_mode_setter(kAXModeComplete);
 
   AXPlatformNodeBase* root = static_cast<AXPlatformNodeBase*>(
-      TestAXNodeWrapper::GetOrCreate(&tree, tree.root())->ax_platform_node());
+      TestAXNodeWrapper::GetOrCreate(tree, tree->root())->ax_platform_node());
 
   EXPECT_EQ(root->GetHypertext(), u"text1text2text3");
 
@@ -89,8 +66,6 @@
 }
 
 TEST_F(AXPlatformNodeTest, GetHypertextIgnoredContainerSiblings) {
-  AXTreeUpdate update;
-
   // RootWebArea #1
   // ++genericContainer IGNORED #2
   // ++++StaticText "text1" #3
@@ -98,41 +73,18 @@
   // ++++StaticText "text2" #5
   // ++genericContainer IGNORED #6
   // ++++StaticText "text3" #7
+  AXTree* tree =
+      Init({Role::kRootWebArea,
+            {{Role::kGenericContainer, State::kIgnored, {{"text1"}}},
+             {Role::kGenericContainer, State::kIgnored, {{"text2"}}},
+             {Role::kGenericContainer, State::kIgnored, {{"text3"}}}}});
 
-  update.root_id = 1;
-  update.nodes.resize(7);
-
-  update.nodes[0].id = 1;
-  update.nodes[0].role = ax::mojom::Role::kRootWebArea;
-  update.nodes[0].child_ids = {2, 4, 6};
-
-  update.nodes[1].id = 2;
-  update.nodes[1].child_ids = {3};
-  update.nodes[1].role = ax::mojom::Role::kGenericContainer;
-  update.nodes[1].AddState(ax::mojom::State::kIgnored);
-  MakeStaticText(&update.nodes[2], 3, "text1");
-
-  update.nodes[3].id = 4;
-  update.nodes[3].child_ids = {5};
-  update.nodes[3].role = ax::mojom::Role::kGenericContainer;
-  update.nodes[3].AddState(ax::mojom::State::kIgnored);
-  MakeStaticText(&update.nodes[4], 5, "text2");
-
-  update.nodes[5].id = 6;
-  update.nodes[5].child_ids = {7};
-  update.nodes[5].role = ax::mojom::Role::kGenericContainer;
-  update.nodes[5].AddState(ax::mojom::State::kIgnored);
-  MakeStaticText(&update.nodes[6], 7, "text3");
-
-  Init(update);
-
-  AXTree& tree = *GetTree();
   // Set an AXMode on the AXPlatformNode as some platforms (auralinux) use it to
   // determine if it should enable accessibility.
   ui::testing::ScopedAxModeSetter ax_mode_setter(kAXModeComplete);
 
   AXPlatformNodeBase* root = static_cast<AXPlatformNodeBase*>(
-      TestAXNodeWrapper::GetOrCreate(&tree, tree.root())->ax_platform_node());
+      TestAXNodeWrapper::GetOrCreate(tree, tree->root())->ax_platform_node());
 
   EXPECT_EQ(root->GetHypertext(), u"text1text2text3");
 
@@ -153,25 +105,16 @@
 }
 
 TEST_F(AXPlatformNodeTest, GetTextContentIgnoresInvisibleAndIgnored) {
-  AXTreeUpdate update;
-
-  update.root_id = 1;
-  update.nodes.resize(6);
-
-  MakeStaticText(&update.nodes[1], 2, "a");
-  MakeStaticText(&update.nodes[2], 3, "b");
-
-  MakeStaticText(&update.nodes[4], 5, "d");
-  MakeStaticText(&update.nodes[5], 6, "e");
-
-  MakeGroup(&update.nodes[3], 4, {5, 6});
-  MakeGroup(&update.nodes[0], 1, {2, 3, 4});
-
-  Init(update);
-
-  AXTree& tree = *GetTree();
+  // kGroup
+  // ++kStaticText "a"
+  // ++kStaticText "b"
+  // ++kGroup
+  // ++++kStaticText "d"
+  // ++++kStaticText "e"
+  AXTree* tree =
+      Init({Role::kGroup, {{"a"}, {"b"}, {Role::kGroup, {{"d"}, {"e"}}}}});
   auto* root = static_cast<AXPlatformNodeBase*>(
-      TestAXNodeWrapper::GetOrCreate(&tree, tree.root())->ax_platform_node());
+      TestAXNodeWrapper::GetOrCreate(tree, tree->root())->ax_platform_node());
 
   // Set an AXMode on the AXPlatformNode as some platforms (auralinux) use it to
   // determine if it should enable accessibility.
@@ -182,26 +125,26 @@
   // Setting invisible or ignored on a static text node causes it to be included
   // or excluded from the root node's text content:
   {
-    SetIsInvisible(&tree, 2, true);
+    SetIsInvisible(tree, 2, true);
     EXPECT_EQ(root->GetTextContentUTF16(), u"bde");
 
-    SetIsInvisible(&tree, 2, false);
+    SetIsInvisible(tree, 2, false);
     EXPECT_EQ(root->GetTextContentUTF16(), u"abde");
 
-    SetRole(&tree, 2, ax::mojom::Role::kNone);
+    SetRole(tree, 2, ax::mojom::Role::kNone);
     EXPECT_EQ(root->GetTextContentUTF16(), u"bde");
 
-    SetRole(&tree, 2, ax::mojom::Role::kStaticText);
+    SetRole(tree, 2, ax::mojom::Role::kStaticText);
     EXPECT_EQ(root->GetTextContentUTF16(), u"abde");
   }
 
   // Setting invisible or ignored on a group node has no effect on the
   // text content:
   {
-    SetIsInvisible(&tree, 4, true);
+    SetIsInvisible(tree, 4, true);
     EXPECT_EQ(root->GetTextContentUTF16(), u"abde");
 
-    SetRole(&tree, 4, ax::mojom::Role::kNone);
+    SetRole(tree, 4, ax::mojom::Role::kNone);
     EXPECT_EQ(root->GetTextContentUTF16(), u"abde");
   }
 }
diff --git a/ui/accessibility/platform/ax_platform_node_unittest.cc b/ui/accessibility/platform/ax_platform_node_unittest.cc
index 9d8c8f1..0c64716 100644
--- a/ui/accessibility/platform/ax_platform_node_unittest.cc
+++ b/ui/accessibility/platform/ax_platform_node_unittest.cc
@@ -7,6 +7,7 @@
 #include "ui/accessibility/ax_constants.mojom.h"
 #include "ui/accessibility/platform/ax_platform_node_base.h"
 #include "ui/accessibility/platform/test_ax_node_wrapper.h"
+#include "ui/accessibility/platform/test_ax_tree_update.h"
 
 namespace ui {
 
@@ -74,6 +75,12 @@
   Init(update);
 }
 
+AXTree* AXPlatformNodeTest::Init(const TestAXTreeUpdateNode& root) {
+  TestAXTreeUpdate update(root);
+  Init(update);
+  return GetTree();
+}
+
 AXTreeUpdate AXPlatformNodeTest::BuildTextField() {
   AXNodeData text_field_node;
   text_field_node.id = 1;
diff --git a/ui/accessibility/platform/ax_platform_node_unittest.h b/ui/accessibility/platform/ax_platform_node_unittest.h
index b006162b..a795d986 100644
--- a/ui/accessibility/platform/ax_platform_node_unittest.h
+++ b/ui/accessibility/platform/ax_platform_node_unittest.h
@@ -15,6 +15,8 @@
 
 namespace ui {
 
+struct TestAXTreeUpdateNode;
+
 class AXPlatformNodeTest : public ::testing::Test, public TestAXTreeManager {
  public:
   AXPlatformNodeTest();
@@ -42,6 +44,9 @@
             const AXNodeData& node11 = AXNodeData(),
             const AXNodeData& node12 = AXNodeData());
 
+  // Initialize given an AXTreeUpdate by given TestAXTreeUpdateNode instance.
+  AXTree* Init(const TestAXTreeUpdateNode& root);
+
   AXTreeUpdate BuildTextField();
   AXTreeUpdate BuildTextFieldWithSelectionRange(int32_t start, int32_t stop);
   AXTreeUpdate BuildContentEditable();
diff --git a/ui/accessibility/platform/test_ax_tree_update.cc b/ui/accessibility/platform/test_ax_tree_update.cc
new file mode 100644
index 0000000..5a02173
--- /dev/null
+++ b/ui/accessibility/platform/test_ax_tree_update.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 "ui/accessibility/platform/test_ax_tree_update.h"
+
+namespace ui {
+
+TestAXTreeUpdateNode::TestAXTreeUpdateNode(const TestAXTreeUpdateNode&) =
+    default;
+
+TestAXTreeUpdateNode::TestAXTreeUpdateNode(TestAXTreeUpdateNode&&) = default;
+
+TestAXTreeUpdateNode::~TestAXTreeUpdateNode() = default;
+
+TestAXTreeUpdateNode::TestAXTreeUpdateNode(
+    ax::mojom::Role role,
+    const std::vector<TestAXTreeUpdateNode>& children)
+    : children(children) {
+  DCHECK_NE(role, ax::mojom::Role::kUnknown);
+  data.role = role;
+}
+
+TestAXTreeUpdateNode::TestAXTreeUpdateNode(
+    ax::mojom::Role role,
+    ax::mojom::State state,
+    const std::vector<TestAXTreeUpdateNode>& children)
+    : children(children) {
+  DCHECK_NE(role, ax::mojom::Role::kUnknown);
+  DCHECK_NE(state, ax::mojom::State::kNone);
+  data.role = role;
+  data.AddState(state);
+}
+
+TestAXTreeUpdateNode::TestAXTreeUpdateNode(const std::string& text) {
+  data.role = ax::mojom::Role::kStaticText;
+  data.SetName(text);
+}
+
+TestAXTreeUpdate::TestAXTreeUpdate(const TestAXTreeUpdateNode& root) {
+  root_id = SetSubtree(root);
+}
+
+AXNodeID TestAXTreeUpdate::SetSubtree(const TestAXTreeUpdateNode& node) {
+  size_t node_index = nodes.size();
+  nodes.push_back(node.data);
+  nodes[node_index].id = node_index + 1;
+  std::vector<AXNodeID> child_ids;
+  for (const auto& child : node.children) {
+    child_ids.push_back(SetSubtree(child));
+  }
+  nodes[node_index].child_ids = child_ids;
+  return nodes[node_index].id;
+}
+
+}  // namespace ui
diff --git a/ui/accessibility/platform/test_ax_tree_update.h b/ui/accessibility/platform/test_ax_tree_update.h
new file mode 100644
index 0000000..41878fa0
--- /dev/null
+++ b/ui/accessibility/platform/test_ax_tree_update.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 UI_ACCESSIBILITY_PLATFORM_TEST_AX_TREE_UPDATE_H_
+#define UI_ACCESSIBILITY_PLATFORM_TEST_AX_TREE_UPDATE_H_
+
+#include "ui/accessibility/ax_tree_update.h"
+
+namespace ui {
+
+// These utility classes, help construct an AXTreeUpdate  together with all of
+// the updated nodes more easily. Only for use in tests for constructing /
+// updating simple accessibility trees.
+
+// Used to construct AXTreeUpdate node.
+struct TestAXTreeUpdateNode {
+  TestAXTreeUpdateNode() = delete;
+  ~TestAXTreeUpdateNode();
+
+  TestAXTreeUpdateNode(const TestAXTreeUpdateNode&);
+  TestAXTreeUpdateNode(TestAXTreeUpdateNode&&);
+
+  TestAXTreeUpdateNode(ax::mojom::Role role,
+                       const std::vector<TestAXTreeUpdateNode>& children);
+  TestAXTreeUpdateNode(ax::mojom::Role role,
+                       ax::mojom::State state,
+                       const std::vector<TestAXTreeUpdateNode>& children);
+  TestAXTreeUpdateNode(const std::string& text);
+
+  AXNodeData data;
+  std::vector<TestAXTreeUpdateNode> children;
+};
+
+// Used to construct an accessible tree from a hierarchical list of nodes
+// {<node_properties>, {<node_children>}}. For example,
+// {Role::kRootWebArea, {"text"}} will create the following tree:
+// kRootWebArea
+// ++kStaticText "text"
+class TestAXTreeUpdate final : public AXTreeUpdate {
+ public:
+  TestAXTreeUpdate(const TestAXTreeUpdateNode& root);
+
+  TestAXTreeUpdate(const TestAXTreeUpdate&) = delete;
+  TestAXTreeUpdate& operator=(const TestAXTreeUpdate&) = delete;
+
+ private:
+  // Recursively creates the tree update structure.
+  AXNodeID SetSubtree(const TestAXTreeUpdateNode& node);
+};
+
+}  // namespace ui
+
+#endif  // UI_ACCESSIBILITY_PLATFORM_TEST_AX_TREE_UPDATE_H_
diff --git a/ui/gfx/render_text_harfbuzz.cc b/ui/gfx/render_text_harfbuzz.cc
index cd19053a..cd779904 100644
--- a/ui/gfx/render_text_harfbuzz.cc
+++ b/ui/gfx/render_text_harfbuzz.cc
@@ -201,7 +201,7 @@
         properties.block = ublock_getCode(codepoint);
     }
 
-    if (codepoint == '\n' || codepoint == ' ')
+    if (codepoint == '\n' || codepoint == '\r' || codepoint == ' ')
       properties.has_control = true;
     if (IsBracket(codepoint))
       properties.has_bracket = true;
diff --git a/ui/gfx/render_text_unittest.cc b/ui/gfx/render_text_unittest.cc
index 4c27a8e9..87c8279 100644
--- a/ui/gfx/render_text_unittest.cc
+++ b/ui/gfx/render_text_unittest.cc
@@ -1575,6 +1575,9 @@
     {"multiline_newline1", u"\n\n", "[0][1]", true},
     {"multiline_newline2", u"\r\n\r\n", "[0->1][2->3]", true},
     {"multiline_newline3", u"\r\r\n", "[0][1->2]", true},
+    {"multiline_newline4", u"x\r\r", "[0][1][2]", true},
+    {"multiline_newline5", u"x\n\r\r", "[0][1][2][3]", true},
+    {"multiline_newline6", u"x\ny\rz\r\n", "[0][1][2][3][4][5->6]", true},
 };
 
 INSTANTIATE_TEST_SUITE_P(ItemizeTextToRunsBasics,
@@ -8562,8 +8565,7 @@
   gfx::FontList font_list;
   gfx::Rect field(2119635455, font_list.GetHeight());
 
-  std::unique_ptr<gfx::RenderText> render_text =
-      gfx::RenderText::CreateRenderText();
+  RenderText* render_text = GetRenderText();
   render_text->SetFontList(font_list);
   render_text->SetHorizontalAlignment(ALIGN_RIGHT);
   render_text->SetDirectionalityMode(DIRECTIONALITY_FROM_UI);
@@ -8571,7 +8573,7 @@
   render_text->SetDisplayRect(field);
   render_text->SetCursorEnabled(true);
 
-  gfx::test::RenderTextTestApi render_text_test_api(render_text.get());
+  gfx::test::RenderTextTestApi render_text_test_api(render_text);
   render_text_test_api.SetGlyphWidth(2016371456);
 
   EXPECT_FALSE(render_text->multiline());
@@ -8592,8 +8594,7 @@
   gfx::FontList font_list;
   gfx::Rect field(-1334808765, font_list.GetHeight());
 
-  std::unique_ptr<gfx::RenderText> render_text =
-      gfx::RenderText::CreateRenderText();
+  RenderText* render_text = GetRenderText();
   render_text->SetFontList(font_list);
   render_text->SetHorizontalAlignment(ALIGN_CENTER);
   render_text->SetDirectionalityMode(DIRECTIONALITY_FROM_TEXT);
@@ -8601,7 +8602,7 @@
   render_text->SetDisplayRect(field);
   render_text->SetCursorEnabled(false);
 
-  gfx::test::RenderTextTestApi render_text_test_api(render_text.get());
+  gfx::test::RenderTextTestApi render_text_test_api(render_text);
   render_text_test_api.SetGlyphWidth(1778384896);
 
   const Vector2d& offset = render_text->GetUpdatedDisplayOffset();
@@ -8609,4 +8610,14 @@
   EXPECT_EQ(0, offset.y());
 }
 
+TEST_F(RenderTextTest, Clusterfuzz_Issue_1287804) {
+  RenderText* render_text = GetRenderText();
+  render_text->SetMaxLines(1);
+  render_text->SetText(u">\r\r");
+  render_text->SetMultiline(true);
+  render_text->SetDisplayRect(Rect(0, 0, 100, 24));
+  render_text->SetElideBehavior(ELIDE_TAIL);
+  EXPECT_EQ(RangeF(0, 0), render_text->GetCursorSpan(Range(0, 0)));
+}
+
 }  // namespace gfx
diff --git a/ui/qt/BUILD.gn b/ui/qt/BUILD.gn
index a74956f..349b529 100644
--- a/ui/qt/BUILD.gn
+++ b/ui/qt/BUILD.gn
@@ -8,7 +8,7 @@
 
 assert(use_qt)
 assert(is_linux)
-assert(!is_chromecast)
+assert(!is_castos)
 
 pkg_config("qt5_config") {
   packages = [
diff --git a/ui/shell_dialogs/BUILD.gn b/ui/shell_dialogs/BUILD.gn
index 192251ba..ae6c1b07 100644
--- a/ui/shell_dialogs/BUILD.gn
+++ b/ui/shell_dialogs/BUILD.gn
@@ -41,11 +41,11 @@
     "//url",
   ]
 
-  if (is_chromeos || is_chromecast) {
+  if (is_chromeos || is_castos || is_cast_android) {
     sources += [ "shell_dialog_stub.cc" ]
   }
 
-  if (is_linux && !is_chromecast) {
+  if (is_linux && !is_castos) {
     sources += [
       "select_file_dialog_linux.cc",
       "select_file_dialog_linux.h",
diff --git a/ui/views/test/widget_test.h b/ui/views/test/widget_test.h
index 549704e..d3a0ec7 100644
--- a/ui/views/test/widget_test.h
+++ b/ui/views/test/widget_test.h
@@ -20,8 +20,9 @@
 #include "ui/views/widget/widget_delegate.h"
 #include "ui/views/widget/widget_observer.h"
 
-#if (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) && \
-    !BUILDFLAG(IS_CHROMECAST)
+#if (BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CASTOS)) || \
+    BUILDFLAG(IS_CHROMEOS_LACROS)
+
 #include "ui/display/screen.h"
 #endif
 
@@ -163,8 +164,8 @@
   // DesktopWidgetTest
   void SetUp() override;
 
-#if (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) && \
-    !BUILDFLAG(IS_CHROMECAST)
+#if (BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CASTOS)) || \
+    BUILDFLAG(IS_CHROMEOS_LACROS)
   void TearDown() override;
   std::unique_ptr<display::Screen> screen_;
 #endif
diff --git a/ui/webui/resources/cr_components/app_management/app_management.mojom b/ui/webui/resources/cr_components/app_management/app_management.mojom
index f9cb799b..c19cec68 100644
--- a/ui/webui/resources/cr_components/app_management/app_management.mojom
+++ b/ui/webui/resources/cr_components/app_management/app_management.mojom
@@ -42,6 +42,7 @@
   kContacts        = 5,
   kStorage         = 6,
   kPrinting        = 7,
+  kFileHandling    = 8,
 };
 
 enum TriState {
diff --git a/ui/webui/resources/cr_components/app_management/app_management_mojom_traits.cc b/ui/webui/resources/cr_components/app_management/app_management_mojom_traits.cc
index 0363252..c4b4b100 100644
--- a/ui/webui/resources/cr_components/app_management/app_management_mojom_traits.cc
+++ b/ui/webui/resources/cr_components/app_management/app_management_mojom_traits.cc
@@ -129,6 +129,8 @@
       return PermissionType::kStorage;
     case apps::PermissionType::kPrinting:
       return PermissionType::kPrinting;
+    case apps::PermissionType::kFileHandling:
+      return PermissionType::kFileHandling;
   }
 }
 
@@ -160,6 +162,9 @@
     case PermissionType::kPrinting:
       *output = apps::PermissionType::kPrinting;
       return true;
+    case PermissionType::kFileHandling:
+      *output = apps::PermissionType::kFileHandling;
+      return true;
   }
 }