diff --git a/DEPS b/DEPS
index e982f38..f803c7d 100644
--- a/DEPS
+++ b/DEPS
@@ -297,19 +297,19 @@
   # 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': 'bd204f1afaca173576be83c3b5d25818bbaa3ac7',
+  'skia_revision': 'da1c56b693348ac18187a7f72233ec3971319f2b',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': 'd35cc240b2cdb7dd9a20edf1bbc673283041ac6d',
+  'v8_revision': '5275adc18e435dd1efd80736f0a463b4babe47bf',
   # 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': '6e6f3e6da27c26de99c41c48d68c4231cb7bc348',
+  'angle_revision': '05d86e06003bc9bcfdf62d769d6c6229e7680f5e',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
-  'swiftshader_revision': '0296680c782c0da62744cad6d5ab545602a8e548',
+  'swiftshader_revision': 'a07b3fb6b3bd47be49c0c3879475d25452b22106',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
@@ -324,7 +324,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Fuchsia sdk
   # and whatever else without interference from each other.
-  'fuchsia_version': 'version:9.20220802.1.1',
+  'fuchsia_version': 'version:9.20220802.3.1',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling google-toolbox-for-mac
   # and whatever else without interference from each other.
@@ -348,7 +348,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': 'd53c114165b152d58b8b86d3c25a2bd27b006136',
+  'freetype_revision': 'dcb5fc5bcd1d73b6510ce20579ccbd8e96b639c5',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling freetype
   # and whatever else without interference from each other.
@@ -368,7 +368,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': '81c03c3de984993f8e62d477b337527705102f64',
+  'catapult_revision': '2a52133e52c1fd021510b0b474d11676a680856f',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -412,7 +412,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': '24d36b022747fddcd345eeecd0767ac68bcaf204',
+  'dawn_revision': 'ce6246502c4d4e43b158bd161859179ba606bf75',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -773,7 +773,7 @@
     Var('chromium_git') + '/external/github.com/toji/webvr.info.git' + '@' + 'c58ae99b9ff9e2aa4c524633519570bf33536248',
 
   'src/docs/website': {
-    'url': Var('chromium_git') + '/website.git' + '@' + '84f1d0ad752311606ac02d635da82e087e5d0a0f',
+    'url': Var('chromium_git') + '/website.git' + '@' + 'd065cbfff30c5eabd423510b58b2ccd64fd66d07',
   },
 
   'src/ios/third_party/earl_grey2/src': {
@@ -1465,7 +1465,7 @@
     Var('chromium_git') + '/webm/libwebp.git' + '@' +  '7366f7f394af26de814296152c50e673ed0a832f',
 
   'src/third_party/libyuv':
-    Var('chromium_git') + '/libyuv/libyuv.git' + '@' + 'b028453ba61043a560298acae28eb813ea9bc67d',
+    Var('chromium_git') + '/libyuv/libyuv.git' + '@' + '98ec7c28d5f4664d0cf5b7631e82a876ccb11c26',
 
   'src/third_party/lighttpd': {
       'url': Var('chromium_git') + '/chromium/deps/lighttpd.git' + '@' + Var('lighttpd_revision'),
@@ -1556,7 +1556,7 @@
     Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + 'fac04ceb3e966f613ed17e98178e9d690280bba6',
 
   'src/third_party/openscreen/src':
-    Var('chromium_git') + '/openscreen' + '@' + '6be6b78224a276e908b8272542d125e133c40f3f',
+    Var('chromium_git') + '/openscreen' + '@' + '1c8b6f256f032c93611712bb1c9ba3e6a511e960',
 
   'src/third_party/openxr/src': {
     'url': Var('chromium_git') + '/external/github.com/KhronosGroup/OpenXR-SDK' + '@' + 'bf21ccb1007bb531b45d9978919a56ea5059c245',
@@ -1680,7 +1680,7 @@
     Var('chromium_git') + '/external/github.com/GoogleChromeLabs/text-fragments-polyfill.git' + '@' + 'c036420683f672d685e27415de0a5f5e85bdc23f',
 
   'src/third_party/tflite/src':
-    Var('chromium_git') + '/external/github.com/tensorflow/tensorflow.git' + '@' + '66b1a1f6d88f5e205c7001a4b5794a5182abffca',
+    Var('chromium_git') + '/external/github.com/tensorflow/tensorflow.git' + '@' + '179fbbab3fc38152be53b519376f0067736fd934',
 
   'src/third_party/turbine': {
       'packages': [
@@ -1753,7 +1753,7 @@
   },
 
   'src/third_party/xnnpack/src':
-    Var('chromium_git') + '/external/github.com/google/XNNPACK.git' + '@' + 'a33b227047def29b79853ef688b6dda6c6fc5386',
+    Var('chromium_git') + '/external/github.com/google/XNNPACK.git' + '@' + '8e3d3359f9bec608e09fac1f7054a2a14b1bd73c',
 
   'src/tools/page_cycler/acid3':
     Var('chromium_git') + '/chromium/deps/acid3.git' + '@' + '6be0a66a1ebd7ebc5abc1b2f405a945f6d871521',
@@ -1805,7 +1805,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@ca28931612a053dfc58e3c4d7b9489c4dbb050b0',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@7541357ca26c5a3172c642ba27d081a8e10c09d8',
     'condition': 'checkout_src_internal',
   },
 
@@ -1857,7 +1857,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/projector_app/app',
-        'version': '_FCQyKBzKZj5RznB5PCT09KDtwRx4bBASWVSV45dv04C',
+        'version': 'hkxJY91p1OSrQy88P4fPDCR-CpqvY7IAHhQ7KXjU4vUC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -4357,18 +4357,6 @@
     ],
   },
   {
-    'name': 'gvr_static_shim_android_arm_1',
-    'pattern': '\\.sha1',
-    'condition': 'checkout_android',
-    'action': [ 'python3',
-                'src/third_party/depot_tools/download_from_google_storage.py',
-                '--no_resume',
-                '--no_auth',
-                '--bucket', 'chromium-gvr-static-shim',
-                '-s', 'src/third_party/gvr-android-sdk/libgvr_shim_static_arm_1.a.sha1',
-    ],
-  },
-  {
     'name': 'gvr_static_shim_android_arm_Cr',
     'pattern': '\\.sha1',
     'condition': 'checkout_android',
@@ -4381,18 +4369,6 @@
     ],
   },
   {
-    'name': 'gvr_static_shim_android_arm64_1',
-    'pattern': '\\.sha1',
-    'condition': 'checkout_android',
-    'action': [ 'python3',
-                'src/third_party/depot_tools/download_from_google_storage.py',
-                '--no_resume',
-                '--no_auth',
-                '--bucket', 'chromium-gvr-static-shim',
-                '-s', 'src/third_party/gvr-android-sdk/libgvr_shim_static_arm64_1.a.sha1',
-    ],
-  },
-  {
     'name': 'gvr_static_shim_android_arm64_Cr',
     'pattern': '\\.sha1',
     'condition': 'checkout_android',
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn
index c78e3be..dd2e9203 100644
--- a/android_webview/BUILD.gn
+++ b/android_webview/BUILD.gn
@@ -812,6 +812,7 @@
     "//services/network/public:features_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
     "//third_party/blink/public/common:common_java",
+    "//third_party/blink/renderer/platform/scheduler:blink_scheduler_java",
   ]
   srcjar_deps = [
     ":common_java_features_srcjar",
diff --git a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
index 7466a11..5d277bd2 100644
--- a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
+++ b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
@@ -7,6 +7,7 @@
 import org.chromium.base.BaseFeatures;
 import org.chromium.base.BaseSwitches;
 import org.chromium.blink_public.common.BlinkFeatures;
+import org.chromium.blink_scheduler.BlinkSchedulerFeatures;
 import org.chromium.cc.base.CcSwitches;
 import org.chromium.components.autofill.AutofillFeatures;
 import org.chromium.components.feature_engagement.FeatureConstants;
@@ -340,6 +341,9 @@
             Flag.baseFeature(BlinkFeatures.SCROLL_UPDATE_OPTIMIZATIONS,
                     "Enable scroll update optimizations. See https://crbug.com/1346789."),
             Flag.baseFeature(BaseFeatures.ALIGN_WAKE_UPS, "Align delayed wake ups at 125 Hz"),
+            Flag.baseFeature(BlinkSchedulerFeatures.THREADED_SCROLL_PREVENT_RENDERING_STARVATION,
+                    "Enable rendering starvation-prevention during threaded scrolling."
+                            + " See https://crbug.com/1315279."),
             // Add new commandline switches and features above. The final entry should have a
             // trailing comma for cleaner diffs.
     };
diff --git a/ash/components/arc/PRESUBMIT.py b/ash/components/arc/PRESUBMIT.py
index 0655b58..bb25c4f 100644
--- a/ash/components/arc/PRESUBMIT.py
+++ b/ash/components/arc/PRESUBMIT.py
@@ -3,8 +3,9 @@
 # found in the LICENSE file.
 
 USE_PYTHON3 = True
+PRESUBMIT_VERSION = '2.0.0'
 
-def CheckChangeOnUpload(input_api, output_api):
+def CheckCommon(input_api, output_api):
   results = []
   results += input_api.canned_checks.CheckChangeLintsClean(
       input_api, output_api)
diff --git a/ash/components/arc/dark_theme/arc_dark_theme_bridge_unittest.cc b/ash/components/arc/dark_theme/arc_dark_theme_bridge_unittest.cc
index dca8d54..96619aa0 100644
--- a/ash/components/arc/dark_theme/arc_dark_theme_bridge_unittest.cc
+++ b/ash/components/arc/dark_theme/arc_dark_theme_bridge_unittest.cc
@@ -34,7 +34,7 @@
     bridge_->Shutdown();
   }
 
-  ArcDarkThemeBridgeTest(const ArcDarkThemeBridge&) = delete;
+  explicit ArcDarkThemeBridgeTest(const ArcDarkThemeBridge&) = delete;
   ArcDarkThemeBridgeTest& operator=(const ArcDarkThemeBridge&) = delete;
 
   content::BrowserTaskEnvironment task_environment_;
diff --git a/ash/components/arc/volume_mounter/arc_volume_mounter_bridge.cc b/ash/components/arc/volume_mounter/arc_volume_mounter_bridge.cc
index 9dfd8b3..9d56205e 100644
--- a/ash/components/arc/volume_mounter/arc_volume_mounter_bridge.cc
+++ b/ash/components/arc/volume_mounter/arc_volume_mounter_bridge.cc
@@ -153,8 +153,8 @@
   SendMountEventForMyFiles();
 
   for (const auto& keyValue : DiskMountManager::GetInstance()->mount_points()) {
-    OnMountEvent(DiskMountManager::MountEvent::MOUNTING,
-                 chromeos::MountError::MOUNT_ERROR_NONE, keyValue.second);
+    OnMountEvent(DiskMountManager::MountEvent::MOUNTING, ash::MountError::kNone,
+                 keyValue.second);
   }
 }
 
@@ -196,18 +196,18 @@
   for (const auto& key_value :
        DiskMountManager::GetInstance()->mount_points()) {
     OnMountEvent(DiskMountManager::MountEvent::UNMOUNTING,
-                 chromeos::MountError::MOUNT_ERROR_NONE, key_value.second);
+                 ash::MountError::kNone, key_value.second);
   }
   for (const auto& key_value :
        DiskMountManager::GetInstance()->mount_points()) {
-    OnMountEvent(DiskMountManager::MountEvent::MOUNTING,
-                 chromeos::MountError::MOUNT_ERROR_NONE, key_value.second);
+    OnMountEvent(DiskMountManager::MountEvent::MOUNTING, ash::MountError::kNone,
+                 key_value.second);
   }
 }
 
 void ArcVolumeMounterBridge::OnMountEvent(
     DiskMountManager::MountEvent event,
-    chromeos::MountError error_code,
+    ash::MountError error_code,
     const DiskMountManager::MountPointInfo& mount_info) {
   DCHECK(delegate_);
 
@@ -219,7 +219,7 @@
              << mount_info.mount_path;
     return;
   }
-  if (error_code != chromeos::MountError::MOUNT_ERROR_NONE) {
+  if (error_code != ash::MountError::kNone) {
     DVLOG(1) << "Error " << error_code << "occurs during MountEvent " << event;
     return;
   }
diff --git a/ash/components/arc/volume_mounter/arc_volume_mounter_bridge.h b/ash/components/arc/volume_mounter/arc_volume_mounter_bridge.h
index 9decf77..c919cd3 100644
--- a/ash/components/arc/volume_mounter/arc_volume_mounter_bridge.h
+++ b/ash/components/arc/volume_mounter/arc_volume_mounter_bridge.h
@@ -75,7 +75,7 @@
   // ash::disks::DiskMountManager::Observer overrides:
   void OnMountEvent(
       ash::disks::DiskMountManager::MountEvent event,
-      chromeos::MountError error_code,
+      ash::MountError error_code,
       const ash::disks::DiskMountManager::MountPointInfo& mount_info) override;
 
   // ConnectionObserver<mojom::VolumeMounterInstance> overrides:
diff --git a/ash/components/cryptohome/userdataauth_util.h b/ash/components/cryptohome/userdataauth_util.h
index 2ccf039..3c554faa 100644
--- a/ash/components/cryptohome/userdataauth_util.h
+++ b/ash/components/cryptohome/userdataauth_util.h
@@ -15,7 +15,7 @@
 
 namespace user_data_auth {
 
-// Returns a MountError code from |reply|, returning MOUNT_ERROR_NONE
+// Returns a MountError code from |reply|, returning MountError::kNone
 // if the reply is well-formed and there is no error.
 template <typename ReplyType>
 COMPONENT_EXPORT(ASH_COMPONENTS_CRYPTOHOME)
diff --git a/ash/components/disks/disk_mount_manager.cc b/ash/components/disks/disk_mount_manager.cc
index ed3168e..e7423c3 100644
--- a/ash/components/disks/disk_mount_manager.cc
+++ b/ash/components/disks/disk_mount_manager.cc
@@ -41,7 +41,7 @@
       : callback(std::move(in_callback)) {}
 
   DiskMountManager::UnmountDeviceRecursivelyCallbackType callback;
-  MountError error_code = MOUNT_ERROR_NONE;
+  MountError error_code = MountError::kNone;
 };
 
 void OnAllUnmountDeviceRecursively(
@@ -102,7 +102,7 @@
             mount_callbacks_.try_emplace(source_path, std::move(callback));
         !ok) {
       std::move(callback).Run(
-          MOUNT_ERROR_PATH_ALREADY_MOUNTED,
+          MountError::kPathAlreadyMounted,
           MountPointInfo(source_path, "", type, MOUNT_CONDITION_NONE));
       return;
     }
@@ -112,7 +112,7 @@
       DiskMap::const_iterator it = disks_.find(source_path);
       if (it == disks_.end() || it->second->is_hidden()) {
         OnMountCompleted(
-            MountEntry(MOUNT_ERROR_INTERNAL, source_path, type, ""));
+            MountEntry(MountError::kInternal, source_path, type, ""));
         return;
       }
     }
@@ -269,12 +269,12 @@
     if (devices_to_unmount.empty()) {
       if (disks_.find(device_path) == disks_.end()) {
         LOG(WARNING) << "Cannot find device '" << device_path << "'";
-        std::move(callback).Run(MOUNT_ERROR_INVALID_DEVICE_PATH);
+        std::move(callback).Run(MountError::kInvalidDevicePath);
         return;
       }
 
       // Nothing to unmount.
-      std::move(callback).Run(MOUNT_ERROR_NONE);
+      std::move(callback).Run(MountError::kNone);
       return;
     }
 
@@ -385,7 +385,7 @@
       return;
 
     OnMountCompleted(
-        MountEntry(MOUNT_ERROR_INTERNAL, source_path, type, std::string()));
+        MountEntry(MountError::kInternal, source_path, type, std::string()));
   }
 
   void RemountRemovableDrive(const Disk& disk, MountAccessMode access_mode) {
@@ -395,7 +395,7 @@
       // Not in mount_points_. This happens when the mount_points and disks_ are
       // inconsistent.
       LOG(ERROR) << "Cannot find mount point '" << mount_path << "'";
-      OnMountCompleted(MountEntry(MOUNT_ERROR_PATH_NOT_MOUNTED,
+      OnMountCompleted(MountEntry(MountError::kPathNotMounted,
                                   disk.device_path(), MountType::kDevice,
                                   mount_path));
       return;
@@ -443,15 +443,15 @@
                                   const std::string& mount_path,
                                   base::OnceClosure done_callback,
                                   MountError error_code) {
-    if (error_code == MOUNT_ERROR_PATH_NOT_MOUNTED ||
-        error_code == MOUNT_ERROR_INVALID_PATH) {
+    if (error_code == MountError::kPathNotMounted ||
+        error_code == MountError::kInvalidPath) {
       // The path was already unmounted by something else.
-      error_code = MOUNT_ERROR_NONE;
+      error_code = MountError::kNone;
     }
 
-    if (error_code == MOUNT_ERROR_NONE) {
+    if (error_code == MountError::kNone) {
       // Do standard processing for Unmount event.
-      OnUnmountPath(UnmountPathCallback(), mount_path, MOUNT_ERROR_NONE);
+      OnUnmountPath(UnmountPathCallback(), mount_path, MountError::kNone);
       VLOG(1) << "Unmounted '" << mount_path << "'";
     } else {
       // This causes the last non-success error to be reported.
@@ -471,10 +471,10 @@
 
     MountCondition mount_condition = MOUNT_CONDITION_NONE;
     if (entry.mount_type() == MountType::kDevice) {
-      if (entry.error_code() == MOUNT_ERROR_UNKNOWN_FILESYSTEM) {
+      if (entry.error_code() == MountError::kUnknownFilesystem) {
         mount_condition = MOUNT_CONDITION_UNKNOWN_FILESYSTEM;
       }
-      if (entry.error_code() == MOUNT_ERROR_UNSUPPORTED_FILESYSTEM) {
+      if (entry.error_code() == MountError::kUnsupportedFilesystem) {
         mount_condition = MOUNT_CONDITION_UNSUPPORTED_FILESYSTEM;
       }
     }
@@ -483,12 +483,12 @@
 
     // If the device is corrupted but it's still possible to format it, it will
     // be fake mounted.
-    if (entry.error_code() == MOUNT_ERROR_NONE || mount_info.mount_condition) {
+    if (entry.error_code() == MountError::kNone || mount_info.mount_condition) {
       mount_points_.emplace(mount_info.mount_path, mount_info);
     }
 
     Disk* disk = nullptr;
-    if ((entry.error_code() == MOUNT_ERROR_NONE ||
+    if ((entry.error_code() == MountError::kNone ||
          mount_info.mount_condition) &&
         mount_info.mount_type == MountType::kDevice &&
         !mount_info.source_path.empty() && !mount_info.mount_path.empty()) {
@@ -516,7 +516,7 @@
         // non-trivial.
         // TODO(amistry): Change these code paths to use device path instead of
         // mount path.
-        disk->set_mounted(entry.error_code() == MOUNT_ERROR_NONE);
+        disk->set_mounted(entry.error_code() == MountError::kNone);
       }
     }
     // Observers may read the values of disks_. So notify them after tweaking
@@ -537,10 +537,10 @@
   void OnUnmountPath(UnmountPathCallback callback,
                      const std::string& mount_path,
                      MountError error) {
-    if (error == MOUNT_ERROR_PATH_NOT_MOUNTED ||
-        error == MOUNT_ERROR_INVALID_PATH) {
+    if (error == MountError::kPathNotMounted ||
+        error == MountError::kInvalidPath) {
       // The path was already unmounted by something else.
-      error = MOUNT_ERROR_NONE;
+      error = MountError::kNone;
     }
 
     if (const MountPointMap::const_iterator mp_it =
@@ -549,7 +549,7 @@
       const MountPointInfo& mp = mp_it->second;
       NotifyMountStatusUpdate(UNMOUNTING, error, mp);
 
-      if (error == MOUNT_ERROR_NONE) {
+      if (error == MountError::kNone) {
         if (const DiskMap::iterator disk_it = disks_.find(mp.source_path);
             disk_it != disks_.end()) {
           Disk* const disk = disk_it->second.get();
@@ -570,7 +570,7 @@
                               FormatFileSystemType filesystem,
                               const std::string& label,
                               MountError error_code) {
-    if (error_code == MOUNT_ERROR_NONE &&
+    if (error_code == MountError::kNone &&
         disks_.find(device_path) != disks_.end()) {
       FormatUnmountedDevice(device_path, filesystem, label);
     } else {
@@ -582,7 +582,7 @@
                                                FormatFileSystemType filesystem,
                                                const std::string& label,
                                                MountError error_code) {
-    if (error_code != MOUNT_ERROR_NONE ||
+    if (error_code != MountError::kNone ||
         disks_.find(device_path) == disks_.end()) {
       OnPartitionCompleted(device_path, filesystem, label,
                            PARTITION_ERROR_UNKNOWN);
@@ -752,7 +752,7 @@
   void OnUnmountPathForRename(const std::string& device_path,
                               const std::string& volume_name,
                               MountError error_code) {
-    if (error_code != MOUNT_ERROR_NONE ||
+    if (error_code != MountError::kNone ||
         disks_.find(device_path) == disks_.end()) {
       OnRenameCompleted(RENAME_ERROR_UNKNOWN, device_path);
       return;
diff --git a/ash/components/disks/disk_mount_manager_unittest.cc b/ash/components/disks/disk_mount_manager_unittest.cc
index a87370ae..157f1e7 100644
--- a/ash/components/disks/disk_mount_manager_unittest.cc
+++ b/ash/components/disks/disk_mount_manager_unittest.cc
@@ -312,7 +312,7 @@
 // Represents an invocation of |DiskMountManager::Observer::OnMountEvent()|.
 struct MountEvent : public ObserverEvent {
   DiskMountManager::MountEvent event;
-  chromeos::MountError error_code;
+  MountError error_code;
   DiskMountManager::MountPointInfo mount_point;
 
   // Not passed to callback, but read by handlers. So it's captured upon
@@ -325,7 +325,7 @@
         mount_point(other.mount_point),
         disk(std::move(other.disk)) {}
   MountEvent(DiskMountManager::MountEvent event,
-             chromeos::MountError error_code,
+             MountError error_code,
              const DiskMountManager::MountPointInfo& mount_point,
              const Disk& disk)
       : event(event),
@@ -391,7 +391,7 @@
 
   void OnMountEvent(
       DiskMountManager::MountEvent event,
-      chromeos::MountError error_code,
+      MountError error_code,
       const DiskMountManager::MountPointInfo& mount_point) override {
     // Take a snapshot (copy) of a Disk object at the time of invocation.
     // It can be verified later besides the arguments.
@@ -454,7 +454,7 @@
   // Counts the number of |MountEvent| recorded so far that matches the given
   // condition.
   size_t CountMountEvents(DiskMountManager::MountEvent mount_event_type,
-                          chromeos::MountError error_code,
+                          MountError error_code,
                           const std::string& mount_path) {
     size_t num_matched = 0;
     for (const auto& it : events_) {
@@ -656,7 +656,7 @@
   // format the device.
 
   fake_cros_disks_client_->MakeUnmountFail(
-      chromeos::MOUNT_ERROR_INSUFFICIENT_PERMISSIONS);
+      MountError::kInsufficientPermissions);
   // Start test.
   DiskMountManager::GetInstance()->FormatMountedDevice(
       kDevice1MountPath, kFormatFileSystemType1, kFormatLabel1);
@@ -669,8 +669,7 @@
   ASSERT_EQ(2U, observer_->GetEventCount());
   const MountEvent& mount_event = observer_->GetMountEvent(0);
   EXPECT_EQ(DiskMountManager::UNMOUNTING, mount_event.event);
-  EXPECT_EQ(chromeos::MOUNT_ERROR_INSUFFICIENT_PERMISSIONS,
-            mount_event.error_code);
+  EXPECT_EQ(MountError::kInsufficientPermissions, mount_event.error_code);
   EXPECT_EQ(kDevice1MountPath, mount_event.mount_point.mount_path);
 
   EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_COMPLETED,
@@ -706,7 +705,7 @@
   ASSERT_EQ(2U, observer_->GetEventCount());
   const MountEvent& mount_event = observer_->GetMountEvent(0);
   EXPECT_EQ(DiskMountManager::UNMOUNTING, mount_event.event);
-  EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, mount_event.error_code);
+  EXPECT_EQ(MountError::kNone, mount_event.error_code);
   EXPECT_EQ(kDevice1MountPath, mount_event.mount_point.mount_path);
 
   EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_COMPLETED,
@@ -738,7 +737,7 @@
   fake_cros_disks_client_->set_unmount_listener(
       base::BindRepeating(&FakeCrosDisksClient::MakeUnmountFail,
                           base::Unretained(fake_cros_disks_client_),
-                          chromeos::MOUNT_ERROR_INVALID_UNMOUNT_OPTIONS));
+                          MountError::kInvalidUnmountOptions));
   // Start the test.
   DiskMountManager::GetInstance()->FormatMountedDevice(
       kDevice1MountPath, kFormatFileSystemType1, kFormatLabel1);
@@ -761,7 +760,7 @@
   ASSERT_EQ(3U, observer_->GetEventCount());
   const MountEvent& mount_event = observer_->GetMountEvent(0);
   EXPECT_EQ(DiskMountManager::UNMOUNTING, mount_event.event);
-  EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, mount_event.error_code);
+  EXPECT_EQ(MountError::kNone, mount_event.error_code);
   EXPECT_EQ(kDevice1MountPath, mount_event.mount_point.mount_path);
   EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_COMPLETED,
                         chromeos::FORMAT_ERROR_UNKNOWN, kDevice1SourcePath,
@@ -791,7 +790,7 @@
 // preceding mount invocations.
 void VerifyMountEvent(const MountEvent& mount_event,
                       DiskMountManager::MountEvent mount_event_type,
-                      chromeos::MountError error_code,
+                      MountError error_code,
                       const std::string& mount_path) {
   EXPECT_EQ(mount_event_type, mount_event.event);
   EXPECT_EQ(error_code, mount_event.error_code);
@@ -835,7 +834,7 @@
   // formatting has failed (FORMAT_COMPLETED event).
   ASSERT_EQ(3U, observer_->GetEventCount());
   VerifyMountEvent(observer_->GetMountEvent(0), DiskMountManager::UNMOUNTING,
-                   chromeos::MOUNT_ERROR_NONE, kDevice1MountPath);
+                   MountError::kNone, kDevice1MountPath);
   EXPECT_EQ(
       FormatEvent(DiskMountManager::FORMAT_STARTED, chromeos::FORMAT_ERROR_NONE,
                   kDevice1SourcePath, kFormatLabel1),
@@ -882,7 +881,7 @@
   // events (all of them without an error set).
   ASSERT_EQ(3U, observer_->GetEventCount());
   VerifyMountEvent(observer_->GetMountEvent(0), DiskMountManager::UNMOUNTING,
-                   chromeos::MOUNT_ERROR_NONE, kDevice1MountPath);
+                   MountError::kNone, kDevice1MountPath);
   EXPECT_EQ(
       FormatEvent(DiskMountManager::FORMAT_STARTED, chromeos::FORMAT_ERROR_NONE,
                   kDevice1SourcePath, kFormatLabel1),
@@ -931,7 +930,7 @@
 
   // Simulate the device remounting.
   fake_cros_disks_client_->NotifyMountCompleted(
-      chromeos::MOUNT_ERROR_NONE, kDevice1SourcePath, MountType::kDevice,
+      MountError::kNone, kDevice1SourcePath, MountType::kDevice,
       kDevice1MountPath);
 
   EXPECT_TRUE(HasMountPoint(kDevice1MountPath));
@@ -984,13 +983,13 @@
                 DiskMountManager::FORMAT_STARTED, chromeos::FORMAT_ERROR_NONE,
                 kDevice1SourcePath, kFormatLabel2)));
 
-  EXPECT_EQ(2U, observer_->CountMountEvents(DiskMountManager::UNMOUNTING,
-                                            chromeos::MOUNT_ERROR_NONE,
-                                            kDevice1MountPath));
+  EXPECT_EQ(2U,
+            observer_->CountMountEvents(DiskMountManager::UNMOUNTING,
+                                        MountError::kNone, kDevice1MountPath));
 
-  EXPECT_EQ(1U, observer_->CountMountEvents(DiskMountManager::MOUNTING,
-                                            chromeos::MOUNT_ERROR_NONE,
-                                            kDevice1MountPath));
+  EXPECT_EQ(1U,
+            observer_->CountMountEvents(DiskMountManager::MOUNTING,
+                                        MountError::kNone, kDevice1MountPath));
 }
 
 TEST_F(DiskMountManagerTest, MountPath_RecordAccessMode) {
@@ -1007,15 +1006,15 @@
   base::MockCallback<DiskMountManager::MountPathCallback> mock_callback1;
   EXPECT_CALL(
       mock_callback1,
-      Run(chromeos::MOUNT_ERROR_NONE,
+      Run(MountError::kNone,
           Field(&DiskMountManager::MountPointInfo::mount_path, kMountPath1)));
 
   base::MockCallback<DiskMountManager::MountPathCallback> mock_callback2;
   EXPECT_CALL(
       mock_callback2,
-      Run(chromeos::MOUNT_ERROR_NONE,
+      Run(MountError::kNone,
           Field(&DiskMountManager::MountPointInfo::mount_path, kMountPath2)))
-      .WillOnce([&](chromeos::MountError,
+      .WillOnce([&](MountError,
                     const DiskMountManager::MountPointInfo& mount_point) {
         // Verify the disk appears read-only when the callback is invoked. See
         // below comment about the 2nd source.
@@ -1032,16 +1031,14 @@
                      mock_callback2.Get());
   // Simulate cros_disks reporting mount completed.
   fake_cros_disks_client_->NotifyMountCompleted(
-      chromeos::MOUNT_ERROR_NONE, kSourcePath1, MountType::kDevice,
-      kMountPath1);
+      MountError::kNone, kSourcePath1, MountType::kDevice, kMountPath1);
   fake_cros_disks_client_->NotifyMountCompleted(
-      chromeos::MOUNT_ERROR_NONE, kSourcePath2, MountType::kDevice,
-      kMountPath2);
+      MountError::kNone, kSourcePath2, MountType::kDevice, kMountPath2);
 
   // Event handlers of observers should be called.
   ASSERT_EQ(2U, observer_->GetEventCount());
   VerifyMountEvent(observer_->GetMountEvent(0), DiskMountManager::MOUNTING,
-                   chromeos::MOUNT_ERROR_NONE, kMountPath1);
+                   MountError::kNone, kMountPath1);
   // For the 2nd source, the disk (block device) is not read-only but the
   // test will mount it in read-only mode.
   // Observers query |disks_| from |DiskMountManager| in its event handler for
@@ -1049,7 +1046,7 @@
   // |read_only| value before notifying to observers.
   const MountEvent& secondMountEvent = observer_->GetMountEvent(1);
   EXPECT_EQ(DiskMountManager::MOUNTING, secondMountEvent.event);
-  EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, secondMountEvent.error_code);
+  EXPECT_EQ(MountError::kNone, secondMountEvent.error_code);
   EXPECT_EQ(kMountPath2, secondMountEvent.mount_point.mount_path);
   // Verify if the disk appears read-only at the time of notification to
   // observers.
@@ -1070,7 +1067,7 @@
 
   base::MockCallback<DiskMountManager::MountPathCallback> mock_callback;
   EXPECT_CALL(mock_callback,
-              Run(chromeos::MOUNT_ERROR_NONE,
+              Run(MountError::kNone,
                   Field(&DiskMountManager::MountPointInfo::mount_path,
                         kReadOnlyDeviceMountPath)));
 
@@ -1081,13 +1078,13 @@
                      mock_callback.Get());
   // Simulate cros_disks reporting mount completed.
   fake_cros_disks_client_->NotifyMountCompleted(
-      chromeos::MOUNT_ERROR_NONE, kReadOnlyDeviceSourcePath, MountType::kDevice,
+      MountError::kNone, kReadOnlyDeviceSourcePath, MountType::kDevice,
       kReadOnlyDeviceMountPath);
 
   // Event handlers of observers should be called.
   ASSERT_EQ(1U, observer_->GetEventCount());
   VerifyMountEvent(observer_->GetMountEvent(0), DiskMountManager::MOUNTING,
-                   chromeos::MOUNT_ERROR_NONE, kReadOnlyDeviceMountPath);
+                   MountError::kNone, kReadOnlyDeviceMountPath);
   const DiskMountManager::DiskMap& disks = manager->disks();
   ASSERT_GT(disks.count(kReadOnlyDeviceSourcePath), 0U);
   // The mounted disk should preserve the read-only flag of the block device.
@@ -1108,8 +1105,7 @@
     // While the first mount is occurring, queue up a second mount for the same
     // source. It should immediately fail.
     base::MockCallback<DiskMountManager::MountPathCallback> mock_callback2;
-    EXPECT_CALL(mock_callback2,
-                Run(chromeos::MOUNT_ERROR_PATH_ALREADY_MOUNTED, _));
+    EXPECT_CALL(mock_callback2, Run(MountError::kPathAlreadyMounted, _));
 
     manager->MountPath(kDevice1SourcePath, "", "", {}, MountType::kDevice,
                        chromeos::MOUNT_ACCESS_MODE_READ_WRITE,
@@ -1119,11 +1115,10 @@
   // Verify the first mount can complete as expected.
   EXPECT_CALL(
       mock_callback1,
-      Run(chromeos::MOUNT_ERROR_NONE,
+      Run(MountError::kNone,
           Field(&DiskMountManager::MountPointInfo::mount_path, kMountPath1)));
   fake_cros_disks_client_->NotifyMountCompleted(
-      chromeos::MOUNT_ERROR_NONE, kDevice1SourcePath, MountType::kDevice,
-      kMountPath1);
+      MountError::kNone, kDevice1SourcePath, MountType::kDevice, kMountPath1);
 }
 
 TEST_F(DiskMountManagerTest, MountPath_CallbackCallsMount) {
@@ -1136,14 +1131,13 @@
   // Try call MountPath() again in the complete callback of a MountPath() call.
   EXPECT_CALL(
       mock_callback1,
-      Run(chromeos::MOUNT_ERROR_NONE,
+      Run(MountError::kNone,
           Field(&DiskMountManager::MountPointInfo::mount_path, kMountPath1)))
-      .WillOnce([=](chromeos::MountError error,
+      .WillOnce([=](MountError error,
                     const DiskMountManager::MountPointInfo& mount_info) {
         // Try remount the same path and verify it fails.
         base::MockCallback<DiskMountManager::MountPathCallback> mock_callback2;
-        EXPECT_CALL(mock_callback2,
-                    Run(chromeos::MOUNT_ERROR_PATH_ALREADY_MOUNTED, _));
+        EXPECT_CALL(mock_callback2, Run(MountError::kPathAlreadyMounted, _));
         manager->MountPath(kDevice1SourcePath, "", "", {}, MountType::kDevice,
                            chromeos::MOUNT_ACCESS_MODE_READ_WRITE,
                            mock_callback2.Get());
@@ -1151,14 +1145,14 @@
         // Try mount a different path and verify it succeeds.
         base::MockCallback<DiskMountManager::MountPathCallback> mock_callback3;
         EXPECT_CALL(mock_callback3,
-                    Run(chromeos::MOUNT_ERROR_NONE,
+                    Run(MountError::kNone,
                         Field(&DiskMountManager::MountPointInfo::mount_path,
                               kMountPath2)));
         manager->MountPath(kDevice2SourcePath, "", "", {}, MountType::kDevice,
                            chromeos::MOUNT_ACCESS_MODE_READ_WRITE,
                            mock_callback3.Get());
         fake_cros_disks_client_->NotifyMountCompleted(
-            chromeos::MOUNT_ERROR_NONE, kDevice2SourcePath, MountType::kDevice,
+            MountError::kNone, kDevice2SourcePath, MountType::kDevice,
             kMountPath2);
       });
 
@@ -1166,8 +1160,7 @@
                      chromeos::MOUNT_ACCESS_MODE_READ_WRITE,
                      mock_callback1.Get());
   fake_cros_disks_client_->NotifyMountCompleted(
-      chromeos::MOUNT_ERROR_NONE, kDevice1SourcePath, MountType::kDevice,
-      kMountPath1);
+      MountError::kNone, kDevice1SourcePath, MountType::kDevice, kMountPath1);
 }
 
 TEST_F(DiskMountManagerTest, RemountRemovableDrives) {
@@ -1180,13 +1173,13 @@
 
   // Simulate cros_disks reporting mount completed.
   fake_cros_disks_client_->NotifyMountCompleted(
-      chromeos::MOUNT_ERROR_NONE, kDevice1SourcePath, MountType::kDevice,
+      MountError::kNone, kDevice1SourcePath, MountType::kDevice,
       kDevice1MountPath);
 
   // Should remount disks that are not read-only by its hardware device.
   ASSERT_EQ(1U, observer_->GetEventCount());
   VerifyMountEvent(observer_->GetMountEvent(0), DiskMountManager::MOUNTING,
-                   chromeos::MOUNT_ERROR_NONE, kDevice1MountPath);
+                   MountError::kNone, kDevice1MountPath);
   // The disk is remounted in read-only mode.
   EXPECT_TRUE(
       manager->FindDiskBySourcePath(kDevice1SourcePath)->is_read_only());
@@ -1198,12 +1191,12 @@
 
   // Simulate cros_disks reporting mount completed.
   fake_cros_disks_client_->NotifyMountCompleted(
-      chromeos::MOUNT_ERROR_NONE, kDevice1SourcePath, MountType::kDevice,
+      MountError::kNone, kDevice1SourcePath, MountType::kDevice,
       kDevice1MountPath);
   // Event handlers of observers should be called.
   ASSERT_EQ(2U, observer_->GetEventCount());
   VerifyMountEvent(observer_->GetMountEvent(1), DiskMountManager::MOUNTING,
-                   chromeos::MOUNT_ERROR_NONE, kDevice1MountPath);
+                   MountError::kNone, kDevice1MountPath);
   // The read-write device should be remounted in read-write mode.
   EXPECT_FALSE(
       manager->FindDiskBySourcePath(kDevice1SourcePath)->is_read_only());
@@ -1252,7 +1245,7 @@
   // In this test unmount will fail, and there should be no attempt to
   // rename the device.
 
-  fake_cros_disks_client_->MakeUnmountFail(chromeos::MOUNT_ERROR_UNKNOWN);
+  fake_cros_disks_client_->MakeUnmountFail(MountError::kUnknown);
   // Start test.
   DiskMountManager::GetInstance()->RenameMountedDevice(kDevice1MountPath,
                                                        "MYUSB");
@@ -1265,7 +1258,7 @@
   ASSERT_EQ(2U, observer_->GetEventCount());
   const MountEvent& mount_event = observer_->GetMountEvent(0);
   EXPECT_EQ(DiskMountManager::UNMOUNTING, mount_event.event);
-  EXPECT_EQ(chromeos::MOUNT_ERROR_UNKNOWN, mount_event.error_code);
+  EXPECT_EQ(MountError::kUnknown, mount_event.error_code);
   EXPECT_EQ(kDevice1MountPath, mount_event.mount_point.mount_path);
 
   EXPECT_EQ(
@@ -1301,7 +1294,7 @@
   ASSERT_EQ(2U, observer_->GetEventCount());
   const MountEvent& mount_event = observer_->GetMountEvent(0);
   EXPECT_EQ(DiskMountManager::UNMOUNTING, mount_event.event);
-  EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, mount_event.error_code);
+  EXPECT_EQ(MountError::kNone, mount_event.error_code);
   EXPECT_EQ(kDevice1MountPath, mount_event.mount_point.mount_path);
 
   EXPECT_EQ(
@@ -1328,10 +1321,9 @@
   // CrosDisksClient will report that the rename process for the first request
   // is successfully started.
 
-  fake_cros_disks_client_->set_unmount_listener(
-      base::BindRepeating(&FakeCrosDisksClient::MakeUnmountFail,
-                          base::Unretained(fake_cros_disks_client_),
-                          chromeos::MOUNT_ERROR_INTERNAL));
+  fake_cros_disks_client_->set_unmount_listener(base::BindRepeating(
+      &FakeCrosDisksClient::MakeUnmountFail,
+      base::Unretained(fake_cros_disks_client_), MountError::kInternal));
   // Start the test.
   DiskMountManager::GetInstance()->RenameMountedDevice(kDevice1MountPath,
                                                        "MYUSB1");
@@ -1354,7 +1346,7 @@
   ASSERT_EQ(3U, observer_->GetEventCount());
   const MountEvent& mount_event = observer_->GetMountEvent(0);
   EXPECT_EQ(DiskMountManager::UNMOUNTING, mount_event.event);
-  EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, mount_event.error_code);
+  EXPECT_EQ(MountError::kNone, mount_event.error_code);
   EXPECT_EQ(kDevice1MountPath, mount_event.mount_point.mount_path);
   EXPECT_EQ(
       RenameEvent(DiskMountManager::RENAME_COMPLETED,
@@ -1412,7 +1404,7 @@
   // renaming has failed (RENAME_COMPLETED event).
   ASSERT_EQ(3U, observer_->GetEventCount());
   VerifyMountEvent(observer_->GetMountEvent(0), DiskMountManager::UNMOUNTING,
-                   chromeos::MOUNT_ERROR_NONE, kDevice1MountPath);
+                   MountError::kNone, kDevice1MountPath);
   EXPECT_EQ(
       RenameEvent(DiskMountManager::RENAME_STARTED, chromeos::RENAME_ERROR_NONE,
                   kDevice1SourcePath, "MYUSB"),
@@ -1456,7 +1448,7 @@
   // events (all of them without an error set).
   ASSERT_EQ(3U, observer_->GetEventCount());
   VerifyMountEvent(observer_->GetMountEvent(0), DiskMountManager::UNMOUNTING,
-                   chromeos::MOUNT_ERROR_NONE, kDevice1MountPath);
+                   MountError::kNone, kDevice1MountPath);
   EXPECT_EQ(
       RenameEvent(DiskMountManager::RENAME_STARTED, chromeos::RENAME_ERROR_NONE,
                   kDevice1SourcePath, "MYUSB1"),
@@ -1503,7 +1495,7 @@
 
   // Simulate the device remounting.
   fake_cros_disks_client_->NotifyMountCompleted(
-      chromeos::MOUNT_ERROR_NONE, kDevice1SourcePath, MountType::kDevice,
+      MountError::kNone, kDevice1SourcePath, MountType::kDevice,
       kDevice1MountPath);
 
   EXPECT_TRUE(HasMountPoint(kDevice1MountPath));
@@ -1556,13 +1548,13 @@
                 DiskMountManager::RENAME_STARTED, chromeos::RENAME_ERROR_NONE,
                 kDevice1SourcePath, "MYUSB2")));
 
-  EXPECT_EQ(2U, observer_->CountMountEvents(DiskMountManager::UNMOUNTING,
-                                            chromeos::MOUNT_ERROR_NONE,
-                                            kDevice1MountPath));
+  EXPECT_EQ(2U,
+            observer_->CountMountEvents(DiskMountManager::UNMOUNTING,
+                                        MountError::kNone, kDevice1MountPath));
 
-  EXPECT_EQ(1U, observer_->CountMountEvents(DiskMountManager::MOUNTING,
-                                            chromeos::MOUNT_ERROR_NONE,
-                                            kDevice1MountPath));
+  EXPECT_EQ(1U,
+            observer_->CountMountEvents(DiskMountManager::MOUNTING,
+                                        MountError::kNone, kDevice1MountPath));
 }
 
 void SaveUnmountResult(MountError* save_error,
@@ -1594,7 +1586,7 @@
   EXPECT_TRUE(
       DiskMountManager::GetInstance()->AddDiskForTest(std::move(disk_sda2)));
 
-  MountError error_code = chromeos::MOUNT_ERROR_UNKNOWN;
+  MountError error_code = MountError::kUnknown;
   DiskMountManager::GetInstance()->UnmountDeviceRecursively(
       "/dev/sda",
       base::BindOnce(&SaveUnmountResult, base::Unretained(&error_code),
@@ -1602,7 +1594,7 @@
   run_loop.Run();
 
   EXPECT_EQ(2, fake_cros_disks_client_->unmount_call_count());
-  EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, error_code);
+  EXPECT_EQ(MountError::kNone, error_code);
 }
 
 TEST_F(DiskMountManagerTest, UnmountDeviceRecursively_NoMounted) {
@@ -1617,7 +1609,7 @@
   EXPECT_TRUE(
       DiskMountManager::GetInstance()->AddDiskForTest(std::move(disk_sda1)));
 
-  MountError error_code = chromeos::MOUNT_ERROR_UNKNOWN;
+  MountError error_code = MountError::kUnknown;
   DiskMountManager::GetInstance()->UnmountDeviceRecursively(
       "/dev/sda",
       base::BindOnce(&SaveUnmountResult, base::Unretained(&error_code),
@@ -1625,7 +1617,7 @@
   run_loop.Run();
 
   EXPECT_EQ(0, fake_cros_disks_client_->unmount_call_count());
-  EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, error_code);
+  EXPECT_EQ(MountError::kNone, error_code);
 }
 
 TEST_F(DiskMountManagerTest, UnmountDeviceRecursively_NoDisk) {
@@ -1640,7 +1632,7 @@
   EXPECT_TRUE(
       DiskMountManager::GetInstance()->AddDiskForTest(std::move(disk_sda1)));
 
-  MountError error_code = chromeos::MOUNT_ERROR_UNKNOWN;
+  MountError error_code = MountError::kUnknown;
   // Unmount sdB instead of sdA.
   DiskMountManager::GetInstance()->UnmountDeviceRecursively(
       "/dev/sdb",
@@ -1649,7 +1641,7 @@
   run_loop.Run();
 
   EXPECT_EQ(0, fake_cros_disks_client_->unmount_call_count());
-  EXPECT_EQ(chromeos::MOUNT_ERROR_INVALID_DEVICE_PATH, error_code);
+  EXPECT_EQ(MountError::kInvalidDevicePath, error_code);
 }
 
 void SetUnmountError(FakeCrosDisksClient* client, MountError error_code) {
@@ -1679,13 +1671,12 @@
       DiskMountManager::GetInstance()->AddDiskForTest(std::move(disk_sda2)));
 
   // Fail the first unmount, but make the second succeed.
-  fake_cros_disks_client_->MakeUnmountFail(
-      chromeos::MOUNT_ERROR_INVALID_UNMOUNT_OPTIONS);
+  fake_cros_disks_client_->MakeUnmountFail(MountError::kInvalidUnmountOptions);
   fake_cros_disks_client_->set_unmount_listener(base::BindRepeating(
       &SetUnmountError, base::Unretained(fake_cros_disks_client_),
-      chromeos::MOUNT_ERROR_NONE));
+      MountError::kNone));
 
-  MountError error_code = chromeos::MOUNT_ERROR_UNKNOWN;
+  MountError error_code = MountError::kUnknown;
   DiskMountManager::GetInstance()->UnmountDeviceRecursively(
       "/dev/sda",
       base::BindOnce(&SaveUnmountResult, base::Unretained(&error_code),
@@ -1693,7 +1684,7 @@
   run_loop.Run();
 
   EXPECT_EQ(2, fake_cros_disks_client_->unmount_call_count());
-  EXPECT_EQ(chromeos::MOUNT_ERROR_INVALID_UNMOUNT_OPTIONS, error_code);
+  EXPECT_EQ(MountError::kInvalidUnmountOptions, error_code);
 }
 
 TEST_F(DiskMountManagerTest, UnmountDeviceRecursively_AlreadyUnmounted) {
@@ -1712,10 +1703,9 @@
       DiskMountManager::GetInstance()->AddDiskForTest(std::move(disk_sda1)));
 
   // Fail the unmount with "not mounted".
-  fake_cros_disks_client_->MakeUnmountFail(
-      chromeos::MOUNT_ERROR_PATH_NOT_MOUNTED);
+  fake_cros_disks_client_->MakeUnmountFail(MountError::kPathNotMounted);
 
-  MountError error_code = chromeos::MOUNT_ERROR_UNKNOWN;
+  MountError error_code = MountError::kUnknown;
   DiskMountManager::GetInstance()->UnmountDeviceRecursively(
       "/dev/sda",
       base::BindOnce(&SaveUnmountResult, base::Unretained(&error_code),
@@ -1723,7 +1713,7 @@
   run_loop.Run();
 
   EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
-  EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, error_code);
+  EXPECT_EQ(MountError::kNone, error_code);
 }
 
 TEST_F(DiskMountManagerTest, Mount_MountUnsetsFirstMount) {
@@ -1732,7 +1722,7 @@
   EXPECT_TRUE(device1->is_first_mount());
 
   fake_cros_disks_client_->NotifyMountCompleted(
-      chromeos::MOUNT_ERROR_NONE, kDevice1SourcePath, MountType::kDevice,
+      MountError::kNone, kDevice1SourcePath, MountType::kDevice,
       kDevice1MountPath);
 
   EXPECT_FALSE(device1->is_first_mount());
@@ -1758,7 +1748,7 @@
       manager->FindDiskBySourcePath(kDevice1SourcePath)->is_first_mount());
 
   fake_cros_disks_client_->NotifyMountCompleted(
-      chromeos::MOUNT_ERROR_NONE, kDevice1SourcePath, MountType::kDevice,
+      MountError::kNone, kDevice1SourcePath, MountType::kDevice,
       kDevice1MountPath);
   EXPECT_FALSE(
       manager->FindDiskBySourcePath(kDevice1SourcePath)->is_first_mount());
@@ -1793,14 +1783,14 @@
   fake_cros_disks_client_->NotifyMountEvent(CROS_DISKS_DISK_ADDED,
                                             kDevice1SourcePath);
   fake_cros_disks_client_->NotifyMountCompleted(
-      chromeos::MOUNT_ERROR_NONE, kDevice1SourcePath, MountType::kDevice,
+      MountError::kNone, kDevice1SourcePath, MountType::kDevice,
       kDevice1MountPath);
 
   // The mount event will not have fired yet as we are still waiting for
   // GetDeviceProperties() to return.
   EXPECT_EQ(0u,
             observer_->CountMountEvents(DiskMountManager::MOUNTING,
-                                        MOUNT_ERROR_NONE, kDevice1MountPath));
+                                        MountError::kNone, kDevice1MountPath));
   base::RunLoop().RunUntilIdle();
 
   // We have fired 3 events: disk removed -> disk added -> mounting
diff --git a/ash/components/disks/mount_point.cc b/ash/components/disks/mount_point.cc
index 5a77dc4..6163433 100644
--- a/ash/components/disks/mount_point.cc
+++ b/ash/components/disks/mount_point.cc
@@ -20,7 +20,7 @@
                  MountError error_code,
                  const DiskMountManager::MountPointInfo& mount_info) {
   std::unique_ptr<MountPoint> mount_point;
-  if (error_code == chromeos::MOUNT_ERROR_NONE) {
+  if (error_code == MountError::kNone) {
     DCHECK(!mount_info.mount_path.empty());
     mount_point = std::make_unique<MountPoint>(
         base::FilePath(mount_info.mount_path), disk_mount_manager);
@@ -63,7 +63,7 @@
   if (!mount_path_.empty()) {
     disk_mount_manager_->UnmountPath(
         mount_path_.value(), base::BindOnce([](MountError error_code) {
-          LOG_IF(WARNING, error_code != MOUNT_ERROR_NONE)
+          LOG_IF(WARNING, error_code != MountError::kNone)
               << "Failed to unmount with error code: " << error_code;
         }));
   }
diff --git a/ash/components/disks/mount_point_unittest.cc b/ash/components/disks/mount_point_unittest.cc
index e91f7ae..20eb9198 100644
--- a/ash/components/disks/mount_point_unittest.cc
+++ b/ash/components/disks/mount_point_unittest.cc
@@ -38,9 +38,9 @@
               MountPath(kSourcePath, "", "", _, MountType::kDevice,
                         MOUNT_ACCESS_MODE_READ_WRITE, _))
       .WillOnce(RunOnceCallback<6>(
-          MOUNT_ERROR_NONE, DiskMountManager::MountPointInfo(
-                                kSourcePath, kMountPath, MountType::kDevice,
-                                MOUNT_CONDITION_NONE)));
+          MountError::kNone, DiskMountManager::MountPointInfo(
+                                 kSourcePath, kMountPath, MountType::kDevice,
+                                 MOUNT_CONDITION_NONE)));
   EXPECT_CALL(disk_mount_manager_, UnmountPath(kMountPath, _)).Times(1);
 
   base::RunLoop run_loop;
@@ -49,7 +49,7 @@
                     base::BindLambdaForTesting(
                         [&run_loop](MountError mount_error,
                                     std::unique_ptr<MountPoint> mount) {
-                          EXPECT_EQ(MOUNT_ERROR_NONE, mount_error);
+                          EXPECT_EQ(MountError::kNone, mount_error);
                           EXPECT_EQ(kMountPath, mount->mount_path().value());
                           run_loop.Quit();
                         }));
@@ -61,9 +61,9 @@
               MountPath(kSourcePath, "", "", _, MountType::kDevice,
                         MOUNT_ACCESS_MODE_READ_WRITE, _))
       .WillOnce(RunOnceCallback<6>(
-          MOUNT_ERROR_UNKNOWN, DiskMountManager::MountPointInfo(
-                                   kSourcePath, kMountPath, MountType::kDevice,
-                                   MOUNT_CONDITION_UNSUPPORTED_FILESYSTEM)));
+          MountError::kUnknown, DiskMountManager::MountPointInfo(
+                                    kSourcePath, kMountPath, MountType::kDevice,
+                                    MOUNT_CONDITION_UNSUPPORTED_FILESYSTEM)));
   EXPECT_CALL(disk_mount_manager_, UnmountPath(_, _)).Times(0);
 
   base::RunLoop run_loop;
@@ -72,7 +72,7 @@
                     base::BindLambdaForTesting(
                         [&run_loop](MountError mount_error,
                                     std::unique_ptr<MountPoint> mount) {
-                          EXPECT_EQ(MOUNT_ERROR_UNKNOWN, mount_error);
+                          EXPECT_EQ(MountError::kUnknown, mount_error);
                           EXPECT_FALSE(mount);
                           run_loop.Quit();
                         }));
@@ -81,12 +81,12 @@
 
 TEST_F(MountPointTest, Unmount) {
   EXPECT_CALL(disk_mount_manager_, UnmountPath(kMountPath, _))
-      .WillOnce(base::test::RunOnceCallback<1>(MOUNT_ERROR_INTERNAL));
+      .WillOnce(base::test::RunOnceCallback<1>(MountError::kInternal));
 
   base::RunLoop run_loop;
   MountPoint mount_point(base::FilePath(kMountPath), &disk_mount_manager_);
   mount_point.Unmount(base::BindLambdaForTesting([&run_loop](MountError error) {
-    EXPECT_EQ(MOUNT_ERROR_INTERNAL, error);
+    EXPECT_EQ(MountError::kInternal, error);
     run_loop.Quit();
   }));
   run_loop.Run();
@@ -105,7 +105,7 @@
           [this, &run_loop](DiskMountManager::UnmountPathCallback callback) {
             task_environment_.GetMainThreadTaskRunner()->PostTask(
                 FROM_HERE,
-                base::BindOnce(std::move(callback), MOUNT_ERROR_INTERNAL));
+                base::BindOnce(std::move(callback), MountError::kInternal));
             task_environment_.GetMainThreadTaskRunner()->PostTask(
                 FROM_HERE, run_loop.QuitClosure());
           }));
diff --git a/ash/components/disks/suspend_unmount_manager.cc b/ash/components/disks/suspend_unmount_manager.cc
index 812d0b1..57723f1 100644
--- a/ash/components/disks/suspend_unmount_manager.cc
+++ b/ash/components/disks/suspend_unmount_manager.cc
@@ -70,7 +70,7 @@
 }
 
 void SuspendUnmountManager::OnUnmountComplete(const std::string& mount_path,
-                                              chromeos::MountError error_code) {
+                                              MountError error_code) {
   // This can happen when unmount completes after suspend done is called.
   if (unmounting_paths_.erase(mount_path) != 1)
     return;
diff --git a/ash/components/disks/suspend_unmount_manager.h b/ash/components/disks/suspend_unmount_manager.h
index b89e5ec..e624d4a3 100644
--- a/ash/components/disks/suspend_unmount_manager.h
+++ b/ash/components/disks/suspend_unmount_manager.h
@@ -32,8 +32,7 @@
   ~SuspendUnmountManager() override;
 
  private:
-  void OnUnmountComplete(const std::string& mount_path,
-                         chromeos::MountError error_code);
+  void OnUnmountComplete(const std::string& mount_path, MountError error_code);
 
   // PowerManagerClient::Observer
   void SuspendImminent(power_manager::SuspendImminent::Reason reason) override;
diff --git a/ash/components/disks/suspend_unmount_manager_unittest.cc b/ash/components/disks/suspend_unmount_manager_unittest.cc
index 53e0d2f..07e4d6911 100644
--- a/ash/components/disks/suspend_unmount_manager_unittest.cc
+++ b/ash/components/disks/suspend_unmount_manager_unittest.cc
@@ -111,7 +111,7 @@
   EXPECT_EQ(0, std::count(disk_mount_manager_.unmounting_mount_paths().begin(),
                           disk_mount_manager_.unmounting_mount_paths().end(),
                           kDummyMountPathUnknown));
-  disk_mount_manager_.NotifyUnmountDeviceComplete(MOUNT_ERROR_NONE);
+  disk_mount_manager_.NotifyUnmountDeviceComplete(MountError::kNone);
   EXPECT_EQ(
       0,
       FakePowerManagerClient::Get()->num_pending_suspend_readiness_callbacks());
diff --git a/ash/components/drivefs/drivefs_host_unittest.cc b/ash/components/drivefs/drivefs_host_unittest.cc
index 5084587..b58496f 100644
--- a/ash/components/drivefs/drivefs_host_unittest.cc
+++ b/ash/components/drivefs/drivefs_host_unittest.cc
@@ -274,10 +274,10 @@
 
   void CallMountCallbackSuccess(const std::string& token) {
     std::move(mount_callback_)
-        .Run(chromeos::MOUNT_ERROR_NONE, {base::StrCat({"drivefs://", token}),
-                                          "/media/drivefsroot/salt-g-ID",
-                                          ash::MountType::kNetworkStorage,
-                                          {}});
+        .Run(ash::MountError::kNone, {base::StrCat({"drivefs://", token}),
+                                      "/media/drivefsroot/salt-g-ID",
+                                      ash::MountType::kNetworkStorage,
+                                      {}});
   }
 
   void SendOnMounted() { delegate_->OnMounted(); }
@@ -428,7 +428,7 @@
   EXPECT_CALL(*host_delegate_, OnMountFailed(MountFailure::kInvocation, _))
       .WillOnce(RunOnceClosure(std::move(quit_closure)));
   std::move(mount_callback_)
-      .Run(chromeos::MOUNT_ERROR_INVALID_MOUNT_OPTIONS,
+      .Run(ash::MountError::kInvalidMountOptions,
            {base::StrCat({"drivefs://", token}),
             "/media/drivefsroot/salt-g-ID",
             ash::MountType::kNetworkStorage,
diff --git a/ash/components/drivefs/drivefs_session.cc b/ash/components/drivefs/drivefs_session.cc
index 7e5aa9aa..a5553b1 100644
--- a/ash/components/drivefs/drivefs_session.cc
+++ b/ash/components/drivefs/drivefs_session.cc
@@ -55,11 +55,11 @@
 
  private:
   // MountPoint::Mount() done callback.
-  void OnMountDone(chromeos::MountError error_code,
+  void OnMountDone(ash::MountError error_code,
                    std::unique_ptr<ash::disks::MountPoint> mount_point) {
     DCHECK(callback_);
 
-    if (error_code != chromeos::MOUNT_ERROR_NONE) {
+    if (error_code != ash::MountError::kNone) {
       LOG(WARNING) << "DriveFs mount failed with error: " << error_code;
       std::move(callback_).Run({});
       return;
diff --git a/ash/components/drivefs/drivefs_session_unittest.cc b/ash/components/drivefs/drivefs_session_unittest.cc
index b4ec4e93..db6794de 100644
--- a/ash/components/drivefs/drivefs_session_unittest.cc
+++ b/ash/components/drivefs/drivefs_session_unittest.cc
@@ -78,10 +78,10 @@
   EXPECT_CALL(*this, OnCompleted(base::FilePath(kExpectedMountPath)))
       .WillOnce(base::test::RunClosure(run_loop.QuitClosure()));
   std::move(mount_callback_)
-      .Run(chromeos::MOUNT_ERROR_NONE, {base::StrCat({"drivefs://", token}),
-                                        kExpectedMountPath,
-                                        ash::MountType::kNetworkStorage,
-                                        {}});
+      .Run(ash::MountError::kNone, {base::StrCat({"drivefs://", token}),
+                                    kExpectedMountPath,
+                                    ash::MountType::kNetworkStorage,
+                                    {}});
   run_loop.Run();
 
   EXPECT_CALL(disk_manager_, UnmountPath(kExpectedMountPath, _));
@@ -95,10 +95,10 @@
   EXPECT_CALL(*this, OnCompleted(base::FilePath(kExpectedMountPath)))
       .WillOnce(base::test::RunClosure(run_loop.QuitClosure()));
   std::move(mount_callback_)
-      .Run(chromeos::MOUNT_ERROR_NONE, {base::StrCat({"drivefs://", token}),
-                                        kExpectedMountPath,
-                                        ash::MountType::kNetworkStorage,
-                                        {}});
+      .Run(ash::MountError::kNone, {base::StrCat({"drivefs://", token}),
+                                    kExpectedMountPath,
+                                    ash::MountType::kNetworkStorage,
+                                    {}});
   run_loop.Run();
 
   EXPECT_CALL(disk_manager_, UnmountPath(kExpectedMountPath, _));
@@ -119,7 +119,7 @@
   EXPECT_CALL(*this, OnCompleted(base::FilePath()))
       .WillOnce(base::test::RunClosure(run_loop.QuitClosure()));
   std::move(mount_callback_)
-      .Run(chromeos::MOUNT_ERROR_INVALID_MOUNT_OPTIONS,
+      .Run(ash::MountError::kInvalidMountOptions,
            {base::StrCat({"drivefs://", token}),
             kExpectedMountPath,
             ash::MountType::kNetworkStorage,
diff --git a/ash/components/smbfs/smbfs_host.cc b/ash/components/smbfs/smbfs_host.cc
index 69c2470..c849cb5 100644
--- a/ash/components/smbfs/smbfs_host.cc
+++ b/ash/components/smbfs/smbfs_host.cc
@@ -107,8 +107,8 @@
 }
 
 void SmbFsHost::OnUnmountDone(SmbFsHost::UnmountCallback callback,
-                              chromeos::MountError result) {
-  LOG_IF(ERROR, result != chromeos::MountError::MOUNT_ERROR_NONE)
+                              ash::MountError result) {
+  LOG_IF(ERROR, result != ash::MountError::kNone)
       << "Could not unmount smbfs share: " << result;
   std::move(callback).Run(result);
 }
diff --git a/ash/components/smbfs/smbfs_host.h b/ash/components/smbfs/smbfs_host.h
index 0275ac5..475e45b0 100644
--- a/ash/components/smbfs/smbfs_host.h
+++ b/ash/components/smbfs/smbfs_host.h
@@ -57,7 +57,7 @@
     return mount_point_->mount_path();
   }
 
-  using UnmountCallback = base::OnceCallback<void(chromeos::MountError)>;
+  using UnmountCallback = base::OnceCallback<void(ash::MountError)>;
   void Unmount(UnmountCallback callback);
 
   // Request any credentials saved by smbfs are deleted.
@@ -75,7 +75,7 @@
 
   // Called after cros-disks has attempted to unmount the share.
   void OnUnmountDone(SmbFsHost::UnmountCallback callback,
-                     chromeos::MountError result);
+                     ash::MountError result);
 
   // Callback for mojom::SmbFs::RemoveSavedCredentials().
   void OnRemoveSavedCredentialsDone(RemoveSavedCredentialsCallback callback,
diff --git a/ash/components/smbfs/smbfs_host_unittest.cc b/ash/components/smbfs/smbfs_host_unittest.cc
index 06712a5..85d29df 100644
--- a/ash/components/smbfs/smbfs_host_unittest.cc
+++ b/ash/components/smbfs/smbfs_host_unittest.cc
@@ -56,7 +56,7 @@
   EXPECT_CALL(mock_delegate_, OnDisconnected())
       .WillOnce(base::test::RunClosure(run_loop.QuitClosure()));
   EXPECT_CALL(mock_disk_mount_manager_, UnmountPath(kMountPath, _))
-      .WillOnce(base::test::RunOnceCallback<1>(chromeos::MOUNT_ERROR_NONE));
+      .WillOnce(base::test::RunOnceCallback<1>(ash::MountError::kNone));
 
   std::unique_ptr<SmbFsHost> host = std::make_unique<SmbFsHost>(
       std::make_unique<ash::disks::MountPoint>(base::FilePath(kMountPath),
@@ -73,7 +73,7 @@
   EXPECT_CALL(mock_delegate_, OnDisconnected())
       .WillOnce(base::test::RunClosure(run_loop.QuitClosure()));
   EXPECT_CALL(mock_disk_mount_manager_, UnmountPath(kMountPath, _))
-      .WillOnce(base::test::RunOnceCallback<1>(chromeos::MOUNT_ERROR_NONE));
+      .WillOnce(base::test::RunOnceCallback<1>(ash::MountError::kNone));
 
   std::unique_ptr<SmbFsHost> host = std::make_unique<SmbFsHost>(
       std::make_unique<ash::disks::MountPoint>(base::FilePath(kMountPath),
@@ -88,7 +88,7 @@
 TEST_F(SmbFsHostTest, UnmountOnDestruction) {
   EXPECT_CALL(mock_delegate_, OnDisconnected()).Times(0);
   EXPECT_CALL(mock_disk_mount_manager_, UnmountPath(kMountPath, _))
-      .WillOnce(base::test::RunOnceCallback<1>(chromeos::MOUNT_ERROR_NONE));
+      .WillOnce(base::test::RunOnceCallback<1>(ash::MountError::kNone));
 
   base::RunLoop run_loop;
   std::unique_ptr<SmbFsHost> host = std::make_unique<SmbFsHost>(
@@ -102,7 +102,7 @@
 
 TEST_F(SmbFsHostTest, RequestCredentials_ProvideCredentials) {
   EXPECT_CALL(mock_disk_mount_manager_, UnmountPath(kMountPath, _))
-      .WillOnce(base::test::RunOnceCallback<1>(chromeos::MOUNT_ERROR_NONE));
+      .WillOnce(base::test::RunOnceCallback<1>(ash::MountError::kNone));
 
   std::unique_ptr<SmbFsHost> host = std::make_unique<SmbFsHost>(
       std::make_unique<ash::disks::MountPoint>(base::FilePath(kMountPath),
@@ -136,7 +136,7 @@
 
 TEST_F(SmbFsHostTest, RequestCredentials_Cancel) {
   EXPECT_CALL(mock_disk_mount_manager_, UnmountPath(kMountPath, _))
-      .WillOnce(base::test::RunOnceCallback<1>(chromeos::MOUNT_ERROR_NONE));
+      .WillOnce(base::test::RunOnceCallback<1>(ash::MountError::kNone));
 
   std::unique_ptr<SmbFsHost> host = std::make_unique<SmbFsHost>(
       std::make_unique<ash::disks::MountPoint>(base::FilePath(kMountPath),
diff --git a/ash/components/smbfs/smbfs_mounter.cc b/ash/components/smbfs/smbfs_mounter.cc
index 1679127..6f324f7a 100644
--- a/ash/components/smbfs/smbfs_mounter.cc
+++ b/ash/components/smbfs/smbfs_mounter.cc
@@ -107,7 +107,7 @@
 }
 
 void SmbFsMounter::OnMountDone(
-    chromeos::MountError error_code,
+    ash::MountError error_code,
     std::unique_ptr<ash::disks::MountPoint> mount_point) {
   if (!callback_) {
     // This can happen if the mount timeout expires and the callback is already
@@ -115,7 +115,7 @@
     return;
   }
 
-  if (error_code != chromeos::MOUNT_ERROR_NONE) {
+  if (error_code != ash::MountError::kNone) {
     LOG(WARNING) << "smbfs mount error: " << error_code;
     ProcessMountError(mojom::MountError::kUnknown);
     return;
diff --git a/ash/components/smbfs/smbfs_mounter.h b/ash/components/smbfs/smbfs_mounter.h
index d8943823..7bd1391 100644
--- a/ash/components/smbfs/smbfs_mounter.h
+++ b/ash/components/smbfs/smbfs_mounter.h
@@ -100,7 +100,7 @@
 
  private:
   // Callback for MountPoint::Mount().
-  void OnMountDone(chromeos::MountError error_code,
+  void OnMountDone(ash::MountError error_code,
                    std::unique_ptr<ash::disks::MountPoint> mount_point);
 
   // Callback for receiving a Mojo bootstrap channel.
diff --git a/ash/components/smbfs/smbfs_mounter_unittest.cc b/ash/components/smbfs/smbfs_mounter_unittest.cc
index 3ee0cf3..9db566a 100644
--- a/ash/components/smbfs/smbfs_mounter_unittest.cc
+++ b/ash/components/smbfs/smbfs_mounter_unittest.cc
@@ -95,7 +95,7 @@
                    const MountOptions& options,
                    SmbFsHost::Delegate* delegate,
                    const base::FilePath& mount_path,
-                   chromeos::MountError mount_error,
+                   ash::MountError mount_error,
                    mojo::Remote<mojom::SmbFsBootstrap> bootstrap)
       : SmbFsMounter(share_path,
                      kMountDir,
@@ -115,9 +115,9 @@
                       std::move(callback), mount_error,
                       MakeMountPointInfo(source_path, mount_path.value())));
             }));
-    if (mount_error == chromeos::MOUNT_ERROR_NONE) {
+    if (mount_error == ash::MountError::kNone) {
       EXPECT_CALL(mock_disk_mount_manager_, UnmountPath(mount_path.value(), _))
-          .WillOnce(base::test::RunOnceCallback<1>(chromeos::MOUNT_ERROR_NONE));
+          .WillOnce(base::test::RunOnceCallback<1>(ash::MountError::kNone));
     } else {
       EXPECT_CALL(mock_disk_mount_manager_, UnmountPath(mount_path.value(), _))
           .Times(0);
@@ -133,7 +133,7 @@
   void PostMountEvent(
       const std::string& source_path,
       const std::string& mount_path,
-      chromeos::MountError mount_error,
+      ash::MountError mount_error,
       ash::disks::DiskMountManager::MountPathCallback callback) {
     base::SequencedTaskRunnerHandle::Get()->PostTask(
         FROM_HERE, base::BindOnce(std::move(callback), mount_error,
@@ -195,8 +195,8 @@
       .WillOnce(WithArgs<0, 6>(
           [this](const std::string& source_path,
                  ash::disks::DiskMountManager::MountPathCallback callback) {
-            PostMountEvent(source_path, kMountPath,
-                           chromeos::MOUNT_ERROR_INTERNAL, std::move(callback));
+            PostMountEvent(source_path, kMountPath, ash::MountError::kInternal,
+                           std::move(callback));
           }));
   EXPECT_CALL(mock_disk_mount_manager_, UnmountPath(_, _)).Times(0);
 
@@ -223,7 +223,7 @@
       .WillOnce(WithArgs<0, 6>(
           [this](const std::string& source_path,
                  ash::disks::DiskMountManager::MountPathCallback callback) {
-            PostMountEvent(source_path, kMountPath, chromeos::MOUNT_ERROR_NONE,
+            PostMountEvent(source_path, kMountPath, ash::MountError::kNone,
                            std::move(callback));
           }));
   // Destructing SmbFsMounter on failure will cause the mount point to be
@@ -258,8 +258,8 @@
                  ash::disks::DiskMountManager::MountPathCallback callback) {
             // This posts a mount event to the task queue, which will not be run
             // until |run_loop| is started.
-            PostMountEvent(source_path, kMountPath,
-                           chromeos::MOUNT_ERROR_INTERNAL, std::move(callback));
+            PostMountEvent(source_path, kMountPath, ash::MountError::kInternal,
+                           std::move(callback));
           }));
   EXPECT_CALL(mock_disk_mount_manager_, UnmountPath(_, _)).Times(0);
 
@@ -325,7 +325,7 @@
   mount_options.resolved_host = net::IPAddress(1, 2, 3, 4);
   std::unique_ptr<SmbFsMounter> mounter = std::make_unique<TestSmbFsMounter>(
       kSharePath, mount_options, &mock_delegate_, base::FilePath(kMountPath),
-      chromeos::MOUNT_ERROR_NONE,
+      ash::MountError::kNone,
       mojo::Remote<mojom::SmbFsBootstrap>(
           bootstrap_receiver.BindNewPipeAndPassRemote()));
   mounter->Mount(callback);
@@ -368,7 +368,7 @@
   mount_options.skip_connect = true;
   std::unique_ptr<SmbFsMounter> mounter = std::make_unique<TestSmbFsMounter>(
       kSharePath, mount_options, &mock_delegate_, base::FilePath(kMountPath),
-      chromeos::MOUNT_ERROR_NONE,
+      ash::MountError::kNone,
       mojo::Remote<mojom::SmbFsBootstrap>(
           bootstrap_receiver.BindNewPipeAndPassRemote()));
   mounter->Mount(callback);
@@ -420,7 +420,7 @@
   mount_options.password_salt = kSalt;
   std::unique_ptr<SmbFsMounter> mounter = std::make_unique<TestSmbFsMounter>(
       kSharePath, mount_options, &mock_delegate_, base::FilePath(kMountPath),
-      chromeos::MOUNT_ERROR_NONE,
+      ash::MountError::kNone,
       mojo::Remote<mojom::SmbFsBootstrap>(
           bootstrap_receiver.BindNewPipeAndPassRemote()));
   mounter->Mount(callback);
@@ -478,7 +478,7 @@
           SmbFsMounter::KerberosOptions::Source::kKerberos, kKerberosIdentity);
   std::unique_ptr<SmbFsMounter> mounter = std::make_unique<TestSmbFsMounter>(
       kSharePath, mount_options, &mock_delegate_, base::FilePath(kMountPath),
-      chromeos::MOUNT_ERROR_NONE,
+      ash::MountError::kNone,
       mojo::Remote<mojom::SmbFsBootstrap>(
           bootstrap_receiver.BindNewPipeAndPassRemote()));
   mounter->Mount(callback);
@@ -512,7 +512,7 @@
 
   std::unique_ptr<SmbFsMounter> mounter = std::make_unique<TestSmbFsMounter>(
       kSharePath, SmbFsMounter::MountOptions(), &mock_delegate_,
-      base::FilePath(kMountPath), chromeos::MOUNT_ERROR_NONE,
+      base::FilePath(kMountPath), ash::MountError::kNone,
       mojo::Remote<mojom::SmbFsBootstrap>(
           bootstrap_receiver.BindNewPipeAndPassRemote()));
   mounter->Mount(callback);
@@ -547,7 +547,7 @@
 
   std::unique_ptr<SmbFsMounter> mounter = std::make_unique<TestSmbFsMounter>(
       kSharePath, SmbFsMounter::MountOptions(), &mock_delegate_,
-      base::FilePath(kMountPath), chromeos::MOUNT_ERROR_NONE,
+      base::FilePath(kMountPath), ash::MountError::kNone,
       mojo::Remote<mojom::SmbFsBootstrap>(
           bootstrap_receiver.BindNewPipeAndPassRemote()));
   mounter->Mount(callback);
@@ -562,9 +562,8 @@
       const std::string& mount_path,
       ash::disks::DiskMountManager::MountPathCallback callback) {
     base::SequencedTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE,
-        base::BindOnce(std::move(callback), chromeos::MOUNT_ERROR_NONE,
-                       MakeMountPointInfo(source_path, mount_path)));
+        FROM_HERE, base::BindOnce(std::move(callback), ash::MountError::kNone,
+                                  MakeMountPointInfo(source_path, mount_path)));
   }
 
  protected:
@@ -674,7 +673,7 @@
             }));
       }));
   EXPECT_CALL(mock_disk_mount_manager_, UnmountPath(kMountPath, _))
-      .WillOnce(base::test::RunOnceCallback<1>(chromeos::MOUNT_ERROR_NONE));
+      .WillOnce(base::test::RunOnceCallback<1>(ash::MountError::kNone));
   EXPECT_CALL(mock_delegate_, OnDisconnected()).Times(0);
 
   base::RunLoop run_loop;
diff --git a/ash/keyboard/ui/keyboard_ui_controller.cc b/ash/keyboard/ui/keyboard_ui_controller.cc
index b85c0b6..4830918 100644
--- a/ash/keyboard/ui/keyboard_ui_controller.cc
+++ b/ash/keyboard/ui/keyboard_ui_controller.cc
@@ -1152,7 +1152,7 @@
   TRACE_EVENT0("vk", "EnsureCaretInWorkArea");
 
   if (IsOverscrollAllowed()) {
-    ime->SetOnScreenKeyboardBounds(occluded_bounds_in_screen);
+    ime->SetVirtualKeyboardBounds(occluded_bounds_in_screen);
   } else if (ime->GetTextInputClient()) {
     ime->GetTextInputClient()->EnsureCaretNotInRect(occluded_bounds_in_screen);
   }
diff --git a/ash/public/cpp/ash_constants.h b/ash/public/cpp/ash_constants.h
index 086cce7..de3031d 100644
--- a/ash/public/cpp/ash_constants.h
+++ b/ash/public/cpp/ash_constants.h
@@ -22,8 +22,6 @@
 constexpr FloatingMenuPosition kDefaultFloatingMenuPosition =
     FloatingMenuPosition::kSystemDefault;
 
-constexpr int kPipRoundedCornerRadius = 8;
-
 }  // namespace ash
 
 #endif  // ASH_PUBLIC_CPP_ASH_CONSTANTS_H_
diff --git a/ash/style/ash_color_mixer.cc b/ash/style/ash_color_mixer.cc
index db634fe..6f86a82 100644
--- a/ash/style/ash_color_mixer.cc
+++ b/ash/style/ash_color_mixer.cc
@@ -17,6 +17,7 @@
 #include "ui/color/color_mixer.h"
 #include "ui/color/color_provider.h"
 #include "ui/color/color_recipe.h"
+#include "ui/color/color_transform.h"
 #include "ui/gfx/color_palette.h"
 #include "ui/gfx/color_utils.h"
 
@@ -75,9 +76,7 @@
   mixer[kColorAshHairlineBorderColor] =
       use_dark_color ? ui::ColorTransform(SkColorSetA(SK_ColorWHITE, 0x24))
                      : ui::ColorTransform(SkColorSetA(SK_ColorBLACK, 0x24));
-  mixer[kColorAshControlBackgroundColorActive] =
-      use_dark_color ? ui::ColorTransform(gfx::kGoogleBlue300)
-                     : ui::ColorTransform(gfx::kGoogleBlue600);
+  mixer[kColorAshControlBackgroundColorActive] = {cros_tokens::kColorProminent};
   mixer[kColorAshControlBackgroundColorInactive] =
       use_dark_color ? ui::ColorTransform(SkColorSetA(SK_ColorWHITE, 0x1A))
                      : ui::ColorTransform(SkColorSetA(SK_ColorBLACK, 0x0D));
@@ -91,12 +90,8 @@
       use_dark_color ? ui::ColorTransform(gfx::kGoogleGreen300)
                      : ui::ColorTransform(gfx::kGoogleGreen600);
   mixer[kColorAshFocusAuraColor] =
-      use_dark_color
-          ? ui::ColorTransform(SkColorSetA(gfx::kGoogleBlue300, 0x3D))
-          : ui::ColorTransform(SkColorSetA(gfx::kGoogleBlue600, 0x3D));
-  mixer[ui::kColorAshFocusRing] = use_dark_color
-                                      ? ui::ColorTransform(gfx::kGoogleBlue300)
-                                      : ui::ColorTransform(gfx::kGoogleBlue600);
+      ui::SetAlpha(cros_tokens::kColorProminent, 0x3D);
+  mixer[ui::kColorAshFocusRing] = {cros_tokens::kColorProminent};
 }
 
 // Mappings the Content layer colors for Material 2.
@@ -129,9 +124,7 @@
   mixer[kColorAshTextColorPositive] =
       use_dark_color ? ui::ColorTransform(gfx::kGoogleGreen300)
                      : ui::ColorTransform(gfx::kGoogleGreen600);
-  mixer[kColorAshTextColorURL] = use_dark_color
-                                     ? ui::ColorTransform(gfx::kGoogleBlue300)
-                                     : ui::ColorTransform(gfx::kGoogleBlue600);
+  mixer[kColorAshTextColorURL] = {cros_tokens::kColorProminent};
   mixer[kColorAshIconColorPrimary] = {kColorAshTextColorPrimary};
   mixer[kColorAshIconColorSecondary] = {kColorAshTextColorSecondary};
   mixer[kColorAshIconColorAlert] = {kColorAshTextColorAlert};
@@ -170,8 +163,8 @@
                                          ? ui::ColorTransform(SK_ColorWHITE)
                                          : ui::ColorTransform(SK_ColorBLACK);
   mixer[kColorAshBatteryBadgeColor] = {kColorAshButtonLabelColorPrimary};
-  mixer[kColorAshSwitchAccessInnerStrokeColor] =
-      ui::ColorTransform(gfx::kGoogleBlue300);
+  mixer[kColorAshSwitchAccessInnerStrokeColor] = {
+      cros_tokens::kColorProminentDark};
   mixer[kColorAshSwitchAccessOuterStrokeColor] =
       ui::ColorTransform(gfx::kGoogleBlue900);
   mixer[kColorAshProgressBarColorForeground] = {kColorAshTextColorURL};
@@ -375,7 +368,8 @@
   AddControlsColors(mixer, key);
   AddContentColors(mixer, key);
 
-  mixer[ui::kColorAshActionLabelFocusRingEdit] = {gfx::kGoogleBlue300};
+  mixer[ui::kColorAshActionLabelFocusRingEdit] = {
+      cros_tokens::kColorProminentDark};
   mixer[ui::kColorAshActionLabelFocusRingError] = {gfx::kGoogleRed300};
   mixer[ui::kColorAshActionLabelFocusRingHover] =
       ui::SetAlpha(gfx::kGoogleGrey200, 0x60);
@@ -386,15 +380,16 @@
   mixer[ui::kColorAshAppListSeparator] =
       ui::SetAlpha(gfx::kGoogleGrey900, 0x24);
   mixer[ui::kColorAshArcInputMenuSeparator] = {SK_ColorGRAY};
-  mixer[ui::kColorAshEditFinishFocusRing] = {gfx::kGoogleBlue300};
+  mixer[ui::kColorAshEditFinishFocusRing] = {cros_tokens::kColorProminentDark};
   mixer[ui::kColorAshIconInOobe] = {kIconColorInOobe};
 
   // TODO(skau): Remove when dark/light mode launches.
-  mixer[ui::kColorAshAppListFocusRingCompat] = {gfx::kGoogleBlue600};
+  mixer[ui::kColorAshAppListFocusRingCompat] = {
+      cros_tokens::kColorProminentLight};
 
-  mixer[ui::kColorAshLightFocusRing] = {gfx::kGoogleBlue300};
+  mixer[ui::kColorAshLightFocusRing] = {cros_tokens::kColorProminentDark};
 
-  mixer[ui::kColorAshOnboardingFocusRing] = {gfx::kGoogleBlue300};
+  mixer[ui::kColorAshOnboardingFocusRing] = {cros_tokens::kColorProminentDark};
 
   if (!features::IsDarkLightModeEnabled()) {
     ash::ScopedLightModeAsDefault scoped_light_mode_as_default;
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 123abe6..d88d946 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -756,6 +756,8 @@
     "task/sequence_manager/thread_controller_with_message_pump_impl.h",
     "task/sequence_manager/time_domain.cc",
     "task/sequence_manager/time_domain.h",
+    "task/sequence_manager/timing_wheel.cc",
+    "task/sequence_manager/timing_wheel.h",
     "task/sequence_manager/wake_up_queue.cc",
     "task/sequence_manager/wake_up_queue.h",
     "task/sequence_manager/work_deduplicator.cc",
@@ -3271,6 +3273,7 @@
     "task/sequence_manager/test/mock_time_message_pump_unittest.cc",
     "task/sequence_manager/thread_controller_power_monitor_unittest.cc",
     "task/sequence_manager/thread_controller_with_message_pump_impl_unittest.cc",
+    "task/sequence_manager/timing_wheel_unittest.cc",
     "task/sequence_manager/wake_up_queue_unittest.cc",
     "task/sequence_manager/work_deduplicator_unittest.cc",
     "task/sequence_manager/work_queue_sets_unittest.cc",
diff --git a/base/task/post_job.cc b/base/task/post_job.cc
index a1d685f..04fed78a 100644
--- a/base/task/post_job.cc
+++ b/base/task/post_job.cc
@@ -127,6 +127,12 @@
       << "Join may not be called on Job with higher priority than the current "
          "thread.";
   UpdatePriority(internal::GetTaskPriorityForCurrentThread());
+  if (task_source_->GetRemainingConcurrency() != 0) {
+    // Make sure the task source is in the queue if not enough workers are
+    // contributing. This is necessary for CreateJob(...).Join(). This is a
+    // noop if the task source was already in the queue.
+    task_source_->delegate()->EnqueueJobTaskSource(task_source_);
+  }
   bool must_run = task_source_->WillJoin();
   while (must_run)
     must_run = task_source_->RunJoinTask();
diff --git a/base/task/post_job_unittest.cc b/base/task/post_job_unittest.cc
index b6ecf74..0faf40e3 100644
--- a/base/task/post_job_unittest.cc
+++ b/base/task/post_job_unittest.cc
@@ -8,11 +8,13 @@
 #include <iterator>
 #include <numeric>
 
+#include "base/barrier_closure.h"
 #include "base/task/test_task_traits_extension.h"
 #include "base/test/bind.h"
 #include "base/test/gtest_util.h"
 #include "base/test/task_environment.h"
 #include "base/test/test_timeouts.h"
+#include "base/test/test_waitable_event.h"
 #include "base/threading/platform_thread.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -34,10 +36,17 @@
 TEST(PostJobTest, CreateJobSimple) {
   test::TaskEnvironment task_environment;
   std::atomic_size_t num_tasks_to_run(4);
+  TestWaitableEvent threads_continue;
+  RepeatingClosure barrier = BarrierClosure(
+      num_tasks_to_run, BindLambdaForTesting([&threads_continue]() {
+        threads_continue.Signal();
+      }));
   bool job_started = false;
   auto handle =
       CreateJob(FROM_HERE, {}, BindLambdaForTesting([&](JobDelegate* delegate) {
                   EXPECT_TRUE(job_started);
+                  barrier.Run();
+                  threads_continue.Wait();
                   --num_tasks_to_run;
                 }),
                 BindLambdaForTesting([&](size_t /*worker_count*/) -> size_t {
diff --git a/base/task/sequence_manager/timing_wheel.cc b/base/task/sequence_manager/timing_wheel.cc
new file mode 100644
index 0000000..6c74254
--- /dev/null
+++ b/base/task/sequence_manager/timing_wheel.cc
@@ -0,0 +1,48 @@
+// 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/task/sequence_manager/timing_wheel.h"
+
+namespace base::sequence_manager::internal {
+
+////////////////////////////////////////////////////////////////////////////////
+// TimingWheelHandle
+
+TimingWheelHandle::TimingWheelHandle(TimingWheelHandle&& other) noexcept
+    : bucket_index_(std::exchange(other.bucket_index_, kInvalidIndex)),
+      element_index_(std::exchange(other.element_index_, kInvalidIndex)) {}
+
+TimingWheelHandle& TimingWheelHandle::operator=(
+    TimingWheelHandle&& other) noexcept {
+  bucket_index_ = std::exchange(other.bucket_index_, kInvalidIndex);
+  element_index_ = std::exchange(other.element_index_, kInvalidIndex);
+  return *this;
+}
+
+// static
+TimingWheelHandle TimingWheelHandle::Invalid() {
+  return TimingWheelHandle();
+}
+
+void TimingWheelHandle::Reset() {
+  bucket_index_ = kInvalidIndex;
+  element_index_ = kInvalidIndex;
+}
+
+bool TimingWheelHandle::IsValid() const {
+  return bucket_index_ != kInvalidIndex && element_index_ != kInvalidIndex;
+}
+
+size_t TimingWheelHandle::bucket_index() const {
+  return bucket_index_;
+}
+
+size_t TimingWheelHandle::element_index() const {
+  return element_index_;
+}
+
+TimingWheelHandle::TimingWheelHandle(size_t bucket_index, size_t element_index)
+    : bucket_index_(bucket_index), element_index_(element_index) {}
+
+}  // namespace base::sequence_manager::internal
diff --git a/base/task/sequence_manager/timing_wheel.h b/base/task/sequence_manager/timing_wheel.h
new file mode 100644
index 0000000..d31b966
--- /dev/null
+++ b/base/task/sequence_manager/timing_wheel.h
@@ -0,0 +1,254 @@
+// 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 BASE_TASK_SEQUENCE_MANAGER_TIMING_WHEEL_H_
+#define BASE_TASK_SEQUENCE_MANAGER_TIMING_WHEEL_H_
+
+#include <array>
+#include <limits>
+#include <memory>
+#include <vector>
+
+#include "base/notreached.h"
+#include "base/time/time.h"
+
+namespace base::sequence_manager::internal {
+
+// Intended as a wrapper around a |bucket_index_| and |element_element_index_|
+// in the vector storage backing a TimingWheel. A TimingWheelHandle is
+// associated with each element in a TimingWheel, and is maintained by
+// the timing wheel as the object moves around within it. It can be used to
+// subsequently remove the element, or update it in place.
+class BASE_EXPORT TimingWheelHandle {
+ public:
+  enum : size_t { kInvalidIndex = std::numeric_limits<size_t>::max() };
+
+  constexpr TimingWheelHandle() = default;
+
+  constexpr TimingWheelHandle(const TimingWheelHandle& other) = default;
+  TimingWheelHandle(TimingWheelHandle&& other) noexcept;
+
+  TimingWheelHandle& operator=(const TimingWheelHandle& other) = default;
+  TimingWheelHandle& operator=(TimingWheelHandle&& other) noexcept;
+
+  ~TimingWheelHandle() = default;
+
+  // Returns an invalid TimingWheelHandle.
+  static TimingWheelHandle Invalid();
+
+  // Resets this handle back to an invalid state.
+  void Reset();
+
+  bool IsValid() const;
+
+  // Accessors.
+  size_t bucket_index() const;
+  size_t element_index() const;
+
+ private:
+  template <typename T,
+            size_t WheelSize,
+            typename TimingWheelHandleAccessor,
+            TimeTicks (*GetDelayedRunTime)(const T&)>
+  friend class TimingWheel;
+
+  // Only TimingWheels can create valid TimingWheelHandles.
+  explicit TimingWheelHandle(size_t bucket_index, size_t element_index);
+
+  // The index of the bucket in the timing wheel where the element is in.
+  size_t bucket_index_ = kInvalidIndex;
+
+  // The index of the element in the bucket where the element is in.
+  size_t element_index_ = kInvalidIndex;
+};
+
+// This class implements a container that acts as timer queue where element are
+// associated with a delay. It provides efficient retrieval of earliest
+// elements. It also provides constant time element removal. To facilitate this,
+// each element has associated with it a TimingWheelHandle (an opaque wrapper
+// around the index at which the element is stored), which is maintained by the
+// wheel as elements move within it. Only elements whose delay is between
+// |time_delta_per_bucket_| and WheelSize*|time_delta_per_bucket_| can be
+// inserted in a TimingWheel. |T| is a typename for element. |WheelSize| is the
+// number of buckets this TimingWheel has. |TimingWheelHandleAccessor| is the
+// type of the object which under the hood manages the TimingWheelHandle.
+// |GetDelayedRunTime| is a function which returns the time when the element is
+// due at.
+template <typename T,
+          size_t WheelSize,
+          typename TimingWheelHandleAccessor,
+          TimeTicks (*GetDelayedRunTime)(const T&)>
+class TimingWheel {
+ public:
+  // Constructs a TimingWheel instance where each bucket corresponds to a
+  // TimeDelta of |time_delta_per_bucket_|.
+  TimingWheel(TimeDelta time_delta_per_bucket)
+      : time_delta_per_bucket_(time_delta_per_bucket),
+        last_updated_bucket_index_(0),
+        time_passed_(Microseconds(0)),
+        total_elements_(0) {}
+
+  TimingWheel(TimingWheel&&) = delete;
+  TimingWheel& operator=(TimingWheel&&) = delete;
+
+  TimingWheel(const TimingWheel&) = delete;
+  TimingWheel& operator=(const TimingWheel&) = delete;
+
+  ~TimingWheel() = default;
+
+  // Inserts the |element| into the bucket based on its delay. This is the delay
+  // relative to a baseline implied by the last call to
+  // |AdvanceTimeAndRemoveExpiredElements| method.
+  typename std::vector<T>::const_iterator Insert(T element,
+                                                 const TimeDelta delay) {
+    DCHECK_GE(delay, time_delta_per_bucket_);
+    DCHECK_LT(delay, time_delta_per_bucket_ * WheelSize);
+
+    const size_t bucket_index = CalculateBucketIndex(delay);
+    auto& bucket = buckets_[bucket_index];
+    bucket.push_back(std::move(element));
+    const size_t element_index = bucket.size() - 1;
+
+    // Sets the handle for the element.
+    timing_wheel_handle_accessor.SetTimingWheelHandle(
+        &buckets_[bucket_index][element_index],
+        TimingWheelHandle(bucket_index, element_index));
+
+    total_elements_ += 1;
+    return bucket.cend() - 1;
+  }
+
+  // Removes the element which holds this |handle|.
+  void Remove(TimingWheelHandle handle) {
+    DCHECK(handle.IsValid());
+
+    const size_t bucket_index = handle.bucket_index();
+    const size_t element_index = handle.element_index();
+    DCHECK(IsBounded(bucket_index, element_index));
+
+    auto& bucket = buckets_[bucket_index];
+    const size_t last_index_of_bucket = bucket.size() - 1;
+
+    // Swaps the element's position with the last element for removal. The
+    // swapped element is assigned with an updated handle.
+    if (element_index != last_index_of_bucket) {
+      timing_wheel_handle_accessor.SetTimingWheelHandle(
+          &bucket[last_index_of_bucket],
+          TimingWheelHandle(bucket_index, element_index));
+      std::swap(bucket[element_index], bucket[last_index_of_bucket]);
+    }
+
+    // The handle of the last element doesn't need to be cleared since the
+    // element is destroyed right after.
+    bucket.pop_back();
+    total_elements_ -= 1;
+  }
+
+  // Updates the internal state to reflect the latest wakeup and returns the
+  // expired elements through an out-parameter so that the caller can keep using
+  // the same vector when advancing multiple TimingWheels.
+  void AdvanceTimeAndRemoveExpiredElements(const TimeDelta time_delta,
+                                           std::vector<T>& expired_elements) {
+    const size_t nb_buckets_passed =
+        (time_passed_ + time_delta) / time_delta_per_bucket_ + 1;
+    const size_t new_bucket_index =
+        (last_updated_bucket_index_ + nb_buckets_passed) % WheelSize;
+    const TimeDelta new_time_passed =
+        (time_passed_ + time_delta) % time_delta_per_bucket_;
+
+    // Ensures each bucket is iterated over at most once if |nb_buckets_passed|
+    // is bigger than the total number of buckets.
+    const size_t nb_buckets_to_traverse =
+        std::min(nb_buckets_passed, WheelSize);
+    for (size_t i = 0; i < nb_buckets_to_traverse; i++) {
+      last_updated_bucket_index_ = (last_updated_bucket_index_ + 1) % WheelSize;
+      ExtractElementsFromBucket(last_updated_bucket_index_, expired_elements);
+    }
+
+    last_updated_bucket_index_ = new_bucket_index;
+    time_passed_ = new_time_passed;
+  }
+
+  // Returns the earliest due element.
+  typename std::vector<T>::const_reference Top() {
+    DCHECK(total_elements_ != 0);
+    for (size_t i = 0; i < WheelSize; i++) {
+      const size_t bucket_index = (i + last_updated_bucket_index_) % WheelSize;
+      auto& bucket = buckets_[bucket_index];
+      if (bucket.size() == 0) {
+        continue;
+      }
+
+      auto it = std::min_element(
+          bucket.begin(), bucket.end(), [](const T& a, const T& b) {
+            // return a.delayed_run_time > b.delayed_run_time;
+            return GetDelayedRunTime(a) > GetDelayedRunTime(b);
+          });
+      return *it;
+    }
+
+    NOTREACHED();
+    return buckets_[0].back();
+  }
+
+  TimeDelta time_delta_per_bucket() { return time_delta_per_bucket_; }
+  size_t total_elements() { return total_elements_; }
+
+ private:
+  // Checks if the |bucket_index| and |element_index| is bounded.
+  bool IsBounded(const size_t bucket_index, const size_t element_index) const {
+    return bucket_index < WheelSize &&
+           element_index < buckets_[bucket_index].size();
+  }
+
+  // Calculates the index at which a task with |delay| should be inserted in.
+  size_t CalculateBucketIndex(const TimeDelta delay) const {
+    const size_t nb_buckets_passed =
+        (delay + time_passed_) / time_delta_per_bucket_;
+    const size_t bucket_index = last_updated_bucket_index_ + nb_buckets_passed;
+
+    // |bucket_index| should not be more than |WheelSize|.
+    return bucket_index % WheelSize;
+  }
+
+  // Removes the elements from the index in |buckets_| and returns the
+  // expired elements through an out-parameter.
+  void ExtractElementsFromBucket(const size_t bucket_index,
+                                 std::vector<T>& expired_elements) {
+    std::vector<T>& bucket = buckets_[bucket_index];
+    expired_elements.reserve(expired_elements.size() + bucket.size());
+
+    for (auto& element : bucket) {
+      timing_wheel_handle_accessor.ClearTimingWheelHandle(&element);
+      expired_elements.push_back(std::move(element));
+    }
+
+    total_elements_ -= bucket.size();
+    bucket.clear();
+  }
+
+  TimingWheelHandleAccessor timing_wheel_handle_accessor;
+
+  // The time period each bucket contains.
+  const TimeDelta time_delta_per_bucket_;
+
+  // The buckets where the elements are added according to their delay.
+  std::array<std::vector<T>, WheelSize> buckets_;
+
+  // The index of the bucket that was last updated. This helps in Inserting and
+  // expired elements.
+  size_t last_updated_bucket_index_;
+
+  // The time passed unaccounted for after updating
+  // |last_updated_bucket_index_|. This will be aggregated with the
+  // |time_passed_| at the next wakeup.
+  TimeDelta time_passed_;
+
+  // The number of elements in |buckets_|.
+  size_t total_elements_;
+};
+
+}  // namespace base::sequence_manager::internal
+
+#endif
diff --git a/base/task/sequence_manager/timing_wheel_unittest.cc b/base/task/sequence_manager/timing_wheel_unittest.cc
new file mode 100644
index 0000000..cdbf9f3
--- /dev/null
+++ b/base/task/sequence_manager/timing_wheel_unittest.cc
@@ -0,0 +1,296 @@
+// 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 <array>
+#include <vector>
+
+#include "base/task/sequence_manager/timing_wheel.h"
+
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace base::sequence_manager::internal {
+
+namespace {
+
+class Element {
+ public:
+  Element(TimeTicks delayed_run_time)
+      : delayed_run_time(delayed_run_time),
+        handle_(std::make_unique<TimingWheelHandle>()) {}
+
+  // Implementation of TimingWheel contract.
+  void SetTimingWheelHandle(TimingWheelHandle handle) {
+    DCHECK(handle.IsValid());
+    if (handle_)
+      *handle_ = handle;
+  }
+  void ClearTimingWheelHandle() {
+    if (handle_)
+      handle_->Reset();
+  }
+
+  TimingWheelHandle* handle() const { return handle_.get(); }
+
+  TimeTicks delayed_run_time;
+
+ private:
+  std::unique_ptr<TimingWheelHandle> handle_;
+};
+
+// The default TimingWheelHandleAccessor, which simply forwards calls to the
+// underlying type.
+template <typename T>
+struct TimingWheelHandleAccessor {
+  void SetTimingWheelHandle(T* element, TimingWheelHandle handle) const {
+    element->SetTimingWheelHandle(handle);
+  }
+  void ClearTimingWheelHandle(T* element) const {
+    element->ClearTimingWheelHandle();
+  }
+};
+
+// Gets the delayed run time of the |element|.
+template <typename T>
+TimeTicks GetDelayedRunTime(const T& element) {
+  return element.delayed_run_time;
+}
+
+// The total number of buckets that we use for the TimingWheel in all the unit
+// tests.
+const size_t kWheelSize = 100;
+
+// The time period used for each bucket in the TimingWheel in all the unit
+// tests.
+const TimeDelta kBucketTimeDelta = Microseconds(500);
+
+// The TimingWheel has an index which points to the last updated bucket. On
+// initialization, the index points at bucket 0. The immediate
+// insertable bucket is always the bucket after the index. Hence, index 1 is
+// considered the first bucket. Suppose, the timing wheel is updated and the
+// index now points at Index X. This would mean that while the index is
+// pointing at Index X, no element can be inserted at Index X.
+const size_t kFirstBucketIndex = 1;
+
+// The index of the last bucket in the TimingWheel
+const size_t kLastBucketIndex = kWheelSize - 1;
+
+}  // namespace
+
+// Tests the construction of the object.
+TEST(TimingWheelTest, Initialize) {
+  TimingWheel<Element, kWheelSize, TimingWheelHandleAccessor<Element>,
+              GetDelayedRunTime>
+      timing_wheel(kBucketTimeDelta);
+
+  EXPECT_EQ(timing_wheel.time_delta_per_bucket(), kBucketTimeDelta);
+  EXPECT_EQ(timing_wheel.total_elements(), 0u);
+}
+
+// Tests whether an element can be added to the first bucket.
+TEST(TimingWheelTest, InsertElement) {
+  TimingWheel<Element, kWheelSize, TimingWheelHandleAccessor<Element>,
+              GetDelayedRunTime>
+      timing_wheel(kBucketTimeDelta);
+  const TimeTicks baseline = TimeTicks::Now();
+
+  // Pick a time delta that ensures the element is added to the first bucket.
+  const TimeDelta kTestDelay = kFirstBucketIndex * kBucketTimeDelta;
+
+  const auto it = timing_wheel.Insert({baseline + kTestDelay}, kTestDelay);
+  const TimingWheelHandle* handle = it->handle();
+
+  EXPECT_EQ(handle->element_index(), 0u);
+  EXPECT_EQ(handle->bucket_index(), kFirstBucketIndex);
+  EXPECT_EQ(timing_wheel.total_elements(), 1u);
+}
+
+// Tests advancing time by a delta equal to the wheel's complete time delta.
+TEST(TimingWheelTest, AdvancingFullWheel) {
+  TimingWheel<Element, kWheelSize, TimingWheelHandleAccessor<Element>,
+              GetDelayedRunTime>
+      timing_wheel(kBucketTimeDelta);
+  const TimeTicks baseline = TimeTicks::Now();
+  const TimeDelta kTimePassed = kBucketTimeDelta * kLastBucketIndex;
+
+  // Pick time delta that ensures the elements are added to the last bucket.
+  const TimeDelta kLastBucketMinDelay = kLastBucketIndex * kBucketTimeDelta;
+
+  timing_wheel.Insert({baseline + kLastBucketMinDelay}, kLastBucketMinDelay);
+
+  std::vector<Element> expired_elements;
+  timing_wheel.AdvanceTimeAndRemoveExpiredElements(kTimePassed,
+                                                   expired_elements);
+
+  EXPECT_EQ(expired_elements.size(), 1u);
+  EXPECT_EQ(timing_wheel.total_elements(), 0u);
+}
+
+// Tests advancing time by a delta greater than the wheel's complete time delta.
+TEST(TimingWheelTest, AdvancingMoreThanFullWheel) {
+  TimingWheel<Element, kWheelSize, TimingWheelHandleAccessor<Element>,
+              GetDelayedRunTime>
+      timing_wheel(kBucketTimeDelta);
+  std::vector<Element> expired_elements;
+  const TimeDelta kTimePassed =
+      kBucketTimeDelta * kWheelSize + kBucketTimeDelta;
+
+  timing_wheel.AdvanceTimeAndRemoveExpiredElements(kTimePassed,
+                                                   expired_elements);
+
+  EXPECT_EQ(timing_wheel.total_elements(), 0u);
+  EXPECT_EQ(expired_elements.size(), 0u);
+}
+
+// Tests whether multiple elements can be added to different buckets.
+TEST(TimingWheelTest, InsertMultipleElementsInDifferentBuckets) {
+  TimingWheel<Element, kWheelSize, TimingWheelHandleAccessor<Element>,
+              GetDelayedRunTime>
+      timing_wheel(kBucketTimeDelta);
+  const TimeTicks baseline = TimeTicks::Now();
+  const size_t kBucketIndex1 = 50;
+  const size_t kBucketIndex2 = 75;
+  const TimeDelta kTestDelay1 = kBucketIndex1 * kBucketTimeDelta;
+  const TimeDelta kTestDelay2 = kBucketIndex2 * kBucketTimeDelta;
+
+  // Insert five elements that are due before |kTestDelay1|.
+  timing_wheel.Insert({baseline + kTestDelay1}, kTestDelay1);
+  timing_wheel.Insert({baseline + kTestDelay1 - Milliseconds(2)}, kTestDelay1);
+  timing_wheel.Insert({baseline + kTestDelay1 - Milliseconds(5)}, kTestDelay1);
+  timing_wheel.Insert({baseline + kTestDelay1 - Milliseconds(10)}, kTestDelay1);
+  timing_wheel.Insert({baseline + kTestDelay1 - Milliseconds(10)}, kTestDelay1);
+
+  // Insert two elements that are due after |kTestDelay1|.
+  timing_wheel.Insert({baseline + kTestDelay2 - Milliseconds(4)}, kTestDelay2);
+  timing_wheel.Insert({baseline + kTestDelay2}, kTestDelay2);
+
+  std::vector<Element> expired_elements;
+
+  // Advances time by |kTestDelay1| so that all the elements except the last
+  // two can be picked up.
+  timing_wheel.AdvanceTimeAndRemoveExpiredElements(kTestDelay1,
+                                                   expired_elements);
+  EXPECT_EQ(expired_elements.size(), 5u);
+  EXPECT_EQ(timing_wheel.total_elements(), 2u);
+
+  // Need to advance time by at least (kTestDelay2 - kTestDelay1) to pick the
+  // last elements.
+  timing_wheel.AdvanceTimeAndRemoveExpiredElements(kTestDelay2 - kTestDelay1,
+                                                   expired_elements);
+  EXPECT_EQ(expired_elements.size(), 7u);
+  EXPECT_EQ(timing_wheel.total_elements(), 0u);
+}
+
+// Tests whether multiple elements that expire at the same time can be added
+// to the same buckets.
+TEST(TimingWheelTest, InsertMultipleSimilarElementsInSameBucket) {
+  TimingWheel<Element, kWheelSize, TimingWheelHandleAccessor<Element>,
+              GetDelayedRunTime>
+      timing_wheel(kBucketTimeDelta);
+  const TimeTicks baseline = TimeTicks::Now();
+  const size_t kBucketIndex = 15;
+  const TimeDelta kTestDelay = kBucketIndex * kBucketTimeDelta;
+
+  timing_wheel.Insert({baseline + kTestDelay}, kTestDelay);
+  timing_wheel.Insert({baseline + kTestDelay}, kTestDelay);
+
+  std::vector<Element> expired_elements;
+  timing_wheel.AdvanceTimeAndRemoveExpiredElements(kTestDelay,
+                                                   expired_elements);
+  EXPECT_EQ(expired_elements.size(), 2u);
+  EXPECT_EQ(timing_wheel.total_elements(), 0u);
+}
+
+// Tests the circular nature of the timing wheel, and ensure that when the
+// current index advances, the buckets before it can now be used for elements
+// whose deadline is greater than kBucketTimeDelta * kWheelSize.
+TEST(TimingWheelTest, InsertToLastBucketButNotLastIndex) {
+  TimingWheel<Element, kWheelSize, TimingWheelHandleAccessor<Element>,
+              GetDelayedRunTime>
+      timing_wheel(kBucketTimeDelta);
+  const TimeTicks baseline = TimeTicks::Now();
+  const TimeDelta kTimePassed = 2 * kBucketTimeDelta;
+  const TimeDelta kTestDelay = kLastBucketIndex * kBucketTimeDelta;
+  std::vector<Element> expired_elements;
+
+  // First advance time to change the current index of the wheel.
+  timing_wheel.AdvanceTimeAndRemoveExpiredElements(kTimePassed,
+                                                   expired_elements);
+  timing_wheel.Insert({baseline + kTestDelay + kTimePassed}, kTestDelay);
+
+  // Advance time to pick up the element.
+  timing_wheel.AdvanceTimeAndRemoveExpiredElements(kTestDelay,
+                                                   expired_elements);
+  EXPECT_EQ(expired_elements.size(), 1u);
+}
+
+// Tests removal of an element using its handle.
+TEST(TimingWheelTest, RemoveElement) {
+  TimingWheel<Element, kWheelSize, TimingWheelHandleAccessor<Element>,
+              GetDelayedRunTime>
+      timing_wheel(kBucketTimeDelta);
+  const TimeTicks baseline = TimeTicks::Now();
+  const TimeDelta kLastBucketMinDelay = kLastBucketIndex * kBucketTimeDelta;
+  const TimeDelta kLastBucketMaxDelay =
+      (kLastBucketIndex + 1) * kBucketTimeDelta - Microseconds(1u);
+  const TimeDelta kTimePassed = kBucketTimeDelta * kLastBucketIndex;
+
+  timing_wheel.Insert({baseline + kLastBucketMinDelay}, kLastBucketMinDelay);
+  const TimingWheelHandle* handle =
+      timing_wheel
+          .Insert({baseline + kLastBucketMaxDelay}, kLastBucketMaxDelay)
+          ->handle();
+  timing_wheel.Remove(*handle);
+  EXPECT_EQ(timing_wheel.total_elements(), 1u);
+
+  std::vector<Element> expired_elements;
+  timing_wheel.AdvanceTimeAndRemoveExpiredElements(kTimePassed,
+                                                   expired_elements);
+
+  EXPECT_EQ(expired_elements.size(), 1u);
+  EXPECT_EQ(timing_wheel.total_elements(), 0u);
+}
+
+// Tests whether we get the earliest due element from two elements in different
+// buckets.
+TEST(TimingWheelTest, TopElementfromDifferentElements) {
+  TimingWheel<Element, kWheelSize, TimingWheelHandleAccessor<Element>,
+              GetDelayedRunTime>
+      timing_wheel(kBucketTimeDelta);
+  const TimeTicks baseline = TimeTicks::Now();
+  const TimeDelta kTestDelay1 = kBucketTimeDelta;
+  const TimeDelta kTestDelay2 = kBucketTimeDelta * 2;
+
+  Element element1(baseline + kTestDelay1);
+  Element element2(baseline + kTestDelay2);
+  const TimingWheelHandle* handle = element1.handle();
+
+  timing_wheel.Insert(std::move(element1), kTestDelay1);
+  timing_wheel.Insert(std::move(element2), kTestDelay2);
+
+  EXPECT_EQ(handle, timing_wheel.Top().handle());
+  EXPECT_EQ(timing_wheel.total_elements(), 2u);
+}
+
+// Tests whether we get the earliest due element when two elements are in the
+// same bucket.
+TEST(TimingWheelTest, TopElementFromSimilarElements) {
+  TimingWheel<Element, kWheelSize, TimingWheelHandleAccessor<Element>,
+              GetDelayedRunTime>
+      timing_wheel(kBucketTimeDelta);
+  const TimeTicks baseline = TimeTicks::Now();
+  const TimeDelta kTestDelay1 = kBucketTimeDelta;
+  const TimeDelta kTestDelay2 = kBucketTimeDelta + Milliseconds(1);
+  Element element1(baseline + kTestDelay1);
+  Element element2(baseline + kTestDelay2);
+  const TimingWheelHandle* handle = element1.handle();
+
+  timing_wheel.Insert(std::move(element1), kTestDelay1);
+  timing_wheel.Insert(std::move(element2), kTestDelay2);
+
+  EXPECT_EQ(handle, timing_wheel.Top().handle());
+  EXPECT_EQ(timing_wheel.total_elements(), 2u);
+}
+
+}  // namespace base::sequence_manager::internal
diff --git a/base/task/thread_pool/sequence.cc b/base/task/thread_pool/sequence.cc
index 052e441..6ebde82 100644
--- a/base/task/thread_pool/sequence.cc
+++ b/base/task/thread_pool/sequence.cc
@@ -25,13 +25,29 @@
 Sequence::Transaction::~Transaction() = default;
 
 bool Sequence::Transaction::WillPushTask() const {
-  // If the sequence is empty before a Task is inserted into it and the pool is
-  // not running any task from this sequence, it should be queued.
-  // Otherwise, one of these must be true:
+  // A sequence should be queued if it's not already in the queue and the pool
+  // is not running any task from it. Otherwise, one of these must be true:
   // - The Sequence is already queued, or,
   // - A thread is running a Task from the Sequence. It is expected to reenqueue
   //   the Sequence once it's done running the Task.
-  return sequence()->queue_.empty() && !sequence()->has_worker_;
+  // Access to |current_location_| can get racy between calls to WillRunTask()
+  // and WillPushTask(). WillRunTask() updates |current_location_| from
+  // kImmediateQueue to kInWorker, it can only be called on sequence when
+  // sequence is already in immediate queue so this behavior is always
+  // guaranteed. Hence, WillPushTask behavior won't be affected no matter if
+  // WillRunTask runs before or after it's called since it returns false
+  // whether |current_location_| is set to kImmediateQueue or kInWorker.
+  auto current_location =
+      sequence()->current_location_.load(std::memory_order_relaxed);
+  if (current_location == Sequence::SequenceLocation::kImmediateQueue) {
+    return false;
+  }
+
+  if (current_location == Sequence::SequenceLocation::kInWorker) {
+    return false;
+  }
+
+  return true;
 }
 
 void Sequence::Transaction::PushTask(Task task) {
@@ -54,6 +70,10 @@
   }
   sequence()->queue_.push(std::move(task));
 
+  if (should_be_queued)
+    sequence()->current_location_.store(
+        Sequence::SequenceLocation::kImmediateQueue, std::memory_order_relaxed);
+
   // AddRef() matched by manual Release() when the sequence has no more tasks
   // to run (in DidProcessTask() or Clear()).
   if (should_be_queued && sequence()->task_runner())
@@ -63,13 +83,17 @@
 TaskSource::RunStatus Sequence::WillRunTask() {
   // There should never be a second call to WillRunTask() before DidProcessTask
   // since the RunStatus is always marked a saturated.
-  DCHECK(!has_worker_);
+  DCHECK(current_location_.load(std::memory_order_relaxed) !=
+         Sequence::SequenceLocation::kInWorker);
 
-  // It's ok to access |has_worker_| outside of a Transaction since
+  // It's ok to access |current_location_| outside of a Transaction since
   // WillRunTask() is externally synchronized, always called in sequence with
-  // TakeTask() and DidProcessTask() and only called if |!queue_.empty()|, which
-  // means it won't race with WillPushTask()/PushTask().
-  has_worker_ = true;
+  // TakeTask() and DidProcessTask() and only called if sequence is in immediate
+  // queue. Even though it can get racy with WillPushTask()/PushTask(), the
+  // behavior of each function is not affected as explained in WillPushTask().
+  current_location_.store(Sequence::SequenceLocation::kInWorker,
+                          std::memory_order_relaxed);
+
   return RunStatus::kAllowedSaturated;
 }
 
@@ -80,7 +104,8 @@
 Task Sequence::TakeTask(TaskSource::Transaction* transaction) {
   CheckedAutoLockMaybe auto_lock(transaction ? nullptr : &lock_);
 
-  DCHECK(has_worker_);
+  DCHECK(current_location_.load(std::memory_order_relaxed) ==
+         Sequence::SequenceLocation::kInWorker);
   DCHECK(!queue_.empty());
   DCHECK(queue_.front().task);
 
@@ -96,13 +121,19 @@
   CheckedAutoLockMaybe auto_lock(transaction ? nullptr : &lock_);
   // There should never be a call to DidProcessTask without an associated
   // WillRunTask().
-  DCHECK(has_worker_);
-  has_worker_ = false;
+  DCHECK(current_location_.load(std::memory_order_relaxed) ==
+         Sequence::SequenceLocation::kInWorker);
+
   // See comment on TaskSource::task_runner_ for lifetime management details.
   if (queue_.empty()) {
     ReleaseTaskRunner();
+    current_location_.store(Sequence::SequenceLocation::kNone,
+                            std::memory_order_relaxed);
     return false;
   }
+
+  current_location_.store(Sequence::SequenceLocation::kImmediateQueue,
+                          std::memory_order_relaxed);
   // Let the caller re-enqueue this non-empty Sequence regardless of
   // |run_result| so it can continue churning through this Sequence's tasks and
   // skip/delete them in the proper scope.
@@ -118,8 +149,11 @@
 Task Sequence::Clear(TaskSource::Transaction* transaction) {
   CheckedAutoLockMaybe auto_lock(transaction ? nullptr : &lock_);
   // See comment on TaskSource::task_runner_ for lifetime management details.
-  if (!queue_.empty() && !has_worker_)
+  if (!queue_.empty() && current_location_.load(std::memory_order_relaxed) !=
+                             Sequence::SequenceLocation::kInWorker) {
     ReleaseTaskRunner();
+  }
+
   return Task(FROM_HERE,
               base::BindOnce(
                   [](base::queue<Task> queue) {
@@ -153,5 +187,9 @@
   return {token_, &sequence_local_storage_};
 }
 
+Sequence::SequenceLocation Sequence::GetCurrentLocationForTesting() {
+  return current_location_.load(std::memory_order_relaxed);
+}
+
 }  // namespace internal
 }  // namespace base
diff --git a/base/task/thread_pool/sequence.h b/base/task/thread_pool/sequence.h
index 2d85bac..8e65d695 100644
--- a/base/task/thread_pool/sequence.h
+++ b/base/task/thread_pool/sequence.h
@@ -67,6 +67,19 @@
     explicit Transaction(Sequence* sequence);
   };
 
+  // This indicates where a sequence is stored, used by Sequence to keep track
+  // of its status.
+  enum class SequenceLocation {
+    // Sequence is not present in any queue.
+    kNone,
+    // Sequence is present in queue of immediate sequences.
+    kImmediateQueue,
+    // Sequence is present in queue of delayed sequences.
+    kDelayedQueue,
+    // Sequence is being run by a worker.
+    kInWorker,
+  };
+
   // |traits| is metadata that applies to all Tasks in the Sequence.
   // |task_runner| is a reference to the TaskRunner feeding this TaskSource.
   // |task_runner| can be nullptr only for tasks with no TaskRunner, in which
@@ -95,6 +108,8 @@
     return &sequence_local_storage_;
   }
 
+  SequenceLocation GetCurrentLocationForTesting();
+
  private:
   ~Sequence() override;
 
@@ -114,11 +129,13 @@
 
   std::atomic<TimeTicks> ready_time_{TimeTicks()};
 
-  // True if a worker is currently associated with a Task from this Sequence.
-  bool has_worker_ = false;
-
   // Holds data stored through the SequenceLocalStorageSlot API.
   SequenceLocalStorageMap sequence_local_storage_;
+
+  // This member will hold the current location of the sequence at any time.
+  // At instantiation, the sequence is not put in any queue yet so the
+  // sequence location is set to |kNone|.
+  std::atomic<SequenceLocation> current_location_{SequenceLocation::kNone};
 };
 
 }  // namespace internal
diff --git a/base/task/thread_pool/sequence_unittest.cc b/base/task/thread_pool/sequence_unittest.cc
index 990c7da2..bddc48b 100644
--- a/base/task/thread_pool/sequence_unittest.cc
+++ b/base/task/thread_pool/sequence_unittest.cc
@@ -233,5 +233,147 @@
   });
 }
 
+// Verify that the sequence sets its current location correctly depending on how
+// it's interacted with.
+TEST(ThreadPoolSequenceTest, PushTakeRemoveTasksWithLocationSetting) {
+  testing::StrictMock<MockTask> mock_task_a;
+  testing::StrictMock<MockTask> mock_task_b;
+
+  scoped_refptr<Sequence> sequence =
+      MakeRefCounted<Sequence>(TaskTraits(TaskPriority::BEST_EFFORT), nullptr,
+                               TaskSourceExecutionMode::kParallel);
+
+  // sequence location is kNone at creation.
+  EXPECT_EQ(sequence->GetCurrentLocationForTesting(),
+            Sequence::SequenceLocation::kNone);
+
+  Sequence::Transaction sequence_transaction(sequence->BeginTransaction());
+
+  // Push task A in the sequence. WillPushTask() should return true
+  // since sequence is empty.
+  EXPECT_TRUE(sequence_transaction.WillPushTask());
+  sequence_transaction.PushTask(CreateTask(&mock_task_a));
+
+  // WillPushTask is called when a new task is about to be pushed and sequence
+  // will be put in the priority queue or is already in it.
+  EXPECT_EQ(sequence->GetCurrentLocationForTesting(),
+            Sequence::SequenceLocation::kImmediateQueue);
+
+  // Push task B into the sequence. WillPushTask() should return false.
+  EXPECT_FALSE(sequence_transaction.WillPushTask());
+  sequence_transaction.PushTask(CreateTask(&mock_task_b));
+
+  // WillPushTask is called when a new task is about to be pushed and sequence
+  // will be put in the priority queue or is already in it. Sequence location
+  // should be kImmediateQueue.
+  EXPECT_EQ(sequence->GetCurrentLocationForTesting(),
+            Sequence::SequenceLocation::kImmediateQueue);
+
+  auto registered_task_source =
+      RegisteredTaskSource::CreateForTesting(sequence);
+
+  registered_task_source.WillRunTask();
+
+  // WillRunTask typically indicate that a worker has called GetWork() and
+  // is ready to run a task so sequence location should have been changed
+  // to kInWorker.
+  EXPECT_EQ(sequence->GetCurrentLocationForTesting(),
+            Sequence::SequenceLocation::kInWorker);
+
+  // The next task we get when we call Sequence::TakeTask should be Task A.
+  absl::optional<Task> task =
+      registered_task_source.TakeTask(&sequence_transaction);
+
+  // Remove the empty slot. Sequence still has task B. This should return true.
+  EXPECT_TRUE(registered_task_source.DidProcessTask(&sequence_transaction));
+
+  // Sequence is not empty so it will be returned to the priority queue and its
+  // location should be updated to kImmediateQueue.
+  EXPECT_EQ(sequence->GetCurrentLocationForTesting(),
+            Sequence::SequenceLocation::kImmediateQueue);
+
+  registered_task_source.WillRunTask();
+
+  // WillRunTask typically indicate that a worker has called GetWork() and
+  // is ready to run a task so sequence location should have been changed
+  // to kInWorker.
+  EXPECT_EQ(sequence->GetCurrentLocationForTesting(),
+            Sequence::SequenceLocation::kInWorker);
+
+  task = registered_task_source.TakeTask(&sequence_transaction);
+
+  // Remove the empty slot. Sequence is be empty. This should return false.
+  EXPECT_FALSE(registered_task_source.DidProcessTask(&sequence_transaction));
+
+  // Sequence is empty so it won't be returned to the priority queue and its
+  // location should be updated to kNone.
+  EXPECT_EQ(sequence->GetCurrentLocationForTesting(),
+            Sequence::SequenceLocation::kNone);
+}
+
+// Verify that the sequence location stays kInWorker when new tasks are being
+// pushed while it's being processed.
+TEST(ThreadPoolSequenceTest, CheckSequenceLocationInWorker) {
+  testing::StrictMock<MockTask> mock_task_a;
+  testing::StrictMock<MockTask> mock_task_b;
+
+  scoped_refptr<Sequence> sequence =
+      MakeRefCounted<Sequence>(TaskTraits(TaskPriority::BEST_EFFORT), nullptr,
+                               TaskSourceExecutionMode::kParallel);
+
+  Sequence::Transaction sequence_transaction(sequence->BeginTransaction());
+
+  // Push task A in the sequence. WillPushTask() should return true
+  // since sequence is empty.
+  EXPECT_TRUE(sequence_transaction.WillPushTask());
+  sequence_transaction.PushTask(CreateTask(&mock_task_a));
+
+  auto registered_task_source =
+      RegisteredTaskSource::CreateForTesting(sequence);
+
+  registered_task_source.WillRunTask();
+
+  // The next task we get when we call Sequence::TakeTask should be Task A.
+  absl::optional<Task> task_a =
+      registered_task_source.TakeTask(&sequence_transaction);
+
+  // WillRunTask typically indicate that a worker has called GetWork() and
+  // is ready to run a task so sequence location should have been changed
+  // to kInWorker.
+  EXPECT_EQ(sequence->GetCurrentLocationForTesting(),
+            Sequence::SequenceLocation::kInWorker);
+
+  // Push task B into the sequence. WillPushTask() should return false.
+  EXPECT_FALSE(sequence_transaction.WillPushTask());
+  sequence_transaction.PushTask(CreateTask(&mock_task_b));
+
+  // Sequence is still being processed by a worker so pushing a new task
+  // shouldn't change its location. We should expect it to still be in worker.
+  EXPECT_EQ(sequence->GetCurrentLocationForTesting(),
+            Sequence::SequenceLocation::kInWorker);
+
+  // Remove the empty slot. Sequence still has task B. This should return true.
+  EXPECT_TRUE(registered_task_source.DidProcessTask(&sequence_transaction));
+
+  // Sequence is not empty so it will be returned to the priority queue and its
+  // location should be updated to kImmediateQueue.
+  EXPECT_EQ(sequence->GetCurrentLocationForTesting(),
+            Sequence::SequenceLocation::kImmediateQueue);
+
+  registered_task_source.WillRunTask();
+
+  // The next task we get when we call Sequence::TakeTask should be Task B.
+  absl::optional<Task> task_b =
+      registered_task_source.TakeTask(&sequence_transaction);
+
+  // Remove the empty slot. Sequence is be empty. This should return false.
+  EXPECT_FALSE(registered_task_source.DidProcessTask(&sequence_transaction));
+
+  // Sequence is empty so it won't be returned to the priority queue and its
+  // location should be updated to kNone.
+  EXPECT_EQ(sequence->GetCurrentLocationForTesting(),
+            Sequence::SequenceLocation::kNone);
+}
+
 }  // namespace internal
 }  // namespace base
diff --git a/build/config/android/config.gni b/build/config/android/config.gni
index e6eb587d..692a3af0 100644
--- a/build/config/android/config.gni
+++ b/build/config/android/config.gni
@@ -143,11 +143,7 @@
   # google_play_services_package contains the path where individual client
   # targets (e.g. google_play_services_base_java) are located.
   if (!defined(google_play_services_package)) {
-    if (is_cast_android && chromecast_branding != "public") {
-      google_play_services_package = "//chromecast/internal/android/prebuilt/google-play-services-first-party"
-    } else {
-      google_play_services_package = "//third_party/android_deps"
-    }
+    google_play_services_package = "//third_party/android_deps"
   }
 
   if (!defined(dagger_java_target)) {
diff --git a/build/config/chromecast/BUILD.gn b/build/config/chromecast/BUILD.gn
index 7507aae..4f0f2b75 100644
--- a/build/config/chromecast/BUILD.gn
+++ b/build/config/chromecast/BUILD.gn
@@ -45,11 +45,6 @@
     ldflags = [ "-Wl,-rpath=${target_rpath}" ]
   }
 
-  if (chromecast_branding != "public") {
-    # Some internal x64 builds need additional rpath and dynamic-linker config.
-    configs += [ "//chromecast/internal/build/config/ldconfig" ]
-  }
-
   # Binaries which don't live in the same directory as Chrome component
   # libraries may still depend on them. Explicitly add the component library
   # directory to the rpath for the component build.
diff --git a/build/config/chromecast_build.gni b/build/config/chromecast_build.gni
index e06dba9..6d8091d 100644
--- a/build/config/chromecast_build.gni
+++ b/build/config/chromecast_build.gni
@@ -15,11 +15,6 @@
   # for specific types of devices.
   is_chromecast = false
 
-  # chromecast_branding is used to include or exclude Google-branded components.
-  # Set it to "public" for a Chromium build.
-  # TODO(crbug.com/1293517): Remove usages in Chromium and move to //chromecast.
-  chromecast_branding = "public"
-
   # Set this true for an audio-only Chromecast build.
   # TODO(crbug.com/1293538): Replace with a buildflag for speaker-only builds not
   # specific to Cast.
diff --git a/build/fuchsia/linux_internal.sdk.sha1 b/build/fuchsia/linux_internal.sdk.sha1
index 30e799ad..68e22d64 100644
--- a/build/fuchsia/linux_internal.sdk.sha1
+++ b/build/fuchsia/linux_internal.sdk.sha1
@@ -1 +1 @@
-9.20220802.2.1
+9.20220802.3.1
diff --git a/chrome/VERSION b/chrome/VERSION
index 3b37737..7389ee9 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=106
 MINOR=0
-BUILD=5216
+BUILD=5217
 PATCH=0
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 a0b499a..cf514f9 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -1235,6 +1235,8 @@
             // be the first thing shown after startup.
             setTrackColdStartupMetrics(false);
             showOverview(StartSurfaceState.SHOWING_START);
+            mAppLaunchDrawBlocker.onOverviewPageAvailable(
+                    mOverviewShownOnStart && !isInstantStartEnabled());
             return;
         }
 
@@ -1745,11 +1747,7 @@
                 getTabReparentingControllerSupplier(),
                 // TODO(sinansahin): This currently only checks for incognito extras in the intent.
                 // We should make it more robust by using more signals.
-                IntentHandler.hasAnyIncognitoExtra(getIntent().getExtras()), mBackPressManager,
-                mCallbackController.makeCancelable(
-                        ()
-                                -> mAppLaunchDrawBlocker.onOverviewPageAvailable(
-                                        mOverviewShownOnStart && !isInstantStartEnabled())));
+                IntentHandler.hasAnyIncognitoExtra(getIntent().getExtras()), mBackPressManager);
     }
 
     @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
index 5e7d157..467b54902 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
@@ -532,7 +532,7 @@
                 /* statusBarColorProvider= */ this, getIntentRequestTracker(),
                 mTabReparentingControllerSupplier,
                 /*ephemeralTabCoordinatorSupplier=*/new ObservableSupplierImpl<>(),
-                false, mBackPressManager, /* unblockDrawForOverviewPageRunnable= */ null);
+                false, mBackPressManager);
         // clang-format on
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabRootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabRootUiCoordinator.java
index 1b6054e..b1ceee9 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabRootUiCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabRootUiCoordinator.java
@@ -155,8 +155,7 @@
                 snackbarManagerSupplier, activityType,
                 isInOverviewModeSupplier, isWarmOnResumeSupplier, appMenuDelegate,
                 statusBarColorProvider, intentRequestTracker, new OneshotSupplierImpl<>(),
-                ephemeralTabCoordinatorSupplier, false, backPressManager,
-                /* unblockDrawForOverviewPageRunnable= */ null);
+                ephemeralTabCoordinatorSupplier, false, backPressManager);
         // clang-format on
         mToolbarCoordinator = customTabToolbarCoordinator;
         mNavigationController = customTabNavigationController;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java
index 24f1334..c095f41 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java
@@ -99,7 +99,6 @@
 import org.chromium.chrome.browser.tasks.tab_management.UndoGroupSnackbarController;
 import org.chromium.chrome.browser.toolbar.ToolbarButtonInProductHelpController;
 import org.chromium.chrome.browser.toolbar.ToolbarIntentMetadata;
-import org.chromium.chrome.browser.ui.AppLaunchDrawBlocker;
 import org.chromium.chrome.browser.ui.RootUiCoordinator;
 import org.chromium.chrome.browser.ui.appmenu.AppMenuBlocker;
 import org.chromium.chrome.browser.ui.appmenu.AppMenuDelegate;
@@ -249,10 +248,6 @@
      * @param tabReparentingControllerSupplier Supplier for the {@link TabReparentingController}.
      * @param initializeUiWithIncognitoColors Whether to initialize the UI with incognito colors.
      * @param backPressManager The {@link BackPressManager} handling back press.
-     * @param unblockDrawForOverviewPageRunnable The runnable for unblocking the {@link
-     *                                           AppLaunchDrawBlocker} which is specifically for
-     *                                           blocking draw on launch when overview page
-     *                                           is showing during startup.
      */
     public TabbedRootUiCoordinator(@NonNull AppCompatActivity activity,
             @Nullable Callback<Boolean> onOmniboxFocusChangedListener,
@@ -293,8 +288,7 @@
             @NonNull Supplier<InsetObserverView> insetObserverViewSupplier,
             @NonNull Function<Tab, Boolean> backButtonShouldCloseTabFn,
             OneshotSupplier<TabReparentingController> tabReparentingControllerSupplier,
-            boolean initializeUiWithIncognitoColors, @NonNull BackPressManager backPressManager,
-            @NonNull Runnable unblockDrawForOverviewPageRunnable) {
+            boolean initializeUiWithIncognitoColors, @NonNull BackPressManager backPressManager) {
         super(activity, onOmniboxFocusChangedListener, shareDelegateSupplier, tabProvider,
                 profileSupplier, bookmarkBridgeSupplier, tabBookmarkerSupplier,
                 contextualSearchManagerSupplier, tabModelSelectorSupplier, startSurfaceSupplier,
@@ -307,8 +301,7 @@
                 compositorViewHolderSupplier, tabContentManagerSupplier, snackbarManagerSupplier,
                 activityType, isInOverviewModeSupplier, isWarmOnResumeSupplier, appMenuDelegate,
                 statusBarColorProvider, intentRequestTracker, tabReparentingControllerSupplier,
-                ephemeralTabCoordinatorSupplier, initializeUiWithIncognitoColors, backPressManager,
-                unblockDrawForOverviewPageRunnable);
+                ephemeralTabCoordinatorSupplier, initializeUiWithIncognitoColors, backPressManager);
         mControlContainerHeightResource = controlContainerHeightResource;
         mInsetObserverViewSupplier = insetObserverViewSupplier;
         mBackButtonShouldCloseTabFn = backButtonShouldCloseTabFn;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
index 0b8bdbb..35108626 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
@@ -133,7 +133,6 @@
 import org.chromium.chrome.browser.toolbar.top.TopToolbarCoordinator;
 import org.chromium.chrome.browser.toolbar.top.TopToolbarInteractabilityManager;
 import org.chromium.chrome.browser.toolbar.top.ViewShiftingActionBarDelegate;
-import org.chromium.chrome.browser.ui.AppLaunchDrawBlocker;
 import org.chromium.chrome.browser.ui.TabObscuringHandler;
 import org.chromium.chrome.browser.ui.appmenu.AppMenuCoordinator;
 import org.chromium.chrome.browser.ui.appmenu.AppMenuDelegate;
@@ -293,8 +292,6 @@
     private StartSurface mStartSurface;
     private StartSurface.StateObserver mStartSurfaceStateObserver;
     private AppBarLayout.OnOffsetChangedListener mStartSurfaceHeaderOffsetChangeListener;
-    @Nullable
-    private Runnable mUnblockAppLaunchDrawRunnable;
 
     private OneshotSupplier<ToolbarIntentMetadata> mIntentMetadataOneshotSupplier;
     private OneshotSupplier<Boolean> mPromoShownOneshotSupplier;
@@ -383,10 +380,6 @@
      * @param ephemeralTabCoordinatorSupplier Supplies the {@link EphemeralTabCoordinator}.
      * @param initializeWithIncognitoColors Whether the toolbar should be initialized with incognito
      * @param backPressManager The {@link BackPressManager} handling back press gesture.
-     * @param unblockDrawForOverviewPageRunnable The runnable for unblocking the {@link
-     *                                           AppLaunchDrawBlocker} which is specifically for
-     *                                           blocking draw on launch when overview page
-     *                                           is showing during startup.
      */
     public ToolbarManager(AppCompatActivity activity, BrowserControlsSizer controlsSizer,
             FullscreenManager fullscreenManager, ToolbarControlContainer controlContainer,
@@ -423,8 +416,7 @@
             OneshotSupplier<TabReparentingController> tabReparentingControllerSupplier,
             @NonNull OmniboxPedalDelegate omniboxPedalDelegate,
             Supplier<EphemeralTabCoordinator> ephemeralTabCoordinatorSupplier,
-            boolean initializeWithIncognitoColors, @Nullable BackPressManager backPressManager,
-            @Nullable Runnable unblockDrawForOverviewPageRunnable) {
+            boolean initializeWithIncognitoColors, @Nullable BackPressManager backPressManager) {
         TraceEvent.begin("ToolbarManager.ToolbarManager");
         mActivity = activity;
         mWindowAndroid = windowAndroid;
@@ -451,7 +443,6 @@
         mSnackbarManager = snackbarManager;
         mTabReparentingControllerSupplier = tabReparentingControllerSupplier;
         mEphemeralTabCoordinatorSupplier = ephemeralTabCoordinatorSupplier;
-        mUnblockAppLaunchDrawRunnable = unblockDrawForOverviewPageRunnable;
 
         mIsProgressBarVisibleSupplier.set(!VrModuleProvider.getDelegate().isInVr());
         mVrModeObserver = new VrModeObserver() {
@@ -1011,10 +1002,6 @@
                 assert mLocationBar instanceof LocationBarCoordinator;
                 ((LocationBarCoordinator) mLocationBar).startAutocompletePrefetch();
             }
-            if (mUnblockAppLaunchDrawRunnable != null) {
-                mUnblockAppLaunchDrawRunnable.run();
-                mUnblockAppLaunchDrawRunnable = null;
-            }
         }
         mToolbar.setContentAttached(layoutType == LayoutType.BROWSING);
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java
index 0e380e6..0f3791ef 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java
@@ -125,6 +125,7 @@
 import org.chromium.chrome.browser.ui.appmenu.AppMenuCoordinator;
 import org.chromium.chrome.browser.ui.appmenu.AppMenuCoordinatorFactory;
 import org.chromium.chrome.browser.ui.appmenu.AppMenuDelegate;
+import org.chromium.chrome.browser.ui.appmenu.AppMenuObserver;
 import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager;
 import org.chromium.chrome.browser.ui.system.StatusBarColorController;
 import org.chromium.chrome.browser.ui.system.StatusBarColorController.StatusBarColorProvider;
@@ -296,9 +297,8 @@
     @Nullable
     private final BackPressManager mBackPressManager;
     @Nullable
-    private final Runnable mUnblockDrawForOverviewPageRunnable;
-    @Nullable
     private PageZoomCoordinator mPageZoomCoordinator;
+    private AppMenuObserver mAppMenuObserver;
 
     /**
      * Create a new {@link RootUiCoordinator} for the given activity.
@@ -343,10 +343,6 @@
      * @param ephemeralTabCoordinatorSupplier Supplies the {@link EphemeralTabCoordinator}.
      * @param initializeUiWithIncognitoColors Whether to initialize the UI with incognito colors.
      * @param backPressManager The {@link BackPressManager} handling back press.
-     * @param unblockDrawForOverviewPageRunnable The runnable for unblocking the {@link
-     *                                           AppLaunchDrawBlocker} which is specifically for
-     *                                           blocking draw on launch when overview page
-     *                                           is showing during startup.
      */
     public RootUiCoordinator(@NonNull AppCompatActivity activity,
             @Nullable Callback<Boolean> onOmniboxFocusChangedListener,
@@ -384,8 +380,7 @@
             @NonNull IntentRequestTracker intentRequestTracker,
             @NonNull OneshotSupplier<TabReparentingController> tabReparentingControllerSupplier,
             @NonNull Supplier<EphemeralTabCoordinator> ephemeralTabCoordinatorSupplier,
-            boolean initializeUiWithIncognitoColors, @Nullable BackPressManager backPressManager,
-            @Nullable Runnable unblockDrawForOverviewPageRunnable) {
+            boolean initializeUiWithIncognitoColors, @Nullable BackPressManager backPressManager) {
         mJankTracker = jankTracker;
         mCallbackController = new CallbackController();
         mActivity = activity;
@@ -413,7 +408,6 @@
         mTabReparentingControllerSupplier = tabReparentingControllerSupplier;
         mInitializeUiWithIncognitoColors = initializeUiWithIncognitoColors;
         mBackPressManager = backPressManager;
-        mUnblockDrawForOverviewPageRunnable = unblockDrawForOverviewPageRunnable;
 
         mMenuOrKeyboardActionController = menuOrKeyboardActionController;
         mMenuOrKeyboardActionController.registerMenuOrKeyboardActionHandler(this);
@@ -564,6 +558,10 @@
         if (mAppMenuCoordinator != null) {
             mAppMenuCoordinator.unregisterAppMenuBlocker(this);
             mAppMenuCoordinator.unregisterAppMenuBlocker(mAppMenuBlocker);
+
+            if (mAppMenuObserver != null) {
+                mAppMenuCoordinator.getAppMenuHandler().removeObserver(mAppMenuObserver);
+            }
             mAppMenuCoordinator.destroy();
         }
 
@@ -1127,8 +1125,7 @@
                     mSnackbarManagerSupplier.get(), mJankTracker,
                     getMerchantTrustSignalsCoordinatorSupplier(), mTabReparentingControllerSupplier,
                     mOmniboxPedalDelegate, mEphemeralTabCoordinatorSupplier,
-                    mInitializeUiWithIncognitoColors, mBackPressManager,
-                    mUnblockDrawForOverviewPageRunnable);
+                    mInitializeUiWithIncognitoColors, mBackPressManager);
             if (!mSupportsAppMenuSupplier.getAsBoolean()) {
                 mToolbarManager.getToolbar().disableMenuButton();
             }
@@ -1239,6 +1236,19 @@
             mAppMenuCoordinator.registerAppMenuBlocker(mAppMenuBlocker);
 
             mAppMenuSupplier.set(mAppMenuCoordinator);
+
+            mAppMenuObserver = new AppMenuObserver() {
+                @Override
+                public void onMenuVisibilityChanged(boolean isVisible) {
+                    if (isVisible && mPageZoomCoordinator != null) {
+                        mPageZoomCoordinator.hide();
+                    }
+                }
+
+                @Override
+                public void onMenuHighlightChanged(boolean highlighting) {}
+            };
+            mAppMenuCoordinator.getAppMenuHandler().addObserver(mAppMenuObserver);
         }
     }
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ShareIntentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ShareIntentTest.java
index 26626160..a2f334b 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/ShareIntentTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ShareIntentTest.java
@@ -163,8 +163,7 @@
                     /* appMenuDelegate= */ mockActivity,
                     /* statusBarColorProvider= */ mockActivity,
                     mockActivity.getIntentRequestTracker(), new OneshotSupplierImpl<>(),
-                    new ObservableSupplierImpl<>(), false, null,
-                    /* unblockDrawForOverviewPageRunnable= */ null);
+                    new ObservableSupplierImpl<>(), false, null);
 
             ShareHelper.setLastShareComponentName(
                     null, new ComponentName("test.package", "test.activity"));
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 5aa3c3f..2c28bb9 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -1615,6 +1615,14 @@
      std::size(kNtpDriveModuleManagedUsersOnly), nullptr},
 };
 
+const FeatureEntry::FeatureParam kNtpMiddleSlotPromoDismissalFakeData[] = {
+    {ntp_features::kNtpMiddleSlotPromoDismissalParam, "fake"}};
+const FeatureEntry::FeatureVariation kNtpMiddleSlotPromoDismissalVariations[] =
+    {
+        {"- Fake Data", kNtpMiddleSlotPromoDismissalFakeData,
+         std::size(kNtpMiddleSlotPromoDismissalFakeData), nullptr},
+};
+
 const FeatureEntry::FeatureParam kNtpPhotosModuleFakeData0[] = {
     {ntp_features::kNtpPhotosModuleDataParam, "0"}};
 const FeatureEntry::FeatureParam kNtpPhotosModuleFakeData1[] = {
@@ -5569,7 +5577,9 @@
     {"ntp-middle-slot-promo-dismissal",
      flag_descriptions::kNtpMiddleSlotPromoDismissalName,
      flag_descriptions::kNtpMiddleSlotPromoDismissalDescription, kOsDesktop,
-     FEATURE_VALUE_TYPE(ntp_features::kNtpMiddleSlotPromoDismissal)},
+     FEATURE_WITH_PARAMS_VALUE_TYPE(ntp_features::kNtpMiddleSlotPromoDismissal,
+                                    kNtpMiddleSlotPromoDismissalVariations,
+                                    "DesktopNtpModules")},
 
     {"ntp-modules-drag-and-drop", flag_descriptions::kNtpModulesDragAndDropName,
      flag_descriptions::kNtpModulesDragAndDropDescription, kOsDesktop,
@@ -6964,6 +6974,11 @@
          autofill::features::kAutofillEnableManualFallbackForVirtualCards)},
 #endif  // BUILDFLAG(IS_ANDROID)
 
+    {"autofill-enable-card-product-name",
+     flag_descriptions::kAutofillEnableCardProductNameName,
+     flag_descriptions::kAutofillEnableCardProductNameDescription, kOsAll,
+     FEATURE_VALUE_TYPE(autofill::features::kAutofillEnableCardProductName)},
+
 #if BUILDFLAG(IS_CHROMEOS_ASH)
     {"account-id-migration", flag_descriptions::kAccountIdMigrationName,
      flag_descriptions::kAccountIdMigrationDescription, kOsCrOS,
@@ -8303,6 +8318,13 @@
      FEATURE_VALUE_TYPE(features::kSideSearchDSESupport)},
 #endif  // defined(TOOLKIT_VIEWS)
 
+#if !BUILDFLAG(IS_ANDROID)
+    {"customize-chrome-side-panel",
+     flag_descriptions::kCustomizeChromeSidePanelName,
+     flag_descriptions::KCustomizeChromeSidePanelDescription, kOsDesktop,
+     FEATURE_VALUE_TYPE(ntp_features::kCustomizeChromeSidePanel)},
+#endif
+
 #if BUILDFLAG(IS_CHROMEOS_ASH)
     {"enable-component-updater-test-request",
      flag_descriptions::kComponentUpdaterTestRequestName,
diff --git a/chrome/browser/android/contextualsearch/contextual_search_manager.cc b/chrome/browser/android/contextualsearch/contextual_search_manager.cc
index 8197d9d..1431402 100644
--- a/chrome/browser/android/contextualsearch/contextual_search_manager.cc
+++ b/chrome/browser/android/contextualsearch/contextual_search_manager.cc
@@ -43,13 +43,7 @@
   Profile* profile = ProfileManager::GetActiveUserProfile();
   delegate_ = std::make_unique<ContextualSearchDelegate>(
       profile->GetURLLoaderFactory(),
-      TemplateURLServiceFactory::GetForProfile(profile),
-      base::BindRepeating(
-          &ContextualSearchManager::OnSearchTermResolutionResponse,
-          base::Unretained(this)),
-      base::BindRepeating(
-          &ContextualSearchManager::OnTextSurroundingSelectionAvailable,
-          base::Unretained(this)));
+      TemplateURLServiceFactory::GetForProfile(profile));
 }
 
 ContextualSearchManager::~ContextualSearchManager() {
@@ -74,8 +68,11 @@
       NativeContextualSearchContext::FromJavaContextualSearchContext(
           j_contextual_search_context);
   // Calls back to OnSearchTermResolutionResponse.
-  delegate_->StartSearchTermResolutionRequest(contextual_search_context,
-                                              base_web_contents);
+  delegate_->StartSearchTermResolutionRequest(
+      contextual_search_context, base_web_contents,
+      base::BindRepeating(
+          &ContextualSearchManager::OnSearchTermResolutionResponse,
+          base::Unretained(this)));
 }
 
 void ContextualSearchManager::GatherSurroundingText(
@@ -89,8 +86,11 @@
   base::WeakPtr<NativeContextualSearchContext> contextual_search_context =
       NativeContextualSearchContext::FromJavaContextualSearchContext(
           j_contextual_search_context);
-  delegate_->GatherAndSaveSurroundingText(contextual_search_context,
-                                          base_web_contents);
+  delegate_->GatherAndSaveSurroundingText(
+      contextual_search_context, base_web_contents,
+      base::BindRepeating(
+          &ContextualSearchManager::OnTextSurroundingSelectionAvailable,
+          base::Unretained(this)));
 }
 
 void ContextualSearchManager::OnSearchTermResolutionResponse(
diff --git a/chrome/browser/apps/app_service/app_service_proxy_unittest.cc b/chrome/browser/apps/app_service/app_service_proxy_unittest.cc
index b84b737..f24574af 100644
--- a/chrome/browser/apps/app_service/app_service_proxy_unittest.cc
+++ b/chrome/browser/apps/app_service/app_service_proxy_unittest.cc
@@ -786,15 +786,15 @@
 
   auto intent_filter_1 = apps_util::MakeIntentFilterForUrlScope(filter_url_1);
   apps_util::AddConditionValue(ConditionType::kScheme, filter_url_2.scheme(),
-                               PatternMatchType::kNone, intent_filter_1);
+                               PatternMatchType::kLiteral, intent_filter_1);
   apps_util::AddConditionValue(ConditionType::kHost, filter_url_2.host(),
-                               PatternMatchType::kNone, intent_filter_1);
+                               PatternMatchType::kLiteral, intent_filter_1);
 
   auto intent_filter_2 = apps_util::MakeIntentFilterForUrlScope(filter_url_3);
   apps_util::AddConditionValue(ConditionType::kScheme, filter_url_2.scheme(),
-                               PatternMatchType::kNone, intent_filter_2);
+                               PatternMatchType::kLiteral, intent_filter_2);
   apps_util::AddConditionValue(ConditionType::kHost, filter_url_2.host(),
-                               PatternMatchType::kNone, intent_filter_2);
+                               PatternMatchType::kLiteral, intent_filter_2);
 
   auto intent_filter_3 = apps_util::MakeIntentFilterForUrlScope(filter_url_1);
 
@@ -848,15 +848,15 @@
 
   auto intent_filter_1 = apps_util::MakeIntentFilterForUrlScope(filter_url_1);
   apps_util::AddConditionValue(ConditionType::kScheme, filter_url_2.scheme(),
-                               PatternMatchType::kNone, intent_filter_1);
+                               PatternMatchType::kLiteral, intent_filter_1);
   apps_util::AddConditionValue(ConditionType::kHost, filter_url_2.host(),
-                               PatternMatchType::kNone, intent_filter_1);
+                               PatternMatchType::kLiteral, intent_filter_1);
 
   auto intent_filter_2 = apps_util::MakeIntentFilterForUrlScope(filter_url_3);
   apps_util::AddConditionValue(ConditionType::kScheme, filter_url_2.scheme(),
-                               PatternMatchType::kNone, intent_filter_2);
+                               PatternMatchType::kLiteral, intent_filter_2);
   apps_util::AddConditionValue(ConditionType::kHost, filter_url_2.host(),
-                               PatternMatchType::kNone, intent_filter_2);
+                               PatternMatchType::kLiteral, intent_filter_2);
 
   auto intent_filter_3 = apps_util::MakeIntentFilterForUrlScope(filter_url_1);
 
diff --git a/chrome/browser/apps/app_service/intent_util.cc b/chrome/browser/apps/app_service/intent_util.cc
index 02d02c3..b8dfbde 100644
--- a/chrome/browser/apps/app_service/intent_util.cc
+++ b/chrome/browser/apps/app_service/intent_util.cc
@@ -83,7 +83,7 @@
   // kAction == View.
   std::vector<apps::mojom::ConditionValuePtr> action_condition_values;
   action_condition_values.push_back(MakeConditionValue(
-      kIntentActionView, apps::mojom::PatternMatchType::kNone));
+      kIntentActionView, apps::mojom::PatternMatchType::kLiteral));
   auto action_condition = MakeCondition(apps::mojom::ConditionType::kAction,
                                         std::move(action_condition_values));
   intent_filter->conditions.push_back(std::move(action_condition));
@@ -129,7 +129,7 @@
 
   std::vector<apps::mojom::ConditionValuePtr> action_condition_values;
   action_condition_values.push_back(MakeConditionValue(
-      kIntentActionSend, apps::mojom::PatternMatchType::kNone));
+      kIntentActionSend, apps::mojom::PatternMatchType::kLiteral));
   auto action_condition = MakeCondition(apps::mojom::ConditionType::kAction,
                                         std::move(action_condition_values));
   intent_filter->conditions.push_back(std::move(action_condition));
@@ -377,7 +377,7 @@
   std::vector<apps::mojom::ConditionValuePtr> action_condition_values;
   for (auto& action : intent_actions) {
     action_condition_values.push_back(
-        MakeConditionValue(action, apps::mojom::PatternMatchType::kNone));
+        MakeConditionValue(action, apps::mojom::PatternMatchType::kLiteral));
   }
   if (!action_condition_values.empty()) {
     auto action_condition = MakeCondition(apps::mojom::ConditionType::kAction,
@@ -629,7 +629,7 @@
   auto intent_filter = std::make_unique<apps::IntentFilter>();
   intent_filter->AddSingleValueCondition(apps::ConditionType::kAction,
                                          kIntentActionCreateNote,
-                                         apps::PatternMatchType::kNone);
+                                         apps::PatternMatchType::kLiteral);
   return intent_filter;
 }
 
@@ -641,7 +641,7 @@
   auto intent_filter = std::make_unique<apps::IntentFilter>();
   intent_filter->AddSingleValueCondition(apps::ConditionType::kAction,
                                          kIntentActionStartOnLockScreen,
-                                         apps::PatternMatchType::kNone);
+                                         apps::PatternMatchType::kLiteral);
   return intent_filter;
 }
 
@@ -905,7 +905,6 @@
             case apps::PatternMatchType::kGlob:
               match_type = arc::mojom::PatternType::PATTERN_SIMPLE_GLOB;
               break;
-            case apps::PatternMatchType::kNone:
             case apps::PatternMatchType::kMimeType:
             case apps::PatternMatchType::kFileExtension:
             case apps::PatternMatchType::kIsDirectory:
@@ -955,7 +954,7 @@
     }
 
     action_condition_values.push_back(std::make_unique<apps::ConditionValue>(
-        action, apps::PatternMatchType::kNone));
+        action, apps::PatternMatchType::kLiteral));
   }
   if (!action_condition_values.empty()) {
     auto action_condition = std::make_unique<apps::Condition>(
@@ -969,7 +968,7 @@
     apps::ConditionValues scheme_condition_values;
     for (auto& scheme : arc_intent_filter.schemes()) {
       scheme_condition_values.push_back(std::make_unique<apps::ConditionValue>(
-          scheme, apps::PatternMatchType::kNone));
+          scheme, apps::PatternMatchType::kLiteral));
     }
     if (!scheme_condition_values.empty()) {
       auto scheme_condition = std::make_unique<apps::Condition>(
@@ -981,7 +980,7 @@
   apps::ConditionValues host_condition_values;
   for (auto& authority : arc_intent_filter.authorities()) {
     auto match_type = authority.wild() ? apps::PatternMatchType::kSuffix
-                                       : apps::PatternMatchType::kNone;
+                                       : apps::PatternMatchType::kLiteral;
     host_condition_values.push_back(
         std::make_unique<apps::ConditionValue>(authority.host(), match_type));
   }
@@ -1077,7 +1076,7 @@
     }
 
     action_condition_values.push_back(
-        MakeConditionValue(action, apps::mojom::PatternMatchType::kNone));
+        MakeConditionValue(action, apps::mojom::PatternMatchType::kLiteral));
   }
   if (!action_condition_values.empty()) {
     auto action_condition = MakeCondition(apps::mojom::ConditionType::kAction,
@@ -1091,7 +1090,7 @@
     std::vector<apps::mojom::ConditionValuePtr> scheme_condition_values;
     for (auto& scheme : arc_intent_filter.schemes()) {
       scheme_condition_values.push_back(
-          MakeConditionValue(scheme, apps::mojom::PatternMatchType::kNone));
+          MakeConditionValue(scheme, apps::mojom::PatternMatchType::kLiteral));
     }
     if (!scheme_condition_values.empty()) {
       auto scheme_condition = MakeCondition(apps::mojom::ConditionType::kScheme,
@@ -1102,8 +1101,9 @@
 
   std::vector<apps::mojom::ConditionValuePtr> host_condition_values;
   for (auto& authority : arc_intent_filter.authorities()) {
-    auto match_type = authority.wild() ? apps::mojom::PatternMatchType::kSuffix
-                                       : apps::mojom::PatternMatchType::kNone;
+    auto match_type = authority.wild()
+                          ? apps::mojom::PatternMatchType::kSuffix
+                          : apps::mojom::PatternMatchType::kLiteral;
     host_condition_values.push_back(
         MakeConditionValue(authority.host(), match_type));
   }
diff --git a/chrome/browser/apps/app_service/intent_util_browsertest.cc b/chrome/browser/apps/app_service/intent_util_browsertest.cc
index 8dc623f9..a683e4b 100644
--- a/chrome/browser/apps/app_service/intent_util_browsertest.cc
+++ b/chrome/browser/apps/app_service/intent_util_browsertest.cc
@@ -39,7 +39,7 @@
     ASSERT_EQ(condition.condition_values.size(), 1U);
 
     EXPECT_EQ(condition.condition_values[0]->match_type,
-              PatternMatchType::kNone);
+              PatternMatchType::kLiteral);
     EXPECT_EQ(condition.condition_values[0]->value, "send");
   }
 
@@ -76,11 +76,11 @@
     ASSERT_EQ(condition.condition_values.size(), 2U);
 
     EXPECT_EQ(condition.condition_values[0]->match_type,
-              PatternMatchType::kNone);
+              PatternMatchType::kLiteral);
     EXPECT_EQ(condition.condition_values[0]->value, "send");
 
     EXPECT_EQ(condition.condition_values[1]->match_type,
-              PatternMatchType::kNone);
+              PatternMatchType::kLiteral);
     EXPECT_EQ(condition.condition_values[1]->value, "send_multiple");
   }
 
diff --git a/chrome/browser/apps/app_service/intent_util_unittest.cc b/chrome/browser/apps/app_service/intent_util_unittest.cc
index 332f8e7..a5ccf99 100644
--- a/chrome/browser/apps/app_service/intent_util_unittest.cc
+++ b/chrome/browser/apps/app_service/intent_util_unittest.cc
@@ -244,7 +244,7 @@
     EXPECT_EQ(condition.condition_type, ConditionType::kAction);
     ASSERT_EQ(condition.condition_values.size(), 1U);
     EXPECT_EQ(condition.condition_values[0]->match_type,
-              PatternMatchType::kNone);
+              PatternMatchType::kLiteral);
     EXPECT_EQ(condition.condition_values[0]->value,
               apps_util::kIntentActionView);
   }
@@ -254,7 +254,7 @@
     EXPECT_EQ(condition.condition_type, ConditionType::kScheme);
     ASSERT_EQ(condition.condition_values.size(), 1U);
     EXPECT_EQ(condition.condition_values[0]->match_type,
-              PatternMatchType::kNone);
+              PatternMatchType::kLiteral);
     EXPECT_EQ(condition.condition_values[0]->value, scope.scheme());
   }
 
@@ -263,7 +263,7 @@
     EXPECT_EQ(condition.condition_type, ConditionType::kHost);
     ASSERT_EQ(condition.condition_values.size(), 1U);
     EXPECT_EQ(condition.condition_values[0]->match_type,
-              PatternMatchType::kNone);
+              PatternMatchType::kLiteral);
     EXPECT_EQ(condition.condition_values[0]->value, scope.host());
   }
 
@@ -300,7 +300,7 @@
     EXPECT_EQ(condition.condition_type, apps::mojom::ConditionType::kAction);
     ASSERT_EQ(condition.condition_values.size(), 1U);
     EXPECT_EQ(condition.condition_values[0]->match_type,
-              apps::mojom::PatternMatchType::kNone);
+              apps::mojom::PatternMatchType::kLiteral);
     EXPECT_EQ(condition.condition_values[0]->value,
               apps_util::kIntentActionView);
   }
@@ -310,7 +310,7 @@
     EXPECT_EQ(condition.condition_type, apps::mojom::ConditionType::kScheme);
     ASSERT_EQ(condition.condition_values.size(), 1U);
     EXPECT_EQ(condition.condition_values[0]->match_type,
-              apps::mojom::PatternMatchType::kNone);
+              apps::mojom::PatternMatchType::kLiteral);
     EXPECT_EQ(condition.condition_values[0]->value, scope.scheme());
   }
 
@@ -319,7 +319,7 @@
     EXPECT_EQ(condition.condition_type, apps::mojom::ConditionType::kHost);
     ASSERT_EQ(condition.condition_values.size(), 1U);
     EXPECT_EQ(condition.condition_values[0]->match_type,
-              apps::mojom::PatternMatchType::kNone);
+              apps::mojom::PatternMatchType::kLiteral);
     EXPECT_EQ(condition.condition_values[0]->value, scope.host());
   }
 
@@ -1157,7 +1157,7 @@
                 apps::PatternMatchType::kSuffix);
       // Check non-wildcard host
       EXPECT_EQ(condition->condition_values[1]->match_type,
-                apps::PatternMatchType::kNone);
+                apps::PatternMatchType::kLiteral);
     }
   }
 }
@@ -1296,7 +1296,7 @@
       // Check non-wildcard host
       EXPECT_EQ(condition->condition_values[1]->match_type,
                 ConvertPatternMatchTypeToMojomPatternMatchType(
-                    apps::PatternMatchType::kNone));
+                    apps::PatternMatchType::kLiteral));
     }
   }
 }
diff --git a/chrome/browser/apps/app_service/publishers/arc_apps_unittest.cc b/chrome/browser/apps/app_service/publishers/arc_apps_unittest.cc
index 789ce8b..3ac1933b2 100644
--- a/chrome/browser/apps/app_service/publishers/arc_apps_unittest.cc
+++ b/chrome/browser/apps/app_service/publishers/arc_apps_unittest.cc
@@ -68,20 +68,20 @@
 
   apps::ConditionValues values1;
   values1.push_back(std::make_unique<apps::ConditionValue>(
-      apps_util::kIntentActionView, apps::PatternMatchType::kNone));
+      apps_util::kIntentActionView, apps::PatternMatchType::kLiteral));
   filter->conditions.push_back(std::make_unique<apps::Condition>(
       apps::ConditionType::kAction, std::move(values1)));
 
   apps::ConditionValues values2;
   values2.push_back(std::make_unique<apps::ConditionValue>(
-      "https", apps::PatternMatchType::kNone));
+      "https", apps::PatternMatchType::kLiteral));
   filter->conditions.push_back(std::make_unique<apps::Condition>(
       apps::ConditionType::kScheme, std::move(values2)));
 
   apps::ConditionValues values;
   for (const std::string& authority : authorities) {
     values.push_back(std::make_unique<apps::ConditionValue>(
-        authority, apps::PatternMatchType::kNone));
+        authority, apps::PatternMatchType::kLiteral));
   }
   filter->conditions.push_back(std::make_unique<apps::Condition>(
       apps::ConditionType::kHost, std::move(values)));
diff --git a/chrome/browser/apps/app_service/publishers/publisher_unittest.cc b/chrome/browser/apps/app_service/publishers/publisher_unittest.cc
index 57cda243..5b4ba1ec 100644
--- a/chrome/browser/apps/app_service/publishers/publisher_unittest.cc
+++ b/chrome/browser/apps/app_service/publishers/publisher_unittest.cc
@@ -146,19 +146,19 @@
 
   apps::ConditionValues values1;
   values1.push_back(std::make_unique<apps::ConditionValue>(
-      apps_util::kIntentActionView, apps::PatternMatchType::kNone));
+      apps_util::kIntentActionView, apps::PatternMatchType::kLiteral));
   filter->conditions.push_back(std::make_unique<apps::Condition>(
       apps::ConditionType::kAction, std::move(values1)));
 
   apps::ConditionValues values2;
   values2.push_back(std::make_unique<apps::ConditionValue>(
-      url.scheme(), apps::PatternMatchType::kNone));
+      url.scheme(), apps::PatternMatchType::kLiteral));
   filter->conditions.push_back(std::make_unique<apps::Condition>(
       apps::ConditionType::kScheme, std::move(values2)));
 
   apps::ConditionValues values3;
   values3.push_back(std::make_unique<apps::ConditionValue>(
-      url.host(), apps::PatternMatchType::kNone));
+      url.host(), apps::PatternMatchType::kLiteral));
   filter->conditions.push_back(std::make_unique<apps::Condition>(
       apps::ConditionType::kHost, std::move(values3)));
 
diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc
index 43b5466..b1d50d5 100644
--- a/chrome/browser/apps/guest_view/web_view_browsertest.cc
+++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc
@@ -9,14 +9,11 @@
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "base/containers/contains.h"
-#include "base/containers/queue.h"
 #include "base/feature_list.h"
 #include "base/files/file_util.h"
-#include "base/files/scoped_temp_dir.h"
 #include "base/guid.h"
 #include "base/location.h"
 #include "base/memory/raw_ptr.h"
-#include "base/path_service.h"
 #include "base/process/process.h"
 #include "base/run_loop.h"
 #include "base/strings/string_number_conversions.h"
@@ -33,12 +30,7 @@
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/apps/platform_apps/app_browsertest_util.h"
 #include "chrome/browser/chrome_content_browser_client.h"
-#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
 #include "chrome/browser/devtools/devtools_window_testing.h"
-#include "chrome/browser/download/download_core_service.h"
-#include "chrome/browser/download/download_core_service_factory.h"
-#include "chrome/browser/download/download_history.h"
-#include "chrome/browser/download/download_prefs.h"
 #include "chrome/browser/extensions/identifiability_metrics_test_util.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
 #include "chrome/browser/net/profile_network_context_service.h"
@@ -50,18 +42,13 @@
 #include "chrome/browser/renderer_context_menu/render_view_context_menu_test_util.h"
 #include "chrome/browser/safe_browsing/test_safe_browsing_service.h"
 #include "chrome/browser/task_manager/task_manager_browsertest_util.h"
-#include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_dialogs.h"
-#include "chrome/browser/ui/recently_audible_helper.h"
-#include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/common/chrome_features.h"
-#include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/webui_url_constants.h"
 #include "chrome/test/base/ui_test_utils.h"
-#include "components/content_settings/core/browser/host_content_settings_map.h"
 #include "components/download/public/common/download_task_runner.h"
 #include "components/find_in_page/find_tab_helper.h"
 #include "components/guest_view/browser/guest_view_manager.h"
@@ -78,17 +65,16 @@
 #include "content/public/browser/ax_event_notification_details.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
-#include "content/public/browser/gpu_data_manager.h"
 #include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_process_host_creation_observer.h"
+#include "content/public/browser/render_view_host.h"
 #include "content/public/browser/render_widget_host.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/site_isolation_policy.h"
 #include "content/public/browser/web_contents_delegate.h"
-#include "content/public/common/child_process_host.h"
 #include "content/public/common/content_features.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/common/result_codes.h"
@@ -105,7 +91,6 @@
 #include "content/public/test/ppapi_test_utils.h"
 #include "content/public/test/test_file_error_injector.h"
 #include "content/public/test/test_navigation_observer.h"
-#include "content/public/test/test_renderer_host.h"
 #include "content/public/test/test_utils.h"
 #include "content/public/test/url_loader_interceptor.h"
 #include "extensions/browser/api/declarative/rules_cache_delegate.h"
@@ -115,12 +100,10 @@
 #include "extensions/browser/api/declarative_webrequest/webrequest_constants.h"
 #include "extensions/browser/api/extensions_api_client.h"
 #include "extensions/browser/app_window/native_app_window.h"
-#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_embedder.h"
 #include "extensions/browser/guest_view/web_view/web_view_guest.h"
 #include "extensions/browser/guest_view/web_view/web_view_renderer_state.h"
 #include "extensions/browser/process_map.h"
 #include "extensions/common/extension.h"
-#include "extensions/common/extension_urls.h"
 #include "extensions/common/extensions_client.h"
 #include "extensions/common/features/feature_channel.h"
 #include "extensions/common/identifiability_metrics.h"
@@ -129,7 +112,6 @@
 #include "net/dns/mock_host_resolver.h"
 #include "net/ssl/client_cert_identity_test_util.h"
 #include "net/ssl/client_cert_store.h"
-#include "net/test/cert_test_util.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
 #include "net/test/embedded_test_server/http_request.h"
 #include "net/test/embedded_test_server/http_response.h"
@@ -137,28 +119,20 @@
 #include "pdf/buildflags.h"
 #include "ppapi/buildflags/buildflags.h"
 #include "services/device/public/cpp/test/scoped_geolocation_overrider.h"
-#include "services/network/public/cpp/features.h"
-#include "testing/gmock/include/gmock/gmock.h"
 #include "third_party/blink/public/common/features.h"
 #include "third_party/blink/public/common/input/web_mouse_event.h"
 #include "third_party/blink/public/common/switches.h"
-#include "ui/compositor/compositor.h"
-#include "ui/compositor/compositor_observer.h"
 #include "ui/display/display_switches.h"
 #include "ui/events/gesture_detection/gesture_configuration.h"
-#include "ui/gl/gl_switches.h"
-#include "ui/views/accessibility/view_accessibility.h"
-#include "ui/views/view.h"
-#include "ui/views/widget/widget.h"
+#include "ui/gfx/geometry/point.h"
 
 #if defined(USE_AURA)
 #include "ui/aura/env.h"
+#include "ui/aura/env_observer.h"
 #include "ui/aura/window.h"
 #endif
 
 #if BUILDFLAG(ENABLE_PLUGINS)
-#include "content/public/browser/plugin_service.h"
-#include "content/public/common/webplugininfo.h"
 #include "content/public/test/ppapi_test_utils.h"
 #endif
 
@@ -413,6 +387,15 @@
   }
 }
 
+// Wraps around the browser-initiated |NavigateToURL| to hide direct guest
+// WebContents access. For MPArch GuestView migration pre-work, we do not have
+// such a mechanism to trigger a browser-initiated navigation on GuestView or
+// guest RenderFrameHost.
+[[nodiscard]] bool BrowserInitNavigationToUrl(guest_view::GuestViewBase* guest,
+                                              const GURL& url) {
+  return NavigateToURL(guest->web_contents(), url);
+}
+
 }  // namespace
 
 // This class intercepts media access request from the embedder. The request
@@ -723,32 +706,6 @@
     ASSERT_TRUE(done_listener.WaitUntilSatisfied());
   }
 
-  content::WebContents* LoadGuest(const std::string& guest_path,
-                                  const std::string& app_path) {
-    GURL::Replacements replace_host;
-    replace_host.SetHostStr("localhost");
-
-    GURL guest_url = embedded_test_server()->GetURL(guest_path);
-    guest_url = guest_url.ReplaceComponents(replace_host);
-
-    ui_test_utils::UrlLoadObserver guest_observer(
-        guest_url, content::NotificationService::AllSources());
-
-    LoadAndLaunchPlatformApp(app_path.c_str(), "guest-loaded");
-
-    guest_observer.Wait();
-    content::Source<content::NavigationController> source =
-        guest_observer.source();
-    EXPECT_TRUE(source->DeprecatedGetWebContents()
-                    ->GetPrimaryMainFrame()
-                    ->GetProcess()
-                    ->IsForGuestsOnly());
-
-    content::WebContents* guest_web_contents =
-        source->DeprecatedGetWebContents();
-    return guest_web_contents;
-  }
-
   // Helper to load interstitial page in a <webview>.
   void InterstitialTestHelper() {
     // Start a HTTPS server so we can load an interstitial page inside guest.
@@ -778,11 +735,9 @@
     ASSERT_TRUE(guest_loaded.WaitUntilSatisfied());
 
     // Wait for interstitial page to be shown in guest.
-    content::WebContents* guest_web_contents =
-        GetGuestViewManager()->WaitForSingleGuestCreated();
-    ASSERT_TRUE(guest_web_contents->GetPrimaryMainFrame()
-                    ->GetProcess()
-                    ->IsForGuestsOnly());
+    auto* guest_rfh =
+        GetGuestViewManager()->WaitForSingleGuestRenderFrameHostCreated();
+    ASSERT_TRUE(guest_rfh->GetProcess()->IsForGuestsOnly());
     GURL target_url = https_server.GetURL(
         "/extensions/platform_apps/web_view/interstitial_teardown/"
         "https_page.html");
@@ -819,7 +774,7 @@
     launched_listener.set_failure_message("WebViewTest.FAILURE");
     LoadAndLaunchPlatformApp(app_path.c_str(), &launched_listener);
 
-    guest_web_contents_ = GetGuestViewManager()->WaitForSingleGuestCreated();
+    guest_view_ = GetGuestViewManager()->WaitForSingleGuestViewCreated();
   }
 
   void SendMessageToEmbedder(const std::string& message) {
@@ -836,36 +791,42 @@
       listener = std::make_unique<ExtensionTestMessageListener>(wait_message);
     }
 
-    EXPECT_TRUE(
-        content::ExecuteScript(
-            GetGuestWebContents(),
-            base::StringPrintf("onAppCommand('%s');", message.c_str())));
+    EXPECT_TRUE(content::ExecuteScript(
+        GetGuestViewManager()->WaitForSingleGuestRenderFrameHostCreated(),
+        base::StringPrintf("onAppCommand('%s');", message.c_str())));
 
     if (listener) {
       ASSERT_TRUE(listener->WaitUntilSatisfied());
     }
   }
 
-  void OpenContextMenu(content::WebContents* web_contents) {
+  // Opens the context menu by simulating a mouse right-click at (1,1) relative
+  // to the guest's |RenderWidgethostView|. The mouse event is forwarded
+  // directly to the guest RWHV.
+  void OpenContextMenu(content::RenderFrameHost* guest_main_frame) {
+    ASSERT_TRUE(guest_main_frame);
+
     blink::WebMouseEvent mouse_event(
         blink::WebInputEvent::Type::kMouseDown,
         blink::WebInputEvent::kNoModifiers,
         blink::WebInputEvent::GetStaticTimeStampForTests());
+
     mouse_event.button = blink::WebMouseEvent::Button::kRight;
+    // (1, 1) is chosen to make sure we click inside the guest.
     mouse_event.SetPositionInWidget(1, 1);
-    web_contents->GetPrimaryMainFrame()
-        ->GetRenderViewHost()
-        ->GetWidget()
-        ->ForwardMouseEvent(mouse_event);
+
+    auto* guest_rwh = guest_main_frame->GetRenderWidgetHost();
+    guest_rwh->ForwardMouseEvent(mouse_event);
     mouse_event.SetType(blink::WebInputEvent::Type::kMouseUp);
-    web_contents->GetPrimaryMainFrame()
-        ->GetRenderViewHost()
-        ->GetWidget()
-        ->ForwardMouseEvent(mouse_event);
+    guest_rwh->ForwardMouseEvent(mouse_event);
   }
 
+  guest_view::GuestViewBase* GetGuestView() { return guest_view_; }
   content::WebContents* GetGuestWebContents() {
-    return guest_web_contents_;
+    return guest_view_->web_contents();
+  }
+  content::RenderFrameHost* GetGuestRenderFrameHost() {
+    return guest_view_->web_contents()->GetPrimaryMainFrame();
   }
 
   content::WebContents* GetEmbedderWebContents() {
@@ -878,8 +839,8 @@
   TestGuestViewManager* GetGuestViewManager() {
     TestGuestViewManager* manager = static_cast<TestGuestViewManager*>(
         TestGuestViewManager::FromBrowserContext(browser()->profile()));
-    // TestGuestViewManager::WaitForSingleGuestCreated may and will get called
-    // before a guest is created.
+    // Test code may access the TestGuestViewManager before it would be created
+    // during creation of the first guest.
     if (!manager) {
       manager = static_cast<TestGuestViewManager*>(
           GuestViewManager::CreateWithDelegate(
@@ -890,8 +851,7 @@
     return manager;
   }
 
-  WebViewTestBase()
-      : guest_web_contents_(nullptr), embedder_web_contents_(nullptr) {
+  WebViewTestBase() : guest_view_(nullptr), embedder_web_contents_(nullptr) {
     GuestViewManager::set_factory_for_testing(&factory_);
   }
 
@@ -916,7 +876,7 @@
 
   TestGuestViewManagerFactory factory_;
   // Note that these are only set if you launch app using LoadAppWithGuest().
-  raw_ptr<content::WebContents> guest_web_contents_;
+  raw_ptr<guest_view::GuestViewBase> guest_view_;
   raw_ptr<content::WebContents> embedder_web_contents_;
 };
 
@@ -1132,7 +1092,7 @@
 
   SendMessageToEmbedder("create-guest");
   content::WebContents* guest =
-      GetGuestViewManager()->WaitForSingleGuestCreated();
+      GetGuestViewManager()->DeprecatedWaitForSingleGuestCreated();
 
   EXPECT_TRUE(embedder->IsAudioMuted());
   WebContentsAudioMutedObserver observer(guest);
@@ -1282,7 +1242,7 @@
                            "WebViewTest.LAUNCHED");
   // Navigate the guest while it's in "display: none" state.
   SendMessageToEmbedder("navigate-guest");
-  GetGuestViewManager()->WaitForSingleGuestCreated();
+  GetGuestViewManager()->DeprecatedWaitForSingleGuestCreated();
 
   // Now attempt to navigate the guest again.
   SendMessageToEmbedder("navigate-guest");
@@ -1384,7 +1344,8 @@
   ASSERT_TRUE(embedder_contents);
 
   std::vector<content::WebContents*> guest_contents_list;
-  GetGuestViewManager()->GetGuestWebContentsList(&guest_contents_list);
+  GetGuestViewManager()->DeprecatedGetGuestWebContentsList(
+      &guest_contents_list);
   ASSERT_EQ(1u, guest_contents_list.size());
   content::WebContents* guest_contents = guest_contents_list[0];
 
@@ -1638,14 +1599,14 @@
   // that the two <webview>'s remain in the same BrowsingInstance and
   // StoragePartition.
   GetGuestViewManager()->WaitForNumGuestsCreated(2);
-  std::vector<content::WebContents*> guest_contents_list;
-  GetGuestViewManager()->GetGuestWebContentsList(&guest_contents_list);
-  ASSERT_EQ(2u, guest_contents_list.size());
-  content::WebContents* guest1 = guest_contents_list[0];
-  content::WebContents* guest2 = guest_contents_list[1];
+  std::vector<content::RenderFrameHost*> guest_rfh_list;
+  GetGuestViewManager()->GetGuestRenderFrameHostList(&guest_rfh_list);
+  ASSERT_EQ(2u, guest_rfh_list.size());
+  auto* guest1 = guest_rfh_list[0];
+  auto* guest2 = guest_rfh_list[1];
   ASSERT_NE(guest1, guest2);
-  auto* guest_instance1 = guest1->GetPrimaryMainFrame()->GetSiteInstance();
-  auto* guest_instance2 = guest2->GetPrimaryMainFrame()->GetSiteInstance();
+  auto* guest_instance1 = guest1->GetSiteInstance();
+  auto* guest_instance2 = guest2->GetSiteInstance();
   EXPECT_TRUE(guest_instance1->IsGuest());
   EXPECT_TRUE(guest_instance2->IsGuest());
   EXPECT_EQ(guest_instance1->GetStoragePartitionConfig(),
@@ -1676,14 +1637,14 @@
   // that both <webview>'s are in guest SiteInstances and in the same
   // StoragePartition.
   GetGuestViewManager()->WaitForNumGuestsCreated(2);
-  std::vector<content::WebContents*> guest_contents_list;
-  GetGuestViewManager()->GetGuestWebContentsList(&guest_contents_list);
-  ASSERT_EQ(2u, guest_contents_list.size());
-  content::WebContents* guest1 = guest_contents_list[0];
-  content::WebContents* guest2 = guest_contents_list[1];
-  ASSERT_NE(guest1, guest2);
-  auto* guest_instance1 = guest1->GetPrimaryMainFrame()->GetSiteInstance();
-  auto* guest_instance2 = guest2->GetPrimaryMainFrame()->GetSiteInstance();
+  std::vector<content::RenderFrameHost*> guest_rfh_list;
+  GetGuestViewManager()->GetGuestRenderFrameHostList(&guest_rfh_list);
+  ASSERT_EQ(2u, guest_rfh_list.size());
+  auto* guest1_rfh = guest_rfh_list[0];
+  auto* guest2_rfh = guest_rfh_list[1];
+  ASSERT_NE(guest1_rfh, guest2_rfh);
+  auto* guest_instance1 = guest1_rfh->GetSiteInstance();
+  auto* guest_instance2 = guest2_rfh->GetSiteInstance();
   EXPECT_TRUE(guest_instance1->IsGuest());
   EXPECT_TRUE(guest_instance2->IsGuest());
   EXPECT_EQ(guest_instance1->GetStoragePartitionConfig(),
@@ -1752,7 +1713,8 @@
   // guests are different and the embedders are different, then we have four
   // distinct WebContents, as we expect.
   std::vector<content::WebContents*> guest_contents_list;
-  GetGuestViewManager()->GetGuestWebContentsList(&guest_contents_list);
+  GetGuestViewManager()->DeprecatedGetGuestWebContentsList(
+      &guest_contents_list);
   ASSERT_EQ(2u, guest_contents_list.size());
   content::WebContents* new_window_guest_contents = guest_contents_list[0];
 
@@ -1896,7 +1858,8 @@
   GetGuestViewManager()->WaitForNumGuestsCreated(2);
 
   std::vector<content::WebContents*> guest_contents_list;
-  GetGuestViewManager()->GetGuestWebContentsList(&guest_contents_list);
+  GetGuestViewManager()->DeprecatedGetGuestWebContentsList(
+      &guest_contents_list);
   ASSERT_EQ(2u, guest_contents_list.size());
   content::WebContents* guest1 = guest_contents_list[0];
   content::WebContents* guest2 = guest_contents_list[1];
@@ -1952,14 +1915,15 @@
 
   content::WebContents* embedder = GetEmbedderWebContents();
   auto* unattached_guest = extensions::WebViewGuest::FromWebContents(
-      GetGuestViewManager()->GetLastGuestCreated());
+      GetGuestViewManager()->DeprecatedGetLastGuestCreated());
   ASSERT_TRUE(unattached_guest);
   ASSERT_EQ(embedder, unattached_guest->owner_web_contents());
   ASSERT_FALSE(unattached_guest->attached());
   ASSERT_FALSE(unattached_guest->embedder_web_contents());
 
   std::vector<content::WebContents*> guest_contents_list;
-  GetGuestViewManager()->GetGuestWebContentsList(&guest_contents_list);
+  GetGuestViewManager()->DeprecatedGetGuestWebContentsList(
+      &guest_contents_list);
   ASSERT_EQ(2u, guest_contents_list.size());
   content::WebContents* other_guest =
       (guest_contents_list[0] == unattached_guest->web_contents())
@@ -2193,7 +2157,7 @@
   InterstitialTestHelper();
 
   content::WebContents* guest_web_contents =
-      GetGuestViewManager()->WaitForSingleGuestCreated();
+      GetGuestViewManager()->DeprecatedWaitForSingleGuestCreated();
   EXPECT_TRUE(IsShowingInterstitial(guest_web_contents));
 }
 
@@ -2234,7 +2198,7 @@
   InterstitialTestHelper();
 
   content::WebContents* guest_web_contents =
-      GetGuestViewManager()->WaitForSingleGuestCreated();
+      GetGuestViewManager()->DeprecatedWaitForSingleGuestCreated();
   EXPECT_TRUE(IsShowingInterstitial(guest_web_contents));
 
   // Navigate to about:blank.
@@ -2364,7 +2328,7 @@
 
     // Wait for guest navigation to complete.
     auto* guest_web_contents =
-        GetGuestViewManager()->WaitForSingleGuestCreated();
+        GetGuestViewManager()->DeprecatedWaitForSingleGuestCreated();
     ASSERT_TRUE(guest_web_contents->GetPrimaryMainFrame()
                     ->GetProcess()
                     ->IsForGuestsOnly());
@@ -2397,7 +2361,8 @@
 
   // Page should load without any interstitial (and no crashing).
   auto* embedder_web_contents = GetFirstAppWindowWebContents();
-  auto* guest_web_contents = GetGuestViewManager()->WaitForSingleGuestCreated();
+  auto* guest_web_contents =
+      GetGuestViewManager()->DeprecatedWaitForSingleGuestCreated();
   EXPECT_FALSE(IsShowingInterstitial(guest_web_contents));
   EXPECT_FALSE(IsShowingInterstitial(embedder_web_contents));
 }
@@ -2416,7 +2381,8 @@
 
   // Page should load without any interstitial (and no crashing).
   auto* embedder_web_contents = GetFirstAppWindowWebContents();
-  auto* guest_web_contents = GetGuestViewManager()->WaitForSingleGuestCreated();
+  auto* guest_web_contents =
+      GetGuestViewManager()->DeprecatedWaitForSingleGuestCreated();
   EXPECT_FALSE(IsShowingInterstitial(guest_web_contents));
   EXPECT_FALSE(IsShowingInterstitial(embedder_web_contents));
 }
@@ -2432,15 +2398,14 @@
 // only. If it breaks then this is a bug in the prerenderer.
 IN_PROC_BROWSER_TEST_P(WebViewTest, NoPrerenderer) {
   ASSERT_TRUE(StartEmbeddedTestServer());
-  content::WebContents* guest_web_contents =
-      LoadGuest(
-          "/extensions/platform_apps/web_view/noprerenderer/guest.html",
-          "web_view/noprerenderer");
-  ASSERT_TRUE(guest_web_contents != nullptr);
+  LoadAndLaunchPlatformApp("web_view/noprerenderer", "guest-loaded");
+  auto* guest_rfh =
+      GetGuestViewManager()->WaitForSingleGuestRenderFrameHostCreated();
+  ASSERT_TRUE(guest_rfh);
 
   NoStatePrefetchLinkManager* no_state_prefetch_link_manager =
       NoStatePrefetchLinkManagerFactory::GetForBrowserContext(
-          guest_web_contents->GetBrowserContext());
+          guest_rfh->GetBrowserContext());
   ASSERT_TRUE(no_state_prefetch_link_manager != nullptr);
   EXPECT_TRUE(no_state_prefetch_link_manager->IsEmpty());
 }
@@ -2450,8 +2415,9 @@
 IN_PROC_BROWSER_TEST_P(WebViewTest, TaskManagerExistingWebView) {
   ASSERT_TRUE(StartEmbeddedTestServer());
 
-  LoadGuest("/extensions/platform_apps/web_view/task_manager/guest.html",
-            "web_view/task_manager");
+  LoadAndLaunchPlatformApp("web_view/task_manager", "guest-loaded");
+  ASSERT_TRUE(
+      GetGuestViewManager()->WaitForSingleGuestRenderFrameHostCreated());
 
   chrome::ShowTaskManager(browser());  // Show task manager AFTER guest loads.
 
@@ -2474,8 +2440,9 @@
 
   chrome::ShowTaskManager(browser());  // Show task manager BEFORE guest loads.
 
-  LoadGuest("/extensions/platform_apps/web_view/task_manager/guest.html",
-            "web_view/task_manager");
+  LoadAndLaunchPlatformApp("web_view/task_manager", "guest-loaded");
+  ASSERT_TRUE(
+      GetGuestViewManager()->WaitForSingleGuestRenderFrameHostCreated());
 
   const char* guest_title = "WebViewed test content";
   const char* app_name = "<webview> task manager test";
@@ -2734,7 +2701,7 @@
 
   // Verify that a new guest was created.
   content::WebContents* new_guest_web_contents =
-      GetGuestViewManager()->GetLastGuestCreated();
+      GetGuestViewManager()->DeprecatedGetLastGuestCreated();
   EXPECT_NE(GetGuestWebContents(), new_guest_web_contents);
 
   // Verify that the new <webview> guest ends up at about:blank.
@@ -2756,7 +2723,8 @@
   GetGuestViewManager()->WaitForNumGuestsCreated(2);
 
   std::vector<content::WebContents*> guest_contents_list;
-  GetGuestViewManager()->GetGuestWebContentsList(&guest_contents_list);
+  GetGuestViewManager()->DeprecatedGetGuestWebContentsList(
+      &guest_contents_list);
   ASSERT_EQ(2u, guest_contents_list.size());
   content::WebContents* guest1 = guest_contents_list[0];
   content::WebContents* guest2 = guest_contents_list[1];
@@ -2880,8 +2848,9 @@
 
 IN_PROC_BROWSER_TEST_P(WebViewTest, ContextMenusAPI_PreventDefault) {
   LoadAppWithGuest("web_view/context_menus/basic");
-
-  content::WebContents* guest_web_contents = GetGuestWebContents();
+  auto* guest_main_frame =
+      GetGuestViewManager()->GetLastGuestRenderFrameHostCreated();
+  ASSERT_TRUE(guest_main_frame);
   content::WebContents* embedder = GetEmbedderWebContents();
   ASSERT_TRUE(embedder);
 
@@ -2892,7 +2861,7 @@
   EXPECT_TRUE(content::ExecuteScript(embedder, "registerPreventDefault()"));
   ContextMenuShownObserver context_menu_shown_observer;
 
-  OpenContextMenu(guest_web_contents);
+  OpenContextMenu(guest_main_frame);
 
   EXPECT_TRUE(prevent_default_listener.WaitUntilSatisfied());
   // Expect the menu to not show up.
@@ -2901,7 +2870,7 @@
   // Now remove the preventDefault() and expect context menu to be shown.
   ExecuteScriptWaitForTitle(
       embedder, "removePreventDefault()", "PREVENT_DEFAULT_LISTENER_REMOVED");
-  OpenContextMenu(guest_web_contents);
+  OpenContextMenu(guest_main_frame);
 
   // We expect to see a context menu for the second call to |OpenContextMenu|.
   context_menu_shown_observer.Wait();
@@ -2912,7 +2881,9 @@
 // also tests that the 'contextmenu' event is handled correctly.
 IN_PROC_BROWSER_TEST_P(WebViewTest, TestContextMenu) {
   LoadAppWithGuest("web_view/context_menus/basic");
-  content::WebContents* guest_web_contents = GetGuestWebContents();
+  auto* guest_main_frame =
+      GetGuestViewManager()->WaitForSingleGuestRenderFrameHostCreated();
+  ASSERT_TRUE(guest_main_frame);
 
   auto close_menu_and_stop_run_loop = [](base::OnceClosure closure,
                                          RenderViewContextMenu* context_menu) {
@@ -2927,7 +2898,7 @@
   RenderViewContextMenu::RegisterMenuShownCallbackForTesting(
       base::BindOnce(close_menu_and_stop_run_loop, run_loop.QuitClosure()));
 
-  OpenContextMenu(guest_web_contents);
+  OpenContextMenu(guest_main_frame);
 
   // Wait for the context menu to be visible.
   run_loop.Run();
@@ -3330,9 +3301,9 @@
 
 IN_PROC_BROWSER_TEST_P(WebViewTest, DownloadPermission) {
   ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.
-  content::WebContents* guest_web_contents =
-      LoadGuest("/extensions/platform_apps/web_view/download/guest.html",
-                "web_view/download");
+  LoadAndLaunchPlatformApp("web_view/download", "guest-loaded");
+  auto* guest_web_contents =
+      GetGuestViewManager()->DeprecatedWaitForSingleGuestCreated();
   ASSERT_TRUE(guest_web_contents);
 
   std::unique_ptr<content::DownloadTestObserver> completion_observer(
@@ -3910,7 +3881,7 @@
   // resources belonging to the base URL's origin.
   if (content::SiteIsolationPolicy::IsSiteIsolationForGuestsEnabled()) {
     content::WebContents* guest =
-        GetGuestViewManager()->WaitForSingleGuestCreated();
+        GetGuestViewManager()->DeprecatedWaitForSingleGuestCreated();
     ASSERT_TRUE(guest);
     content::RenderFrameHost* main_frame = guest->GetPrimaryMainFrame();
     EXPECT_TRUE(main_frame->GetSiteInstance()->RequiresDedicatedProcess());
@@ -4355,7 +4326,8 @@
 
   std::vector<content::WebContents*> guest_web_contents_list;
   GetGuestViewManager()->WaitForNumGuestsCreated(2u);
-  GetGuestViewManager()->GetGuestWebContentsList(&guest_web_contents_list);
+  GetGuestViewManager()->DeprecatedGetGuestWebContentsList(
+      &guest_web_contents_list);
   ASSERT_EQ(2u, guest_web_contents_list.size());
 
   content::WebContents* web_view_contents = guest_web_contents_list[0];
@@ -4378,7 +4350,8 @@
 
   std::vector<content::WebContents*> guest_web_contents_list;
   GetGuestViewManager()->WaitForNumGuestsCreated(2u);
-  GetGuestViewManager()->GetGuestWebContentsList(&guest_web_contents_list);
+  GetGuestViewManager()->DeprecatedGetGuestWebContentsList(
+      &guest_web_contents_list);
   ASSERT_EQ(2u, guest_web_contents_list.size());
 
   content::WebContents* web_view_contents = guest_web_contents_list[0];
@@ -4450,7 +4423,8 @@
 
   // Ensure that the <webview> process isn't considered an extension process,
   // even though the last committed URL is an extension URL.
-  content::WebContents* guest = GetGuestViewManager()->GetLastGuestCreated();
+  content::WebContents* guest =
+      GetGuestViewManager()->DeprecatedGetLastGuestCreated();
   GURL guest_url(guest->GetLastCommittedURL());
   EXPECT_TRUE(guest_url.SchemeIs(extensions::kExtensionScheme));
 
@@ -4477,7 +4451,7 @@
 
   content::WebContents* embedder_contents = GetEmbedderWebContents();
   content::WebContents* web_view_contents =
-      GetGuestViewManager()->GetLastGuestCreated();
+      GetGuestViewManager()->DeprecatedGetLastGuestCreated();
   ASSERT_TRUE(embedder_contents);
   ASSERT_TRUE(web_view_contents);
 
@@ -4496,7 +4470,7 @@
 
   content::WebContents* embedder_contents = GetEmbedderWebContents();
   content::WebContents* web_view_contents =
-      GetGuestViewManager()->GetLastGuestCreated();
+      GetGuestViewManager()->DeprecatedGetLastGuestCreated();
   ASSERT_TRUE(embedder_contents);
   ASSERT_TRUE(web_view_contents);
 
@@ -4527,7 +4501,7 @@
 
   content::WebContents* embedder_contents = GetEmbedderWebContents();
   content::WebContents* web_view_contents =
-      GetGuestViewManager()->GetLastGuestCreated();
+      GetGuestViewManager()->DeprecatedGetLastGuestCreated();
   ASSERT_TRUE(embedder_contents);
   ASSERT_TRUE(web_view_contents);
 
@@ -4617,10 +4591,10 @@
   TestHelper("testLoadWebviewInsideIframe",
              "web_view/load_webview_inside_iframe", NEEDS_TEST_SERVER);
 
-  ASSERT_TRUE(GetGuestViewManager()->GetLastGuestCreated());
+  ASSERT_TRUE(GetGuestViewManager()->DeprecatedGetLastGuestCreated());
 
   content::WebContentsDestroyedWatcher watcher(
-      GetGuestViewManager()->GetLastGuestCreated());
+      GetGuestViewManager()->DeprecatedGetLastGuestCreated());
 
   // Remove the iframe.
   content::ExecuteScriptAsync(GetEmbedderWebContents(),
@@ -4852,7 +4826,8 @@
 
   std::vector<content::WebContents*> guest_web_contents_list;
   GetGuestViewManager()->WaitForNumGuestsCreated(1u);
-  GetGuestViewManager()->GetGuestWebContentsList(&guest_web_contents_list);
+  GetGuestViewManager()->DeprecatedGetGuestWebContentsList(
+      &guest_web_contents_list);
   ASSERT_EQ(1u, guest_web_contents_list.size());
 
   content::WebContents* guest_contents = guest_web_contents_list[0];
@@ -4928,7 +4903,8 @@
 
   std::vector<content::WebContents*> guest_web_contents_list;
   GetGuestViewManager()->WaitForNumGuestsCreated(1u);
-  GetGuestViewManager()->GetGuestWebContentsList(&guest_web_contents_list);
+  GetGuestViewManager()->DeprecatedGetGuestWebContentsList(
+      &guest_web_contents_list);
   ASSERT_EQ(1u, guest_web_contents_list.size());
 
   content::WebContents* guest_contents = guest_web_contents_list[0];
@@ -5028,7 +5004,8 @@
 
   std::vector<content::WebContents*> guest_web_contents_list;
   GetGuestViewManager()->WaitForNumGuestsCreated(1u);
-  GetGuestViewManager()->GetGuestWebContentsList(&guest_web_contents_list);
+  GetGuestViewManager()->DeprecatedGetGuestWebContentsList(
+      &guest_web_contents_list);
   ASSERT_EQ(1u, guest_web_contents_list.size());
 
   content::WebContents* guest_contents = guest_web_contents_list[0];
@@ -5143,8 +5120,11 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), signin_url));
   auto* embedder_web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  auto* attached_guest = GetGuestViewManager()->WaitForNextGuestCreated();
-  GetGuestViewManager()->WaitUntilAttached(attached_guest);
+  auto* attached_guest_view =
+      GetGuestViewManager()->WaitForNextGuestViewCreated();
+  GetGuestViewManager()->WaitUntilAttached(attached_guest_view);
+  auto* attached_guest =
+      GetGuestViewManager()->GetLastGuestRenderFrameHostCreated();
   // Now add a new <webview> and wait until its guest WebContents is created.
   ASSERT_TRUE(ExecuteScript(embedder_web_contents,
                             "var webview = document.createElement('webview');"
@@ -5153,7 +5133,8 @@
   // Right after this line, the guest is created but *not* attached (the
   // callback for 'GuestViewInternal.createGuest' is invoked after this line;
   // which is before attaching begins).
-  auto* unattached_guest = GetGuestViewManager()->GetLastGuestCreated();
+  auto* unattached_guest =
+      GetGuestViewManager()->GetLastGuestRenderFrameHostCreated();
   EXPECT_NE(unattached_guest, attached_guest);
   auto* find_helper =
       find_in_page::FindTabHelper::FromWebContents(embedder_web_contents);
@@ -5163,12 +5144,13 @@
   // Request for main frame of the tab.
   EXPECT_EQ(1U, pending.count(embedder_web_contents->GetPrimaryMainFrame()));
   // Request for main frame of the attached guest.
-  EXPECT_EQ(1U, pending.count(attached_guest->GetPrimaryMainFrame()));
+  EXPECT_EQ(1U, pending.count(attached_guest));
   // No request for the unattached guest.
-  EXPECT_EQ(0U, pending.count(unattached_guest->GetPrimaryMainFrame()));
+  EXPECT_EQ(0U, pending.count(unattached_guest));
   // Sanity-check: try the set returned for guest.
-  pending =
-      content::GetRenderFrameHostsWithPendingFindResults(unattached_guest);
+  // TODO(crbug.com/1261928): Remove the following for MPArch guest view.
+  pending = content::GetRenderFrameHostsWithPendingFindResults(
+      content::WebContents::FromRenderFrameHost(unattached_guest));
   EXPECT_TRUE(pending.empty());
 }
 
@@ -5802,8 +5784,9 @@
 
   // Navigate to a normal page and then repeat the above with an
   // embedder-initiated navigation to an error page.
-  EXPECT_TRUE(NavigateToURL(
-      guest, embedded_test_server()->GetURL("b.test", "/iframe.html")));
+  EXPECT_TRUE(BrowserInitNavigationToUrl(
+      GetGuestView(),
+      embedded_test_server()->GetURL("b.test", "/iframe.html")));
   EXPECT_FALSE(guest->GetPrimaryMainFrame()->IsErrorDocument());
   EXPECT_NE(guest->GetPrimaryMainFrame()->GetSiteInstance(), error_instance);
 
@@ -5861,7 +5844,7 @@
   // navigation to force a BrowsingInstance swap.
   const GURL second_url =
       embedded_test_server()->GetURL("b.test", "/title1.html");
-  EXPECT_TRUE(NavigateToURL(guest, second_url));
+  EXPECT_TRUE(BrowserInitNavigationToUrl(GetGuestView(), second_url));
   scoped_refptr<content::SiteInstance> second_instance =
       guest->GetPrimaryMainFrame()->GetSiteInstance();
 
@@ -5908,15 +5891,14 @@
 
   // Load an app with a <webview> guest that starts at a data: URL.
   LoadAppWithGuest("web_view/simple");
-  content::WebContents* guest = GetGuestWebContents();
-  ASSERT_TRUE(guest);
+  ASSERT_TRUE(GetGuestView());
 
   // Start a navigation in the <webview> to a cross-site page and use a
   // browser-initiated navigation to force a BrowsingInstance swap.
   const GURL guest_url =
       embedded_test_server()->GetURL("a.test", "/title1.html");
   GuestProcessCreationObserver observer;
-  EXPECT_TRUE(NavigateToURL(guest, guest_url));
+  EXPECT_TRUE(BrowserInitNavigationToUrl(GetGuestView(), guest_url));
 
   // This should only trigger creation of one additional guest process. There
   // used to be a bug where a speculative RenderFrameHost that was created
@@ -5953,7 +5935,7 @@
   // BrowsingInstances as it's a cross-site browser-initiated navigation.
   const GURL second_url =
       embedded_test_server()->GetURL("b.test", "/title1.html");
-  EXPECT_TRUE(NavigateToURL(guest, second_url));
+  EXPECT_TRUE(BrowserInitNavigationToUrl(GetGuestView(), second_url));
   scoped_refptr<content::SiteInstance> third_instance =
       guest->GetPrimaryMainFrame()->GetSiteInstance();
   EXPECT_TRUE(third_instance->IsGuest());
@@ -5986,7 +5968,7 @@
   TestHelper("testBlankWebview", "web_view/shim", NO_TEST_SERVER);
 
   content::WebContents* guest =
-      GetGuestViewManager()->WaitForSingleGuestCreated();
+      GetGuestViewManager()->DeprecatedWaitForSingleGuestCreated();
   ASSERT_TRUE(guest);
   scoped_refptr<content::SiteInstance> site_instance =
       guest->GetPrimaryMainFrame()->GetSiteInstance();
@@ -6029,7 +6011,7 @@
       embedded_test_server()->GetURL("a.test", "/title1.html");
   {
     content::RenderFrameDeletedObserver deleted_observer(main_frame);
-    EXPECT_TRUE(NavigateToURL(guest, start_url));
+    EXPECT_TRUE(BrowserInitNavigationToUrl(GetGuestView(), start_url));
     deleted_observer.WaitUntilDeleted();
     ASSERT_EQ(1u, web_view_renderer_state->guest_count_for_testing());
   }
@@ -6069,7 +6051,7 @@
       embedded_test_server()->GetURL("b.test", "/title1.html");
   {
     content::RenderFrameDeletedObserver deleted_observer(main_frame);
-    EXPECT_TRUE(NavigateToURL(guest, second_url));
+    EXPECT_TRUE(BrowserInitNavigationToUrl(GetGuestView(), second_url));
     deleted_observer.WaitUntilDeleted();
     ASSERT_EQ(1u, web_view_renderer_state->guest_count_for_testing());
   }
@@ -6137,7 +6119,7 @@
       embedded_test_server()->GetURL("a.test", "/iframe.html");
   {
     content::RenderFrameDeletedObserver deleted_observer(main_frame);
-    EXPECT_TRUE(NavigateToURL(guest, start_url));
+    EXPECT_TRUE(BrowserInitNavigationToUrl(GetGuestView(), start_url));
     deleted_observer.WaitUntilDeleted();
 
     // There should be two guest frames at this point.
@@ -6178,7 +6160,7 @@
   // Navigate <webview> to a cross-site page with a same-site iframe.
   const GURL start_url =
       embedded_test_server()->GetURL("a.test", "/iframe.html");
-  EXPECT_TRUE(NavigateToURL(guest, start_url));
+  EXPECT_TRUE(BrowserInitNavigationToUrl(GetGuestView(), start_url));
 
   // Navigate <webview> subframe cross-site.
   const GURL frame_url =
@@ -6195,7 +6177,7 @@
                          "document.body.appendChild(w);",
                          start_url.spec().c_str())));
   GetGuestViewManager()->WaitForNumGuestsCreated(2u);
-  auto* guest2 = GetGuestViewManager()->GetLastGuestCreated();
+  auto* guest2 = GetGuestViewManager()->DeprecatedGetLastGuestCreated();
   EXPECT_TRUE(content::WaitForLoadStop(guest2));
   ASSERT_NE(guest, guest2);
 
@@ -6203,7 +6185,8 @@
   // BrowsingInstances.
   const GURL second_guest_url =
       embedded_test_server()->GetURL("c.test", "/iframe.html");
-  EXPECT_TRUE(NavigateToURL(guest2, second_guest_url));
+  EXPECT_TRUE(BrowserInitNavigationToUrl(
+      GetGuestViewManager()->GetLastGuestViewCreated(), second_guest_url));
   EXPECT_NE(guest->GetPrimaryMainFrame()->GetSiteInstance(),
             guest2->GetPrimaryMainFrame()->GetSiteInstance());
   EXPECT_NE(guest->GetPrimaryMainFrame()->GetProcess(),
@@ -6394,7 +6377,8 @@
                        FencedFrameInGuestHasGuestSiteInstance) {
   TestHelper("testAddFencedFrame", "web_view/shim", NEEDS_TEST_SERVER);
 
-  auto* guest_web_contents = GetGuestViewManager()->WaitForSingleGuestCreated();
+  auto* guest_web_contents =
+      GetGuestViewManager()->DeprecatedWaitForSingleGuestCreated();
   std::vector<content::RenderFrameHost*> rfhs =
       content::CollectAllRenderFrameHosts(
           guest_web_contents->GetPrimaryMainFrame());
diff --git a/chrome/browser/apps/guest_view/web_view_interactive_browsertest.cc b/chrome/browser/apps/guest_view/web_view_interactive_browsertest.cc
index a0124f8..b795bb0 100644
--- a/chrome/browser/apps/guest_view/web_view_interactive_browsertest.cc
+++ b/chrome/browser/apps/guest_view/web_view_interactive_browsertest.cc
@@ -134,8 +134,8 @@
   TestGuestViewManager* GetGuestViewManager() {
     TestGuestViewManager* manager = static_cast<TestGuestViewManager*>(
         TestGuestViewManager::FromBrowserContext(browser()->profile()));
-    // TestGuestViewManager::WaitForSingleGuestCreated may and will get called
-    // before a guest is created.
+    // Test code may access the TestGuestViewManager before it would be created
+    // during creation of the first guest.
     if (!manager) {
       manager = static_cast<TestGuestViewManager*>(
           GuestViewManager::CreateWithDelegate(
@@ -297,7 +297,8 @@
     ASSERT_TRUE(done_listener->WaitUntilSatisfied());
 
     embedder_web_contents_ = embedder_web_contents;
-    guest_web_contents_ = GetGuestViewManager()->WaitForSingleGuestCreated();
+    guest_web_contents_ =
+        GetGuestViewManager()->DeprecatedWaitForSingleGuestCreated();
   }
 
   void SendMessageToEmbedder(const std::string& message) {
@@ -752,7 +753,7 @@
 
     // In oopif-webview, the click it directly routed to the guest.
     content::WebContents* guest =
-        GetGuestViewManager()->WaitForSingleGuestCreated();
+        GetGuestViewManager()->DeprecatedWaitForSingleGuestCreated();
 
     SimulateRWHMouseClick(
         guest->GetPrimaryMainFrame()->GetRenderViewHost()->GetWidget(),
@@ -790,7 +791,7 @@
 
   content::WebContents* embedder_web_contents = GetFirstAppWindowWebContents();
   content::WebContents* guest_web_contents =
-      GetGuestViewManager()->WaitForSingleGuestCreated();
+      GetGuestViewManager()->DeprecatedWaitForSingleGuestCreated();
 
   content::MainThreadFrameObserver embedder_observer(
       embedder_web_contents->GetPrimaryMainFrame()
@@ -1508,7 +1509,7 @@
   content::RunAllPendingInMessageLoop();
 
   content::WebContents* guest_web_contents =
-      GetGuestViewManager()->GetLastGuestCreated();
+      GetGuestViewManager()->DeprecatedGetLastGuestCreated();
 
   // Click the <input> element inside the <webview>. In its focus handle, the
   // <input> inside the <webview> initializes its value to "A B X D".
@@ -1565,7 +1566,7 @@
   content::RunAllPendingInMessageLoop();
 
   content::WebContents* guest_web_contents =
-      GetGuestViewManager()->GetLastGuestCreated();
+      GetGuestViewManager()->DeprecatedGetLastGuestCreated();
 
   // Click the <input> element inside the <webview>. In its focus handle, the
   // <input> inside the <webview> initializes its value to "A B X D".
diff --git a/chrome/browser/ash/app_mode/kiosk_external_updater.cc b/chrome/browser/ash/app_mode/kiosk_external_updater.cc
index f054a3b..12adb57 100644
--- a/chrome/browser/ash/app_mode/kiosk_external_updater.cc
+++ b/chrome/browser/ash/app_mode/kiosk_external_updater.cc
@@ -112,7 +112,7 @@
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   if (mount_info.mount_type != MountType::kDevice ||
-      error_code != MountError::MOUNT_ERROR_NONE) {
+      error_code != MountError::kNone) {
     return;
   }
 
diff --git a/chrome/browser/ash/app_mode/kiosk_external_updater.h b/chrome/browser/ash/app_mode/kiosk_external_updater.h
index 4df4d31a..56f874f 100644
--- a/chrome/browser/ash/app_mode/kiosk_external_updater.h
+++ b/chrome/browser/ash/app_mode/kiosk_external_updater.h
@@ -59,7 +59,7 @@
   // ash::disks::DiskMountManager::Observer overrides.
   void OnMountEvent(
       disks::DiskMountManager::MountEvent event,
-      chromeos::MountError error_code,
+      MountError error_code,
       const disks::DiskMountManager::MountPointInfo& mount_info) override;
 
   // KioskExternalUpdateValidatorDelegate overrides:
diff --git a/chrome/browser/ash/crosapi/volume_manager_ash.cc b/chrome/browser/ash/crosapi/volume_manager_ash.cc
index f1adda2..d3ea63c 100644
--- a/chrome/browser/ash/crosapi/volume_manager_ash.cc
+++ b/chrome/browser/ash/crosapi/volume_manager_ash.cc
@@ -103,12 +103,12 @@
                                            : nullptr);
 }
 
-void VolumeManagerAsh::OnVolumeMounted(chromeos::MountError error_code,
+void VolumeManagerAsh::OnVolumeMounted(ash::MountError error_code,
                                        const file_manager::Volume& volume) {
   DispatchVolumeList();
 }
 
-void VolumeManagerAsh::OnVolumeUnmounted(chromeos::MountError error_code,
+void VolumeManagerAsh::OnVolumeUnmounted(ash::MountError error_code,
                                          const file_manager::Volume& volume) {
   DispatchVolumeList();
 }
diff --git a/chrome/browser/ash/crosapi/volume_manager_ash.h b/chrome/browser/ash/crosapi/volume_manager_ash.h
index c65f456..14de6bed 100644
--- a/chrome/browser/ash/crosapi/volume_manager_ash.h
+++ b/chrome/browser/ash/crosapi/volume_manager_ash.h
@@ -40,9 +40,9 @@
                           GetVolumeMountInfoCallback callback) override;
 
   // file_manager::VolumeManagerObserver:
-  void OnVolumeMounted(chromeos::MountError error_code,
+  void OnVolumeMounted(ash::MountError error_code,
                        const file_manager::Volume& volume) override;
-  void OnVolumeUnmounted(chromeos::MountError error_code,
+  void OnVolumeUnmounted(ash::MountError error_code,
                          const file_manager::Volume& volume) override;
   void OnShutdownStart(file_manager::VolumeManager* volume_manager) override;
 
diff --git a/chrome/browser/ash/crostini/crostini_browser_test_util.cc b/chrome/browser/ash/crostini/crostini_browser_test_util.cc
index b69f9e62..9de1d2e 100644
--- a/chrome/browser/ash/crostini/crostini_browser_test_util.cc
+++ b/chrome/browser/ash/crostini/crostini_browser_test_util.cc
@@ -115,9 +115,9 @@
     ash::disks::DiskMountManager::MountPathCallback callback) {
   ash::disks::DiskMountManager::MountPointInfo info(
       source_path, "/path/to/mount", type, ash::disks::MOUNT_CONDITION_NONE);
-  std::move(callback).Run(chromeos::MountError::MOUNT_ERROR_NONE, info);
+  std::move(callback).Run(ash::MountError::kNone, info);
   dmgr_->NotifyMountEvent(ash::disks::DiskMountManager::MountEvent::MOUNTING,
-                          chromeos::MountError::MOUNT_ERROR_NONE, info);
+                          ash::MountError::kNone, info);
 }
 
 void CrostiniBrowserTestBase::CreatedBrowserMainParts(
diff --git a/chrome/browser/ash/crostini/crostini_package_service.cc b/chrome/browser/ash/crostini/crostini_package_service.cc
index 8b895ce7..fc0aa1c9 100644
--- a/chrome/browser/ash/crostini/crostini_package_service.cc
+++ b/chrome/browser/ash/crostini/crostini_package_service.cc
@@ -178,15 +178,19 @@
   // Share path if it is not in crostini.
   if (package_url.mount_filesystem_id() !=
       file_manager::util::GetCrostiniMountPointName(profile_)) {
-    guest_os::GuestOsSharePath::GetForProfile(profile_)->SharePaths(
-        container_id.vm_name, {package_url.path()}, /*persist=*/false,
-        base::BindOnce(
-            &CrostiniPackageService::OnSharePathForGetLinuxPackageInfo,
-            weak_ptr_factory_.GetWeakPtr(), container_id, package_url, path,
-            std::move(callback)));
+    CrostiniManager::RestartOptions options;
+    options.share_paths.push_back(package_url.path());
+    restart_id_for_testing_ =
+        CrostiniManager::GetForProfile(profile_)->RestartCrostiniWithOptions(
+            container_id, std::move(options),
+            base::BindOnce(
+                &CrostiniPackageService::OnSharePathForGetLinuxPackageInfo,
+                weak_ptr_factory_.GetWeakPtr(), container_id, package_url, path,
+                std::move(callback)));
   } else {
     OnSharePathForGetLinuxPackageInfo(container_id, package_url, path,
-                                      std::move(callback), true, "");
+                                      std::move(callback),
+                                      CrostiniResult::SUCCESS);
   }
 }
 
@@ -195,13 +199,12 @@
     const storage::FileSystemURL& package_url,
     const base::FilePath& package_path,
     CrostiniManager::GetLinuxPackageInfoCallback callback,
-    bool share_success,
-    const std::string& share_failure_reason) {
-  if (!share_success) {
+    CrostiniResult result) {
+  if (result != CrostiniResult::SUCCESS) {
     LinuxPackageInfo info;
     info.success = false;
     info.failure_reason = "Error sharing package " + package_url.DebugString() +
-                          ": " + share_failure_reason;
+                          ": " + CrostiniResultString(result);
     return std::move(callback).Run(info);
   }
   CrostiniManager::GetForProfile(profile_)->GetLinuxPackageInfo(
@@ -601,4 +604,8 @@
                             next_notification_id_++);
 }
 
+CrostiniManager::RestartId CrostiniPackageService::GetRestartIdForTesting() {
+  return restart_id_for_testing_;
+}
+
 }  // namespace crostini
diff --git a/chrome/browser/ash/crostini/crostini_package_service.h b/chrome/browser/ash/crostini/crostini_package_service.h
index e85dd90..ec8de209f 100644
--- a/chrome/browser/ash/crostini/crostini_package_service.h
+++ b/chrome/browser/ash/crostini/crostini_package_service.h
@@ -85,6 +85,8 @@
   // started, a system notification will be used to display further updates.
   void QueueUninstallApplication(const std::string& app_id);
 
+  CrostiniManager::RestartId GetRestartIdForTesting();
+
  private:
   // The user can request new operations while a different operation is in
   // progress. Rather than sending a request which will fail, just queue the
@@ -134,8 +136,7 @@
       const storage::FileSystemURL& package_url,
       const base::FilePath& package_path,
       CrostiniManager::GetLinuxPackageInfoCallback callback,
-      bool share_success,
-      const std::string& share_failure_reason);
+      CrostiniResult result);
 
   // Wraps the callback provided in GetLinuxPackageInfo().
   void OnGetLinuxPackageInfo(
@@ -199,6 +200,8 @@
 
   int next_notification_id_ = 0;
 
+  CrostiniManager::RestartId restart_id_for_testing_;
+
   base::WeakPtrFactory<CrostiniPackageService> weak_ptr_factory_{this};
 };
 
diff --git a/chrome/browser/ash/crostini/crostini_package_service_unittest.cc b/chrome/browser/ash/crostini/crostini_package_service_unittest.cc
index 4ecac0e4..b1d7e15 100644
--- a/chrome/browser/ash/crostini/crostini_package_service_unittest.cc
+++ b/chrome/browser/ash/crostini/crostini_package_service_unittest.cc
@@ -2019,7 +2019,6 @@
   EXPECT_EQ(request.container_name(), kDifferentContainerContainerName);
   EXPECT_EQ(request.owner_id(), CryptohomeIdForProfile(profile_.get()));
   EXPECT_EQ(request.file_path(), kPackageFileContainerPath);
-  EXPECT_TRUE(fake_seneschal_client_->share_path_called());
 }
 
 TEST_F(CrostiniPackageServiceTest, GetLinuxPackageInfoReturnsInfoOnSuccess) {
@@ -2074,6 +2073,10 @@
   service_->GetLinuxPackageInfo(
       kDifferentContainerId, package_file_url_,
       base::BindOnce(&RecordPackageInfoResult, base::Unretained(&result)));
+  CrostiniManager::GetForProfile(profile_.get())
+      ->CallRestarterStartLxdContainerFinishedForTesting(
+          service_->GetRestartIdForTesting(),
+          CrostiniResult::CONTAINER_START_FAILED);
 
   base::RunLoop().RunUntilIdle();
 
diff --git a/chrome/browser/ash/crostini/crostini_sshfs.cc b/chrome/browser/ash/crostini/crostini_sshfs.cc
index d4450e8..92761c21 100644
--- a/chrome/browser/ash/crostini/crostini_sshfs.cc
+++ b/chrome/browser/ash/crostini/crostini_sshfs.cc
@@ -167,21 +167,21 @@
 }
 
 void CrostiniSshfs::OnMountEvent(
-    chromeos::MountError error_code,
+    ash::MountError error_code,
     const ash::disks::DiskMountManager::MountPointInfo& mount_info) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
-  if (error_code != chromeos::MountError::MOUNT_ERROR_NONE) {
+  if (error_code != ash::MountError::kNone) {
     LOG(ERROR) << "Error mounting crostini container: error_code=" << error_code
                << ", source_path=" << mount_info.source_path
                << ", mount_path=" << mount_info.mount_path
                << ", mount_type=" << static_cast<int>(mount_info.mount_type)
                << ", mount_condition=" << mount_info.mount_condition;
     switch (error_code) {
-      case chromeos::MountError::MOUNT_ERROR_INTERNAL:
+      case ash::MountError::kInternal:
         Finish(CrostiniSshfsResult::kMountErrorInternal);
         return;
-      case chromeos::MountError::MOUNT_ERROR_MOUNT_PROGRAM_FAILED:
+      case ash::MountError::kMountProgramFailed:
         Finish(CrostiniSshfsResult::kMountErrorProgramFailed);
         return;
       default:
diff --git a/chrome/browser/ash/crostini/crostini_sshfs.h b/chrome/browser/ash/crostini/crostini_sshfs.h
index 6279d88..5660c16 100644
--- a/chrome/browser/ash/crostini/crostini_sshfs.h
+++ b/chrome/browser/ash/crostini/crostini_sshfs.h
@@ -46,7 +46,7 @@
   void OnContainerShutdown(const guest_os::GuestId& container_id) override;
 
   void OnMountEvent(
-      chromeos::MountError error_code,
+      ash::MountError error_code,
       const ash::disks::DiskMountManager::MountPointInfo& mount_info);
 
   // Returns true if sshfs is mounted for the specified container, else false.
diff --git a/chrome/browser/ash/crostini/crostini_sshfs_unittest.cc b/chrome/browser/ash/crostini/crostini_sshfs_unittest.cc
index edf70f26..bcf797e 100644
--- a/chrome/browser/ash/crostini/crostini_sshfs_unittest.cc
+++ b/chrome/browser/ash/crostini/crostini_sshfs_unittest.cc
@@ -126,7 +126,7 @@
       chromeos::MountAccessMode access_mode,
       ash::disks::DiskMountManager::MountPathCallback callback) {
     auto event = DiskMountManager::MountEvent::MOUNTING;
-    auto code = chromeos::MountError::MOUNT_ERROR_NONE;
+    auto code = ash::MountError::kNone;
     auto info = DiskMountManager::MountPointInfo(
         "sshfs://username@hostname:", "/media/fuse/" + kMountName,
         ash::MountType::kNetworkStorage, ash::disks::MOUNT_CONDITION_NONE);
@@ -279,7 +279,7 @@
           [this](const std::string& mount_path,
                  DiskMountManager::UnmountPathCallback callback) {
             EXPECT_EQ(mount_path, "/media/fuse/" + kMountName);
-            std::move(callback).Run(chromeos::MOUNT_ERROR_NONE);
+            std::move(callback).Run(ash::MountError::kNone);
           }));
 
   crostini_sshfs_->MountCrostiniFiles(
diff --git a/chrome/browser/ash/file_manager/app_service_file_tasks_unittest.cc b/chrome/browser/ash/file_manager/app_service_file_tasks_unittest.cc
index 08efb58..b6035f4 100644
--- a/chrome/browser/ash/file_manager/app_service_file_tasks_unittest.cc
+++ b/chrome/browser/ash/file_manager/app_service_file_tasks_unittest.cc
@@ -301,7 +301,7 @@
                                                   std::string mime_type) {
     auto intent_filter = std::make_unique<apps::IntentFilter>();
     intent_filter->AddSingleValueCondition(apps::ConditionType::kAction, action,
-                                           apps::PatternMatchType::kNone);
+                                           apps::PatternMatchType::kLiteral);
     intent_filter->AddSingleValueCondition(apps::ConditionType::kFile,
                                            mime_type,
                                            apps::PatternMatchType::kMimeType);
diff --git a/chrome/browser/ash/file_manager/fake_disk_mount_manager.cc b/chrome/browser/ash/file_manager/fake_disk_mount_manager.cc
index 24603db..8629d43 100644
--- a/chrome/browser/ash/file_manager/fake_disk_mount_manager.cc
+++ b/chrome/browser/ash/file_manager/fake_disk_mount_manager.cc
@@ -84,10 +84,10 @@
   const MountPointInfo mount_point(source_path, source_path, type,
                                    ash::disks::MOUNT_CONDITION_NONE);
   mount_points_.insert(make_pair(source_path, mount_point));
-  std::move(callback).Run(chromeos::MOUNT_ERROR_NONE, mount_point);
+  std::move(callback).Run(ash::MountError::kNone, mount_point);
   for (auto& observer : observers_) {
-    observer.OnMountEvent(DiskMountManager::MOUNTING,
-                          chromeos::MOUNT_ERROR_NONE, mount_point);
+    observer.OnMountEvent(DiskMountManager::MOUNTING, ash::MountError::kNone,
+                          mount_point);
   }
 }
 
@@ -95,7 +95,7 @@
                                        UnmountPathCallback callback) {
   unmount_requests_.emplace_back(mount_path);
 
-  chromeos::MountError error = chromeos::MOUNT_ERROR_NONE;
+  ash::MountError error = ash::MountError::kNone;
   auto unmount_iter = unmount_errors_.find(mount_path);
   if (unmount_iter != unmount_errors_.end()) {
     error = unmount_iter->second;
@@ -109,7 +109,7 @@
     mount_points_.erase(iter);
     for (auto& observer : observers_) {
       observer.OnMountEvent(DiskMountManager::UNMOUNTING,
-                            chromeos::MOUNT_ERROR_NONE, mount_point);
+                            ash::MountError::kNone, mount_point);
     }
   }
 
@@ -138,7 +138,7 @@
 }
 
 void FakeDiskMountManager::FailUnmountRequest(const std::string& mount_path,
-                                              chromeos::MountError error_code) {
+                                              ash::MountError error_code) {
   unmount_errors_[mount_path] = error_code;
 }
 
diff --git a/chrome/browser/ash/file_manager/fake_disk_mount_manager.h b/chrome/browser/ash/file_manager/fake_disk_mount_manager.h
index 6b4aa71..25a2e2f0 100644
--- a/chrome/browser/ash/file_manager/fake_disk_mount_manager.h
+++ b/chrome/browser/ash/file_manager/fake_disk_mount_manager.h
@@ -67,7 +67,7 @@
 
   // Fails a future unmount request for |mount_path| with |error_code|.
   void FailUnmountRequest(const std::string& mount_path,
-                          chromeos::MountError error_code);
+                          ash::MountError error_code);
 
   // DiskMountManager overrides.
   void AddObserver(Observer* observer) override;
@@ -118,7 +118,7 @@
   std::vector<MountRequest> mount_requests_;
   std::vector<std::string> unmount_requests_;
   std::vector<RemountAllRequest> remount_all_requests_;
-  std::map<std::string, chromeos::MountError> unmount_errors_;
+  std::map<std::string, ash::MountError> unmount_errors_;
 };
 
 }  // namespace file_manager
diff --git a/chrome/browser/ash/file_manager/file_manager_test_util.cc b/chrome/browser/ash/file_manager/file_manager_test_util.cc
index 713cec3a..9f99d360 100644
--- a/chrome/browser/ash/file_manager/file_manager_test_util.cc
+++ b/chrome/browser/ash/file_manager/file_manager_test_util.cc
@@ -148,7 +148,7 @@
     VolumeManager::Get(profile_)->RemoveObserver(this);
   }
 
-  void OnVolumeMounted(chromeos::MountError error_code,
+  void OnVolumeMounted(ash::MountError error_code,
                        const Volume& volume) override {
     on_mount_.Run();
   }
diff --git a/chrome/browser/ash/file_manager/fusebox_mounter.cc b/chrome/browser/ash/file_manager/fusebox_mounter.cc
index 90ad830..b84d354 100644
--- a/chrome/browser/ash/file_manager/fusebox_mounter.cc
+++ b/chrome/browser/ash/file_manager/fusebox_mounter.cc
@@ -97,17 +97,17 @@
   return weak_ptr_factory_.GetWeakPtr();
 }
 
-void FuseBoxMounter::MountResponse(chromeos::MountError error,
+void FuseBoxMounter::MountResponse(ash::MountError error,
                                    const FuseBoxMountInfo& info) {
-  if (error) {
+  if (error != ash::MountError::kNone) {
     LOG(ERROR) << uri_ << " mount error " << error;
   } else {
     mounted_ = true;
   }
 }
 
-void FuseBoxMounter::UnmountResponse(chromeos::MountError error) {
-  if (error) {
+void FuseBoxMounter::UnmountResponse(ash::MountError error) {
+  if (error != ash::MountError::kNone) {
     LOG(ERROR) << uri_ << " unmount error " << error;
   } else {
     mounted_ = false;
diff --git a/chrome/browser/ash/file_manager/fusebox_mounter.h b/chrome/browser/ash/file_manager/fusebox_mounter.h
index 13617e8..da3e0a7 100644
--- a/chrome/browser/ash/file_manager/fusebox_mounter.h
+++ b/chrome/browser/ash/file_manager/fusebox_mounter.h
@@ -57,10 +57,10 @@
   base::WeakPtr<FuseBoxMounter> GetWeakPtr();
 
   // Mount response.
-  void MountResponse(chromeos::MountError error, const FuseBoxMountInfo& info);
+  void MountResponse(ash::MountError error, const FuseBoxMountInfo& info);
 
   // Unmount response.
-  void UnmountResponse(chromeos::MountError error);
+  void UnmountResponse(ash::MountError error);
 
  private:
   // Cros-disks fusebox mountpoint URI.
diff --git a/chrome/browser/ash/file_manager/path_util_unittest.cc b/chrome/browser/ash/file_manager/path_util_unittest.cc
index b1d39d2..a9a0271b 100644
--- a/chrome/browser/ash/file_manager/path_util_unittest.cc
+++ b/chrome/browser/ash/file_manager/path_util_unittest.cc
@@ -386,7 +386,7 @@
 
   Test tests[] = {
       {
-          "Downloads-testing_profile-hash",
+          "Downloads-testing_profile%40test-hash",
           "path/in/myfiles",
           "/mnt/chromeos/MyFiles/path/in/myfiles",
       },
@@ -500,7 +500,7 @@
   EXPECT_TRUE(ConvertPathInsideVMToFileSystemURL(
       profile_.get(), base::FilePath("//chromeos/MyFiles/path/in/pluginvm"),
       base::FilePath("//ChromeOS"), /*map_crostini_home=*/false, &url));
-  EXPECT_EQ("Downloads-testing_profile-hash/path/in/pluginvm",
+  EXPECT_EQ("Downloads-testing_profile%40test-hash/path/in/pluginvm",
             url.virtual_path().value());
 
   profile_.reset();
diff --git a/chrome/browser/ash/file_manager/volume_manager.cc b/chrome/browser/ash/file_manager/volume_manager.cc
index 83428d3b..48c24a22 100644
--- a/chrome/browser/ash/file_manager/volume_manager.cc
+++ b/chrome/browser/ash/file_manager/volume_manager.cc
@@ -703,8 +703,7 @@
   const bool success = RegisterDownloadsMountPoint(profile_, localVolume);
   DCHECK(success);
 
-  DoMountEvent(chromeos::MOUNT_ERROR_NONE,
-               Volume::CreateForDownloads(localVolume));
+  DoMountEvent(ash::MountError::kNone, Volume::CreateForDownloads(localVolume));
 
   // Asynchronously record the disk usage for the downloads path.
   base::ThreadPool::PostTask(
@@ -716,7 +715,7 @@
   // Subscribe to DriveIntegrationService.
   drive_integration_service_->AddObserver(this);
   if (drive_integration_service_->IsMounted()) {
-    DoMountEvent(chromeos::MOUNT_ERROR_NONE,
+    DoMountEvent(ash::MountError::kNone,
                  Volume::CreateForDrive(GetDriveMountPointPath()));
   }
 
@@ -773,7 +772,7 @@
 
   RegisterShareCacheMountPoint(profile_);
   DoMountEvent(
-      chromeos::MOUNT_ERROR_NONE,
+      ash::MountError::kNone,
       Volume::CreateForShareCache(util::GetShareCacheFilePath(profile_)));
 }
 
@@ -867,7 +866,7 @@
   // Ignore if volume already exists.
   if (mounted_volumes_.find(volume->volume_id()) != mounted_volumes_.end())
     return;
-  DoMountEvent(chromeos::MOUNT_ERROR_NONE, std::move(volume));
+  DoMountEvent(ash::MountError::kNone, std::move(volume));
 
   // Listen for crostini container shutdown and remove volume.
   crostini::CrostiniManager::GetForProfile(profile_)
@@ -892,7 +891,7 @@
   // Ignore if volume already exists.
   if (mounted_volumes_.find(volume->volume_id()) != mounted_volumes_.end())
     return;
-  DoMountEvent(chromeos::MOUNT_ERROR_NONE, std::move(volume));
+  DoMountEvent(ash::MountError::kNone, std::move(volume));
 }
 
 void VolumeManager::RemoveSshfsCrostiniVolume(
@@ -926,14 +925,14 @@
           storage::kFileSystemTypeLocal, storage::FileSystemMountOption(),
           path);
   DCHECK(result);
-  DoMountEvent(chromeos::MOUNT_ERROR_NONE, Volume::CreateForAndroidFiles(path));
+  DoMountEvent(ash::MountError::kNone, Volume::CreateForAndroidFiles(path));
   return true;
 }
 
 bool VolumeManager::RegisterMediaViewForTesting(
     const std::string& root_document_id) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  DoMountEvent(chromeos::MOUNT_ERROR_NONE,
+  DoMountEvent(ash::MountError::kNone,
                Volume::CreateForMediaView(root_document_id));
   return true;
 }
@@ -941,8 +940,7 @@
 bool VolumeManager::RemoveAndroidFilesDirectoryForTesting(
     const base::FilePath& path) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  DoUnmountEvent(chromeos::MOUNT_ERROR_NONE,
-                 *Volume::CreateForAndroidFiles(path));
+  DoUnmountEvent(ash::MountError::kNone, *Volume::CreateForAndroidFiles(path));
   return true;
 }
 
@@ -950,8 +948,7 @@
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   base::FilePath path;
   if (FindDownloadsMountPointPath(profile_, &path)) {
-    DoUnmountEvent(chromeos::MOUNT_ERROR_NONE,
-                   *Volume::CreateForDownloads(path));
+    DoUnmountEvent(ash::MountError::kNone, *Volume::CreateForDownloads(path));
   }
 }
 
@@ -961,14 +958,13 @@
 
   base::FilePath old_path;
   if (FindDownloadsMountPointPath(profile_, &old_path)) {
-    DoUnmountEvent(chromeos::MOUNT_ERROR_NONE,
+    DoUnmountEvent(ash::MountError::kNone,
                    *Volume::CreateForDownloads(old_path));
   }
 
   bool success = RegisterDownloadsMountPoint(profile_, path);
-  DoMountEvent(
-      success ? chromeos::MOUNT_ERROR_NONE : chromeos::MOUNT_ERROR_INVALID_PATH,
-      Volume::CreateForDownloads(path));
+  DoMountEvent(success ? ash::MountError::kNone : ash::MountError::kInvalidPath,
+               Volume::CreateForDownloads(path));
   return success;
 }
 
@@ -982,7 +978,7 @@
           storage::kFileSystemTypeLocal, storage::FileSystemMountOption(),
           path);
   DoMountEvent(
-      success ? chromeos::MOUNT_ERROR_NONE : chromeos::MOUNT_ERROR_INVALID_PATH,
+      success ? ash::MountError::kNone : ash::MountError::kInvalidPath,
       Volume::CreateForSshfsCrostini(path, base::FilePath("/home/testuser")));
   return true;
 }
@@ -996,7 +992,7 @@
                                         const std::string& file_system_type,
                                         bool hidden) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  DoMountEvent(chromeos::MOUNT_ERROR_NONE,
+  DoMountEvent(ash::MountError::kNone,
                Volume::CreateForTesting(path, volume_type, device_type,
                                         read_only, device_path, drive_label,
                                         file_system_type, hidden));
@@ -1004,7 +1000,7 @@
 
 void VolumeManager::AddVolumeForTesting(std::unique_ptr<Volume> volume) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  DoMountEvent(chromeos::MOUNT_ERROR_NONE, std::move(volume));
+  DoMountEvent(ash::MountError::kNone, std::move(volume));
 }
 
 void VolumeManager::RemoveVolumeForTesting(
@@ -1017,7 +1013,7 @@
     const std::string& file_system_type) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   DoUnmountEvent(
-      chromeos::MOUNT_ERROR_NONE,
+      ash::MountError::kNone,
       *Volume::CreateForTesting(path, volume_type, device_type, read_only,
                                 device_path, drive_label, file_system_type));
 }
@@ -1026,16 +1022,16 @@
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   // Raise mount event.
-  // We can pass chromeos::MOUNT_ERROR_NONE even when authentication is failed
+  // We can pass ash::MountError::kNone even when authentication is failed
   // or network is unreachable. These two errors will be handled later.
-  DoMountEvent(chromeos::MOUNT_ERROR_NONE,
+  DoMountEvent(ash::MountError::kNone,
                Volume::CreateForDrive(GetDriveMountPointPath()));
 }
 
 void VolumeManager::OnFileSystemBeingUnmounted() {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
-  DoUnmountEvent(chromeos::MOUNT_ERROR_NONE,
+  DoUnmountEvent(ash::MountError::kNone,
                  *Volume::CreateForDrive(GetDriveMountPointPath()));
 }
 
@@ -1125,7 +1121,7 @@
 
 void VolumeManager::OnMountEvent(
     ash::disks::DiskMountManager::MountEvent event,
-    chromeos::MountError error_code,
+    ash::MountError error_code,
     const ash::disks::DiskMountManager::MountPointInfo& mount_info) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
@@ -1302,16 +1298,16 @@
 
   // TODO(mtomasz): Introduce own type, and avoid using MountError internally,
   // since it is related to cros disks only.
-  chromeos::MountError mount_error;
+  ash::MountError mount_error;
   switch (error) {
     case base::File::FILE_OK:
-      mount_error = chromeos::MOUNT_ERROR_NONE;
+      mount_error = ash::MountError::kNone;
       break;
     case base::File::FILE_ERROR_EXISTS:
-      mount_error = chromeos::MOUNT_ERROR_PATH_ALREADY_MOUNTED;
+      mount_error = ash::MountError::kPathAlreadyMounted;
       break;
     default:
-      mount_error = chromeos::MOUNT_ERROR_UNKNOWN;
+      mount_error = ash::MountError::kUnknown;
       break;
   }
 
@@ -1367,7 +1363,7 @@
   DCHECK(result);
 
   // Mount the fusebox FSP storage device in files app.
-  DoMountEvent(chromeos::MOUNT_ERROR_NONE, std::move(volume));
+  DoMountEvent(ash::MountError::kNone, std::move(volume));
 }
 
 void VolumeManager::ConvertFuseBoxFSPVolumeIdToFSPIfNeeded(
@@ -1388,9 +1384,9 @@
     base::File::Error error) {
   // TODO(mtomasz): Introduce own type, and avoid using MountError internally,
   // since it is related to cros disks only.
-  const chromeos::MountError mount_error = error == base::File::FILE_OK
-                                               ? chromeos::MOUNT_ERROR_NONE
-                                               : chromeos::MOUNT_ERROR_UNKNOWN;
+  const ash::MountError mount_error = error == base::File::FILE_OK
+                                          ? ash::MountError::kNone
+                                          : ash::MountError::kUnknown;
   std::unique_ptr<Volume> volume = Volume::CreateForProvidedFileSystem(
       file_system_info, MOUNT_CONTEXT_UNKNOWN);
   DoUnmountEvent(mount_error, *volume);
@@ -1422,8 +1418,8 @@
 
 void VolumeManager::OnExternalStorageDisabledChangedUnmountCallback(
     std::vector<std::string> remaining_mount_paths,
-    chromeos::MountError error_code) {
-  LOG_IF(ERROR, error_code != chromeos::MOUNT_ERROR_NONE)
+    ash::MountError error_code) {
+  LOG_IF(ERROR, error_code != ash::MountError::kNone)
       << "Unmount on ExternalStorageDisabled policy change failed: "
       << error_code;
 
@@ -1455,29 +1451,29 @@
 
   // Need to mount all roots declared in in arc_media_view_util.cc.
   if (enabled) {
-    DoMountEvent(chromeos::MOUNT_ERROR_NONE,
+    DoMountEvent(ash::MountError::kNone,
                  Volume::CreateForMediaView(arc::kImagesRootDocumentId));
-    DoMountEvent(chromeos::MOUNT_ERROR_NONE,
+    DoMountEvent(ash::MountError::kNone,
                  Volume::CreateForMediaView(arc::kVideosRootDocumentId));
-    DoMountEvent(chromeos::MOUNT_ERROR_NONE,
+    DoMountEvent(ash::MountError::kNone,
                  Volume::CreateForMediaView(arc::kAudioRootDocumentId));
-    DoMountEvent(chromeos::MOUNT_ERROR_NONE,
+    DoMountEvent(ash::MountError::kNone,
                  Volume::CreateForMediaView(arc::kDocumentsRootDocumentId));
     if (!base::FeatureList::IsEnabled(arc::kEnableVirtioBlkForData))
-      DoMountEvent(chromeos::MOUNT_ERROR_NONE,
+      DoMountEvent(ash::MountError::kNone,
                    Volume::CreateForAndroidFiles(
                        base::FilePath(util::kAndroidFilesPath)));
   } else {
-    DoUnmountEvent(chromeos::MOUNT_ERROR_NONE,
+    DoUnmountEvent(ash::MountError::kNone,
                    *Volume::CreateForMediaView(arc::kImagesRootDocumentId));
-    DoUnmountEvent(chromeos::MOUNT_ERROR_NONE,
+    DoUnmountEvent(ash::MountError::kNone,
                    *Volume::CreateForMediaView(arc::kVideosRootDocumentId));
-    DoUnmountEvent(chromeos::MOUNT_ERROR_NONE,
+    DoUnmountEvent(ash::MountError::kNone,
                    *Volume::CreateForMediaView(arc::kAudioRootDocumentId));
-    DoUnmountEvent(chromeos::MOUNT_ERROR_NONE,
+    DoUnmountEvent(ash::MountError::kNone,
                    *Volume::CreateForMediaView(arc::kDocumentsRootDocumentId));
     if (!base::FeatureList::IsEnabled(arc::kEnableVirtioBlkForData))
-      DoUnmountEvent(chromeos::MOUNT_ERROR_NONE,
+      DoUnmountEvent(ash::MountError::kNone,
                      *Volume::CreateForAndroidFiles(
                          base::FilePath(util::kAndroidFilesPath)));
   }
@@ -1591,7 +1587,7 @@
 
   // Mount the MTP storage device in files app.
   std::unique_ptr<Volume> volume = Volume::CreateForMTP(path, label, read_only);
-  DoMountEvent(chromeos::MOUNT_ERROR_NONE, std::move(volume));
+  DoMountEvent(ash::MountError::kNone, std::move(volume));
 
   // The fusebox_mounter_ is enabled by a chrome flag.
   if (!fusebox_mounter_)
@@ -1635,7 +1631,7 @@
   DCHECK(result);
 
   // Mount the fusebox MTP storage device in files app.
-  DoMountEvent(chromeos::MOUNT_ERROR_NONE, std::move(volume));
+  DoMountEvent(ash::MountError::kNone, std::move(volume));
 }
 
 void VolumeManager::OnRemovableStorageDetached(
@@ -1649,7 +1645,7 @@
 
     // Unmount the MTP storage device in files app.
     const std::string volume_id = mounted_volume.second->volume_id();
-    DoUnmountEvent(chromeos::MOUNT_ERROR_NONE, *mounted_volume.second.get());
+    DoUnmountEvent(ash::MountError::kNone, *mounted_volume.second.get());
 
     // Remove the MTP storage device from chrome::storage.
     const std::string fsid = GetMountPointNameForMediaStorage(info);
@@ -1670,7 +1666,7 @@
     // Unmount the fusebox MTP storage device in files app.
     base::WeakPtr<Volume> volume = FindVolumeById(util::kFuseBox + volume_id);
     if (volume.get())
-      DoUnmountEvent(chromeos::MOUNT_ERROR_NONE, *volume.get());
+      DoUnmountEvent(ash::MountError::kNone, *volume.get());
 
     // Remove the fusebox MTP storage device from chrome::storage.
     mount_points->RevokeFileSystem(util::kFuseBox + fsid);
@@ -1694,7 +1690,7 @@
   arc::ArcDocumentsProviderRootMap::GetForArcBrowserContext()->RegisterRoot(
       authority, document_id, root_id, read_only, mime_types);
   DoMountEvent(
-      chromeos::MOUNT_ERROR_NONE,
+      ash::MountError::kNone,
       Volume::CreateForDocumentsProvider(authority, root_id, document_id, title,
                                          summary, icon_url, read_only));
 }
@@ -1703,7 +1699,7 @@
     const std::string& authority,
     const std::string& root_id,
     const std::string& document_id) {
-  DoUnmountEvent(chromeos::MOUNT_ERROR_NONE,
+  DoUnmountEvent(ash::MountError::kNone,
                  *Volume::CreateForDocumentsProvider(
                      authority, root_id, std::string(), std::string(),
                      std::string(), GURL(), false));
@@ -1713,14 +1709,14 @@
 
 void VolumeManager::AddSmbFsVolume(const base::FilePath& mount_point,
                                    const std::string& display_name) {
-  DoMountEvent(chromeos::MOUNT_ERROR_NONE,
+  DoMountEvent(ash::MountError::kNone,
                Volume::CreateForSmb(mount_point, display_name));
 }
 
 void VolumeManager::RemoveSmbFsVolume(const base::FilePath& mount_point) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
-  DoUnmountEvent(chromeos::MOUNT_ERROR_NONE,
+  DoUnmountEvent(ash::MountError::kNone,
                  *Volume::CreateForSmb(mount_point, ""));
 }
 
@@ -1744,7 +1740,7 @@
       }
       case ash::MountType::kDevice: {
         DoMountEvent(
-            chromeos::MOUNT_ERROR_NONE,
+            ash::MountError::kNone,
             Volume::CreateForRemovable(
                 mount_point.second, disk_mount_manager_->FindDiskBySourcePath(
                                         mount_point.second.source_path)));
@@ -1785,7 +1781,7 @@
 
     // Mount from the tail of chain.
     for (size_t i = chain.size(); i > 0; --i) {
-      DoMountEvent(chromeos::MOUNT_ERROR_NONE, std::move(chain[i - 1]));
+      DoMountEvent(ash::MountError::kNone, std::move(chain[i - 1]));
     }
   }
 }
@@ -1798,7 +1794,7 @@
   storage_monitor::StorageMonitor::GetInstance()->AddObserver(this);
 }
 
-void VolumeManager::DoMountEvent(chromeos::MountError error_code,
+void VolumeManager::DoMountEvent(ash::MountError error_code,
                                  std::unique_ptr<Volume> volume) {
   // Archive files are mounted globally in system. We however don't want to show
   // archives from profile-specific folders (Drive/Downloads) of other users in
@@ -1826,7 +1822,7 @@
   }
 
   Volume* raw_volume = volume.get();
-  if (error_code == chromeos::MOUNT_ERROR_NONE || volume->mount_condition()) {
+  if (error_code == ash::MountError::kNone || volume->mount_condition()) {
     mounted_volumes_[volume->volume_id()] = std::move(volume);
     UMA_HISTOGRAM_ENUMERATION("FileBrowser.VolumeType", raw_volume->type(),
                               NUM_VOLUME_TYPE);
@@ -1836,13 +1832,13 @@
     observer.OnVolumeMounted(error_code, *raw_volume);
 }
 
-void VolumeManager::DoUnmountEvent(chromeos::MountError error_code,
+void VolumeManager::DoUnmountEvent(ash::MountError error_code,
                                    const Volume& volume) {
   auto iter = mounted_volumes_.find(volume.volume_id());
   if (iter == mounted_volumes_.end())
     return;
   std::unique_ptr<Volume> volume_ref;
-  if (error_code == chromeos::MOUNT_ERROR_NONE) {
+  if (error_code == ash::MountError::kNone) {
     // It is important to hold a reference to the removed Volume from
     // |mounted_volumes_|, because OnVolumeMounted() will access it.
     volume_ref = std::move(iter->second);
@@ -1860,13 +1856,13 @@
 void VolumeManager::OnSshfsCrostiniUnmountCallback(
     const base::FilePath& sshfs_mount_path,
     RemoveSshfsCrostiniVolumeCallback callback,
-    chromeos::MountError error_code) {
-  if ((error_code == chromeos::MOUNT_ERROR_NONE) ||
-      (error_code == chromeos::MOUNT_ERROR_PATH_NOT_MOUNTED)) {
+    ash::MountError error_code) {
+  if ((error_code == ash::MountError::kNone) ||
+      (error_code == ash::MountError::kPathNotMounted)) {
     // Remove metadata associated with the mount. It will be a no-op if it
     // wasn't mounted or unmounted out of band.
     DoUnmountEvent(
-        chromeos::MOUNT_ERROR_NONE,
+        ash::MountError::kNone,
         *Volume::CreateForSshfsCrostini(sshfs_mount_path, base::FilePath()));
     if (callback)
       std::move(callback).Run(true);
@@ -1881,16 +1877,16 @@
 void VolumeManager::OnSftpGuestOsUnmountCallback(
     const base::FilePath& sftp_mount_path,
     RemoveSftpGuestOsVolumeCallback callback,
-    chromeos::MountError error_code) {
-  if ((error_code == chromeos::MOUNT_ERROR_NONE) ||
-      (error_code == chromeos::MOUNT_ERROR_PATH_NOT_MOUNTED)) {
+    ash::MountError error_code) {
+  if ((error_code == ash::MountError::kNone) ||
+      (error_code == ash::MountError::kPathNotMounted)) {
     // Remove metadata associated with the mount. It will be a no-op if it
     // wasn't mounted or unmounted out of band. We need the VolumeId to be
     // consistent, which means the mount path needs to be the same.
     // display_name, remote_mount_path and vm_type aren't needed and we don't
     // know them at unmount so leave them blank.
     DoUnmountEvent(
-        chromeos::MOUNT_ERROR_NONE,
+        ash::MountError::kNone,
         // TODO(b/230667118): Once http://crrev/3627129 makes it into
         // Chrome change the type to unknown.
         *Volume::CreateForSftpGuestOs("", sftp_mount_path, base::FilePath(),
diff --git a/chrome/browser/ash/file_manager/volume_manager.h b/chrome/browser/ash/file_manager/volume_manager.h
index da27500..4284c47 100644
--- a/chrome/browser/ash/file_manager/volume_manager.h
+++ b/chrome/browser/ash/file_manager/volume_manager.h
@@ -459,7 +459,7 @@
                      const std::string& device_path) override;
   void OnMountEvent(
       ash::disks::DiskMountManager::MountEvent event,
-      chromeos::MountError error_code,
+      ash::MountError error_code,
       const ash::disks::DiskMountManager::MountPointInfo& mount_info) override;
   void OnFormatEvent(ash::disks::DiskMountManager::FormatEvent event,
                      chromeos::FormatError error_code,
@@ -543,12 +543,11 @@
   void OnStorageMonitorInitialized();
   void DoAttachMtpStorage(const storage_monitor::StorageInfo& info,
                           device::mojom::MtpStorageInfoPtr mtp_storage_info);
-  void DoMountEvent(chromeos::MountError error_code,
-                    std::unique_ptr<Volume> volume);
-  void DoUnmountEvent(chromeos::MountError error_code, const Volume& volume);
+  void DoMountEvent(ash::MountError error_code, std::unique_ptr<Volume> volume);
+  void DoUnmountEvent(ash::MountError error_code, const Volume& volume);
   void OnExternalStorageDisabledChangedUnmountCallback(
       std::vector<std::string> remaining_mount_paths,
-      chromeos::MountError error_code);
+      ash::MountError error_code);
 
   // Returns the path of the mount point for drive.
   base::FilePath GetDriveMountPointPath() const;
@@ -556,11 +555,11 @@
   void OnSshfsCrostiniUnmountCallback(
       const base::FilePath& sshfs_mount_path,
       RemoveSshfsCrostiniVolumeCallback callback,
-      chromeos::MountError error_code);
+      ash::MountError error_code);
 
   void OnSftpGuestOsUnmountCallback(const base::FilePath& sftp_mount_path,
                                     RemoveSftpGuestOsVolumeCallback callback,
-                                    chromeos::MountError error_code);
+                                    ash::MountError error_code);
 
   Profile* profile_;
   drive::DriveIntegrationService* drive_integration_service_;  // Not owned.
diff --git a/chrome/browser/ash/file_manager/volume_manager_observer.h b/chrome/browser/ash/file_manager/volume_manager_observer.h
index 2e83924..8d8a6d14 100644
--- a/chrome/browser/ash/file_manager/volume_manager_observer.h
+++ b/chrome/browser/ash/file_manager/volume_manager_observer.h
@@ -38,11 +38,11 @@
   virtual void OnDeviceRemoved(const std::string& device_path) {}
 
   // Fired when a volume is mounted.
-  virtual void OnVolumeMounted(chromeos::MountError error_code,
+  virtual void OnVolumeMounted(ash::MountError error_code,
                                const Volume& volume) {}
 
   // Fired when a volume is unmounted.
-  virtual void OnVolumeUnmounted(chromeos::MountError error_code,
+  virtual void OnVolumeUnmounted(ash::MountError error_code,
                                  const Volume& volume) {}
 
   // Fired when formatting a device is started (or failed to start).
diff --git a/chrome/browser/ash/file_manager/volume_manager_unittest.cc b/chrome/browser/ash/file_manager/volume_manager_unittest.cc
index 3b24ec5..b4642f7 100644
--- a/chrome/browser/ash/file_manager/volume_manager_unittest.cc
+++ b/chrome/browser/ash/file_manager/volume_manager_unittest.cc
@@ -93,7 +93,7 @@
     bool mounting;
 
     // Available on VOLUME_MOUNTED and VOLUME_UNMOUNTED.
-    chromeos::MountError mount_error;
+    ash::MountError mount_error;
 
     // Available on FORMAT_STARTED and FORMAT_COMPLETED, PARTITION_STARTED,
     // PARTITION_COMPLETED.
@@ -139,7 +139,7 @@
     events_.push_back(event);
   }
 
-  void OnVolumeMounted(chromeos::MountError error_code,
+  void OnVolumeMounted(ash::MountError error_code,
                        const Volume& volume) override {
     Event event;
     event.type = Event::VOLUME_MOUNTED;
@@ -149,7 +149,7 @@
     events_.push_back(event);
   }
 
-  void OnVolumeUnmounted(chromeos::MountError error_code,
+  void OnVolumeUnmounted(ash::MountError error_code,
                          const Volume& volume) override {
     Event event;
     event.type = Event::VOLUME_UNMOUNTED;
@@ -391,7 +391,7 @@
                 ->GetMountPointPath()
                 .AsUTF8Unsafe(),
             event.device_path);
-  EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, event.mount_error);
+  EXPECT_EQ(ash::MountError::kNone, event.mount_error);
 
   volume_manager()->OnFileSystemBeingUnmounted();
 
@@ -402,7 +402,7 @@
                 ->GetMountPointPath()
                 .AsUTF8Unsafe(),
             event.device_path);
-  EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, event.mount_error);
+  EXPECT_EQ(ash::MountError::kNone, event.mount_error);
 
   volume_manager()->RemoveObserver(&observer);
 }
@@ -699,22 +699,22 @@
       ash::disks::MOUNT_CONDITION_NONE);
 
   volume_manager()->OnMountEvent(DiskMountManager::MOUNTING,
-                                 chromeos::MOUNT_ERROR_NONE, kMountPoint);
+                                 ash::MountError::kNone, kMountPoint);
 
   ASSERT_EQ(1U, observer.events().size());
   LoggingObserver::Event event = observer.events()[0];
   EXPECT_EQ(LoggingObserver::Event::VOLUME_MOUNTED, event.type);
   EXPECT_EQ("device1", event.device_path);
-  EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, event.mount_error);
+  EXPECT_EQ(ash::MountError::kNone, event.mount_error);
 
   volume_manager()->OnMountEvent(DiskMountManager::UNMOUNTING,
-                                 chromeos::MOUNT_ERROR_NONE, kMountPoint);
+                                 ash::MountError::kNone, kMountPoint);
 
   ASSERT_EQ(2U, observer.events().size());
   event = observer.events()[1];
   EXPECT_EQ(LoggingObserver::Event::VOLUME_UNMOUNTED, event.type);
   EXPECT_EQ("device1", event.device_path);
-  EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, event.mount_error);
+  EXPECT_EQ(ash::MountError::kNone, event.mount_error);
 
   volume_manager()->RemoveObserver(&observer);
 }
@@ -734,7 +734,7 @@
       ash::disks::MOUNT_CONDITION_NONE);
 
   volume_manager()->OnMountEvent(DiskMountManager::MOUNTING,
-                                 chromeos::MOUNT_ERROR_NONE, kMountPoint);
+                                 ash::MountError::kNone, kMountPoint);
 
   LoggingObserver observer;
 
@@ -746,20 +746,20 @@
 
     // After resume, the device is unmounted and then mounted.
     volume_manager()->OnMountEvent(DiskMountManager::UNMOUNTING,
-                                   chromeos::MOUNT_ERROR_NONE, kMountPoint);
+                                   ash::MountError::kNone, kMountPoint);
 
     // Observe what happened for the mount event.
     volume_manager()->AddObserver(&observer);
 
     volume_manager()->OnMountEvent(DiskMountManager::MOUNTING,
-                                   chromeos::MOUNT_ERROR_NONE, kMountPoint);
+                                   ash::MountError::kNone, kMountPoint);
   }
 
   ASSERT_EQ(1U, observer.events().size());
   const LoggingObserver::Event& event = observer.events()[0];
   EXPECT_EQ(LoggingObserver::Event::VOLUME_MOUNTED, event.type);
   EXPECT_EQ("device1", event.device_path);
-  EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, event.mount_error);
+  EXPECT_EQ(ash::MountError::kNone, event.mount_error);
 
   volume_manager()->RemoveObserver(&observer);
 }
@@ -773,7 +773,7 @@
       ash::disks::MOUNT_CONDITION_NONE);
 
   volume_manager()->OnMountEvent(DiskMountManager::UNMOUNTING,
-                                 chromeos::MOUNT_ERROR_NONE, kMountPoint);
+                                 ash::MountError::kNone, kMountPoint);
 
   // Unmount event for a disk not mounted in this manager is not reported.
   ASSERT_EQ(0U, observer.events().size());
@@ -967,7 +967,7 @@
       "failed_unmount", "", "", {}, ash::MountType::kDevice,
       chromeos::MOUNT_ACCESS_MODE_READ_WRITE, base::DoNothing());
   disk_mount_manager_->FailUnmountRequest("failed_unmount",
-                                          chromeos::MOUNT_ERROR_UNKNOWN);
+                                          ash::MountError::kUnknown);
 
   // Initially, there are four mount points.
   ASSERT_EQ(4U, disk_mount_manager_->mount_points().size());
@@ -1152,14 +1152,14 @@
 
   // Mount a USB stick.
   volume_manager()->OnMountEvent(
-      DiskMountManager::MOUNTING, chromeos::MOUNT_ERROR_NONE,
+      DiskMountManager::MOUNTING, ash::MountError::kNone,
       DiskMountManager::MountPointInfo("/removable/usb", "/removable/usb",
                                        ash::MountType::kDevice,
                                        ash::disks::MOUNT_CONDITION_NONE));
 
   // Mount a zip archive in the stick.
   volume_manager()->OnMountEvent(
-      DiskMountManager::MOUNTING, chromeos::MOUNT_ERROR_NONE,
+      DiskMountManager::MOUNTING, ash::MountError::kNone,
       DiskMountManager::MountPointInfo("/removable/usb/1.zip", "/archive/1",
                                        ash::MountType::kArchive,
                                        ash::disks::MOUNT_CONDITION_NONE));
@@ -1170,7 +1170,7 @@
 
   // Mount a zip archive in the previous zip archive.
   volume_manager()->OnMountEvent(
-      DiskMountManager::MOUNTING, chromeos::MOUNT_ERROR_NONE,
+      DiskMountManager::MOUNTING, ash::MountError::kNone,
       DiskMountManager::MountPointInfo("/archive/1/2.zip", "/archive/2",
                                        ash::MountType::kArchive,
                                        ash::disks::MOUNT_CONDITION_NONE));
@@ -1183,7 +1183,7 @@
   // A zip file is mounted from other profile. It must be ignored in the current
   // VolumeManager.
   volume_manager()->OnMountEvent(
-      DiskMountManager::MOUNTING, chromeos::MOUNT_ERROR_NONE,
+      DiskMountManager::MOUNTING, ash::MountError::kNone,
       DiskMountManager::MountPointInfo("/other/profile/drive/folder/3.zip",
                                        "/archive/3", ash::MountType::kArchive,
                                        ash::disks::MOUNT_CONDITION_NONE));
@@ -1330,7 +1330,7 @@
   unsigned index = 0;
   for (const auto& event : observer.events()) {
     EXPECT_EQ(LoggingObserver::Event::VOLUME_MOUNTED, event.type);
-    EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, event.mount_error);
+    EXPECT_EQ(ash::MountError::kNone, event.mount_error);
     if (index < 4) {
       EXPECT_EQ(arc::GetMediaViewVolumeId(arc_volume_ids[index]),
                 event.volume_id);
@@ -1361,7 +1361,7 @@
   unsigned index = 0;
   for (const auto& event : observer.events()) {
     EXPECT_EQ(LoggingObserver::Event::VOLUME_UNMOUNTED, event.type);
-    EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, event.mount_error);
+    EXPECT_EQ(ash::MountError::kNone, event.mount_error);
     if (index < 4) {
       EXPECT_EQ(arc::GetMediaViewVolumeId(arc_volume_ids[index]),
                 event.volume_id);
diff --git a/chrome/browser/ash/guest_os/guest_os_share_path.cc b/chrome/browser/ash/guest_os/guest_os_share_path.cc
index 128acc6..b616150 100644
--- a/chrome/browser/ash/guest_os/guest_os_share_path.cc
+++ b/chrome/browser/ash/guest_os/guest_os_share_path.cc
@@ -624,9 +624,9 @@
   }
 }
 
-void GuestOsSharePath::OnVolumeMounted(chromeos::MountError error_code,
+void GuestOsSharePath::OnVolumeMounted(ash::MountError error_code,
                                        const file_manager::Volume& volume) {
-  if (error_code != chromeos::MountError::MOUNT_ERROR_NONE) {
+  if (error_code != ash::MountError::kNone) {
     return;
   }
 
@@ -652,10 +652,10 @@
   }
 }
 
-void GuestOsSharePath::OnVolumeUnmounted(chromeos::MountError error_code,
+void GuestOsSharePath::OnVolumeUnmounted(ash::MountError error_code,
                                          const file_manager::Volume& volume) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  if (error_code != chromeos::MountError::MOUNT_ERROR_NONE) {
+  if (error_code != ash::MountError::kNone) {
     return;
   }
   for (auto it = shared_paths_.begin(); it != shared_paths_.end();) {
diff --git a/chrome/browser/ash/guest_os/guest_os_share_path.h b/chrome/browser/ash/guest_os/guest_os_share_path.h
index 2992561f..0b31c0ce 100644
--- a/chrome/browser/ash/guest_os/guest_os_share_path.h
+++ b/chrome/browser/ash/guest_os/guest_os_share_path.h
@@ -125,9 +125,9 @@
   void OnVmShutdown(const std::string& vm_name) override;
 
   // file_manager::VolumeManagerObserver
-  void OnVolumeMounted(chromeos::MountError error_code,
+  void OnVolumeMounted(ash::MountError error_code,
                        const file_manager::Volume& volume) override;
-  void OnVolumeUnmounted(chromeos::MountError error_code,
+  void OnVolumeUnmounted(ash::MountError error_code,
                          const file_manager::Volume& volume) override;
 
   // drivefs::DriveFsHostObserver
diff --git a/chrome/browser/ash/guest_os/guest_os_share_path_unittest.cc b/chrome/browser/ash/guest_os/guest_os_share_path_unittest.cc
index 95b3bd1..d51e11d 100644
--- a/chrome/browser/ash/guest_os/guest_os_share_path_unittest.cc
+++ b/chrome/browser/ash/guest_os/guest_os_share_path_unittest.cc
@@ -952,7 +952,7 @@
       Persist::NO, SeneschalClientCalled::YES,
       &vm_tools::seneschal::SharePathRequest::MY_FILES, "already-shared",
       Success::YES, ""));
-  guest_os_share_path_->OnVolumeMounted(chromeos::MountError::MOUNT_ERROR_NONE,
+  guest_os_share_path_->OnVolumeMounted(ash::MountError::kNone,
                                         *volume_downloads_);
   run_loop_->Run();
 }
@@ -969,7 +969,7 @@
       Persist::NO, SeneschalClientCalled::YES,
       &vm_tools::seneschal::SharePathRequest::MY_FILES, "already-shared",
       Success::YES, ""));
-  guest_os_share_path_->OnVolumeMounted(chromeos::MountError::MOUNT_ERROR_NONE,
+  guest_os_share_path_->OnVolumeMounted(ash::MountError::kNone,
                                         *volume_shared_path);
   run_loop()->Run();
 }
@@ -978,13 +978,13 @@
   SetUpVolume();
 
   // Test mount.
-  guest_os_share_path_->OnVolumeMounted(chromeos::MountError::MOUNT_ERROR_NONE,
+  guest_os_share_path_->OnVolumeMounted(ash::MountError::kNone,
                                         *volume_downloads_);
   EXPECT_EQ(fake_seneschal_client_->share_path_called(), false);
 
   // Test unmount.
-  guest_os_share_path_->OnVolumeUnmounted(
-      chromeos::MountError::MOUNT_ERROR_NONE, *volume_downloads_);
+  guest_os_share_path_->OnVolumeUnmounted(ash::MountError::kNone,
+                                          *volume_downloads_);
   EXPECT_EQ(fake_seneschal_client_->share_path_called(), false);
 }
 
@@ -994,13 +994,13 @@
       base::FilePath("/unrelated/path"));
 
   // Test mount.
-  guest_os_share_path_->OnVolumeMounted(chromeos::MountError::MOUNT_ERROR_NONE,
+  guest_os_share_path_->OnVolumeMounted(ash::MountError::kNone,
                                         *volume_unrelated_);
   EXPECT_EQ(fake_seneschal_client_->share_path_called(), false);
 
   // Test unmount.
-  guest_os_share_path_->OnVolumeUnmounted(
-      chromeos::MountError::MOUNT_ERROR_NONE, *volume_unrelated_);
+  guest_os_share_path_->OnVolumeUnmounted(ash::MountError::kNone,
+                                          *volume_unrelated_);
   EXPECT_EQ(fake_seneschal_client_->share_path_called(), false);
 }
 
@@ -1012,8 +1012,8 @@
       &GuestOsSharePathTest::SeneschalUnsharePathCallback,
       base::Unretained(this), "unshare-on-unmount", shared_path_, Persist::YES,
       SeneschalClientCalled::YES, "MyFiles/already-shared", Success::YES, ""));
-  guest_os_share_path_->OnVolumeUnmounted(
-      chromeos::MountError::MOUNT_ERROR_NONE, *volume_downloads_);
+  guest_os_share_path_->OnVolumeUnmounted(ash::MountError::kNone,
+                                          *volume_downloads_);
   run_loop()->Run();
 }
 
@@ -1027,8 +1027,8 @@
       &GuestOsSharePathTest::SeneschalUnsharePathCallback,
       base::Unretained(this), "unshare-on-unmount", shared_path_, Persist::YES,
       SeneschalClientCalled::YES, "MyFiles/already-shared", Success::YES, ""));
-  guest_os_share_path_->OnVolumeUnmounted(
-      chromeos::MountError::MOUNT_ERROR_NONE, *volume_shared_path);
+  guest_os_share_path_->OnVolumeUnmounted(ash::MountError::kNone,
+                                          *volume_shared_path);
   run_loop()->Run();
 }
 
diff --git a/chrome/browser/ash/guest_os/public/guest_os_mount_provider.cc b/chrome/browser/ash/guest_os/public/guest_os_mount_provider.cc
index 7329959..2f0279c 100644
--- a/chrome/browser/ash/guest_os/public/guest_os_mount_provider.cc
+++ b/chrome/browser/ash/guest_os/public/guest_os_mount_provider.cc
@@ -124,9 +124,9 @@
   void OnMountEvent(
       RealCallback callback,
       base::FilePath remote_path,
-      chromeos::MountError error_code,
+      ash::MountError error_code,
       const ash::disks::DiskMountManager::MountPointInfo& mount_info) {
-    if (error_code != chromeos::MountError::MOUNT_ERROR_NONE) {
+    if (error_code != ash::MountError::kNone) {
       LOG(ERROR) << "Error mounting Guest OS container: error_code="
                  << error_code << ", source_path=" << mount_info.source_path
                  << ", mount_path=" << mount_info.mount_path
diff --git a/chrome/browser/ash/guest_os/public/guest_os_mount_provider_unittest.cc b/chrome/browser/ash/guest_os/public/guest_os_mount_provider_unittest.cc
index 026515f..7b96aee 100644
--- a/chrome/browser/ash/guest_os/public/guest_os_mount_provider_unittest.cc
+++ b/chrome/browser/ash/guest_os/public/guest_os_mount_provider_unittest.cc
@@ -86,7 +86,7 @@
       chromeos::MountAccessMode access_mode,
       ash::disks::DiskMountManager::MountPathCallback callback) {
     auto event = DiskMountManager::MountEvent::MOUNTING;
-    auto code = chromeos::MountError::MOUNT_ERROR_NONE;
+    auto code = ash::MountError::kNone;
     auto info = DiskMountManager::MountPointInfo(
         base::StringPrintf("sftp://%d:%d", cid_, port_),
         "/media/fuse/" + kMountName, ash::MountType::kNetworkStorage,
@@ -170,7 +170,7 @@
           [this](const std::string& mount_path,
                  DiskMountManager::UnmountPathCallback callback) {
             EXPECT_EQ(mount_path, "/media/fuse/" + kMountName);
-            std::move(callback).Run(chromeos::MOUNT_ERROR_NONE);
+            std::move(callback).Run(ash::MountError::kNone);
           }));
 
   provider_->Mount(
diff --git a/chrome/browser/ash/input_method/longpress_diacritics_suggester.cc b/chrome/browser/ash/input_method/longpress_diacritics_suggester.cc
index 0d9d819..a45c4ec9 100644
--- a/chrome/browser/ash/input_method/longpress_diacritics_suggester.cc
+++ b/chrome/browser/ash/input_method/longpress_diacritics_suggester.cc
@@ -10,6 +10,7 @@
 #include "base/containers/flat_map.h"
 #include "base/logging.h"
 #include "base/no_destructor.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/strings/string_split.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/ash/input_method/ui/assistive_delegate.h"
@@ -133,6 +134,21 @@
       highlighted_index_ = new_index;
       return SuggestionStatus::kBrowsing;
     default:
+      size_t key_number = 0;
+      // If the key value is a number then accept the corresponding suggestion.
+      if (base::StringToSizeT(std::u16string(1, event.GetCharacter()),
+                              &key_number)) {
+        // Ignore 0 values, make sure the key numbers are valid.
+        if (1 <= key_number && key_number <= 9 &&
+            key_number <= GetCurrentShownDiacritics().size()) {
+          // The "key" char value starts from 1.
+          // The actual index of the suggestions start at 0.
+          size_t index_to_accept = key_number - 1;
+          if (AcceptSuggestion(index_to_accept)) {
+            return SuggestionStatus::kAccept;
+          }
+        }
+      }
       return SuggestionStatus::kNotHandled;
   }
 }
diff --git a/chrome/browser/ash/input_method/longpress_diacritics_suggester_unittest.cc b/chrome/browser/ash/input_method/longpress_diacritics_suggester_unittest.cc
index 49fc88e..88c93d02 100644
--- a/chrome/browser/ash/input_method/longpress_diacritics_suggester_unittest.cc
+++ b/chrome/browser/ash/input_method/longpress_diacritics_suggester_unittest.cc
@@ -364,6 +364,182 @@
   EXPECT_EQ(suggestion_handler.GetDeletePreviousUtf16Len(), 1);
 }
 
+TEST_P(LongpressDiacriticsSuggesterTest, NotHandledOnDigit0KeyPress) {
+  FakeSuggestionHandler suggestion_handler;
+  LongpressDiacriticsSuggester suggester =
+      LongpressDiacriticsSuggester(&suggestion_handler);
+  suggester.OnFocus(kContextId);
+
+  suggester.TrySuggestOnLongpress(GetParam().longpress_char);
+  suggester.HandleKeyEvent(CreateKeyEventFromCode(ui::DomCode::DIGIT0));
+
+  EXPECT_EQ(suggestion_handler.GetContextId(), kContextId);
+  EXPECT_FALSE(suggestion_handler.GetAcceptedSuggestion());
+}
+
+TEST_P(LongpressDiacriticsSuggesterTest, HandlesDigit1KeyPress) {
+  FakeSuggestionHandler suggestion_handler;
+  LongpressDiacriticsSuggester suggester =
+      LongpressDiacriticsSuggester(&suggestion_handler);
+  suggester.OnFocus(kContextId);
+
+  suggester.TrySuggestOnLongpress(GetParam().longpress_char);
+  suggester.HandleKeyEvent(CreateKeyEventFromCode(ui::DomCode::DIGIT1));
+
+  EXPECT_EQ(suggestion_handler.GetContextId(), kContextId);
+  EXPECT_FALSE(suggestion_handler.GetShowingSuggestion());
+  EXPECT_EQ(suggestion_handler.GetAcceptedSuggestionText(),
+            GetParam().candidates[0]);
+  EXPECT_EQ(suggestion_handler.GetDeletePreviousUtf16Len(), 1);
+}
+
+TEST_P(LongpressDiacriticsSuggesterTest, HandlesDigit2KeyPress) {
+  FakeSuggestionHandler suggestion_handler;
+  LongpressDiacriticsSuggester suggester =
+      LongpressDiacriticsSuggester(&suggestion_handler);
+  suggester.OnFocus(kContextId);
+
+  suggester.TrySuggestOnLongpress(GetParam().longpress_char);
+  suggester.HandleKeyEvent(CreateKeyEventFromCode(ui::DomCode::DIGIT2));
+
+  if (GetParam().candidates.size() < 2) {
+    EXPECT_EQ(suggestion_handler.GetContextId(), kContextId);
+    EXPECT_FALSE(suggestion_handler.GetAcceptedSuggestion());
+  } else {
+    EXPECT_EQ(suggestion_handler.GetContextId(), kContextId);
+    EXPECT_FALSE(suggestion_handler.GetShowingSuggestion());
+    EXPECT_EQ(suggestion_handler.GetAcceptedSuggestionText(),
+              GetParam().candidates[1]);
+    EXPECT_EQ(suggestion_handler.GetDeletePreviousUtf16Len(), 1);
+  }
+}
+
+TEST_P(LongpressDiacriticsSuggesterTest, HandlesDigit3KeyPress) {
+  FakeSuggestionHandler suggestion_handler;
+  LongpressDiacriticsSuggester suggester =
+      LongpressDiacriticsSuggester(&suggestion_handler);
+  suggester.OnFocus(kContextId);
+
+  suggester.TrySuggestOnLongpress(GetParam().longpress_char);
+  suggester.HandleKeyEvent(CreateKeyEventFromCode(ui::DomCode::DIGIT3));
+
+  if (GetParam().candidates.size() < 3) {
+    EXPECT_EQ(suggestion_handler.GetContextId(), kContextId);
+    EXPECT_FALSE(suggestion_handler.GetAcceptedSuggestion());
+  } else {
+    EXPECT_EQ(suggestion_handler.GetContextId(), kContextId);
+    EXPECT_FALSE(suggestion_handler.GetShowingSuggestion());
+    EXPECT_EQ(suggestion_handler.GetAcceptedSuggestionText(),
+              GetParam().candidates[2]);
+    EXPECT_EQ(suggestion_handler.GetDeletePreviousUtf16Len(), 1);
+  }
+}
+
+TEST_P(LongpressDiacriticsSuggesterTest, HandlesDigit4KeyPress) {
+  FakeSuggestionHandler suggestion_handler;
+  LongpressDiacriticsSuggester suggester =
+      LongpressDiacriticsSuggester(&suggestion_handler);
+  suggester.OnFocus(kContextId);
+
+  suggester.TrySuggestOnLongpress(GetParam().longpress_char);
+  suggester.HandleKeyEvent(CreateKeyEventFromCode(ui::DomCode::DIGIT4));
+
+  if (GetParam().candidates.size() < 4) {
+    EXPECT_EQ(suggestion_handler.GetContextId(), kContextId);
+    EXPECT_FALSE(suggestion_handler.GetAcceptedSuggestion());
+  } else {
+    EXPECT_EQ(suggestion_handler.GetContextId(), kContextId);
+    EXPECT_FALSE(suggestion_handler.GetShowingSuggestion());
+    EXPECT_EQ(suggestion_handler.GetAcceptedSuggestionText(),
+              GetParam().candidates[3]);
+    EXPECT_EQ(suggestion_handler.GetDeletePreviousUtf16Len(), 1);
+  }
+}
+
+TEST_P(LongpressDiacriticsSuggesterTest, HandlesDigit5KeyPress) {
+  FakeSuggestionHandler suggestion_handler;
+  LongpressDiacriticsSuggester suggester =
+      LongpressDiacriticsSuggester(&suggestion_handler);
+  suggester.OnFocus(kContextId);
+
+  suggester.TrySuggestOnLongpress(GetParam().longpress_char);
+  suggester.HandleKeyEvent(CreateKeyEventFromCode(ui::DomCode::DIGIT5));
+
+  if (GetParam().candidates.size() < 5) {
+    EXPECT_EQ(suggestion_handler.GetContextId(), kContextId);
+    EXPECT_FALSE(suggestion_handler.GetAcceptedSuggestion());
+  } else {
+    EXPECT_EQ(suggestion_handler.GetContextId(), kContextId);
+    EXPECT_FALSE(suggestion_handler.GetShowingSuggestion());
+    EXPECT_EQ(suggestion_handler.GetAcceptedSuggestionText(),
+              GetParam().candidates[4]);
+    EXPECT_EQ(suggestion_handler.GetDeletePreviousUtf16Len(), 1);
+  }
+}
+
+TEST_P(LongpressDiacriticsSuggesterTest, HandlesDigit6KeyPress) {
+  FakeSuggestionHandler suggestion_handler;
+  LongpressDiacriticsSuggester suggester =
+      LongpressDiacriticsSuggester(&suggestion_handler);
+  suggester.OnFocus(kContextId);
+
+  suggester.TrySuggestOnLongpress(GetParam().longpress_char);
+  suggester.HandleKeyEvent(CreateKeyEventFromCode(ui::DomCode::DIGIT6));
+
+  if (GetParam().candidates.size() < 6) {
+    EXPECT_EQ(suggestion_handler.GetContextId(), kContextId);
+    EXPECT_FALSE(suggestion_handler.GetAcceptedSuggestion());
+  } else {
+    EXPECT_EQ(suggestion_handler.GetContextId(), kContextId);
+    EXPECT_FALSE(suggestion_handler.GetShowingSuggestion());
+    EXPECT_EQ(suggestion_handler.GetAcceptedSuggestionText(),
+              GetParam().candidates[5]);
+    EXPECT_EQ(suggestion_handler.GetDeletePreviousUtf16Len(), 1);
+  }
+}
+
+TEST_P(LongpressDiacriticsSuggesterTest, HandlesDigit7KeyPress) {
+  FakeSuggestionHandler suggestion_handler;
+  LongpressDiacriticsSuggester suggester =
+      LongpressDiacriticsSuggester(&suggestion_handler);
+  suggester.OnFocus(kContextId);
+
+  suggester.TrySuggestOnLongpress(GetParam().longpress_char);
+  suggester.HandleKeyEvent(CreateKeyEventFromCode(ui::DomCode::DIGIT7));
+
+  if (GetParam().candidates.size() < 7) {
+    EXPECT_EQ(suggestion_handler.GetContextId(), kContextId);
+    EXPECT_FALSE(suggestion_handler.GetAcceptedSuggestion());
+  } else {
+    EXPECT_EQ(suggestion_handler.GetContextId(), kContextId);
+    EXPECT_FALSE(suggestion_handler.GetShowingSuggestion());
+    EXPECT_EQ(suggestion_handler.GetAcceptedSuggestionText(),
+              GetParam().candidates[6]);
+    EXPECT_EQ(suggestion_handler.GetDeletePreviousUtf16Len(), 1);
+  }
+}
+
+TEST_P(LongpressDiacriticsSuggesterTest, HandlesDigit8KeyPress) {
+  FakeSuggestionHandler suggestion_handler;
+  LongpressDiacriticsSuggester suggester =
+      LongpressDiacriticsSuggester(&suggestion_handler);
+  suggester.OnFocus(kContextId);
+
+  suggester.TrySuggestOnLongpress(GetParam().longpress_char);
+  suggester.HandleKeyEvent(CreateKeyEventFromCode(ui::DomCode::DIGIT8));
+
+  if (GetParam().candidates.size() < 8) {
+    EXPECT_EQ(suggestion_handler.GetContextId(), kContextId);
+    EXPECT_FALSE(suggestion_handler.GetAcceptedSuggestion());
+  } else {
+    EXPECT_EQ(suggestion_handler.GetContextId(), kContextId);
+    EXPECT_FALSE(suggestion_handler.GetShowingSuggestion());
+    EXPECT_EQ(suggestion_handler.GetAcceptedSuggestionText(),
+              GetParam().candidates[7]);
+    EXPECT_EQ(suggestion_handler.GetDeletePreviousUtf16Len(), 1);
+  }
+}
+
 TEST_P(LongpressDiacriticsSuggesterTest,
        NotHandledOnEnterKeyPressIfNoHighlight) {
   FakeSuggestionHandler suggestion_handler;
diff --git a/chrome/browser/ash/login/signin/signin_error_notifier_unittest.cc b/chrome/browser/ash/login/signin/signin_error_notifier_unittest.cc
index 96d1576..c3eeab3 100644
--- a/chrome/browser/ash/login/signin/signin_error_notifier_unittest.cc
+++ b/chrome/browser/ash/login/signin/signin_error_notifier_unittest.cc
@@ -33,17 +33,17 @@
 namespace ash {
 namespace {
 
-const char kTestEmail[] = "email@example.com";
-const char kTestSecondaryEmail[] = "email2@example.com";
+constexpr char kTestEmail[] = "email@example.com";
+constexpr char kTestSecondaryEmail[] = "email2@example.com";
 
-const char kTokenHandle[] = "test_token_handle";
+constexpr char kTokenHandle[] = "test_token_handle";
 
 // Notification ID corresponding to kProfileSigninNotificationId +
 // kTestAccountId.
-const char kPrimaryAccountErrorNotificationId[] =
-    "chrome://settings/signin/testing_profile";
-const char kSecondaryAccountErrorNotificationId[] =
-    "chrome://settings/signin/testing_profile/secondary-account";
+constexpr char kPrimaryAccountErrorNotificationId[] =
+    "chrome://settings/signin/testing_profile@test";
+constexpr char kSecondaryAccountErrorNotificationId[] =
+    "chrome://settings/signin/testing_profile@test/secondary-account";
 }  // namespace
 
 class SigninErrorNotifierTest : public BrowserWithTestWindowTest {
diff --git a/chrome/browser/ash/smb_client/smbfs_share.cc b/chrome/browser/ash/smb_client/smbfs_share.cc
index 6c7665d..ddcacd7 100644
--- a/chrome/browser/ash/smb_client/smbfs_share.cc
+++ b/chrome/browser/ash/smb_client/smbfs_share.cc
@@ -146,7 +146,7 @@
 void SmbFsShare::Unmount(SmbFsShare::UnmountCallback callback) {
   if (unmount_pending_) {
     LOG(WARNING) << "Cannot unmount a shared that is being unmounted";
-    std::move(callback).Run(chromeos::MountError::MOUNT_ERROR_INTERNAL);
+    std::move(callback).Run(MountError::kInternal);
     return;
   }
 
@@ -157,7 +157,7 @@
 
   if (!host_) {
     LOG(WARNING) << "Cannot unmount as the share is already unmounted";
-    std::move(callback).Run(chromeos::MountError::MOUNT_ERROR_PATH_NOT_MOUNTED);
+    std::move(callback).Run(MountError::kPathNotMounted);
     return;
   }
 
@@ -183,7 +183,7 @@
 }
 
 void SmbFsShare::OnUnmountDone(SmbFsShare::UnmountCallback callback,
-                               chromeos::MountError result) {
+                               MountError result) {
   host_.reset();
 
   // Must do this *after* destroying SmbFsHost so that reentrant calls to
diff --git a/chrome/browser/ash/smb_client/smbfs_share.h b/chrome/browser/ash/smb_client/smbfs_share.h
index 9ad0fbb..99b2918 100644
--- a/chrome/browser/ash/smb_client/smbfs_share.h
+++ b/chrome/browser/ash/smb_client/smbfs_share.h
@@ -32,7 +32,7 @@
   using KerberosOptions = smbfs::SmbFsMounter::KerberosOptions;
   using MountOptions = smbfs::SmbFsMounter::MountOptions;
   using MountCallback = base::OnceCallback<void(SmbMountResult)>;
-  using UnmountCallback = base::OnceCallback<void(chromeos::MountError)>;
+  using UnmountCallback = base::OnceCallback<void(MountError)>;
   using RemoveCredentialsCallback = base::OnceCallback<void(bool)>;
   using DeleteRecursivelyCallback = base::OnceCallback<void(base::File::Error)>;
   using MounterCreationCallback =
@@ -97,8 +97,7 @@
                    std::unique_ptr<smbfs::SmbFsHost> smbfs_host);
 
   // Called after cros-disks has attempted to unmount the share.
-  void OnUnmountDone(SmbFsShare::UnmountCallback callback,
-                     chromeos::MountError result);
+  void OnUnmountDone(SmbFsShare::UnmountCallback callback, MountError result);
 
   // Callback for smb_dialog::SmbCredentialsDialog::Show().
   void OnSmbCredentialsDialogShowDone(RequestCredentialsCallback callback,
diff --git a/chrome/browser/ash/smb_client/smbfs_share_unittest.cc b/chrome/browser/ash/smb_client/smbfs_share_unittest.cc
index b665a05..77f01f5 100644
--- a/chrome/browser/ash/smb_client/smbfs_share_unittest.cc
+++ b/chrome/browser/ash/smb_client/smbfs_share_unittest.cc
@@ -64,13 +64,11 @@
  public:
   MOCK_METHOD(void,
               OnVolumeMounted,
-              (chromeos::MountError error_code,
-               const file_manager::Volume& volume),
+              (MountError error_code, const file_manager::Volume& volume),
               (override));
   MOCK_METHOD(void,
               OnVolumeUnmounted,
-              (chromeos::MountError error_code,
-               const file_manager::Volume& volume),
+              (MountError error_code, const file_manager::Volume& volume),
               (override));
 };
 
@@ -172,7 +170,7 @@
   EXPECT_CALL(
       observer_,
       OnVolumeMounted(
-          chromeos::MOUNT_ERROR_NONE,
+          MountError::kNone,
           AllOf(Property(&file_manager::Volume::type,
                          file_manager::VOLUME_TYPE_SMB),
                 Property(&file_manager::Volume::mount_path,
@@ -180,7 +178,7 @@
                 Property(&file_manager::Volume::volume_label, kDisplayName))))
       .Times(1);
   EXPECT_CALL(observer_, OnVolumeUnmounted(
-                             chromeos::MOUNT_ERROR_NONE,
+                             MountError::kNone,
                              AllOf(Property(&file_manager::Volume::type,
                                             file_manager::VOLUME_TYPE_SMB),
                                    Property(&file_manager::Volume::mount_path,
@@ -210,10 +208,8 @@
       .WillOnce([](smbfs::SmbFsMounter::DoneCallback callback) {
         std::move(callback).Run(smbfs::mojom::MountError::kTimeout, nullptr);
       });
-  EXPECT_CALL(observer_, OnVolumeMounted(chromeos::MOUNT_ERROR_NONE, _))
-      .Times(0);
-  EXPECT_CALL(observer_, OnVolumeUnmounted(chromeos::MOUNT_ERROR_NONE, _))
-      .Times(0);
+  EXPECT_CALL(observer_, OnVolumeMounted(MountError::kNone, _)).Times(0);
+  EXPECT_CALL(observer_, OnVolumeUnmounted(MountError::kNone, _)).Times(0);
 
   SmbFsShare share(&profile_, SmbUrl(kSharePath), kDisplayName, {});
   share.SetMounterCreationCallbackForTest(mounter_creation_callback_);
@@ -249,7 +245,7 @@
   EXPECT_CALL(
       observer_,
       OnVolumeMounted(
-          chromeos::MOUNT_ERROR_NONE,
+          MountError::kNone,
           AllOf(Property(&file_manager::Volume::type,
                          file_manager::VOLUME_TYPE_SMB),
                 Property(&file_manager::Volume::mount_path,
@@ -258,7 +254,7 @@
       .Times(1);
   base::RunLoop run_loop;
   EXPECT_CALL(observer_, OnVolumeUnmounted(
-                             chromeos::MOUNT_ERROR_NONE,
+                             MountError::kNone,
                              AllOf(Property(&file_manager::Volume::type,
                                             file_manager::VOLUME_TYPE_SMB),
                                    Property(&file_manager::Volume::mount_path,
@@ -290,10 +286,8 @@
             smbfs::mojom::MountError::kOk,
             CreateSmbFsHost(&share, &smbfs_receiver, &delegate));
       });
-  EXPECT_CALL(observer_, OnVolumeMounted(chromeos::MOUNT_ERROR_NONE, _))
-      .Times(1);
-  EXPECT_CALL(observer_, OnVolumeUnmounted(chromeos::MOUNT_ERROR_NONE, _))
-      .Times(1);
+  EXPECT_CALL(observer_, OnVolumeMounted(MountError::kNone, _)).Times(1);
+  EXPECT_CALL(observer_, OnVolumeUnmounted(MountError::kNone, _)).Times(1);
 
   {
     base::RunLoop run_loop;
@@ -328,10 +322,8 @@
             smbfs::mojom::MountError::kOk,
             CreateSmbFsHost(&share, &smbfs_receiver, &delegate));
       });
-  EXPECT_CALL(observer_, OnVolumeMounted(chromeos::MOUNT_ERROR_NONE, _))
-      .Times(1);
-  EXPECT_CALL(observer_, OnVolumeUnmounted(chromeos::MOUNT_ERROR_NONE, _))
-      .Times(1);
+  EXPECT_CALL(observer_, OnVolumeMounted(MountError::kNone, _)).Times(1);
+  EXPECT_CALL(observer_, OnVolumeUnmounted(MountError::kNone, _)).Times(1);
 
   {
     base::RunLoop run_loop;
@@ -371,10 +363,8 @@
             smbfs::mojom::MountError::kOk,
             CreateSmbFsHost(&share, &smbfs_receiver, &delegate));
       });
-  EXPECT_CALL(observer_, OnVolumeMounted(chromeos::MOUNT_ERROR_NONE, _))
-      .Times(1);
-  EXPECT_CALL(observer_, OnVolumeUnmounted(chromeos::MOUNT_ERROR_NONE, _))
-      .Times(1);
+  EXPECT_CALL(observer_, OnVolumeMounted(MountError::kNone, _)).Times(1);
+  EXPECT_CALL(observer_, OnVolumeUnmounted(MountError::kNone, _)).Times(1);
 
   {
     base::RunLoop run_loop;
@@ -413,10 +403,8 @@
             smbfs::mojom::MountError::kOk,
             CreateSmbFsHost(&share, &smbfs_receiver, &delegate));
       });
-  EXPECT_CALL(observer_, OnVolumeMounted(chromeos::MOUNT_ERROR_NONE, _))
-      .Times(1);
-  EXPECT_CALL(observer_, OnVolumeUnmounted(chromeos::MOUNT_ERROR_NONE, _))
-      .Times(1);
+  EXPECT_CALL(observer_, OnVolumeMounted(MountError::kNone, _)).Times(1);
+  EXPECT_CALL(observer_, OnVolumeUnmounted(MountError::kNone, _)).Times(1);
 
   {
     base::RunLoop run_loop;
diff --git a/chrome/browser/ash/sync/sync_error_notifier_unittest.cc b/chrome/browser/ash/sync/sync_error_notifier_unittest.cc
index 249cad9..2489539 100644
--- a/chrome/browser/ash/sync/sync_error_notifier_unittest.cc
+++ b/chrome/browser/ash/sync/sync_error_notifier_unittest.cc
@@ -25,7 +25,8 @@
 
 // Notification ID corresponding to kProfileSyncNotificationId + the test
 // profile's name.
-const char kNotificationId[] = "chrome://settings/sync/testing_profile";
+constexpr char kNotificationId[] =
+    "chrome://settings/sync/testing_profile@test";
 
 class FakeLoginUIService : public LoginUIService {
  public:
diff --git a/chrome/browser/ash/usb/cros_usb_detector.cc b/chrome/browser/ash/usb/cros_usb_detector.cc
index 535d5c6..296f7a4 100644
--- a/chrome/browser/ash/usb/cros_usb_detector.cc
+++ b/chrome/browser/ash/usb/cros_usb_detector.cc
@@ -372,7 +372,7 @@
 }
 
 void FilesystemUnmounter::OnUnmountPath(MountError mount_error) {
-  if (mount_error != MOUNT_ERROR_NONE) {
+  if (mount_error != MountError::kNone) {
     LOG(ERROR) << "Error unmounting USB drive: " << mount_error;
     success_ = false;
   }
@@ -573,7 +573,7 @@
     MountError error_code,
     const disks::DiskMountManager::MountPointInfo& mount_info) {
   if (mount_info.mount_type != MountType::kDevice ||
-      error_code != MOUNT_ERROR_NONE) {
+      error_code != MountError::kNone) {
     return;
   }
 
diff --git a/chrome/browser/ash/usb/cros_usb_detector_unittest.cc b/chrome/browser/ash/usb/cros_usb_detector_unittest.cc
index 11cc26a..9455fce6 100644
--- a/chrome/browser/ash/usb/cros_usb_detector_unittest.cc
+++ b/chrome/browser/ash/usb/cros_usb_detector_unittest.cc
@@ -55,7 +55,7 @@
 namespace {
 
 using testing::_;
-using MountCallback = ::base::OnceCallback<void(chromeos::MountError)>;
+using MountCallback = ::base::OnceCallback<void(MountError)>;
 
 const char* kProfileName = "test@example.com";
 
@@ -264,10 +264,9 @@
       NotifyMountEvent(name, disks::DiskMountManager::MOUNTING);
   }
 
-  void NotifyMountEvent(
-      const std::string& name,
-      disks::DiskMountManager::MountEvent event,
-      chromeos::MountError mount_error = chromeos::MOUNT_ERROR_NONE) {
+  void NotifyMountEvent(const std::string& name,
+                        disks::DiskMountManager::MountEvent event,
+                        MountError mount_error = MountError::kNone) {
     // In theory we should also clear the mounted flag from the disk, but we
     // don't rely on that.
     disks::DiskMountManager::MountPointInfo info(
@@ -1062,7 +1061,7 @@
   AddDisk("disk1", 3, 4, true);
   AddDisk("disk2", 3, 4, /*mounted=*/false);
   NotifyMountEvent("disk2", disks::DiskMountManager::MOUNTING,
-                   chromeos::MOUNT_ERROR_INTERNAL);
+                   MountError::kInternal);
   AddDisk("disk3", 3, 5, true);
   AddDisk("disk4", 3, 4, true);
   AddDisk("disk5", 2, 4, true);
@@ -1078,14 +1077,14 @@
 
   // Unmount events would normally be fired by the DiskMountManager.
   NotifyMountEvent("disk1", disks::DiskMountManager::UNMOUNTING);
-  std::move(callback1).Run(chromeos::MOUNT_ERROR_NONE);
+  std::move(callback1).Run(MountError::kNone);
   base::RunLoop().RunUntilIdle();
   EXPECT_FALSE(GetSingleDeviceInfo().shared_vm_name.has_value());
   EXPECT_EQ(fake_concierge_client_->attach_usb_device_call_count(), 0);
 
   // All unmounts must complete before sharing succeeds.
   NotifyMountEvent("disk4", disks::DiskMountManager::UNMOUNTING);
-  std::move(callback4).Run(chromeos::MOUNT_ERROR_NONE);
+  std::move(callback4).Run(MountError::kNone);
   base::RunLoop().RunUntilIdle();
 
   EXPECT_GE(fake_concierge_client_->attach_usb_device_call_count(), 1);
@@ -1117,10 +1116,10 @@
   // Unmount events would normally be fired by the DiskMountManager.
   AttachDeviceToVm("VM1", GetSingleDeviceInfo().guid, /*success=*/false);
   NotifyMountEvent("disk1", disks::DiskMountManager::UNMOUNTING);
-  std::move(callback1).Run(chromeos::MOUNT_ERROR_NONE);
-  std::move(callback2).Run(chromeos::MOUNT_ERROR_UNKNOWN);
+  std::move(callback1).Run(MountError::kNone);
+  std::move(callback2).Run(MountError::kUnknown);
   NotifyMountEvent("disk3", disks::DiskMountManager::UNMOUNTING);
-  std::move(callback3).Run(chromeos::MOUNT_ERROR_NONE);
+  std::move(callback3).Run(MountError::kNone);
   base::RunLoop().RunUntilIdle();
 
   // AttachDeviceToVm() verifies CrosUsbDetector correctly calls the completion
@@ -1166,7 +1165,7 @@
   // A disk which fails to mount shouldn't cause the prompt to be shown.
   AddDisk("disk_error", 1, 5, /*mounted=*/false);
   NotifyMountEvent("disk_error", disks::DiskMountManager::MOUNTING,
-                   chromeos::MOUNT_ERROR_INTERNAL);
+                   MountError::kInternal);
   EXPECT_FALSE(GetSingleDeviceInfo().prompt_before_sharing);
 
   AddDisk("disk_success", 1, 5, true);
diff --git a/chrome/browser/chromeos/extensions/file_manager/device_event_router_unittest.cc b/chrome/browser/chromeos/extensions/file_manager/device_event_router_unittest.cc
index 761d073a..80019b02 100644
--- a/chrome/browser/chromeos/extensions/file_manager/device_event_router_unittest.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/device_event_router_unittest.cc
@@ -102,9 +102,9 @@
       base::FilePath(FILE_PATH_LITERAL("/mount/path1"))));
   device_event_router->OnDeviceAdded("/device/test");
   device_event_router->OnDiskAdded(disk1, true);
-  device_event_router->OnVolumeMounted(chromeos::MOUNT_ERROR_NONE,
+  device_event_router->OnVolumeMounted(chromeos::MountError::kNone,
                                        *volume.get());
-  device_event_router->OnVolumeUnmounted(chromeos::MOUNT_ERROR_NONE,
+  device_event_router->OnVolumeUnmounted(chromeos::MountError::kNone,
                                          *volume.get());
   device_event_router->OnDiskRemoved(disk1_unmounted);
   device_event_router->OnDeviceRemoved("/device/test");
diff --git a/chrome/browser/chromeos/extensions/file_manager/event_router.cc b/chrome/browser/chromeos/extensions/file_manager/event_router.cc
index 9c17516..8ca2526e1 100644
--- a/chrome/browser/chromeos/extensions/file_manager/event_router.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/event_router.cc
@@ -487,60 +487,60 @@
 file_manager_private::MountCompletedStatus MountErrorToMountCompletedStatus(
     chromeos::MountError error) {
   switch (error) {
-    case chromeos::MOUNT_ERROR_NONE:
+    case chromeos::MountError::kNone:
       return file_manager_private::MOUNT_COMPLETED_STATUS_SUCCESS;
-    case chromeos::MOUNT_ERROR_UNKNOWN:
+    case chromeos::MountError::kUnknown:
       return file_manager_private::MOUNT_COMPLETED_STATUS_ERROR_UNKNOWN;
-    case chromeos::MOUNT_ERROR_INTERNAL:
+    case chromeos::MountError::kInternal:
       return file_manager_private::MOUNT_COMPLETED_STATUS_ERROR_INTERNAL;
-    case chromeos::MOUNT_ERROR_INVALID_ARGUMENT:
+    case chromeos::MountError::kInvalidArgument:
       return file_manager_private::
           MOUNT_COMPLETED_STATUS_ERROR_INVALID_ARGUMENT;
-    case chromeos::MOUNT_ERROR_INVALID_PATH:
+    case chromeos::MountError::kInvalidPath:
       return file_manager_private::MOUNT_COMPLETED_STATUS_ERROR_INVALID_PATH;
-    case chromeos::MOUNT_ERROR_PATH_ALREADY_MOUNTED:
+    case chromeos::MountError::kPathAlreadyMounted:
       return file_manager_private::
           MOUNT_COMPLETED_STATUS_ERROR_PATH_ALREADY_MOUNTED;
-    case chromeos::MOUNT_ERROR_PATH_NOT_MOUNTED:
+    case chromeos::MountError::kPathNotMounted:
       return file_manager_private::
           MOUNT_COMPLETED_STATUS_ERROR_PATH_NOT_MOUNTED;
-    case chromeos::MOUNT_ERROR_DIRECTORY_CREATION_FAILED:
+    case chromeos::MountError::kDirectoryCreationFailed:
       return file_manager_private::
           MOUNT_COMPLETED_STATUS_ERROR_DIRECTORY_CREATION_FAILED;
-    case chromeos::MOUNT_ERROR_INVALID_MOUNT_OPTIONS:
+    case chromeos::MountError::kInvalidMountOptions:
       return file_manager_private::
           MOUNT_COMPLETED_STATUS_ERROR_INVALID_MOUNT_OPTIONS;
-    case chromeos::MOUNT_ERROR_INVALID_UNMOUNT_OPTIONS:
+    case chromeos::MountError::kInvalidUnmountOptions:
       return file_manager_private::
           MOUNT_COMPLETED_STATUS_ERROR_INVALID_UNMOUNT_OPTIONS;
-    case chromeos::MOUNT_ERROR_INSUFFICIENT_PERMISSIONS:
+    case chromeos::MountError::kInsufficientPermissions:
       return file_manager_private::
           MOUNT_COMPLETED_STATUS_ERROR_INSUFFICIENT_PERMISSIONS;
-    case chromeos::MOUNT_ERROR_MOUNT_PROGRAM_NOT_FOUND:
+    case chromeos::MountError::kMountProgramNotFound:
       return file_manager_private::
           MOUNT_COMPLETED_STATUS_ERROR_MOUNT_PROGRAM_NOT_FOUND;
-    case chromeos::MOUNT_ERROR_MOUNT_PROGRAM_FAILED:
+    case chromeos::MountError::kMountProgramFailed:
       return file_manager_private::
           MOUNT_COMPLETED_STATUS_ERROR_MOUNT_PROGRAM_FAILED;
-    case chromeos::MOUNT_ERROR_INVALID_DEVICE_PATH:
+    case chromeos::MountError::kInvalidDevicePath:
       return file_manager_private::
           MOUNT_COMPLETED_STATUS_ERROR_INVALID_DEVICE_PATH;
-    case chromeos::MOUNT_ERROR_UNKNOWN_FILESYSTEM:
+    case chromeos::MountError::kUnknownFilesystem:
       return file_manager_private::
           MOUNT_COMPLETED_STATUS_ERROR_UNKNOWN_FILESYSTEM;
-    case chromeos::MOUNT_ERROR_UNSUPPORTED_FILESYSTEM:
+    case chromeos::MountError::kUnsupportedFilesystem:
       return file_manager_private::
           MOUNT_COMPLETED_STATUS_ERROR_UNSUPPORTED_FILESYSTEM;
-    case chromeos::MOUNT_ERROR_INVALID_ARCHIVE:
+    case chromeos::MountError::kInvalidArchive:
       return file_manager_private::MOUNT_COMPLETED_STATUS_ERROR_INVALID_ARCHIVE;
-    case chromeos::MOUNT_ERROR_NEED_PASSWORD:
+    case chromeos::MountError::kNeedPassword:
       return file_manager_private::MOUNT_COMPLETED_STATUS_ERROR_NEED_PASSWORD;
-    case chromeos::MOUNT_ERROR_IN_PROGRESS:
+    case chromeos::MountError::kInProgress:
       return file_manager_private::MOUNT_COMPLETED_STATUS_ERROR_IN_PROGRESS;
-    case chromeos::MOUNT_ERROR_CANCELLED:
+    case chromeos::MountError::kCancelled:
       return file_manager_private::MOUNT_COMPLETED_STATUS_ERROR_CANCELLED;
     // Not a real error.
-    case chromeos::MOUNT_ERROR_COUNT:
+    case chromeos::MountError::kCount:
       NOTREACHED();
   }
   NOTREACHED();
diff --git a/chrome/browser/chromeos/extensions/file_manager/file_manager_private_apitest.cc b/chrome/browser/chromeos/extensions/file_manager/file_manager_private_apitest.cc
index 14008d7..a195f10 100644
--- a/chrome/browser/chromeos/extensions/file_manager/file_manager_private_apitest.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/file_manager_private_apitest.cc
@@ -338,9 +338,9 @@
         ash::MountType::kNetworkStorage,
         ash::disks::MountCondition::MOUNT_CONDITION_NONE);
     disk_mount_manager_mock_->NotifyMountEvent(
-        DiskMountManager::MountEvent::MOUNTING,
-        chromeos::MountError::MOUNT_ERROR_NONE, mount_point_info);
-    std::move(callback).Run(chromeos::MOUNT_ERROR_NONE, mount_point_info);
+        DiskMountManager::MountEvent::MOUNTING, chromeos::MountError::kNone,
+        mount_point_info);
+    std::move(callback).Run(chromeos::MountError::kNone, mount_point_info);
   }
 
   void ExpectCrostiniMount() {
@@ -405,7 +405,7 @@
             EXPECT_EQ("mount_path1", name.value());
             ++events[0];
             EXPECT_EQ(1, events[0]);
-            std::move(callback).Run(chromeos::MOUNT_ERROR_NONE);
+            std::move(callback).Run(chromeos::MountError::kNone);
           }))
       .WillOnce(testing::Invoke(
           [&events](const std::string& path,
@@ -414,7 +414,7 @@
             EXPECT_EQ("mount_path1", name.value());
             ++events[1];
             EXPECT_EQ(1, events[1]);
-            std::move(callback).Run(chromeos::MOUNT_ERROR_CANCELLED);
+            std::move(callback).Run(chromeos::MountError::kCancelled);
           }));
 
   EXPECT_CALL(*disk_mount_manager_mock_,
@@ -429,7 +429,7 @@
             EXPECT_EQ("archive_mount_path", name.value());
             ++events[2];
             EXPECT_EQ(1, events[2]);
-            std::move(callback).Run(chromeos::MOUNT_ERROR_NONE);
+            std::move(callback).Run(chromeos::MountError::kNone);
           }))
       .WillOnce(testing::Invoke(
           [&events](const std::string& path,
@@ -438,7 +438,7 @@
             EXPECT_EQ("archive_mount_path", name.value());
             ++events[3];
             EXPECT_EQ(1, events[3]);
-            std::move(callback).Run(chromeos::MOUNT_ERROR_NEED_PASSWORD);
+            std::move(callback).Run(chromeos::MountError::kNeedPassword);
           }));
 
   ASSERT_TRUE(RunExtensionTest("file_browser/mount_test", {},
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_mount.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_mount.cc
index f1aa81e..99e2880a 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_mount.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_mount.cc
@@ -169,7 +169,7 @@
 
 void FileManagerPrivateCancelMountingFunction::OnCancelled(
     chromeos::MountError error) {
-  if (error == chromeos::MOUNT_ERROR_NONE) {
+  if (error == chromeos::MountError::kNone) {
     Respond(NoArguments());
   } else {
     Respond(Error(file_manager_private::ToString(
@@ -262,7 +262,7 @@
 
 void FileManagerPrivateRemoveMountFunction::OnDiskUnmounted(
     chromeos::MountError error) {
-  if (error == chromeos::MOUNT_ERROR_NONE) {
+  if (error == chromeos::MountError::kNone) {
     Respond(NoArguments());
   } else {
     Respond(Error(file_manager_private::ToString(
diff --git a/chrome/browser/chromeos/fileapi/file_change_service_unittest.cc b/chrome/browser/chromeos/fileapi/file_change_service_unittest.cc
index 66e9d9e..b9e7a612 100644
--- a/chrome/browser/chromeos/fileapi/file_change_service_unittest.cc
+++ b/chrome/browser/chromeos/fileapi/file_change_service_unittest.cc
@@ -238,7 +238,7 @@
  private:
   // BrowserWithTestWindowTest:
   TestingProfile* CreateProfile() override {
-    constexpr char kPrimaryProfileName[] = "primary_profile";
+    constexpr char kPrimaryProfileName[] = "primary_profile@test";
     return CreateProfileWithName(kPrimaryProfileName);
   }
 
@@ -261,7 +261,7 @@
   ASSERT_TRUE(primary_profile_service);
 
   // `FileChangeService` should be created as needed for additional profiles.
-  constexpr char kSecondaryProfileName[] = "secondary_profile";
+  constexpr char kSecondaryProfileName[] = "secondary_profile@test";
   auto* secondary_profile = CreateProfileWithName(kSecondaryProfileName);
   auto* secondary_profile_service = factory->GetService(secondary_profile);
   ASSERT_TRUE(secondary_profile_service);
diff --git a/chrome/browser/extensions/api/image_writer_private/operation.h b/chrome/browser/extensions/api/image_writer_private/operation.h
index 5dd6272..0d6d87327 100644
--- a/chrome/browser/extensions/api/image_writer_private/operation.h
+++ b/chrome/browser/extensions/api/image_writer_private/operation.h
@@ -187,7 +187,7 @@
   void UnmountVolumes(base::OnceClosure continuation);
   // Starts the write after unmounting.
   void UnmountVolumesCallback(base::OnceClosure continuation,
-                              chromeos::MountError error_code);
+                              ash::MountError error_code);
   // Starts the ImageBurner write.  Note that target_path is the file path of
   // the device where device_path has been a system device path.
   void StartWriteOnUIThread(const std::string& target_path,
diff --git a/chrome/browser/extensions/api/image_writer_private/operation_chromeos.cc b/chrome/browser/extensions/api/image_writer_private/operation_chromeos.cc
index 23958cb..679fbab 100644
--- a/chrome/browser/extensions/api/image_writer_private/operation_chromeos.cc
+++ b/chrome/browser/extensions/api/image_writer_private/operation_chromeos.cc
@@ -62,10 +62,10 @@
 }
 
 void Operation::UnmountVolumesCallback(base::OnceClosure continuation,
-                                       chromeos::MountError error_code) {
+                                       ash::MountError error_code) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
-  if (error_code != chromeos::MOUNT_ERROR_NONE) {
+  if (error_code != ash::MountError::kNone) {
     LOG(ERROR) << "Volume unmounting failed with error code " << error_code;
     PostTask(
         base::BindOnce(&Operation::Error, this, error::kUnmountVolumesError));
diff --git a/chrome/browser/extensions/api/image_writer_private/test_utils.cc b/chrome/browser/extensions/api/image_writer_private/test_utils.cc
index 329c192..b2f2c62 100644
--- a/chrome/browser/extensions/api/image_writer_private/test_utils.cc
+++ b/chrome/browser/extensions/api/image_writer_private/test_utils.cc
@@ -77,8 +77,7 @@
     const std::string& device_path,
     UnmountDeviceRecursivelyCallbackType callback) {
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE,
-      base::BindOnce(std::move(callback), chromeos::MOUNT_ERROR_NONE));
+      FROM_HERE, base::BindOnce(std::move(callback), ash::MountError::kNone));
 }
 #endif
 
diff --git a/chrome/browser/extensions/event_router_forwarder.cc b/chrome/browser/extensions/event_router_forwarder.cc
index 5a52bcb6..3a98c98d 100644
--- a/chrome/browser/extensions/event_router_forwarder.cc
+++ b/chrome/browser/extensions/event_router_forwarder.cc
@@ -108,23 +108,15 @@
   if (profiles_to_dispatch_to.size() == 0u)
     return;
 
-  // Use the same event_args for each profile (making copies as needed).
-  std::vector<base::Value::List> per_profile_args;
-  per_profile_args.reserve(profiles_to_dispatch_to.size());
-  per_profile_args.emplace_back(std::move(event_args));
-  for (size_t i = 1; i < profiles_to_dispatch_to.size(); ++i)
-    per_profile_args.emplace_back(per_profile_args.front().Clone());
-  DCHECK_EQ(per_profile_args.size(), profiles_to_dispatch_to.size());
-
-  size_t profile_args_index = 0;
   for (Profile* profile_to_dispatch_to : profiles_to_dispatch_to) {
     CallEventRouter(
         profile_to_dispatch_to, extension_id, histogram_value, event_name,
-        std::move(per_profile_args[profile_args_index++]),
+        profile_to_dispatch_to != *std::prev(profiles_to_dispatch_to.end())
+            ? event_args.Clone()
+            : std::move(event_args),
         use_profile_to_restrict_events ? profile_to_dispatch_to : nullptr,
         event_url);
   }
-  DCHECK_EQ(per_profile_args.size(), profile_args_index);
 }
 
 void EventRouterForwarder::CallEventRouter(
diff --git a/chrome/browser/extensions/extension_webui_apitest.cc b/chrome/browser/extensions/extension_webui_apitest.cc
index c3b6bdf4..503072a 100644
--- a/chrome/browser/extensions/extension_webui_apitest.cc
+++ b/chrome/browser/extensions/extension_webui_apitest.cc
@@ -119,7 +119,7 @@
             extension->id())));
 
     content::WebContents* guest_web_contents =
-        test_guest_view_manager_->WaitForSingleGuestCreated();
+        test_guest_view_manager_->DeprecatedWaitForSingleGuestCreated();
     EXPECT_TRUE(guest_web_contents);
     EXPECT_TRUE(content::WaitForLoadStop(guest_web_contents));
 
diff --git a/chrome/browser/extensions/process_manager_browsertest.cc b/chrome/browser/extensions/process_manager_browsertest.cc
index 1e11b06..9c33839 100644
--- a/chrome/browser/extensions/process_manager_browsertest.cc
+++ b/chrome/browser/extensions/process_manager_browsertest.cc
@@ -1220,8 +1220,9 @@
       static_cast<guest_view::TestGuestViewManager*>(
           guest_view::TestGuestViewManager::FromBrowserContext(
               browser()->profile()));
-  content::WebContents* guest = guest_manager->WaitForSingleGuestCreated();
-  guest_manager->WaitUntilAttached(guest);
+  auto* guest_view = guest_manager->WaitForSingleGuestViewCreated();
+  guest_manager->WaitUntilAttached(guest_view);
+  auto* guest_rfh = guest_manager->GetLastGuestRenderFrameHostCreated();
 
   // There should be two extension frames in ProcessManager: the app's main
   // page and the background page.
@@ -1252,9 +1253,8 @@
   EXPECT_FALSE(policy->CanRequestURL(
       web_tab->GetPrimaryMainFrame()->GetProcess()->GetID(),
       app_origin.GetURL()));
-  EXPECT_TRUE(
-      policy->CanRequestURL(guest->GetPrimaryMainFrame()->GetProcess()->GetID(),
-                            app_origin.GetURL()));
+  EXPECT_TRUE(policy->CanRequestURL(guest_rfh->GetProcess()->GetID(),
+                                    app_origin.GetURL()));
 
   // Try navigating the web tab to each nested URL with the app's origin.  This
   // should be blocked.
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index 8776e1c..0c10751 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -421,6 +421,11 @@
     "expiry_milestone": 106
   },
   {
+    "name": "autofill-enable-card-product-name",
+    "owners": [ "vishwasuppoor", "siyua" ],
+    "expiry_milestone": 120
+  },
+  {
     "name": "autofill-enable-fido-progress-dialog",
     "owners": [ "siashah", "yiian" ],
     "expiry_milestone": 113
@@ -1120,6 +1125,11 @@
     "expiry_milestone": 112
   },
   {
+    "name": "customize-chrome-side-panel",
+    "owners": [ "chrome-desktop-ntp@google.com" ],
+    "expiry_milestone": 110
+  },
+  {
     "name": "dark-light-mode",
     "owners": [ "minch", "tclaiborne" ],
     "expiry_milestone": 110
@@ -4911,7 +4921,7 @@
   {
     "name": "overlay-scrollbars",
     "owners": [ "chaopeng", "bokan", "input-dev" ],
-    "expiry_milestone": 105
+    "expiry_milestone": 107
   },
   {
     "name": "overlay-strategies",
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 01ffb610..4372567 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -130,6 +130,11 @@
     "Enables bringing user's content languages that are translatable to the "
     "top of the list with all languages shown in the translate menu";
 
+const char kCustomizeChromeSidePanelName[] = "Customize Chrome Side Panel";
+const char KCustomizeChromeSidePanelDescription[] =
+    "Enables the ability to use Customize Chrome functionality from the "
+    "unified side panel on the New Tab Page.";
+
 const char kForceStartupSigninPromoName[] = "Force Start-up Signin Promo";
 const char kForceStartupSigninPromoDescription[] =
     "If enabled, the full screen signin promo will be forced to show up at "
@@ -377,6 +382,12 @@
     "When enabled, manual fallback will be enabled for virtual cards on "
     "Android.";
 
+const char kAutofillEnableCardProductNameName[] =
+    "Enable showing card product name";
+const char kAutofillEnableCardProductNameDescription[] =
+    "When enabled, card product name (instead of issuer network) will be shown "
+    "in Payments UI.";
+
 const char kAutofillEnableOfferNotificationForPromoCodesName[] =
     "Extend Autofill offers and rewards notification to promo code offers";
 const char kAutofillEnableOfferNotificationForPromoCodesDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index bcc310d..59e4537 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -95,6 +95,9 @@
 extern const char kContentLanguagesInLanguagePickerName[];
 extern const char kContentLanguagesInLanguagePickerDescription[];
 
+extern const char kCustomizeChromeSidePanelName[];
+extern const char KCustomizeChromeSidePanelDescription[];
+
 extern const char kDebugHistoryInterventionNoUserActivationName[];
 extern const char kDebugHistoryInterventionNoUserActivationDescription[];
 
@@ -212,6 +215,9 @@
 extern const char kAutofillEnableManualFallbackForVirtualCardsName[];
 extern const char kAutofillEnableManualFallbackForVirtualCardsDescription[];
 
+extern const char kAutofillEnableCardProductNameName[];
+extern const char kAutofillEnableCardProductNameDescription[];
+
 extern const char kAutofillEnableOfferNotificationForPromoCodesName[];
 extern const char kAutofillEnableOfferNotificationForPromoCodesDescription[];
 
diff --git a/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_browsertest.cc b/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_browsertest.cc
index f698acff..9fca93e 100644
--- a/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_browsertest.cc
+++ b/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_browsertest.cc
@@ -89,11 +89,12 @@
   TestGuestViewManager* GetGuestViewManager() {
     TestGuestViewManager* manager = static_cast<TestGuestViewManager*>(
         TestGuestViewManager::FromBrowserContext(browser()->profile()));
-    // TestGuestViewManager::WaitForSingleGuestCreated can and will get called
-    // before a guest is created. Since GuestViewManager is usually not created
-    // until the first guest is created, this means that |manager| will be
-    // nullptr if trying to use the manager to wait for the first guest. Because
-    // of this, the manager must be created here if it does not already exist.
+    // TestGuestViewManager::DeprecatedWaitForSingleGuestCreated can and will
+    // get called before a guest is created. Since GuestViewManager is usually
+    // not created until the first guest is created, this means that |manager|
+    // will be nullptr if trying to use the manager to wait for the first guest.
+    // Because of this, the manager must be created here if it does not already
+    // exist.
     if (!manager) {
       manager = static_cast<TestGuestViewManager*>(
           GuestViewManager::CreateWithDelegate(
@@ -127,7 +128,7 @@
     if (!catcher.GetNextResult())
       FAIL() << catcher.message();
 
-    ASSERT_TRUE(GetGuestViewManager()->WaitForSingleGuestCreated());
+    ASSERT_TRUE(GetGuestViewManager()->DeprecatedWaitForSingleGuestCreated());
     ASSERT_TRUE(GetEmbedderWebContents());
   }
 
@@ -326,7 +327,7 @@
 IN_PROC_BROWSER_TEST_F(ChromeMimeHandlerViewTest, EmbedderFrameRemovedNoCrash) {
   RunTest("test_iframe_basic.html");
   auto* guest_view = GuestViewBase::FromWebContents(
-      GetGuestViewManager()->WaitForSingleGuestCreated());
+      GetGuestViewManager()->DeprecatedWaitForSingleGuestCreated());
   ASSERT_TRUE(guest_view);
   int32_t element_instance_id = guest_view->element_instance_id();
   auto* embedder_web_contents = GetEmbedderWebContents();
@@ -393,7 +394,7 @@
   ASSERT_TRUE(alert->is_before_unload_dialog());
   alert->view()->AcceptAppModalDialog();
 
-  EXPECT_TRUE(GetGuestViewManager()->WaitForSingleGuestCreated());
+  EXPECT_TRUE(GetGuestViewManager()->DeprecatedWaitForSingleGuestCreated());
 }
 
 IN_PROC_BROWSER_TEST_F(ChromeMimeHandlerViewTest, PostMessage) {
@@ -522,7 +523,8 @@
   content::PrepContentsForBeforeUnloadTest(web_contents, false);
 
   // Make sure we have a guestviewmanager.
-  auto* guest_contents = GetGuestViewManager()->WaitForSingleGuestCreated();
+  auto* guest_contents =
+      GetGuestViewManager()->DeprecatedWaitForSingleGuestCreated();
   UserActivationUpdateWaiter activation_waiter(guest_contents);
 
   // Activate |guest_contents| through a click, then wait until the activation
@@ -553,7 +555,8 @@
                               "const e = document.createElement('embed');"
                               "e.src = './testEmbedded.csv'; e.type='text/csv';"
                               "document.body.appendChild(e);"));
-  DocumentLoadCompletionWaiter(GetGuestViewManager()->WaitForNextGuestCreated())
+  DocumentLoadCompletionWaiter(
+      GetGuestViewManager()->DeprecatedWaitForNextGuestCreated())
       .Wait();
   // After load, an IPC has been sent to the renderer to update routing IDs for
   // the guest frame and the content frame (and activate the
@@ -593,7 +596,7 @@
   // Therefore, it suffices to wait for one GuestView to be created, then remove
   // the non-sandboxed frame, and ensue there are no GuestViews left.
   if (guest_view_manager->num_guests_created() == 0)
-    ASSERT_TRUE(guest_view_manager->WaitForNextGuestCreated());
+    ASSERT_TRUE(guest_view_manager->DeprecatedWaitForNextGuestCreated());
   ASSERT_EQ(1U, guest_view_manager->num_guests_created());
 
   // Remove the non-sandboxed frame.
@@ -635,7 +638,8 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
       browser(), embedded_test_server()->GetURL("/test_embedded.html")));
 
-  auto* guest_contents = GetGuestViewManager()->WaitForSingleGuestCreated();
+  auto* guest_contents =
+      GetGuestViewManager()->DeprecatedWaitForSingleGuestCreated();
   // Make sure the load has started, before waiting for it to stop.
   // This is a little hacky, but will unjank the test for now.
   while (!guest_contents->IsLoading() &&
@@ -666,7 +670,8 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), data_url));
   auto* embedder_web_contents =
       browser()->tab_strip_model()->GetWebContentsAt(0);
-  auto* guest_web_contents = GetGuestViewManager()->WaitForSingleGuestCreated();
+  auto* guest_web_contents =
+      GetGuestViewManager()->DeprecatedWaitForSingleGuestCreated();
   EXPECT_NE(embedder_web_contents, guest_web_contents);
   while (guest_web_contents->IsLoading()) {
     base::RunLoop run_loop;
@@ -700,7 +705,7 @@
       "data:text/html, <iframe src='data:application/pdf,foo' "
       "style='display:none'></iframe>,foo2");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), data_url));
-  ASSERT_TRUE(GetGuestViewManager()->WaitForSingleGuestCreated());
+  ASSERT_TRUE(GetGuestViewManager()->DeprecatedWaitForSingleGuestCreated());
 }
 
 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
diff --git a/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_interactive_uitest.cc b/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_interactive_uitest.cc
index 8b9ec29..06fd7e1 100644
--- a/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_interactive_uitest.cc
+++ b/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_interactive_uitest.cc
@@ -54,11 +54,8 @@
   TestGuestViewManager* GetGuestViewManager() {
     TestGuestViewManager* manager = static_cast<TestGuestViewManager*>(
         TestGuestViewManager::FromBrowserContext(browser()->profile()));
-    // TestGuestViewManager::WaitForSingleGuestCreated can and will get called
-    // before a guest is created. Since GuestViewManager is usually not created
-    // until the first guest is created, this means that |manager| will be
-    // nullptr if trying to use the manager to wait for the first guest. Because
-    // of this, the manager must be created here if it does not already exist.
+    // Test code may access the TestGuestViewManager before it would be created
+    // during creation of the first guest.
     if (!manager) {
       manager = static_cast<TestGuestViewManager*>(
           GuestViewManager::CreateWithDelegate(
@@ -155,7 +152,8 @@
 
   // Make sure we have a guestviewmanager.
   auto* embedder_contents = browser()->tab_strip_model()->GetWebContentsAt(0);
-  auto* guest_contents = GetGuestViewManager()->WaitForSingleGuestCreated();
+  auto* guest_contents =
+      GetGuestViewManager()->DeprecatedWaitForSingleGuestCreated();
   auto* guest_rwh =
       guest_contents->GetRenderWidgetHostView()->GetRenderWidgetHost();
 
diff --git a/chrome/browser/hid/chrome_hid_delegate.cc b/chrome/browser/hid/chrome_hid_delegate.cc
index f1dc29a..2c6ceda 100644
--- a/chrome/browser/hid/chrome_hid_delegate.cc
+++ b/chrome/browser/hid/chrome_hid_delegate.cc
@@ -6,7 +6,9 @@
 
 #include <utility>
 
+#include "base/containers/contains.h"
 #include "base/observer_list.h"
+#include "base/scoped_observation.h"
 #include "chrome/browser/hid/hid_chooser_context.h"
 #include "chrome/browser/hid/hid_chooser_context_factory.h"
 #include "chrome/browser/profiles/profile.h"
@@ -15,6 +17,7 @@
 #include "chrome/browser/ui/hid/hid_chooser.h"
 #include "chrome/browser/ui/hid/hid_chooser_controller.h"
 #include "chrome/common/chrome_features.h"
+#include "components/permissions/object_permission_context_base.h"
 #include "content/public/browser/render_frame_host.h"
 
 #if BUILDFLAG(ENABLE_EXTENSIONS)
@@ -30,6 +33,84 @@
 
 }  // namespace
 
+// Manages the HidDelegate observers for a single browser context.
+class ChromeHidDelegate::ContextObservation
+    : public permissions::ObjectPermissionContextBase::PermissionObserver,
+      public HidChooserContext::DeviceObserver {
+ public:
+  ContextObservation(ChromeHidDelegate* parent,
+                     content::BrowserContext* browser_context)
+      : parent_(parent), browser_context_(browser_context) {
+    auto* chooser_context = GetChooserContext(browser_context_);
+    device_observation_.Observe(chooser_context);
+    permission_observation_.Observe(chooser_context);
+  }
+
+  ContextObservation(ContextObservation&) = delete;
+  ContextObservation& operator=(ContextObservation&) = delete;
+  ~ContextObservation() override = default;
+
+  // permissions::ObjectPermissionContextBase::PermissionObserver:
+  void OnPermissionRevoked(const url::Origin& origin) override {
+    for (auto& observer : observer_list_)
+      observer.OnPermissionRevoked(origin);
+  }
+
+  // HidChooserContext::DeviceObserver:
+  void OnDeviceAdded(const device::mojom::HidDeviceInfo& device_info) override {
+    for (auto& observer : observer_list_)
+      observer.OnDeviceAdded(device_info);
+  }
+
+  void OnDeviceRemoved(
+      const device::mojom::HidDeviceInfo& device_info) override {
+    for (auto& observer : observer_list_)
+      observer.OnDeviceRemoved(device_info);
+  }
+
+  void OnDeviceChanged(
+      const device::mojom::HidDeviceInfo& device_info) override {
+    for (auto& observer : observer_list_)
+      observer.OnDeviceChanged(device_info);
+  }
+
+  void OnHidManagerConnectionError() override {
+    for (auto& observer : observer_list_)
+      observer.OnHidManagerConnectionError();
+  }
+
+  void OnHidChooserContextShutdown() override {
+    parent_->observations_.erase(browser_context_);
+    // Return since `this` is now deleted.
+  }
+
+  void AddObserver(content::HidDelegate::Observer* observer) {
+    observer_list_.AddObserver(observer);
+  }
+
+  void RemoveObserver(content::HidDelegate::Observer* observer) {
+    observer_list_.RemoveObserver(observer);
+  }
+
+ private:
+  // Safe because `parent_` owns `this`.
+  const raw_ptr<ChromeHidDelegate> parent_;
+
+  // Safe because `this` is destroyed when the context is lost.
+  const raw_ptr<content::BrowserContext> browser_context_;
+
+  base::ScopedObservation<HidChooserContext,
+                          HidChooserContext::DeviceObserver,
+                          &HidChooserContext::AddDeviceObserver,
+                          &HidChooserContext::RemoveDeviceObserver>
+      device_observation_{this};
+  base::ScopedObservation<
+      permissions::ObjectPermissionContextBase,
+      permissions::ObjectPermissionContextBase::PermissionObserver>
+      permission_observation_{this};
+  base::ObserverList<content::HidDelegate::Observer> observer_list_;
+};
+
 ChromeHidDelegate::ChromeHidDelegate() = default;
 
 ChromeHidDelegate::~ChromeHidDelegate() = default;
@@ -40,12 +121,11 @@
     std::vector<blink::mojom::HidDeviceFilterPtr> exclusion_filters,
     content::HidChooser::Callback callback) {
   DCHECK(render_frame_host);
-  auto* chooser_context =
-      GetChooserContext(render_frame_host->GetBrowserContext());
-  if (!device_observation_.IsObserving())
-    device_observation_.Observe(chooser_context);
-  if (!permission_observation_.IsObserving())
-    permission_observation_.Observe(chooser_context);
+  auto* browser_context = render_frame_host->GetBrowserContext();
+
+  // Start observing HidChooserContext for permission and device events.
+  GetContextObserver(browser_context);
+  DCHECK(base::Contains(observations_, browser_context));
 
   return std::make_unique<HidChooser>(chrome::ShowDeviceChooserDialog(
       render_frame_host,
@@ -83,17 +163,14 @@
 
 void ChromeHidDelegate::AddObserver(content::BrowserContext* browser_context,
                                     Observer* observer) {
-  observer_list_.AddObserver(observer);
-  auto* chooser_context = GetChooserContext(browser_context);
-  if (!device_observation_.IsObserving())
-    device_observation_.Observe(chooser_context);
-  if (!permission_observation_.IsObserving())
-    permission_observation_.Observe(chooser_context);
+  GetContextObserver(browser_context)->AddObserver(observer);
 }
 
 void ChromeHidDelegate::RemoveObserver(
+    content::BrowserContext* browser_context,
     content::HidDelegate::Observer* observer) {
-  observer_list_.RemoveObserver(observer);
+  DCHECK(base::Contains(observations_, browser_context));
+  GetContextObserver(browser_context)->RemoveObserver(observer);
 }
 
 const device::mojom::HidDeviceInfo* ChromeHidDelegate::GetDeviceInfo(
@@ -123,38 +200,11 @@
   return false;
 }
 
-void ChromeHidDelegate::OnPermissionRevoked(const url::Origin& origin) {
-  for (auto& observer : observer_list_)
-    observer.OnPermissionRevoked(origin);
-}
-
-void ChromeHidDelegate::OnDeviceAdded(
-    const device::mojom::HidDeviceInfo& device_info) {
-  for (auto& observer : observer_list_)
-    observer.OnDeviceAdded(device_info);
-}
-
-void ChromeHidDelegate::OnDeviceRemoved(
-    const device::mojom::HidDeviceInfo& device_info) {
-  for (auto& observer : observer_list_)
-    observer.OnDeviceRemoved(device_info);
-}
-
-void ChromeHidDelegate::OnDeviceChanged(
-    const device::mojom::HidDeviceInfo& device_info) {
-  for (auto& observer : observer_list_)
-    observer.OnDeviceChanged(device_info);
-}
-
-void ChromeHidDelegate::OnHidManagerConnectionError() {
-  device_observation_.Reset();
-  permission_observation_.Reset();
-
-  for (auto& observer : observer_list_)
-    observer.OnHidManagerConnectionError();
-}
-
-void ChromeHidDelegate::OnHidChooserContextShutdown() {
-  device_observation_.Reset();
-  permission_observation_.Reset();
+ChromeHidDelegate::ContextObservation* ChromeHidDelegate::GetContextObserver(
+    content::BrowserContext* browser_context) {
+  if (!base::Contains(observations_, browser_context)) {
+    observations_.emplace(browser_context, std::make_unique<ContextObservation>(
+                                               this, browser_context));
+  }
+  return observations_[browser_context].get();
 }
diff --git a/chrome/browser/hid/chrome_hid_delegate.h b/chrome/browser/hid/chrome_hid_delegate.h
index a06d18c..61a0025a 100644
--- a/chrome/browser/hid/chrome_hid_delegate.h
+++ b/chrome/browser/hid/chrome_hid_delegate.h
@@ -6,24 +6,29 @@
 #define CHROME_BROWSER_HID_CHROME_HID_DELEGATE_H_
 
 #include <memory>
+#include <string>
 #include <vector>
 
-#include "base/observer_list.h"
-#include "base/scoped_observation.h"
-#include "chrome/browser/hid/hid_chooser_context.h"
-#include "components/permissions/object_permission_context_base.h"
+#include "base/containers/flat_map.h"
+#include "content/public/browser/hid_chooser.h"
 #include "content/public/browser/hid_delegate.h"
+#include "services/device/public/mojom/hid.mojom-forward.h"
+#include "third_party/blink/public/mojom/hid/hid.mojom-forward.h"
+#include "url/origin.h"
 
-class ChromeHidDelegate
-    : public content::HidDelegate,
-      public permissions::ObjectPermissionContextBase::PermissionObserver,
-      public HidChooserContext::DeviceObserver {
+namespace content {
+class BrowserContext;
+class RenderFrameHost;
+}  // namespace content
+
+class ChromeHidDelegate : public content::HidDelegate {
  public:
   ChromeHidDelegate();
   ChromeHidDelegate(ChromeHidDelegate&) = delete;
   ChromeHidDelegate& operator=(ChromeHidDelegate&) = delete;
   ~ChromeHidDelegate() override;
 
+  // content::HidDelegate:
   std::unique_ptr<content::HidChooser> RunChooser(
       content::RenderFrameHost* render_frame_host,
       std::vector<blink::mojom::HidDeviceFilterPtr> filters,
@@ -42,7 +47,8 @@
       content::BrowserContext* browser_context) override;
   void AddObserver(content::BrowserContext* browser_context,
                    content::HidDelegate::Observer* observer) override;
-  void RemoveObserver(content::HidDelegate::Observer* observer) override;
+  void RemoveObserver(content::BrowserContext* browser_context,
+                      content::HidDelegate::Observer* observer) override;
   const device::mojom::HidDeviceInfo* GetDeviceInfo(
       content::BrowserContext* browser_context,
       const std::string& guid) override;
@@ -50,27 +56,14 @@
                               const url::Origin& origin) override;
   bool IsServiceWorkerAllowedForOrigin(const url::Origin& origin) override;
 
-  // permissions::ObjectPermissionContextBase::PermissionObserver:
-  void OnPermissionRevoked(const url::Origin& origin) override;
-
-  // HidChooserContext::DeviceObserver:
-  void OnDeviceAdded(const device::mojom::HidDeviceInfo&) override;
-  void OnDeviceRemoved(const device::mojom::HidDeviceInfo&) override;
-  void OnDeviceChanged(const device::mojom::HidDeviceInfo&) override;
-  void OnHidManagerConnectionError() override;
-  void OnHidChooserContextShutdown() override;
-
  private:
-  base::ScopedObservation<HidChooserContext,
-                          HidChooserContext::DeviceObserver,
-                          &HidChooserContext::AddDeviceObserver,
-                          &HidChooserContext::RemoveDeviceObserver>
-      device_observation_{this};
-  base::ScopedObservation<
-      permissions::ObjectPermissionContextBase,
-      permissions::ObjectPermissionContextBase::PermissionObserver>
-      permission_observation_{this};
-  base::ObserverList<content::HidDelegate::Observer> observer_list_;
+  class ContextObservation;
+
+  ContextObservation* GetContextObserver(
+      content::BrowserContext* browser_context);
+
+  base::flat_map<content::BrowserContext*, std::unique_ptr<ContextObservation>>
+      observations_;
 };
 
 #endif  // CHROME_BROWSER_HID_CHROME_HID_DELEGATE_H_
diff --git a/chrome/browser/hid/hid_browsertest.cc b/chrome/browser/hid/hid_browsertest.cc
index db12835..329839b 100644
--- a/chrome/browser/hid/hid_browsertest.cc
+++ b/chrome/browser/hid/hid_browsertest.cc
@@ -12,6 +12,7 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chrome_content_browser_client.h"
 #include "chrome/browser/hid/chrome_hid_delegate.h"
+#include "chrome/browser/hid/hid_chooser_context.h"
 #include "chrome/browser/hid/hid_chooser_context_factory.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/pref_names.h"
diff --git a/chrome/browser/media/encrypted_media_supported_types_browsertest.cc b/chrome/browser/media/encrypted_media_supported_types_browsertest.cc
index cf1e79bb..7da8f0b 100644
--- a/chrome/browser/media/encrypted_media_supported_types_browsertest.cc
+++ b/chrome/browser/media/encrypted_media_supported_types_browsertest.cc
@@ -179,6 +179,12 @@
     av1_codecs_.push_back("av01.0.04M.08");        // 8 bit
     av1_codecs_.push_back("av01.0.00M.10.0.112");  // 10 bit
 
+    // Dolby Vision codec string:
+    // https://professional.dolby.com/siteassets/content-creation/dolby-vision-for-content-creators/dolby-vision-streams-within-the-http-live-streaming-format-v2.0-13-november-2018.pdf
+    // [Dolby_Vision_fourCC].[Dovi_Profile_ID].[Dovi_Level_ID]
+    // For example: "dvhe.05.07"
+    dolby_vision_codecs_.push_back("dvhe.05.07");
+
     // Extended codecs are used, so make sure generic ones fail. These will be
     // tested against all init data types as they should always fail to be
     // supported.
@@ -228,6 +234,10 @@
     return vp9_profile2_codecs_;
   }
   const CodecVector& av1_codecs() const { return av1_codecs_; }
+  const CodecVector& dolby_vision_codecs() const {
+    return dolby_vision_codecs_;
+  }
+
   const CodecVector& invalid_codecs() const { return invalid_codecs_; }
 
   void SetUpDefaultCommandLine(base::CommandLine* command_line) override {
@@ -478,6 +488,7 @@
   CodecVector vp9_profile0_codecs_;
   CodecVector vp9_profile2_codecs_;
   CodecVector av1_codecs_;
+  CodecVector dolby_vision_codecs_;
   CodecVector invalid_codecs_;
 };
 
@@ -563,11 +574,12 @@
 
   void SetUpCommandLine(base::CommandLine* command_line) override {
     EncryptedMediaSupportedTypesWidevineTest::SetUpCommandLine(command_line);
-    // Pretend that we support hardware secure decryption for vp8 and vp9, but
-    // not for avc1. This will also pretend that there is support for vorbis
-    // audio.
+    // Pretend that we support hardware secure decryption for vp8, vp9 and
+    // dolbyvision, but not for avc1. This will also pretend that there is
+    // support for vorbis audio.
     command_line->AppendSwitchASCII(
-        switches::kOverrideHardwareSecureCodecsForTesting, "vp8,vp9,vorbis");
+        switches::kOverrideHardwareSecureCodecsForTesting,
+        "vp8,vp9,dolbyvision,vorbis");
   }
 };
 
@@ -1493,6 +1505,15 @@
       kWidevine, SessionType::kPersistentLicense, "HW_SECURE_ALL"));
 }
 
+#if BUILDFLAG(ENABLE_PLATFORM_ENCRYPTED_DOLBY_VISION)
+IN_PROC_BROWSER_TEST_F(EncryptedMediaSupportedTypesWidevineHwSecureTest,
+                       DolbyVision) {
+  EXPECT_WV(IsSupportedByKeySystem(kWidevine, kVideoMP4MimeType,
+                                   dolby_vision_codecs(),
+                                   SessionType::kTemporary, "HW_SECURE_ALL"));
+}
+#endif  // BUILDFLAG(ENABLE_PLATFORM_ENCRYPTED_DOLBY_VISION)
+
 IN_PROC_BROWSER_TEST_F(EncryptedMediaSupportedTypesWidevineHwSecureTest,
                        WidevineExperiment) {
   EXPECT_UNSUPPORTED(
diff --git a/chrome/browser/media/webrtc/multi_capture_browsertest.cc b/chrome/browser/media/webrtc/multi_capture_browsertest.cc
index be8c07f..adb4504 100644
--- a/chrome/browser/media/webrtc/multi_capture_browsertest.cc
+++ b/chrome/browser/media/webrtc/multi_capture_browsertest.cc
@@ -45,30 +45,14 @@
         true /* is_initialization_complete_return */,
         true /* is_first_policy_load_complete_return */);
     policy::BrowserPolicyConnector::SetPolicyProviderForTesting(&provider_);
-    SetUpGeneralMockExpectations();
-  }
-
-  void SetUpGeneralMockExpectations() {
-    testing::ExpectationSet allowed_initial_calls;
-    allowed_initial_calls +=
-        EXPECT_CALL(provider_, IsInitializationComplete(testing::_))
-            .Times(testing::AnyNumber());
-    allowed_initial_calls +=
-        EXPECT_CALL(provider_, IsFirstPolicyLoadComplete(testing::_))
-            .Times(testing::AnyNumber());
-    EXPECT_CALL(initialization_end_checkpoint, Call())
-        .After(allowed_initial_calls);
   }
 
  protected:
-  testing::MockFunction<void()> initialization_end_checkpoint;
-  testing::StrictMock<policy::MockConfigurationPolicyProvider> provider_;
+  testing::NiceMock<policy::MockConfigurationPolicyProvider> provider_;
 };
 
 IN_PROC_BROWSER_TEST_F(SelectAllScreensTest,
                        SelectAllScreensDisabledByDefault) {
-  initialization_end_checkpoint.Call();
-
   Browser* current_browser = browser();
   TabStripModel* current_tab_strip_model = current_browser->tab_strip_model();
   content::WebContents* current_web_contents =
@@ -80,12 +64,6 @@
 #if BUILDFLAG(IS_CHROMEOS)
 IN_PROC_BROWSER_TEST_F(SelectAllScreensTest,
                        SelectAllScreensDisabledWithEmptyPolicy) {
-  initialization_end_checkpoint.Call();
-  EXPECT_CALL(provider_, IsInitializationComplete(
-                             policy::PolicyDomain::POLICY_DOMAIN_CHROME));
-  EXPECT_CALL(provider_, IsFirstPolicyLoadComplete(
-                             policy::PolicyDomain::POLICY_DOMAIN_CHROME));
-
   policy::PolicyMap policies;
   policies.Set(policy::key::kGetDisplayMediaSetSelectAllScreensAllowedForUrls,
                policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER,
@@ -103,12 +81,6 @@
 
 IN_PROC_BROWSER_TEST_F(SelectAllScreensTest,
                        SelectAllScreensEnabledWithCorrectUrl) {
-  initialization_end_checkpoint.Call();
-  EXPECT_CALL(provider_, IsInitializationComplete(
-                             policy::PolicyDomain::POLICY_DOMAIN_CHROME));
-  EXPECT_CALL(provider_, IsFirstPolicyLoadComplete(
-                             policy::PolicyDomain::POLICY_DOMAIN_CHROME));
-
   policy::PolicyMap policies;
   base::Value::List allowed_origins;
   allowed_origins.Append(base::Value("https://www.chromium.org"));
@@ -133,12 +105,6 @@
 
 IN_PROC_BROWSER_TEST_F(SelectAllScreensTest,
                        SelectAllScreensEnabledWithCorrectUrlWildcard) {
-  initialization_end_checkpoint.Call();
-  EXPECT_CALL(provider_, IsInitializationComplete(
-                             policy::PolicyDomain::POLICY_DOMAIN_CHROME));
-  EXPECT_CALL(provider_, IsFirstPolicyLoadComplete(
-                             policy::PolicyDomain::POLICY_DOMAIN_CHROME));
-
   policy::PolicyMap policies;
   base::Value::List allowed_origins;
   allowed_origins.Append(base::Value("[*.]chromium.org"));
@@ -163,12 +129,6 @@
 
 IN_PROC_BROWSER_TEST_F(SelectAllScreensTest,
                        SelectAllScreensDisabledWithWrongUrlWildCard) {
-  initialization_end_checkpoint.Call();
-  EXPECT_CALL(provider_, IsInitializationComplete(
-                             policy::PolicyDomain::POLICY_DOMAIN_CHROME));
-  EXPECT_CALL(provider_, IsFirstPolicyLoadComplete(
-                             policy::PolicyDomain::POLICY_DOMAIN_CHROME));
-
   policy::PolicyMap policies;
   base::Value::List allowed_origins;
   allowed_origins.Append(base::Value("[*.]chrome.org"));
@@ -192,12 +152,6 @@
 
 IN_PROC_BROWSER_TEST_F(SelectAllScreensTest,
                        SelectAllScreensEnabledWithMultipleAllowedOrigins) {
-  initialization_end_checkpoint.Call();
-  EXPECT_CALL(provider_, IsInitializationComplete(
-                             policy::PolicyDomain::POLICY_DOMAIN_CHROME));
-  EXPECT_CALL(provider_, IsFirstPolicyLoadComplete(
-                             policy::PolicyDomain::POLICY_DOMAIN_CHROME));
-
   policy::PolicyMap policies;
   base::Value::List allowed_origins;
   allowed_origins.Append(base::Value("[*.]chrome.org"));
@@ -224,12 +178,6 @@
 IN_PROC_BROWSER_TEST_F(
     SelectAllScreensTest,
     SelectAllScreensEnabledWithMultipleAllowedOriginsDynamicRefresh) {
-  initialization_end_checkpoint.Call();
-  EXPECT_CALL(provider_, IsInitializationComplete(
-                             policy::PolicyDomain::POLICY_DOMAIN_CHROME));
-  EXPECT_CALL(provider_, IsFirstPolicyLoadComplete(
-                             policy::PolicyDomain::POLICY_DOMAIN_CHROME));
-
   policy::PolicyMap policies;
   base::Value::List allowed_origins;
   allowed_origins.Append(base::Value("[*.]chrome.org"));
@@ -251,11 +199,6 @@
           GURL("https://www.chromium.org"));
   EXPECT_FALSE(multi_capture_allowed);
 
-  EXPECT_CALL(provider_, IsInitializationComplete(
-                             policy::PolicyDomain::POLICY_DOMAIN_CHROME));
-  EXPECT_CALL(provider_, IsFirstPolicyLoadComplete(
-                             policy::PolicyDomain::POLICY_DOMAIN_CHROME));
-
   policies.Clear();
   base::Value::List new_allowed_origins;
   new_allowed_origins.Append(base::Value("[*.]chrome.org"));
diff --git a/chrome/browser/new_tab_page/promos/promo_service.cc b/chrome/browser/new_tab_page/promos/promo_service.cc
index 2681a9be..56425ba 100644
--- a/chrome/browser/new_tab_page/promos/promo_service.cc
+++ b/chrome/browser/new_tab_page/promos/promo_service.cc
@@ -256,9 +256,10 @@
 
   DictionaryPrefUpdate update(profile_->GetPrefs(), prefs::kNtpPromoBlocklist);
   double now = base::Time::Now().ToDeltaSinceWindowsEpoch().InSecondsF();
-  // TODO(crbug.com/1003508): verify that promo_id belongs to valid promo.
   update->SetDoubleKey(promo_id, now);
 
+  // Check if the promo id to be blocked is the same as the promo id of the
+  // current promo being served.
   if (promo_data_ && promo_data_->promo_id == promo_id) {
     promo_data_ = PromoData();
     promo_status_ = Status::OK_BUT_BLOCKED;
diff --git a/chrome/browser/pdf/pdf_extension_test.cc b/chrome/browser/pdf/pdf_extension_test.cc
index 887c5dbe..f58568f 100644
--- a/chrome/browser/pdf/pdf_extension_test.cc
+++ b/chrome/browser/pdf/pdf_extension_test.cc
@@ -407,11 +407,8 @@
     // TestGuestViewManager class to avoid all callers needing this cast.
     auto* manager = static_cast<TestGuestViewManager*>(
         TestGuestViewManager::FromBrowserContext(browser()->profile()));
-    // TestGuestViewManager::WaitForSingleGuestCreated can and will get called
-    // before a guest is created. Since GuestViewManager is usually not created
-    // until the first guest is created, this means that |manager| will be
-    // nullptr if trying to use the manager to wait for the first guest. Because
-    // of this, the manager must be created here if it does not already exist.
+    // Test code may access the TestGuestViewManager before it would be created
+    // during creation of the first guest.
     if (!manager) {
       manager = static_cast<TestGuestViewManager*>(
           GuestViewManager::CreateWithDelegate(
@@ -439,7 +436,8 @@
   auto* embedder_web_contents = GetActiveWebContents();
 
   // Verify the pdf has loaded.
-  auto* guest_web_contents = GetGuestViewManager()->WaitForSingleGuestCreated();
+  auto* guest_web_contents =
+      GetGuestViewManager()->DeprecatedWaitForSingleGuestCreated();
   ASSERT_TRUE(guest_web_contents);
   EXPECT_NE(embedder_web_contents, guest_web_contents);
   WaitForLoadStart(guest_web_contents);
@@ -464,7 +462,8 @@
   auto* embedder_web_contents = GetActiveWebContents();
 
   // Verify the pdf has loaded.
-  auto* guest_web_contents = GetGuestViewManager()->WaitForSingleGuestCreated();
+  auto* guest_web_contents =
+      GetGuestViewManager()->DeprecatedWaitForSingleGuestCreated();
   ASSERT_TRUE(guest_web_contents);
   EXPECT_NE(embedder_web_contents, guest_web_contents);
   WaitForLoadStart(guest_web_contents);
@@ -542,7 +541,8 @@
   auto* embedder_web_contents = GetActiveWebContents();
 
   // Verify the PDF has loaded.
-  auto* guest_web_contents = GetGuestViewManager()->WaitForSingleGuestCreated();
+  auto* guest_web_contents =
+      GetGuestViewManager()->DeprecatedWaitForSingleGuestCreated();
   ASSERT_TRUE(guest_web_contents);
   EXPECT_NE(embedder_web_contents, guest_web_contents);
   WaitForLoadStart(guest_web_contents);
@@ -589,7 +589,7 @@
   delayer.ResumeAttach();
   navigation_observer.Wait();
   auto* guest_web_contents2 =
-      GetGuestViewManager()->WaitForSingleGuestCreated();
+      GetGuestViewManager()->DeprecatedWaitForSingleGuestCreated();
   ASSERT_TRUE(guest_web_contents2);
   EXPECT_NE(embedder_web_contents, guest_web_contents2);
   WaitForLoadStart(guest_web_contents2);
@@ -611,7 +611,8 @@
   ASSERT_TRUE(embedder_web_contents);
 
   // Verify the pdf has loaded.
-  auto* guest_web_contents = GetGuestViewManager()->WaitForSingleGuestCreated();
+  auto* guest_web_contents =
+      GetGuestViewManager()->DeprecatedWaitForSingleGuestCreated();
   ASSERT_TRUE(guest_web_contents);
   EXPECT_NE(embedder_web_contents, guest_web_contents);
   WaitForLoadStart(guest_web_contents);
@@ -641,7 +642,8 @@
   ASSERT_TRUE(embedder_web_contents);
 
   // Verify the pdf has loaded.
-  auto* guest_web_contents = GetGuestViewManager()->WaitForSingleGuestCreated();
+  auto* guest_web_contents =
+      GetGuestViewManager()->DeprecatedWaitForSingleGuestCreated();
   ASSERT_TRUE(guest_web_contents);
   EXPECT_NE(embedder_web_contents, guest_web_contents);
   WaitForLoadStart(guest_web_contents);
@@ -686,7 +688,8 @@
   ASSERT_TRUE(embedder_web_contents);
 
   // Verify the pdf has loaded.
-  auto* guest_web_contents = GetGuestViewManager()->WaitForSingleGuestCreated();
+  auto* guest_web_contents =
+      GetGuestViewManager()->DeprecatedWaitForSingleGuestCreated();
   ASSERT_TRUE(guest_web_contents);
   EXPECT_NE(embedder_web_contents, guest_web_contents);
   WaitForLoadStart(guest_web_contents);
@@ -4580,7 +4583,8 @@
           GetActiveWebContents()->GetPrimaryMainFrame(), fenced_frame_url);
   ASSERT_TRUE(fenced_frame_host);
 
-  auto* guest_web_contents = GetGuestViewManager()->WaitForSingleGuestCreated();
+  auto* guest_web_contents =
+      GetGuestViewManager()->DeprecatedWaitForSingleGuestCreated();
   ASSERT_TRUE(guest_web_contents);
   WaitForLoadStart(guest_web_contents);
   EXPECT_TRUE(content::WaitForLoadStop(guest_web_contents));
diff --git a/chrome/browser/preloading/prefetch/no_state_prefetch/prerender_nostate_prefetch_browsertest.cc b/chrome/browser/preloading/prefetch/no_state_prefetch/prerender_nostate_prefetch_browsertest.cc
index b8454a1..7df2e550 100644
--- a/chrome/browser/preloading/prefetch/no_state_prefetch/prerender_nostate_prefetch_browsertest.cc
+++ b/chrome/browser/preloading/prefetch/no_state_prefetch/prerender_nostate_prefetch_browsertest.cc
@@ -37,6 +37,7 @@
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/location_bar/location_bar.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/common/chrome_features.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/content_settings/core/browser/cookie_settings.h"
@@ -1592,6 +1593,21 @@
     prerender->WaitForStart();
     return prerender;
   }
+
+ protected:
+  void SetUp() override {
+    // kOmniboxTriggerForPrerender2 or kOmniboxTriggerForNoStatePrefetch can be
+    // enabled in the experiment. Explicitly disable
+    // kOmniboxTriggerForPrerender2 as fieldtrial tests run with a config to
+    // enable it by default.
+    feature_list_.InitWithFeatures({},
+                                   {features::kOmniboxTriggerForPrerender2});
+
+    NoStatePrefetchBrowserTest::SetUp();
+  }
+
+ private:
+  base::test::ScopedFeatureList feature_list_;
 };
 
 // Checks that closing the omnibox popup cancels an omnibox prerender.
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc
index 929ef0c..ced0a588 100644
--- a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc
+++ b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc
@@ -448,7 +448,7 @@
 
     // Wait for the guest contents of the PDF plugin is created.
     WebContents* guest_contents =
-        test_guest_view_manager_->WaitForSingleGuestCreated();
+        test_guest_view_manager_->DeprecatedWaitForSingleGuestCreated();
     TestMimeHandlerViewGuest* guest = static_cast<TestMimeHandlerViewGuest*>(
         extensions::MimeHandlerViewGuest::FromWebContents(guest_contents));
     ASSERT_TRUE(guest);
diff --git a/chrome/browser/resources/feedback_webui/BUILD.gn b/chrome/browser/resources/feedback_webui/BUILD.gn
index 9543f34..88f8a8f 100644
--- a/chrome/browser/resources/feedback_webui/BUILD.gn
+++ b/chrome/browser/resources/feedback_webui/BUILD.gn
@@ -3,64 +3,50 @@
 # found in the LICENSE file.
 
 import("//build/config/chromeos/ui_mode.gni")
+import("//chrome/browser/resources/tools/build_webui.gni")
 import("//chrome/common/features.gni")
-import("//tools/grit/grit_rule.gni")
-import("//ui/webui/resources/tools/generate_grd.gni")
 
 assert(!is_android)
 
-# Note: No need to pass these CSS files to preprocess_if_expr() for now.
-css_files = [
-  "css/common.css",
-  "css/feedback.css",
-  "css/feedback_shared_styles.css",
-  "css/feedback_shared_vars.css",
-  "css/sys_info.css",
-]
-
-if (is_chromeos_ash) {
-  css_files += [ "css/assistant_logs_info.css" ]
-}
-
-icon_files = [
-  "images/button_butter_bar_close.png",
-  "images/button_butter_bar_close_hover.png",
-  "images/button_butter_bar_close_pressed.png",
-  "images/2x/button_butter_bar_close.png",
-  "images/2x/button_butter_bar_close_hover.png",
-  "images/2x/button_butter_bar_close_pressed.png",
-]
-
-grit("resources") {
-  defines = chrome_grit_defines
-
-  # These arguments are needed since the grd is generated at build time.
-  enable_input_discovery_for_gn_analyze = false
-  source = "$target_gen_dir/resources.grd"
-  deps = [ ":build_grd" ]
-
-  outputs = [
-    "grit/feedback_webui_resources.h",
-    "grit/feedback_webui_resources_map.cc",
-    "grit/feedback_webui_resources_map.h",
-    "feedback_webui_resources.pak",
-  ]
-  output_dir = "$root_gen_dir/chrome"
-}
-
-generate_grd("build_grd") {
+build_webui("build") {
   grd_prefix = "feedback_webui"
-  out_grd = "$target_gen_dir/resources.grd"
 
-  input_files = css_files + icon_files
-  input_files_base_dir = rebase_path(".", "//")
+  static_files = [
+    "css/common.css",
+    "css/feedback.css",
+    "css/feedback_shared_styles.css",
+    "css/feedback_shared_vars.css",
+    "css/sys_info.css",
+    "html/default.html",
+    "html/sys_info.html",
+    "images/2x/button_butter_bar_close_hover.png",
+    "images/2x/button_butter_bar_close.png",
+    "images/2x/button_butter_bar_close_pressed.png",
+    "images/button_butter_bar_close_hover.png",
+    "images/button_butter_bar_close.png",
+    "images/button_butter_bar_close_pressed.png",
+  ]
 
-  deps = [
-    "html:build_grdp",
-    "js:build_grdp",
+  if (is_chromeos_ash) {
+    static_files += [
+      "css/assistant_logs_info.css",
+      "html/assistant_logs_info.html",
+      "html/bluetooth_logs_info.html",
+    ]
+  }
+
+  non_web_component_files = [
+    "js/feedback.ts",
+    "js/feedback_util.ts",
+    "js/questionnaire.ts",
+    "js/sys_info.ts",
+    "js/take_screenshot.ts",
   ]
-  grdp_files = [
-    "$target_gen_dir/js/resources.grdp",
-    "$target_gen_dir/html/resources.grdp",
+
+  ts_definitions = [
+    "//tools/typescript/definitions/feedback_private.d.ts",
+    "//tools/typescript/definitions/chrome_send.d.ts",
   ]
+  ts_deps = [ "//ui/webui/resources:library" ]
+  ts_use_local_config = false
 }
diff --git a/chrome/browser/resources/feedback_webui/html/BUILD.gn b/chrome/browser/resources/feedback_webui/html/BUILD.gn
deleted file mode 100644
index 904fbd87..0000000
--- a/chrome/browser/resources/feedback_webui/html/BUILD.gn
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright 2022 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/config/chromeos/ui_mode.gni")
-import("//tools/grit/preprocess_if_expr.gni")
-import("//ui/webui/resources/tools/generate_grd.gni")
-
-assert(!is_android)
-
-preprocess_folder = "$target_gen_dir/../preprocessed"
-
-html_files = [
-  "default.html",
-  "sys_info.html",
-]
-
-if (is_chromeos_ash) {
-  html_files += [
-    "assistant_logs_info.html",
-    "bluetooth_logs_info.html",
-  ]
-}
-
-preprocess_if_expr("preprocess") {
-  out_folder = "$preprocess_folder/html"
-  in_files = html_files
-}
-
-generate_grd("build_grdp") {
-  grd_prefix = "feedback_webui_html"
-  out_grd = "$target_gen_dir/resources.grdp"
-  input_files = html_files
-  input_files_base_dir = rebase_path("$preprocess_folder/html", root_build_dir)
-  resource_path_prefix = "html"
-  deps = [ ":preprocess" ]
-}
diff --git a/chrome/browser/resources/feedback_webui/js/BUILD.gn b/chrome/browser/resources/feedback_webui/js/BUILD.gn
deleted file mode 100644
index 21c09853..0000000
--- a/chrome/browser/resources/feedback_webui/js/BUILD.gn
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright 2021 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/config/chromeos/ui_mode.gni")
-import("//tools/grit/preprocess_if_expr.gni")
-import("//tools/typescript/ts_library.gni")
-import("//ui/webui/resources/tools/generate_grd.gni")
-
-assert(!is_android)
-
-preprocess_folder = "$target_gen_dir/../preprocessed/js"
-
-ts_files = [
-  "feedback.ts",
-  "feedback_util.ts",
-  "questionnaire.ts",
-  "sys_info.ts",
-  "take_screenshot.ts",
-]
-
-preprocess_if_expr("preprocess") {
-  out_folder = preprocess_folder
-  in_files = ts_files
-}
-
-ts_library("build_ts") {
-  root_dir = preprocess_folder
-  out_dir = "$target_gen_dir/tsc"
-  in_files = ts_files
-
-  definitions = [
-    "//tools/typescript/definitions/feedback_private.d.ts",
-    "//tools/typescript/definitions/chrome_send.d.ts",
-  ]
-
-  deps = [ "//ui/webui/resources:library" ]
-  extra_deps = [ ":preprocess" ]
-}
-
-generate_grd("build_grdp") {
-  grd_prefix = "feedback_webui_js"
-  out_grd = "$target_gen_dir/resources.grdp"
-  manifest_files =
-      filter_include(get_target_outputs(":build_ts"), [ "*.manifest" ])
-  resource_path_prefix = "js"
-  deps = [ ":build_ts" ]
-}
diff --git a/chrome/browser/resources/tools/build_webui.gni b/chrome/browser/resources/tools/build_webui.gni
index c91b4b1e..cc4a64c 100644
--- a/chrome/browser/resources/tools/build_webui.gni
+++ b/chrome/browser/resources/tools/build_webui.gni
@@ -11,10 +11,16 @@
 import("//ui/webui/resources/tools/generate_grd.gni")
 import("../tools/optimize_webui.gni")
 
+# See documentation at https://chromium.googlesource.com/chromium/src/+/HEAD/docs/webui_build_configuration.md#build_webui
+
 template("build_webui") {
   not_needed([ "target_name" ])
 
-  forward_variables_from(invoker, [ "grd_prefix" ])
+  forward_variables_from(invoker,
+                         [
+                           "grd_prefix",
+                           "static_files",
+                         ])
 
   preprocess_dir = "${target_gen_dir}/preprocessed"
   tsc_dir = "${target_gen_dir}/tsc"
@@ -76,6 +82,17 @@
     }
   }
 
+  # Compute which static_files should be preprocessed.
+  non_preprocessed_files_filter = [
+    "*.jpg",
+    "*.png",
+    "*.svg",
+  ]
+  static_non_preprocessed_files =
+      filter_include(static_files, non_preprocessed_files_filter)
+  static_preprocessed_files =
+      filter_exclude(static_files, non_preprocessed_files_filter)
+
   ### Define the various targets that are required by the build pipeline.
 
   # Specifically the order in which these targets are executed is:
@@ -87,6 +104,15 @@
   #  5) generate_grd()
   #  6) grit()
 
+  preprocess_if_expr("preprocess_static_files") {
+    visibility = [ ":build_grd" ]
+    defines = chrome_grit_defines
+    in_folder = "."
+    out_folder = preprocess_dir
+    in_files = static_preprocessed_files
+    out_manifest = "${target_gen_dir}/preprocess_static_files_manifest.json"
+  }
+
   preprocess_if_expr("preprocess") {
     visibility = [
       ":build_ts",
@@ -230,16 +256,20 @@
     grd_prefix = grd_prefix
     out_grd = "$target_gen_dir/resources.grd"
 
-    input_files = invoker.static_files
+    input_files = static_non_preprocessed_files
     input_files_base_dir = rebase_path(".", "//")
 
+    deps = [ ":preprocess_static_files" ]
+    manifest_files =
+        [ "${target_gen_dir}/preprocess_static_files_manifest.json" ]
+
     if (optimize) {
-      deps = [ ":build_bundle" ]
-      manifest_files = [ "$target_gen_dir/$bundle_manifest" ]
+      deps += [ ":build_bundle" ]
+      manifest_files += [ "$target_gen_dir/$bundle_manifest" ]
       resource_path_rewrites = invoker.optimize_webui_resource_paths_rewrites
     } else {
-      deps = [ ":build_ts" ]
-      manifest_files =
+      deps += [ ":build_ts" ]
+      manifest_files +=
           filter_include(get_target_outputs(":build_ts"), [ "*.manifest" ])
     }
 
diff --git a/chrome/browser/site_isolation/chrome_site_per_process_browsertest.cc b/chrome/browser/site_isolation/chrome_site_per_process_browsertest.cc
index 8ebbcd5..5e4262c 100644
--- a/chrome/browser/site_isolation/chrome_site_per_process_browsertest.cc
+++ b/chrome/browser/site_isolation/chrome_site_per_process_browsertest.cc
@@ -326,7 +326,7 @@
 
     // Wait until the guest for PDF is created.
     content::WebContents* guest_web_contents =
-        test_guest_view_manager()->WaitForSingleGuestCreated();
+        test_guest_view_manager()->DeprecatedWaitForSingleGuestCreated();
 
     ResetTouchAction(
         guest_view::GuestViewBase::FromWebContents(guest_web_contents)
@@ -361,7 +361,7 @@
 
   // Wait until the guest for PDF is created.
   content::WebContents* guest_web_contents =
-      test_guest_view_manager()->WaitForSingleGuestCreated();
+      test_guest_view_manager()->DeprecatedWaitForSingleGuestCreated();
 
   // Now detach the frame and observe that the guest is destroyed.
   content::WebContentsDestroyedWatcher observer(guest_web_contents);
diff --git a/chrome/browser/site_isolation/site_per_process_interactive_browsertest.cc b/chrome/browser/site_isolation/site_per_process_interactive_browsertest.cc
index 213ae28a..6bba0ae 100644
--- a/chrome/browser/site_isolation/site_per_process_interactive_browsertest.cc
+++ b/chrome/browser/site_isolation/site_per_process_interactive_browsertest.cc
@@ -1235,7 +1235,7 @@
 
   // Wait until the guest contents for PDF is created.
   content::WebContents* guest_contents =
-      test_guest_view_manager()->WaitForSingleGuestCreated();
+      test_guest_view_manager()->DeprecatedWaitForSingleGuestCreated();
 
   // Observe navigations in guest to find out when navigation to the (PDF)
   // extension commits. It will be used as an indicator that BrowserPlugin
@@ -1340,7 +1340,7 @@
 
   // Verify the pdf has loaded.
   auto* guest_web_contents =
-      test_guest_view_manager()->WaitForSingleGuestCreated();
+      test_guest_view_manager()->DeprecatedWaitForSingleGuestCreated();
   ASSERT_TRUE(guest_web_contents);
   EXPECT_NE(embedder_web_contents, guest_web_contents);
 
diff --git a/chrome/browser/ssl/stateful_ssl_host_state_delegate_test.cc b/chrome/browser/ssl/stateful_ssl_host_state_delegate_test.cc
index 49bc67e..8e49d8be 100644
--- a/chrome/browser/ssl/stateful_ssl_host_state_delegate_test.cc
+++ b/chrome/browser/ssl/stateful_ssl_host_state_delegate_test.cc
@@ -26,6 +26,7 @@
 #include "components/browsing_data/core/browsing_data_utils.h"
 #include "components/content_settings/core/browser/host_content_settings_map.h"
 #include "components/content_settings/core/common/content_settings_pattern.h"
+#include "components/guest_view/browser/guest_view_base.h"
 #include "components/guest_view/browser/test_guest_view_manager.h"
 #include "content/public/browser/browsing_data_remover.h"
 #include "content/public/browser/ssl_host_state_delegate.h"
@@ -933,17 +934,19 @@
   guest_view::TestGuestViewManager* guest_manager =
       static_cast<guest_view::TestGuestViewManager*>(
           guest_view::TestGuestViewManager::FromBrowserContext(profile));
-  content::WebContents* guest = guest_manager->WaitForSingleGuestCreated();
+  auto* guest = guest_manager->WaitForSingleGuestViewCreated();
   guest_manager->WaitUntilAttached(guest);
 
   // Store a certificate exception for the guest.
   content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();
   scoped_refptr<net::X509Certificate> cert = GetOkCert();
-  state->AllowCert(kWWWGoogleHost, *cert, net::ERR_CERT_DATE_INVALID, guest);
-  EXPECT_EQ(content::SSLHostStateDelegate::ALLOWED,
-            state->QueryPolicy(kWWWGoogleHost, *cert,
-                               net::ERR_CERT_DATE_INVALID, guest));
-  EXPECT_TRUE(state->HasAllowException(kWWWGoogleHost, guest));
+  state->AllowCert(kWWWGoogleHost, *cert, net::ERR_CERT_DATE_INVALID,
+                   guest->web_contents());
+  EXPECT_EQ(
+      content::SSLHostStateDelegate::ALLOWED,
+      state->QueryPolicy(kWWWGoogleHost, *cert, net::ERR_CERT_DATE_INVALID,
+                         guest->web_contents()));
+  EXPECT_TRUE(state->HasAllowException(kWWWGoogleHost, guest->web_contents()));
 
   // Navigate to a non-app page and test that the exception is not carried over.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
@@ -980,14 +983,15 @@
   guest_view::TestGuestViewManager* guest_manager =
       static_cast<guest_view::TestGuestViewManager*>(
           guest_view::TestGuestViewManager::FromBrowserContext(profile));
-  content::WebContents* guest = guest_manager->WaitForSingleGuestCreated();
+  auto* guest = guest_manager->WaitForSingleGuestViewCreated();
   guest_manager->WaitUntilAttached(guest);
 
   // Store an HTTP exception for the guest.
   content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();
-  state->AllowHttpForHost(kWWWGoogleHost, guest);
-  EXPECT_TRUE(state->IsHttpAllowedForHost(kWWWGoogleHost, guest));
-  EXPECT_TRUE(state->HasAllowException(kWWWGoogleHost, guest));
+  state->AllowHttpForHost(kWWWGoogleHost, guest->web_contents());
+  EXPECT_TRUE(
+      state->IsHttpAllowedForHost(kWWWGoogleHost, guest->web_contents()));
+  EXPECT_TRUE(state->HasAllowException(kWWWGoogleHost, guest->web_contents()));
 
   // Navigate to a non-app page and test that the exception is not carried over.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
diff --git a/chrome/browser/ui/android/fast_checkout/fast_checkout_view_impl.cc b/chrome/browser/ui/android/fast_checkout/fast_checkout_view_impl.cc
index 69596c6..1b958932 100644
--- a/chrome/browser/ui/android/fast_checkout/fast_checkout_view_impl.cc
+++ b/chrome/browser/ui/android/fast_checkout/fast_checkout_view_impl.cc
@@ -53,8 +53,8 @@
 }
 
 void FastCheckoutViewImpl::Show(
-    base::span<const autofill::AutofillProfile> autofill_profiles,
-    base::span<const autofill::CreditCard> credit_cards) {
+    const std::vector<autofill::AutofillProfile*>& autofill_profiles,
+    const std::vector<autofill::CreditCard*>& credit_cards) {
   if (!RecreateJavaObject()) {
     // It's possible that the constructor cannot access the bottom sheet clank
     // component. That case may be temporary but we can't let users in a waiting
@@ -72,7 +72,7 @@
     Java_FastCheckoutBridge_setAutofillProfile(
         env, autofill_profiles_array, i,
         CreateFastCheckoutAutofillProfile(
-            env, autofill_profiles[i],
+            env, *autofill_profiles[i],
             g_browser_process->GetApplicationLocale()));
   }
 
@@ -82,7 +82,7 @@
     Java_FastCheckoutBridge_setCreditCard(
         env, credit_cards_array, i,
         CreateFastCheckoutCreditCard(
-            env, credit_cards[i], g_browser_process->GetApplicationLocale()));
+            env, *credit_cards[i], g_browser_process->GetApplicationLocale()));
   }
 
   Java_FastCheckoutBridge_showBottomSheet(
diff --git a/chrome/browser/ui/android/fast_checkout/fast_checkout_view_impl.h b/chrome/browser/ui/android/fast_checkout/fast_checkout_view_impl.h
index 455bd55..06f81a1 100644
--- a/chrome/browser/ui/android/fast_checkout/fast_checkout_view_impl.h
+++ b/chrome/browser/ui/android/fast_checkout/fast_checkout_view_impl.h
@@ -29,8 +29,8 @@
   void OnDismiss(JNIEnv* env);
 
   // FastCheckoutView:
-  void Show(base::span<const autofill::AutofillProfile> autofill_profiles,
-            base::span<const autofill::CreditCard> credit_cards) override;
+  void Show(const std::vector<autofill::AutofillProfile*>& autofill_profiles,
+            const std::vector<autofill::CreditCard*>& credit_cards) override;
 
  private:
   // Returns either true if the java counterpart of this bridge is initialized
diff --git a/chrome/browser/ui/app_list/search/search_controller_factory.cc b/chrome/browser/ui/app_list/search/search_controller_factory.cc
index 935e9092..8af49e6 100644
--- a/chrome/browser/ui/app_list/search/search_controller_factory.cc
+++ b/chrome/browser/ui/app_list/search/search_controller_factory.cc
@@ -153,7 +153,7 @@
 
   if (ash::features::IsProductivityLauncherEnabled() &&
       base::GetFieldTrialParamByFeatureAsBool(
-          ash::features::kProductivityLauncher, "enable_continue", false)) {
+          ash::features::kProductivityLauncher, "enable_continue", true)) {
     size_t zero_state_files_group_id =
         controller->AddGroup(kMaxZeroStateFileResults);
     controller->AddProvider(zero_state_files_group_id,
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_file_system_delegate.cc b/chrome/browser/ui/ash/holding_space/holding_space_file_system_delegate.cc
index ab64672..2adad6e1 100644
--- a/chrome/browser/ui/ash/holding_space/holding_space_file_system_delegate.cc
+++ b/chrome/browser/ui/ash/holding_space/holding_space_file_system_delegate.cc
@@ -349,7 +349,7 @@
 }
 
 void HoldingSpaceFileSystemDelegate::OnVolumeMounted(
-    chromeos::MountError error_code,
+    MountError error_code,
     const file_manager::Volume& volume) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   holding_space_util::FilePathsWithValidityRequirements
@@ -370,7 +370,7 @@
 }
 
 void HoldingSpaceFileSystemDelegate::OnVolumeUnmounted(
-    chromeos::MountError error_code,
+    MountError error_code,
     const file_manager::Volume& volume) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_file_system_delegate.h b/chrome/browser/ui/ash/holding_space/holding_space_file_system_delegate.h
index 31de2e8..48c7feb7 100644
--- a/chrome/browser/ui/ash/holding_space/holding_space_file_system_delegate.h
+++ b/chrome/browser/ui/ash/holding_space/holding_space_file_system_delegate.h
@@ -63,9 +63,9 @@
   void OnHoldingSpaceItemInitialized(const HoldingSpaceItem* item) override;
 
   // file_manager::VolumeManagerObserver:
-  void OnVolumeMounted(chromeos::MountError error_code,
+  void OnVolumeMounted(MountError error_code,
                        const file_manager::Volume& volume) override;
-  void OnVolumeUnmounted(chromeos::MountError error_code,
+  void OnVolumeUnmounted(MountError error_code,
                          const file_manager::Volume& volume) override;
 
   // chromeos::FileChangeServiceObserver:
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_keyed_service_unittest.cc b/chrome/browser/ui/ash/holding_space/holding_space_keyed_service_unittest.cc
index 88a1635..e5b2974 100644
--- a/chrome/browser/ui/ash/holding_space/holding_space_keyed_service_unittest.cc
+++ b/chrome/browser/ui/ash/holding_space/holding_space_keyed_service_unittest.cc
@@ -349,7 +349,7 @@
   }
 
   TestingProfile* CreateProfile() override {
-    const std::string kPrimaryProfileName = "primary_profile";
+    const std::string kPrimaryProfileName = "primary_profile@test";
     const AccountId account_id(AccountId::FromUserEmail(kPrimaryProfileName));
 
     fake_user_manager_->AddUser(account_id);
diff --git a/chrome/browser/ui/ash/shelf/chrome_shelf_controller_unittest.cc b/chrome/browser/ui/ash/shelf/chrome_shelf_controller_unittest.cc
index 02bbb0721..f4751b7 100644
--- a/chrome/browser/ui/ash/shelf/chrome_shelf_controller_unittest.cc
+++ b/chrome/browser/ui/ash/shelf/chrome_shelf_controller_unittest.cc
@@ -1242,7 +1242,8 @@
 
     // Login a user. The "email" must match the TestingProfile's
     // GetProfileUserName() so that profile() will be the primary profile.
-    const AccountId account_id = AccountId::FromUserEmail("testing_profile");
+    const AccountId account_id =
+        AccountId::FromUserEmail("testing_profile@test");
     fake_user_manager->AddUser(account_id);
     fake_user_manager->LoginUser(account_id);
 
diff --git a/chrome/browser/ui/ash/wallpaper_controller_client_impl.cc b/chrome/browser/ui/ash/wallpaper_controller_client_impl.cc
index 8c0aff9..e113014 100644
--- a/chrome/browser/ui/ash/wallpaper_controller_client_impl.cc
+++ b/chrome/browser/ui/ash/wallpaper_controller_client_impl.cc
@@ -560,9 +560,9 @@
 }
 
 void WallpaperControllerClientImpl::OnVolumeMounted(
-    chromeos::MountError error_code,
+    ash::MountError error_code,
     const file_manager::Volume& volume) {
-  if (error_code != chromeos::MOUNT_ERROR_NONE) {
+  if (error_code != ash::MountError::kNone) {
     return;
   }
   if (volume.type() != file_manager::VolumeType::VOLUME_TYPE_GOOGLE_DRIVE) {
diff --git a/chrome/browser/ui/ash/wallpaper_controller_client_impl.h b/chrome/browser/ui/ash/wallpaper_controller_client_impl.h
index f75ab6a..95eb61db 100644
--- a/chrome/browser/ui/ash/wallpaper_controller_client_impl.h
+++ b/chrome/browser/ui/ash/wallpaper_controller_client_impl.h
@@ -97,7 +97,7 @@
   bool IsWallpaperSyncEnabled(const AccountId& account_id) const override;
 
   // file_manager::VolumeManagerObserver:
-  void OnVolumeMounted(chromeos::MountError error_code,
+  void OnVolumeMounted(ash::MountError error_code,
                        const file_manager::Volume& volume) override;
 
   // session_manager::SessionManagerObserver implementation.
diff --git a/chrome/browser/ui/fast_checkout/fast_checkout_controller_impl.cc b/chrome/browser/ui/fast_checkout/fast_checkout_controller_impl.cc
index da6ce71f..3e5215c 100644
--- a/chrome/browser/ui/fast_checkout/fast_checkout_controller_impl.cc
+++ b/chrome/browser/ui/fast_checkout/fast_checkout_controller_impl.cc
@@ -4,6 +4,8 @@
 
 #include "chrome/browser/ui/fast_checkout/fast_checkout_controller_impl.h"
 
+#include "chrome/browser/autofill/personal_data_manager_factory.h"
+#include "chrome/browser/profiles/profile.h"
 #include "components/autofill/core/browser/autofill_data_util.h"
 #include "components/autofill/core/browser/data_model/autofill_profile.h"
 #include "components/autofill/core/browser/data_model/credit_card.h"
@@ -16,18 +18,39 @@
 
 FastCheckoutControllerImpl::~FastCheckoutControllerImpl() = default;
 
-void FastCheckoutControllerImpl::Show() {}
+void FastCheckoutControllerImpl::Show() {
+  GetOrCreateView()->Show(GetPersonalDataManager()->GetProfilesToSuggest(),
+                          GetPersonalDataManager()->GetCreditCardsToSuggest(
+                              /* include_server_cards= */ true));
+}
 
 void FastCheckoutControllerImpl::OnOptionsSelected(
     std::unique_ptr<autofill::AutofillProfile> profile,
     std::unique_ptr<autofill::CreditCard> credit_card) {
+  view_.reset();
   delegate_->OnOptionsSelected(std::move(profile), std::move(credit_card));
 }
 
 void FastCheckoutControllerImpl::OnDismiss() {
+  view_.reset();
   delegate_->OnDismiss();
 }
 
+FastCheckoutView* FastCheckoutControllerImpl::GetOrCreateView() {
+  if (!view_) {
+    view_ = FastCheckoutView::Create(weak_ptr_factory_.GetWeakPtr());
+  }
+  return view_.get();
+}
+
+autofill::PersonalDataManager*
+FastCheckoutControllerImpl::GetPersonalDataManager() {
+  Profile* profile =
+      Profile::FromBrowserContext(web_contents_->GetBrowserContext());
+  return autofill::PersonalDataManagerFactory::GetForProfile(
+      profile->GetOriginalProfile());
+}
+
 gfx::NativeView FastCheckoutControllerImpl::GetNativeView() {
   return web_contents_->GetNativeView();
 }
diff --git a/chrome/browser/ui/fast_checkout/fast_checkout_controller_impl.h b/chrome/browser/ui/fast_checkout/fast_checkout_controller_impl.h
index 26ee60c..eef2026 100644
--- a/chrome/browser/ui/fast_checkout/fast_checkout_controller_impl.h
+++ b/chrome/browser/ui/fast_checkout/fast_checkout_controller_impl.h
@@ -8,6 +8,9 @@
 #include "chrome/browser/ui/fast_checkout/fast_checkout_controller.h"
 
 #include "base/memory/raw_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "chrome/browser/ui/fast_checkout/fast_checkout_view.h"
+#include "components/autofill/core/browser/personal_data_manager.h"
 #include "ui/gfx/native_widget_types.h"
 
 namespace content {
@@ -48,11 +51,28 @@
   void OnDismiss() override;
   gfx::NativeView GetNativeView() override;
 
+ protected:
+  // Methods below are protected (rather than private) and virtual for
+  // testing.
+
+  // Gets or creates (if needed) the FastCheckoutView associated with this
+  // controller.
+  virtual FastCheckoutView* GetOrCreateView();
+
+  // Returns the current active personal data manager.
+  virtual autofill::PersonalDataManager* GetPersonalDataManager();
+
  private:
   // Weak pointer to the WebContents this class is tied to.
   const raw_ptr<content::WebContents> web_contents_;
 
+  // View used to communicate with the Android frontend. It's non-null between
+  // Show() and OnDismiss()/OnOptionsSelected().
+  std::unique_ptr<FastCheckoutView> view_;
+
   // The delegate of UI events. It must outlive `this`.
   const raw_ptr<Delegate> delegate_;
+
+  base::WeakPtrFactory<FastCheckoutController> weak_ptr_factory_{this};
 };
 #endif  // CHROME_BROWSER_UI_FAST_CHECKOUT_FAST_CHECKOUT_CONTROLLER_IMPL_H_
diff --git a/chrome/browser/ui/fast_checkout/fast_checkout_controller_impl_unittest.cc b/chrome/browser/ui/fast_checkout/fast_checkout_controller_impl_unittest.cc
new file mode 100644
index 0000000..f222ba13
--- /dev/null
+++ b/chrome/browser/ui/fast_checkout/fast_checkout_controller_impl_unittest.cc
@@ -0,0 +1,134 @@
+// 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/ui/fast_checkout/fast_checkout_controller_impl.h"
+#include <memory>
+
+#include "chrome/browser/autofill/personal_data_manager_factory.h"
+#include "chrome/browser/ui/fast_checkout/fast_checkout_view.h"
+#include "chrome/test/base/chrome_render_view_host_test_harness.h"
+#include "components/autofill/core/browser/autofill_test_utils.h"
+#include "components/autofill/core/browser/test_personal_data_manager.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+using ::autofill::AutofillProfile;
+using ::autofill::CreditCard;
+using ::testing::Eq;
+using ::testing::Pointee;
+using ::testing::UnorderedElementsAre;
+
+struct MockFastCheckoutView : FastCheckoutView {
+  MockFastCheckoutView() = default;
+  ~MockFastCheckoutView() override = default;
+
+  MOCK_METHOD(void,
+              Show,
+              (const std::vector<autofill::AutofillProfile*>&,
+               const std::vector<autofill::CreditCard*>&),
+              (override));
+};
+
+struct MockFastCheckoutImplDelegate : FastCheckoutControllerImpl::Delegate {
+  MockFastCheckoutImplDelegate() = default;
+  ~MockFastCheckoutImplDelegate() override = default;
+
+  MOCK_METHOD(void,
+              OnOptionsSelected,
+              (std::unique_ptr<AutofillProfile>, std::unique_ptr<CreditCard>),
+              (override));
+
+  MOCK_METHOD(void, OnDismiss, (), (override));
+};
+
+class TestFastCheckoutControllerImpl : public FastCheckoutControllerImpl {
+ public:
+  TestFastCheckoutControllerImpl(
+      content::WebContents* web_contents,
+      Delegate* delegate,
+      FastCheckoutView* view,
+      autofill::PersonalDataManager* personal_manager)
+      : FastCheckoutControllerImpl(web_contents, delegate),
+        view_(view),
+        personal_manager_(personal_manager) {}
+  ~TestFastCheckoutControllerImpl() override = default;
+
+  FastCheckoutView* GetOrCreateView() override { return view_; }
+  autofill::PersonalDataManager* GetPersonalDataManager() override {
+    return personal_manager_;
+  }
+
+ private:
+  FastCheckoutView* view_;
+  autofill::PersonalDataManager* personal_manager_;
+};
+
+}  // namespace
+
+class FastCheckoutControllerImplTest : public ChromeRenderViewHostTestHarness {
+ protected:
+  FastCheckoutControllerImplTest() = default;
+  ~FastCheckoutControllerImplTest() override = default;
+
+  void SetUp() override {
+    ChromeRenderViewHostTestHarness::SetUp();
+
+    fast_checkout_controller_ =
+        std::make_unique<TestFastCheckoutControllerImpl>(
+            web_contents(), &delegate_, &mock_view_,
+            &test_personal_data_manager_);
+
+    test_personal_data_manager_.SetAutofillProfileEnabled(true);
+    test_personal_data_manager_.SetAutofillCreditCardEnabled(true);
+    test_personal_data_manager_.SetAutofillWalletImportEnabled(true);
+  }
+
+  MockFastCheckoutView mock_view_;
+  MockFastCheckoutImplDelegate delegate_;
+  autofill::TestPersonalDataManager test_personal_data_manager_;
+  // The object to be tested.
+  std::unique_ptr<TestFastCheckoutControllerImpl> fast_checkout_controller_;
+};
+
+TEST_F(FastCheckoutControllerImplTest, Show) {
+  AutofillProfile profile1 = autofill::test::GetFullProfile();
+  AutofillProfile profile2 = autofill::test::GetFullProfile2();
+  test_personal_data_manager_.AddProfile(profile1);
+  test_personal_data_manager_.AddProfile(profile2);
+
+  CreditCard credit_card1 = autofill::test::GetCreditCard();
+  CreditCard credit_card2 = autofill::test::GetCreditCard2();
+  test_personal_data_manager_.AddCreditCard(credit_card1);
+  test_personal_data_manager_.AddCreditCard(credit_card2);
+
+  EXPECT_CALL(
+      mock_view_,
+      Show(UnorderedElementsAre(Pointee(profile1), Pointee(profile2)),
+           UnorderedElementsAre(Pointee(credit_card1), Pointee(credit_card2))));
+
+  fast_checkout_controller_->Show();
+}
+
+TEST_F(FastCheckoutControllerImplTest, OnOptionsSelected) {
+  std::unique_ptr<AutofillProfile> profile =
+      std::make_unique<AutofillProfile>(autofill::test::GetFullProfile());
+  raw_ptr<AutofillProfile> profile_ptr = profile.get();
+
+  std::unique_ptr<CreditCard> credit_card =
+      std::make_unique<CreditCard>(autofill::test::GetCreditCard());
+  raw_ptr<CreditCard> credit_card_ptr = credit_card.get();
+
+  EXPECT_CALL(delegate_, OnOptionsSelected(Pointee(Eq(*profile_ptr)),
+                                           Pointee(Eq(*credit_card_ptr))));
+
+  fast_checkout_controller_->OnOptionsSelected(std::move(profile),
+                                               std::move(credit_card));
+}
+
+TEST_F(FastCheckoutControllerImplTest, OnDismiss) {
+  EXPECT_CALL(delegate_, OnDismiss);
+  fast_checkout_controller_->OnDismiss();
+}
diff --git a/chrome/browser/ui/fast_checkout/fast_checkout_view.h b/chrome/browser/ui/fast_checkout/fast_checkout_view.h
index de39f7a0..6cb508a2 100644
--- a/chrome/browser/ui/fast_checkout/fast_checkout_view.h
+++ b/chrome/browser/ui/fast_checkout/fast_checkout_view.h
@@ -23,8 +23,8 @@
   // Show the sheet with provided options to the user. After user interaction,
   // either `OnCredentialSelected` or `OnDismiss` gets invoked.
   virtual void Show(
-      base::span<const autofill::AutofillProfile> autofill_profiles,
-      base::span<const autofill::CreditCard> credit_cards) = 0;
+      const std::vector<autofill::AutofillProfile*>& autofill_profiles,
+      const std::vector<autofill::CreditCard*>& credit_cards) = 0;
 
   // Factory function for creating the view.
   static std::unique_ptr<FastCheckoutView> Create(
diff --git a/chrome/browser/ui/views/download/bubble/download_bubble_row_view.cc b/chrome/browser/ui/views/download/bubble/download_bubble_row_view.cc
index d78854f..c80b90a4 100644
--- a/chrome/browser/ui/views/download/bubble/download_bubble_row_view.cc
+++ b/chrome/browser/ui/views/download/bubble/download_bubble_row_view.cc
@@ -273,7 +273,7 @@
                     views::LayoutAlignment::kStart,
                     views::TableLayout::kFixedSize,
                     views::TableLayout::ColumnSize::kUsePreferred, 0, 0);
-  // Download name/status labels
+  // Download name label (primary_label_)
   layout->AddPaddingColumn(views::TableLayout::kFixedSize, icon_label_spacing)
       .AddColumn(views::LayoutAlignment::kStart, views::LayoutAlignment::kStart,
                  1.0f, views::TableLayout::ColumnSize::kUsePreferred, 0, 0)
@@ -312,6 +312,8 @@
       views::style::CONTEXT_DIALOG_BODY_TEXT, views::style::STYLE_PRIMARY));
   primary_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
   primary_label_->SetCanProcessEventsWithinSubtree(false);
+  primary_label_->SetMultiLine(true);
+  primary_label_->SetAllowCharacterBreak(true);
 
   main_button_holder_ = AddChildView(std::make_unique<views::FlexLayoutView>());
   cancel_button_ =
@@ -369,6 +371,8 @@
   // The 4 columns are filename text, Padding, Main Button, Subpage Icon.
   secondary_label_->SetProperty(views::kTableColAndRowSpanKey, gfx::Size(4, 1));
   secondary_label_->SetCanProcessEventsWithinSubtree(false);
+  secondary_label_->SetMultiLine(true);
+  secondary_label_->SetAllowCharacterBreak(true);
 
   // TODO(bhatiarohit): Remove the progress bar holder view here.
   // Currently the animation does not show up on deep scanning without
@@ -445,6 +449,17 @@
   }
 }
 
+gfx::Size DownloadBubbleRowView::CalculatePreferredSize() const {
+  // TODO(crbug.com/1349528): The size constraint is not passed down from the
+  // views tree in the first round of layout, so setting a fixed width to bound
+  // the view. This is assuming that the row view is loaded inside a bubble. It
+  // will break if the row view is loaded inside a different parent view.
+  int fixed_width = ChromeLayoutProvider::Get()->GetDistanceMetric(
+                        views::DISTANCE_BUBBLE_PREFERRED_WIDTH) -
+                    GetLayoutInsets(DOWNLOAD_ROW).width();
+  return {fixed_width, GetHeightForWidth(fixed_width)};
+}
+
 void DownloadBubbleRowView::OnWillChangeFocus(views::View* before,
                                               views::View* now) {
   if (now) {
@@ -464,6 +479,9 @@
     GetActionButtonForCommand(ui_info_.quick_actions.back().command)
         ->RequestFocus();
   }
+  // Resize is needed because the height of the primary_label_ can change when
+  // the quick actions are shown.
+  navigation_handler_->ResizeDialog();
 }
 
 void DownloadBubbleRowView::Layout() {
@@ -549,11 +567,6 @@
 
   hover_button_->SetAccessibleName(base::JoinString(
       {primary_label_->GetText(), secondary_label_->GetText()}, u" "));
-  // TODO(crbug.com/1326181): Below is a workaround for single line labels.
-  // Remove the tooltip text once `primary_label_` and `secondary_label_` can
-  // display multiline text.
-  hover_button_->SetTooltipText(base::JoinString(
-      {primary_label_->GetText(), secondary_label_->GetText()}, u"\n"));
 
   if (GetWidget()) {
     secondary_label_->SetEnabledColor(
@@ -588,6 +601,10 @@
 
 void DownloadBubbleRowView::OnDownloadUpdated() {
   UpdateRow(/*initial_setup=*/false);
+  // Resize is needed because the height of the row can change when the text
+  // (primary_label_ or secondary_label_) is updated.
+  PreferredSizeChanged();
+  navigation_handler_->ResizeDialog();
 }
 
 void DownloadBubbleRowView::OnDownloadOpened() {
diff --git a/chrome/browser/ui/views/download/bubble/download_bubble_row_view.h b/chrome/browser/ui/views/download/bubble/download_bubble_row_view.h
index 6b34b6d..6f33e91 100644
--- a/chrome/browser/ui/views/download/bubble/download_bubble_row_view.h
+++ b/chrome/browser/ui/views/download/bubble/download_bubble_row_view.h
@@ -55,6 +55,7 @@
   Views GetChildrenInZOrder() override;
   bool OnMouseDragged(const ui::MouseEvent& event) override;
   void OnMouseCaptureLost() override;
+  gfx::Size CalculatePreferredSize() const override;
 
   // Overrides views::FocusChangeListener
   void OnWillChangeFocus(views::View* before, views::View* now) override;
diff --git a/chrome/browser/ui/views/overlay/overlay_window_views.cc b/chrome/browser/ui/views/overlay/overlay_window_views.cc
index 55b53039..590d247 100644
--- a/chrome/browser/ui/views/overlay/overlay_window_views.cc
+++ b/chrome/browser/ui/views/overlay/overlay_window_views.cc
@@ -18,6 +18,7 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/grit/generated_resources.h"
+#include "chromeos/ui/base/chromeos_ui_constants.h"
 #include "components/vector_icons/vector_icons.h"
 #include "content/public/browser/picture_in_picture_window_controller.h"
 #include "content/public/browser/web_contents.h"
@@ -295,7 +296,7 @@
   // For rounded corners.
   if (ash::features::IsPipRoundedCornersEnabled()) {
     ash::SetCornerRadius(GetNativeWindow(), GetRootView()->layer(),
-                         ash::kPipRoundedCornerRadius);
+                         chromeos::kPipRoundedCornerRadius);
   }
 #endif
 
diff --git a/chrome/browser/ui/webui/browser_command/browser_command_handler.cc b/chrome/browser/ui/webui/browser_command/browser_command_handler.cc
index 4cfff3b..b9825e39 100644
--- a/chrome/browser/ui/webui/browser_command/browser_command_handler.cc
+++ b/chrome/browser/ui/webui/browser_command/browser_command_handler.cc
@@ -90,6 +90,9 @@
     case Command::kOpenPasswordManager:
       can_execute = true;
       break;
+    case Command::kNoOpCommand:
+      can_execute = true;
+      break;
   }
   std::move(callback).Run(can_execute);
 }
@@ -151,6 +154,9 @@
           GURL(chrome::GetSettingsUrl(chrome::kPasswordManagerSubPage)),
           disposition);
       break;
+    case Command::kNoOpCommand:
+      // Nothing to do.
+      break;
     default:
       NOTREACHED() << "Unspecified behavior for command " << id;
       break;
diff --git a/chrome/browser/ui/webui/browser_command/browser_command_handler_unittest.cc b/chrome/browser/ui/webui/browser_command/browser_command_handler_unittest.cc
index 6e025974..2d5d95e 100644
--- a/chrome/browser/ui/webui/browser_command/browser_command_handler_unittest.cc
+++ b/chrome/browser/ui/webui/browser_command/browser_command_handler_unittest.cc
@@ -46,6 +46,7 @@
     Command::kOpenPrivacyGuide,
     Command::kStartTabGroupTutorial,
     Command::kOpenPasswordManager,
+    Command::kNoOpCommand,
 };
 
 const ui::ElementContext kTestContext1(1);
diff --git a/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.cc b/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.cc
index e737851..84dae52a4 100644
--- a/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.cc
+++ b/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.cc
@@ -67,6 +67,7 @@
 #include "ui/gfx/color_palette.h"
 #include "ui/gfx/color_utils.h"
 #include "ui/native_theme/native_theme.h"
+#include "ui/webui/resources/js/browser_command/browser_command.mojom.h"
 
 namespace {
 
@@ -614,10 +615,22 @@
 }
 
 void NewTabPageHandler::GetPromo(GetPromoCallback callback) {
+  std::string command_id;
   // Replace the promo URL with "command:<id>" if such a command ID is set
   // via the feature params.
-  const std::string command_id = base::GetFieldTrialParamValueByFeature(
-      features::kPromoBrowserCommands, features::kBrowserCommandIdParam);
+  // If fake data is being used, we set the command_id to 7, which corresponds
+  // to kNoOpCommand in
+  // ui/webui/resources/js/browser_command/browser_command.mojom
+  if (base::GetFieldTrialParamValueByFeature(
+          ntp_features::kNtpMiddleSlotPromoDismissal,
+          ntp_features::kNtpMiddleSlotPromoDismissalParam) == "fake") {
+    command_id = base::NumberToString(
+        static_cast<int>(browser_command::mojom::Command::kNoOpCommand));
+  } else {
+    command_id = base::GetFieldTrialParamValueByFeature(
+        features::kPromoBrowserCommands, features::kBrowserCommandIdParam);
+  }
+
   if (!command_id.empty()) {
     auto promo = new_tab_page::mojom::Promo::New();
     std::vector<new_tab_page::mojom::PromoPartPtr> parts;
@@ -636,6 +649,7 @@
     link->text = "Test command: " + command_id;
     parts.push_back(new_tab_page::mojom::PromoPart::NewLink(std::move(link)));
     promo->middle_slot_parts = std::move(parts);
+    promo->id = "test" + command_id;
     std::move(callback).Run(std::move(promo));
     return;
   }
diff --git a/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc b/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc
index 3937a9cf..b0d5328 100644
--- a/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc
+++ b/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc
@@ -727,6 +727,7 @@
   std::vector<Command> supported_commands = {
       Command::kOpenSafetyCheck,
       Command::kOpenSafeBrowsingEnhancedProtectionSettings,
+      Command::kNoOpCommand,
   };
   promo_browser_command_handler_ = std::make_unique<BrowserCommandHandler>(
       std::move(pending_handler), profile_, supported_commands);
diff --git a/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.cc b/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.cc
index b0d5b37..ad5425f 100644
--- a/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.cc
@@ -239,7 +239,7 @@
     DiskMountManager::MountEvent event,
     chromeos::MountError error_code,
     const DiskMountManager::MountPointInfo& mount_info) {
-  if (error_code != chromeos::MountError::MOUNT_ERROR_NONE)
+  if (error_code != chromeos::MountError::kNone)
     return;
 
   if (!IsEligibleForAndroidStorage(mount_info.source_path))
diff --git a/chrome/browser/usb/chrome_usb_delegate.cc b/chrome/browser/usb/chrome_usb_delegate.cc
index 7aedd97..f61b9a75 100644
--- a/chrome/browser/usb/chrome_usb_delegate.cc
+++ b/chrome/browser/usb/chrome_usb_delegate.cc
@@ -225,6 +225,11 @@
     observer.OnDeviceManagerConnectionError();
 }
 
+void ChromeUsbDelegate::OnBrowserContextShutdown() {
+  device_observation_.Reset();
+  permission_observation_.Reset();
+}
+
 bool ChromeUsbDelegate::HasDevicePermission(
     RenderFrameHost& frame,
     const device::mojom::UsbDeviceInfo& device) {
diff --git a/chrome/browser/usb/chrome_usb_delegate.h b/chrome/browser/usb/chrome_usb_delegate.h
index 047cc23..09d3fd1 100644
--- a/chrome/browser/usb/chrome_usb_delegate.h
+++ b/chrome/browser/usb/chrome_usb_delegate.h
@@ -68,6 +68,7 @@
   void OnDeviceAdded(const device::mojom::UsbDeviceInfo&) override;
   void OnDeviceRemoved(const device::mojom::UsbDeviceInfo&) override;
   void OnDeviceManagerConnectionError() override;
+  void OnBrowserContextShutdown() override;
 
  private:
   base::ScopedObservation<UsbChooserContext,
diff --git a/chrome/browser/usb/usb_chooser_context.cc b/chrome/browser/usb/usb_chooser_context.cc
index 72cace0..84e48e4d 100644
--- a/chrome/browser/usb/usb_chooser_context.cc
+++ b/chrome/browser/usb/usb_chooser_context.cc
@@ -237,6 +237,11 @@
 
 UsbChooserContext::~UsbChooserContext() {
   OnDeviceManagerConnectionError();
+  for (auto& observer : device_observer_list_) {
+    observer.OnBrowserContextShutdown();
+    DCHECK(!device_observer_list_.HasObserver(&observer));
+  }
+  DCHECK(permission_observer_list_.empty());
 }
 
 std::vector<std::unique_ptr<permissions::ObjectPermissionContextBase::Object>>
diff --git a/chrome/browser/usb/usb_chooser_context.h b/chrome/browser/usb/usb_chooser_context.h
index 725ce00..55fd657 100644
--- a/chrome/browser/usb/usb_chooser_context.h
+++ b/chrome/browser/usb/usb_chooser_context.h
@@ -45,6 +45,10 @@
     virtual void OnDeviceAdded(const device::mojom::UsbDeviceInfo&);
     virtual void OnDeviceRemoved(const device::mojom::UsbDeviceInfo&);
     virtual void OnDeviceManagerConnectionError();
+
+    // Called when the BrowserContext is shutting down. Observers must remove
+    // themselves before returning.
+    virtual void OnBrowserContextShutdown() = 0;
   };
 
   static base::Value DeviceInfoToValue(
diff --git a/chrome/browser/usb/usb_chooser_context_mock_device_observer.h b/chrome/browser/usb/usb_chooser_context_mock_device_observer.h
index 6adb667..c697a6f 100644
--- a/chrome/browser/usb/usb_chooser_context_mock_device_observer.h
+++ b/chrome/browser/usb/usb_chooser_context_mock_device_observer.h
@@ -17,6 +17,7 @@
   MOCK_METHOD1(OnDeviceAdded, void(const device::mojom::UsbDeviceInfo&));
   MOCK_METHOD1(OnDeviceRemoved, void(const device::mojom::UsbDeviceInfo&));
   MOCK_METHOD0(OnDeviceManagerConnectionError, void());
+  MOCK_METHOD0(OnBrowserContextShutdown, void());
 };
 
 #endif  // CHROME_BROWSER_USB_USB_CHOOSER_CONTEXT_MOCK_DEVICE_OBSERVER_H_
diff --git a/chrome/browser/usb/usb_chooser_context_unittest.cc b/chrome/browser/usb/usb_chooser_context_unittest.cc
index 92fbdd2..ce3bf946a3 100644
--- a/chrome/browser/usb/usb_chooser_context_unittest.cc
+++ b/chrome/browser/usb/usb_chooser_context_unittest.cc
@@ -5,11 +5,13 @@
 #include <vector>
 
 #include "base/callback_helpers.h"
+#include "base/containers/flat_map.h"
 #include "base/json/json_reader.h"
 #include "base/no_destructor.h"
 #include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/bind.h"
+#include "base/test/test_future.h"
 #include "base/values.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
@@ -30,7 +32,8 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-using device::mojom::UsbDeviceInfoPtr;
+using ::base::test::TestFuture;
+using ::device::mojom::UsbDeviceInfoPtr;
 using ::testing::_;
 using ::testing::AnyNumber;
 using ::testing::NiceMock;
@@ -48,15 +51,19 @@
  public:
   UsbChooserContextTest() {}
   ~UsbChooserContextTest() override {
-    // When UsbChooserContext is destroyed, OnDeviceManagerConnectionError
-    // should be called on the observers and OnPermissionRevoked will be called
-    // for any ephemeral device permissions that are active.
-    EXPECT_CALL(mock_device_observer_, OnDeviceManagerConnectionError())
-        .Times(AnyNumber());
-    EXPECT_CALL(mock_permission_observer_, OnPermissionRevoked(_))
-        .Times(AnyNumber());
-    EXPECT_CALL(mock_permission_observer_, OnObjectPermissionChanged(_, _))
-        .Times(AnyNumber());
+    // When UsbChooserContext is destroyed, OnDeviceManagerConnectionError will
+    // be called for each device observer.
+    for (const auto& entry : mock_device_observers_) {
+      EXPECT_CALL(*entry.second, OnDeviceManagerConnectionError)
+          .Times(AnyNumber());
+    }
+
+    // OnPermissionRevoked and OnObjectPermissionChanged will be called for any
+    // ephemeral device permissions that are active.
+    for (const auto& entry : mock_permission_observers_) {
+      EXPECT_CALL(*entry.second, OnPermissionRevoked).Times(AnyNumber());
+      EXPECT_CALL(*entry.second, OnObjectPermissionChanged).Times(AnyNumber());
+    }
   }
 
  protected:
@@ -71,21 +78,42 @@
 
     // Call GetDevices once to make sure the connection with DeviceManager has
     // been set up, so that it can be notified when device is removed.
-    chooser_context->GetDevices(base::DoNothing());
-    base::RunLoop().RunUntilIdle();
+    TestFuture<std::vector<device::mojom::UsbDeviceInfoPtr>> devices_future;
+    chooser_context->GetDevices(devices_future.GetCallback());
+    EXPECT_TRUE(devices_future.Wait());
 
     // Add observers
+    EXPECT_FALSE(base::Contains(mock_permission_observers_, profile));
+    EXPECT_FALSE(base::Contains(mock_device_observers_, profile));
+    mock_permission_observers_.emplace(
+        profile,
+        std::make_unique<NiceMock<permissions::MockPermissionObserver>>());
+    mock_device_observers_.emplace(profile,
+                                   std::make_unique<MockDeviceObserver>());
+    NiceMock<permissions::MockPermissionObserver>* permission_observer =
+        mock_permission_observers_[profile].get();
     chooser_context->permissions::ObjectPermissionContextBase::AddObserver(
-        &mock_permission_observer_);
-    chooser_context->AddObserver(&mock_device_observer_);
+        permission_observer);
+    MockDeviceObserver* device_observer = mock_device_observers_[profile].get();
+    chooser_context->AddObserver(device_observer);
+    EXPECT_CALL(*device_observer, OnBrowserContextShutdown)
+        .WillOnce([chooser_context, permission_observer, device_observer]() {
+          chooser_context
+              ->permissions::ObjectPermissionContextBase::RemoveObserver(
+                  permission_observer);
+          chooser_context->RemoveObserver(device_observer);
+        });
     return chooser_context;
   }
 
   device::FakeUsbDeviceManager device_manager_;
 
   // Mock observers
-  NiceMock<permissions::MockPermissionObserver> mock_permission_observer_;
-  MockDeviceObserver mock_device_observer_;
+  base::flat_map<Profile*,
+                 std::unique_ptr<NiceMock<permissions::MockPermissionObserver>>>
+      mock_permission_observers_;
+  base::flat_map<Profile*, std::unique_ptr<MockDeviceObserver>>
+      mock_device_observers_;
 
  private:
   content::BrowserTaskEnvironment task_environment_;
@@ -108,7 +136,7 @@
   object.SetStringKey(kSerialNumberKey, "123ABC");
 
   EXPECT_FALSE(store->HasDevicePermission(origin, *device_info));
-  EXPECT_CALL(mock_permission_observer_,
+  EXPECT_CALL(*mock_permission_observers_[profile()],
               OnObjectPermissionChanged(
                   absl::make_optional(ContentSettingsType::USB_GUARD),
                   ContentSettingsType::USB_CHOOSER_DATA));
@@ -127,11 +155,12 @@
   EXPECT_EQ(object, all_origin_objects[0]->value);
   EXPECT_FALSE(all_origin_objects[0]->incognito);
 
-  EXPECT_CALL(mock_permission_observer_,
+  EXPECT_CALL(*mock_permission_observers_[profile()],
               OnObjectPermissionChanged(
                   absl::make_optional(ContentSettingsType::USB_GUARD),
                   ContentSettingsType::USB_CHOOSER_DATA));
-  EXPECT_CALL(mock_permission_observer_, OnPermissionRevoked(origin));
+  EXPECT_CALL(*mock_permission_observers_[profile()],
+              OnPermissionRevoked(origin));
 
   store->RevokeObjectPermission(origin, objects[0]->value);
   EXPECT_FALSE(store->HasDevicePermission(origin, *device_info));
@@ -160,7 +189,7 @@
   object.SetIntKey(kProductIdKey, device_info->product_id);
 
   EXPECT_FALSE(store->HasDevicePermission(origin, *device_info));
-  EXPECT_CALL(mock_permission_observer_,
+  EXPECT_CALL(*mock_permission_observers_[profile()],
               OnObjectPermissionChanged(
                   absl::make_optional(ContentSettingsType::USB_GUARD),
                   ContentSettingsType::USB_CHOOSER_DATA));
@@ -181,11 +210,12 @@
   EXPECT_EQ(object, all_origin_objects[0]->value);
   EXPECT_FALSE(all_origin_objects[0]->incognito);
 
-  EXPECT_CALL(mock_permission_observer_,
+  EXPECT_CALL(*mock_permission_observers_[profile()],
               OnObjectPermissionChanged(
                   absl::make_optional(ContentSettingsType::USB_GUARD),
                   ContentSettingsType::USB_CHOOSER_DATA));
-  EXPECT_CALL(mock_permission_observer_, OnPermissionRevoked(origin));
+  EXPECT_CALL(*mock_permission_observers_[profile()],
+              OnPermissionRevoked(origin));
 
   store->RevokeObjectPermission(origin, objects[0]->value);
   EXPECT_FALSE(store->HasDevicePermission(origin, *device_info));
@@ -205,7 +235,7 @@
   UsbChooserContext* store = GetChooserContext(profile());
 
   EXPECT_FALSE(store->HasDevicePermission(origin, *device_info));
-  EXPECT_CALL(mock_permission_observer_,
+  EXPECT_CALL(*mock_permission_observers_[profile()],
               OnObjectPermissionChanged(
                   absl::make_optional(ContentSettingsType::USB_GUARD),
                   ContentSettingsType::USB_CHOOSER_DATA));
@@ -221,7 +251,7 @@
       store->GetAllGrantedObjects();
   EXPECT_EQ(1u, all_origin_objects.size());
 
-  EXPECT_CALL(mock_device_observer_, OnDeviceRemoved(_));
+  EXPECT_CALL(*mock_device_observers_[profile()], OnDeviceRemoved(_));
   device_manager_.RemoveDevice(device_info->guid);
   base::RunLoop().RunUntilIdle();
 
@@ -250,7 +280,7 @@
   UsbChooserContext* store = GetChooserContext(profile());
 
   EXPECT_FALSE(store->HasDevicePermission(origin, *device_info));
-  EXPECT_CALL(mock_permission_observer_,
+  EXPECT_CALL(*mock_permission_observers_[profile()],
               OnObjectPermissionChanged(
                   absl::make_optional(ContentSettingsType::USB_GUARD),
                   ContentSettingsType::USB_CHOOSER_DATA));
@@ -266,11 +296,11 @@
       store->GetAllGrantedObjects();
   EXPECT_EQ(1u, all_origin_objects.size());
 
-  EXPECT_CALL(mock_permission_observer_,
+  EXPECT_CALL(*mock_permission_observers_[profile()],
               OnObjectPermissionChanged(
                   absl::make_optional(ContentSettingsType::USB_GUARD),
                   ContentSettingsType::USB_CHOOSER_DATA));
-  EXPECT_CALL(mock_device_observer_, OnDeviceRemoved(_));
+  EXPECT_CALL(*mock_device_observers_[profile()], OnDeviceRemoved(_));
   device_manager_.RemoveDevice(device_info->guid);
   base::RunLoop().RunUntilIdle();
 
@@ -298,10 +328,11 @@
   UsbDeviceInfoPtr device_info_2 =
       device_manager_.CreateAndAddDevice(0, 0, "Google", "Gizmo", "");
   UsbChooserContext* store = GetChooserContext(profile());
-  UsbChooserContext* incognito_store = GetChooserContext(
-      profile()->GetPrimaryOTRProfile(/*create_if_needed=*/true));
+  auto* otr_profile =
+      profile()->GetPrimaryOTRProfile(/*create_if_needed=*/true);
+  UsbChooserContext* incognito_store = GetChooserContext(otr_profile);
 
-  EXPECT_CALL(mock_permission_observer_,
+  EXPECT_CALL(*mock_permission_observers_[profile()],
               OnObjectPermissionChanged(
                   absl::make_optional(ContentSettingsType::USB_GUARD),
                   ContentSettingsType::USB_CHOOSER_DATA));
@@ -310,7 +341,7 @@
   EXPECT_TRUE(store->HasDevicePermission(origin, *device_info_1));
   EXPECT_FALSE(incognito_store->HasDevicePermission(origin, *device_info_1));
 
-  EXPECT_CALL(mock_permission_observer_,
+  EXPECT_CALL(*mock_permission_observers_[otr_profile],
               OnObjectPermissionChanged(
                   absl::make_optional(ContentSettingsType::USB_GUARD),
                   ContentSettingsType::USB_CHOOSER_DATA));
@@ -356,7 +387,7 @@
       kFooUrl, kFooUrl, ContentSettingsType::USB_GUARD, CONTENT_SETTING_BLOCK);
 
   auto* store = GetChooserContext(profile());
-  EXPECT_CALL(mock_permission_observer_,
+  EXPECT_CALL(*mock_permission_observers_[profile()],
               OnObjectPermissionChanged(
                   absl::make_optional(ContentSettingsType::USB_GUARD),
                   ContentSettingsType::USB_CHOOSER_DATA))
@@ -975,7 +1006,7 @@
 
   auto* store = GetChooserContext(profile());
 
-  EXPECT_CALL(mock_permission_observer_,
+  EXPECT_CALL(*mock_permission_observers_[profile()],
               OnObjectPermissionChanged(
                   absl::make_optional(ContentSettingsType::USB_GUARD),
                   ContentSettingsType::USB_CHOOSER_DATA))
@@ -1046,7 +1077,7 @@
   UsbDeviceInfoPtr persistent_device_info = device_manager_.CreateAndAddDevice(
       6353, 5678, "Specific", "Product", "123ABC");
 
-  EXPECT_CALL(mock_permission_observer_,
+  EXPECT_CALL(*mock_permission_observers_[profile()],
               OnObjectPermissionChanged(
                   absl::make_optional(ContentSettingsType::USB_GUARD),
                   ContentSettingsType::USB_CHOOSER_DATA));
@@ -1103,7 +1134,7 @@
   profile()->GetPrefs()->Set(prefs::kManagedWebUsbAllowDevicesForUrls,
                              *base::JSONReader::ReadDeprecated(kPolicySetting));
 
-  EXPECT_CALL(mock_permission_observer_,
+  EXPECT_CALL(*mock_permission_observers_[profile()],
               OnObjectPermissionChanged(
                   absl::make_optional(ContentSettingsType::USB_GUARD),
                   ContentSettingsType::USB_CHOOSER_DATA));
@@ -1156,7 +1187,7 @@
   profile()->GetPrefs()->Set(prefs::kManagedWebUsbAllowDevicesForUrls,
                              *base::JSONReader::ReadDeprecated(kPolicySetting));
 
-  EXPECT_CALL(mock_permission_observer_,
+  EXPECT_CALL(*mock_permission_observers_[profile()],
               OnObjectPermissionChanged(
                   absl::make_optional(ContentSettingsType::USB_GUARD),
                   ContentSettingsType::USB_CHOOSER_DATA));
diff --git a/chrome/browser/usb/usb_chooser_controller.cc b/chrome/browser/usb/usb_chooser_controller.cc
index 00578e1..a735644 100644
--- a/chrome/browser/usb/usb_chooser_controller.cc
+++ b/chrome/browser/usb/usb_chooser_controller.cc
@@ -234,7 +234,7 @@
   }
 }
 
-void UsbChooserController::OnDeviceManagerConnectionError() {
+void UsbChooserController::OnBrowserContextShutdown() {
   observation_.Reset();
 }
 
diff --git a/chrome/browser/usb/usb_chooser_controller.h b/chrome/browser/usb/usb_chooser_controller.h
index 515933e5..e6d9631 100644
--- a/chrome/browser/usb/usb_chooser_controller.h
+++ b/chrome/browser/usb/usb_chooser_controller.h
@@ -55,7 +55,7 @@
   void OnDeviceAdded(const device::mojom::UsbDeviceInfo& device_info) override;
   void OnDeviceRemoved(
       const device::mojom::UsbDeviceInfo& device_info) override;
-  void OnDeviceManagerConnectionError() override;
+  void OnBrowserContextShutdown() override;
 
  private:
   void GotUsbDeviceList(std::vector<device::mojom::UsbDeviceInfoPtr> devices);
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index fc75bcf..c1ea4be 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-main-1659462943-2312c19677ae412d349ad68fea81b66b45a3d6d2.profdata
+chrome-linux-main-1659484575-aa21dd6c3c2af862c5f0f8787701a08eec85a7c3.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt
index c862d8d3..6f63074 100644
--- a/chrome/build/mac-arm.pgo.txt
+++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@
-chrome-mac-arm-main-1659441545-183eb2157c18e2e453701853aa68eb82e68a1924.profdata
+chrome-mac-arm-main-1659484575-8635c2ba0f24232a06db0b706ec75bb9e41f9480.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index a51c049..404552d 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-main-1659441545-4596e6e6000c0c346c41495efc6be10af4c14f23.profdata
+chrome-mac-main-1659484575-37bf97f4195514edfb49b625a622265894788433.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index 97c8e06..f5c27fb 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1659452269-c961bad24cdf50badee4dd200bac586a3c0f512d.profdata
+chrome-win32-main-1659462943-7492dd0f78b6af43a1eeadd05f98b57f42975de8.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 01095a8..558a937 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1659452269-ada18e647af1ec75e1cfafc6769cc4476a60fdb2.profdata
+chrome-win64-main-1659473906-e142187540b19655958f4ad02997f41054724f8f.profdata
diff --git a/chrome/common/safe_browsing/zip_analyzer.cc b/chrome/common/safe_browsing/zip_analyzer.cc
index 23ac801..7b761eb 100644
--- a/chrome/common/safe_browsing/zip_analyzer.cc
+++ b/chrome/common/safe_browsing/zip_analyzer.cc
@@ -55,6 +55,9 @@
   bool timeout = false;
   results->file_count = 0;
   results->directory_count = 0;
+
+  bool has_encrypted = false;
+  bool has_aes_encrypted = false;
   while (const zip::ZipReader::Entry* const entry = reader.Next()) {
     if (base::Time::Now() - start_time >
         base::Milliseconds(kZipAnalysisTimeoutMs)) {
@@ -82,6 +85,14 @@
       results->directory_count++;
     else
       results->file_count++;
+
+    has_encrypted |= entry->is_encrypted;
+    has_aes_encrypted |= entry->uses_aes_encryption;
+  }
+
+  if (has_encrypted) {
+    base::UmaHistogramBoolean("SBClientDownload.EncryptedZipUsesAes",
+                              has_aes_encrypted);
   }
 
   if (timeout) {
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 7853938..0119e51 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -6324,6 +6324,7 @@
       "../browser/ui/autofill/payments/autofill_error_dialog_controller_impl_unittest.cc",
       "../browser/ui/autofill/payments/autofill_progress_dialog_controller_impl_unittest.cc",
       "../browser/ui/autofill/payments/autofill_snackbar_controller_impl_unittest.cc",
+      "../browser/ui/fast_checkout/fast_checkout_controller_impl_unittest.cc",
     ]
 
     deps += [
diff --git a/chrome/test/base/browser_with_test_window_test.cc b/chrome/test/base/browser_with_test_window_test.cc
index 45feedd..19569dd 100644
--- a/chrome/test/base/browser_with_test_window_test.cc
+++ b/chrome/test/base/browser_with_test_window_test.cc
@@ -211,7 +211,8 @@
 
 TestingProfile* BrowserWithTestWindowTest::CreateProfile() {
   return profile_manager_->CreateTestingProfile(
-      "testing_profile", nullptr, std::u16string(), 0, GetTestingFactories());
+      TestingProfile::kDefaultProfileUserName, nullptr, std::u16string(), 0,
+      GetTestingFactories());
 }
 
 TestingProfile::TestingFactories
diff --git a/chrome/test/base/testing_profile.cc b/chrome/test/base/testing_profile.cc
index 22bb9fb07..2ed93f7 100644
--- a/chrome/test/base/testing_profile.cc
+++ b/chrome/test/base/testing_profile.cc
@@ -159,7 +159,7 @@
 }  // namespace
 
 // static
-const char TestingProfile::kDefaultProfileUserName[] = "testing_profile";
+const char TestingProfile::kDefaultProfileUserName[] = "testing_profile@test";
 
 // static
 #if BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/chrome/test/base/testing_profile_manager.cc b/chrome/test/base/testing_profile_manager.cc
index 8ffb5dd..50b5bfa 100644
--- a/chrome/test/base/testing_profile_manager.cc
+++ b/chrome/test/base/testing_profile_manager.cc
@@ -10,6 +10,7 @@
 #include "base/bind.h"
 #include "base/feature_list.h"
 #include "base/memory/ref_counted.h"
+#include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/test_file_util.h"
 #include "build/build_config.h"
@@ -89,9 +90,14 @@
   if (profile_name != chrome::kInitialProfile &&
       profile_name != chrome::kLockScreenProfile &&
       profile_name != ash::ProfileHelper::GetLockScreenAppProfileName()) {
+    const std::string fake_email =
+        profile_name.find('@') == std::string::npos
+            ? base::ToLowerASCII(profile_name) + "@test"
+            : profile_name;
     profile_path =
         profile_path.Append(ash::ProfileHelper::Get()->GetUserProfileDir(
-            ash::ProfileHelper::GetUserIdHashByUserIdForTesting(profile_name)));
+            ash::ProfileHelper::GetUserIdHashByUserIdForTesting(
+                AccountId::FromUserEmail(fake_email).GetUserEmail())));
   } else {
     profile_path = profile_path.AppendASCII(profile_name);
   }
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json
index 6ec2530d..a5db0be 100644
--- a/chrome/test/data/policy/policy_test_cases.json
+++ b/chrome/test/data/policy/policy_test_cases.json
@@ -11834,7 +11834,7 @@
         "policies": {},
         "prefs": {
           "power.adaptive_charging_enabled": {
-            "default_value": true
+            "value": false
           }
         }
       },
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 e2cb896..b77f64b 100644
--- a/chrome/updater/app/server/win/com_classes_legacy_unittest.cc
+++ b/chrome/updater/app/server/win/com_classes_legacy_unittest.cc
@@ -15,6 +15,7 @@
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
+#include "base/path_service.h"
 #include "base/strings/strcat.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/synchronization/waitable_event.h"
@@ -23,9 +24,12 @@
 #include "base/time/time.h"
 #include "base/win/scoped_handle.h"
 #include "base/win/scoped_variant.h"
+#include "base/win/win_util.h"
 #include "chrome/updater/test/integration_tests_impl.h"
 #include "chrome/updater/test_scope.h"
 #include "chrome/updater/unittest_util_win.h"
+#include "chrome/updater/util.h"
+#include "chrome/updater/win/setup/setup_util.h"
 #include "chrome/updater/win/test/test_executables.h"
 #include "chrome/updater/win/test/test_strings.h"
 #include "chrome/updater/win/win_util.h"
@@ -226,4 +230,94 @@
   EXPECT_EQ(exit_code, 999U);
 }
 
+TEST_F(LegacyAppCommandWebImplTest, CheckLegacyTypeLibAndInterfaceExist) {
+  base::FilePath typelib_path;
+  ASSERT_TRUE(base::PathService::Get(base::DIR_EXE, &typelib_path));
+
+  Microsoft::WRL::ComPtr<ITypeLib> type_lib;
+  ASSERT_HRESULT_SUCCEEDED(::LoadTypeLib(
+      typelib_path.Append(GetExecutableRelativePath())
+          .Append(GetComTypeLibResourceIndex(__uuidof(IAppCommandWeb)))
+          .value()
+          .c_str(),
+      &type_lib));
+
+  Microsoft::WRL::ComPtr<ITypeInfo> type_info;
+  EXPECT_HRESULT_SUCCEEDED(
+      type_lib->GetTypeInfoOfGuid(__uuidof(IAppCommandWeb), &type_info))
+      << " Could not load type info for legacy interface IAppCommandWeb, "
+         "IID_IAppCommand: "
+      << base::win::WStringFromGUID(__uuidof(IAppCommandWeb));
+}
+
+TEST(LegacyCOMClassesTest, CheckLegacyInterfaceIDs) {
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
+  EXPECT_EQ(base::win::WStringFromGUID(__uuidof(GoogleUpdate3WebUserClass)),
+            L"{22181302-A8A6-4f84-A541-E5CBFC70CC43}");
+  EXPECT_EQ(base::win::WStringFromGUID(__uuidof(GoogleUpdate3WebSystemClass)),
+            L"{8A1D4361-2C08-4700-A351-3EAA9CBFF5E4}");
+  EXPECT_EQ(base::win::WStringFromGUID(__uuidof(PolicyStatusUserClass)),
+            L"{6DDCE70D-A4AE-4E97-908C-BE7B2DB750AD}");
+  EXPECT_EQ(base::win::WStringFromGUID(__uuidof(PolicyStatusSystemClass)),
+            L"{521FDB42-7130-4806-822A-FC5163FAD983}");
+  EXPECT_EQ(base::win::WStringFromGUID(__uuidof(ProcessLauncherClass)),
+            L"{ABC01078-F197-4b0b-ADBC-CFE684B39C82}");
+  EXPECT_EQ(base::win::WStringFromGUID(__uuidof(ICurrentState)),
+            L"{247954F9-9EDC-4E68-8CC3-150C2B89EADF}");
+  EXPECT_EQ(base::win::WStringFromGUID(__uuidof(IGoogleUpdate3Web)),
+            L"{494B20CF-282E-4BDD-9F5D-B70CB09D351E}");
+  EXPECT_EQ(base::win::WStringFromGUID(__uuidof(IAppBundleWeb)),
+            L"{DD42475D-6D46-496a-924E-BD5630B4CBBA}");
+  EXPECT_EQ(base::win::WStringFromGUID(__uuidof(IAppWeb)),
+            L"{18D0F672-18B4-48e6-AD36-6E6BF01DBBC4}");
+  EXPECT_EQ(base::win::WStringFromGUID(__uuidof(IAppCommandWeb)),
+            L"{8476CE12-AE1F-4198-805C-BA0F9B783F57}");
+  EXPECT_EQ(base::win::WStringFromGUID(__uuidof(IPolicyStatus)),
+            L"{F63F6F8B-ACD5-413C-A44B-0409136D26CB}");
+  EXPECT_EQ(base::win::WStringFromGUID(__uuidof(IPolicyStatus2)),
+            L"{34527502-D3DB-4205-A69B-789B27EE0414}");
+  EXPECT_EQ(base::win::WStringFromGUID(__uuidof(IPolicyStatus3)),
+            L"{05A30352-EB25-45B6-8449-BCA7B0542CE5}");
+  EXPECT_EQ(base::win::WStringFromGUID(__uuidof(IPolicyStatusValue)),
+            L"{27634814-8E41-4C35-8577-980134A96544}");
+  EXPECT_EQ(base::win::WStringFromGUID(__uuidof(IProcessLauncher)),
+            L"{128C2DA6-2BC0-44c0-B3F6-4EC22E647964}");
+  EXPECT_EQ(base::win::WStringFromGUID(__uuidof(IProcessLauncher2)),
+            L"{D106AB5F-A70E-400E-A21B-96208C1D8DBB}");
+#else
+  EXPECT_EQ(base::win::WStringFromGUID(__uuidof(GoogleUpdate3WebUserClass)),
+            L"{75828ED1-7BE8-45D0-8950-AA85CBF74510}");
+  EXPECT_EQ(base::win::WStringFromGUID(__uuidof(GoogleUpdate3WebSystemClass)),
+            L"{283209B7-C761-41CA-BE8D-B5321CD78FD6}");
+  EXPECT_EQ(base::win::WStringFromGUID(__uuidof(PolicyStatusUserClass)),
+            L"{4DAC24AB-B340-4B7E-AD01-1504A7F59EEA}");
+  EXPECT_EQ(base::win::WStringFromGUID(__uuidof(PolicyStatusSystemClass)),
+            L"{83FE19AC-72A6-4A72-B136-724444121586}");
+  EXPECT_EQ(base::win::WStringFromGUID(__uuidof(ProcessLauncherClass)),
+            L"{811A664F-703E-407C-A323-E6E31D1EFFA0}");
+  EXPECT_EQ(base::win::WStringFromGUID(__uuidof(ICurrentState)),
+            L"{BE5D3E90-A66C-4A0A-9B7B-1A6B9BF3971E}");
+  EXPECT_EQ(base::win::WStringFromGUID(__uuidof(IGoogleUpdate3Web)),
+            L"{027234BD-61BB-4F5C-9386-7FE804171C8C}");
+  EXPECT_EQ(base::win::WStringFromGUID(__uuidof(IAppBundleWeb)),
+            L"{D734C877-21F4-496E-B857-3E5B2E72E4CC}");
+  EXPECT_EQ(base::win::WStringFromGUID(__uuidof(IAppWeb)),
+            L"{2C6218B9-088D-4D25-A4F8-570558124142}");
+  EXPECT_EQ(base::win::WStringFromGUID(__uuidof(IAppCommandWeb)),
+            L"{87DBF75E-F590-4802-93FD-F8D07800E2E9}");
+  EXPECT_EQ(base::win::WStringFromGUID(__uuidof(IPolicyStatus)),
+            L"{7D908375-C9D0-44C5-BB98-206F3C24A74C}");
+  EXPECT_EQ(base::win::WStringFromGUID(__uuidof(IPolicyStatus2)),
+            L"{9D31EA63-2E06-4D41-98C7-CB1F307DB597}");
+  EXPECT_EQ(base::win::WStringFromGUID(__uuidof(IPolicyStatus3)),
+            L"{5C674FC1-80E3-48D2-987B-79D9D286065B}");
+  EXPECT_EQ(base::win::WStringFromGUID(__uuidof(IPolicyStatusValue)),
+            L"{47C8886A-A4B5-4F6C-865A-41A207074DFA}");
+  EXPECT_EQ(base::win::WStringFromGUID(__uuidof(IProcessLauncher)),
+            L"{EED70106-3604-4385-866E-6D540E99CA1A}");
+  EXPECT_EQ(base::win::WStringFromGUID(__uuidof(IProcessLauncher2)),
+            L"{BAEE6326-C925-4FA4-AFE9-5FA69902B021}");
+#endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING)
+}
+
 }  // namespace updater
diff --git a/chrome/updater/win/BUILD.gn b/chrome/updater/win/BUILD.gn
index db07c99..19e5a41b 100644
--- a/chrome/updater/win/BUILD.gn
+++ b/chrome/updater/win/BUILD.gn
@@ -32,6 +32,10 @@
     "updater.rc",
   ]
 
+  # `updater.rc` does not process `#if BUILDFLAG(GOOGLE_CHROME_BRANDING)`
+  # correctly sometimes, especially seen with the `win10_chromium_x64_rel_ng`
+  # build bot. Explicitly defining `CHROME_BRANDED_TLB` is being done here as a
+  # workaround.
   if (is_chrome_branded) {
     defines = [ "CHROME_BRANDED_TLB=1" ]
   } else {
diff --git a/chromecast/chromecast.gni b/chromecast/chromecast.gni
index e62efbc06..690a27d 100644
--- a/chromecast/chromecast.gni
+++ b/chromecast/chromecast.gni
@@ -18,6 +18,10 @@
   is_cast_desktop_build =
       target_os == "linux" && (target_cpu == "x86" || target_cpu == "x64") &&
       enable_cast_receiver
+
+  # chromecast_branding is used to include or exclude Google-branded components.
+  # Set it to "public" for a Chromium build.
+  chromecast_branding = "public"
 }
 
 declare_args() {
diff --git a/chromeos/ash/components/dbus/cros_disks/cros_disks_client.cc b/chromeos/ash/components/dbus/cros_disks/cros_disks_client.cc
index 5bed7e6..101ba39 100644
--- a/chromeos/ash/components/dbus/cros_disks/cros_disks_client.cc
+++ b/chromeos/ash/components/dbus/cros_disks/cros_disks_client.cc
@@ -85,51 +85,51 @@
     cros_disks::MountErrorType mount_error) {
   switch (mount_error) {
     case cros_disks::MOUNT_ERROR_NONE:
-      return MOUNT_ERROR_NONE;
+      return MountError::kNone;
     case cros_disks::MOUNT_ERROR_UNKNOWN:
-      return MOUNT_ERROR_UNKNOWN;
+      return MountError::kUnknown;
     case cros_disks::MOUNT_ERROR_INTERNAL:
-      return MOUNT_ERROR_INTERNAL;
+      return MountError::kInternal;
     case cros_disks::MOUNT_ERROR_INVALID_ARGUMENT:
-      return MOUNT_ERROR_INVALID_ARGUMENT;
+      return MountError::kInvalidArgument;
     case cros_disks::MOUNT_ERROR_INVALID_PATH:
-      return MOUNT_ERROR_INVALID_PATH;
+      return MountError::kInvalidPath;
     case cros_disks::MOUNT_ERROR_PATH_ALREADY_MOUNTED:
-      return MOUNT_ERROR_PATH_ALREADY_MOUNTED;
+      return MountError::kPathAlreadyMounted;
     case cros_disks::MOUNT_ERROR_PATH_NOT_MOUNTED:
-      return MOUNT_ERROR_PATH_NOT_MOUNTED;
+      return MountError::kPathNotMounted;
     case cros_disks::MOUNT_ERROR_DIRECTORY_CREATION_FAILED:
-      return MOUNT_ERROR_DIRECTORY_CREATION_FAILED;
+      return MountError::kDirectoryCreationFailed;
     case cros_disks::MOUNT_ERROR_INVALID_MOUNT_OPTIONS:
-      return MOUNT_ERROR_INVALID_MOUNT_OPTIONS;
+      return MountError::kInvalidMountOptions;
     case cros_disks::MOUNT_ERROR_INVALID_UNMOUNT_OPTIONS:
-      return MOUNT_ERROR_INVALID_UNMOUNT_OPTIONS;
+      return MountError::kInvalidUnmountOptions;
     case cros_disks::MOUNT_ERROR_INSUFFICIENT_PERMISSIONS:
-      return MOUNT_ERROR_INSUFFICIENT_PERMISSIONS;
+      return MountError::kInsufficientPermissions;
     case cros_disks::MOUNT_ERROR_MOUNT_PROGRAM_NOT_FOUND:
-      return MOUNT_ERROR_MOUNT_PROGRAM_NOT_FOUND;
+      return MountError::kMountProgramNotFound;
     case cros_disks::MOUNT_ERROR_MOUNT_PROGRAM_FAILED:
-      return MOUNT_ERROR_MOUNT_PROGRAM_FAILED;
+      return MountError::kMountProgramFailed;
     case cros_disks::MOUNT_ERROR_INVALID_DEVICE_PATH:
-      return MOUNT_ERROR_INVALID_DEVICE_PATH;
+      return MountError::kInvalidDevicePath;
     case cros_disks::MOUNT_ERROR_UNKNOWN_FILESYSTEM:
-      return MOUNT_ERROR_UNKNOWN_FILESYSTEM;
+      return MountError::kUnknownFilesystem;
     case cros_disks::MOUNT_ERROR_UNSUPPORTED_FILESYSTEM:
-      return MOUNT_ERROR_UNSUPPORTED_FILESYSTEM;
+      return MountError::kUnsupportedFilesystem;
     case cros_disks::MOUNT_ERROR_INVALID_ARCHIVE:
-      return MOUNT_ERROR_INVALID_ARCHIVE;
+      return MountError::kInvalidArchive;
     case cros_disks::MOUNT_ERROR_UNSUPPORTED_ARCHIVE:
       // TODO(amistry): Add MOUNT_ERROR_UNSUPPORTED_ARCHIVE.
-      return MOUNT_ERROR_UNKNOWN;
+      return MountError::kUnknown;
     case cros_disks::MOUNT_ERROR_NEED_PASSWORD:
-      return MOUNT_ERROR_NEED_PASSWORD;
+      return MountError::kNeedPassword;
     case cros_disks::MOUNT_ERROR_IN_PROGRESS:
-      return MOUNT_ERROR_IN_PROGRESS;
+      return MountError::kInProgress;
     case cros_disks::MOUNT_ERROR_CANCELLED:
-      return MOUNT_ERROR_CANCELLED;
+      return MountError::kCancelled;
     default:
       LOG(ERROR) << "Unrecognised mount error code " << mount_error;
-      return MOUNT_ERROR_UNKNOWN;
+      return MountError::kUnknown;
   }
 }
 
@@ -379,24 +379,24 @@
 
     const char kUnmountHistogramName[] = "CrosDisksClient.UnmountError";
     if (!response) {
-      UMA_HISTOGRAM_ENUMERATION(kUnmountHistogramName, MOUNT_ERROR_UNKNOWN,
-                                MOUNT_ERROR_COUNT);
-      std::move(callback).Run(MOUNT_ERROR_UNKNOWN);
+      UMA_HISTOGRAM_ENUMERATION(kUnmountHistogramName, MountError::kUnknown,
+                                MountError::kCount);
+      std::move(callback).Run(MountError::kUnknown);
       return;
     }
 
     dbus::MessageReader reader(response);
     uint32_t error_code = 0;
-    MountError mount_error = MOUNT_ERROR_NONE;
+    MountError mount_error = MountError::kNone;
     if (reader.PopUint32(&error_code)) {
       mount_error = CrosDisksMountErrorToChromeMountError(
           static_cast<cros_disks::MountErrorType>(error_code));
     } else {
       LOG(ERROR) << "Invalid response: " << response->ToString();
-      mount_error = MOUNT_ERROR_UNKNOWN;
+      mount_error = MountError::kUnknown;
     }
     UMA_HISTOGRAM_ENUMERATION(kUnmountHistogramName, mount_error,
-                              MOUNT_ERROR_COUNT);
+                              MountError::kCount);
     std::move(callback).Run(mount_error);
   }
 
@@ -489,15 +489,15 @@
     }
 
     UMA_HISTOGRAM_ENUMERATION("CrosDisksClient.MountCompletedError",
-                              entry.error_code(), MOUNT_ERROR_COUNT);
+                              entry.error_code(), MountError::kCount);
     // Flatten MountType and MountError into a single dimension.
     constexpr int kMaxMountErrors = 100;
-    static_assert(MOUNT_ERROR_COUNT <= kMaxMountErrors,
+    static_assert(static_cast<int>(MountError::kCount) <= kMaxMountErrors,
                   "CrosDisksClient.MountErrorMountType histogram must be "
                   "updated.");
     const int type_and_error =
         (static_cast<int>(entry.mount_type()) * kMaxMountErrors) +
-        entry.error_code();
+        static_cast<int>(entry.error_code());
     base::UmaHistogramSparse("CrosDisksClient.MountErrorMountType",
                              type_and_error);
     for (auto& observer : observer_list_)
@@ -584,39 +584,45 @@
 };
 
 }  // namespace
+}  // namespace chromeos
+
+namespace ash {
 
 std::ostream& operator<<(std::ostream& out, const MountError error) {
   switch (error) {
 #define PRINT_ERROR(s) \
   case s:              \
     return out << #s;
-    PRINT_ERROR(MOUNT_ERROR_NONE)
-    PRINT_ERROR(MOUNT_ERROR_UNKNOWN)
-    PRINT_ERROR(MOUNT_ERROR_INTERNAL)
-    PRINT_ERROR(MOUNT_ERROR_INVALID_ARGUMENT)
-    PRINT_ERROR(MOUNT_ERROR_INVALID_PATH)
-    PRINT_ERROR(MOUNT_ERROR_PATH_ALREADY_MOUNTED)
-    PRINT_ERROR(MOUNT_ERROR_PATH_NOT_MOUNTED)
-    PRINT_ERROR(MOUNT_ERROR_DIRECTORY_CREATION_FAILED)
-    PRINT_ERROR(MOUNT_ERROR_INVALID_MOUNT_OPTIONS)
-    PRINT_ERROR(MOUNT_ERROR_INVALID_UNMOUNT_OPTIONS)
-    PRINT_ERROR(MOUNT_ERROR_INSUFFICIENT_PERMISSIONS)
-    PRINT_ERROR(MOUNT_ERROR_MOUNT_PROGRAM_NOT_FOUND)
-    PRINT_ERROR(MOUNT_ERROR_MOUNT_PROGRAM_FAILED)
-    PRINT_ERROR(MOUNT_ERROR_INVALID_DEVICE_PATH)
-    PRINT_ERROR(MOUNT_ERROR_UNKNOWN_FILESYSTEM)
-    PRINT_ERROR(MOUNT_ERROR_UNSUPPORTED_FILESYSTEM)
-    PRINT_ERROR(MOUNT_ERROR_INVALID_ARCHIVE)
-    PRINT_ERROR(MOUNT_ERROR_NEED_PASSWORD)
-    PRINT_ERROR(MOUNT_ERROR_IN_PROGRESS)
-    PRINT_ERROR(MOUNT_ERROR_CANCELLED)
-    PRINT_ERROR(MOUNT_ERROR_COUNT)
+    PRINT_ERROR(MountError::kNone)
+    PRINT_ERROR(MountError::kUnknown)
+    PRINT_ERROR(MountError::kInternal)
+    PRINT_ERROR(MountError::kInvalidArgument)
+    PRINT_ERROR(MountError::kInvalidPath)
+    PRINT_ERROR(MountError::kPathAlreadyMounted)
+    PRINT_ERROR(MountError::kPathNotMounted)
+    PRINT_ERROR(MountError::kDirectoryCreationFailed)
+    PRINT_ERROR(MountError::kInvalidMountOptions)
+    PRINT_ERROR(MountError::kInvalidUnmountOptions)
+    PRINT_ERROR(MountError::kInsufficientPermissions)
+    PRINT_ERROR(MountError::kMountProgramNotFound)
+    PRINT_ERROR(MountError::kMountProgramFailed)
+    PRINT_ERROR(MountError::kInvalidDevicePath)
+    PRINT_ERROR(MountError::kUnknownFilesystem)
+    PRINT_ERROR(MountError::kUnsupportedFilesystem)
+    PRINT_ERROR(MountError::kInvalidArchive)
+    PRINT_ERROR(MountError::kNeedPassword)
+    PRINT_ERROR(MountError::kInProgress)
+    PRINT_ERROR(MountError::kCancelled)
+    PRINT_ERROR(MountError::kCount)
 #undef PRINT_ERROR
   }
 
   return out << "MOUNT_ERROR_" << std::underlying_type_t<MountError>(error);
 }
 
+}  // namespace ash
+
+namespace chromeos {
 ////////////////////////////////////////////////////////////////////////////////
 // DiskInfo
 
diff --git a/chromeos/ash/components/dbus/cros_disks/cros_disks_client.h b/chromeos/ash/components/dbus/cros_disks/cros_disks_client.h
index 8143ac3..2066b8f 100644
--- a/chromeos/ash/components/dbus/cros_disks/cros_disks_client.h
+++ b/chromeos/ash/components/dbus/cros_disks/cros_disks_client.h
@@ -50,46 +50,47 @@
   kDVD,          // DVD.
 };
 
+// Mount error code used by cros-disks.
+// These values are NOT the same as cros_disks::MountErrorType.
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused.
+enum class MountError {
+  kNone = 0,
+  kUnknown = 1,
+  kInternal = 2,
+  kInvalidArgument = 3,
+  kInvalidPath = 4,
+  kPathAlreadyMounted = 5,
+  kPathNotMounted = 6,
+  kDirectoryCreationFailed = 7,
+  kInvalidMountOptions = 8,
+  kInvalidUnmountOptions = 9,
+  kInsufficientPermissions = 10,
+  kMountProgramNotFound = 11,
+  kMountProgramFailed = 12,
+  kInvalidDevicePath = 13,
+  kUnknownFilesystem = 14,
+  kUnsupportedFilesystem = 15,
+  kInvalidArchive = 16,
+  kNeedPassword = 17,
+  kInProgress = 18,
+  kCancelled = 19,
+  kCount,
+};
+
+// Output operator for logging.
+COMPONENT_EXPORT(ASH_DBUS_CROS_DISKS)
+std::ostream& operator<<(std::ostream& out, MountError error);
+
 }  // namespace ash
 
 namespace chromeos {
 
 // TODO(https://crbug.com/1164001): remove when the migration is finished.
 using ::ash::DeviceType;
+using ::ash::MountError;
 using ::ash::MountType;
 
-// Mount error code used by cros-disks.
-// These values are NOT the same as cros_disks::MountErrorType.
-// These values are persisted to logs. Entries should not be renumbered and
-// numeric values should never be reused.
-enum MountError {
-  MOUNT_ERROR_NONE = 0,
-  MOUNT_ERROR_UNKNOWN = 1,
-  MOUNT_ERROR_INTERNAL = 2,
-  MOUNT_ERROR_INVALID_ARGUMENT = 3,
-  MOUNT_ERROR_INVALID_PATH = 4,
-  MOUNT_ERROR_PATH_ALREADY_MOUNTED = 5,
-  MOUNT_ERROR_PATH_NOT_MOUNTED = 6,
-  MOUNT_ERROR_DIRECTORY_CREATION_FAILED = 7,
-  MOUNT_ERROR_INVALID_MOUNT_OPTIONS = 8,
-  MOUNT_ERROR_INVALID_UNMOUNT_OPTIONS = 9,
-  MOUNT_ERROR_INSUFFICIENT_PERMISSIONS = 10,
-  MOUNT_ERROR_MOUNT_PROGRAM_NOT_FOUND = 11,
-  MOUNT_ERROR_MOUNT_PROGRAM_FAILED = 12,
-  MOUNT_ERROR_INVALID_DEVICE_PATH = 13,
-  MOUNT_ERROR_UNKNOWN_FILESYSTEM = 14,
-  MOUNT_ERROR_UNSUPPORTED_FILESYSTEM = 15,
-  MOUNT_ERROR_INVALID_ARCHIVE = 16,
-  MOUNT_ERROR_NEED_PASSWORD = 17,
-  MOUNT_ERROR_IN_PROGRESS = 18,
-  MOUNT_ERROR_CANCELLED = 19,
-  MOUNT_ERROR_COUNT,
-};
-
-// Output operator for logging.
-COMPONENT_EXPORT(ASH_DBUS_CROS_DISKS)
-std::ostream& operator<<(std::ostream& out, MountError error);
-
 // Rename error reported by cros-disks.
 enum RenameError {
   RENAME_ERROR_NONE,
@@ -156,11 +157,11 @@
 enum RemountOption {
   // Mount a new device. If the device is already mounted, the mount status is
   // unchanged and the callback for MountCompleted will receive
-  // MOUNT_ERROR_PATH_ALREADY_MOUNTED error code.
+  // MountError::kPathAlreadyMounted error code.
   REMOUNT_OPTION_MOUNT_NEW_DEVICE,
   // Remount a device that is already mounted. If the device is not mounted
   // yet, it will do nothing and the callback for MountCompleted will receive
-  // MOUNT_ERROR_PATH_NOT_MOUNTED error code.
+  // MountError::kPathNotMounted error code.
   REMOUNT_OPTION_REMOUNT_EXISTING_DEVICE,
 };
 
@@ -279,7 +280,7 @@
 struct COMPONENT_EXPORT(ASH_DBUS_CROS_DISKS) MountEntry {
  public:
   MountEntry()
-      : error_code_(MOUNT_ERROR_UNKNOWN), mount_type_(MountType::kInvalid) {}
+      : error_code_(MountError::kUnknown), mount_type_(MountType::kInvalid) {}
 
   MountEntry(MountError error_code,
              const std::string& source_path,
@@ -463,18 +464,8 @@
 using ::chromeos::FormatError;
 using ::chromeos::MOUNT_ACCESS_MODE_READ_ONLY;
 using ::chromeos::MOUNT_ACCESS_MODE_READ_WRITE;
-using ::chromeos::MOUNT_ERROR_INTERNAL;
-using ::chromeos::MOUNT_ERROR_INVALID_DEVICE_PATH;
-using ::chromeos::MOUNT_ERROR_INVALID_PATH;
-using ::chromeos::MOUNT_ERROR_NONE;
-using ::chromeos::MOUNT_ERROR_PATH_ALREADY_MOUNTED;
-using ::chromeos::MOUNT_ERROR_PATH_NOT_MOUNTED;
-using ::chromeos::MOUNT_ERROR_UNKNOWN;
-using ::chromeos::MOUNT_ERROR_UNKNOWN_FILESYSTEM;
-using ::chromeos::MOUNT_ERROR_UNSUPPORTED_FILESYSTEM;
 using ::chromeos::MountAccessMode;
 using ::chromeos::MountEntry;
-using ::chromeos::MountError;
 using ::chromeos::MountEventType;
 using ::chromeos::PARTITION_ERROR_INVALID_DEVICE_PATH;
 using ::chromeos::PARTITION_ERROR_NONE;
diff --git a/chromeos/ash/components/dbus/cros_disks/fake_cros_disks_client.cc b/chromeos/ash/components/dbus/cros_disks/fake_cros_disks_client.cc
index 6d40245..67a771c 100644
--- a/chromeos/ash/components/dbus/cros_disks/fake_cros_disks_client.cc
+++ b/chromeos/ash/components/dbus/cros_disks/fake_cros_disks_client.cc
@@ -24,18 +24,18 @@
                             const base::FilePath& mounted_path,
                             MountType type) {
   if (mounted_path.empty())
-    return MOUNT_ERROR_INVALID_ARGUMENT;
+    return MountError::kInvalidArgument;
 
   // Just create an empty directory and shows it as the mounted directory.
   if (!base::CreateDirectory(mounted_path)) {
     DLOG(ERROR) << "Failed to create directory at " << mounted_path.value();
-    return MOUNT_ERROR_DIRECTORY_CREATION_FAILED;
+    return MountError::kDirectoryCreationFailed;
   }
 
   // Fake network mounts are responsible for populating their mount paths so
   // don't need a dummy file.
   if (type == MountType::kNetworkStorage)
-    return MOUNT_ERROR_NONE;
+    return MountError::kNone;
 
   // Put a dummy file.
   const base::FilePath dummy_file_path =
@@ -45,10 +45,10 @@
       dummy_file_path, dummy_file_content.data(), dummy_file_content.size());
   if (write_result != static_cast<int>(dummy_file_content.size())) {
     DLOG(ERROR) << "Failed to put a dummy file at " << dummy_file_path.value();
-    return MOUNT_ERROR_MOUNT_PROGRAM_FAILED;
+    return MountError::kMountProgramFailed;
   }
 
-  return MOUNT_ERROR_NONE;
+  return MountError::kNone;
 }
 
 }  // namespace
diff --git a/chromeos/ash/components/dbus/cros_disks/fake_cros_disks_client.h b/chromeos/ash/components/dbus/cros_disks/fake_cros_disks_client.h
index 43491fd..e6891f4 100644
--- a/chromeos/ash/components/dbus/cros_disks/fake_cros_disks_client.h
+++ b/chromeos/ash/components/dbus/cros_disks/fake_cros_disks_client.h
@@ -177,7 +177,7 @@
   base::ObserverList<Observer> observer_list_;
   int unmount_call_count_ = 0;
   std::string last_unmount_device_path_;
-  MountError unmount_error_ = MOUNT_ERROR_NONE;
+  MountError unmount_error_ = MountError::kNone;
   base::RepeatingClosure unmount_listener_;
   int format_call_count_ = 0;
   std::string last_format_device_path_;
diff --git a/chromeos/ash/components/oobe_quick_start/connectivity/fast_pair_advertiser.cc b/chromeos/ash/components/oobe_quick_start/connectivity/fast_pair_advertiser.cc
index 33f56164..52667318 100644
--- a/chromeos/ash/components/oobe_quick_start/connectivity/fast_pair_advertiser.cc
+++ b/chromeos/ash/components/oobe_quick_start/connectivity/fast_pair_advertiser.cc
@@ -58,10 +58,12 @@
 
 void FastPairAdvertiser::StartAdvertising(
     base::OnceCallback<void()> callback,
-    base::OnceCallback<void()> error_callback) {
+    base::OnceCallback<void()> error_callback,
+    const base::UnguessableToken& random_session_id) {
   DCHECK(adapter_->IsPresent() && adapter_->IsPowered());
   DCHECK(!advertisement_);
-  RegisterAdvertisement(std::move(callback), std::move(error_callback));
+  RegisterAdvertisement(std::move(callback), std::move(error_callback),
+                        random_session_id);
 }
 
 void FastPairAdvertiser::StopAdvertising(base::OnceCallback<void()> callback) {
@@ -76,7 +78,8 @@
 
 void FastPairAdvertiser::RegisterAdvertisement(
     base::OnceClosure callback,
-    base::OnceClosure error_callback) {
+    base::OnceClosure error_callback,
+    const base::UnguessableToken& random_session_id) {
   auto advertisement_data =
       std::make_unique<device::BluetoothAdvertisement::Data>(
           device::BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST);
@@ -95,7 +98,8 @@
 
   auto manufacturer_data =
       std::make_unique<device::BluetoothAdvertisement::ManufacturerData>();
-  auto manufacturer_metadata = GenerateManufacturerMetadata();
+  std::vector<uint8_t> manufacturer_metadata =
+      GenerateManufacturerMetadata(random_session_id);
   manufacturer_data->insert(std::pair<uint16_t, std::vector<uint8_t>>(
       kCompanyId, manufacturer_metadata));
   advertisement_data->set_manufacturer_data(std::move(manufacturer_data));
@@ -151,15 +155,9 @@
   // |this| might be destroyed here, do not access local fields.
 }
 
-std::vector<uint8_t> FastPairAdvertiser::GenerateManufacturerMetadata() {
-  // TODO(b/235403498): This code may need to be updated later to be derived
-  // from the device BT address. It is not required in order for the
-  // advertisement to trigger the Fast Pair halfsheet.
-  auto token = base::UnguessableToken::Create();
-  base::span<const uint8_t> fast_pair_code = token.AsBytes().first(2);
-
-  std::vector<uint8_t> metadata(std::begin(fast_pair_code),
-                                std::end(fast_pair_code));
-
+std::vector<uint8_t> FastPairAdvertiser::GenerateManufacturerMetadata(
+    const base::UnguessableToken& random_session_id) {
+  base::span<const uint8_t, 16> id = random_session_id.AsBytes();
+  std::vector<uint8_t> metadata(std::begin(id), std::end(id));
   return metadata;
 }
\ No newline at end of file
diff --git a/chromeos/ash/components/oobe_quick_start/connectivity/fast_pair_advertiser.h b/chromeos/ash/components/oobe_quick_start/connectivity/fast_pair_advertiser.h
index 85b7284..149857f6 100644
--- a/chromeos/ash/components/oobe_quick_start/connectivity/fast_pair_advertiser.h
+++ b/chromeos/ash/components/oobe_quick_start/connectivity/fast_pair_advertiser.h
@@ -10,6 +10,7 @@
 
 #include "base/callback.h"
 #include "base/memory/weak_ptr.h"
+#include "base/unguessable_token.h"
 #include "device/bluetooth/bluetooth_adapter.h"
 #include "device/bluetooth/bluetooth_advertisement.h"
 
@@ -44,19 +45,24 @@
   FastPairAdvertiser& operator=(const FastPairAdvertiser&) = delete;
 
   // Begin broadcasting Fast Pair advertisement.
-  virtual void StartAdvertising(base::OnceClosure callback,
-                                base::OnceClosure error_callback);
+  virtual void StartAdvertising(
+      base::OnceClosure callback,
+      base::OnceClosure error_callback,
+      const base::UnguessableToken& random_session_id);
 
   // Stop broadcasting Fast Pair advertisement.
   virtual void StopAdvertising(base::OnceClosure callback);
 
  private:
+  friend class FastPairAdvertiserTest;
+
   // device::BluetoothAdvertisement::Observer:
   void AdvertisementReleased(
       device::BluetoothAdvertisement* advertisement) override;
 
   void RegisterAdvertisement(base::OnceClosure callback,
-                             base::OnceClosure error_callback);
+                             base::OnceClosure error_callback,
+                             const base::UnguessableToken& random_session_id);
   void OnRegisterAdvertisement(
       base::OnceClosure callback,
       scoped_refptr<device::BluetoothAdvertisement> advertisement);
@@ -68,8 +74,9 @@
   void OnUnregisterAdvertisementError(
       device::BluetoothAdvertisement::ErrorCode error_code);
 
-  // Returns metadata in format [ fast_pair_code (2 bytes) ].
-  std::vector<uint8_t> GenerateManufacturerMetadata();
+  // Returns metadata in format [ random_session_id (16 bytes) ].
+  std::vector<uint8_t> GenerateManufacturerMetadata(
+      const base::UnguessableToken& random_session_id);
 
   scoped_refptr<device::BluetoothAdapter> adapter_;
   scoped_refptr<device::BluetoothAdvertisement> advertisement_;
diff --git a/chromeos/ash/components/oobe_quick_start/connectivity/fast_pair_advertiser_unittest.cc b/chromeos/ash/components/oobe_quick_start/connectivity/fast_pair_advertiser_unittest.cc
index 24caa61..5aa987a 100644
--- a/chromeos/ash/components/oobe_quick_start/connectivity/fast_pair_advertiser_unittest.cc
+++ b/chromeos/ash/components/oobe_quick_start/connectivity/fast_pair_advertiser_unittest.cc
@@ -14,6 +14,7 @@
 #include "base/test/bind.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/time/time.h"
+#include "base/unguessable_token.h"
 #include "device/bluetooth/test/mock_bluetooth_adapter.h"
 #include "device/bluetooth/test/mock_bluetooth_advertisement.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -160,7 +161,8 @@
         base::BindOnce(&FastPairAdvertiserTest::OnStartAdvertising,
                        base::Unretained(this)),
         base::BindOnce(&FastPairAdvertiserTest::OnStartAdvertisingError,
-                       base::Unretained(this)));
+                       base::Unretained(this)),
+        base::UnguessableToken::Create());
     auto service_uuid_list =
         std::make_unique<device::BluetoothAdvertisement::UUIDList>();
     service_uuid_list->push_back(kFastPairServiceUuid);
@@ -189,6 +191,11 @@
   }
   bool called_on_stop_advertising() { return called_on_stop_advertising_; }
 
+  std::vector<uint8_t> GetManufacturerMetadata(
+      const base::UnguessableToken& random_id) {
+    return fast_pair_advertiser_->GenerateManufacturerMetadata(random_id);
+  }
+
   scoped_refptr<NiceMock<MockBluetoothAdapterWithAdvertisements>> mock_adapter_;
   std::unique_ptr<FastPairAdvertiser> fast_pair_advertiser_;
   std::unique_ptr<RegisterAdvertisementArgs> register_args_;
@@ -228,7 +235,8 @@
 TEST_F(FastPairAdvertiserTest, TestStartAdvertising_DeleteInErrorCallback) {
   fast_pair_advertiser_->StartAdvertising(
       base::DoNothing(),
-      base::BindLambdaForTesting([&]() { fast_pair_advertiser_.reset(); }));
+      base::BindLambdaForTesting([&]() { fast_pair_advertiser_.reset(); }),
+      base::UnguessableToken::Create());
 
   std::move(register_args_->error_callback)
       .Run(device::BluetoothAdvertisement::ErrorCode::
@@ -281,4 +289,16 @@
   EXPECT_FALSE(called_on_start_advertising_error());
   EXPECT_FALSE(called_on_stop_advertising());
   EXPECT_FALSE(fake_advertisement->HasObserver(fast_pair_advertiser_.get()));
+}
+
+TEST_F(FastPairAdvertiserTest, TestGenerateManufacturerMetadata) {
+  auto random_id = base::UnguessableToken::Create();
+  base::span<const uint8_t, 16> random_id_bytes = random_id.AsBytes();
+  std::vector<uint8_t> manufacturer_metadata =
+      GetManufacturerMetadata(random_id);
+
+  EXPECT_EQ(random_id_bytes.size(), manufacturer_metadata.size());
+  for (int i = 0; i < 16; i++) {
+    EXPECT_EQ(random_id_bytes[i], manufacturer_metadata[i]);
+  }
 }
\ No newline at end of file
diff --git a/chromeos/ash/components/oobe_quick_start/connectivity/target_device_connection_broker_impl.cc b/chromeos/ash/components/oobe_quick_start/connectivity/target_device_connection_broker_impl.cc
index 034b978d..ddf73bc 100644
--- a/chromeos/ash/components/oobe_quick_start/connectivity/target_device_connection_broker_impl.cc
+++ b/chromeos/ash/components/oobe_quick_start/connectivity/target_device_connection_broker_impl.cc
@@ -73,6 +73,10 @@
     return;
   }
 
+  if (!random_session_id_) {
+    random_session_id_ = base::UnguessableToken::Create();
+  }
+
   fast_pair_advertiser_ =
       FastPairAdvertiser::Factory::Create(bluetooth_adapter_);
   auto [success_callback, failure_callback] =
@@ -82,7 +86,8 @@
       base::BindOnce(std::move(success_callback), /*success=*/true),
       base::BindOnce(
           &TargetDeviceConnectionBrokerImpl::OnStartFastPairAdvertisingError,
-          weak_ptr_factory_.GetWeakPtr(), std::move(failure_callback)));
+          weak_ptr_factory_.GetWeakPtr(), std::move(failure_callback)),
+      random_session_id_);
 }
 
 void TargetDeviceConnectionBrokerImpl::OnStartFastPairAdvertisingError(
diff --git a/chromeos/ash/components/oobe_quick_start/connectivity/target_device_connection_broker_impl.h b/chromeos/ash/components/oobe_quick_start/connectivity/target_device_connection_broker_impl.h
index d7f5e541..01e2b91 100644
--- a/chromeos/ash/components/oobe_quick_start/connectivity/target_device_connection_broker_impl.h
+++ b/chromeos/ash/components/oobe_quick_start/connectivity/target_device_connection_broker_impl.h
@@ -6,6 +6,7 @@
 #define CHROMEOS_ASH_COMPONENTS_OOBE_QUICK_START_CONNECTIVITY_TARGET_DEVICE_CONNECTION_BROKER_IMPL_H_
 
 #include "base/memory/weak_ptr.h"
+#include "base/unguessable_token.h"
 #include "chromeos/ash/components/oobe_quick_start/connectivity/target_device_connection_broker.h"
 
 class FastPairAdvertiser;
@@ -43,6 +44,7 @@
   scoped_refptr<device::BluetoothAdapter> bluetooth_adapter_;
 
   std::unique_ptr<FastPairAdvertiser> fast_pair_advertiser_;
+  base::UnguessableToken random_session_id_;
 
   base::WeakPtrFactory<TargetDeviceConnectionBrokerImpl> weak_ptr_factory_{
       this};
diff --git a/chromeos/ash/components/oobe_quick_start/connectivity/target_device_connection_broker_impl_unittest.cc b/chromeos/ash/components/oobe_quick_start/connectivity/target_device_connection_broker_impl_unittest.cc
index 69d9eba..e996b2d 100644
--- a/chromeos/ash/components/oobe_quick_start/connectivity/target_device_connection_broker_impl_unittest.cc
+++ b/chromeos/ash/components/oobe_quick_start/connectivity/target_device_connection_broker_impl_unittest.cc
@@ -39,8 +39,10 @@
     std::move(on_destroy_callback_).Run();
   }
 
-  void StartAdvertising(base::OnceCallback<void()> callback,
-                        base::OnceCallback<void()> error_callback) override {
+  void StartAdvertising(
+      base::OnceCallback<void()> callback,
+      base::OnceCallback<void()> error_callback,
+      const base::UnguessableToken& random_session_id) override {
     ++start_advertising_call_count_;
     if (should_succeed_on_start_)
       std::move(callback).Run();
diff --git a/chromeos/crosapi/mojom/app_service_types_mojom_traits.cc b/chromeos/crosapi/mojom/app_service_types_mojom_traits.cc
index b815fe1..e78b03e 100644
--- a/chromeos/crosapi/mojom/app_service_types_mojom_traits.cc
+++ b/chromeos/crosapi/mojom/app_service_types_mojom_traits.cc
@@ -609,8 +609,6 @@
 EnumTraits<crosapi::mojom::PatternMatchType, apps::PatternMatchType>::ToMojom(
     apps::PatternMatchType input) {
   switch (input) {
-    case apps::PatternMatchType::kNone:
-      return crosapi::mojom::PatternMatchType::kNone;
     case apps::PatternMatchType::kLiteral:
       return crosapi::mojom::PatternMatchType::kLiteral;
     case apps::PatternMatchType::kPrefix:
@@ -635,8 +633,6 @@
               apps::PatternMatchType* output) {
   switch (input) {
     case crosapi::mojom::PatternMatchType::kNone:
-      *output = apps::PatternMatchType::kNone;
-      return true;
     case crosapi::mojom::PatternMatchType::kLiteral:
       *output = apps::PatternMatchType::kLiteral;
       return true;
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 8635c426..6cb8298 100644
--- a/chromeos/crosapi/mojom/app_service_types_mojom_traits_unittest.cc
+++ b/chromeos/crosapi/mojom/app_service_types_mojom_traits_unittest.cc
@@ -48,7 +48,7 @@
 
   auto intent_filter = std::make_unique<apps::IntentFilter>();
   intent_filter->AddSingleValueCondition(apps::ConditionType::kScheme, "https",
-                                         apps::PatternMatchType::kNone);
+                                         apps::PatternMatchType::kLiteral);
   intent_filter->activity_name = "activity_name";
   intent_filter->activity_label = "activity_label";
   input->intent_filters.push_back(std::move(intent_filter));
@@ -107,7 +107,7 @@
   ASSERT_EQ(condition->condition_values.size(), 1U);
   EXPECT_EQ(condition->condition_values[0]->value, "https");
   EXPECT_EQ(condition->condition_values[0]->match_type,
-            apps::PatternMatchType::kNone);
+            apps::PatternMatchType::kLiteral);
   EXPECT_EQ(filter->activity_name, "activity_name");
   EXPECT_EQ(filter->activity_label, "activity_label");
 
@@ -151,7 +151,7 @@
 
   auto intent_filter = std::make_unique<apps::IntentFilter>();
   intent_filter->AddSingleValueCondition(apps::ConditionType::kScheme, "https",
-                                         apps::PatternMatchType::kNone);
+                                         apps::PatternMatchType::kLiteral);
   input->intent_filters.push_back(std::move(intent_filter));
   input->window_mode = apps::WindowMode::kBrowser;
   input->allow_uninstall = true;
@@ -186,7 +186,7 @@
   ASSERT_EQ(condition->condition_values.size(), 1U);
   EXPECT_EQ(condition->condition_values[0]->value, "https");
   EXPECT_EQ(condition->condition_values[0]->match_type,
-            apps::PatternMatchType::kNone);
+            apps::PatternMatchType::kLiteral);
 
   EXPECT_EQ(output->window_mode, apps::WindowMode::kBrowser);
   EXPECT_TRUE(output->allow_uninstall);
@@ -575,7 +575,7 @@
   auto input = std::make_unique<apps::App>(apps::AppType::kArc, "abcdefg");
   auto intent_filter = std::make_unique<apps::IntentFilter>();
   intent_filter->AddSingleValueCondition(apps::ConditionType::kScheme, "1",
-                                         apps::PatternMatchType::kNone);
+                                         apps::PatternMatchType::kLiteral);
   intent_filter->AddSingleValueCondition(apps::ConditionType::kHost, "2",
                                          apps::PatternMatchType::kLiteral);
   intent_filter->AddSingleValueCondition(apps::ConditionType::kPath, "3",
@@ -604,7 +604,7 @@
     EXPECT_EQ(condition->condition_type, apps::ConditionType::kScheme);
     ASSERT_EQ(condition->condition_values.size(), 1U);
     EXPECT_EQ(condition->condition_values[0]->match_type,
-              apps::PatternMatchType::kNone);
+              apps::PatternMatchType::kLiteral);
     EXPECT_EQ(condition->condition_values[0]->value, "1");
   }
   {
@@ -1118,7 +1118,7 @@
 TEST(AppServiceTypesMojomTraitsTest, PreferredApp) {
   auto intent_filter = std::make_unique<apps::IntentFilter>();
   intent_filter->AddSingleValueCondition(apps::ConditionType::kScheme, "1",
-                                         apps::PatternMatchType::kNone);
+                                         apps::PatternMatchType::kLiteral);
   auto input =
       std::make_unique<apps::PreferredApp>(std::move(intent_filter), "abcdefg");
 
@@ -1134,7 +1134,7 @@
   apps::IntentFilters added_filters;
   auto intent_filter1 = std::make_unique<apps::IntentFilter>();
   intent_filter1->AddSingleValueCondition(apps::ConditionType::kScheme, "1",
-                                          apps::PatternMatchType::kNone);
+                                          apps::PatternMatchType::kLiteral);
   auto intent_filter2 = std::make_unique<apps::IntentFilter>();
   intent_filter2->AddSingleValueCondition(apps::ConditionType::kHost, "2",
                                           apps::PatternMatchType::kLiteral);
diff --git a/chromeos/dbus/missive/missive_client_test_observer.h b/chromeos/dbus/missive/missive_client_test_observer.h
index 14824a10..12a1035 100644
--- a/chromeos/dbus/missive/missive_client_test_observer.h
+++ b/chromeos/dbus/missive/missive_client_test_observer.h
@@ -34,13 +34,16 @@
   void OnRecordEnqueued(::reporting::Priority priority,
                         const ::reporting::Record& record) override;
 
-  // Wait for next |::reporting::Record| to be enqueued and return it along with
-  // the corresponding |::reporting::Priority|.
+  // Wait for next |::reporting::Record| to be enqueued, remove it, and return
+  // it along with the corresponding |::reporting::Priority|. Returns
+  // immediately if a record is present in the queue. Times out if a
+  // record does not arrive after a period of time.
   std::tuple<::reporting::Priority, ::reporting::Record>
   GetNextEnqueuedRecord();
 
-  // Return true if there is no new enqueued records that was not consumed by
-  // |GetNextEnqueuedRecord()|.
+  // Returns true immediately if there any records in the queue. Return false
+  // otherwise. Does not wait for new records to arrive. Intended to be called
+  // after GetNextEnqueuedRecord().
   bool HasNewEnqueuedRecords();
 
  private:
diff --git a/chromeos/ui/base/chromeos_ui_constants.h b/chromeos/ui/base/chromeos_ui_constants.h
index 510bfac..e77936d 100644
--- a/chromeos/ui/base/chromeos_ui_constants.h
+++ b/chromeos/ui/base/chromeos_ui_constants.h
@@ -14,6 +14,9 @@
 // Radius of the header's top corners when the window is restored.
 constexpr int kTopCornerRadiusWhenRestored = 2;
 
+// Rounded corner radius for Pip window.
+constexpr int kPipRoundedCornerRadius = 8;
+
 // In the window corners, the resize areas don't actually expand bigger, but the
 // 16 px at the end of each edge triggers diagonal resizing.
 constexpr int kResizeAreaCornerSize = 16;
diff --git a/chromeos/ui/frame/highlight_border_overlay.cc b/chromeos/ui/frame/highlight_border_overlay.cc
index c20e3b0..2a692a8 100644
--- a/chromeos/ui/frame/highlight_border_overlay.cc
+++ b/chromeos/ui/frame/highlight_border_overlay.cc
@@ -37,6 +37,9 @@
 };
 
 int GetRoundedCornerRadius(chromeos::WindowStateType type) {
+  if (type == chromeos::WindowStateType::kPip)
+    return chromeos::kPipRoundedCornerRadius;
+
   return IsNormalWindowStateType(type) ? chromeos::kTopCornerRadiusWhenRestored
                                        : 0;
 }
diff --git a/components/account_manager_core/DEPS b/components/account_manager_core/DEPS
index 4761c276..646bdde 100644
--- a/components/account_manager_core/DEPS
+++ b/components/account_manager_core/DEPS
@@ -1,5 +1,4 @@
 include_rules = [
-  "+absl/types/optional.h",
   "+chromeos/crosapi/mojom/account_manager.mojom.h",
   "+chromeos/lacros",
   "+components/prefs",
diff --git a/components/account_manager_core/account_manager_util.cc b/components/account_manager_core/account_manager_util.cc
index 550d7bc..f2f18aec 100644
--- a/components/account_manager_core/account_manager_util.cc
+++ b/components/account_manager_core/account_manager_util.cc
@@ -4,11 +4,11 @@
 
 #include "components/account_manager_core/account_manager_util.h"
 
-#include "absl/types/optional.h"
 #include "components/account_manager_core/account.h"
 #include "components/account_manager_core/account_addition_options.h"
 #include "components/account_manager_core/account_addition_result.h"
 #include "google_apis/gaia/google_service_auth_error.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace account_manager {
 
diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc
index c52e078..7fc84dd 100644
--- a/components/autofill/core/browser/personal_data_manager.cc
+++ b/components/autofill/core/browser/personal_data_manager.cc
@@ -775,6 +775,9 @@
 }
 
 void PersonalDataManager::AddIBAN(const IBAN& iban) {
+  if (!IsAutofillIBANEnabled())
+    return;
+
   if (is_off_the_record_ || FindByGUID(local_ibans_, iban.guid()) ||
       !database_helper_->GetLocalDatabase() ||
       FindByContents(local_ibans_, iban)) {
@@ -1424,7 +1427,8 @@
 }
 
 bool PersonalDataManager::IsAutofillEnabled() const {
-  return IsAutofillProfileEnabled() || IsAutofillCreditCardEnabled();
+  return IsAutofillProfileEnabled() || IsAutofillCreditCardEnabled() ||
+         IsAutofillIBANEnabled();
 }
 
 bool PersonalDataManager::IsAutofillProfileEnabled() const {
@@ -1435,6 +1439,10 @@
   return prefs::IsAutofillCreditCardEnabled(pref_service_);
 }
 
+bool PersonalDataManager::IsAutofillIBANEnabled() const {
+  return prefs::IsAutofillIBANEnabled(pref_service_);
+}
+
 bool PersonalDataManager::IsAutofillWalletImportEnabled() const {
   return prefs::IsPaymentsIntegrationEnabled(pref_service_);
 }
diff --git a/components/autofill/core/browser/personal_data_manager.h b/components/autofill/core/browser/personal_data_manager.h
index 245f1224..27295af 100644
--- a/components/autofill/core/browser/personal_data_manager.h
+++ b/components/autofill/core/browser/personal_data_manager.h
@@ -448,8 +448,8 @@
   // Returns the value of the AutofillCreditCardEnabled pref.
   virtual bool IsAutofillCreditCardEnabled() const;
 
-  // TODO(crbug.com/1340310): Add IsAutofillIbanEnabled after adding
-  // kAutofillIbanEnabled which is related to Enterprise prefs.
+  // Returns the value of the AutofillIBANEnabled pref.
+  virtual bool IsAutofillIBANEnabled() const;
 
   // Returns the value of the AutofillWalletImportEnabled pref.
   virtual bool IsAutofillWalletImportEnabled() const;
diff --git a/components/autofill/core/browser/personal_data_manager_unittest.cc b/components/autofill/core/browser/personal_data_manager_unittest.cc
index f783d7e..e3da8915 100644
--- a/components/autofill/core/browser/personal_data_manager_unittest.cc
+++ b/components/autofill/core/browser/personal_data_manager_unittest.cc
@@ -999,7 +999,24 @@
   ExpectSameElements(profiles, personal_data_->GetProfiles());
 }
 
-TEST_F(PersonalDataManagerTest, AddUpdateRemoveIBANs) {
+TEST_F(PersonalDataManagerTest, NoIBANsAddedIfDisabled) {
+  prefs::SetAutofillIBANEnabled(prefs_.get(), false);
+  IBAN iban0(base::GenerateGUID());
+  iban0.set_value(u"IE12 BOFI 9000 0112 3456 78");
+  iban0.set_nickname(u"Nickname 0");
+
+  IBAN iban1(base::GenerateGUID());
+  iban1.set_value(u"DE91 1000 0000 0123 4567 89");
+  iban1.set_nickname(u"Nickname 1");
+
+  personal_data_->AddIBAN(iban0);
+  personal_data_->AddIBAN(iban1);
+
+  EXPECT_EQ(0U, personal_data_->GetIBANs().size());
+}
+
+TEST_F(PersonalDataManagerTest, AddUpdateRemoveIbans) {
+  prefs::SetAutofillIBANEnabled(prefs_.get(), true);
   IBAN iban0(base::GenerateGUID());
   iban0.set_value(u"IE12 BOFI 9000 0112 3456 78");
   iban0.set_nickname(u"Nickname 0");
@@ -1981,6 +1998,7 @@
   // profiles.
   prefs::SetAutofillProfileEnabled(prefs_.get(), false);
   prefs::SetAutofillCreditCardEnabled(prefs_.get(), false);
+  prefs::SetAutofillIBANEnabled(prefs_.get(), false);
   WaitForOnPersonalDataChanged();
   EXPECT_EQ(default_country,
             personal_data_->GetDefaultCountryCodeForNewAddress());
diff --git a/components/autofill/core/common/autofill_payments_features.cc b/components/autofill/core/common/autofill_payments_features.cc
index 4e26f7f..a65e5ac 100644
--- a/components/autofill/core/common/autofill_payments_features.cc
+++ b/components/autofill/core/common/autofill_payments_features.cc
@@ -67,6 +67,11 @@
     "AutofillEnableManualFallbackForVirtualCards",
     base::FEATURE_ENABLED_BY_DEFAULT};
 
+// When enabled, card product name (instead of issuer network) will be shown in
+// Payments UI.
+const base::Feature kAutofillEnableCardProductName{
+    "AutofillEnableCardProductName", base::FEATURE_DISABLED_BY_DEFAULT};
+
 // When enabled, a notification will be displayed on page navigation if the
 // domain has an eligible merchant promo code offer or reward.
 const base::Feature kAutofillEnableOfferNotificationForPromoCodes{
diff --git a/components/autofill/core/common/autofill_payments_features.h b/components/autofill/core/common/autofill_payments_features.h
index 259405e..cfca1f6 100644
--- a/components/autofill/core/common/autofill_payments_features.h
+++ b/components/autofill/core/common/autofill_payments_features.h
@@ -24,6 +24,7 @@
     kAutofillEnableGetDetailsForEnrollParsingInUploadCardResponse;
 extern const base::Feature kAutofillEnableFIDOProgressDialog;
 extern const base::Feature kAutofillEnableManualFallbackForVirtualCards;
+extern const base::Feature kAutofillEnableCardProductName;
 extern const base::Feature kAutofillEnableOfferNotificationForPromoCodes;
 extern const base::Feature kAutofillEnableOffersInClankKeyboardAccessory;
 extern const base::Feature kAutofillEnableRemadeDownstreamMetrics;
diff --git a/components/autofill/core/common/autofill_prefs.cc b/components/autofill/core/common/autofill_prefs.cc
index d2e741e..2892290 100644
--- a/components/autofill/core/common/autofill_prefs.cc
+++ b/components/autofill/core/common/autofill_prefs.cc
@@ -61,6 +61,9 @@
 const char kAutofillJapanCityFieldMigratedDeprecated[] =
     "autofill.japan_city_field_migrated_to_street_address";
 
+// Boolean that is true if Autofill is enabled and allowed to save IBAN data.
+extern const char kAutofillIBANEnabled[] = "autofill.iban_enabled";
+
 // Integer that is set to the last version where the profile deduping routine
 // was run. This routine will be run once per version.
 const char kAutofillLastVersionDeduped[] = "autofill.last_version_deduped";
@@ -135,6 +138,9 @@
   registry->RegisterBooleanPref(
       prefs::kAutofillCreditCardEnabled, true,
       user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
+  registry->RegisterBooleanPref(
+      prefs::kAutofillIBANEnabled, true,
+      user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
 
   // Non-synced prefs. Used for per-device choices, e.g., signin promo.
   registry->RegisterBooleanPref(prefs::kAutofillCreditCardFidoAuthEnabled,
@@ -217,6 +223,14 @@
   prefs->SetBoolean(kAutofillCreditCardEnabled, enabled);
 }
 
+bool IsAutofillIBANEnabled(const PrefService* prefs) {
+  return prefs->GetBoolean(kAutofillIBANEnabled);
+}
+
+void SetAutofillIBANEnabled(PrefService* prefs, bool enabled) {
+  prefs->SetBoolean(kAutofillIBANEnabled, enabled);
+}
+
 bool IsAutofillManaged(const PrefService* prefs) {
   return prefs->IsManagedPreference(kAutofillEnabledDeprecated);
 }
diff --git a/components/autofill/core/common/autofill_prefs.h b/components/autofill/core/common/autofill_prefs.h
index f086613bc..12d11824 100644
--- a/components/autofill/core/common/autofill_prefs.h
+++ b/components/autofill/core/common/autofill_prefs.h
@@ -28,8 +28,10 @@
 extern const char kAutofillCreditCardFidoAuthOfferCheckboxState[];
 #endif
 extern const char kAutofillCreditCardSigninPromoImpressionCount[];
-// Please use kAutofillCreditCardEnabled and kAutofillProfileEnabled instead.
+// Please use kAutofillCreditCardEnabled, kAutofillIBANEnabled and
+// kAutofillProfileEnabled instead.
 extern const char kAutofillEnabledDeprecated[];
+extern const char kAutofillIBANEnabled[];
 extern const char kAutofillJapanCityFieldMigratedDeprecated[];
 extern const char kAutofillLastVersionDeduped[];
 extern const char kAutofillLastVersionDisusedAddressesDeleted[];
@@ -68,6 +70,10 @@
 
 void SetAutofillCreditCardEnabled(PrefService* prefs, bool enabled);
 
+bool IsAutofillIBANEnabled(const PrefService* prefs);
+
+void SetAutofillIBANEnabled(PrefService* prefs, bool enabled);
+
 bool IsAutofillManaged(const PrefService* prefs);
 
 bool IsAutofillProfileManaged(const PrefService* prefs);
diff --git a/components/contextual_search/core/browser/contextual_search_delegate.cc b/components/contextual_search/core/browser/contextual_search_delegate.cc
index 15d41df..71cf063 100644
--- a/components/contextual_search/core/browser/contextual_search_delegate.cc
+++ b/components/contextual_search/core/browser/contextual_search_delegate.cc
@@ -102,67 +102,65 @@
 // Handles tasks for the ContextualSearchManager in a separable, testable way.
 ContextualSearchDelegate::ContextualSearchDelegate(
     scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
-    TemplateURLService* template_url_service,
-    ContextualSearchDelegate::SearchTermResolutionCallback search_term_callback,
-    ContextualSearchDelegate::SurroundingTextCallback surrounding_text_callback)
+    TemplateURLService* template_url_service)
     : url_loader_factory_(std::move(url_loader_factory)),
       template_url_service_(template_url_service),
-      field_trial_(std::make_unique<ContextualSearchFieldTrial>()),
-      search_term_callback_(std::move(search_term_callback)),
-      surrounding_text_callback_(std::move(surrounding_text_callback)) {}
+      field_trial_(std::make_unique<ContextualSearchFieldTrial>()) {}
 
 ContextualSearchDelegate::~ContextualSearchDelegate() = default;
 
 void ContextualSearchDelegate::GatherAndSaveSurroundingText(
-    base::WeakPtr<ContextualSearchContext> contextual_search_context,
-    content::WebContents* web_contents) {
+    base::WeakPtr<ContextualSearchContext> context,
+    content::WebContents* web_contents,
+    SurroundingTextCallback callback) {
   DCHECK(web_contents);
-  blink::mojom::LocalFrame::GetTextSurroundingSelectionCallback callback =
-      base::BindOnce(
+  blink::mojom::LocalFrame::GetTextSurroundingSelectionCallback
+      get_text_callback = base::BindOnce(
           &ContextualSearchDelegate::OnTextSurroundingSelectionAvailable,
-          AsWeakPtr());
-  context_ = contextual_search_context;
-  if (context_ == nullptr)
+          AsWeakPtr(), context, callback);
+  if (!context)
     return;
 
-  context_->SetBasePageEncoding(web_contents->GetEncoding());
-  int surroundingTextSize = context_->CanResolve()
+  context->SetBasePageEncoding(web_contents->GetEncoding());
+  int surroundingTextSize = context->CanResolve()
                                 ? field_trial_->GetResolveSurroundingSize()
                                 : field_trial_->GetSampleSurroundingSize();
   RenderFrameHost* focused_frame = web_contents->GetFocusedFrame();
   if (focused_frame) {
-    focused_frame->RequestTextSurroundingSelection(std::move(callback),
+    focused_frame->RequestTextSurroundingSelection(std::move(get_text_callback),
                                                    surroundingTextSize);
   } else {
-    std::move(callback).Run(std::u16string(), 0, 0);
+    std::move(get_text_callback).Run(std::u16string(), 0, 0);
   }
 }
 
 void ContextualSearchDelegate::StartSearchTermResolutionRequest(
-    base::WeakPtr<ContextualSearchContext> contextual_search_context,
-    content::WebContents* web_contents) {
+    base::WeakPtr<ContextualSearchContext> context,
+    content::WebContents* web_contents,
+    SearchTermResolutionCallback callback) {
   DCHECK(web_contents);
-  if (context_ == nullptr)
+  if (!context)
     return;
 
-  DCHECK(context_.get() == contextual_search_context.get());
-  DCHECK(context_->CanResolve());
+  DCHECK(context->CanResolve());
 
   // Immediately cancel any request that's in flight, since we're building a new
   // context (and the response disposes of any existing context).
   url_loader_.reset();
 
   // Decide if the URL should be sent with the context.
-  if (context_->CanSendBasePageUrl())
-    context_->SetBasePageUrl(web_contents->GetLastCommittedURL());
+  if (context->CanSendBasePageUrl())
+    context->SetBasePageUrl(web_contents->GetLastCommittedURL());
 
   // Issue the resolve request.
-  ResolveSearchTermFromContext();
+  ResolveSearchTermFromContext(context, std::move(callback));
 }
 
-void ContextualSearchDelegate::ResolveSearchTermFromContext() {
-  DCHECK(context_ != nullptr);
-  GURL request_url(BuildRequestUrl(context_.get()));
+void ContextualSearchDelegate::ResolveSearchTermFromContext(
+    base::WeakPtr<ContextualSearchContext> context,
+    SearchTermResolutionCallback callback) {
+  DCHECK(context);
+  GURL request_url(BuildRequestUrl(context.get()));
   DCHECK(request_url.is_valid());
 
   auto resource_request = std::make_unique<network::ResourceRequest>();
@@ -170,7 +168,7 @@
 
   // Populates the discourse context and adds it to the HTTP header of the
   // search term resolution request.
-  resource_request->headers.CopyFrom(GetDiscourseContext(*context_));
+  resource_request->headers.CopyFrom(GetDiscourseContext(*context));
 
   // Disable cookies for this request.
   resource_request->credentials_mode = network::mojom::CredentialsMode::kOmit;
@@ -218,12 +216,14 @@
   url_loader_->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
       url_loader_factory_.get(),
       base::BindOnce(&ContextualSearchDelegate::OnUrlLoadComplete,
-                     base::Unretained(this)));
+                     base::Unretained(this), context, std::move(callback)));
 }
 
 void ContextualSearchDelegate::OnUrlLoadComplete(
+    base::WeakPtr<ContextualSearchContext> context,
+    SearchTermResolutionCallback callback,
     std::unique_ptr<std::string> response_body) {
-  if (!context_)
+  if (!context)
     return;
 
   int response_code = ResolvedSearchTerm::kResponseCodeUninitialized;
@@ -235,16 +235,16 @@
       std::make_unique<ResolvedSearchTerm>(response_code);
   if (response_body && response_code == net::HTTP_OK) {
     resolved_search_term =
-        GetResolvedSearchTermFromJson(response_code, *response_body);
+        GetResolvedSearchTermFromJson(*context, response_code, *response_body);
   }
-  search_term_callback_.Run(*resolved_search_term);
+  callback.Run(*resolved_search_term);
 }
 
 std::unique_ptr<ResolvedSearchTerm>
 ContextualSearchDelegate::GetResolvedSearchTermFromJson(
+    const ContextualSearchContext& context,
     int response_code,
     const std::string& json_string) {
-  DCHECK(context_ != nullptr);
   std::string search_term;
   std::string display_text;
   std::string alternate_term;
@@ -277,13 +277,13 @@
     // the new and old selection.
     if (mention_start >= mention_end ||
         (mention_end - mention_start) > kContextualSearchMaxSelection ||
-        mention_end <= context_->GetStartOffset() ||
-        mention_start >= context_->GetEndOffset()) {
+        mention_end <= context.GetStartOffset() ||
+        mention_start >= context.GetEndOffset()) {
       start_adjust = 0;
       end_adjust = 0;
     } else {
-      start_adjust = mention_start - context_->GetStartOffset();
-      end_adjust = mention_end - context_->GetEndOffset();
+      start_adjust = mention_start - context.GetStartOffset();
+      end_adjust = mention_end - context.GetEndOffset();
     }
   }
   bool is_invalid =
@@ -324,7 +324,7 @@
   }
 
   int mainFunctionVersion = kContextualSearchRequestVersion;
-  if (context_->GetRelatedSearches())
+  if (context->GetRelatedSearches())
     mainFunctionVersion = kRelatedSearchesVersion;
 
   TemplateURLRef::SearchTermsArgs::ContextualSearchParams params(
@@ -357,16 +357,18 @@
 }
 
 void ContextualSearchDelegate::OnTextSurroundingSelectionAvailable(
+    base::WeakPtr<ContextualSearchContext> context,
+    SurroundingTextCallback callback,
     const std::u16string& surrounding_text,
     uint32_t start_offset,
     uint32_t end_offset) {
-  if (context_ == nullptr)
+  if (!context)
     return;
 
   // Sometimes the surroundings are 0, 0, '', so run the callback with empty
   // data in that case. See https://crbug.com/393100.
   if (start_offset == 0 && end_offset == 0 && surrounding_text.length() == 0) {
-    surrounding_text_callback_.Run(std::string(), std::u16string(), 0, 0);
+    callback.Run(std::string(), std::u16string(), 0, 0);
     return;
   }
 
@@ -377,8 +379,7 @@
   start_offset = std::min(surrounding_length, start_offset);
   end_offset = std::min(surrounding_length, end_offset);
 
-  context_->SetSelectionSurroundings(start_offset, end_offset,
-                                     surrounding_text);
+  context->SetSelectionSurroundings(start_offset, end_offset, surrounding_text);
 
   // Call the Java surrounding callback with a shortened copy of the
   // surroundings to use as a sample of the surrounding text.
@@ -392,9 +393,8 @@
       SampleSurroundingText(surrounding_text, sample_padding_each_side,
                             &selection_start, &selection_end);
   DCHECK(selection_start <= selection_end);
-  surrounding_text_callback_.Run(context_->GetBasePageEncoding(),
-                                 sample_surrounding_text, selection_start,
-                                 selection_end);
+  callback.Run(context->GetBasePageEncoding(), sample_surrounding_text,
+               selection_start, selection_end);
 }
 
 // Decodes the given response from the search term resolution request and sets
@@ -530,7 +530,7 @@
 void ContextualSearchDelegate::ExtractMentionsStartEnd(
     const base::Value::List& mentions_list,
     int* start_result,
-    int* end_result) {
+    int* end_result) const {
   if (mentions_list.size() >= 1 && mentions_list[0].is_int())
     *start_result = std::max(0, mentions_list[0].GetInt());
   if (mentions_list.size() >= 2 && mentions_list[1].is_int())
@@ -541,7 +541,7 @@
     const std::u16string& surrounding_text,
     int padding_each_side,
     size_t* start,
-    size_t* end) {
+    size_t* end) const {
   std::u16string result_text = surrounding_text;
   size_t start_offset = *start;
   size_t end_offset = *end;
diff --git a/components/contextual_search/core/browser/contextual_search_delegate.h b/components/contextual_search/core/browser/contextual_search_delegate.h
index 6cbdfc7..a13b252 100644
--- a/components/contextual_search/core/browser/contextual_search_delegate.h
+++ b/components/contextual_search/core/browser/contextual_search_delegate.h
@@ -44,32 +44,32 @@
       void(const std::string&, const std::u16string&, size_t, size_t)>
       SurroundingTextCallback;
 
-  // Constructs a delegate that will always call back to the given callbacks
-  // when search term resolution or surrounding text responses are available.
+  // Constructs a delegate that uses the given url_loader_factory and
+  // template_url_service for all contextual search requests.
   ContextualSearchDelegate(
       scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
-      TemplateURLService* template_url_service,
-      SearchTermResolutionCallback search_term_callback,
-      SurroundingTextCallback surrounding_callback);
+      TemplateURLService* template_url_service);
 
   ContextualSearchDelegate(const ContextualSearchDelegate&) = delete;
   ContextualSearchDelegate& operator=(const ContextualSearchDelegate&) = delete;
 
   virtual ~ContextualSearchDelegate();
 
-  // Gathers surrounding text and saves it locally in the given context.
+  // Gathers surrounding text and saves it in the given context. The given
+  // callback will be run when the surrounding text becomes available.
   void GatherAndSaveSurroundingText(
       base::WeakPtr<ContextualSearchContext> contextual_search_context,
-      content::WebContents* web_contents);
+      content::WebContents* web_contents,
+      SurroundingTextCallback callback);
 
   // Starts an asynchronous search term resolution request.
-  // The given context includes some content from a web page and must be able
+  // The given context may include some content from a web page and must be able
   // to resolve.
-  // When the response is available the callback specified in the constructor
-  // is run.
+  // When the response is available the given callback will be run.
   void StartSearchTermResolutionRequest(
       base::WeakPtr<ContextualSearchContext> contextual_search_context,
-      content::WebContents* web_contents);
+      content::WebContents* web_contents,
+      SearchTermResolutionCallback callback);
 
  private:
   // Friend our test which allows our private methods to be used in helper
@@ -95,23 +95,31 @@
   FRIEND_TEST_ALL_PREFIXES(ContextualSearchDelegateTest,
                            DecodeSearchTermFromJsonResponse);
 
-  void OnUrlLoadComplete(std::unique_ptr<std::string> response_body);
-
   // Resolves the search term specified by the current context.
-  // Only needed for tests.  TODO(donnd): make private and friend?
-  void ResolveSearchTermFromContext();
+  void ResolveSearchTermFromContext(
+      base::WeakPtr<ContextualSearchContext> context,
+      SearchTermResolutionCallback callback);
+
+  // Handles the contextual search response included in |response_body|. Calls
+  // |callback| with the resulting ResolvedSearchTerm.
+  void OnUrlLoadComplete(base::WeakPtr<ContextualSearchContext> context,
+                         SearchTermResolutionCallback callback,
+                         std::unique_ptr<std::string> response_body);
 
   // Builds and returns the search term resolution request URL.
   // |context| is used to help build the query.
   std::string BuildRequestUrl(ContextualSearchContext* context);
 
   void OnTextSurroundingSelectionAvailable(
+      base::WeakPtr<ContextualSearchContext> context,
+      SurroundingTextCallback callback,
       const std::u16string& surrounding_text,
       uint32_t start_offset,
       uint32_t end_offset);
 
   // Builds a Resolved Search Term by decoding the given JSON string.
   std::unique_ptr<ResolvedSearchTerm> GetResolvedSearchTermFromJson(
+      const ContextualSearchContext& context,
       int response_code,
       const std::string& json_string);
 
@@ -140,7 +148,7 @@
   // |mentions_list| must be a list.
   void ExtractMentionsStartEnd(const base::Value::List& mentions_list,
                                int* start_result,
-                               int* end_result);
+                               int* end_result) const;
 
   // Generates a subset of the given surrounding_text string, for usage from
   // Java.
@@ -157,13 +165,7 @@
   std::u16string SampleSurroundingText(const std::u16string& surrounding_text,
                                        int padding_each_side,
                                        size_t* start,
-                                       size_t* end);
-
-  // For testing.
-  void SetContextForTesting(
-      const base::WeakPtr<ContextualSearchContext>& context) {
-    context_ = context;
-  }
+                                       size_t* end) const;
 
   // The current request in progress, or NULL.
   std::unique_ptr<network::SimpleURLLoader> url_loader_;
@@ -176,16 +178,6 @@
 
   // The field trial helper instance, always set up by the constructor.
   std::unique_ptr<ContextualSearchFieldTrial> field_trial_;
-
-  // The callback for notifications of completed URL fetches.
-  SearchTermResolutionCallback search_term_callback_;
-
-  // The callback for notifications of surrounding text being available.
-  SurroundingTextCallback surrounding_text_callback_;
-
-  // Used to hold the context until an upcoming search term request is started.
-  // Owned by the Java ContextualSearchContext.
-  base::WeakPtr<ContextualSearchContext> context_;
 };
 
 #endif  // COMPONENTS_CONTEXTUAL_SEARCH_CORE_BROWSER_CONTEXTUAL_SEARCH_DELEGATE_H_
diff --git a/components/contextual_search/core/browser/contextual_search_delegate_unittest.cc b/components/contextual_search/core/browser/contextual_search_delegate_unittest.cc
index 914d00b..d909e172 100644
--- a/components/contextual_search/core/browser/contextual_search_delegate_unittest.cc
+++ b/components/contextual_search/core/browser/contextual_search_delegate_unittest.cc
@@ -14,6 +14,7 @@
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "base/memory/raw_ptr.h"
+#include "base/memory/weak_ptr.h"
 #include "base/strings/escape.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/scoped_feature_list.h"
@@ -73,13 +74,7 @@
             &test_url_loader_factory_);
     template_url_service_.reset(CreateTemplateURLService());
     delegate_ = std::make_unique<ContextualSearchDelegate>(
-        test_shared_url_loader_factory_, template_url_service_.get(),
-        base::BindRepeating(
-            &ContextualSearchDelegateTest::recordSearchTermResolutionResponse,
-            base::Unretained(this)),
-        base::BindRepeating(
-            &ContextualSearchDelegateTest::recordSampleSelectionAvailable,
-            base::Unretained(this)));
+        test_shared_url_loader_factory_, template_url_service_.get());
   }
 
   void TearDown() override {
@@ -117,12 +112,13 @@
       int end_offset) {
     test_context_ = std::make_unique<WeakContextualSearchContext>(
         std::string(), GURL(kSomeSpecificBasePage), "utf-8");
-    // ContextualSearchDelegate class takes ownership of the context.
-    delegate_->SetContextForTesting(test_context_->GetWeakPtr());
-
     test_context_->SetSelectionSurroundings(start_offset, end_offset,
                                             surrounding_text);
-    delegate_->ResolveSearchTermFromContext();
+    delegate_->ResolveSearchTermFromContext(
+        test_context_->GetWeakPtr(),
+        base::BindRepeating(
+            &ContextualSearchDelegateTest::recordSearchTermResolutionResponse,
+            base::Unretained(this)));
     ASSERT_TRUE(test_url_loader_factory_.GetPendingRequest(0));
   }
 
@@ -154,7 +150,6 @@
   void CreateTestContext() {
     test_context_ = std::make_unique<WeakContextualSearchContext>(
         std::string(), GURL(kSomeSpecificBasePage), "utf-8");
-    delegate_->SetContextForTesting(test_context_->GetWeakPtr());
   }
 
   void DestroyTestContext() { test_context_.reset(); }
@@ -162,12 +157,23 @@
   // Call the OnTextSurroundingSelectionAvailable.
   // Cannot be in an actual test because OnTextSurroundingSelectionAvailable
   // is private.
-  void CallOnTextSurroundingSelectionAvailable() {
-    delegate_->OnTextSurroundingSelectionAvailable(std::u16string(), 1, 2);
+  void CallOnTextSurroundingSelectionAvailable(
+      base::WeakPtr<ContextualSearchContext> context) {
+    delegate_->OnTextSurroundingSelectionAvailable(
+        context,
+        base::BindRepeating(
+            &ContextualSearchDelegateTest::recordSampleSelectionAvailable,
+            base::Unretained(this)),
+        std::u16string(), 1, 2);
   }
 
-  void CallResolveSearchTermFromContext() {
-    delegate_->ResolveSearchTermFromContext();
+  void CallResolveSearchTermFromContext(
+      base::WeakPtr<ContextualSearchContext> context) {
+    delegate_->ResolveSearchTermFromContext(
+        context,
+        base::BindRepeating(
+            &ContextualSearchDelegateTest::recordSearchTermResolutionResponse,
+            base::Unretained(this)));
   }
 
   void SetResponseStringAndSimulateResponse(const std::string& selected_text,
@@ -198,7 +204,6 @@
         std::string(), GURL(kSomeSpecificBasePage), "utf-8");
     test_context_->SetSelectionSurroundings(start_offset, end_offset,
                                             surrounding_text);
-    delegate_->SetContextForTesting(test_context_->GetWeakPtr());
   }
 
   // Gets the Client Discourse Context proto from the request header.
@@ -260,6 +265,7 @@
 
   // The delegate under test.
   std::unique_ptr<ContextualSearchDelegate> delegate_;
+  std::unique_ptr<WeakContextualSearchContext> test_context_;
 
   network::TestURLLoaderFactory test_url_loader_factory_;
 
@@ -321,8 +327,6 @@
   scoped_refptr<network::SharedURLLoaderFactory>
       test_shared_url_loader_factory_;
 
-  std::unique_ptr<WeakContextualSearchContext> test_context_;
-
   // Features to enable
   base::test::ScopedFeatureList feature_list_;
 };
@@ -675,9 +679,11 @@
 
 // Test that we can destroy the context while resolving without a crash.
 // Test is flaky: https://crbug.com/890427
-TEST_F(ContextualSearchDelegateTest, DISABLED_DestroyContextDuringResolve) {
+TEST_F(ContextualSearchDelegateTest, DestroyContextDuringResolve) {
   CreateTestContext();
-  CallResolveSearchTermFromContext();
+  base::WeakPtr<ContextualSearchContext> weak_context =
+      test_context_->GetWeakPtr();
+  CallResolveSearchTermFromContext(weak_context);
   DestroyTestContext();
 
   std::string response("Any response as it does not matter here.");
@@ -689,8 +695,10 @@
 // Test that we can destroy the context while gathering surrounding text.
 TEST_F(ContextualSearchDelegateTest, DestroyContextDuringGatherSurroundings) {
   CreateTestContext();
+  base::WeakPtr<ContextualSearchContext> weak_context =
+      test_context_->GetWeakPtr();
   DestroyTestContext();
-  CallOnTextSurroundingSelectionAvailable();
+  CallOnTextSurroundingSelectionAvailable(weak_context);
 }
 
 TEST_F(ContextualSearchDelegateTest, ResponseWithCocaCardTag) {
diff --git a/components/exo/shell_surface_base.cc b/components/exo/shell_surface_base.cc
index 0495942..b054b012 100644
--- a/components/exo/shell_surface_base.cc
+++ b/components/exo/shell_surface_base.cc
@@ -37,6 +37,7 @@
 #include "build/chromeos_buildflags.h"
 #include "cc/trees/layer_tree_frame_sink.h"
 #include "chromeos/crosapi/cpp/crosapi_constants.h"
+#include "chromeos/ui/base/chromeos_ui_constants.h"
 #include "chromeos/ui/base/window_pin_type.h"
 #include "chromeos/ui/base/window_properties.h"
 #include "chromeos/ui/base/window_state_type.h"
@@ -1527,7 +1528,7 @@
     ash::SetCornerRadius(
         window_state->window(), host_window()->layer(),
         window_state->IsPip()
-            ? base::ClampRound(GetScale() * ash::kPipRoundedCornerRadius)
+            ? base::ClampRound(GetScale() * chromeos::kPipRoundedCornerRadius)
             : 0);
   }
 }
diff --git a/components/exo/text_input.cc b/components/exo/text_input.cc
index a669ae4..bae361a 100644
--- a/components/exo/text_input.cc
+++ b/components/exo/text_input.cc
@@ -350,7 +350,9 @@
                                    gfx::Range(utf16_start, utf16_end));
 }
 
-void TextInput::EnsureCaretNotInRect(const gfx::Rect& rect) {}
+void TextInput::EnsureCaretNotInRect(const gfx::Rect& rect) {
+  delegate_->OnVirtualKeyboardOccludedBoundsChanged(rect);
+}
 
 bool TextInput::IsTextEditCommandEnabled(ui::TextEditCommand command) const {
   return false;
@@ -438,6 +440,7 @@
 }
 
 void TextInput::OnKeyboardHidden() {
+  delegate_->OnVirtualKeyboardOccludedBoundsChanged({});
   delegate_->OnVirtualKeyboardVisibilityChanged(false);
 }
 
diff --git a/components/exo/text_input.h b/components/exo/text_input.h
index 2f63d244..2610b8fa 100644
--- a/components/exo/text_input.h
+++ b/components/exo/text_input.h
@@ -51,6 +51,11 @@
     // Called when the virtual keyboard visibility state has changed.
     virtual void OnVirtualKeyboardVisibilityChanged(bool is_visible) = 0;
 
+    // Called when the virtual keyboard's occluded bounds has changed.
+    // The bounds are in screen DIP.
+    virtual void OnVirtualKeyboardOccludedBoundsChanged(
+        const gfx::Rect& screen_bounds) = 0;
+
     // Set the 'composition text' of the current text input.
     virtual void SetCompositionText(const ui::CompositionText& composition) = 0;
 
diff --git a/components/exo/text_input_unittest.cc b/components/exo/text_input_unittest.cc
index 0ccbddb..32a992bf 100644
--- a/components/exo/text_input_unittest.cc
+++ b/components/exo/text_input_unittest.cc
@@ -84,6 +84,10 @@
               SetAutocorrectRange,
               (base::StringPiece16, const gfx::Range&),
               ());
+  MOCK_METHOD(void,
+              OnVirtualKeyboardOccludedBoundsChanged,
+              (const gfx::Rect&),
+              ());
 };
 
 class TestingInputMethodObserver : public ui::InputMethodObserver {
@@ -768,5 +772,18 @@
   text_input()->AddGrammarFragments(fragments);
 }
 
+TEST_F(TextInputTest, EnsureCaretNotInRect) {
+  const gfx::Rect bounds(10, 20, 300, 400);
+  EXPECT_CALL(*delegate(), OnVirtualKeyboardOccludedBoundsChanged(bounds));
+  text_input()->EnsureCaretNotInRect(bounds);
+}
+
+TEST_F(TextInputTest, OnKeyboardHidden) {
+  const gfx::Rect bounds;
+  EXPECT_CALL(*delegate(), OnVirtualKeyboardOccludedBoundsChanged(bounds));
+  EXPECT_CALL(*delegate(), OnVirtualKeyboardVisibilityChanged(false));
+  text_input()->OnKeyboardHidden();
+}
+
 }  // anonymous namespace
 }  // namespace exo
diff --git a/components/exo/wayland/server.cc b/components/exo/wayland/server.cc
index e6d44d7c..20c3d46 100644
--- a/components/exo/wayland/server.cc
+++ b/components/exo/wayland/server.cc
@@ -399,7 +399,7 @@
 
   zcr_text_input_extension_data_ =
       std::make_unique<WaylandTextInputExtension>();
-  wl_global_create(wl_display_.get(), &zcr_text_input_extension_v1_interface, 4,
+  wl_global_create(wl_display_.get(), &zcr_text_input_extension_v1_interface, 5,
                    zcr_text_input_extension_data_.get(),
                    bind_text_input_extension);
 
diff --git a/components/exo/wayland/zwp_text_input_manager.cc b/components/exo/wayland/zwp_text_input_manager.cc
index df3e33f..b768d374 100644
--- a/components/exo/wayland/zwp_text_input_manager.cc
+++ b/components/exo/wayland/zwp_text_input_manager.cc
@@ -106,6 +106,20 @@
     wl_client_flush(client());
   }
 
+  void OnVirtualKeyboardOccludedBoundsChanged(
+      const gfx::Rect& screen_bounds) override {
+    if (!extended_text_input_)
+      return;
+
+    if (wl_resource_get_version(extended_text_input_) >=
+        ZCR_EXTENDED_TEXT_INPUT_V1_SET_VIRTUAL_KEYBOARD_OCCLUDED_BOUNDS_SINCE_VERSION) {
+      zcr_extended_text_input_v1_send_set_virtual_keyboard_occluded_bounds(
+          extended_text_input_, screen_bounds.x(), screen_bounds.y(),
+          screen_bounds.width(), screen_bounds.height());
+      wl_client_flush(client());
+    }
+  }
+
   void SetCompositionText(const ui::CompositionText& composition) override {
     SendPreeditStyle(composition.text, composition.ime_text_spans);
 
diff --git a/components/guest_view/browser/guest_view_base.h b/components/guest_view/browser/guest_view_base.h
index 80d3ca70..920c535 100644
--- a/components/guest_view/browser/guest_view_base.h
+++ b/components/guest_view/browser/guest_view_base.h
@@ -196,6 +196,10 @@
   // <iframe> which is cross process.
   virtual bool CanBeEmbeddedInsideCrossProcessFrames() const;
 
+  // TODO(crbug.com/1261928): Add a |GetGuestMainFrame| method to allow direct
+  // access to the GuestView's main frame, without using the guest inner
+  // WebContents which will soon be removed.
+
  protected:
   explicit GuestViewBase(content::WebContents* owner_web_contents);
 
diff --git a/components/guest_view/browser/test_guest_view_manager.cc b/components/guest_view/browser/test_guest_view_manager.cc
index c117d51..55d4fa09 100644
--- a/components/guest_view/browser/test_guest_view_manager.cc
+++ b/components/guest_view/browser/test_guest_view_manager.cc
@@ -9,6 +9,21 @@
 
 #include "components/guest_view/browser/guest_view_base.h"
 #include "components/guest_view/browser/guest_view_manager_delegate.h"
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/test/browser_test_utils.h"
+
+namespace {
+// Returns the current RFH owned by the FrameTreeNode, denoted by
+// |frame_tree_node_id|.
+content::RenderFrameHost* GetCurrentGuestMainRenderFrameHost(
+    int frame_tree_node_id) {
+  auto* web_contents =
+      content::WebContents::FromFrameTreeNodeId(frame_tree_node_id);
+  DCHECK(web_contents);
+  return web_contents->UnsafeFindFrameByFrameTreeNodeId(frame_tree_node_id);
+}
+}  // namespace
 
 namespace guest_view {
 
@@ -23,8 +38,7 @@
       waiting_for_guests_created_(false),
       waiting_for_attach_(nullptr) {}
 
-TestGuestViewManager::~TestGuestViewManager() {
-}
+TestGuestViewManager::~TestGuestViewManager() = default;
 
 size_t TestGuestViewManager::GetNumGuestsActive() const {
   return guest_web_contents_by_instance_id_.size();
@@ -34,43 +48,76 @@
   return removed_instance_ids_.size();
 }
 
-content::WebContents* TestGuestViewManager::GetLastGuestCreated() {
-  content::WebContents* web_contents = nullptr;
-  for (int i = current_instance_id_; i >= 0; i--) {
-    web_contents = GetGuestByInstanceID(i);
-    if (web_contents) {
-      break;
+content::RenderFrameHost*
+TestGuestViewManager::GetLastGuestRenderFrameHostCreated() {
+  for (auto it = guest_view_watchers_.rbegin();
+       it != guest_view_watchers_.rend(); ++it) {
+    const auto& watcher = *it;
+    if (!watcher->IsDeleted()) {
+      return GetCurrentGuestMainRenderFrameHost(watcher->GetFrameTreeNodeId());
     }
   }
-  return web_contents;
+  return nullptr;
+}
+
+content::WebContents* TestGuestViewManager::DeprecatedGetLastGuestCreated() {
+  return content::WebContents::FromRenderFrameHost(
+      GetLastGuestRenderFrameHostCreated());
+}
+
+GuestViewBase* TestGuestViewManager::GetLastGuestViewCreated() {
+  auto* last_guest = DeprecatedGetLastGuestCreated();
+  return GuestViewBase::FromWebContents(last_guest);
 }
 
 void TestGuestViewManager::WaitForAllGuestsDeleted() {
   // Make sure that every guest that was created has been removed.
-  for (auto& watcher : guest_web_contents_watchers_)
+  for (auto& watcher : guest_view_watchers_) {
     watcher->Wait();
+  }
 }
 
 void TestGuestViewManager::WaitForLastGuestDeleted() {
   // Wait for the last guest that was created to be deleted.
-  guest_web_contents_watchers_.back()->Wait();
+  guest_view_watchers_.back()->Wait();
 }
 
-content::WebContents* TestGuestViewManager::WaitForSingleGuestCreated() {
+content::RenderFrameHost*
+TestGuestViewManager::WaitForSingleGuestRenderFrameHostCreated() {
   if (!GetNumGuestsActive()) {
     // Guests have been created and subsequently destroyed.
     if (num_guests_created() > 0)
       return nullptr;
     WaitForNumGuestsCreated(1u);
   }
-
-  return GetLastGuestCreated();
+  return GetLastGuestRenderFrameHostCreated();
 }
 
-content::WebContents* TestGuestViewManager::WaitForNextGuestCreated() {
-  created_message_loop_runner_ = new content::MessageLoopRunner();
-  created_message_loop_runner_->Run();
-  return GetLastGuestCreated();
+content::WebContents*
+TestGuestViewManager::DeprecatedWaitForSingleGuestCreated() {
+  return content::WebContents::FromRenderFrameHost(
+      WaitForSingleGuestRenderFrameHostCreated());
+}
+
+GuestViewBase* TestGuestViewManager::WaitForSingleGuestViewCreated() {
+  return GuestViewBase::FromWebContents(DeprecatedWaitForSingleGuestCreated());
+}
+
+content::RenderFrameHost*
+TestGuestViewManager::WaitForNextGuestRenderFrameHostCreated() {
+  created_run_loop_ = std::make_unique<base::RunLoop>();
+  created_run_loop_->Run();
+  return GetLastGuestRenderFrameHostCreated();
+}
+
+content::WebContents*
+TestGuestViewManager::DeprecatedWaitForNextGuestCreated() {
+  return content::WebContents::FromRenderFrameHost(
+      WaitForNextGuestRenderFrameHostCreated());
+}
+
+GuestViewBase* TestGuestViewManager::WaitForNextGuestViewCreated() {
+  return GuestViewBase::FromWebContents(DeprecatedWaitForNextGuestCreated());
 }
 
 void TestGuestViewManager::WaitForNumGuestsCreated(size_t count) {
@@ -80,26 +127,23 @@
   waiting_for_guests_created_ = true;
   expected_num_guests_created_ = count;
 
-  num_created_message_loop_runner_ = new content::MessageLoopRunner;
-  num_created_message_loop_runner_->Run();
+  num_created_run_loop_ = std::make_unique<base::RunLoop>();
+  num_created_run_loop_->Run();
 }
 
-void TestGuestViewManager::WaitUntilAttached(
-    content::WebContents* guest_web_contents) {
-  GuestViewBase* guest = GuestViewBase::FromWebContents(guest_web_contents);
-
-  if (guest->attached())
+void TestGuestViewManager::WaitUntilAttached(GuestViewBase* guest_view) {
+  if (guest_view->attached())
     return;
 
-  waiting_for_attach_ = guest;
+  waiting_for_attach_ = guest_view;
 
-  attached_message_loop_runner_ = new content::MessageLoopRunner;
-  attached_message_loop_runner_->Run();
+  attached_run_loop_ = std::make_unique<base::RunLoop>();
+  attached_run_loop_->Run();
 }
 
 void TestGuestViewManager::WaitForViewGarbageCollected() {
-  gc_message_loop_runner_ = new content::MessageLoopRunner;
-  gc_message_loop_runner_->Run();
+  gc_run_loop_ = std::make_unique<base::RunLoop>();
+  gc_run_loop_->Run();
 }
 
 void TestGuestViewManager::WaitForSingleViewGarbageCollected() {
@@ -111,12 +155,12 @@
                                     content::WebContents* guest_web_contents) {
   GuestViewManager::AddGuest(guest_instance_id, guest_web_contents);
 
-  guest_web_contents_watchers_.push_back(
-      std::make_unique<content::WebContentsDestroyedWatcher>(
-          guest_web_contents));
+  guest_view_watchers_.push_back(
+      std::make_unique<content::FrameDeletedObserver>(
+          guest_web_contents->GetPrimaryMainFrame()));
 
-  if (created_message_loop_runner_)
-    created_message_loop_runner_->Quit();
+  if (created_run_loop_)
+    created_run_loop_->Quit();
 
   ++num_guests_created_;
   if (!waiting_for_guests_created_ &&
@@ -124,8 +168,8 @@
     return;
   }
 
-  if (num_created_message_loop_runner_)
-    num_created_message_loop_runner_->Quit();
+  if (num_created_run_loop_)
+    num_created_run_loop_->Quit();
 }
 
 void TestGuestViewManager::AttachGuest(int embedder_process_id,
@@ -138,19 +182,30 @@
   if (waiting_for_attach_ &&
       (waiting_for_attach_ ==
        GuestViewBase::From(embedder_process_id, guest_instance_id))) {
-    attached_message_loop_runner_->Quit();
+    attached_run_loop_->Quit();
     waiting_for_attach_ = nullptr;
   }
 }
 
-void TestGuestViewManager::GetGuestWebContentsList(
+void TestGuestViewManager::DeprecatedGetGuestWebContentsList(
     std::vector<content::WebContents*>* guest_web_contents_list) {
-  for (auto& watcher : guest_web_contents_watchers_)
-    guest_web_contents_list->push_back(watcher->web_contents());
+  for (auto& watcher : guest_view_watchers_) {
+    if (!watcher->IsDeleted()) {
+      auto ftn_id = watcher->GetFrameTreeNodeId();
+      guest_web_contents_list->push_back(
+          content::WebContents::FromFrameTreeNodeId(ftn_id));
+    }
+  }
 }
 
-void TestGuestViewManager::RemoveGuest(int guest_instance_id) {
-  GuestViewManager::RemoveGuest(guest_instance_id);
+void TestGuestViewManager::GetGuestRenderFrameHostList(
+    std::vector<content::RenderFrameHost*>* guest_render_frame_host_list) {
+  for (auto& watcher : guest_view_watchers_) {
+    if (!watcher->IsDeleted()) {
+      guest_render_frame_host_list->push_back(
+          GetCurrentGuestMainRenderFrameHost(watcher->GetFrameTreeNodeId()));
+    }
+  }
 }
 
 void TestGuestViewManager::EmbedderProcessDestroyed(int embedder_process_id) {
@@ -162,8 +217,8 @@
                                                 int view_instance_id) {
   GuestViewManager::ViewGarbageCollected(embedder_process_id, view_instance_id);
   ++num_views_garbage_collected_;
-  if (gc_message_loop_runner_)
-    gc_message_loop_runner_->Quit();
+  if (gc_run_loop_)
+    gc_run_loop_->Quit();
 }
 
 // Test factory for creating test instances of GuestViewManager.
diff --git a/components/guest_view/browser/test_guest_view_manager.h b/components/guest_view/browser/test_guest_view_manager.h
index 8b424621..0466f30 100644
--- a/components/guest_view/browser/test_guest_view_manager.h
+++ b/components/guest_view/browser/test_guest_view_manager.h
@@ -14,7 +14,8 @@
 #include "base/memory/raw_ptr.h"
 #include "components/guest_view/browser/guest_view_manager.h"
 #include "components/guest_view/browser/guest_view_manager_factory.h"
-#include "content/public/test/test_utils.h"
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/test/browser_test_utils.h"
 
 namespace guest_view {
 
@@ -32,15 +33,32 @@
 
   void WaitForLastGuestDeleted();
 
-  content::WebContents* WaitForSingleGuestCreated();
-  content::WebContents* WaitForNextGuestCreated();
+  // While the GuestViewBase directly represents a guest view, the
+  // RenderFrameHost version exposes the guest view's main frame for the ease of
+  // testing.
+  //
+  // All the WebContents versions APIs (here and on) will be removed during the
+  // MPArch migration. Consider using GuestViewBase or RenderFrameHost versions,
+  // unless necessary.
+  //
+  // TODO(crbug.com/1261928): Remove all the WebContents version.
+  GuestViewBase* WaitForSingleGuestViewCreated();
+  content::RenderFrameHost* WaitForSingleGuestRenderFrameHostCreated();
+  content::WebContents* DeprecatedWaitForSingleGuestCreated();
+
+  GuestViewBase* WaitForNextGuestViewCreated();
+  content::RenderFrameHost* WaitForNextGuestRenderFrameHostCreated();
+  content::WebContents* DeprecatedWaitForNextGuestCreated();
+
   void WaitForNumGuestsCreated(size_t count);
 
   void WaitForSingleViewGarbageCollected();
 
-  content::WebContents* GetLastGuestCreated();
+  GuestViewBase* GetLastGuestViewCreated();
+  content::RenderFrameHost* GetLastGuestRenderFrameHostCreated();
+  content::WebContents* DeprecatedGetLastGuestCreated();
 
-  void WaitUntilAttached(content::WebContents* web_contents);
+  void WaitUntilAttached(GuestViewBase* guest_view);
 
   // Returns the number of guests currently still alive at the time of calling
   // this method.
@@ -67,18 +85,18 @@
   // Returns the last guest instance ID removed from the manager.
   int last_instance_id_removed() const { return last_instance_id_removed_; }
 
-  // Returns the list of guests WebContentses that were created by this
-  // manager.
-  void GetGuestWebContentsList(
+  // Returns the list of guests that were created by this manager.
+  void DeprecatedGetGuestWebContentsList(
       std::vector<content::WebContents*>* guest_web_contents_list);
+  void GetGuestRenderFrameHostList(
+      std::vector<content::RenderFrameHost*>* guest_render_frame_host_list);
 
  private:
   FRIEND_TEST_ALL_PREFIXES(GuestViewManagerTest, AddRemove);
 
-  // GuestViewManager override:
+  // guest_view::GuestViewManager:
   void AddGuest(int guest_instance_id,
                 content::WebContents* guest_web_contents) override;
-  void RemoveGuest(int guest_instance_id) override;
   void EmbedderProcessDestroyed(int embedder_process_id) override;
   void ViewGarbageCollected(int embedder_process_id,
                             int view_instance_id) override;
@@ -98,13 +116,15 @@
   int num_views_garbage_collected_;
   bool waiting_for_guests_created_;
 
-  std::vector<std::unique_ptr<content::WebContentsDestroyedWatcher>>
-      guest_web_contents_watchers_;
-  scoped_refptr<content::MessageLoopRunner> created_message_loop_runner_;
-  scoped_refptr<content::MessageLoopRunner> num_created_message_loop_runner_;
+  // Tracks the life time of the GuestView's main FrameTreeNode. The main FTN
+  // has the same lifesspan as the GuestView.
+  std::vector<std::unique_ptr<content::FrameDeletedObserver>>
+      guest_view_watchers_;
+  std::unique_ptr<base::RunLoop> created_run_loop_;
+  std::unique_ptr<base::RunLoop> num_created_run_loop_;
   raw_ptr<GuestViewBase> waiting_for_attach_;
-  scoped_refptr<content::MessageLoopRunner> attached_message_loop_runner_;
-  scoped_refptr<content::MessageLoopRunner> gc_message_loop_runner_;
+  std::unique_ptr<base::RunLoop> attached_run_loop_;
+  std::unique_ptr<base::RunLoop> gc_run_loop_;
 };
 
 // Test factory for creating test instances of GuestViewManager.
diff --git a/components/omnibox/browser/autocomplete_result.cc b/components/omnibox/browser/autocomplete_result.cc
index 826bb02..af6d955 100644
--- a/components/omnibox/browser/autocomplete_result.cc
+++ b/components/omnibox/browser/autocomplete_result.cc
@@ -971,8 +971,10 @@
     SuggestionGroupId suggestion_group_id) const {
   const auto& it = suggestion_groups_map_.find(suggestion_group_id);
   DCHECK(it != suggestion_groups_map_.end());
+  if (!it->second.original_group_id.has_value()) {
+    return false;
+  }
 
-  DCHECK(it->second.original_group_id.has_value());
   omnibox::SuggestionGroupVisibility user_preference =
       omnibox::GetUserPreferenceForSuggestionGroupVisibility(
           prefs, it->second.original_group_id.value());
@@ -992,8 +994,8 @@
     bool hidden) const {
   const auto& it = suggestion_groups_map_.find(suggestion_group_id);
   DCHECK(it != suggestion_groups_map_.end());
-
   DCHECK(it->second.original_group_id.has_value());
+
   omnibox::SetUserPreferenceForSuggestionGroupVisibility(
       prefs, it->second.original_group_id.value(),
       hidden ? omnibox::SuggestionGroupVisibility::HIDDEN
diff --git a/components/omnibox/browser/autocomplete_result.h b/components/omnibox/browser/autocomplete_result.h
index 381a1a0..97d15d4 100644
--- a/components/omnibox/browser/autocomplete_result.h
+++ b/components/omnibox/browser/autocomplete_result.h
@@ -241,8 +241,9 @@
   // Returns whether or not |suggestion_group_id| should be collapsed in the UI.
   // This method takes into account both the user's stored prefs as well as
   // the server-provided visibility hint for |suggestion_group_id|.
-  // DCHECKs whether |suggestion_group_id| is found in |suggestion_groups_map_|
-  // and whether the group info contains the original server provided group ID.
+  // DCHECKs whether |suggestion_group_id| is found in |suggestion_groups_map_|.
+  // Returns false if the group info does not contain the original server
+  // provided group ID.
   bool IsSuggestionGroupHidden(PrefService* prefs,
                                SuggestionGroupId suggestion_group_id) const;
 
diff --git a/components/omnibox/browser/omnibox_edit_model_unittest.cc b/components/omnibox/browser/omnibox_edit_model_unittest.cc
index 808991e9..320f6524 100644
--- a/components/omnibox/browser/omnibox_edit_model_unittest.cc
+++ b/components/omnibox/browser/omnibox_edit_model_unittest.cc
@@ -749,7 +749,8 @@
 
   SuggestionGroupsMap suggestion_groups_map;
   suggestion_groups_map[kNewGroupId].header = u"header";
-  suggestion_groups_map[kNewGroupId].original_group_id = 12345;
+  // Do not set the original_group_id on purpose to test that default visibility
+  // can be safely queried via AutocompleteResult::IsSuggestionGroupHidden().
   result->MergeSuggestionGroupsMap(suggestion_groups_map);
 
   AutocompleteInput input(u"match", metrics::OmniboxEventProto::NTP,
@@ -836,6 +837,8 @@
   SuggestionGroupsMap suggestion_groups_map;
   suggestion_groups_map[kNewGroupId].header = u"header";
   suggestion_groups_map[kNewGroupId].original_group_id = 12345;
+  // Setting the original_group_id allows the default visibility to be set via
+  // AutocompleteResult::SetSuggestionGroupHidden().
   result->MergeSuggestionGroupsMap(suggestion_groups_map);
   result->SetSuggestionGroupHidden(pref_service(), kNewGroupId,
                                    /*hidden=*/true);
@@ -909,7 +912,8 @@
 
   SuggestionGroupsMap suggestion_groups_map;
   suggestion_groups_map[kNewGroupId].header = u"header";
-  suggestion_groups_map[kNewGroupId].original_group_id = 12345;
+  // Do not set the original_group_id on purpose to test that default visibility
+  // can be safely queried via AutocompleteResult::IsSuggestionGroupHidden().
   result->MergeSuggestionGroupsMap(suggestion_groups_map);
 
   AutocompleteInput input(u"a", metrics::OmniboxEventProto::NTP,
diff --git a/components/optimization_guide/core/prediction_manager.cc b/components/optimization_guide/core/prediction_manager.cc
index a6a3d671..eff576c 100644
--- a/components/optimization_guide/core/prediction_manager.cc
+++ b/components/optimization_guide/core/prediction_manager.cc
@@ -333,7 +333,7 @@
   proto::ModelInfo base_model_info;
   // There should only be one supported model engine version at a time.
   base_model_info.add_supported_model_engine_versions(
-      proto::MODEL_ENGINE_VERSION_TFLITE_2_10);
+      proto::MODEL_ENGINE_VERSION_TFLITE_2_11);
   // This histogram is used for integration tests. Do not remove.
   // Update this to be 10000 if/when we exceed 100 model engine versions.
   LOCAL_HISTOGRAM_COUNTS_100(
diff --git a/components/optimization_guide/proto/models.proto b/components/optimization_guide/proto/models.proto
index 4154047..ffb4cb9 100644
--- a/components/optimization_guide/proto/models.proto
+++ b/components/optimization_guide/proto/models.proto
@@ -312,6 +312,8 @@
   MODEL_ENGINE_VERSION_TFLITE_2_9_0_1 = 8;
   // A model using only operations that are supported by TensorflowLite 2.10.0.
   MODEL_ENGINE_VERSION_TFLITE_2_10 = 9;
+  // A model using only operations that are supported by TensorflowLite 2.11.0.
+  MODEL_ENGINE_VERSION_TFLITE_2_11 = 10;
 }
 
 // A set of model features and the host that it applies to.
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json
index 16752dd..adda79a 100644
--- a/components/policy/resources/policy_templates.json
+++ b/components/policy/resources/policy_templates.json
@@ -31988,14 +31988,15 @@
         },
       ],
       'default': True,
+      'default_for_enterprise_users': False,
       'example_value': False,
       'id': 971,
       'caption': '''Enable adaptive charging model to hold charging process to extend battery life''',
       'tags': [],
       'desc': '''Specifies whether an adaptive charging model is allowed to hold charging process to extend battery life.
 
-      When the device is on AC, the adaptive charging model evaluates if charging process should be hold to extend battery life. If the adaptive charging model holds the charging process, it'll keep the battery at a certain level (i.e. 80%) and then charge the device to 100% when the user need it.
-      If this policy is set to True or left not set, the adaptive charging model will be enabled and allowed to hold the charging process to extend battery life. If this policy is set to False, the adaptive charging model will not influence the charging process.''',
+      When the device is on AC, the adaptive charging model evaluates if charging process should be hold to extend battery life. If the adaptive charging model holds the charging process, it'll keep the battery at a certain level (i.e. 80%) and then charge the device to 100% when the user needs it.
+      If this policy is set to True, the adaptive charging model will be enabled and allowed to hold the charging process to extend battery life. If this policy is set to False or unset, the adaptive charging model will not influence the charging process.''',
     },
     {
       'name': 'WarnBeforeQuittingEnabled',
diff --git a/components/search/ntp_features.cc b/components/search/ntp_features.cc
index 372177b..a642e5a 100644
--- a/components/search/ntp_features.cc
+++ b/components/search/ntp_features.cc
@@ -179,6 +179,8 @@
     "NtpDriveModuleCacheMaxAgeSParam";
 const char kNtpDriveModuleExperimentGroupParam[] =
     "NtpDriveModuleExperimentGroupParam";
+const char kNtpMiddleSlotPromoDismissalParam[] =
+    "NtpMiddleSlotPromoDismissalParam";
 const char kNtpPhotosModuleDataParam[] = "NtpPhotosModuleDataParam";
 const char kNtpPhotosModuleOptInTitleParam[] = "NtpPhotosModuleOptInTitleParam";
 const char kNtpPhotosModuleOptInArtWorkParam[] =
diff --git a/components/search/ntp_features.h b/components/search/ntp_features.h
index 58e5aef..5f3be68 100644
--- a/components/search/ntp_features.h
+++ b/components/search/ntp_features.h
@@ -82,6 +82,8 @@
 // Parameter for communicating the experiment group of the Drive module
 // experiment.
 extern const char kNtpDriveModuleExperimentGroupParam[];
+// Parameter determining the type of middle slot promo data to render.
+extern const char kNtpMiddleSlotPromoDismissalParam[];
 // Parameter determining the type of Photos data to render.
 extern const char kNtpPhotosModuleDataParam[];
 // Parameter determining the art work in opt-in card.
diff --git a/components/services/app_service/app_service_mojom_impl_unittest.cc b/components/services/app_service/app_service_mojom_impl_unittest.cc
index 61196aa..0c6bf9a 100644
--- a/components/services/app_service/app_service_mojom_impl_unittest.cc
+++ b/components/services/app_service/app_service_mojom_impl_unittest.cc
@@ -612,18 +612,18 @@
   auto intent_filter_1 = apps_util::CreateIntentFilterForUrlScope(filter_url_1);
   apps_util::AddConditionValue(
       apps::mojom::ConditionType::kScheme, filter_url_2.scheme(),
-      apps::mojom::PatternMatchType::kNone, intent_filter_1);
+      apps::mojom::PatternMatchType::kLiteral, intent_filter_1);
   apps_util::AddConditionValue(
       apps::mojom::ConditionType::kHost, filter_url_2.host(),
-      apps::mojom::PatternMatchType::kNone, intent_filter_1);
+      apps::mojom::PatternMatchType::kLiteral, intent_filter_1);
 
   auto intent_filter_2 = apps_util::CreateIntentFilterForUrlScope(filter_url_3);
   apps_util::AddConditionValue(
       apps::mojom::ConditionType::kScheme, filter_url_2.scheme(),
-      apps::mojom::PatternMatchType::kNone, intent_filter_2);
+      apps::mojom::PatternMatchType::kLiteral, intent_filter_2);
   apps_util::AddConditionValue(
       apps::mojom::ConditionType::kHost, filter_url_2.host(),
-      apps::mojom::PatternMatchType::kNone, intent_filter_2);
+      apps::mojom::PatternMatchType::kLiteral, intent_filter_2);
 
   auto intent_filter_3 = apps_util::CreateIntentFilterForUrlScope(filter_url_1);
 
@@ -681,18 +681,18 @@
   auto intent_filter_1 = apps_util::CreateIntentFilterForUrlScope(filter_url_1);
   apps_util::AddConditionValue(
       apps::mojom::ConditionType::kScheme, filter_url_2.scheme(),
-      apps::mojom::PatternMatchType::kNone, intent_filter_1);
+      apps::mojom::PatternMatchType::kLiteral, intent_filter_1);
   apps_util::AddConditionValue(
       apps::mojom::ConditionType::kHost, filter_url_2.host(),
-      apps::mojom::PatternMatchType::kNone, intent_filter_1);
+      apps::mojom::PatternMatchType::kLiteral, intent_filter_1);
 
   auto intent_filter_2 = apps_util::CreateIntentFilterForUrlScope(filter_url_3);
   apps_util::AddConditionValue(
       apps::mojom::ConditionType::kScheme, filter_url_2.scheme(),
-      apps::mojom::PatternMatchType::kNone, intent_filter_2);
+      apps::mojom::PatternMatchType::kLiteral, intent_filter_2);
   apps_util::AddConditionValue(
       apps::mojom::ConditionType::kHost, filter_url_2.host(),
-      apps::mojom::PatternMatchType::kNone, intent_filter_2);
+      apps::mojom::PatternMatchType::kLiteral, intent_filter_2);
 
   auto intent_filter_3 = apps_util::CreateIntentFilterForUrlScope(filter_url_1);
 
diff --git a/components/services/app_service/public/cpp/app_update_unittest.cc b/components/services/app_service/public/cpp/app_update_unittest.cc
index 18e4b865..31ccaa0 100644
--- a/components/services/app_service/public/cpp/app_update_unittest.cc
+++ b/components/services/app_service/public/cpp/app_update_unittest.cc
@@ -918,14 +918,14 @@
       IntentFilterPtr intent_filter = std::make_unique<IntentFilter>();
 
       ConditionValues scheme_condition_values;
-      scheme_condition_values.push_back(
-          std::make_unique<ConditionValue>("https", PatternMatchType::kNone));
+      scheme_condition_values.push_back(std::make_unique<ConditionValue>(
+          "https", PatternMatchType::kLiteral));
       ConditionPtr scheme_condition = std::make_unique<Condition>(
           ConditionType::kScheme, std::move(scheme_condition_values));
 
       ConditionValues host_condition_values;
       host_condition_values.push_back(std::make_unique<ConditionValue>(
-          "www.google.com", PatternMatchType::kNone));
+          "www.google.com", PatternMatchType::kLiteral));
       auto host_condition = std::make_unique<Condition>(
           ConditionType::kHost, std::move(host_condition_values));
 
@@ -944,15 +944,15 @@
       IntentFilterPtr intent_filter = std::make_unique<IntentFilter>();
 
       ConditionValues scheme_condition_values;
-      scheme_condition_values.push_back(
-          std::make_unique<ConditionValue>("https", PatternMatchType::kNone));
+      scheme_condition_values.push_back(std::make_unique<ConditionValue>(
+          "https", PatternMatchType::kLiteral));
       ConditionPtr scheme_condition = std::make_unique<Condition>(
           ConditionType::kScheme, std::move(scheme_condition_values));
       intent_filter->conditions.push_back(scheme_condition->Clone());
 
       ConditionValues host_condition_values;
       host_condition_values.push_back(std::make_unique<ConditionValue>(
-          "www.abc.com", PatternMatchType::kNone));
+          "www.abc.com", PatternMatchType::kLiteral));
       auto host_condition = std::make_unique<Condition>(
           ConditionType::kHost, std::move(host_condition_values));
       intent_filter->conditions.push_back(host_condition->Clone());
diff --git a/components/services/app_service/public/cpp/features.cc b/components/services/app_service/public/cpp/features.cc
index dd3bdbe1..b969a35 100644
--- a/components/services/app_service/public/cpp/features.cc
+++ b/components/services/app_service/public/cpp/features.cc
@@ -10,6 +10,9 @@
     "AppServicePreferredAppsWithoutMojom", base::FEATURE_ENABLED_BY_DEFAULT};
 
 const base::Feature kAppServiceLaunchWithoutMojom{
-    "AppServiceLaunchWithoutMojom", base::FEATURE_ENABLED_BY_DEFAULT};
+    "AppServiceLaunchWithoutMojom", base::FEATURE_DISABLED_BY_DEFAULT};
+
+const base::Feature kAppServiceSetPermissionWithoutMojom{
+    "AppServiceSetPermissionWithoutMojom", base::FEATURE_DISABLED_BY_DEFAULT};
 
 }  // namespace apps
diff --git a/components/services/app_service/public/cpp/features.h b/components/services/app_service/public/cpp/features.h
index 32bae59..aa51235 100644
--- a/components/services/app_service/public/cpp/features.h
+++ b/components/services/app_service/public/cpp/features.h
@@ -14,6 +14,8 @@
 extern const base::Feature kAppServicePreferredAppsWithoutMojom;
 COMPONENT_EXPORT(APP_TYPES)
 extern const base::Feature kAppServiceLaunchWithoutMojom;
+COMPONENT_EXPORT(APP_TYPES)
+extern const base::Feature kAppServiceSetPermissionWithoutMojom;
 
 }  // namespace apps
 
diff --git a/components/services/app_service/public/cpp/intent.cc b/components/services/app_service/public/cpp/intent.cc
index 4f8800b..a336117 100644
--- a/components/services/app_service/public/cpp/intent.cc
+++ b/components/services/app_service/public/cpp/intent.cc
@@ -39,7 +39,6 @@
 
 bool IntentFile::MatchConditionValue(const ConditionValuePtr& condition_value) {
   switch (condition_value->match_type) {
-    case PatternMatchType::kNone:
     case PatternMatchType::kLiteral:
     case PatternMatchType::kPrefix:
     case PatternMatchType::kSuffix: {
diff --git a/components/services/app_service/public/cpp/intent_filter.cc b/components/services/app_service/public/cpp/intent_filter.cc
index 730a3a26..53af407 100644
--- a/components/services/app_service/public/cpp/intent_filter.cc
+++ b/components/services/app_service/public/cpp/intent_filter.cc
@@ -393,8 +393,6 @@
 PatternMatchType ConvertMojomPatternMatchTypeToPatternMatchType(
     const apps::mojom::PatternMatchType& mojom_pattern_match_type) {
   switch (mojom_pattern_match_type) {
-    case apps::mojom::PatternMatchType::kNone:
-      return PatternMatchType::kNone;
     case apps::mojom::PatternMatchType::kLiteral:
       return PatternMatchType::kLiteral;
     case apps::mojom::PatternMatchType::kPrefix:
@@ -415,8 +413,6 @@
 apps::mojom::PatternMatchType ConvertPatternMatchTypeToMojomPatternMatchType(
     const PatternMatchType& pattern_match_type) {
   switch (pattern_match_type) {
-    case PatternMatchType::kNone:
-      return apps::mojom::PatternMatchType::kNone;
     case PatternMatchType::kLiteral:
       return apps::mojom::PatternMatchType::kLiteral;
     case PatternMatchType::kPrefix:
diff --git a/components/services/app_service/public/cpp/intent_filter.h b/components/services/app_service/public/cpp/intent_filter.h
index 605489d..73ce4b0e 100644
--- a/components/services/app_service/public/cpp/intent_filter.h
+++ b/components/services/app_service/public/cpp/intent_filter.h
@@ -35,35 +35,38 @@
 // field will be matched against.
 // Values are persisted to disk by preferred_apps_converter.h, so should not be
 // changed or removed without migrating existing data.
-ENUM(ConditionType,
-     // Matches the URL scheme (e.g. https, tel).
-     kScheme,
-     // Matches the URL host (e.g. www.google.com).
-     kHost,
-     // Matches the URL path (e.g. /abc/*). Does not include the URL query or
-     // hash.
-     kPath,
-     // Matches the action type (e.g. view, send).
-     kAction,
-     // Matches the top-level mime type (e.g. text/plain).
-     kMimeType,
-     // Matches against files. All files in the Intent must separately match a
-     // ConditionValue for this Condition to match. kFile conditions may only
-     // use the following PatternMatchTypes: kMimeType, kFileExtension,
-     // kIsDirectory, and kGlob.
-     kFile)
+enum class ConditionType {
+  // Matches the URL scheme (e.g. https, tel).
+  kScheme = 0,
+  // Matches the URL host (e.g. www.google.com).
+  kHost = 1,
+  // Matches the URL path (e.g. /abc/*). Does not include the URL query or
+  // hash.
+  kPath = 2,
+  // Matches the action type (e.g. view, send).
+  kAction = 3,
+  // Matches the top-level mime type (e.g. text/plain).
+  kMimeType = 4,
+  // Matches against files. All files in the Intent must separately match a
+  // ConditionValue for this Condition to match. kFile conditions may only
+  // use the following PatternMatchTypes: kMimeType, kFileExtension,
+  // kIsDirectory, and kGlob.
+  kFile = 5
+};
 
 // Describes what pattern matching rules are applied to a ConditionValue.
 // Values are persisted to disk by preferred_apps_converter.h, so should not be
-// changed or removed without migrating existing data.
+// changed or removed without migrating existing data and the integer values
+// should be preserved
 enum class PatternMatchType {
-  kNone = 0,
+  // kNone    Deprecated. Use kLiteral which has the same function
+
   // The ConditionValue is a literal string which must match the value in the
   // Intent exactly.
-  kLiteral,
+  kLiteral = 1,
   // The ConditionValue matches if it is a prefix of the value in the Intent.
   // For example, a ConditionValue of "/users/" matches a value of "/users/me".
-  kPrefix,
+  kPrefix = 2,
   // The ConditionValue is a simple glob pattern which matches against the value
   // in the Intent. The syntax allows the following special characters:
   //  *  - match 0 or more occurrences of the previous character
@@ -71,22 +74,22 @@
   //  \  - escape character
   // All wildcard matching is non-greedy. This syntax is the same as Android:
   // https://developer.android.com/reference/android/os/PatternMatcher#PATTERN_SIMPLE_GLOB
-  kGlob,
+  kGlob = 3,
   // The ConditionValue is a mime type with optional wildcards (e.g.
   // "image/png", or "image/*", or "*/*"), which matches against a mime type
   // from the Intent.
-  kMimeType,
+  kMimeType = 4,
   // The ConditionValue is a file extension (e.g. "png") or a wildcard ("*")
   // which is matched against file names in the Intent. Common double extension
   // file types are supported: for example, a file named "file.tar.gz" matches
   // both "gz" and "tar.gz" ConditionValues.
-  kFileExtension,
+  kFileExtension = 5,
   // The ConditionValue matches any files which are directories.
-  kIsDirectory,
+  kIsDirectory = 6,
   // The ConditionValue matches if it is a suffix of the value in the Intent.
   // For example, a ConditionValue of ".google.com" matches a value of
   // "maps.google.com".
-  kSuffix
+  kSuffix = 7
 };
 
 // A ConditionValue is a possible value that is accepted by a Condition. The
diff --git a/components/services/app_service/public/cpp/intent_filter_util.cc b/components/services/app_service/public/cpp/intent_filter_util.cc
index 59efd93..976e438 100644
--- a/components/services/app_service/public/cpp/intent_filter_util.cc
+++ b/components/services/app_service/public/cpp/intent_filter_util.cc
@@ -21,8 +21,7 @@
   }
 
   if (value1->match_type == apps::PatternMatchType::kSuffix &&
-      (value2->match_type == apps::PatternMatchType::kNone ||
-       value2->match_type == apps::PatternMatchType::kLiteral ||
+      (value2->match_type == apps::PatternMatchType::kLiteral ||
        value2->match_type == apps::PatternMatchType::kSuffix)) {
     return base::EndsWith(/*str=*/value2->value,
                           /*search_for=*/value1->value);
@@ -59,8 +58,7 @@
   }
 
   if (value1->match_type == apps::mojom::PatternMatchType::kSuffix &&
-      (value2->match_type == apps::mojom::PatternMatchType::kNone ||
-       value2->match_type == apps::mojom::PatternMatchType::kLiteral ||
+      (value2->match_type == apps::mojom::PatternMatchType::kLiteral ||
        value2->match_type == apps::mojom::PatternMatchType::kSuffix)) {
     return base::EndsWith(/*str=*/value2->value,
                           /*search_for=*/value1->value);
@@ -165,14 +163,14 @@
 
   intent_filter->AddSingleValueCondition(apps::ConditionType::kAction,
                                          apps_util::kIntentActionView,
-                                         apps::PatternMatchType::kNone);
+                                         apps::PatternMatchType::kLiteral);
 
   intent_filter->AddSingleValueCondition(apps::ConditionType::kScheme,
                                          url.scheme(),
-                                         apps::PatternMatchType::kNone);
+                                         apps::PatternMatchType::kLiteral);
 
   intent_filter->AddSingleValueCondition(apps::ConditionType::kHost, url.host(),
-                                         apps::PatternMatchType::kNone);
+                                         apps::PatternMatchType::kLiteral);
 
   intent_filter->AddSingleValueCondition(apps::ConditionType::kPath, url.path(),
                                          apps::PatternMatchType::kPrefix);
@@ -183,15 +181,17 @@
 apps::mojom::IntentFilterPtr CreateIntentFilterForUrlScope(const GURL& url) {
   auto intent_filter = apps::mojom::IntentFilter::New();
 
-  AddSingleValueCondition(apps::mojom::ConditionType::kAction,
-                          apps_util::kIntentActionView,
-                          apps::mojom::PatternMatchType::kNone, intent_filter);
+  AddSingleValueCondition(
+      apps::mojom::ConditionType::kAction, apps_util::kIntentActionView,
+      apps::mojom::PatternMatchType::kLiteral, intent_filter);
 
   AddSingleValueCondition(apps::mojom::ConditionType::kScheme, url.scheme(),
-                          apps::mojom::PatternMatchType::kNone, intent_filter);
+                          apps::mojom::PatternMatchType::kLiteral,
+                          intent_filter);
 
   AddSingleValueCondition(apps::mojom::ConditionType::kHost, url.host(),
-                          apps::mojom::PatternMatchType::kNone, intent_filter);
+                          apps::mojom::PatternMatchType::kLiteral,
+                          intent_filter);
 
   AddSingleValueCondition(apps::mojom::ConditionType::kPath, url.path(),
                           apps::mojom::PatternMatchType::kPrefix,
@@ -275,7 +275,7 @@
 void UpgradeFilter(apps::IntentFilterPtr& filter) {
   std::vector<apps::ConditionValuePtr> condition_values;
   condition_values.push_back(std::make_unique<apps::ConditionValue>(
-      apps_util::kIntentActionView, apps::PatternMatchType::kNone));
+      apps_util::kIntentActionView, apps::PatternMatchType::kLiteral));
   auto condition = std::make_unique<apps::Condition>(
       apps::ConditionType::kAction, std::move(condition_values));
   filter->conditions.insert(filter->conditions.begin(), std::move(condition));
@@ -284,7 +284,7 @@
 void UpgradeFilter(apps::mojom::IntentFilterPtr& filter) {
   std::vector<apps::mojom::ConditionValuePtr> condition_values;
   condition_values.push_back(apps_util::MakeConditionValue(
-      apps_util::kIntentActionView, apps::mojom::PatternMatchType::kNone));
+      apps_util::kIntentActionView, apps::mojom::PatternMatchType::kLiteral));
   auto condition = apps_util::MakeCondition(apps::mojom::ConditionType::kAction,
                                             std::move(condition_values));
   filter->conditions.insert(filter->conditions.begin(), std::move(condition));
diff --git a/components/services/app_service/public/cpp/intent_filter_util_unittest.cc b/components/services/app_service/public/cpp/intent_filter_util_unittest.cc
index e98e7bd..f53d9c8 100644
--- a/components/services/app_service/public/cpp/intent_filter_util_unittest.cc
+++ b/components/services/app_service/public/cpp/intent_filter_util_unittest.cc
@@ -35,13 +35,13 @@
 
     intent_filter->AddSingleValueCondition(apps::ConditionType::kAction,
                                            apps_util::kIntentActionView,
-                                           apps::PatternMatchType::kNone);
+                                           apps::PatternMatchType::kLiteral);
 
     intent_filter->AddSingleValueCondition(apps::ConditionType::kScheme, scheme,
-                                           apps::PatternMatchType::kNone);
+                                           apps::PatternMatchType::kLiteral);
 
     intent_filter->AddSingleValueCondition(apps::ConditionType::kHost, host,
-                                           apps::PatternMatchType::kNone);
+                                           apps::PatternMatchType::kLiteral);
 
     intent_filter->AddSingleValueCondition(apps::ConditionType::kPath, path,
                                            pattern);
@@ -59,14 +59,14 @@
 
     apps_util::AddSingleValueCondition(
         apps::mojom::ConditionType::kAction, apps_util::kIntentActionView,
-        apps::mojom::PatternMatchType::kNone, intent_filter);
+        apps::mojom::PatternMatchType::kLiteral, intent_filter);
 
     apps_util::AddSingleValueCondition(
         apps::mojom::ConditionType::kScheme, scheme,
-        apps::mojom::PatternMatchType::kNone, intent_filter);
+        apps::mojom::PatternMatchType::kLiteral, intent_filter);
 
     apps_util::AddSingleValueCondition(apps::mojom::ConditionType::kHost, host,
-                                       apps::mojom::PatternMatchType::kNone,
+                                       apps::mojom::PatternMatchType::kLiteral,
                                        intent_filter);
 
     apps_util::AddSingleValueCondition(apps::mojom::ConditionType::kPath, path,
@@ -107,11 +107,11 @@
 
   intent_filter->AddSingleValueCondition(apps::ConditionType::kScheme,
                                          url::kHttpScheme,
-                                         apps::PatternMatchType::kNone);
+                                         apps::PatternMatchType::kLiteral);
 
   intent_filter->AddSingleValueCondition(apps::ConditionType::kHost,
                                          kHostUrlGoogle,
-                                         apps::PatternMatchType::kNone);
+                                         apps::PatternMatchType::kLiteral);
 
   std::set<std::string> links =
       intent_filter->GetSupportedLinksForAppManagement();
@@ -162,15 +162,15 @@
 
   intent_filter->AddSingleValueCondition(apps::ConditionType::kScheme,
                                          url::kHttpScheme,
-                                         apps::PatternMatchType::kNone);
+                                         apps::PatternMatchType::kLiteral);
 
   std::vector<apps::ConditionValuePtr> condition_values;
 
   condition_values.push_back(std::make_unique<apps::ConditionValue>(
-      kHostUrlGoogle, apps::PatternMatchType::kNone));
+      kHostUrlGoogle, apps::PatternMatchType::kLiteral));
 
   condition_values.push_back(std::make_unique<apps::ConditionValue>(
-      kHostUrlGmail, apps::PatternMatchType::kNone));
+      kHostUrlGmail, apps::PatternMatchType::kLiteral));
 
   intent_filter->conditions.push_back(std::make_unique<apps::Condition>(
       apps::ConditionType::kHost, std::move(condition_values)));
@@ -192,14 +192,14 @@
 
   intent_filter->AddSingleValueCondition(apps::ConditionType::kScheme,
                                          url::kHttpScheme,
-                                         apps::PatternMatchType::kNone);
+                                         apps::PatternMatchType::kLiteral);
 
   std::vector<apps::ConditionValuePtr> host_condition_values;
 
   host_condition_values.push_back(std::make_unique<apps::ConditionValue>(
-      kHostUrlGoogle, apps::PatternMatchType::kNone));
+      kHostUrlGoogle, apps::PatternMatchType::kLiteral));
   host_condition_values.push_back(std::make_unique<apps::ConditionValue>(
-      kHostUrlGmail, apps::PatternMatchType::kNone));
+      kHostUrlGmail, apps::PatternMatchType::kLiteral));
 
   intent_filter->conditions.push_back(std::make_unique<apps::Condition>(
       apps::ConditionType::kHost, std::move(host_condition_values)));
@@ -234,7 +234,7 @@
 
   intent_filter->AddSingleValueCondition(apps::ConditionType::kScheme,
                                          url::kHttpScheme,
-                                         apps::PatternMatchType::kNone);
+                                         apps::PatternMatchType::kLiteral);
   intent_filter->AddSingleValueCondition(apps::ConditionType::kHost, host,
                                          apps::PatternMatchType::kSuffix);
   intent_filter->AddSingleValueCondition(apps::ConditionType::kPath,
@@ -265,17 +265,17 @@
   std::vector<apps::ConditionValuePtr> condition_values;
 
   condition_values.push_back(std::make_unique<apps::ConditionValue>(
-      url::kHttpScheme, apps::PatternMatchType::kNone));
+      url::kHttpScheme, apps::PatternMatchType::kLiteral));
 
   condition_values.push_back(std::make_unique<apps::ConditionValue>(
-      url::kHttpsScheme, apps::PatternMatchType::kNone));
+      url::kHttpsScheme, apps::PatternMatchType::kLiteral));
 
   intent_filter->conditions.push_back(std::make_unique<apps::Condition>(
       apps::ConditionType::kScheme, std::move(condition_values)));
 
   intent_filter->AddSingleValueCondition(apps::ConditionType::kHost,
                                          kHostUrlGoogle,
-                                         apps::PatternMatchType::kNone);
+                                         apps::PatternMatchType::kLiteral);
 
   intent_filter->AddSingleValueCondition(apps::ConditionType::kPath,
                                          kPathLiteral,
@@ -293,11 +293,11 @@
 
   intent_filter->AddSingleValueCondition(apps::ConditionType::kScheme,
                                          url::kHttpScheme,
-                                         apps::PatternMatchType::kNone);
+                                         apps::PatternMatchType::kLiteral);
 
   intent_filter->AddSingleValueCondition(apps::ConditionType::kHost,
                                          "m.youtube.com",
-                                         apps::PatternMatchType::kNone);
+                                         apps::PatternMatchType::kLiteral);
 
   intent_filter->AddSingleValueCondition(apps::ConditionType::kPath, ".*",
                                          apps::PatternMatchType::kGlob);
@@ -346,22 +346,22 @@
   auto browser_filter = apps::mojom::IntentFilter::New();
   apps_util::AddSingleValueCondition(
       apps::mojom::ConditionType::kAction, apps_util::kIntentActionView,
-      apps::mojom::PatternMatchType::kNone, browser_filter);
+      apps::mojom::PatternMatchType::kLiteral, browser_filter);
   apps_util::AddSingleValueCondition(
       apps::mojom::ConditionType::kScheme, "https",
-      apps::mojom::PatternMatchType::kNone, browser_filter);
+      apps::mojom::PatternMatchType::kLiteral, browser_filter);
   ASSERT_FALSE(apps_util::IsSupportedLinkForApp(kAppId, browser_filter));
 
   auto host_filter = apps::mojom::IntentFilter::New();
   apps_util::AddSingleValueCondition(
       apps::mojom::ConditionType::kAction, apps_util::kIntentActionView,
-      apps::mojom::PatternMatchType::kNone, host_filter);
+      apps::mojom::PatternMatchType::kLiteral, host_filter);
   apps_util::AddSingleValueCondition(
       apps::mojom::ConditionType::kScheme, "https",
-      apps::mojom::PatternMatchType::kNone, host_filter);
+      apps::mojom::PatternMatchType::kLiteral, host_filter);
   apps_util::AddSingleValueCondition(
       apps::mojom::ConditionType::kHost, "www.example.com",
-      apps::mojom::PatternMatchType::kNone, host_filter);
+      apps::mojom::PatternMatchType::kLiteral, host_filter);
   ASSERT_FALSE(apps_util::IsSupportedLinkForApp(kAppId, browser_filter));
 }
 
@@ -372,20 +372,20 @@
   auto browser_filter = std::make_unique<apps::IntentFilter>();
   browser_filter->AddSingleValueCondition(apps::ConditionType::kAction,
                                           apps_util::kIntentActionView,
-                                          apps::PatternMatchType::kNone);
+                                          apps::PatternMatchType::kLiteral);
   browser_filter->AddSingleValueCondition(apps::ConditionType::kScheme, "https",
-                                          apps::PatternMatchType::kNone);
+                                          apps::PatternMatchType::kLiteral);
   ASSERT_FALSE(apps_util::IsSupportedLinkForApp(kAppId, browser_filter));
 
   auto host_filter = std::make_unique<apps::IntentFilter>();
   host_filter->AddSingleValueCondition(apps::ConditionType::kAction,
                                        apps_util::kIntentActionView,
-                                       apps::PatternMatchType::kNone);
+                                       apps::PatternMatchType::kLiteral);
   host_filter->AddSingleValueCondition(apps::ConditionType::kScheme, "https",
-                                       apps::PatternMatchType::kNone);
+                                       apps::PatternMatchType::kLiteral);
   host_filter->AddSingleValueCondition(apps::ConditionType::kHost,
                                        "www.example.com",
-                                       apps::PatternMatchType::kNone);
+                                       apps::PatternMatchType::kLiteral);
   ASSERT_FALSE(apps_util::IsSupportedLinkForApp(kAppId, browser_filter));
 }
 
@@ -402,7 +402,7 @@
 
   apps_util::AddConditionValue(
       apps::mojom::ConditionType::kHost, "www.google.com",
-      apps::mojom::PatternMatchType::kNone, maps_domain_filter);
+      apps::mojom::PatternMatchType::kLiteral, maps_domain_filter);
 
   ASSERT_TRUE(
       apps_util::FiltersHaveOverlap(maps_domain_filter, google_domain_filter));
@@ -419,7 +419,7 @@
       apps_util::FiltersHaveOverlap(maps_domain_filter, google_domain_filter));
 
   apps_util::AddConditionValue(apps::ConditionType::kHost, "www.google.com",
-                               apps::PatternMatchType::kNone,
+                               apps::PatternMatchType::kLiteral,
                                maps_domain_filter);
 
   ASSERT_TRUE(
@@ -434,9 +434,9 @@
 
   // Filters that shouldn't overlap
   auto wikipedia_com_filter = MakeHostOnlyFilter(
-      ".wikipedia.com", apps::mojom::PatternMatchType::kNone);
-  auto wikipedia_no_subdomain_filter =
-      MakeHostOnlyFilter("wikipedia.org", apps::mojom::PatternMatchType::kNone);
+      ".wikipedia.com", apps::mojom::PatternMatchType::kLiteral);
+  auto wikipedia_no_subdomain_filter = MakeHostOnlyFilter(
+      "wikipedia.org", apps::mojom::PatternMatchType::kLiteral);
 
   ASSERT_FALSE(apps_util::FiltersHaveOverlap(wikipedia_wildcard_filter,
                                              wikipedia_com_filter));
@@ -445,9 +445,9 @@
 
   // Filters that should overlap
   auto wikipedia_subdomain_filter = MakeHostOnlyFilter(
-      "es.wikipedia.org", apps::mojom::PatternMatchType::kNone);
+      "es.wikipedia.org", apps::mojom::PatternMatchType::kLiteral);
   auto wikipedia_empty_subdomain_filter = MakeHostOnlyFilter(
-      ".wikipedia.org", apps::mojom::PatternMatchType::kNone);
+      ".wikipedia.org", apps::mojom::PatternMatchType::kLiteral);
   auto wikipedia_literal_filter = MakeHostOnlyFilter(
       "fr.wikipedia.org", apps::mojom::PatternMatchType::kLiteral);
   auto wikipedia_other_wildcard_filter = MakeHostOnlyFilter(
@@ -474,9 +474,9 @@
 
   // Filters that shouldn't overlap
   auto wikipedia_com_filter =
-      MakeHostOnlyFilter(".wikipedia.com", apps::PatternMatchType::kNone);
+      MakeHostOnlyFilter(".wikipedia.com", apps::PatternMatchType::kLiteral);
   auto wikipedia_no_subdomain_filter =
-      MakeHostOnlyFilter("wikipedia.org", apps::PatternMatchType::kNone);
+      MakeHostOnlyFilter("wikipedia.org", apps::PatternMatchType::kLiteral);
 
   ASSERT_FALSE(apps_util::FiltersHaveOverlap(wikipedia_wildcard_filter,
                                              wikipedia_com_filter));
@@ -485,9 +485,9 @@
 
   // Filters that should overlap
   auto wikipedia_subdomain_filter =
-      MakeHostOnlyFilter("es.wikipedia.org", apps::PatternMatchType::kNone);
+      MakeHostOnlyFilter("es.wikipedia.org", apps::PatternMatchType::kLiteral);
   auto wikipedia_empty_subdomain_filter =
-      MakeHostOnlyFilter(".wikipedia.org", apps::PatternMatchType::kNone);
+      MakeHostOnlyFilter(".wikipedia.org", apps::PatternMatchType::kLiteral);
   auto wikipedia_literal_filter =
       MakeHostOnlyFilter("fr.wikipedia.org", apps::PatternMatchType::kLiteral);
   auto wikipedia_other_wildcard_filter =
diff --git a/components/services/app_service/public/cpp/intent_test_util.cc b/components/services/app_service/public/cpp/intent_test_util.cc
index 30b1476..9f7a063 100644
--- a/components/services/app_service/public/cpp/intent_test_util.cc
+++ b/components/services/app_service/public/cpp/intent_test_util.cc
@@ -21,7 +21,7 @@
   auto intent_filter = std::make_unique<apps::IntentFilter>();
 
   intent_filter->AddSingleValueCondition(apps::ConditionType::kAction, action,
-                                         apps::PatternMatchType::kNone);
+                                         apps::PatternMatchType::kLiteral);
 
   apps::ConditionValues condition_values;
   if (!mime_type.empty()) {
@@ -54,7 +54,7 @@
 
   apps_util::AddSingleValueCondition(
       apps::mojom::ConditionType::kAction, action,
-      apps::mojom::PatternMatchType::kNone, intent_filter);
+      apps::mojom::PatternMatchType::kLiteral, intent_filter);
 
   std::vector<apps::mojom::ConditionValuePtr> condition_values;
   if (!mime_type.empty()) {
@@ -86,7 +86,7 @@
 
   intent_filter->AddSingleValueCondition(apps::ConditionType::kAction,
                                          kIntentActionSend,
-                                         apps::PatternMatchType::kNone);
+                                         apps::PatternMatchType::kLiteral);
 
   std::vector<apps::ConditionValuePtr> condition_values;
   condition_values.push_back(std::make_unique<apps::ConditionValue>(
@@ -126,7 +126,7 @@
 apps::IntentFilterPtr MakeSchemeOnlyFilter(const std::string& scheme) {
   apps::ConditionValues condition_values;
   condition_values.push_back(std::make_unique<apps::ConditionValue>(
-      scheme, apps::PatternMatchType::kNone));
+      scheme, apps::PatternMatchType::kLiteral));
   auto condition = std::make_unique<apps::Condition>(
       apps::ConditionType::kScheme, std::move(condition_values));
 
@@ -140,13 +140,13 @@
                                                   const std::string& host) {
   apps::ConditionValues scheme_condition_values;
   scheme_condition_values.push_back(std::make_unique<apps::ConditionValue>(
-      scheme, apps::PatternMatchType::kNone));
+      scheme, apps::PatternMatchType::kLiteral));
   auto scheme_condition = std::make_unique<apps::Condition>(
       apps::ConditionType::kScheme, std::move(scheme_condition_values));
 
   apps::ConditionValues host_condition_values;
   host_condition_values.push_back(std::make_unique<apps::ConditionValue>(
-      host, apps::PatternMatchType::kNone));
+      host, apps::PatternMatchType::kLiteral));
   auto host_condition = std::make_unique<apps::Condition>(
       apps::ConditionType::kHost, std::move(host_condition_values));
 
@@ -175,7 +175,7 @@
 apps::mojom::IntentFilterPtr CreateSchemeOnlyFilter(const std::string& scheme) {
   std::vector<apps::mojom::ConditionValuePtr> condition_values;
   condition_values.push_back(apps_util::MakeConditionValue(
-      scheme, apps::mojom::PatternMatchType::kNone));
+      scheme, apps::mojom::PatternMatchType::kLiteral));
   auto condition = apps_util::MakeCondition(apps::mojom::ConditionType::kScheme,
                                             std::move(condition_values));
 
@@ -190,13 +190,13 @@
     const std::string& host) {
   std::vector<apps::mojom::ConditionValuePtr> scheme_condition_values;
   scheme_condition_values.push_back(apps_util::MakeConditionValue(
-      scheme, apps::mojom::PatternMatchType::kNone));
+      scheme, apps::mojom::PatternMatchType::kLiteral));
   auto scheme_condition = apps_util::MakeCondition(
       apps::mojom::ConditionType::kScheme, std::move(scheme_condition_values));
 
   std::vector<apps::mojom::ConditionValuePtr> host_condition_values;
   host_condition_values.push_back(apps_util::MakeConditionValue(
-      host, apps::mojom::PatternMatchType::kNone));
+      host, apps::mojom::PatternMatchType::kLiteral));
   auto host_condition = apps_util::MakeCondition(
       apps::mojom::ConditionType::kHost, std::move(host_condition_values));
 
@@ -220,7 +220,7 @@
 
   apps_util::AddSingleValueCondition(
       apps::mojom::ConditionType::kAction, kIntentActionSend,
-      apps::mojom::PatternMatchType::kNone, intent_filter);
+      apps::mojom::PatternMatchType::kLiteral, intent_filter);
 
   std::vector<apps::mojom::ConditionValuePtr> condition_values;
   condition_values.push_back(apps_util::MakeConditionValue(
diff --git a/components/services/app_service/public/cpp/intent_util.cc b/components/services/app_service/public/cpp/intent_util.cc
index 7d7d14d..5f047360 100644
--- a/components/services/app_service/public/cpp/intent_util.cc
+++ b/components/services/app_service/public/cpp/intent_util.cc
@@ -291,8 +291,6 @@
 bool ConditionValueMatches(const std::string& value,
                            const apps::ConditionValuePtr& condition_value) {
   switch (condition_value->match_type) {
-    // Fallthrough as kNone and kLiteral has same matching type.
-    case apps::PatternMatchType::kNone:
     case apps::PatternMatchType::kLiteral:
       return value == condition_value->value;
     case apps::PatternMatchType::kPrefix:
@@ -319,8 +317,6 @@
     const std::string& value,
     const apps::mojom::ConditionValuePtr& condition_value) {
   switch (condition_value->match_type) {
-    // Fallthrough as kNone and kLiteral has same matching type.
-    case apps::mojom::PatternMatchType::kNone:
     case apps::mojom::PatternMatchType::kLiteral:
       return value == condition_value->value;
     case apps::mojom::PatternMatchType::kPrefix:
@@ -347,7 +343,6 @@
     const apps::mojom::IntentFilePtr& file,
     const apps::mojom::ConditionValuePtr& condition_value) {
   switch (condition_value->match_type) {
-    case apps::mojom::PatternMatchType::kNone:
     case apps::mojom::PatternMatchType::kLiteral:
     case apps::mojom::PatternMatchType::kPrefix:
     case apps::mojom::PatternMatchType::kSuffix:
diff --git a/components/services/app_service/public/cpp/intent_util_unittest.cc b/components/services/app_service/public/cpp/intent_util_unittest.cc
index e5823daa..74e4570f 100644
--- a/components/services/app_service/public/cpp/intent_util_unittest.cc
+++ b/components/services/app_service/public/cpp/intent_util_unittest.cc
@@ -20,9 +20,9 @@
   apps::ConditionPtr CreateMultiConditionValuesCondition() {
     std::vector<apps::ConditionValuePtr> condition_values;
     condition_values.push_back(std::make_unique<apps::ConditionValue>(
-        "https", apps::PatternMatchType::kNone));
+        "https", apps::PatternMatchType::kLiteral));
     condition_values.push_back(std::make_unique<apps::ConditionValue>(
-        "http", apps::PatternMatchType::kNone));
+        "http", apps::PatternMatchType::kLiteral));
     auto condition = std::make_unique<apps::Condition>(
         apps::ConditionType::kScheme, std::move(condition_values));
     return condition;
@@ -31,9 +31,9 @@
   apps::mojom::ConditionPtr CreateMultiMojomConditionValuesCondition() {
     std::vector<apps::mojom::ConditionValuePtr> condition_values;
     condition_values.push_back(apps_util::MakeConditionValue(
-        "https", apps::mojom::PatternMatchType::kNone));
+        "https", apps::mojom::PatternMatchType::kLiteral));
     condition_values.push_back(apps_util::MakeConditionValue(
-        "http", apps::mojom::PatternMatchType::kNone));
+        "http", apps::mojom::PatternMatchType::kLiteral));
     auto condition = apps_util::MakeCondition(
         apps::mojom::ConditionType::kScheme, std::move(condition_values));
     return condition;
@@ -222,14 +222,14 @@
 // TODO(crbug.com/1253250): Remove after migrating to non-mojo AppService.
 TEST_F(IntentUtilTest, NoneMatchTypeMojom) {
   auto condition_value = apps_util::MakeConditionValue(
-      "https", apps::mojom::PatternMatchType::kNone);
+      "https", apps::mojom::PatternMatchType::kLiteral);
   EXPECT_TRUE(apps_util::ConditionValueMatches("https", condition_value));
   EXPECT_FALSE(apps_util::ConditionValueMatches("http", condition_value));
 }
 
 TEST_F(IntentUtilTest, NoneMatchType) {
   auto condition_value = std::make_unique<apps::ConditionValue>(
-      "https", apps::PatternMatchType::kNone);
+      "https", apps::PatternMatchType::kLiteral);
   EXPECT_TRUE(apps_util::ConditionValueMatches("https", condition_value));
   EXPECT_FALSE(apps_util::ConditionValueMatches("http", condition_value));
 }
diff --git a/components/services/app_service/public/cpp/preferred_apps_converter.cc b/components/services/app_service/public/cpp/preferred_apps_converter.cc
index 2a35100..89df433 100644
--- a/components/services/app_service/public/cpp/preferred_apps_converter.cc
+++ b/components/services/app_service/public/cpp/preferred_apps_converter.cc
@@ -52,16 +52,22 @@
              << apps::kValueKey << "\" key with string value.";
     return nullptr;
   }
-
   auto match_type = value.FindIntKey(apps::kMatchTypeKey);
   if (!match_type.has_value()) {
     DVLOG(0) << "Fail to parse condition value. Cannot find \""
              << apps::kMatchTypeKey << "\" key with int value.";
     return nullptr;
   }
-
-  return std::make_unique<apps::ConditionValue>(
-      *value_string, static_cast<apps::PatternMatchType>(match_type.value()));
+  // We used to have a kNone=0 defined in the enum which we have merged with
+  // kLiteral. Some legacy storage may still have zero stored in seralized form
+  // as an integer which we can safely treat as kLiteral=1.
+  apps::PatternMatchType pattern_match_type = apps::PatternMatchType::kLiteral;
+  if (match_type > 0) {
+    pattern_match_type =
+        static_cast<apps::PatternMatchType>(match_type.value());
+  }
+  return std::make_unique<apps::ConditionValue>(*value_string,
+                                                pattern_match_type);
 }
 
 apps::ConditionPtr ParseValueToCondition(const base::Value& value) {
diff --git a/components/services/app_service/public/cpp/preferred_apps_converter_unittest.cc b/components/services/app_service/public/cpp/preferred_apps_converter_unittest.cc
index a38ed44..14af7d8 100644
--- a/components/services/app_service/public/cpp/preferred_apps_converter_unittest.cc
+++ b/components/services/app_service/public/cpp/preferred_apps_converter_unittest.cc
@@ -84,19 +84,19 @@
       "   \"intent_filter\": [ {"
       "      \"condition_type\": 3,"
       "      \"condition_values\": [ {"
-      "         \"match_type\": 0,"
+      "         \"match_type\": 1,"
       "         \"value\": \"view\""
       "      } ]"
       "   }, {"
       "      \"condition_type\": 0,"
       "      \"condition_values\": [ {"
-      "         \"match_type\": 0,"
+      "         \"match_type\": 1,"
       "         \"value\": \"https\""
       "      } ]"
       "   }, {"
       "      \"condition_type\": 1,"
       "      \"condition_values\": [ {"
-      "         \"match_type\": 0,"
+      "         \"match_type\": 1,"
       "         \"value\": \"www.google.com\""
       "      } ]"
       "   }, {"
diff --git a/components/services/app_service/public/cpp/preferred_apps_list_unittest.cc b/components/services/app_service/public/cpp/preferred_apps_list_unittest.cc
index 2847b2dd..313a2f82 100644
--- a/components/services/app_service/public/cpp/preferred_apps_list_unittest.cc
+++ b/components/services/app_service/public/cpp/preferred_apps_list_unittest.cc
@@ -140,7 +140,7 @@
   auto intent_filter =
       apps_util::MakeIntentFilterForUrlScope(GURL("https://www.google.com/"));
   apps_util::AddConditionValue(apps::ConditionType::kScheme, "http",
-                               apps::PatternMatchType::kNone, intent_filter);
+                               apps::PatternMatchType::kLiteral, intent_filter);
 
   preferred_apps_.AddPreferredApp(kAppId1, intent_filter);
 
@@ -200,22 +200,24 @@
   GURL filter_url_1 = GURL("https://www.google.com/abc");
   GURL filter_url_2 = GURL("http://www.google.com.au/abc");
   auto intent_filter_1 = apps_util::MakeIntentFilterForUrlScope(filter_url_1);
-  apps_util::AddConditionValue(apps::ConditionType::kScheme,
-                               filter_url_2.scheme(),
-                               apps::PatternMatchType::kNone, intent_filter_1);
+  apps_util::AddConditionValue(
+      apps::ConditionType::kScheme, filter_url_2.scheme(),
+      apps::PatternMatchType::kLiteral, intent_filter_1);
   apps_util::AddConditionValue(apps::ConditionType::kHost, filter_url_2.host(),
-                               apps::PatternMatchType::kNone, intent_filter_1);
+                               apps::PatternMatchType::kLiteral,
+                               intent_filter_1);
   preferred_apps_.AddPreferredApp(kAppId1, intent_filter_1);
   EXPECT_EQ(kAppId1, preferred_apps_.FindPreferredAppForUrl(filter_url_1));
   EXPECT_EQ(kAppId1, preferred_apps_.FindPreferredAppForUrl(filter_url_2));
 
   GURL filter_url_3 = GURL("https://www.abc.com/abc");
   auto intent_filter_2 = apps_util::MakeIntentFilterForUrlScope(filter_url_3);
-  apps_util::AddConditionValue(apps::ConditionType::kScheme,
-                               filter_url_2.scheme(),
-                               apps::PatternMatchType::kNone, intent_filter_2);
+  apps_util::AddConditionValue(
+      apps::ConditionType::kScheme, filter_url_2.scheme(),
+      apps::PatternMatchType::kLiteral, intent_filter_2);
   apps_util::AddConditionValue(apps::ConditionType::kHost, filter_url_2.host(),
-                               apps::PatternMatchType::kNone, intent_filter_2);
+                               apps::PatternMatchType::kLiteral,
+                               intent_filter_2);
   preferred_apps_.AddPreferredApp(kAppId2, intent_filter_2);
   EXPECT_EQ(absl::nullopt,
             preferred_apps_.FindPreferredAppForUrl(filter_url_1));
@@ -228,22 +230,24 @@
   GURL filter_url_1 = GURL("https://www.google.com/abc");
   GURL filter_url_2 = GURL("http://www.google.com.au/abc");
   auto intent_filter_1 = apps_util::MakeIntentFilterForUrlScope(filter_url_1);
-  apps_util::AddConditionValue(apps::ConditionType::kScheme,
-                               filter_url_2.scheme(),
-                               apps::PatternMatchType::kNone, intent_filter_1);
+  apps_util::AddConditionValue(
+      apps::ConditionType::kScheme, filter_url_2.scheme(),
+      apps::PatternMatchType::kLiteral, intent_filter_1);
   apps_util::AddConditionValue(apps::ConditionType::kHost, filter_url_2.host(),
-                               apps::PatternMatchType::kNone, intent_filter_1);
+                               apps::PatternMatchType::kLiteral,
+                               intent_filter_1);
   auto replaced_app_preferences =
       preferred_apps_.AddPreferredApp(kAppId1, intent_filter_1);
   EXPECT_EQ(0u, replaced_app_preferences.size());
 
   GURL filter_url_3 = GURL("https://www.abc.com/abc");
   auto intent_filter_2 = apps_util::MakeIntentFilterForUrlScope(filter_url_3);
-  apps_util::AddConditionValue(apps::ConditionType::kScheme,
-                               filter_url_2.scheme(),
-                               apps::PatternMatchType::kNone, intent_filter_2);
+  apps_util::AddConditionValue(
+      apps::ConditionType::kScheme, filter_url_2.scheme(),
+      apps::PatternMatchType::kLiteral, intent_filter_2);
   apps_util::AddConditionValue(apps::ConditionType::kHost, filter_url_2.host(),
-                               apps::PatternMatchType::kNone, intent_filter_2);
+                               apps::PatternMatchType::kLiteral,
+                               intent_filter_2);
   replaced_app_preferences =
       preferred_apps_.AddPreferredApp(kAppId2, intent_filter_2);
   EXPECT_EQ(1u, replaced_app_preferences.size());
@@ -252,11 +256,12 @@
 
   GURL filter_url_4 = GURL("http://www.example.com/abc");
   auto intent_filter_3 = apps_util::MakeIntentFilterForUrlScope(filter_url_3);
-  apps_util::AddConditionValue(apps::ConditionType::kScheme,
-                               filter_url_4.scheme(),
-                               apps::PatternMatchType::kNone, intent_filter_3);
+  apps_util::AddConditionValue(
+      apps::ConditionType::kScheme, filter_url_4.scheme(),
+      apps::PatternMatchType::kLiteral, intent_filter_3);
   apps_util::AddConditionValue(apps::ConditionType::kHost, filter_url_4.host(),
-                               apps::PatternMatchType::kNone, intent_filter_3);
+                               apps::PatternMatchType::kLiteral,
+                               intent_filter_3);
   // Test when replacing multiple preferred app entries with same app id.
   replaced_app_preferences =
       preferred_apps_.AddPreferredApp(kAppId1, intent_filter_1);
@@ -314,22 +319,24 @@
   GURL filter_url_1 = GURL("https://www.google.com/abc");
   GURL filter_url_2 = GURL("http://www.google.com.au/abc");
   auto intent_filter_1 = apps_util::MakeIntentFilterForUrlScope(filter_url_1);
-  apps_util::AddConditionValue(apps::ConditionType::kScheme,
-                               filter_url_2.scheme(),
-                               apps::PatternMatchType::kNone, intent_filter_1);
+  apps_util::AddConditionValue(
+      apps::ConditionType::kScheme, filter_url_2.scheme(),
+      apps::PatternMatchType::kLiteral, intent_filter_1);
   apps_util::AddConditionValue(apps::ConditionType::kHost, filter_url_2.host(),
-                               apps::PatternMatchType::kNone, intent_filter_1);
+                               apps::PatternMatchType::kLiteral,
+                               intent_filter_1);
   preferred_apps_.AddPreferredApp(kAppId1, intent_filter_1);
   EXPECT_EQ(kAppId1, preferred_apps_.FindPreferredAppForUrl(filter_url_1));
   EXPECT_EQ(kAppId1, preferred_apps_.FindPreferredAppForUrl(filter_url_2));
 
   GURL filter_url_3 = GURL("https://www.abc.com/abc");
   auto intent_filter_2 = apps_util::MakeIntentFilterForUrlScope(filter_url_3);
-  apps_util::AddConditionValue(apps::ConditionType::kScheme,
-                               filter_url_2.scheme(),
-                               apps::PatternMatchType::kNone, intent_filter_2);
+  apps_util::AddConditionValue(
+      apps::ConditionType::kScheme, filter_url_2.scheme(),
+      apps::PatternMatchType::kLiteral, intent_filter_2);
   apps_util::AddConditionValue(apps::ConditionType::kHost, filter_url_2.host(),
-                               apps::PatternMatchType::kNone, intent_filter_2);
+                               apps::PatternMatchType::kLiteral,
+                               intent_filter_2);
   preferred_apps_.AddPreferredApp(kAppId1, intent_filter_2);
   EXPECT_EQ(kAppId1, preferred_apps_.FindPreferredAppForUrl(filter_url_1));
   EXPECT_EQ(kAppId1, preferred_apps_.FindPreferredAppForUrl(filter_url_2));
@@ -340,11 +347,12 @@
   GURL filter_url_1 = GURL("https://www.google.com/abc");
   GURL filter_url_2 = GURL("http://www.google.com.au/abc");
   auto intent_filter_1 = apps_util::MakeIntentFilterForUrlScope(filter_url_1);
-  apps_util::AddConditionValue(apps::ConditionType::kScheme,
-                               filter_url_2.scheme(),
-                               apps::PatternMatchType::kNone, intent_filter_1);
+  apps_util::AddConditionValue(
+      apps::ConditionType::kScheme, filter_url_2.scheme(),
+      apps::PatternMatchType::kLiteral, intent_filter_1);
   apps_util::AddConditionValue(apps::ConditionType::kHost, filter_url_2.host(),
-                               apps::PatternMatchType::kNone, intent_filter_1);
+                               apps::PatternMatchType::kLiteral,
+                               intent_filter_1);
   preferred_apps_.AddPreferredApp(kAppId1, intent_filter_1);
   EXPECT_EQ(kAppId1, preferred_apps_.FindPreferredAppForUrl(filter_url_1));
   EXPECT_EQ(kAppId1, preferred_apps_.FindPreferredAppForUrl(filter_url_2));
@@ -393,7 +401,7 @@
   auto intent_filter =
       apps_util::MakeIntentFilterForUrlScope(GURL("https://www.google.com/"));
   apps_util::AddConditionValue(apps::ConditionType::kScheme, "http",
-                               apps::PatternMatchType::kNone, intent_filter);
+                               apps::PatternMatchType::kLiteral, intent_filter);
   preferred_apps_.AddPreferredApp(kAppId1, intent_filter);
 
   GURL url_https = GURL("https://www.google.com/");
@@ -447,7 +455,7 @@
   auto intent_filter_to_delete =
       apps_util::MakeIntentFilterForUrlScope(GURL("http://www.google.com/"));
   apps_util::AddConditionValue(apps::ConditionType::kScheme, "https",
-                               apps::PatternMatchType::kNone,
+                               apps::PatternMatchType::kLiteral,
                                intent_filter_to_delete);
 
   preferred_apps_.AddPreferredApp(kAppId1, intent_filter_set);
@@ -470,27 +478,30 @@
 
   // Filter 1 handles url 1 and 2.
   auto intent_filter_1 = apps_util::MakeIntentFilterForUrlScope(filter_url_1);
-  apps_util::AddConditionValue(apps::ConditionType::kScheme,
-                               filter_url_2.scheme(),
-                               apps::PatternMatchType::kNone, intent_filter_1);
+  apps_util::AddConditionValue(
+      apps::ConditionType::kScheme, filter_url_2.scheme(),
+      apps::PatternMatchType::kLiteral, intent_filter_1);
   apps_util::AddConditionValue(apps::ConditionType::kHost, filter_url_2.host(),
-                               apps::PatternMatchType::kNone, intent_filter_1);
+                               apps::PatternMatchType::kLiteral,
+                               intent_filter_1);
 
   // Filter 2 handles url 2 and 3.
   auto intent_filter_2 = apps_util::MakeIntentFilterForUrlScope(filter_url_3);
-  apps_util::AddConditionValue(apps::ConditionType::kScheme,
-                               filter_url_2.scheme(),
-                               apps::PatternMatchType::kNone, intent_filter_2);
+  apps_util::AddConditionValue(
+      apps::ConditionType::kScheme, filter_url_2.scheme(),
+      apps::PatternMatchType::kLiteral, intent_filter_2);
   apps_util::AddConditionValue(apps::ConditionType::kHost, filter_url_2.host(),
-                               apps::PatternMatchType::kNone, intent_filter_2);
+                               apps::PatternMatchType::kLiteral,
+                               intent_filter_2);
 
   // Filter 3 handles url 3 and 4.
   auto intent_filter_3 = apps_util::MakeIntentFilterForUrlScope(filter_url_3);
-  apps_util::AddConditionValue(apps::ConditionType::kScheme,
-                               filter_url_4.scheme(),
-                               apps::PatternMatchType::kNone, intent_filter_3);
+  apps_util::AddConditionValue(
+      apps::ConditionType::kScheme, filter_url_4.scheme(),
+      apps::PatternMatchType::kLiteral, intent_filter_3);
   apps_util::AddConditionValue(apps::ConditionType::kHost, filter_url_4.host(),
-                               apps::PatternMatchType::kNone, intent_filter_3);
+                               apps::PatternMatchType::kLiteral,
+                               intent_filter_3);
 
   preferred_apps_.AddPreferredApp(kAppId1, intent_filter_1);
   preferred_apps_.AddPreferredApp(kAppId1, intent_filter_3);
@@ -567,7 +578,7 @@
   auto intent_filter =
       apps_util::MakeIntentFilterForUrlScope(GURL("https://www.google.com/"));
   apps_util::AddConditionValue(apps::ConditionType::kScheme, "http",
-                               apps::PatternMatchType::kNone, intent_filter);
+                               apps::PatternMatchType::kLiteral, intent_filter);
 
   preferred_apps_.AddPreferredApp(kAppId1, intent_filter);
 
@@ -678,7 +689,7 @@
   auto intent_filter =
       apps_util::MakeIntentFilterForUrlScope(GURL("https://www.example.com/"));
   apps_util::AddConditionValue(apps::ConditionType::kScheme, "ftp",
-                               apps::PatternMatchType::kNone, intent_filter);
+                               apps::PatternMatchType::kLiteral, intent_filter);
   preferred_apps_.AddPreferredApp(kAppId1, intent_filter);
 
   preferred_apps_.DeleteSupportedLinks(kAppId1);
diff --git a/components/services/app_service/public/mojom/types.mojom b/components/services/app_service/public/mojom/types.mojom
index 063bae78..7d3be7e 100644
--- a/components/services/app_service/public/mojom/types.mojom
+++ b/components/services/app_service/public/mojom/types.mojom
@@ -378,8 +378,8 @@
 
 // The pattern match type for intent filter pattern condition.
 enum PatternMatchType {
-  kNone = 0,
-  kLiteral,
+  // kNone = 0   Deprecated. Use kLiteral which has the same function
+  kLiteral = 1,
   kPrefix,
   kGlob,
   kMimeType,
diff --git a/components/services/storage/service_worker/service_worker_database.cc b/components/services/storage/service_worker/service_worker_database.cc
index 0305f13c..914b8a7 100644
--- a/components/services/storage/service_worker/service_worker_database.cc
+++ b/components/services/storage/service_worker/service_worker_database.cc
@@ -1632,12 +1632,36 @@
   (*out)->key = key;
   (*out)->version_id = data.version_id();
   (*out)->is_active = data.is_active();
+  // The old protobuf may not have fetch_handler_type.
   (*out)->fetch_handler_type =
-      blink::mojom::ServiceWorkerFetchHandlerType::kNoHandler;
-  if (data.has_fetch_handler()) {
-    // TODO(crbug.com/1347319): implement other fetch_handler_type.
-    (*out)->fetch_handler_type =
-        blink::mojom::ServiceWorkerFetchHandlerType::kNotSkippable;
+      (data.has_fetch_handler())
+          ? blink::mojom::ServiceWorkerFetchHandlerType::kNotSkippable
+          : blink::mojom::ServiceWorkerFetchHandlerType::kNoHandler;
+  if (data.has_fetch_handler_type()) {
+    if (!data.has_fetch_handler()) {
+      DLOG(ERROR) << "has_fetch_handler must be true if fetch_handler_type"
+                  << " is set.";
+      return Status::kErrorCorrupted;
+    }
+    if (!ServiceWorkerRegistrationData_FetchHandlerType_IsValid(
+            data.fetch_handler_type())) {
+      DLOG(ERROR) << "Fetch handler type '" << data.fetch_handler_type()
+                  << "' is not valid.";
+      return Status::kErrorCorrupted;
+    }
+    switch (data.fetch_handler_type()) {
+      case ServiceWorkerRegistrationData::NOT_SKIPPABLE:
+        (*out)->fetch_handler_type =
+            blink::mojom::ServiceWorkerFetchHandlerType::kNotSkippable;
+        break;
+      // TODO(crbug.com/1347319): implement other fetch_handler_type.
+      default:
+        // UNKNOWN_FETCH_HANDLER, which must not be stored, should also be
+        // handled here.
+        DLOG(ERROR) << "Fetch handler type '" << data.fetch_handler_type()
+                    << "' is not known.";
+        return Status::kErrorCorrupted;
+    }
   }
   (*out)->last_update_check = base::Time::FromDeltaSinceWindowsEpoch(
       base::Microseconds(data.last_update_check_time()));
@@ -1784,6 +1808,18 @@
   data.set_has_fetch_handler(
       registration.fetch_handler_type !=
       blink::mojom::ServiceWorkerFetchHandlerType::kNoHandler);
+  if (data.has_fetch_handler()) {
+    switch (registration.fetch_handler_type) {
+      case blink::mojom::ServiceWorkerFetchHandlerType::kNotSkippable:
+        data.set_fetch_handler_type(
+            ServiceWorkerRegistrationData::NOT_SKIPPABLE);
+        break;
+      // TODO(crbug.com/1347319): implement other fetch_handler_type.
+      default:
+        DCHECK(false) << "Unknown fetch_handler_type is used."
+                      << registration.fetch_handler_type;
+    }
+  }
   data.set_last_update_check_time(
       registration.last_update_check.ToDeltaSinceWindowsEpoch()
           .InMicroseconds());
diff --git a/components/services/storage/service_worker/service_worker_database.proto b/components/services/storage/service_worker/service_worker_database.proto
index 940b293..736c530 100644
--- a/components/services/storage/service_worker/service_worker_database.proto
+++ b/components/services/storage/service_worker/service_worker_database.proto
@@ -22,6 +22,7 @@
   optional string header = 2;
 }
 
+// NEXT ID TO USE: 23
 message ServiceWorkerRegistrationData {
   enum ServiceWorkerScriptType {
     CLASSIC = 0;
@@ -41,6 +42,10 @@
     NORMAL_FRAME = 0;
     FENCED_FRAME = 1;
   }
+  enum FetchHandlerType {
+    UNKNOWN_FETCH_HANDLER = 0;
+    NOT_SKIPPABLE = 1;
+  }
 
   required int64 registration_id = 1;
   required string scope_url = 2;
@@ -53,6 +58,8 @@
 
   required bool is_active = 5;
   required bool has_fetch_handler = 6;
+  optional FetchHandlerType fetch_handler_type = 22
+      [default = UNKNOWN_FETCH_HANDLER];
 
   // Serialized by Time::FromDeltaSinceWindowsEpoch().
   required int64 last_update_check_time = 7;
diff --git a/components/services/storage/service_worker/service_worker_database_unittest.cc b/components/services/storage/service_worker/service_worker_database_unittest.cc
index bc63883..b284e3d 100644
--- a/components/services/storage/service_worker/service_worker_database_unittest.cc
+++ b/components/services/storage/service_worker/service_worker_database_unittest.cc
@@ -2464,6 +2464,7 @@
   data.set_version_id(1);
   data.set_is_active(true);
   data.set_has_fetch_handler(true);
+  data.set_fetch_handler_type(ServiceWorkerRegistrationData::NOT_SKIPPABLE);
   data.set_last_update_check_time(
       base::Time::Now().ToDeltaSinceWindowsEpoch().InMicroseconds());
 
@@ -2584,6 +2585,7 @@
   data.set_version_id(1);
   data.set_is_active(true);
   data.set_has_fetch_handler(true);
+  data.set_fetch_handler_type(ServiceWorkerRegistrationData::NOT_SKIPPABLE);
   data.set_last_update_check_time(
       base::Time::Now().ToDeltaSinceWindowsEpoch().InMicroseconds());
 
diff --git a/components/storage_monitor/storage_monitor_chromeos.cc b/components/storage_monitor/storage_monitor_chromeos.cc
index 96f392f..9cc8dd8 100644
--- a/components/storage_monitor/storage_monitor_chromeos.cc
+++ b/components/storage_monitor/storage_monitor_chromeos.cc
@@ -194,7 +194,7 @@
 
 void StorageMonitorCros::OnMountEvent(
     DiskMountManager::MountEvent event,
-    chromeos::MountError error_code,
+    ash::MountError error_code,
     const DiskMountManager::MountPointInfo& mount_info) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
@@ -202,7 +202,7 @@
   if (mount_info.mount_type != ash::MountType::kDevice)
     return;
   // Ignore errors.
-  if (error_code != chromeos::MOUNT_ERROR_NONE)
+  if (error_code != ash::MountError::kNone)
     return;
   if (mount_info.mount_condition != ash::disks::MOUNT_CONDITION_NONE)
     return;
@@ -268,8 +268,8 @@
 // Forwards result to |EjectDevice| caller.
 void NotifyUnmountResult(
     base::OnceCallback<void(StorageMonitor::EjectStatus)> callback,
-    chromeos::MountError error_code) {
-  if (error_code == chromeos::MOUNT_ERROR_NONE)
+    ash::MountError error_code) {
+  if (error_code == ash::MountError::kNone)
     std::move(callback).Run(StorageMonitor::EJECT_OK);
   else
     std::move(callback).Run(StorageMonitor::EJECT_FAILURE);
diff --git a/components/storage_monitor/storage_monitor_chromeos.h b/components/storage_monitor/storage_monitor_chromeos.h
index 390e8f8..7e59e67 100644
--- a/components/storage_monitor/storage_monitor_chromeos.h
+++ b/components/storage_monitor/storage_monitor_chromeos.h
@@ -58,7 +58,7 @@
                              const ash::disks::Disk& disk) override;
   void OnMountEvent(
       ash::disks::DiskMountManager::MountEvent event,
-      chromeos::MountError error_code,
+      ash::MountError error_code,
       const ash::disks::DiskMountManager::MountPointInfo& mount_info) override;
 
   // StorageMonitor implementation.
diff --git a/components/storage_monitor/storage_monitor_chromeos_unittest.cc b/components/storage_monitor/storage_monitor_chromeos_unittest.cc
index fbe7a5e..08e9c09 100644
--- a/components/storage_monitor/storage_monitor_chromeos_unittest.cc
+++ b/components/storage_monitor/storage_monitor_chromeos_unittest.cc
@@ -85,7 +85,7 @@
 
   void OnMountEvent(
       DiskMountManager::MountEvent event,
-      chromeos::MountError error_code,
+      ash::MountError error_code,
       const DiskMountManager::MountPointInfo& mount_info) override {
     StorageMonitorCros::OnMountEvent(event, error_code, mount_info);
   }
@@ -122,7 +122,7 @@
   void SetUp() override;
   void TearDown() override;
 
-  void MountDevice(chromeos::MountError error_code,
+  void MountDevice(ash::MountError error_code,
                    const DiskMountManager::MountPointInfo& mount_info,
                    const std::string& unique_id,
                    const std::string& device_label,
@@ -131,7 +131,7 @@
                    ash::DeviceType device_type,
                    uint64_t device_size_in_bytes);
 
-  void UnmountDevice(chromeos::MountError error_code,
+  void UnmountDevice(ash::MountError error_code,
                      const DiskMountManager::MountPointInfo& mount_info);
 
   uint64_t GetDeviceStorageSize(const std::string& device_location);
@@ -200,7 +200,7 @@
 }
 
 void StorageMonitorCrosTest::MountDevice(
-    chromeos::MountError error_code,
+    ash::MountError error_code,
     const DiskMountManager::MountPointInfo& mount_info,
     const std::string& unique_id,
     const std::string& device_label,
@@ -208,7 +208,7 @@
     const std::string& product_name,
     ash::DeviceType device_type,
     uint64_t device_size_in_bytes) {
-  if (error_code == chromeos::MOUNT_ERROR_NONE) {
+  if (error_code == ash::MountError::kNone) {
     disk_mount_manager_mock_->CreateDiskEntryForMountDevice(
         mount_info, unique_id, device_label, vendor_name, product_name,
         device_type, device_size_in_bytes, false /* is_parent */,
@@ -220,10 +220,10 @@
 }
 
 void StorageMonitorCrosTest::UnmountDevice(
-    chromeos::MountError error_code,
+    ash::MountError error_code,
     const DiskMountManager::MountPointInfo& mount_info) {
   monitor_->OnMountEvent(DiskMountManager::UNMOUNTING, error_code, mount_info);
-  if (error_code == chromeos::MOUNT_ERROR_NONE)
+  if (error_code == ash::MountError::kNone)
     disk_mount_manager_mock_->RemoveDiskEntryForMountDevice(mount_info);
   task_environment_.RunUntilIdle();
 }
@@ -260,7 +260,7 @@
   DiskMountManager::MountPointInfo mount_info(kDevice1, mount_path1.value(),
                                               ash::MountType::kDevice,
                                               ash::disks::MOUNT_CONDITION_NONE);
-  MountDevice(chromeos::MOUNT_ERROR_NONE,
+  MountDevice(ash::MountError::kNone,
               mount_info,
               kUniqueId1,
               kDevice1Name,
@@ -274,7 +274,7 @@
             observer().last_attached().device_id());
   EXPECT_EQ(mount_path1.value(), observer().last_attached().location());
 
-  UnmountDevice(chromeos::MOUNT_ERROR_NONE, mount_info);
+  UnmountDevice(ash::MountError::kNone, mount_info);
   EXPECT_EQ(1, observer().attach_calls());
   EXPECT_EQ(1, observer().detach_calls());
   EXPECT_EQ(GetDCIMDeviceId(kUniqueId1),
@@ -285,7 +285,7 @@
   DiskMountManager::MountPointInfo mount_info2(
       kDevice2, mount_path2.value(), ash::MountType::kDevice,
       ash::disks::MOUNT_CONDITION_NONE);
-  MountDevice(chromeos::MOUNT_ERROR_NONE,
+  MountDevice(ash::MountError::kNone,
               mount_info2,
               kUniqueId2,
               kDevice2Name,
@@ -299,7 +299,7 @@
             observer().last_attached().device_id());
   EXPECT_EQ(mount_path2.value(), observer().last_attached().location());
 
-  UnmountDevice(chromeos::MOUNT_ERROR_NONE, mount_info2);
+  UnmountDevice(ash::MountError::kNone, mount_info2);
   EXPECT_EQ(2, observer().attach_calls());
   EXPECT_EQ(2, observer().detach_calls());
   EXPECT_EQ(GetDCIMDeviceId(kUniqueId2),
@@ -318,7 +318,7 @@
   const std::string device_id = StorageInfo::MakeDeviceId(
       StorageInfo::REMOVABLE_MASS_STORAGE_NO_DCIM,
       kFSUniqueIdPrefix + kUniqueId);
-  MountDevice(chromeos::MOUNT_ERROR_NONE,
+  MountDevice(ash::MountError::kNone,
               mount_info,
               kUniqueId,
               kDevice1Name,
@@ -343,7 +343,7 @@
   DiskMountManager::MountPointInfo mount_info(kDevice1, mount_path.value(),
                                               ash::MountType::kDevice,
                                               ash::disks::MOUNT_CONDITION_NONE);
-  MountDevice(chromeos::MOUNT_ERROR_UNKNOWN,
+  MountDevice(ash::MountError::kUnknown,
               mount_info,
               kUniqueId,
               kDevice1Name,
@@ -356,7 +356,7 @@
 
   // Not a device
   mount_info.mount_type = ash::MountType::kArchive;
-  MountDevice(chromeos::MOUNT_ERROR_NONE,
+  MountDevice(ash::MountError::kNone,
               mount_info,
               kUniqueId,
               kDevice1Name,
@@ -371,7 +371,7 @@
   mount_info.mount_type = ash::MountType::kDevice;
   mount_info.mount_condition =
       ash::disks::MOUNT_CONDITION_UNSUPPORTED_FILESYSTEM;
-  MountDevice(chromeos::MOUNT_ERROR_NONE,
+  MountDevice(ash::MountError::kNone,
               mount_info,
               kUniqueId,
               kDevice1Name,
@@ -389,7 +389,7 @@
   DiskMountManager::MountPointInfo mount_info1(
       kSDCardDeviceName1, mount_path1.value(), ash::MountType::kDevice,
       ash::disks::MOUNT_CONDITION_NONE);
-  MountDevice(chromeos::MOUNT_ERROR_NONE,
+  MountDevice(ash::MountError::kNone,
               mount_info1,
               kUniqueId2,
               kSDCardDeviceName1,
@@ -403,7 +403,7 @@
             observer().last_attached().device_id());
   EXPECT_EQ(mount_path1.value(), observer().last_attached().location());
 
-  UnmountDevice(chromeos::MOUNT_ERROR_NONE, mount_info1);
+  UnmountDevice(ash::MountError::kNone, mount_info1);
   EXPECT_EQ(1, observer().attach_calls());
   EXPECT_EQ(1, observer().detach_calls());
   EXPECT_EQ(GetDCIMDeviceId(kUniqueId2),
@@ -414,7 +414,7 @@
   DiskMountManager::MountPointInfo mount_info2(
       kSDCardDeviceName2, mount_path2.value(), ash::MountType::kDevice,
       ash::disks::MOUNT_CONDITION_NONE);
-  MountDevice(chromeos::MOUNT_ERROR_NONE,
+  MountDevice(ash::MountError::kNone,
               mount_info2,
               kUniqueId2,
               kSDCardDeviceName2,
@@ -428,7 +428,7 @@
             observer().last_attached().device_id());
   EXPECT_EQ(mount_path2.value(), observer().last_attached().location());
 
-  UnmountDevice(chromeos::MOUNT_ERROR_NONE, mount_info2);
+  UnmountDevice(ash::MountError::kNone, mount_info2);
   EXPECT_EQ(2, observer().attach_calls());
   EXPECT_EQ(2, observer().detach_calls());
   EXPECT_EQ(GetDCIMDeviceId(kUniqueId2),
@@ -441,7 +441,7 @@
   DiskMountManager::MountPointInfo mount_info(
       kEmptyDeviceLabel, mount_path1.value(), ash::MountType::kDevice,
       ash::disks::MOUNT_CONDITION_NONE);
-  MountDevice(chromeos::MOUNT_ERROR_NONE,
+  MountDevice(ash::MountError::kNone,
               mount_info,
               kUniqueId1,
               kEmptyDeviceLabel,
@@ -455,7 +455,7 @@
             observer().last_attached().device_id());
   EXPECT_EQ(mount_path1.value(), observer().last_attached().location());
 
-  UnmountDevice(chromeos::MOUNT_ERROR_NONE, mount_info);
+  UnmountDevice(ash::MountError::kNone, mount_info);
   EXPECT_EQ(1, observer().attach_calls());
   EXPECT_EQ(1, observer().detach_calls());
   EXPECT_EQ(GetDCIMDeviceId(kUniqueId1),
@@ -468,7 +468,7 @@
   DiskMountManager::MountPointInfo mount_info(
       kEmptyDeviceLabel, mount_path1.value(), ash::MountType::kDevice,
       ash::disks::MOUNT_CONDITION_NONE);
-  MountDevice(chromeos::MOUNT_ERROR_NONE,
+  MountDevice(ash::MountError::kNone,
               mount_info,
               kUniqueId1,
               kEmptyDeviceLabel,
@@ -483,7 +483,7 @@
   EXPECT_EQ(mount_path1.value(), observer().last_attached().location());
 
   EXPECT_EQ(kDevice1SizeInBytes, GetDeviceStorageSize(mount_path1.value()));
-  UnmountDevice(chromeos::MOUNT_ERROR_NONE, mount_info);
+  UnmountDevice(ash::MountError::kNone, mount_info);
   EXPECT_EQ(1, observer().attach_calls());
   EXPECT_EQ(1, observer().detach_calls());
   EXPECT_EQ(GetDCIMDeviceId(kUniqueId1),
@@ -496,7 +496,7 @@
   DiskMountManager::MountPointInfo mount_info(
       kEmptyDeviceLabel, mount_path1.value(), ash::MountType::kDevice,
       ash::disks::MOUNT_CONDITION_NONE);
-  MountDevice(chromeos::MOUNT_ERROR_NONE,
+  MountDevice(ash::MountError::kNone,
               mount_info,
               kUniqueId1,
               kEmptyDeviceLabel,
@@ -511,7 +511,7 @@
   ON_CALL(*disk_mount_manager_mock_, UnmountPath(_, _))
       .WillByDefault([](const std::string& location,
                         DiskMountManager::UnmountPathCallback cb) {
-        std::move(cb).Run(chromeos::MOUNT_ERROR_NONE);
+        std::move(cb).Run(ash::MountError::kNone);
       });
   EXPECT_CALL(*disk_mount_manager_mock_,
               UnmountPath(observer().last_attached().location(), _));
diff --git a/components/user_education/README.md b/components/user_education/README.md
index 9a65e6b..bb4b5d1 100644
--- a/components/user_education/README.md
+++ b/components/user_education/README.md
@@ -139,13 +139,121 @@
 
 ## Tutorials
 
-[TBD]
+Tutorials are the more complicated, in-depth way to display a series of help
+bubbles. Often an IPH is an entry point to a Tutorial but Tutorials can also be
+launched from e.g. a "What's New" or "Tips" page.
 
-## New Badge
+Tutorials are:
+  * **Intentional** - the user must always opt-in to seeing a Tutorial.
+  * **Repeatable** - the user may view a Tutorial any number of times, and may
+    view any number of Tutorials.
+  * **In-Depth** - a Tutorial can breadcrumb the user around the UI, requesting
+    the user engage in any number of behaviors, and will respond to those
+    actions.
 
-[TBD]
+Your application will provide a
+[TutorialService](./common/tutorial_service.h) with a
+[TutorialRegistry](./common/tutorial_registry.h). In order to add a new
+Tutorial, you will need to:
+  1. Declare a [TutorialIdentifier](./common/tutorial_identifier.h) in an
+     accessible location.
+  2. Register the `TutorialIdentifier` and
+     [TutorialDescription](./common/tutorial_description.h); details will be
+     provided below.
+  3. Create an entry point for the Tutorial:
+     * Directly call `TutorialService::StartTutorial()`, or...
+     * Register an IPH using the `CreateForTutorialPromo()` factory method.
 
-## Adding User Education to your application
+### Defining and registering your Tutorial
+
+A [TutorialDescription](./common/tutorial_description.h) is the template from
+which a [Tutorial](./common/tutorial.h) is built. A `Tutorial` is a stateful,
+executable object that "runs" the Tutorial itself; since they can't be reused,
+one needs to be created every time the Tutorial is started.
+
+There are only a few fields in a `TutorialDescription`:
+  * **steps** - Contains a sequence of user actions, UI changes, and the help
+    bubbles that will be shown in each step.
+  * **histograms** - Must be populated if you want UMA histograms regarding user
+    engagement with your Tutorial.
+      * The preferred syntax is:
+        ```
+        const char kMyTutorialHistogramPrefix[] = "MyTutorial";
+        
+        tutorial_description.histograms =
+            user_education::MakeTutorialHistograms<kMyTutorialHistogramPrefix>(
+                tutorial_description.steps.size());
+        ```
+      * The `kMyTutorialHistogramPrefix` needs to be declared as a local
+        `const char[]` and have a globally-unique value. This will appear in UMA
+        histogram entries associated with your tutorial. If this value is
+        duplicated the histogram behavior will be undefined.
+      * Note that this cannot be done automatically by the TutorialRegistry as
+        the UMA histograms won't work without the static declarations
+        implemented by the `TutorialHistogramsImpl<>` template class (via C++
+        template specialization magic).
+  * **can_be_restarted** - If set to `true` the Tutorial will provide an option
+    to restart on the last step, in case the user wants to see the Tutorial
+    again.
+    * Setting this to `false` (the default) will not prevent the user from
+      triggering the Tutorial again via other means.
+
+`TutorialDescription::Step` is a bit more complex. Steps may
+either be created all at once with the omnibus constructor, or created with the
+default constructor and then have each field set individually. The fields of the
+struct are as follows:
+  * Help bubble parameters:
+    * **body_text_id** - Localized string ID. The result is placed into
+      `HelpBubbleParams::body_text`. If not set, this Tutorial step is a "hidden
+      step" and will have no bubble.
+    * **title_text_id** - Localized string ID. The result is placed into
+      `HelpBubbleParams::title_text`.
+    * **element_id** - Specifies the UI element the step refers to. If this is
+      not a hidden step, the bubble will anchor to this element. Mandatory
+      unless `element_name` is set.
+    * **arrow** - Specifies how the `HelpBubble` for this step will anchor to
+      the target element.
+  * Interaction sequence parameters; see 
+    [InteractionSequence](/ui/base/interaction/interaction_sequence.h) for
+    details:
+    * **step_type** - Specifies the triggering condition of this step.
+    * **event_type** - If `step_type` is `kCustomEvent`, specifies the custom
+      event the step will transition on. Ignored otherwise.
+    * **name_elements_callback** - Allows either the current element or some
+      other element to be "named" for use later in the Tutorial. This allows a
+      Tutorial to remember elements that may otherwise be ambiguous or not have
+      an `ElementIdentifier` before the Tutorial runs.
+    * **element_name** - Specifies that the step will target an element named
+      via `name_elements_callback` in a previous step, rather than using
+      `element_id`. The element must have been named and still be visible.
+    * **transition_only_on_event** - When `step_type` is `kShown` or `kHidden`,
+      causes this step to start only when a UI element actively becomes visible
+      or loses visibility. Corresponds to
+      `InteractionSequence::StepBuilder::SetTransitionOnlyOnEvent()`.
+    * **must_remain_visible** - Overrides the default "must remain visible"
+      state of the underlying `InteractionSequence::Step`. Should only be set if
+      the Tutorial won't work properly otherwise.
+
+Notes:
+  * `TutorialDescription::Step` is copyable and a step can be added to the
+    `steps` member of multiple related `TutorialDescription`s.
+  * We are aware that the programming interface for `Step` is a little clunky;
+    at some future point they will be moved to a builder pattern like
+    `FeaturePromoSpecification`.
+  * If you're not sure how to construct your Tutorial, reach out to one of the
+    OWNERS of this library.
+
+Once you have defined your Tutorial; call `AddTutorial()` on the
+[TutorialRegistry](./common/tutorial_registry.h) provided by your application
+and pass both your `TutorialIdentifier` and your `TutorialDescription`.
+
+## "New" Badge
+
+For implementation on adding a "New" Badge to Chrome, Googlers can refer to the
+following document:
+[New Badge How-To and Best Practices](https://goto.google.com/new-badge-how-to).
+
+# Adding User Education to your application
 
 There are a number of virtual methods that must be implemented before you can
 use these User Education libraries in a new application, mostly centered around
@@ -153,7 +261,16 @@
 
 Fortunately for Chromium developers, the browser already has the necessary
 support built in for Views, WebUI, and Mac-native context menus. You may refer
-to
-[browser_user_education_service](/chrome/browser/ui/views/user_education/browser_user_education_service.h)
-for an example that could be extended to other (especially Views-based)
-platforms such as ChromeOS.
\ No newline at end of file
+to the following locations for an example that could be extended to other
+platforms such as ChromeOS:
+  * [UserEducationService](
+    /chrome/browser/ui/user_education/user_education_service.h) - sets up the
+    various registries and `TutorialService`.
+  * [BrowserView](/chrome/browser/ui/views/frame/browser_view.cc#831) - sets up
+    the `FeaturePromoController`.
+  * [browser_user_education_service](
+    /chrome/browser/ui/views/user_education/browser_user_education_service.h) -
+    registers Chrome-specific IPH and Tutorials.
+  * Concrete implementations of abstract User Education base classes can be
+    found in [c/b/ui/user_education](/chrome/browser/ui/user_education/) and
+    [c/b/ui/views/user_education](/chrome/browser/ui/views/user_education/).
diff --git a/content/app_shim_remote_cocoa/ns_view_bridge_factory_impl.mm b/content/app_shim_remote_cocoa/ns_view_bridge_factory_impl.mm
index 60e99da..d6d48ab 100644
--- a/content/app_shim_remote_cocoa/ns_view_bridge_factory_impl.mm
+++ b/content/app_shim_remote_cocoa/ns_view_bridge_factory_impl.mm
@@ -39,7 +39,9 @@
           bridge_receiver)
       : host_(std::move(client)) {
     bridge_ = std::make_unique<remote_cocoa::RenderWidgetHostNSViewBridge>(
-        host_.get(), this, view_id);
+        host_.get(), this, view_id,
+        base::BindOnce(&RenderWidgetHostNSViewBridgeOwner::OnMojoDisconnect,
+                       base::Unretained(this)));
     bridge_->BindReceiver(std::move(bridge_receiver));
     host_.set_disconnect_handler(
         base::BindOnce(&RenderWidgetHostNSViewBridgeOwner::OnMojoDisconnect,
@@ -171,10 +173,9 @@
       std::move(view_request_handle));
   // Note that the resulting object will be destroyed when its underlying pipe
   // is closed.
-  mojo::MakeSelfOwnedAssociatedReceiver(
-      std::make_unique<WebContentsNSViewBridge>(view_id, std::move(host)),
-      std::move(ns_view_receiver),
-      ui::WindowResizeHelperMac::Get()->task_runner());
+  (new WebContentsNSViewBridge(view_id, std::move(host)))
+      ->Bind(std::move(ns_view_receiver),
+             ui::WindowResizeHelperMac::Get()->task_runner());
 }
 
 }  // namespace remote_cocoa
diff --git a/content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge.h b/content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge.h
index 5d0ef708..fb407a15 100644
--- a/content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge.h
+++ b/content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge.h
@@ -30,7 +30,8 @@
  public:
   RenderWidgetHostNSViewBridge(mojom::RenderWidgetHostNSViewHost* client,
                                RenderWidgetHostNSViewHostHelper* client_helper,
-                               uint64_t ns_view_id);
+                               uint64_t ns_view_id,
+                               base::OnceClosure destroy_callback = {});
 
   RenderWidgetHostNSViewBridge(const RenderWidgetHostNSViewBridge&) = delete;
   RenderWidgetHostNSViewBridge& operator=(const RenderWidgetHostNSViewBridge&) =
@@ -83,6 +84,7 @@
       const std::string& url,
       const std::vector<std::string>& file_paths,
       ShowSharingServicePickerCallback callback) override;
+  void Destroy() override;
 
  private:
   bool IsPopup() const { return !!popup_window_; }
@@ -116,6 +118,9 @@
 
   // The receiver for this object (only used when remotely instantiated).
   mojo::AssociatedReceiver<mojom::RenderWidgetHostNSView> receiver_{this};
+
+  // The callback to be called when `Destroy()` is called.
+  base::OnceClosure destroy_callback_;
 };
 
 }  // namespace remote_cocoa
diff --git a/content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge.mm b/content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge.mm
index 2b4de90..ded91de 100644
--- a/content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge.mm
+++ b/content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge.mm
@@ -23,7 +23,9 @@
 RenderWidgetHostNSViewBridge::RenderWidgetHostNSViewBridge(
     mojom::RenderWidgetHostNSViewHost* host,
     RenderWidgetHostNSViewHostHelper* host_helper,
-    uint64_t ns_view_id) {
+    uint64_t ns_view_id,
+    base::OnceClosure destroy_callback)
+    : destroy_callback_(std::move(destroy_callback)) {
   cocoa_view_.reset([[RenderWidgetHostViewCocoa alloc]
         initWithHost:host
       withHostHelper:host_helper]);
@@ -292,4 +294,9 @@
                                   std::move(callback));
 }
 
+void RenderWidgetHostNSViewBridge::Destroy() {
+  if (destroy_callback_)
+    std::move(destroy_callback_).Run();
+}
+
 }  // namespace remote_cocoa
diff --git a/content/app_shim_remote_cocoa/web_contents_ns_view_bridge.h b/content/app_shim_remote_cocoa/web_contents_ns_view_bridge.h
index 29baace..a3db548 100644
--- a/content/app_shim_remote_cocoa/web_contents_ns_view_bridge.h
+++ b/content/app_shim_remote_cocoa/web_contents_ns_view_bridge.h
@@ -13,6 +13,7 @@
 #include "components/remote_cocoa/app_shim/ns_view_ids.h"
 #include "content/common/content_export.h"
 #include "content/common/web_contents_ns_view_bridge.mojom.h"
+#include "mojo/public/cpp/bindings/associated_receiver.h"
 #include "mojo/public/cpp/bindings/associated_remote.h"
 #include "mojo/public/cpp/bindings/pending_associated_remote.h"
 
@@ -44,6 +45,9 @@
 
   ~WebContentsNSViewBridge() override;
 
+  void Bind(mojo::PendingAssociatedReceiver<mojom::WebContentsNSView> receiver,
+            scoped_refptr<base::SequencedTaskRunner> task_runner);
+
   WebContentsViewCocoa* GetNSView() const { return ns_view_.get(); }
 
   // mojom::WebContentsNSViewBridge:
@@ -57,9 +61,11 @@
                  uint32_t operation_mask,
                  const gfx::ImageSkia& image,
                  const gfx::Vector2d& image_offset) override;
+  void Destroy() override;
 
  private:
   base::scoped_nsobject<WebContentsViewCocoa> ns_view_;
+  mojo::AssociatedReceiver<mojom::WebContentsNSView> receiver_{this};
   mojo::AssociatedRemote<mojom::WebContentsNSViewHost> host_;
 
   std::unique_ptr<ScopedNSViewIdMapping> view_id_;
diff --git a/content/app_shim_remote_cocoa/web_contents_ns_view_bridge.mm b/content/app_shim_remote_cocoa/web_contents_ns_view_bridge.mm
index 113c4f4..3ddfac82 100644
--- a/content/app_shim_remote_cocoa/web_contents_ns_view_bridge.mm
+++ b/content/app_shim_remote_cocoa/web_contents_ns_view_bridge.mm
@@ -43,6 +43,18 @@
   [ns_view_ removeFromSuperview];
 }
 
+void WebContentsNSViewBridge::Bind(
+    mojo::PendingAssociatedReceiver<mojom::WebContentsNSView> receiver,
+    scoped_refptr<base::SequencedTaskRunner> task_runner) {
+  receiver_.Bind(std::move(receiver), std::move(task_runner));
+  receiver_.set_disconnect_handler(base::BindOnce(
+      &WebContentsNSViewBridge::Destroy, base::Unretained(this)));
+}
+
+void WebContentsNSViewBridge::Destroy() {
+  delete this;
+}
+
 void WebContentsNSViewBridge::SetParentNSView(uint64_t parent_ns_view_id) {
   NSView* parent_ns_view = remote_cocoa::GetNSViewFromId(parent_ns_view_id);
   // If the browser passed an invalid handle, then there is no recovery.
diff --git a/content/browser/first_party_sets/first_party_sets_handler_impl.cc b/content/browser/first_party_sets/first_party_sets_handler_impl.cc
index 3943553..71b87dd8 100644
--- a/content/browser/first_party_sets/first_party_sets_handler_impl.cc
+++ b/content/browser/first_party_sets/first_party_sets_handler_impl.cc
@@ -9,7 +9,6 @@
 
 #include "base/bind.h"
 #include "base/callback_helpers.h"
-#include "base/containers/contains.h"
 #include "base/containers/flat_map.h"
 #include "base/containers/flat_set.h"
 #include "base/files/file.h"
@@ -17,11 +16,11 @@
 #include "base/files/important_file_writer.h"
 #include "base/logging.h"
 #include "base/metrics/histogram_functions.h"
-#include "base/metrics/histogram_macros.h"
 #include "base/task/thread_pool.h"
 #include "base/time/time.h"
 #include "base/timer/elapsed_timer.h"
 #include "base/values.h"
+#include "content/browser/first_party_sets/addition_overlaps_union_find.h"
 #include "content/browser/first_party_sets/first_party_set_parser.h"
 #include "content/browser/first_party_sets/first_party_sets_loader.h"
 #include "content/public/browser/content_browser_client.h"
@@ -33,6 +32,8 @@
 namespace content {
 
 namespace {
+using FlattenedSets = FirstPartySetsHandlerImpl::FlattenedSets;
+using SingleSet = FirstPartySetParser::SingleSet;
 
 constexpr base::FilePath::CharType kPersistedFirstPartySetsFileName[] =
     FILE_PATH_LITERAL("persisted_first_party_sets.json");
@@ -62,9 +63,8 @@
 
 // Converts a list of First-Party Sets from a SingleSet to a FlattenedSet
 // representation.
-FirstPartySetsHandlerImpl::FlattenedSets SetListToFlattenedSets(
-    const std::vector<FirstPartySetParser::SingleSet>& set_list) {
-  FirstPartySetsHandlerImpl::FlattenedSets sets;
+FlattenedSets SetListToFlattenedSets(const std::vector<SingleSet>& set_list) {
+  FlattenedSets sets;
   for (const auto& [owner, members] : set_list) {
     sets.emplace(owner, owner);
     for (const net::SchemefulSite& member : members)
@@ -76,7 +76,7 @@
 // Adds all sets in a list of First-Party Sets into `site_to_owner` which maps
 // from a site to its owner.
 void UpdateCustomizationMap(
-    const std::vector<FirstPartySetParser::SingleSet>& set_list,
+    const std::vector<SingleSet>& set_list,
     FirstPartySetsHandlerImpl::PolicyCustomization& site_to_owner) {
   for (const auto& [owner, members] : set_list) {
     site_to_owner.emplace(owner, owner);
@@ -85,6 +85,70 @@
   }
 }
 
+// Populates the `policy_set_overlaps` out-parameter by checking
+// `existing_sets`. If `site` is equal to an existing site e in `sets`, then
+// `policy_set_index` will be added to the list of set indices at
+// `policy_set_overlaps`[e].
+void AddIfPolicySetOverlaps(
+    const net::SchemefulSite& site,
+    size_t policy_set_index,
+    FlattenedSets existing_sets,
+    base::flat_map<net::SchemefulSite, base::flat_set<size_t>>&
+        policy_set_overlaps) {
+  // Check `site` for membership in `existing_sets`.
+  if (auto it = existing_sets.find(site); it != existing_sets.end()) {
+    // Add the index of `site`'s policy set to the list of policy set indices
+    // that also overlap with site_owner.
+    auto [site_and_sets, inserted] =
+        policy_set_overlaps.insert({it->second, {}});
+    site_and_sets->second.insert(policy_set_index);
+  }
+}
+
+std::vector<SingleSet> NormalizeAdditionSets(
+    const FlattenedSets& existing_sets,
+    const std::vector<SingleSet>& addition_sets) {
+  // Create a mapping from an owner site in `existing_sets` to all policy sets
+  // that intersect with the set that it owns.
+  base::flat_map<net::SchemefulSite, base::flat_set<size_t>>
+      policy_set_overlaps;
+  for (size_t set_idx = 0; set_idx < addition_sets.size(); set_idx++) {
+    const net::SchemefulSite& owner = addition_sets[set_idx].first;
+    AddIfPolicySetOverlaps(owner, set_idx, existing_sets, policy_set_overlaps);
+    for (const net::SchemefulSite& member : addition_sets[set_idx].second) {
+      AddIfPolicySetOverlaps(member, set_idx, existing_sets,
+                             policy_set_overlaps);
+    }
+  }
+
+  AdditionOverlapsUnionFind union_finder(addition_sets.size());
+  for (auto& [public_site, policy_set_indices] : policy_set_overlaps) {
+    // Union together all overlapping policy sets to determine which one will
+    // take ownership.
+    for (size_t representative : policy_set_indices) {
+      union_finder.Union(*policy_set_indices.begin(), representative);
+    }
+  }
+
+  // The union-find data structure now knows which policy set should be given
+  // the role of representative for each entry in policy_set_overlaps.
+  // AdditionOverlapsUnionFind::SetsMapping returns a map from representative
+  // index to list of its children.
+  std::vector<SingleSet> normalized_additions;
+  for (auto& [rep, children] : union_finder.SetsMapping()) {
+    SingleSet normalized = addition_sets[rep];
+    for (size_t child_set_idx : children) {
+      // Update normalized to absorb the child_set_idx-th addition set.
+      const SingleSet& child_set = addition_sets[child_set_idx];
+      normalized.second.insert(child_set.first);
+      normalized.second.insert(child_set.second.begin(),
+                               child_set.second.end());
+    }
+    normalized_additions.push_back(normalized);
+  }
+  return normalized_additions;
+}
+
 }  // namespace
 
 bool FirstPartySetsHandler::PolicyParsingError::operator==(
@@ -148,8 +212,8 @@
 
   // Normalize the addition sets to prevent them from affecting the same
   // existing set.
-  std::vector<FirstPartySetParser::SingleSet> normalized_additions =
-      FirstPartySetsLoader::NormalizeAdditionSets(sets, policy.additions);
+  std::vector<SingleSet> normalized_additions =
+      NormalizeAdditionSets(sets, policy.additions);
 
   // Create flattened versions of the sets for easier lookup.
   FlattenedSets flattened_replacements =
@@ -257,8 +321,8 @@
 
 FirstPartySetsHandlerImpl::~FirstPartySetsHandlerImpl() = default;
 
-absl::optional<FirstPartySetsHandlerImpl::FlattenedSets>
-FirstPartySetsHandlerImpl::GetSets(SetsReadyOnceCallback callback) {
+absl::optional<FlattenedSets> FirstPartySetsHandlerImpl::GetSets(
+    SetsReadyOnceCallback callback) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(IsEnabled());
   DCHECK(!callback.is_null());
@@ -392,8 +456,7 @@
   on_sets_ready_callbacks_.shrink_to_fit();
 }
 
-FirstPartySetsHandlerImpl::FlattenedSets
-FirstPartySetsHandlerImpl::GetSetsSync() const {
+FlattenedSets FirstPartySetsHandlerImpl::GetSetsSync() const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(sets_.has_value());
   return sets_.value();
diff --git a/content/browser/first_party_sets/first_party_sets_handler_impl.h b/content/browser/first_party_sets/first_party_sets_handler_impl.h
index f679ab0..aa8ed567a 100644
--- a/content/browser/first_party_sets/first_party_sets_handler_impl.h
+++ b/content/browser/first_party_sets/first_party_sets_handler_impl.h
@@ -16,7 +16,6 @@
 #include "base/no_destructor.h"
 #include "base/sequence_checker.h"
 #include "base/thread_annotations.h"
-#include "base/time/time.h"
 #include "base/timer/elapsed_timer.h"
 #include "base/values.h"
 #include "content/browser/first_party_sets/first_party_set_parser.h"
diff --git a/content/browser/first_party_sets/first_party_sets_handler_impl_unittest.cc b/content/browser/first_party_sets/first_party_sets_handler_impl_unittest.cc
index 084a53a..09b8ba750 100644
--- a/content/browser/first_party_sets/first_party_sets_handler_impl_unittest.cc
+++ b/content/browser/first_party_sets/first_party_sets_handler_impl_unittest.cc
@@ -33,6 +33,8 @@
 namespace content {
 namespace {
 using PolicyCustomization = FirstPartySetsHandlerImpl::PolicyCustomization;
+using FlattenedSets = FirstPartySetsHandlerImpl::FlattenedSets;
+using SingleSet = FirstPartySetParser::SingleSet;
 
 MATCHER_P(SerializesTo, want, "") {
   const std::string got = arg.Serialize();
@@ -854,6 +856,104 @@
                        Optional(SerializesTo("https://owner1.test")))));
 }
 
+TEST(FirstPartySetsProfilePolicyCustomizations,
+     TransitiveOverlap_TwoCommonOwners) {
+  // {owner1, {member1}} and {owner2, {member2}} transitively overlap with the
+  // existing set.
+  // owner1 takes ownership of the normalized addition set since it was
+  // provided first.
+  // The other addition sets are unaffected.
+  EXPECT_THAT(
+      FirstPartySetsHandlerImpl::ComputeEnterpriseCustomizations(
+          MakeFlattenedSetsFromMap(
+              {{"https://owner1.test", {"https://owner2.test"}}}),
+          FirstPartySetParser::ParsedPolicySetLists(
+              /*replacement_list=*/{},
+              {SingleSet(net::SchemefulSite(GURL("https://owner0.test")),
+                         {net::SchemefulSite(GURL("https://member0.test"))}),
+               SingleSet(net::SchemefulSite(GURL("https://owner1.test")),
+                         {net::SchemefulSite(GURL("https://member1.test"))}),
+               SingleSet(net::SchemefulSite(GURL("https://owner2.test")),
+                         {net::SchemefulSite(GURL("https://member2.test"))}),
+               SingleSet(
+                   net::SchemefulSite(GURL("https://owner42.test")),
+                   {net::SchemefulSite(GURL("https://member42.test"))})})),
+      UnorderedElementsAre(
+          Pair(net::SchemefulSite(GURL("https://member0.test")),
+               absl::make_optional(
+                   net::SchemefulSite(GURL("https://owner0.test")))),
+          Pair(net::SchemefulSite(GURL("https://member1.test")),
+               absl::make_optional(
+                   net::SchemefulSite(GURL("https://owner1.test")))),
+          Pair(net::SchemefulSite(GURL("https://member2.test")),
+               absl::make_optional(
+                   net::SchemefulSite(GURL("https://owner1.test")))),
+          Pair(net::SchemefulSite(GURL("https://member42.test")),
+               absl::make_optional(
+                   net::SchemefulSite(GURL("https://owner42.test")))),
+          Pair(net::SchemefulSite(GURL("https://owner0.test")),
+               absl::make_optional(
+                   net::SchemefulSite(GURL("https://owner0.test")))),
+          Pair(net::SchemefulSite(GURL("https://owner1.test")),
+               absl::make_optional(
+                   net::SchemefulSite(GURL("https://owner1.test")))),
+          Pair(net::SchemefulSite(GURL("https://owner2.test")),
+               absl::make_optional(
+                   net::SchemefulSite(GURL("https://owner1.test")))),
+          Pair(net::SchemefulSite(GURL("https://owner42.test")),
+               absl::make_optional(
+                   net::SchemefulSite(GURL("https://owner42.test"))))));
+}
+
+TEST(FirstPartySetsProfilePolicyCustomizations,
+     TransitiveOverlap_TwoCommonMembers) {
+  // {owner1, {member1}} and {owner2, {member2}} transitively overlap with the
+  // existing set.
+  // owner2 takes ownership of the normalized addition set since it was
+  // provided first.
+  // The other addition sets are unaffected.
+  EXPECT_THAT(
+      FirstPartySetsHandlerImpl::ComputeEnterpriseCustomizations(
+          MakeFlattenedSetsFromMap(
+              {{"https://owner2.test", {"https://owner1.test"}}}),
+          FirstPartySetParser::ParsedPolicySetLists(
+              /*replacement_list=*/{},
+              {SingleSet(net::SchemefulSite(GURL("https://owner0.test")),
+                         {net::SchemefulSite(GURL("https://member0.test"))}),
+               SingleSet(net::SchemefulSite(GURL("https://owner2.test")),
+                         {net::SchemefulSite(GURL("https://member2.test"))}),
+               SingleSet(net::SchemefulSite(GURL("https://owner1.test")),
+                         {net::SchemefulSite(GURL("https://member1.test"))}),
+               SingleSet(
+                   net::SchemefulSite(GURL("https://owner42.test")),
+                   {net::SchemefulSite(GURL("https://member42.test"))})})),
+      UnorderedElementsAre(
+          Pair(net::SchemefulSite(GURL("https://member0.test")),
+               absl::make_optional(
+                   net::SchemefulSite(GURL("https://owner0.test")))),
+          Pair(net::SchemefulSite(GURL("https://member1.test")),
+               absl::make_optional(
+                   net::SchemefulSite(GURL("https://owner2.test")))),
+          Pair(net::SchemefulSite(GURL("https://member2.test")),
+               absl::make_optional(
+                   net::SchemefulSite(GURL("https://owner2.test")))),
+          Pair(net::SchemefulSite(GURL("https://member42.test")),
+               absl::make_optional(
+                   net::SchemefulSite(GURL("https://owner42.test")))),
+          Pair(net::SchemefulSite(GURL("https://owner0.test")),
+               absl::make_optional(
+                   net::SchemefulSite(GURL("https://owner0.test")))),
+          Pair(net::SchemefulSite(GURL("https://owner1.test")),
+               absl::make_optional(
+                   net::SchemefulSite(GURL("https://owner2.test")))),
+          Pair(net::SchemefulSite(GURL("https://owner2.test")),
+               absl::make_optional(
+                   net::SchemefulSite(GURL("https://owner2.test")))),
+          Pair(net::SchemefulSite(GURL("https://owner42.test")),
+               absl::make_optional(
+                   net::SchemefulSite(GURL("https://owner42.test"))))));
+}
+
 // Existing set overlaps with both replacement and addition set.
 TEST(FirstPartySetsProfilePolicyCustomizations,
      ReplacementsAndAdditions_SetListsOverlapWithSameExistingSet) {
diff --git a/content/browser/first_party_sets/first_party_sets_loader.cc b/content/browser/first_party_sets/first_party_sets_loader.cc
index 2ef1a68..b2fe03b 100644
--- a/content/browser/first_party_sets/first_party_sets_loader.cc
+++ b/content/browser/first_party_sets/first_party_sets_loader.cc
@@ -15,12 +15,9 @@
 #include "base/files/file_util.h"
 #include "base/logging.h"
 #include "base/metrics/histogram_functions.h"
-#include "base/ranges/algorithm.h"
 #include "base/sequence_checker.h"
 #include "base/strings/string_split.h"
 #include "base/task/thread_pool.h"
-#include "base/values.h"
-#include "content/browser/first_party_sets/addition_overlaps_union_find.h"
 #include "content/browser/first_party_sets/first_party_set_parser.h"
 #include "net/base/schemeful_site.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -67,26 +64,6 @@
   return base::ReadStreamToString(file.get(), &raw_sets) ? raw_sets : "";
 }
 
-// Populates the `policy_set_overlaps` out-parameter by checking
-// `existing_sets`. If `site` is equal to an existing site e in `sets`, then
-// `policy_set_index` will be added to the list of set indices at
-// `policy_set_overlaps`[e].
-void AddIfPolicySetOverlaps(
-    const net::SchemefulSite& site,
-    size_t policy_set_index,
-    FirstPartySetsLoader::FlattenedSets existing_sets,
-    base::flat_map<net::SchemefulSite, base::flat_set<size_t>>&
-        policy_set_overlaps) {
-  // Check `site` for membership in `existing_sets`.
-  if (auto it = existing_sets.find(site); it != existing_sets.end()) {
-    // Add the index of `site`'s policy set to the list of policy set indices
-    // that also overlap with site_owner.
-    auto [site_and_sets, inserted] =
-        policy_set_overlaps.insert({it->second, {}});
-    site_and_sets->second.insert(policy_set_index);
-  }
-}
-
 }  // namespace
 
 FirstPartySetsLoader::FirstPartySetsLoader(
@@ -158,51 +135,6 @@
   }
 }
 
-std::vector<FirstPartySetsLoader::SingleSet>
-FirstPartySetsLoader::NormalizeAdditionSets(
-    const FlattenedSets& existing_sets,
-    const std::vector<SingleSet>& addition_sets) {
-  // Create a mapping from an owner site in `existing_sets` to all policy sets
-  // that intersect with the set that it owns.
-  base::flat_map<net::SchemefulSite, base::flat_set<size_t>>
-      policy_set_overlaps;
-  for (size_t set_idx = 0; set_idx < addition_sets.size(); set_idx++) {
-    const net::SchemefulSite& owner = addition_sets[set_idx].first;
-    AddIfPolicySetOverlaps(owner, set_idx, existing_sets, policy_set_overlaps);
-    for (const net::SchemefulSite& member : addition_sets[set_idx].second) {
-      AddIfPolicySetOverlaps(member, set_idx, existing_sets,
-                             policy_set_overlaps);
-    }
-  }
-
-  AdditionOverlapsUnionFind union_finder(addition_sets.size());
-  for (auto& [public_site, policy_set_indices] : policy_set_overlaps) {
-    // Union together all overlapping policy sets to determine which one will
-    // take ownership.
-    for (size_t representative : policy_set_indices) {
-      union_finder.Union(*policy_set_indices.begin(), representative);
-    }
-  }
-
-  // The union-find data structure now knows which policy set should be given
-  // the role of representative for each entry in policy_set_overlaps.
-  // AdditionOverlapsUnionFind::SetsMapping returns a map from representative
-  // index to list of its children.
-  std::vector<SingleSet> normalized_additions;
-  for (auto& [rep, children] : union_finder.SetsMapping()) {
-    SingleSet normalized = addition_sets[rep];
-    for (size_t child_set_idx : children) {
-      // Update normalized to absorb the child_set_idx-th addition set.
-      const SingleSet& child_set = addition_sets[child_set_idx];
-      normalized.second.insert(child_set.first);
-      normalized.second.insert(child_set.second.begin(),
-                               child_set.second.end());
-    }
-    normalized_additions.push_back(normalized);
-  }
-  return normalized_additions;
-}
-
 void FirstPartySetsLoader::ApplyManuallySpecifiedSet() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(HasAllInputs());
diff --git a/content/browser/first_party_sets/first_party_sets_loader.h b/content/browser/first_party_sets/first_party_sets_loader.h
index 043c0ea..c28a6c89 100644
--- a/content/browser/first_party_sets/first_party_sets_loader.h
+++ b/content/browser/first_party_sets/first_party_sets_loader.h
@@ -7,7 +7,6 @@
 
 #include "base/callback.h"
 #include "base/containers/flat_map.h"
-#include "base/containers/flat_set.h"
 #include "base/files/file.h"
 #include "base/sequence_checker.h"
 #include "base/thread_annotations.h"
@@ -29,8 +28,7 @@
   using LoadCompleteOnceCallback = base::OnceCallback<void(
       base::flat_map<net::SchemefulSite, net::SchemefulSite>)>;
   using FlattenedSets = base::flat_map<net::SchemefulSite, net::SchemefulSite>;
-  using SingleSet =
-      std::pair<net::SchemefulSite, base::flat_set<net::SchemefulSite>>;
+  using SingleSet = FirstPartySetParser::SingleSet;
 
   explicit FirstPartySetsLoader(LoadCompleteOnceCallback on_load_complete);
 
@@ -55,19 +53,6 @@
   // Close the file on thread pool that allows blocking.
   void DisposeFile(base::File sets_file);
 
-  // Handles addition sets which overlap by intersecting with the same existing
-  // set, known as a transitive-overlap.
-  //
-  // This uses a Union-Find algorithm to select the earliest-provided addition
-  // set as the representative of all other addition sets that
-  // transitively-overlap with it.
-  //
-  // The "earliest-provided" tie-breaker is determined using a set's index in
-  // `addition_sets`.
-  static std::vector<SingleSet> NormalizeAdditionSets(
-      const FlattenedSets& existing_sets,
-      const std::vector<SingleSet>& addition_sets);
-
  private:
   // Parses the contents of `raw_sets` as a collection of First-Party Set
   // declarations, and assigns to `sets_`.
diff --git a/content/browser/first_party_sets/first_party_sets_loader_unittest.cc b/content/browser/first_party_sets/first_party_sets_loader_unittest.cc
index fbbac27..5947f64 100644
--- a/content/browser/first_party_sets/first_party_sets_loader_unittest.cc
+++ b/content/browser/first_party_sets/first_party_sets_loader_unittest.cc
@@ -52,23 +52,6 @@
       base::File(path, base::File::FLAG_OPEN | base::File::FLAG_READ));
 }
 
-enum class FirstPartySetsSource { kPublicSets, kCommandLineSet };
-
-FirstPartySetsLoader::FlattenedSets MakeFlattenedSetsFromMap(
-    const base::flat_map<std::string, std::vector<std::string>>&
-        owners_to_members) {
-  FirstPartySetsLoader::FlattenedSets result;
-  for (const auto& [owner, members] : owners_to_members) {
-    net::SchemefulSite owner_site = net::SchemefulSite(GURL(owner));
-    result.emplace(owner_site, owner_site);
-    for (const std::string& member : members) {
-      net::SchemefulSite member_site = net::SchemefulSite(GURL(member));
-      result.emplace(member_site, owner_site);
-    }
-  }
-  return result;
-}
-
 }  // namespace
 
 class FirstPartySetsLoaderTest : public ::testing::Test {
@@ -435,196 +418,4 @@
                                         SerializesTo("https://example.test"))));
 }
 
-// There is no overlap between the existing sets and the addition sets, so
-// normalization should be a noop.
-TEST(FirstPartySetsLoaderTestNormalizeAdditionSets,
-     NoOverlap_AdditionSetsAreUnchanged) {
-  const FirstPartySetsLoader::FlattenedSets existing_sets(
-      MakeFlattenedSetsFromMap(
-          {{"https://owner42.test", {"https://member42.test"}}}));
-  const std::vector<FirstPartySetsLoader::SingleSet> additions{
-      SingleSet(net::SchemefulSite(GURL("https://owner1.test")),
-                {net::SchemefulSite(GURL("https://member1.test"))}),
-      SingleSet(net::SchemefulSite(GURL("https://owner2.test")),
-                {net::SchemefulSite(GURL("https://member2.test"))})};
-
-  EXPECT_THAT(
-      FirstPartySetsLoader::NormalizeAdditionSets(existing_sets, additions),
-      UnorderedElementsAreArray(additions));
-}
-
-// There is no transitive overlap since only all the overlaps are from the same
-// addition set, so normalization should be a noop.
-TEST(FirstPartySetsLoaderTestNormalizeAdditionSets,
-     NoTransitiveOverlap_SingleSetMultipleOverlaps_AdditionSetsAreUnchanged) {
-  const FirstPartySetsLoader::FlattenedSets existing_sets(
-      MakeFlattenedSetsFromMap(
-          {{"https://owner42.test",
-            {"https://member1a.test", "https://member1b.test"}}}));
-  const std::vector<FirstPartySetsLoader::SingleSet> additions{
-      SingleSet(net::SchemefulSite(GURL("https://owner1.test")),
-                {net::SchemefulSite(GURL("https://member1a.test")),
-                 net::SchemefulSite(GURL("https://member1b.test"))}),
-      SingleSet(net::SchemefulSite(GURL("https://owner2.test")),
-                {net::SchemefulSite(GURL("https://member2.test"))})};
-
-  EXPECT_THAT(
-      FirstPartySetsLoader::NormalizeAdditionSets(existing_sets, additions),
-      UnorderedElementsAreArray(additions));
-}
-
-// There is no transitive overlap since the addition sets intersect with
-// different existing sets, so normalization should be a noop.
-TEST(FirstPartySetsLoaderTestNormalizeAdditionSets,
-     NoTransitiveOverlap_SeparateOverlaps_AdditionSetsAreUnchanged) {
-  const FirstPartySetsLoader::FlattenedSets existing_sets(
-      MakeFlattenedSetsFromMap(
-          {{"https://ownerA.test", {"https://member1.test"}},
-           {"https://ownerB.test", {"https://member2.test"}}}));
-  const std::vector<FirstPartySetsLoader::SingleSet> additions{
-      SingleSet(net::SchemefulSite(GURL("https://owner1.test")),
-                {net::SchemefulSite(GURL("https://member1.test"))}),
-      SingleSet(net::SchemefulSite(GURL("https://owner2.test")),
-                {net::SchemefulSite(GURL("https://member2.test"))})};
-
-  EXPECT_THAT(
-      FirstPartySetsLoader::NormalizeAdditionSets(existing_sets, additions),
-      UnorderedElementsAreArray(additions));
-}
-
-TEST(FirstPartySetsLoaderTestNormalizeAdditionSets,
-     TransitiveOverlap_TwoCommonOwners) {
-  const FirstPartySetsLoader::FlattenedSets existing_sets(
-      MakeFlattenedSetsFromMap(
-          {{"https://owner1.test", {"https://owner2.test"}}}));
-  const std::vector<FirstPartySetsLoader::SingleSet> additions{
-      SingleSet(net::SchemefulSite(GURL("https://owner0.test")),
-                {net::SchemefulSite(GURL("https://member0.test"))}),
-      SingleSet(net::SchemefulSite(GURL("https://owner1.test")),
-                {net::SchemefulSite(GURL("https://member1.test"))}),
-      SingleSet(net::SchemefulSite(GURL("https://owner2.test")),
-                {net::SchemefulSite(GURL("https://member2.test"))}),
-      SingleSet(net::SchemefulSite(GURL("https://owner42.test")),
-                {net::SchemefulSite(GURL("https://member42.test"))})};
-
-  // {owner1, {member1}} and {owner2, {member2}} transitively overlap with the
-  // existing set.
-  // owner1 takes ownership of the normalized addition set since it was
-  // provided first.
-  // The other addition sets are unaffected.
-  EXPECT_THAT(
-      FirstPartySetsLoader::NormalizeAdditionSets(existing_sets, additions),
-      UnorderedElementsAre(
-          SingleSet(net::SchemefulSite(GURL("https://owner0.test")),
-                    {net::SchemefulSite(GURL("https://member0.test"))}),
-          SingleSet(net::SchemefulSite(GURL("https://owner1.test")),
-                    {net::SchemefulSite(GURL("https://member1.test")),
-                     net::SchemefulSite(GURL("https://owner2.test")),
-                     net::SchemefulSite(GURL("https://member2.test"))}),
-          SingleSet(net::SchemefulSite(GURL("https://owner42.test")),
-                    {net::SchemefulSite(GURL("https://member42.test"))})));
-}
-
-TEST(FirstPartySetsLoaderTestNormalizeAdditionSets,
-     TransitiveOverlap_TwoCommonMembers) {
-  const FirstPartySetsLoader::FlattenedSets existing_sets(
-      MakeFlattenedSetsFromMap(
-          {{"https://owner2.test", {"https://owner1.test"}}}));
-  const std::vector<FirstPartySetsLoader::SingleSet> additions{
-      SingleSet(net::SchemefulSite(GURL("https://owner0.test")),
-                {net::SchemefulSite(GURL("https://member0.test"))}),
-      SingleSet(net::SchemefulSite(GURL("https://owner2.test")),
-                {net::SchemefulSite(GURL("https://member2.test"))}),
-      SingleSet(net::SchemefulSite(GURL("https://owner1.test")),
-                {net::SchemefulSite(GURL("https://member1.test"))}),
-      SingleSet(net::SchemefulSite(GURL("https://owner42.test")),
-                {net::SchemefulSite(GURL("https://member42.test"))})};
-
-  // {owner1, {member1}} and {owner2, {member2}} transitively overlap with the
-  // existing set.
-  // owner2 takes ownership of the normalized addition set since it was
-  // provided first.
-  // The other addition sets are unaffected.
-  EXPECT_THAT(
-      FirstPartySetsLoader::NormalizeAdditionSets(existing_sets, additions),
-      UnorderedElementsAre(
-          SingleSet(net::SchemefulSite(GURL("https://owner0.test")),
-                    {net::SchemefulSite(GURL("https://member0.test"))}),
-          SingleSet(net::SchemefulSite(GURL("https://owner2.test")),
-                    {net::SchemefulSite(GURL("https://member2.test")),
-                     net::SchemefulSite(GURL("https://owner1.test")),
-                     net::SchemefulSite(GURL("https://member1.test"))}),
-          SingleSet(net::SchemefulSite(GURL("https://owner42.test")),
-                    {net::SchemefulSite(GURL("https://member42.test"))})));
-}
-
-TEST(FirstPartySetsLoaderTestNormalizeAdditionSets,
-     TransitiveOverlap_ThreeCommonOwners) {
-  const FirstPartySetsLoader::FlattenedSets existing_sets(
-      MakeFlattenedSetsFromMap({{"https://owner.test",
-                                 {"https://owner1.test", "https://owner42.test",
-                                  "https://owner2.test"}}}));
-  const std::vector<FirstPartySetsLoader::SingleSet> additions{
-      SingleSet(net::SchemefulSite(GURL("https://owner42.test")),
-                {net::SchemefulSite(GURL("https://member42.test"))}),
-      SingleSet(net::SchemefulSite(GURL("https://owner0.test")),
-                {net::SchemefulSite(GURL("https://member0.test"))}),
-      SingleSet(net::SchemefulSite(GURL("https://owner2.test")),
-                {net::SchemefulSite(GURL("https://member2.test"))}),
-      SingleSet(net::SchemefulSite(GURL("https://owner1.test")),
-                {net::SchemefulSite(GURL("https://member1.test"))})};
-
-  // {owner1, {member1}}, {owner2, {member2}}, and {owner42, {member42}}
-  // transitively overlap with the existing set.
-  // owner42 takes ownership of the normalized addition set since it was
-  // provided first.
-  // The other addition sets are unaffected.
-  EXPECT_THAT(
-      FirstPartySetsLoader::NormalizeAdditionSets(existing_sets, additions),
-      UnorderedElementsAre(
-          SingleSet(net::SchemefulSite(GURL("https://owner42.test")),
-                    {net::SchemefulSite(GURL("https://member42.test")),
-                     net::SchemefulSite(GURL("https://owner1.test")),
-                     net::SchemefulSite(GURL("https://member1.test")),
-                     net::SchemefulSite(GURL("https://owner2.test")),
-                     net::SchemefulSite(GURL("https://member2.test"))}),
-          SingleSet(net::SchemefulSite(GURL("https://owner0.test")),
-                    {net::SchemefulSite(GURL("https://member0.test"))})));
-}
-
-TEST(FirstPartySetsLoaderTestNormalizeAdditionSets,
-     TransitiveOverlap_ThreeCommonMembers) {
-  const FirstPartySetsLoader::FlattenedSets existing_sets(
-      MakeFlattenedSetsFromMap(
-          {{"https://owner.test",
-            {"https://member1.test", "https://member42.test",
-             "https://member2.test"}}}));
-  const std::vector<FirstPartySetsLoader::SingleSet> additions{
-      SingleSet(net::SchemefulSite(GURL("https://owner42.test")),
-                {net::SchemefulSite(GURL("https://member42.test"))}),
-      SingleSet(net::SchemefulSite(GURL("https://owner0.test")),
-                {net::SchemefulSite(GURL("https://member0.test"))}),
-      SingleSet(net::SchemefulSite(GURL("https://owner2.test")),
-                {net::SchemefulSite(GURL("https://member2.test"))}),
-      SingleSet(net::SchemefulSite(GURL("https://owner1.test")),
-                {net::SchemefulSite(GURL("https://member1.test"))})};
-
-  // {owner1, {member1}}, {owner2, {member2}}, and {owner42, {member42}}
-  // transitively overlap with the existing set.
-  // owner42 takes ownership of the normalized addition set since it was
-  // provided first.
-  // The other addition sets are unaffected.
-  EXPECT_THAT(
-      FirstPartySetsLoader::NormalizeAdditionSets(existing_sets, additions),
-      UnorderedElementsAre(
-          SingleSet(net::SchemefulSite(GURL("https://owner42.test")),
-                    {net::SchemefulSite(GURL("https://member42.test")),
-                     net::SchemefulSite(GURL("https://owner1.test")),
-                     net::SchemefulSite(GURL("https://member1.test")),
-                     net::SchemefulSite(GURL("https://owner2.test")),
-                     net::SchemefulSite(GURL("https://member2.test"))}),
-          SingleSet(net::SchemefulSite(GURL("https://owner0.test")),
-                    {net::SchemefulSite(GURL("https://member0.test"))})));
-}
-
 }  // namespace content
diff --git a/content/browser/hid/hid_service.cc b/content/browser/hid/hid_service.cc
index 3f3d42c..0d07513 100644
--- a/content/browser/hid/hid_service.cc
+++ b/content/browser/hid/hid_service.cc
@@ -139,7 +139,7 @@
 HidService::~HidService() {
   HidDelegate* delegate = GetContentClient()->browser()->GetHidDelegate();
   if (delegate)
-    delegate->RemoveObserver(this);
+    delegate->RemoveObserver(browser_context_, this);
 
   // The remaining watchers will be closed from this end.
   if (!watchers_.empty())
diff --git a/content/browser/hid/hid_test_utils.cc b/content/browser/hid/hid_test_utils.cc
index e6520d5..b62321f3 100644
--- a/content/browser/hid/hid_test_utils.cc
+++ b/content/browser/hid/hid_test_utils.cc
@@ -29,7 +29,8 @@
   observer_list_.AddObserver(observer);
 }
 
-void MockHidDelegate::RemoveObserver(Observer* observer) {
+void MockHidDelegate::RemoveObserver(BrowserContext* browser_context,
+                                     Observer* observer) {
   observer_list_.RemoveObserver(observer);
 }
 
diff --git a/content/browser/hid/hid_test_utils.h b/content/browser/hid/hid_test_utils.h
index fc4538d..a2c1400b 100644
--- a/content/browser/hid/hid_test_utils.h
+++ b/content/browser/hid/hid_test_utils.h
@@ -39,7 +39,8 @@
 
   void AddObserver(BrowserContext* browser_context,
                    Observer* observer) override;
-  void RemoveObserver(Observer* observer) override;
+  void RemoveObserver(BrowserContext* browser_context,
+                      Observer* observer) override;
 
   // MockHidDelegate does not register to receive device connection events. Use
   // these methods to broadcast device connections to all delegate observers.
diff --git a/content/browser/media/cdm_registry_impl.cc b/content/browser/media/cdm_registry_impl.cc
index f83da99..e75f396 100644
--- a/content/browser/media/cdm_registry_impl.cc
+++ b/content/browser/media/cdm_registry_impl.cc
@@ -104,6 +104,8 @@
       video_codecs.emplace(media::VideoCodec::kH264, kAllProfiles);
     else if (codec == "hevc")
       video_codecs.emplace(media::VideoCodec::kHEVC, kAllProfiles);
+    else if (codec == "dolbyvision")
+      video_codecs.emplace(media::VideoCodec::kDolbyVision, kAllProfiles);
     else if (codec == "mp4a")
       audio_codecs.push_back(media::AudioCodec::kAAC);
     else if (codec == "vorbis")
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index c705d6ba..ea62c4a9 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -1535,8 +1535,11 @@
   keyboard_occluded_bounds_ = rect_in_screen;
 
   // If keyboard is disabled, reset the insets_.
-  if (keyboard_occluded_bounds_.IsEmpty())
-    insets_ = gfx::Insets();
+  if (keyboard_occluded_bounds_.IsEmpty()) {
+    SetInsets(gfx::Insets());
+  } else {
+    UpdateInsetsWithVirtualKeyboardEnabled();
+  }
 
   aura::Window* top_level_window = window_->GetToplevelWindow();
 #if BUILDFLAG(IS_CHROMEOS_ASH)
@@ -2453,11 +2456,11 @@
 void RenderWidgetHostViewAura::UpdateInsetsWithVirtualKeyboardEnabled() {
   // Update insets if the keyboard is shown.
   if (!keyboard_occluded_bounds_.IsEmpty()) {
-    insets_ = gfx::Insets::TLBR(
+    SetInsets(gfx::Insets::TLBR(
         0, 0,
         gfx::IntersectRects(GetViewBounds(), keyboard_occluded_bounds_)
             .height(),
-        0);
+        0));
   }
 }
 
diff --git a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
index 3a6bb9fa..e9f0a3f 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
@@ -4973,7 +4973,7 @@
   EXPECT_EQ(view_->GetNativeView()->bounds(), orig_view_bounds);
 
   // Simulate virtual keyboard.
-  input_method->SetOnScreenKeyboardBounds(keyboard_view_bounds);
+  input_method->SetVirtualKeyboardBounds(keyboard_view_bounds);
 
   // Window should be shifted.
   EXPECT_EQ(view_->GetNativeView()->bounds(), shifted_view_bounds);
@@ -5022,7 +5022,7 @@
       0, 0,
       gfx::IntersectRects(orig_view_bounds, keyboard_view_bounds).height(), 0));
   EXPECT_EQ(view_->insets_, origin_view_insets);
-  input_method->SetOnScreenKeyboardBounds(keyboard_view_bounds);
+  input_method->SetVirtualKeyboardBounds(keyboard_view_bounds);
 
   // Window should be shifted. The insets will be updated.
   EXPECT_EQ(view_->GetNativeView()->bounds(), shifted_view_bounds);
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm
index 6975087..9c42f305 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -265,6 +265,8 @@
   // destroying the associated bridge), and close the receiver (to allow it
   // to be re-bound). Note that |in_process_ns_view_bridge_| remains valid.
   remote_ns_view_client_receiver_.reset();
+  if (remote_ns_view_)
+    remote_ns_view_->Destroy();
   remote_ns_view_.reset();
 
   // Enable accessibility focus overriding for remote NSViews.
@@ -738,6 +740,8 @@
   ns_view_ = nullptr;
   in_process_ns_view_bridge_.reset();
   remote_ns_view_client_receiver_.reset();
+  if (remote_ns_view_)
+    remote_ns_view_->Destroy();
   remote_ns_view_.reset();
 
   // Delete the delegated frame state, which will reach back into
diff --git a/content/browser/web_contents/web_contents_view_mac.mm b/content/browser/web_contents/web_contents_view_mac.mm
index 3338202..b78d203 100644
--- a/content/browser/web_contents/web_contents_view_mac.mm
+++ b/content/browser/web_contents/web_contents_view_mac.mm
@@ -654,6 +654,7 @@
     remote_ns_view_->SetVisible(false);
     remote_ns_view_->ResetParentNSView();
     remote_ns_view_host_receiver_.reset();
+    remote_ns_view_->Destroy();
     remote_ns_view_.reset();
     // Permit the in-process NSView to call back into |this| again.
     [GetInProcessNSView() setHost:this];
diff --git a/content/common/render_widget_host_ns_view.mojom b/content/common/render_widget_host_ns_view.mojom
index 6c1763c..7338942 100644
--- a/content/common/render_widget_host_ns_view.mojom
+++ b/content/common/render_widget_host_ns_view.mojom
@@ -101,6 +101,12 @@
                            string url,
                            array<string> file_paths)
     => (blink.mojom.ShareError error);
+
+  // TODO(https://crbug.com/1327478): This is a work around for a bug in mojo
+  // where close notifications for associated messages pipes can sometimes be
+  // delivered later than they should. This method is called before closing the
+  // remote, and is treated as if a close notification was received.
+  Destroy();
 };
 
 // The interface through which the RenderWidgetHostViewCocoa NSView in the app
diff --git a/content/common/web_contents_ns_view_bridge.mojom b/content/common/web_contents_ns_view_bridge.mojom
index f002e34..436941d 100644
--- a/content/common/web_contents_ns_view_bridge.mojom
+++ b/content/common/web_contents_ns_view_bridge.mojom
@@ -39,6 +39,12 @@
             uint32 operation_mask,
             gfx.mojom.ImageSkia? image,
             gfx.mojom.Vector2d image_offset);
+
+  // TODO(https://crbug.com/1327478): This is a work around for a bug in mojo
+  // where close notifications for associated messages pipes can sometimes be
+  // delivered later than they should. This method is called before closing the
+  // remote, and is treated as if a close notification was received.
+  Destroy();
 };
 
 // The method through which a window was focused (directly focused, or by
diff --git a/content/public/browser/hid_delegate.h b/content/public/browser/hid_delegate.h
index 4cfc1cb6..4724dfa 100644
--- a/content/public/browser/hid_delegate.h
+++ b/content/public/browser/hid_delegate.h
@@ -86,7 +86,8 @@
   // object.
   virtual void AddObserver(BrowserContext* browser_context,
                            Observer* observer) = 0;
-  virtual void RemoveObserver(Observer* observer) = 0;
+  virtual void RemoveObserver(BrowserContext* browser_context,
+                              Observer* observer) = 0;
 
   // Returns true if |origin| is allowed to bypass the HID blocklist and
   // access reports contained in FIDO collections.
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc
index a1ed3ab..709d4f6 100644
--- a/content/public/test/browser_test_utils.cc
+++ b/content/public/test/browser_test_utils.cc
@@ -3084,21 +3084,33 @@
 class FrameDeletedObserver::FrameTreeNodeObserverImpl
     : public FrameTreeNode::Observer {
  public:
-  explicit FrameTreeNodeObserverImpl(FrameTreeNode* owner) : owner_(owner) {
+  explicit FrameTreeNodeObserverImpl(FrameTreeNode* owner)
+      : frame_tree_node_id_(owner->frame_tree_node_id()), owner_(owner) {
     owner->AddObserver(this);
   }
   ~FrameTreeNodeObserverImpl() override = default;
 
-  void Run() { run_loop_.Run(); }
-
- private:
-  // FrameTreeNode::Observer
-  void OnFrameTreeNodeDestroyed(FrameTreeNode* node) override {
-    if (node == owner_)
-      run_loop_.Quit();
+  void Run() {
+    if (!IsDestroyed()) {
+      run_loop_.Run();
+    }
   }
 
-  raw_ptr<FrameTreeNode, DanglingUntriaged> owner_;
+  bool IsDestroyed() const { return owner_ == nullptr; }
+
+  int frame_tree_node_id() const { return frame_tree_node_id_; }
+
+ private:
+  // FrameTreeNode::Observer:
+  void OnFrameTreeNodeDestroyed(FrameTreeNode* node) override {
+    if (node == owner_) {
+      owner_ = nullptr;
+      run_loop_.Quit();
+    }
+  }
+
+  const int frame_tree_node_id_;
+  raw_ptr<FrameTreeNode> owner_;
   base::RunLoop run_loop_;
 };
 
@@ -3112,6 +3124,14 @@
   impl_->Run();
 }
 
+bool FrameDeletedObserver::IsDeleted() const {
+  return impl_->IsDestroyed();
+}
+
+int FrameDeletedObserver::GetFrameTreeNodeId() const {
+  return impl_->frame_tree_node_id();
+}
+
 TestNavigationManager::TestNavigationManager(WebContents* web_contents,
                                              const GURL& url)
     : WebContentsObserver(web_contents), url_(url) {}
diff --git a/content/public/test/browser_test_utils.h b/content/public/test/browser_test_utils.h
index 96b498d..f684fff 100644
--- a/content/public/test/browser_test_utils.h
+++ b/content/public/test/browser_test_utils.h
@@ -255,14 +255,18 @@
 
 // Simulates clicking at the center of the given tab asynchronously; modifiers
 // may contain bits from WebInputEvent::Modifiers. Sends the event through
-// RenderWidgetHostInputEventRouter and thus can target OOPIFs.
+// RenderWidgetHostInputEventRouter and thus can target OOPIFs. If an OOPIF is
+// the intended target, ensure that its hit test data is available for routing,
+// using `WaitForHitTestData`, first.
 void SimulateMouseClick(WebContents* web_contents,
                         int modifiers,
                         blink::WebMouseEvent::Button button);
 
 // Simulates clicking at the point |point| of the given tab asynchronously;
 // modifiers may contain bits from WebInputEvent::Modifiers. Sends the event
-// through RenderWidgetHostInputEventRouter and thus can target OOPIFs.
+// through RenderWidgetHostInputEventRouter and thus can target OOPIFs. If an
+// OOPIF is the intended target, ensure that its hit test data is available for
+// routing, using `WaitForHitTestData`, first.
 void SimulateMouseClickAt(WebContents* web_contents,
                           int modifiers,
                           blink::WebMouseEvent::Button button,
@@ -1572,6 +1576,10 @@
 
   void Wait();
 
+  bool IsDeleted() const;
+
+  int GetFrameTreeNodeId() const;
+
  private:
   // Private impl struct which hides non public types including FrameTreeNode.
   class FrameTreeNodeObserverImpl;
diff --git a/content/services/auction_worklet/BUILD.gn b/content/services/auction_worklet/BUILD.gn
index 9ed5367c..7ee1910 100644
--- a/content/services/auction_worklet/BUILD.gn
+++ b/content/services/auction_worklet/BUILD.gn
@@ -75,11 +75,13 @@
   configs += [
     "//build/config/compiler:wexit_time_destructors",
     "//v8:external_startup_data",
+    "//content:content_implementation",
   ]
 
   deps = [
     ":protocol_sources",
     "//base",
+    "//content:export",
     "//gin",
     "//mojo/public/cpp/bindings",
     "//net",
@@ -93,9 +95,23 @@
   public_deps = [ "public/mojom" ]
 }
 
+# See comment at the top of //content/BUILD.gn for how this works.
+group("for_content_tests") {
+  visibility = [ ":tests" ]
+  if (!is_component_build) {
+    public_deps = [ ":auction_worklet" ]
+  }
+}
+
 source_set("tests") {
   testonly = true
 
+  # See comment at the top of //content/BUILD.gn for why this is disabled in
+  # component builds.
+  if (is_component_build) {
+    check_includes = false
+  }
+
   sources = [
     "auction_downloader_unittest.cc",
     "auction_v8_helper_unittest.cc",
@@ -116,8 +132,6 @@
   ]
 
   deps = [
-    ":auction_worklet",
-    "public/mojom",
     "//base",
     "//base/test:test_support",
     "//gin",
@@ -131,6 +145,8 @@
     "//v8",
   ]
 
+  public_deps = [ ":for_content_tests" ]
+
   if (v8_use_external_startup_data) {
     deps += [ "//gin" ]
   }
diff --git a/content/services/auction_worklet/auction_downloader.h b/content/services/auction_worklet/auction_downloader.h
index af2ce2c..bb789d1 100644
--- a/content/services/auction_worklet/auction_downloader.h
+++ b/content/services/auction_worklet/auction_downloader.h
@@ -10,6 +10,7 @@
 
 #include "base/callback.h"
 #include "base/unguessable_token.h"
+#include "content/common/content_export.h"
 #include "net/http/http_response_headers.h"
 #include "net/url_request/redirect_info.h"
 #include "services/network/public/mojom/url_loader_factory.mojom-forward.h"
@@ -25,7 +26,7 @@
 
 // Download utility for auction scripts and JSON data. Creates requests and
 // blocks responses.
-class AuctionDownloader {
+class CONTENT_EXPORT AuctionDownloader {
  public:
   // Mime type to use for Accept header. Any response without a matching
   // Content-Type header is rejected.
diff --git a/content/services/auction_worklet/auction_v8_helper.h b/content/services/auction_worklet/auction_v8_helper.h
index 60283d0..256598d 100644
--- a/content/services/auction_worklet/auction_v8_helper.h
+++ b/content/services/auction_worklet/auction_v8_helper.h
@@ -21,6 +21,7 @@
 #include "base/task/sequenced_task_runner.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/time/time.h"
+#include "content/common/content_export.h"
 #include "gin/public/isolate_holder.h"
 #include "mojo/public/cpp/bindings/pending_associated_receiver.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -56,7 +57,7 @@
 // the thread represented by the `v8_runner` argument to Create(). It's the
 // caller's responsibility to ensure that all other methods are used from the v8
 // runner.
-class AuctionV8Helper
+class CONTENT_EXPORT AuctionV8Helper
     : public base::RefCountedDeleteOnSequence<AuctionV8Helper> {
  public:
   // Timeout for script execution.
@@ -65,7 +66,7 @@
   // Helper class to set up v8 scopes to use Isolate. All methods expect a
   // FullIsolateScope to be have been created on the current thread, and a
   // context to be entered.
-  class FullIsolateScope {
+  class CONTENT_EXPORT FullIsolateScope {
    public:
     explicit FullIsolateScope(AuctionV8Helper* v8_helper);
     explicit FullIsolateScope(const FullIsolateScope&) = delete;
@@ -83,7 +84,7 @@
   //
   // This class is thread-safe, except SetResumeCallback must be used from V8
   // thread.
-  class DebugId : public base::RefCountedThreadSafe<DebugId> {
+  class CONTENT_EXPORT DebugId : public base::RefCountedThreadSafe<DebugId> {
    public:
     explicit DebugId(AuctionV8Helper* v8_helper);
 
diff --git a/content/services/auction_worklet/auction_v8_inspector_util.h b/content/services/auction_worklet/auction_v8_inspector_util.h
index e8e8f6c..2bcdeb6 100644
--- a/content/services/auction_worklet/auction_v8_inspector_util.h
+++ b/content/services/auction_worklet/auction_v8_inspector_util.h
@@ -10,12 +10,14 @@
 #include <string>
 #include <vector>
 
+#include "content/common/content_export.h"
 #include "v8/include/v8-inspector.h"
 
 namespace auction_worklet {
 
 // Extracts UTF-8 bytes from `s` (converting from UTF-16 if needed).
-std::vector<uint8_t> GetStringBytes(const v8_inspector::StringView& s);
+CONTENT_EXPORT std::vector<uint8_t> GetStringBytes(
+    const v8_inspector::StringView& s);
 
 // As above, but for StringBuffer.
 inline std::vector<uint8_t> GetStringBytes(v8_inspector::StringBuffer* s) {
diff --git a/content/services/auction_worklet/auction_worklet_service_impl.h b/content/services/auction_worklet/auction_worklet_service_impl.h
index 5611a0a..b43c3c0 100644
--- a/content/services/auction_worklet/auction_worklet_service_impl.h
+++ b/content/services/auction_worklet/auction_worklet_service_impl.h
@@ -6,6 +6,7 @@
 #define CONTENT_SERVICES_AUCTION_WORKLET_AUCTION_WORKLET_SERVICE_IMPL_H_
 
 #include "base/memory/scoped_refptr.h"
+#include "content/common/content_export.h"
 #include "content/services/auction_worklet/auction_v8_helper.h"
 #include "content/services/auction_worklet/public/mojom/auction_worklet_service.mojom.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
@@ -28,7 +29,8 @@
 
 // mojom::AuctionWorkletService implementation. This is intended to run in a
 // sandboxed utility process.
-class AuctionWorkletServiceImpl : public mojom::AuctionWorkletService {
+class CONTENT_EXPORT AuctionWorkletServiceImpl
+    : public mojom::AuctionWorkletService {
  public:
   explicit AuctionWorkletServiceImpl(const AuctionWorkletServiceImpl&) = delete;
   AuctionWorkletServiceImpl& operator=(const AuctionWorkletServiceImpl&) =
diff --git a/content/services/auction_worklet/bidder_worklet.h b/content/services/auction_worklet/bidder_worklet.h
index a3d5a0c..5ada948 100644
--- a/content/services/auction_worklet/bidder_worklet.h
+++ b/content/services/auction_worklet/bidder_worklet.h
@@ -18,6 +18,7 @@
 #include "base/containers/unique_ptr_adapters.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/time/time.h"
+#include "content/common/content_export.h"
 #include "content/services/auction_worklet/auction_v8_helper.h"
 #include "content/services/auction_worklet/public/mojom/auction_worklet_service.mojom.h"
 #include "content/services/auction_worklet/public/mojom/bidder_worklet.mojom.h"
@@ -56,7 +57,7 @@
 // to both be used for two generateBid() calls for different interest groups
 // with the same owner in the same auction, and to be used to bid for the same
 // interest group in different auctions.
-class BidderWorklet : public mojom::BidderWorklet {
+class CONTENT_EXPORT BidderWorklet : public mojom::BidderWorklet {
  public:
   // Deletes the worklet immediately and resets the BidderWorklet's Mojo pipe
   // with the provided description. See mojo::Receiver::ResetWithReason().
diff --git a/content/services/auction_worklet/context_recycler.h b/content/services/auction_worklet/context_recycler.h
index 337c499e..48ed970 100644
--- a/content/services/auction_worklet/context_recycler.h
+++ b/content/services/auction_worklet/context_recycler.h
@@ -9,6 +9,7 @@
 #include <vector>
 
 #include "base/memory/raw_ptr.h"
+#include "content/common/content_export.h"
 #include "content/services/auction_worklet/auction_v8_helper.h"
 #include "v8/include/v8-forward.h"
 
@@ -40,7 +41,7 @@
 // This helps manage the state of bindings on a context should we chose to
 // recycle it, by calling Reset() after the current usage is done, to prepare
 // for the next. Context is accessed via ContextRecyclerScope.
-class ContextRecycler {
+class CONTENT_EXPORT ContextRecycler {
  public:
   explicit ContextRecycler(AuctionV8Helper* v8_helper);
   ~ContextRecycler();
@@ -94,7 +95,7 @@
 
 // Helper to enter a context scope on creation and reset all bindings
 // on destruction.
-class ContextRecyclerScope {
+class CONTENT_EXPORT ContextRecyclerScope {
  public:
   // `context_recycler` must outlast `this`.
   explicit ContextRecyclerScope(ContextRecycler& context_recycler);
diff --git a/content/services/auction_worklet/debug_command_queue.h b/content/services/auction_worklet/debug_command_queue.h
index b7a64c2..55fc63ec 100644
--- a/content/services/auction_worklet/debug_command_queue.h
+++ b/content/services/auction_worklet/debug_command_queue.h
@@ -15,6 +15,7 @@
 #include "base/synchronization/lock.h"
 #include "base/task/sequenced_task_runner.h"
 #include "base/thread_annotations.h"
+#include "content/common/content_export.h"
 
 namespace auction_worklet {
 
@@ -23,7 +24,8 @@
 // execution of V8 thread when paused in debugger. It's owned by the
 // AuctionV8Helper (but may extend its own lifetime a bit to keep callbacks
 // safe).
-class DebugCommandQueue : public base::RefCountedThreadSafe<DebugCommandQueue> {
+class CONTENT_EXPORT DebugCommandQueue
+    : public base::RefCountedThreadSafe<DebugCommandQueue> {
  public:
   // May be created and destroyed on any thread.
   explicit DebugCommandQueue(
diff --git a/content/services/auction_worklet/public/mojom/BUILD.gn b/content/services/auction_worklet/public/mojom/BUILD.gn
index 9eeb9c0..d52f717 100644
--- a/content/services/auction_worklet/public/mojom/BUILD.gn
+++ b/content/services/auction_worklet/public/mojom/BUILD.gn
@@ -5,7 +5,9 @@
 import("//mojo/public/tools/bindings/mojom.gni")
 
 mojom("mojom") {
-  generate_java = false
+  cpp_only = true
+  disable_variants = true
+
   sources = [
     "auction_worklet_service.mojom",
     "bidder_worklet.mojom",
@@ -20,4 +22,18 @@
   ]
   overridden_deps = [ "//third_party/blink/public/mojom:mojom_platform" ]
   component_deps = [ "//third_party/blink/public/common" ]
+
+  component_output_prefix =
+      "content_services_auction_worklet_public_mojo_bindings"
+  export_class_attribute = "CONTENT_EXPORT"
+  export_define = "CONTENT_IMPLEMENTATION=1"
+  export_header = "content/common/content_export.h"
+}
+
+# See comment at the top of //content/BUILD.gn for how this works.
+group("for_content_tests") {
+  visibility = [ "//content/test/*" ]
+  if (!is_component_build) {
+    public_deps = [ ":mojom" ]
+  }
 }
diff --git a/content/services/auction_worklet/seller_worklet.h b/content/services/auction_worklet/seller_worklet.h
index 87c04d5..33980aa 100644
--- a/content/services/auction_worklet/seller_worklet.h
+++ b/content/services/auction_worklet/seller_worklet.h
@@ -17,6 +17,7 @@
 #include "base/memory/scoped_refptr.h"
 #include "base/sequence_checker.h"
 #include "base/time/time.h"
+#include "content/common/content_export.h"
 #include "content/services/auction_worklet/auction_v8_helper.h"
 #include "content/services/auction_worklet/public/mojom/auction_worklet_service.mojom-forward.h"
 #include "content/services/auction_worklet/public/mojom/auction_worklet_service.mojom.h"
@@ -44,7 +45,7 @@
 // Represents a seller worklet for FLEDGE
 // (https://github.com/WICG/turtledove/blob/main/FLEDGE.md). Loads and runs the
 // seller worklet's Javascript.
-class SellerWorklet : public mojom::SellerWorklet {
+class CONTENT_EXPORT SellerWorklet : public mojom::SellerWorklet {
  public:
   // Deletes the worklet immediately and resets the SellerWorklet's Mojo pipe
   // with the provided description. See mojo::Receiver::ResetWithReason().
diff --git a/content/services/auction_worklet/set_bid_bindings.h b/content/services/auction_worklet/set_bid_bindings.h
index 1f1ab0d1..735cba78 100644
--- a/content/services/auction_worklet/set_bid_bindings.h
+++ b/content/services/auction_worklet/set_bid_bindings.h
@@ -8,6 +8,7 @@
 #include "base/callback.h"
 #include "base/memory/raw_ptr.h"
 #include "base/time/time.h"
+#include "content/common/content_export.h"
 #include "content/services/auction_worklet/auction_v8_helper.h"
 #include "content/services/auction_worklet/context_recycler.h"
 #include "content/services/auction_worklet/public/mojom/bidder_worklet.mojom-forward.h"
@@ -20,7 +21,7 @@
 
 // Class to manage bindings for setting a bidding result. Expected to be used
 // for a context managed by ContextRecycler.
-class SetBidBindings : public Bindings {
+class CONTENT_EXPORT SetBidBindings : public Bindings {
  public:
   explicit SetBidBindings(AuctionV8Helper* v8_helper);
   SetBidBindings(const SetBidBindings&) = delete;
diff --git a/content/services/auction_worklet/trusted_signals.h b/content/services/auction_worklet/trusted_signals.h
index b967735..8fafd9d 100644
--- a/content/services/auction_worklet/trusted_signals.h
+++ b/content/services/auction_worklet/trusted_signals.h
@@ -14,6 +14,7 @@
 #include "base/callback.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_refptr.h"
+#include "content/common/content_export.h"
 #include "net/http/http_response_headers.h"
 #include "services/network/public/mojom/url_loader_factory.mojom-forward.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -39,13 +40,13 @@
 // JSON subcomponents would remove 2 copies, without too much complexity. Could
 // even implement V8 deep-copy logic, to remove two more copies (counting the
 // clone operation as a copy).
-class TrustedSignals {
+class CONTENT_EXPORT TrustedSignals {
  public:
   // Contains the values returned by the server.
   //
   // This can be created and destroyed on any thread, but GetSignals() can only
   // be used on the V8 thread.
-  class Result : public base::RefCountedThreadSafe<Result> {
+  class CONTENT_EXPORT Result : public base::RefCountedThreadSafe<Result> {
    public:
     // Constructor for bidding signals.
     Result(std::map<std::string, std::string> bidder_json_data,
diff --git a/content/services/auction_worklet/trusted_signals_request_manager.h b/content/services/auction_worklet/trusted_signals_request_manager.h
index fc7cd77..031d26e 100644
--- a/content/services/auction_worklet/trusted_signals_request_manager.h
+++ b/content/services/auction_worklet/trusted_signals_request_manager.h
@@ -18,6 +18,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
 #include "base/timer/timer.h"
+#include "content/common/content_export.h"
 #include "content/services/auction_worklet/trusted_signals.h"
 #include "services/network/public/mojom/url_loader_factory.mojom-forward.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -33,7 +34,7 @@
 // requests.
 //
 // TODO(https://crbug.com/1276639): Cache responses as well.
-class TrustedSignalsRequestManager {
+class CONTENT_EXPORT TrustedSignalsRequestManager {
  public:
   // Delay between construction of a Request and automatically starting a
   // network request when `automatically_send_requests` is true.
diff --git a/content/services/auction_worklet/worklet_loader.h b/content/services/auction_worklet/worklet_loader.h
index b15ef5197..d1dae0c 100644
--- a/content/services/auction_worklet/worklet_loader.h
+++ b/content/services/auction_worklet/worklet_loader.h
@@ -15,6 +15,7 @@
 #include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/task/sequenced_task_runner.h"
+#include "content/common/content_export.h"
 #include "content/services/auction_worklet/auction_downloader.h"
 #include "content/services/auction_worklet/auction_v8_helper.h"
 #include "services/network/public/mojom/url_loader_factory.mojom-forward.h"
@@ -35,13 +36,13 @@
 // UnboundScript or WasmModuleObject on the V8 thread. Create via the
 // appropriate subclass. That also provides the way extracting the appropriate
 // type from Result.
-class WorkletLoaderBase {
+class CONTENT_EXPORT WorkletLoaderBase {
  public:
   // The result of loading JS or Wasm, memory-managing the underlying V8 object.
   //
   // This helps ensure that the script handle is deleted on the right thread
   // even in case when the callback handling the result is destroyed.
-  class Result {
+  class CONTENT_EXPORT Result {
    public:
     Result();
     Result(scoped_refptr<AuctionV8Helper> v8_helper,
@@ -150,7 +151,7 @@
 };
 
 // Utility for loading and compiling worklet JavaScript.
-class WorkletLoader : public WorkletLoaderBase {
+class CONTENT_EXPORT WorkletLoader : public WorkletLoaderBase {
  public:
   // Starts loading the resource on construction. Callback will be invoked
   // asynchronously once the data has been fetched and compiled or an error has
@@ -171,7 +172,7 @@
   static v8::Global<v8::UnboundScript> TakeScript(Result&& result);
 };
 
-class WorkletWasmLoader : public WorkletLoaderBase {
+class CONTENT_EXPORT WorkletWasmLoader : public WorkletLoaderBase {
  public:
   // Starts loading the resource on construction. Callback will be invoked
   // asynchronously once the data has been fetched and compiled or an error has
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index f106122..d5cbec7 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -1566,7 +1566,7 @@
     "//content/public/gpu",
     "//content/public/renderer",
     "//content/renderer:for_content_tests",
-    "//content/services/auction_worklet/public/mojom",
+    "//content/services/auction_worklet/public/mojom:for_content_tests",
     "//content/shell:content_browsertests_mojom",
     "//content/shell:content_shell_lib",
     "//content/shell:pak",
@@ -2653,9 +2653,7 @@
     "//content/public/common:trust_tokens_mojo_bindings",
     "//content/public/renderer",
     "//content/renderer:for_content_tests",
-    "//content/services/auction_worklet",
     "//content/services/auction_worklet:tests",
-    "//content/services/auction_worklet/public/mojom",
     "//content/services/shared_storage_worklet:tests",
     "//content/services/shared_storage_worklet/public/mojom",
     "//crypto",
diff --git a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
index 4ea3d976..d915175 100644
--- a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
@@ -416,6 +416,7 @@
 
 # Flakes on Android
 crbug.com/1203317 [ android android-shield-android-tv no-passthrough ] Pixel_OffscreenCanvasWebGLPaintAfterResize [ RetryOnFailure ]
+crbug.com/1191282 [ android android-shield-android-tv android-chromium no-passthrough ] Pixel_WebGLPreservedAfterTabSwitch [ RetryOnFailure ]
 crbug.com/1203317 [ android android-pixel-2 no-passthrough ] Pixel_OffscreenCanvasWebGLPaintAfterResize [ RetryOnFailure ]
 crbug.com/1203317 [ android android-pixel-6 android-chromium ] Pixel_OffscreenCanvasWebGLPaintAfterResize [ RetryOnFailure ]
 
diff --git a/docs/android_accessing_cpp_features_in_java.md b/docs/android_accessing_cpp_features_in_java.md
index a606196b..0af33dd 100644
--- a/docs/android_accessing_cpp_features_in_java.md
+++ b/docs/android_accessing_cpp_features_in_java.md
@@ -63,7 +63,22 @@
     }
     ```
 
-3. The generated file `out/Default/gen/.../org/chromium/foo/FooFeatures.java`
+3. Add a `deps` entry to `"common_java"` in `"//android_webview/BUILD.gn"` if
+   creating a new `android_library` in the previous step:
+
+   ```gn
+   android_library("common_java") {
+     ...
+
+     deps = [
+       ...
+       "//path/to:foo_java",
+       ...
+     ]
+   }
+   ```
+
+4. The generated file `out/Default/gen/.../org/chromium/foo/FooFeatures.java`
    would contain:
 
     ```java
diff --git a/docs/images/webui_build_pipeline.png b/docs/images/webui_build_pipeline.png
index 4e4fb8f..f0d300a8 100644
--- a/docs/images/webui_build_pipeline.png
+++ b/docs/images/webui_build_pipeline.png
Binary files differ
diff --git a/docs/webui_build_configuration.md b/docs/webui_build_configuration.md
index 269ff31..cfe6525 100644
--- a/docs/webui_build_configuration.md
+++ b/docs/webui_build_configuration.md
@@ -410,9 +410,11 @@
 ```
 
 List of files params:
-static_files: List of HTML/CSS files that don't need any processing and will be
-              included in the build verbatim. Don't confuse with |css_files|
-              below. Required parameter.
+static_files: Required parameter. List of
+              1) non Web Component HTML/CSS files (don't confuse with
+                 |css_files| below). These are passed to preprocess_if_expr()
+              2) JPG/PNG/SVG files. These are included in the build verbatim
+                 without any preprocessing.
 
 web_component_files:  List of TS files that hold Web Component definitions with
                       equivalent HTML template files. These can be either native
diff --git a/extensions/browser/api/metrics_private/metrics_private_api.cc b/extensions/browser/api/metrics_private/metrics_private_api.cc
index afb5496..24a73bc 100644
--- a/extensions/browser/api/metrics_private/metrics_private_api.cc
+++ b/extensions/browser/api/metrics_private/metrics_private_api.cc
@@ -32,6 +32,7 @@
 namespace RecordValue = api::metrics_private::RecordValue;
 namespace RecordBoolean = api::metrics_private::RecordBoolean;
 namespace RecordEnumerationValue = api::metrics_private::RecordEnumerationValue;
+namespace RecordSparseHashable = api::metrics_private::RecordSparseHashable;
 namespace RecordSparseValueWithHashMetricName =
     api::metrics_private::RecordSparseValueWithHashMetricName;
 namespace RecordSparseValueWithPersistentHash =
@@ -153,6 +154,15 @@
 }
 
 ExtensionFunction::ResponseAction
+MetricsPrivateRecordSparseHashableFunction::Run() {
+  auto params = RecordSparseHashable::Params::Create(args());
+  EXTENSION_FUNCTION_VALIDATE(params);
+  base::UmaHistogramSparse(params->metric_name,
+                           base::PersistentHash(params->value));
+  return RespondNow(NoArguments());
+}
+
+ExtensionFunction::ResponseAction
 MetricsPrivateRecordSparseValueWithHashMetricNameFunction::Run() {
   auto params = RecordSparseValueWithHashMetricName::Params::Create(args());
   EXTENSION_FUNCTION_VALIDATE(params);
diff --git a/extensions/browser/api/metrics_private/metrics_private_api.h b/extensions/browser/api/metrics_private/metrics_private_api.h
index 3aeb22f2..398abda 100644
--- a/extensions/browser/api/metrics_private/metrics_private_api.h
+++ b/extensions/browser/api/metrics_private/metrics_private_api.h
@@ -113,6 +113,19 @@
   ResponseAction Run() override;
 };
 
+class MetricsPrivateRecordSparseHashableFunction
+    : public MetricsHistogramHelperFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("metricsPrivate.recordSparseHashable",
+                             METRICSPRIVATE_RECORDSPARSEHASHABLE)
+
+ protected:
+  ~MetricsPrivateRecordSparseHashableFunction() override {}
+
+  // ExtensionFunction:
+  ResponseAction Run() override;
+};
+
 class MetricsPrivateRecordSparseValueWithHashMetricNameFunction
     : public MetricsHistogramHelperFunction {
  public:
diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h
index 46e41b7..1b10c9c 100644
--- a/extensions/browser/extension_function_histogram_value.h
+++ b/extensions/browser/extension_function_histogram_value.h
@@ -1252,7 +1252,7 @@
   FILEMANAGERPRIVATE_GETRECENTFILES = 1189,
   FILEMANAGERPRIVATE_RENAMEVOLUME = 1190,
   AUTOTESTPRIVATE_SETMOUSEREVERSESCROLL = 1191,
-  DELETED_METRICSPRIVATE_RECORDSPARSEHASHABLE = 1192,
+  METRICSPRIVATE_RECORDSPARSEHASHABLE = 1192,
   NETWORKINGPRIVATE_SELECTCELLULARMOBILENETWORK = 1193,
   PASSWORDSPRIVATE_IMPORTPASSWORDS = 1194,
   PASSWORDSPRIVATE_EXPORTPASSWORDS = 1195,
diff --git a/extensions/browser/guest_view/web_view/web_view_apitest.cc b/extensions/browser/guest_view/web_view/web_view_apitest.cc
index 0fb9343..1d93f2aa 100644
--- a/extensions/browser/guest_view/web_view/web_view_apitest.cc
+++ b/extensions/browser/guest_view/web_view/web_view_apitest.cc
@@ -310,8 +310,8 @@
       ShellContentBrowserClient::Get()->GetBrowserContext();
   TestGuestViewManager* manager = static_cast<TestGuestViewManager*>(
       TestGuestViewManager::FromBrowserContext(context));
-  // TestGuestViewManager::WaitForSingleGuestCreated may and will get called
-  // before a guest is created.
+  // Test code may access the TestGuestViewManager before it would be created
+  // during creation of the first guest.
   if (!manager) {
     manager =
         static_cast<TestGuestViewManager*>(GuestViewManager::CreateWithDelegate(
@@ -347,7 +347,7 @@
 }
 
 content::WebContents* WebViewAPITest::GetGuestWebContents() {
-  return GetGuestViewManager()->WaitForSingleGuestCreated();
+  return GetGuestViewManager()->DeprecatedWaitForSingleGuestCreated();
 }
 
 // This test verifies that hiding the embedder also hides the guest.
@@ -369,7 +369,7 @@
   LaunchApp("web_view/display_none_set_src");
   // Navigate the guest while it's in "display: none" state.
   SendMessageToEmbedder("navigate-guest");
-  GetGuestViewManager()->WaitForSingleGuestCreated();
+  GetGuestViewManager()->DeprecatedWaitForSingleGuestCreated();
 
   // Now attempt to navigate the guest again.
   SendMessageToEmbedder("navigate-guest");
diff --git a/extensions/common/api/metrics_private.json b/extensions/common/api/metrics_private.json
index 5183f2b..4934c84 100644
--- a/extensions/common/api/metrics_private.json
+++ b/extensions/common/api/metrics_private.json
@@ -188,6 +188,15 @@
         ]
       },
       {
+        "name": "recordSparseHashable",
+        "type": "function",
+        "description": "Increments the count associated with the hash of |value| in the sparse histogram defined by the |metricName| using base::PersistentHash(value). Prefer recordSparseValueWithPersistentHash.",
+        "parameters": [
+          {"name": "metricName", "type": "string"},
+          {"name": "value", "type": "string"}
+        ]
+      },
+      {
         "name": "recordSparseValueWithHashMetricName",
         "type": "function",
         "description": "Increments the count associated with the hash of |value| in the sparse histogram defined by the |metricName| using base::HashMetricName(value).",
diff --git a/gpu/command_buffer/service/shared_image/ozone_image_backing_factory.cc b/gpu/command_buffer/service/shared_image/ozone_image_backing_factory.cc
index 2181049..4dd054f 100644
--- a/gpu/command_buffer/service/shared_image/ozone_image_backing_factory.cc
+++ b/gpu/command_buffer/service/shared_image/ozone_image_backing_factory.cc
@@ -234,11 +234,19 @@
 }
 
 bool OzoneImageBackingFactory::CanImportNativePixmapToWebGPU() {
+#if BUILDFLAG(IS_CHROMEOS)
+  // Safe to always return true here, as it's not possible to create a WebGPU
+  // adapter that doesn't support importing native pixmaps:
+  // https://source.chromium.org/chromium/chromium/src/+/main:gpu/command_buffer/service/webgpu_decoder_impl.cc;drc=daed597d580d450d36578c0cc53b4f72d3b507da;l=1291
+  // TODO(crbug.com/1349189): To check it without vk_context_provider.
+  return true;
+#else
   // Assume that if skia/vulkan vkDevice supports the Vulkan extensions
   // (external_memory_dma_buf, image_drm_format_modifier), then Dawn/WebGPU also
   // support the extensions until there is capability to check the extensions
   // from Dawn vkDevice when they are exposed.
   return CanImportNativePixmapToVulkan();
+#endif
 }
 
 }  // namespace gpu
diff --git a/gpu/config/gpu_util.cc b/gpu/config/gpu_util.cc
index df0d47d..f795466 100644
--- a/gpu/config/gpu_util.cc
+++ b/gpu/config/gpu_util.cc
@@ -936,6 +936,7 @@
       case IntelGpuSeriesType::kSkylake:
       case IntelGpuSeriesType::kGeminilake:
       case IntelGpuSeriesType::kKabylake:
+      case IntelGpuSeriesType::kAmberlake:
       case IntelGpuSeriesType::kCoffeelake:
       case IntelGpuSeriesType::kWhiskeylake:
       case IntelGpuSeriesType::kCometlake:
@@ -947,6 +948,8 @@
       case IntelGpuSeriesType::kJasperlake:
         return "11";
       case IntelGpuSeriesType::kTigerlake:
+      case IntelGpuSeriesType::kRocketlake:
+      case IntelGpuSeriesType::kDG1:
       case IntelGpuSeriesType::kAlderlake:
       case IntelGpuSeriesType::kAlchemist:
         return "12";
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm
index 3b928b31..5b978ac 100644
--- a/ios/chrome/browser/flags/about_flags.mm
+++ b/ios/chrome/browser/flags/about_flags.mm
@@ -926,6 +926,11 @@
      flags_ui::kOsIos,
      FEATURE_VALUE_TYPE(
          autofill::features::kAutofillEnableUnmaskCardRequestSetInstrumentId)},
+    {"autofill-enable-card-product-name",
+     flag_descriptions::kAutofillEnableCardProductNameName,
+     flag_descriptions::kAutofillEnableCardProductNameDescription,
+     flags_ui::kOsIos,
+     FEATURE_VALUE_TYPE(autofill::features::kAutofillEnableCardProductName)},
     {"send-tab-to-self-signin-promo",
      flag_descriptions::kSendTabToSelfSigninPromoName,
      flag_descriptions::kSendTabToSelfSigninPromoDescription, flags_ui::kOsIos,
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
index 15b76e6..5edc494 100644
--- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
+++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
@@ -52,6 +52,12 @@
     "When enabled, UnmaskCardRequest will set the card's non-legacy ID when "
     "available.";
 
+const char kAutofillEnableCardProductNameName[] =
+    "Enable showing card product name";
+const char kAutofillEnableCardProductNameDescription[] =
+    "When enabled, card product name (instead of issuer network) will be shown "
+    "in Payments UI.";
+
 const char kAutofillEnforceDelaysInStrikeDatabaseName[] =
     "Enforce delay between offering Autofill opportunities in the strike "
     "database";
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
index e8bc506..3cb9769 100644
--- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
+++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
@@ -47,6 +47,11 @@
 extern const char kAutofillEnableUnmaskCardRequestSetInstrumentIdName[];
 extern const char kAutofillEnableUnmaskCardRequestSetInstrumentIdDescription[];
 
+// Title and description for flag to enable showing card product name (instead
+// of issuer network) in Payments UI.
+extern const char kAutofillEnableCardProductNameName[];
+extern const char kAutofillEnableCardProductNameDescription[];
+
 // Title and description for flag to enforce delays between offering Autofill
 // opportunities.
 extern const char kAutofillEnforceDelaysInStrikeDatabaseName[];
diff --git a/ios/web/public/test/web_view_interaction_test_util.mm b/ios/web/public/test/web_view_interaction_test_util.mm
index 39e2571..15c1235 100644
--- a/ios/web/public/test/web_view_interaction_test_util.mm
+++ b/ios/web/public/test/web_view_interaction_test_util.mm
@@ -197,7 +197,7 @@
       "    };"
       "})();";
 
-  __block base::DictionaryValue const* rect = nullptr;
+  __block std::unique_ptr<base::DictionaryValue> rect;
 
   bool found = WaitUntilConditionOrTimeout(kWaitForUIElementTimeout, ^{
     std::unique_ptr<base::Value> value =
@@ -208,7 +208,8 @@
       if (dictionary->GetString("error", &error)) {
         DLOG(ERROR) << "Error getting rect: " << error << ", retrying..";
       } else {
-        rect = dictionary->DeepCopy();
+        rect = base::DictionaryValue::From(
+            base::Value::ToUniquePtrValue(dictionary->Clone()));
         return true;
       }
     }
diff --git a/media/BUILD.gn b/media/BUILD.gn
index 576d7a6..4d94c87e 100644
--- a/media/BUILD.gn
+++ b/media/BUILD.gn
@@ -29,6 +29,7 @@
     "ENABLE_DAV1D_DECODER=$enable_dav1d_decoder",
     "ENABLE_AV1_DECODER=$enable_av1_decoder",
     "ENABLE_PLATFORM_DOLBY_VISION=$enable_platform_dolby_vision",
+    "ENABLE_PLATFORM_ENCRYPTED_DOLBY_VISION=$enable_platform_encrypted_dolby_vision",
     "ENABLE_FFMPEG=$media_use_ffmpeg",
     "ENABLE_FFMPEG_VIDEO_DECODERS=$enable_ffmpeg_video_decoders",
     "ENABLE_PLATFORM_HEVC=$enable_platform_hevc",
diff --git a/media/filters/source_buffer_state.cc b/media/filters/source_buffer_state.cc
index 14b82f19..0ff019c8 100644
--- a/media/filters/source_buffer_state.cc
+++ b/media/filters/source_buffer_state.cc
@@ -718,6 +718,18 @@
                << " config: " << video_config.AsHumanReadableString();
       DCHECK(video_config.IsValidConfig());
 
+#if BUILDFLAG(ENABLE_PLATFORM_ENCRYPTED_DOLBY_VISION)
+      // Only encrypted Dolby Vision (DV) is supported, so require the config
+      // to be for an encrypted track.
+      if (video_config.codec() == VideoCodec::kDolbyVision &&
+          !video_config.is_encrypted()) {
+        MEDIA_LOG(ERROR, media_log_)
+            << "MSE playback of DolbyVision is only supported via platform "
+               "decryptor, but the provided DV track is not encrypted.";
+        return false;
+      }
+#endif  // BUILDFLAG(ENABLE_PLATFORM_ENCRYPTED_DOLBY_VISION)
+
       const auto& it = std::find(expected_vcodecs.begin(),
                                  expected_vcodecs.end(), video_config.codec());
       if (it == expected_vcodecs.end()) {
diff --git a/media/gpu/windows/d3d11_decoder_configurator.cc b/media/gpu/windows/d3d11_decoder_configurator.cc
index 6151962..1957f18f 100644
--- a/media/gpu/windows/d3d11_decoder_configurator.cc
+++ b/media/gpu/windows/d3d11_decoder_configurator.cc
@@ -63,7 +63,9 @@
       decoder_dxgi_format = DXGI_FORMAT_P016;
       break;
     default:
-      NOTREACHED() << "Unsupported bit depth: " << bit_depth;
+      MEDIA_LOG(INFO, media_log)
+          << "D3D11VideoDecoder does not support bit depth "
+          << base::strict_cast<int>(bit_depth);
       return nullptr;
   }
 
diff --git a/media/media_options.gni b/media/media_options.gni
index 3349dda..c94ea57 100644
--- a/media/media_options.gni
+++ b/media/media_options.gni
@@ -66,12 +66,16 @@
 
   # Enable Dolby Vision demuxing. Enable by default for Chromecast. Actual
   # decoding must be provided by the platform. Note some Dolby Vision profiles
-  # which are encoded using HEVC require |enable_platform_hevc| to be enabled.
+  # which are encoded using HEVC require `enable_platform_hevc` to be enabled.
   #
   # TODO(crbug.com/1336055): Revisit the default value for this setting as it
   # applies to video-capable devices.
   enable_platform_dolby_vision = proprietary_codecs && is_cast_media_device
 
+  # Enable platform support of encrypted Dolby Vision. Clear Dolby Vision is
+  # still not supported. The actual support depends on platform capability.
+  enable_platform_encrypted_dolby_vision = false
+
   # Enable HLS with SAMPLE-AES decryption.
   #
   # TODO(crbug.com/1329657): Remove the `is_fuchsia` condition once fuchsia
@@ -129,6 +133,9 @@
 assert(
     !enable_platform_dolby_vision || proprietary_codecs,
     "proprietary_codecs=true is required for enable_platform_dolby_vision=true.")
+assert(
+    !enable_platform_encrypted_dolby_vision || enable_platform_dolby_vision,
+    "enable_platform_dolby_vision=true is required for enable_platform_encrypted_dolby_vision=true.")
 assert(!enable_hls_sample_aes || proprietary_codecs,
        "proprietary_codecs=true is required for enable_hls_sample_aes=true.")
 assert(
diff --git a/media/renderers/paint_canvas_video_renderer.cc b/media/renderers/paint_canvas_video_renderer.cc
index 30e42ff..577550d 100644
--- a/media/renderers/paint_canvas_video_renderer.cc
+++ b/media/renderers/paint_canvas_video_renderer.cc
@@ -1509,9 +1509,14 @@
   destination_gl->GenUnverifiedSyncTokenCHROMIUM(
       mailbox_holder.sync_token.GetData());
 
-  if (!VideoFrameYUVConverter::ConvertYUVVideoFrameToDstTextureNoCaching(
+  VideoFrameYUVConverter::GrParams yuv_gr_params;
+  yuv_gr_params.internal_format = internal_format;
+  yuv_gr_params.type = type;
+  yuv_gr_params.flip_y = flip_y;
+  yuv_gr_params.use_visible_rect = true;
+  if (!VideoFrameYUVConverter::ConvertYUVVideoFrameNoCaching(
           video_frame.get(), raster_context_provider, mailbox_holder,
-          internal_format, type, flip_y, true /* use visible_rect */)) {
+          yuv_gr_params)) {
     return false;
   }
 
diff --git a/media/renderers/video_frame_yuv_converter.cc b/media/renderers/video_frame_yuv_converter.cc
index e1ac5c9..7cd02f50 100644
--- a/media/renderers/video_frame_yuv_converter.cc
+++ b/media/renderers/video_frame_yuv_converter.cc
@@ -105,20 +105,18 @@
 bool VideoFrameYUVConverter::ConvertYUVVideoFrameNoCaching(
     const VideoFrame* video_frame,
     viz::RasterContextProvider* raster_context_provider,
-    const gpu::MailboxHolder& dest_mailbox_holder) {
+    const gpu::MailboxHolder& dest_mailbox_holder,
+    absl::optional<GrParams> gr_params) {
   VideoFrameYUVConverter converter;
   return converter.ConvertYUVVideoFrame(video_frame, raster_context_provider,
-                                        dest_mailbox_holder);
+                                        dest_mailbox_holder, gr_params);
 }
 
 bool VideoFrameYUVConverter::ConvertYUVVideoFrame(
     const VideoFrame* video_frame,
     viz::RasterContextProvider* raster_context_provider,
     const gpu::MailboxHolder& dest_mailbox_holder,
-    unsigned int internal_format,
-    unsigned int type,
-    bool flip_y,
-    bool use_visible_rect) {
+    absl::optional<GrParams> gr_params) {
   DCHECK(video_frame);
   DCHECK(IsVideoFrameFormatSupported(*video_frame))
       << "VideoFrame has an unsupported YUV format " << video_frame->format();
@@ -130,10 +128,15 @@
     holder_ = std::make_unique<VideoFrameYUVMailboxesHolder>();
 
   if (raster_context_provider->GrContext()) {
-    // Only SW VideoFrame direct uploading path use SkPixmap.
     return ConvertFromVideoFrameYUVWithGrContext(
         video_frame, raster_context_provider, dest_mailbox_holder,
-        internal_format, type, flip_y, use_visible_rect);
+        gr_params.value_or(GrParams()));
+  }
+
+  // The RasterInterface path does not support flip_y or use_visible_rect.
+  if (gr_params) {
+    DCHECK(!gr_params->flip_y);
+    DCHECK(!gr_params->use_visible_rect);
   }
 
   auto* ri = raster_context_provider->RasterInterface();
@@ -150,20 +153,6 @@
   return true;
 }
 
-bool VideoFrameYUVConverter::ConvertYUVVideoFrameToDstTextureNoCaching(
-    const VideoFrame* video_frame,
-    viz::RasterContextProvider* raster_context_provider,
-    const gpu::MailboxHolder& dest_mailbox_holder,
-    unsigned int internal_format,
-    unsigned int type,
-    bool flip_y,
-    bool use_visible_rect) {
-  VideoFrameYUVConverter converter;
-  return converter.ConvertYUVVideoFrame(video_frame, raster_context_provider,
-                                        dest_mailbox_holder, internal_format,
-                                        type, flip_y, use_visible_rect);
-}
-
 void VideoFrameYUVConverter::ReleaseCachedData() {
   holder_.reset();
 }
@@ -172,10 +161,7 @@
     const VideoFrame* video_frame,
     viz::RasterContextProvider* raster_context_provider,
     const gpu::MailboxHolder& dest_mailbox_holder,
-    unsigned int internal_format,
-    unsigned int type,
-    bool flip_y,
-    bool use_visible_rect) {
+    const GrParams& gr_params) {
   gpu::raster::RasterInterface* ri = raster_context_provider->RasterInterface();
   DCHECK(ri);
   ri->WaitSyncTokenCHROMIUM(dest_mailbox_holder.sync_token.GetConstData());
@@ -186,26 +172,6 @@
         dest_tex_id, GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM);
   }
 
-  bool result = ConvertFromVideoFrameYUVSkia(
-      video_frame, raster_context_provider, dest_mailbox_holder.texture_target,
-      dest_tex_id, internal_format, type, flip_y, use_visible_rect);
-
-  if (dest_mailbox_holder.mailbox.IsSharedImage())
-    ri->EndSharedImageAccessDirectCHROMIUM(dest_tex_id);
-  ri->DeleteGpuRasterTexture(dest_tex_id);
-
-  return result;
-}
-
-bool VideoFrameYUVConverter::ConvertFromVideoFrameYUVSkia(
-    const VideoFrame* video_frame,
-    viz::RasterContextProvider* raster_context_provider,
-    unsigned int texture_target,
-    unsigned int texture_id,
-    unsigned int internal_format,
-    unsigned int type,
-    bool flip_y,
-    bool use_visible_rect) {
   // Rendering YUV textures to SkSurface by dst texture
   GrDirectContext* gr_context = raster_context_provider->GrContext();
   DCHECK(gr_context);
@@ -215,14 +181,17 @@
 
   // Create SkSurface with dst texture.
   GrGLTextureInfo result_gl_texture_info{};
-  result_gl_texture_info.fID = texture_id;
-  result_gl_texture_info.fTarget = texture_target;
-  result_gl_texture_info.fFormat = GetSurfaceColorFormat(internal_format, type);
+  result_gl_texture_info.fID = dest_tex_id;
+  result_gl_texture_info.fTarget = dest_mailbox_holder.texture_target;
+  result_gl_texture_info.fFormat =
+      GetSurfaceColorFormat(gr_params.internal_format, gr_params.type);
 
-  int result_width = use_visible_rect ? video_frame->visible_rect().width()
-                                      : video_frame->coded_size().width();
-  int result_height = use_visible_rect ? video_frame->visible_rect().height()
-                                       : video_frame->coded_size().height();
+  int result_width = gr_params.use_visible_rect
+                         ? video_frame->visible_rect().width()
+                         : video_frame->coded_size().width();
+  int result_height = gr_params.use_visible_rect
+                          ? video_frame->visible_rect().height()
+                          : video_frame->coded_size().height();
 
   GrBackendTexture result_texture(result_width, result_height, GrMipMapped::kNo,
                                   result_gl_texture_info);
@@ -230,25 +199,30 @@
   // Use dst texture as SkSurface back resource.
   auto surface = SkSurface::MakeFromBackendTexture(
       gr_context, result_texture,
-      flip_y ? kBottomLeft_GrSurfaceOrigin : kTopLeft_GrSurfaceOrigin, 1,
-      GetCompatibleSurfaceColorType(result_gl_texture_info.fFormat),
+      gr_params.flip_y ? kBottomLeft_GrSurfaceOrigin : kTopLeft_GrSurfaceOrigin,
+      1, GetCompatibleSurfaceColorType(result_gl_texture_info.fFormat),
       SkColorSpace::MakeSRGB(), nullptr);
 
   // Terminate if surface cannot be created.
-  if (!surface) {
-    return false;
-  }
-
+  bool result = true;
+  if (surface) {
     auto image =
         holder_->VideoFrameToSkImage(video_frame, raster_context_provider);
-    bool result =
-        DrawYUVImageToSkSurface(video_frame, image, surface, use_visible_rect);
+    result = DrawYUVImageToSkSurface(video_frame, image, surface,
+                                     gr_params.use_visible_rect);
+  } else {
+    result = false;
+  }
 
-    // Release textures to guarantee |holder_| doesn't hold read access on
-    // textures it doesn't own.
-    holder_->ReleaseTextures();
+  // Release textures to guarantee |holder_| doesn't hold read access on
+  // textures it doesn't own.
+  holder_->ReleaseTextures();
 
-    return result;
+  if (dest_mailbox_holder.mailbox.IsSharedImage())
+    ri->EndSharedImageAccessDirectCHROMIUM(dest_tex_id);
+  ri->DeleteGpuRasterTexture(dest_tex_id);
+
+  return result;
 }
 
 }  // namespace media
diff --git a/media/renderers/video_frame_yuv_converter.h b/media/renderers/video_frame_yuv_converter.h
index 86059f9..8d907fb 100644
--- a/media/renderers/video_frame_yuv_converter.h
+++ b/media/renderers/video_frame_yuv_converter.h
@@ -34,35 +34,29 @@
 // images.
 class MEDIA_EXPORT VideoFrameYUVConverter {
  public:
-  static bool IsVideoFrameFormatSupported(const VideoFrame& video_frame);
-
-  static bool ConvertYUVVideoFrameNoCaching(
-      const VideoFrame* video_frame,
-      viz::RasterContextProvider* raster_context_provider,
-      const gpu::MailboxHolder& dest_mailbox_holder);
-
-  // TODO(crbug.com/1108154): Will merge this uploading path
-  // with ConvertYUVVideoFrameYUVWithGrContext after solving
-  // issue 1120911, 1120912
-  static bool ConvertYUVVideoFrameToDstTextureNoCaching(
-      const VideoFrame* video_frame,
-      viz::RasterContextProvider* raster_context_provider,
-      const gpu::MailboxHolder& dest_mailbox_holder,
-      unsigned int internal_format,
-      unsigned int type,
-      bool flip_y,
-      bool use_visible_rect);
+  // These parameters are only supported by ConvertYUVVideoFrame et al when the
+  // specified RasterContextProvider also has a GrContext (equivalently, when
+  // OOP-R is disabled). Isolate them in their own structure, so they can
+  // eventually be removed once OOP-R is universal.
+  struct GrParams {
+    unsigned int internal_format = GL_RGBA;
+    unsigned int type = GL_UNSIGNED_BYTE;
+    bool flip_y = false;
+    bool use_visible_rect = false;
+  };
 
   VideoFrameYUVConverter();
   ~VideoFrameYUVConverter();
-
+  static bool IsVideoFrameFormatSupported(const VideoFrame& video_frame);
+  static bool ConvertYUVVideoFrameNoCaching(
+      const VideoFrame* video_frame,
+      viz::RasterContextProvider* raster_context_provider,
+      const gpu::MailboxHolder& dest_mailbox_holder,
+      absl::optional<GrParams> gr_params = absl::nullopt);
   bool ConvertYUVVideoFrame(const VideoFrame* video_frame,
                             viz::RasterContextProvider* raster_context_provider,
                             const gpu::MailboxHolder& dest_mailbox_holder,
-                            unsigned int internal_format = GL_RGBA,
-                            unsigned int type = GL_UNSIGNED_BYTE,
-                            bool flip_y = false,
-                            bool use_visible_rect = false);
+                            absl::optional<GrParams> gr_params = absl::nullopt);
   void ReleaseCachedData();
 
  private:
@@ -70,19 +64,7 @@
       const VideoFrame* video_frame,
       viz::RasterContextProvider* raster_context_provider,
       const gpu::MailboxHolder& dest_mailbox_holder,
-      unsigned int internal_format,
-      unsigned int type,
-      bool flip_y,
-      bool use_visible_rect);
-  bool ConvertFromVideoFrameYUVSkia(
-      const VideoFrame* video_frame,
-      viz::RasterContextProvider* raster_context_provider,
-      unsigned int texture_target,
-      unsigned int texture_id,
-      unsigned int internal_format,
-      unsigned int type,
-      bool flip_y,
-      bool use_visible_rect);
+      const GrParams& gr_params);
 
   std::unique_ptr<VideoFrameYUVMailboxesHolder> holder_;
 };
diff --git a/media/tools/constrained_network_server/cn.py b/media/tools/constrained_network_server/cn.py
deleted file mode 100755
index fe5781c..0000000
--- a/media/tools/constrained_network_server/cn.py
+++ /dev/null
@@ -1,123 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""A script for configuring constraint networks.
-
-Sets up a constrained network configuration on a specific port. Traffic on this
-port will be redirected to another local server port.
-
-The configuration includes bandwidth, latency, and packet loss.
-"""
-
-import collections
-import logging
-import optparse
-import traffic_control
-
-# Default logging is ERROR. Use --verbose to enable DEBUG logging.
-_DEFAULT_LOG_LEVEL = logging.ERROR
-
-Dispatcher = collections.namedtuple('Dispatcher', ['dispatch', 'requires_ports',
-                                                   'desc'])
-
-# Map of command names to traffic_control functions.
-COMMANDS = {
-    # Adds a new constrained network configuration.
-    'add': Dispatcher(traffic_control.CreateConstrainedPort,
-                      requires_ports=True, desc='Add a new constrained port.'),
-
-    # Deletes an existing constrained network configuration.
-    'del': Dispatcher(traffic_control.DeleteConstrainedPort,
-                      requires_ports=True, desc='Delete a constrained port.'),
-
-    # Deletes all constrained network configurations.
-    'teardown': Dispatcher(traffic_control.TearDown,
-                           requires_ports=False,
-                           desc='Teardown all constrained ports.')
-}
-
-
-def _ParseArgs():
-  """Define and parse command-line arguments.
-
-  Returns:
-    tuple as (command, configuration):
-    command: one of the possible commands to setup, delete or teardown the
-             constrained network.
-    configuration: a map of constrained network properties to their values.
-  """
-  parser = optparse.OptionParser()
-
-  indent_first = parser.formatter.indent_increment
-  opt_width = parser.formatter.help_position - indent_first
-
-  cmd_usage = []
-  for s in COMMANDS:
-    cmd_usage.append('%*s%-*s%s' %
-                     (indent_first, '', opt_width, s, COMMANDS[s].desc))
-
-  parser.usage = ('usage: %%prog {%s} [options]\n\n%s' %
-                  ('|'.join(COMMANDS.keys()), '\n'.join(cmd_usage)))
-
-  parser.add_option('--port', type='int',
-                    help='The port to apply traffic control constraints to.')
-  parser.add_option('--server-port', type='int',
-                    help='Port to forward traffic on --port to.')
-  parser.add_option('--bandwidth', type='int',
-                    help='Bandwidth of the network in kbit/s.')
-  parser.add_option('--latency', type='int',
-                    help=('Latency (delay) added to each outgoing packet in '
-                          'ms.'))
-  parser.add_option('--loss', type='int',
-                    help='Packet-loss percentage on outgoing packets. ')
-  parser.add_option('--interface', type='string',
-                    help=('Interface to setup constraints on. Use "lo" for a '
-                          'local client.'))
-  parser.add_option('-v', '--verbose', action='store_true', dest='verbose',
-                    default=False, help='Turn on verbose output.')
-  options, args = parser.parse_args()
-
-  _SetLogger(options.verbose)
-
-  # Check a valid command was entered
-  if not args or args[0].lower() not in COMMANDS:
-    parser.error('Please specify a command {%s}.' % '|'.join(COMMANDS.keys()))
-  user_cmd = args[0].lower()
-
-  # Check if required options are available
-  if COMMANDS[user_cmd].requires_ports:
-    if not (options.port and options.server_port):
-      parser.error('Please provide port and server-port values.')
-
-  config = {
-      'port': options.port,
-      'server_port': options.server_port,
-      'interface': options.interface,
-      'latency': options.latency,
-      'bandwidth': options.bandwidth,
-      'loss': options.loss
-  }
-  return user_cmd, config
-
-
-def _SetLogger(verbose):
-  log_level = _DEFAULT_LOG_LEVEL
-  if verbose:
-    log_level = logging.DEBUG
-  logging.basicConfig(level=log_level, format='%(message)s')
-
-
-def Main():
-  """Get the command and configuration of the network to set up."""
-  user_cmd, config = _ParseArgs()
-
-  try:
-    COMMANDS[user_cmd].dispatch(config)
-  except traffic_control.TrafficControlError as e:
-    logging.error('Error: %s\n\nOutput: %s', e.msg, e.error)
-
-
-if __name__ == '__main__':
-  Main()
diff --git a/media/tools/constrained_network_server/cns.py b/media/tools/constrained_network_server/cns.py
deleted file mode 100755
index d039d8e..0000000
--- a/media/tools/constrained_network_server/cns.py
+++ /dev/null
@@ -1,491 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-#
-# [VPYTHON:BEGIN]
-# wheel: <
-#   name: "infra/python/wheels/pytz-py2_py3"
-#   version: "version:2018.4"
-# >
-# wheel: <
-#   name: "infra/python/wheels/tempora-py2_py3"
-#   version: "version:1.11"
-# >
-# wheel: <
-#   name: "infra/python/wheels/more-itertools-py2_py3"
-#   version: "version:4.1.0"
-# >
-# wheel: <
-#   name: "infra/python/wheels/backports_functools_lru_cache-py2_py3"
-#   version: "version:1.5"
-# >
-# wheel: <
-#   name: "infra/python/wheels/six-py2_py3"
-#   version: "version:1.12.0"
-# >
-# wheel: <
-#   name: "infra/python/wheels/portend-py2_py3"
-#   version: "version:2.2"
-# >
-# wheel: <
-#   name: "infra/python/wheels/cheroot-py2_py3"
-#   version: "version:6.2.4"
-# >
-# wheel: <
-#   name: "infra/python/wheels/cherrypy-py2_py3"
-#   version: "version:14.2.0"
-# >
-# [VPYTHON:END]
-
-"""Constrained Network Server. Serves files with supplied network constraints.
-
-The CNS exposes a web based API allowing network constraints to be imposed on
-file serving.
-
-TODO(dalecurtis): Add some more docs here.
-
-"""
-
-import logging
-from logging import handlers
-import mimetypes
-import optparse
-import os
-import signal
-import sys
-import threading
-import time
-import urllib
-import urllib2
-
-import traffic_control
-
-try:
-  import cherrypy
-except ImportError:
-  print ('CNS requires CherryPy v3 or higher to be installed. Please install\n'
-         'and try again. On Linux: sudo apt-get install python-cherrypy3\n')
-  sys.exit(1)
-
-# Add webm file types to mimetypes map since cherrypy's default type is text.
-mimetypes.types_map['.webm'] = 'video/webm'
-
-# Default logging is ERROR. Use --verbose to enable DEBUG logging.
-_DEFAULT_LOG_LEVEL = logging.ERROR
-
-# Default port to serve the CNS on.
-_DEFAULT_SERVING_PORT = 9000
-
-# Default port range for constrained use.
-_DEFAULT_CNS_PORT_RANGE = (50000, 51000)
-
-# Default number of seconds before a port can be torn down.
-_DEFAULT_PORT_EXPIRY_TIME_SECS = 5 * 60
-
-
-class PortAllocator(object):
-  """Dynamically allocates/deallocates ports with a given set of constraints."""
-
-  def __init__(self, port_range, expiry_time_secs=5 * 60):
-    """Sets up initial state for the Port Allocator.
-
-    Args:
-      port_range: Range of ports available for allocation.
-      expiry_time_secs: Amount of time in seconds before constrained ports are
-          cleaned up.
-    """
-    self._port_range = port_range
-    self._expiry_time_secs = expiry_time_secs
-
-    # Keeps track of ports we've used, the creation key, and the last request
-    # time for the port so they can be cached and cleaned up later.
-    self._ports = {}
-
-    # Locks port creation and cleanup. TODO(dalecurtis): If performance becomes
-    # an issue a per-port based lock system can be used instead.
-    self._port_lock = threading.RLock()
-
-  def Get(self, key, new_port=False, **kwargs):
-    """Sets up a constrained port using the requested parameters.
-
-    Requests for the same key and constraints will result in a cached port being
-    returned if possible, subject to new_port.
-
-    Args:
-      key: Used to cache ports with the given constraints.
-      new_port: Whether to create a new port or use an existing one if possible.
-      **kwargs: Constraints to pass into traffic control.
-
-    Returns:
-      None if no port can be setup or the port number of the constrained port.
-    """
-    with self._port_lock:
-      # Check port key cache to see if this port is already setup. Update the
-      # cache time and return the port if so. Performance isn't a concern here,
-      # so just iterate over ports dict for simplicity.
-      full_key = (key,) + tuple(kwargs.values())
-      if not new_port:
-        for port, status in self._ports.iteritems():
-          if full_key == status['key']:
-            self._ports[port]['last_update'] = time.time()
-            return port
-
-      # Cleanup ports on new port requests. Do it after the cache check though
-      # so we don't erase and then setup the same port.
-      if self._expiry_time_secs > 0:
-        self.Cleanup(all_ports=False)
-
-      # Performance isn't really an issue here, so just iterate over the port
-      # range to find an unused port. If no port is found, None is returned.
-      for port in xrange(self._port_range[0], self._port_range[1]):
-        if port in self._ports:
-          continue
-        if self._SetupPort(port, **kwargs):
-          kwargs['port'] = port
-          self._ports[port] = {'last_update': time.time(), 'key': full_key,
-                               'config': kwargs}
-          return port
-
-  def _SetupPort(self, port, **kwargs):
-    """Setup network constraints on port using the requested parameters.
-
-    Args:
-      port: The port number to setup network constraints on.
-      **kwargs: Network constraints to set up on the port.
-
-    Returns:
-      True if setting the network constraints on the port was successful, false
-      otherwise.
-    """
-    kwargs['port'] = port
-    try:
-      cherrypy.log('Setting up port %d' % port)
-      traffic_control.CreateConstrainedPort(kwargs)
-      return True
-    except traffic_control.TrafficControlError as e:
-      cherrypy.log('Error: %s\nOutput: %s' % (e.msg, e.error))
-      return False
-
-  def Cleanup(self, all_ports, request_ip=None):
-    """Cleans up expired ports, or if all_ports=True, all allocated ports.
-
-    By default, ports which haven't been used for self._expiry_time_secs are
-    torn down. If all_ports=True then they are torn down regardless.
-
-    Args:
-      all_ports: Should all ports be torn down regardless of expiration?
-      request_ip: Tear ports matching the IP address regarless of expiration.
-    """
-    with self._port_lock:
-      now = time.time()
-      # Use .items() instead of .iteritems() so we can delete keys w/o error.
-      for port, status in self._ports.items():
-        expired = now - status['last_update'] > self._expiry_time_secs
-        matching_ip = request_ip and status['key'][0].startswith(request_ip)
-        if all_ports or expired or matching_ip:
-          cherrypy.log('Cleaning up port %d' % port)
-          self._DeletePort(port)
-          del self._ports[port]
-
-  def _DeletePort(self, port):
-    """Deletes network constraints on port.
-
-    Args:
-      port: The port number associated with the network constraints.
-    """
-    try:
-      traffic_control.DeleteConstrainedPort(self._ports[port]['config'])
-    except traffic_control.TrafficControlError as e:
-      cherrypy.log('Error: %s\nOutput: %s' % (e.msg, e.error))
-
-
-class ConstrainedNetworkServer(object):
-  """A CherryPy-based HTTP server for serving files with network constraints."""
-
-  def __init__(self, options, port_allocator):
-    """Sets up initial state for the CNS.
-
-    Args:
-      options: optparse based class returned by ParseArgs()
-      port_allocator: A port allocator instance.
-    """
-    self._options = options
-    self._port_allocator = port_allocator
-
-  @cherrypy.expose
-  def Cleanup(self):
-    """Cleans up all the ports allocated using the request IP address.
-
-    When requesting a constrained port, the cherrypy.request.remote.ip is used
-    as a key for that port (in addition to other request parameters).  Such
-    ports created for the same IP address are removed.
-    """
-    cherrypy.log('Cleaning up ports allocated by %s.' %
-                 cherrypy.request.remote.ip)
-    self._port_allocator.Cleanup(all_ports=False,
-                                 request_ip=cherrypy.request.remote.ip)
-
-  @cherrypy.expose
-  def ServeConstrained(self, f=None, bandwidth=None, latency=None, loss=None,
-                       new_port=False, no_cache=False, **kwargs):
-    """Serves the requested file with the requested constraints.
-
-    Subsequent requests for the same constraints from the same IP will share the
-    previously created port unless new_port equals True. If no constraints
-    are provided the file is served as is.
-
-    Args:
-      f: path relative to http root of file to serve.
-      bandwidth: maximum allowed bandwidth for the provided port (integer
-          in kbit/s).
-      latency: time to add to each packet (integer in ms).
-      loss: percentage of packets to drop (integer, 0-100).
-      new_port: whether to use a new port for this request or not.
-      no_cache: Set reponse's cache-control to no-cache.
-    """
-    if no_cache:
-      response = cherrypy.response
-      response.headers['Pragma'] = 'no-cache'
-      response.headers['Cache-Control'] = 'no-cache'
-
-    # CherryPy is a bit wonky at detecting parameters, so just make them all
-    # optional and validate them ourselves.
-    if not f:
-      raise cherrypy.HTTPError(400, 'Invalid request. File must be specified.')
-
-    # Check existence early to prevent wasted constraint setup.
-    self._CheckRequestedFileExist(f)
-
-    # If there are no constraints, just serve the file.
-    if bandwidth is None and latency is None and loss is None:
-      return self._ServeFile(f)
-
-    constrained_port = self._GetConstrainedPort(
-        f, bandwidth=bandwidth, latency=latency, loss=loss, new_port=new_port,
-        **kwargs)
-
-    # Build constrained URL using the constrained port and original URL
-    # parameters except the network constraints (bandwidth, latency, and loss).
-    constrained_url = self._GetServerURL(f, constrained_port,
-                                         no_cache=no_cache, **kwargs)
-
-    # Redirect request to the constrained port.
-    cherrypy.log('Redirect to %s' % constrained_url)
-    cherrypy.lib.cptools.redirect(constrained_url, internal=False)
-
-  def _CheckRequestedFileExist(self, f):
-    """Checks if the requested file exists, raises HTTPError otherwise."""
-    if self._options.local_server_port:
-      self._CheckFileExistOnLocalServer(f)
-    else:
-      self._CheckFileExistOnServer(f)
-
-  def _CheckFileExistOnServer(self, f):
-    """Checks if requested file f exists to be served by this server."""
-    # Sanitize and check the path to prevent www-root escapes.
-    sanitized_path = os.path.abspath(os.path.join(self._options.www_root, f))
-    if not sanitized_path.startswith(self._options.www_root):
-      raise cherrypy.HTTPError(403, 'Invalid file requested.')
-    if not os.path.exists(sanitized_path):
-      raise cherrypy.HTTPError(404, 'File not found.')
-
-  def _CheckFileExistOnLocalServer(self, f):
-    """Checks if requested file exists on local server hosting files."""
-    test_url = self._GetServerURL(f, self._options.local_server_port)
-    try:
-      cherrypy.log('Check file exist using URL: %s' % test_url)
-      return urllib2.urlopen(test_url) is not None
-    except Exception:
-      raise cherrypy.HTTPError(404, 'File not found on local server.')
-
-  def _ServeFile(self, f):
-    """Serves the file as an http response."""
-    if self._options.local_server_port:
-      redirect_url = self._GetServerURL(f, self._options.local_server_port)
-      cherrypy.log('Redirect to %s' % redirect_url)
-      cherrypy.lib.cptools.redirect(redirect_url, internal=False)
-    else:
-      sanitized_path = os.path.abspath(os.path.join(self._options.www_root, f))
-      return cherrypy.lib.static.serve_file(sanitized_path)
-
-  def _GetServerURL(self, f, port, **kwargs):
-    """Returns a URL for local server to serve the file on given port.
-
-    Args:
-      f: file name to serve on local server. Relative to www_root.
-      port: Local server port (it can be a configured constrained port).
-      kwargs: extra parameteres passed in the URL.
-    """
-    url = '%s?f=%s&' % (cherrypy.url(), f)
-    if self._options.local_server_port:
-      url = '%s/%s?' % (
-          cherrypy.url().replace('ServeConstrained', self._options.www_root), f)
-
-    url = url.replace(':%d' % self._options.port, ':%d' % port)
-    extra_args = urllib.urlencode(kwargs)
-    if extra_args:
-      url += extra_args
-    return url
-
-  def _GetConstrainedPort(self, f=None, bandwidth=None, latency=None, loss=None,
-                          new_port=False, **kwargs):
-    """Creates or gets a port with specified network constraints.
-
-    See ServeConstrained() for more details.
-    """
-    # Validate inputs. isdigit() guarantees a natural number.
-    bandwidth = self._ParseIntParameter(
-        bandwidth, 'Invalid bandwidth constraint.', lambda x: x > 0)
-    latency = self._ParseIntParameter(
-        latency, 'Invalid latency constraint.', lambda x: x >= 0)
-    loss = self._ParseIntParameter(
-        loss, 'Invalid loss constraint.', lambda x: x <= 100 and x >= 0)
-
-    redirect_port = self._options.port
-    if self._options.local_server_port:
-      redirect_port = self._options.local_server_port
-
-    start_time = time.time()
-    # Allocate a port using the given constraints. If a port with the requested
-    # key and kwargs already exist then reuse that port.
-    constrained_port = self._port_allocator.Get(
-        cherrypy.request.remote.ip, server_port=redirect_port,
-        interface=self._options.interface, bandwidth=bandwidth, latency=latency,
-        loss=loss, new_port=new_port, file=f, **kwargs)
-
-    cherrypy.log('Time to set up port %d = %.3fsec.' %
-                 (constrained_port, time.time() - start_time))
-
-    if not constrained_port:
-      raise cherrypy.HTTPError(503, 'Service unavailable. Out of ports.')
-    return constrained_port
-
-  def _ParseIntParameter(self, param, msg, check):
-    """Returns integer value of param and verifies it satisfies the check.
-
-    Args:
-      param: Parameter name to check.
-      msg: Message in error if raised.
-      check: Check to verify the parameter value.
-
-    Returns:
-      None if param is None, integer value of param otherwise.
-
-    Raises:
-      cherrypy.HTTPError if param can not be converted to integer or if it does
-      not satisfy the check.
-    """
-    if param:
-      try:
-        int_value = int(param)
-        if check(int_value):
-          return int_value
-      except:
-        pass
-      raise cherrypy.HTTPError(400, msg)
-
-
-def ParseArgs():
-  """Define and parse the command-line arguments."""
-  parser = optparse.OptionParser()
-
-  parser.add_option('--expiry-time', type='int',
-                    default=_DEFAULT_PORT_EXPIRY_TIME_SECS,
-                    help=('Number of seconds before constrained ports expire '
-                          'and are cleaned up. 0=Disabled. Default: %default'))
-  parser.add_option('--port', type='int', default=_DEFAULT_SERVING_PORT,
-                    help='Port to serve the API on. Default: %default')
-  parser.add_option('--port-range', default=_DEFAULT_CNS_PORT_RANGE,
-                    help=('Range of ports for constrained serving. Specify as '
-                          'a comma separated value pair. Default: %default'))
-  parser.add_option('--interface', default='eth0',
-                    help=('Interface to setup constraints on. Use lo for a '
-                          'local client. Default: %default'))
-  parser.add_option('--socket-timeout', type='int',
-                    default=cherrypy.server.socket_timeout,
-                    help=('Number of seconds before a socket connection times '
-                          'out. Default: %default'))
-  parser.add_option('--threads', type='int',
-                    default=cherrypy._cpserver.Server.thread_pool,
-                    help=('Number of threads in the thread pool. Default: '
-                          '%default'))
-  parser.add_option('--www-root', default='',
-                    help=('Directory root to serve files from. If --local-'
-                          'server-port is used, the path is appended to the '
-                          'redirected URL of local server. Defaults to the '
-                          'current directory (if --local-server-port is not '
-                          'used): %s' % os.getcwd()))
-  parser.add_option('--local-server-port', type='int',
-                    help=('Optional local server port to host files.'))
-  parser.add_option('-v', '--verbose', action='store_true', default=False,
-                    help='Turn on verbose output.')
-
-  options = parser.parse_args()[0]
-
-  # Convert port range into the desired tuple format.
-  try:
-    if isinstance(options.port_range, str):
-      options.port_range = [int(port) for port in options.port_range.split(',')]
-  except ValueError:
-    parser.error('Invalid port range specified.')
-
-  if options.expiry_time < 0:
-    parser.error('Invalid expiry time specified.')
-
-  # Convert the path to an absolute to remove any . or ..
-  if not options.local_server_port:
-    if not options.www_root:
-      options.www_root = os.getcwd()
-    options.www_root = os.path.abspath(options.www_root)
-
-  _SetLogger(options.verbose)
-
-  return options
-
-
-def _SetLogger(verbose):
-  file_handler = handlers.RotatingFileHandler('cns.log', 'a', 10000000, 10)
-  file_handler.setFormatter(logging.Formatter('[%(threadName)s] %(message)s'))
-
-  log_level = _DEFAULT_LOG_LEVEL
-  if verbose:
-    log_level = logging.DEBUG
-  file_handler.setLevel(log_level)
-
-  cherrypy.log.error_log.addHandler(file_handler)
-  cherrypy.log.access_log.addHandler(file_handler)
-
-
-def Main():
-  """Configure and start the ConstrainedNetworkServer."""
-  options = ParseArgs()
-
-  try:
-    traffic_control.CheckRequirements()
-  except traffic_control.TrafficControlError as e:
-    cherrypy.log(e.msg)
-    return
-
-  cherrypy.config.update({'server.socket_host': '::',
-                          'server.socket_port': options.port})
-
-  if options.threads:
-    cherrypy.config.update({'server.thread_pool': options.threads})
-
-  if options.socket_timeout:
-    cherrypy.config.update({'server.socket_timeout': options.socket_timeout})
-
-  # Setup port allocator here so we can call cleanup on failures/exit.
-  pa = PortAllocator(options.port_range, expiry_time_secs=options.expiry_time)
-
-  try:
-    cherrypy.quickstart(ConstrainedNetworkServer(options, pa))
-  finally:
-    # Disable Ctrl-C handler to prevent interruption of cleanup.
-    signal.signal(signal.SIGINT, lambda signal, frame: None)
-    pa.Cleanup(all_ports=True)
-
-
-if __name__ == '__main__':
-  Main()
diff --git a/media/tools/constrained_network_server/cns_test.py b/media/tools/constrained_network_server/cns_test.py
deleted file mode 100755
index a3ac54e..0000000
--- a/media/tools/constrained_network_server/cns_test.py
+++ /dev/null
@@ -1,300 +0,0 @@
-#!/usr/bin/env vpython
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# [VPYTHON:BEGIN]
-# wheel: <
-#   name: "infra/python/wheels/pytz-py2_py3"
-#   version: "version:2018.4"
-# >
-# wheel: <
-#   name: "infra/python/wheels/tempora-py2_py3"
-#   version: "version:1.11"
-# >
-# wheel: <
-#   name: "infra/python/wheels/more-itertools-py2_py3"
-#   version: "version:4.1.0"
-# >
-# wheel: <
-#   name: "infra/python/wheels/backports_functools_lru_cache-py2_py3"
-#   version: "version:1.5"
-# >
-# wheel: <
-#   name: "infra/python/wheels/six-py2_py3"
-#   version: "version:1.12.0"
-# >
-# wheel: <
-#   name: "infra/python/wheels/portend-py2_py3"
-#   version: "version:2.2"
-# >
-# wheel: <
-#   name: "infra/python/wheels/cheroot-py2_py3"
-#   version: "version:6.2.4"
-# >
-# wheel: <
-#   name: "infra/python/wheels/cherrypy-py2_py3"
-#   version: "version:14.2.0"
-# >
-# [VPYTHON:END]
-
-"""Tests for Constrained Network Server."""
-import os
-import signal
-import subprocess
-import tempfile
-import time
-import unittest
-import urllib2
-import cherrypy
-import cns
-import traffic_control
-
-# The local interface to test on.
-_INTERFACE = 'lo'
-
-
-class PortAllocatorTest(unittest.TestCase):
-  """Unit tests for the Port Allocator class."""
-
-  # Expiration time for ports. In mock time.
-  _EXPIRY_TIME = 6
-
-  def setUp(self):
-    # Mock out time.time() to accelerate port expiration testing.
-    self._old_time = time.time
-    self._current_time = 0
-    time.time = lambda: self._current_time
-
-    # TODO(dalecurtis): Mock out actual calls to shadi's port setup.
-    self._pa = cns.PortAllocator(cns._DEFAULT_CNS_PORT_RANGE, self._EXPIRY_TIME)
-    self._MockTrafficControl()
-
-  def tearDown(self):
-    self._pa.Cleanup(all_ports=True)
-    # Ensure ports are cleaned properly.
-    self.assertEquals(self._pa._ports, {})
-    time.time = self._old_time
-    self._RestoreTrafficControl()
-
-  def _MockTrafficControl(self):
-    self.old_CreateConstrainedPort = traffic_control.CreateConstrainedPort
-    self.old_DeleteConstrainedPort = traffic_control.DeleteConstrainedPort
-    self.old_TearDown = traffic_control.TearDown
-
-    traffic_control.CreateConstrainedPort = lambda config: True
-    traffic_control.DeleteConstrainedPort = lambda config: True
-    traffic_control.TearDown = lambda config: True
-
-  def _RestoreTrafficControl(self):
-    traffic_control.CreateConstrainedPort = self.old_CreateConstrainedPort
-    traffic_control.DeleteConstrainedPort = self.old_DeleteConstrainedPort
-    traffic_control.TearDown = self.old_TearDown
-
-  def testPortAllocator(self):
-    # Ensure Get() succeeds and returns the correct port.
-    self.assertEquals(self._pa.Get('test'), cns._DEFAULT_CNS_PORT_RANGE[0])
-
-    # Call again with the same key and make sure we get the same port.
-    self.assertEquals(self._pa.Get('test'), cns._DEFAULT_CNS_PORT_RANGE[0])
-
-    # Call with a different key and make sure we get a different port.
-    self.assertEquals(self._pa.Get('test2'), cns._DEFAULT_CNS_PORT_RANGE[0] + 1)
-
-    # Update fake time so that ports should expire.
-    self._current_time += self._EXPIRY_TIME + 1
-
-    # Test to make sure cache is checked before expiring ports.
-    self.assertEquals(self._pa.Get('test2'), cns._DEFAULT_CNS_PORT_RANGE[0] + 1)
-
-    # Update fake time so that ports should expire.
-    self._current_time += self._EXPIRY_TIME + 1
-
-    # Request a new port, old ports should be expired, so we should get the
-    # first port in the range. Make sure this is the only allocated port.
-    self.assertEquals(self._pa.Get('test3'), cns._DEFAULT_CNS_PORT_RANGE[0])
-    self.assertEquals(self._pa._ports.keys(), [cns._DEFAULT_CNS_PORT_RANGE[0]])
-
-  def testPortAllocatorExpiresOnlyCorrectPorts(self):
-    # Ensure Get() succeeds and returns the correct port.
-    self.assertEquals(self._pa.Get('test'), cns._DEFAULT_CNS_PORT_RANGE[0])
-
-    # Stagger port allocation and so we can ensure only ports older than the
-    # expiry time are actually expired.
-    self._current_time += self._EXPIRY_TIME / 2 + 1
-
-    # Call with a different key and make sure we get a different port.
-    self.assertEquals(self._pa.Get('test2'), cns._DEFAULT_CNS_PORT_RANGE[0] + 1)
-
-    # After this sleep the port with key 'test' should expire on the next Get().
-    self._current_time += self._EXPIRY_TIME / 2 + 1
-
-    # Call with a different key and make sure we get the first port.
-    self.assertEquals(self._pa.Get('test3'), cns._DEFAULT_CNS_PORT_RANGE[0])
-    self.assertEquals(set(self._pa._ports.keys()), set([
-        cns._DEFAULT_CNS_PORT_RANGE[0], cns._DEFAULT_CNS_PORT_RANGE[0] + 1]))
-
-  def testPortAllocatorNoExpiration(self):
-    # Setup PortAllocator w/o port expiration.
-    self._pa = cns.PortAllocator(cns._DEFAULT_CNS_PORT_RANGE, 0)
-
-    # Ensure Get() succeeds and returns the correct port.
-    self.assertEquals(self._pa.Get('test'), cns._DEFAULT_CNS_PORT_RANGE[0])
-
-    # Update fake time to see if ports expire.
-    self._current_time += self._EXPIRY_TIME
-
-    # Send second Get() which would normally cause ports to expire. Ensure that
-    # the ports did not expire.
-    self.assertEquals(self._pa.Get('test2'), cns._DEFAULT_CNS_PORT_RANGE[0] + 1)
-    self.assertEquals(set(self._pa._ports.keys()), set([
-        cns._DEFAULT_CNS_PORT_RANGE[0], cns._DEFAULT_CNS_PORT_RANGE[0] + 1]))
-
-  def testPortAllocatorCleanMatchingIP(self):
-    # Setup PortAllocator w/o port expiration.
-    self._pa = cns.PortAllocator(cns._DEFAULT_CNS_PORT_RANGE, 0)
-
-    # Ensure Get() succeeds and returns the correct port.
-    self.assertEquals(self._pa.Get('ip1', t=1), cns._DEFAULT_CNS_PORT_RANGE[0])
-    self.assertEquals(self._pa.Get('ip1', t=2),
-                      cns._DEFAULT_CNS_PORT_RANGE[0] + 1)
-    self.assertEquals(self._pa.Get('ip1', t=3),
-                      cns._DEFAULT_CNS_PORT_RANGE[0] + 2)
-    self.assertEquals(self._pa.Get('ip2', t=1),
-                      cns._DEFAULT_CNS_PORT_RANGE[0] + 3)
-
-    self._pa.Cleanup(all_ports=False, request_ip='ip1')
-
-    self.assertEquals(self._pa._ports.keys(),
-                      [cns._DEFAULT_CNS_PORT_RANGE[0] + 3])
-    self.assertEquals(self._pa.Get('ip2'), cns._DEFAULT_CNS_PORT_RANGE[0])
-    self.assertEquals(self._pa.Get('ip1'), cns._DEFAULT_CNS_PORT_RANGE[0] + 1)
-
-    self._pa.Cleanup(all_ports=False, request_ip='ip2')
-    self.assertEquals(self._pa._ports.keys(),
-                      [cns._DEFAULT_CNS_PORT_RANGE[0] + 1])
-
-    self._pa.Cleanup(all_ports=False, request_ip='abc')
-    self.assertEquals(self._pa._ports.keys(),
-                      [cns._DEFAULT_CNS_PORT_RANGE[0] + 1])
-
-    self._pa.Cleanup(all_ports=False, request_ip='ip1')
-    self.assertEquals(self._pa._ports.keys(), [])
-
-
-class ConstrainedNetworkServerTest(unittest.TestCase):
-  """End to end tests for ConstrainedNetworkServer system.
-
-  These tests require root access and run the cherrypy server along with
-  tc/iptables commands.
-  """
-
-  # Amount of time to wait for the CNS to start up.
-  _SERVER_START_SLEEP_SECS = 1
-
-  # Sample data used to verify file serving.
-  _TEST_DATA = 'The quick brown fox jumps over the lazy dog'
-
-  # Server information.
-  _SERVER_URL = ('http://127.0.0.1:%d/ServeConstrained?' %
-                 cns._DEFAULT_SERVING_PORT)
-
-  # Setting for latency testing.
-  _LATENCY_TEST_SECS = 1
-
-  def _StartServer(self):
-    """Starts the CNS, returns pid."""
-    cmd = ['python', 'cns.py', '--interface=%s' % _INTERFACE]
-    process = subprocess.Popen(cmd, stderr=subprocess.PIPE)
-
-    # Wait for server to startup.
-    line = True
-    while line:
-      line = process.stderr.readline()
-      if 'STARTED' in line:
-        return process.pid
-
-    self.fail('Failed to start CNS.')
-
-  def setUp(self):
-    # Start the CNS.
-    self._server_pid = self._StartServer()
-
-    # Create temp file for serving. Run after server start so if a failure
-    # during setUp() occurs we don't leave junk files around.
-    f, self._file = tempfile.mkstemp(dir=os.getcwd())
-    os.write(f, self._TEST_DATA)
-    os.close(f)
-
-    # Strip cwd off so we have a proper relative path.
-    self._relative_fn = self._file[len(os.getcwd()) + 1:]
-
-  def tearDown(self):
-    os.unlink(self._file)
-    os.kill(self._server_pid, signal.SIGTERM)
-
-  def testServerServesFiles(self):
-    now = time.time()
-
-    f = urllib2.urlopen('%sf=%s' % (self._SERVER_URL, self._relative_fn))
-
-    # Verify file data is served correctly.
-    self.assertEqual(self._TEST_DATA, f.read())
-
-    # For completeness ensure an unconstrained call takes less time than our
-    # artificial constraints checked in the tests below.
-    self.assertTrue(time.time() - now < self._LATENCY_TEST_SECS)
-
-  def testServerLatencyConstraint(self):
-    """Tests serving a file with a latency network constraint."""
-    # Abort if does not have root access.
-    self.assertEqual(os.geteuid(), 0, 'You need root access to run this test.')
-    now = time.time()
-
-    base_url = '%sf=%s' % (self._SERVER_URL, self._relative_fn)
-    url = '%s&latency=%d' % (base_url, self._LATENCY_TEST_SECS * 1000)
-    f = urllib2.urlopen(url)
-
-    # Verify file data is served correctly.
-    self.assertEqual(self._TEST_DATA, f.read())
-
-    # Verify the request took longer than the requested latency.
-    self.assertTrue(time.time() - now > self._LATENCY_TEST_SECS)
-
-    # Verify the server properly redirected the URL.
-    self.assertTrue(f.geturl().startswith(base_url.replace(
-        str(cns._DEFAULT_SERVING_PORT), str(cns._DEFAULT_CNS_PORT_RANGE[0]))))
-
-
-class ConstrainedNetworkServerUnitTests(unittest.TestCase):
-  """ConstrainedNetworkServer class unit tests."""
-
-  def testGetServerURL(self):
-    """Test server URL is correct when using Cherrypy port."""
-    cns_obj = cns.ConstrainedNetworkServer(self.DummyOptions(), None)
-
-    self.assertEqual(cns_obj._GetServerURL('ab/xz.webm', port=1234, t=1),
-                     'http://127.0.0.1:1234/ServeConstrained?f=ab/xz.webm&t=1')
-
-  def testGetServerURLWithLocalServer(self):
-    """Test server URL is correct when using --local-server-port port."""
-    cns_obj = cns.ConstrainedNetworkServer(self.DummyOptionsWithServer(), None)
-
-    self.assertEqual(cns_obj._GetServerURL('ab/xz.webm', port=1234, t=1),
-                     'http://127.0.0.1:1234/media/ab/xz.webm?t=1')
-
-  class DummyOptions(object):
-    www_root = 'media'
-    port = 9000
-    cherrypy.url = lambda: 'http://127.0.0.1:9000/ServeConstrained'
-    local_server_port = None
-
-  class DummyOptionsWithServer(object):
-    www_root = 'media'
-    port = 9000
-    cherrypy.url = lambda: 'http://127.0.0.1:9000/ServeConstrained'
-    local_server_port = 8080
-
-
-if __name__ == '__main__':
-  unittest.main()
diff --git a/media/tools/constrained_network_server/traffic_control.py b/media/tools/constrained_network_server/traffic_control.py
deleted file mode 100644
index e94cc8d..0000000
--- a/media/tools/constrained_network_server/traffic_control.py
+++ /dev/null
@@ -1,354 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Traffic control library for constraining the network configuration on a port.
-
-The traffic controller sets up a constrained network configuration on a port.
-Traffic to the constrained port is forwarded to a specified server port.
-"""
-
-import logging
-import os
-import re
-import subprocess
-
-# The maximum bandwidth limit.
-_DEFAULT_MAX_BANDWIDTH_KBIT = 1000000
-
-
-class TrafficControlError(BaseException):
-  """Exception raised for errors in traffic control library.
-
-  Attributes:
-    msg: User defined error message.
-    cmd: Command for which the exception was raised.
-    returncode: Return code of running the command.
-    stdout: Output of running the command.
-    stderr: Error output of running the command.
-  """
-
-  def __init__(self, msg, cmd=None, returncode=None, output=None,
-               error=None):
-    BaseException.__init__(self, msg)
-    self.msg = msg
-    self.cmd = cmd
-    self.returncode = returncode
-    self.output = output
-    self.error = error
-
-
-def CheckRequirements():
-  """Checks if permissions are available to run traffic control commands.
-
-  Raises:
-    TrafficControlError: If permissions to run traffic control commands are not
-    available.
-  """
-  if os.geteuid() != 0:
-    _Exec(['sudo', '-n', 'tc', '-help'],
-          msg=('Cannot run \'tc\' command. Traffic Control must be run as root '
-               'or have password-less sudo access to this command.'))
-    _Exec(['sudo', '-n', 'iptables', '-help'],
-          msg=('Cannot run \'iptables\' command. Traffic Control must be run '
-               'as root or have password-less sudo access to this command.'))
-
-
-def CreateConstrainedPort(config):
-  """Creates a new constrained port.
-
-  Imposes packet level constraints such as bandwidth, latency, and packet loss
-  on a given port using the specified configuration dictionary. Traffic to that
-  port is forwarded to a specified server port.
-
-  Args:
-    config: Constraint configuration dictionary, format:
-      port: Port to constrain (integer 1-65535).
-      server_port: Port to redirect traffic on [port] to (integer 1-65535).
-      interface: Network interface name (string).
-      latency: Delay added on each packet sent (integer in ms).
-      bandwidth: Maximum allowed upload bandwidth (integer in kbit/s).
-      loss: Percentage of packets to drop (integer 0-100).
-
-  Raises:
-    TrafficControlError: If any operation fails. The message in the exception
-    describes what failed.
-  """
-  _CheckArgsExist(config, 'interface', 'port', 'server_port')
-  _AddRootQdisc(config['interface'])
-
-  try:
-    _ConfigureClass('add', config)
-    _AddSubQdisc(config)
-    _AddFilter(config['interface'], config['port'])
-    _AddIptableRule(config['interface'], config['port'], config['server_port'])
-  except TrafficControlError as e:
-    logging.debug('Error creating constrained port %d.\nError: %s\n'
-                  'Deleting constrained port.', config['port'], e.error)
-    DeleteConstrainedPort(config)
-    raise e
-
-
-def DeleteConstrainedPort(config):
-  """Deletes an existing constrained port.
-
-  Deletes constraints set on a given port and the traffic forwarding rule from
-  the constrained port to a specified server port.
-
-  The original constrained network configuration used to create the constrained
-  port must be passed in.
-
-  Args:
-    config: Constraint configuration dictionary, format:
-      port: Port to constrain (integer 1-65535).
-      server_port: Port to redirect traffic on [port] to (integer 1-65535).
-      interface: Network interface name (string).
-      bandwidth: Maximum allowed upload bandwidth (integer in kbit/s).
-
-  Raises:
-    TrafficControlError: If any operation fails. The message in the exception
-    describes what failed.
-  """
-  _CheckArgsExist(config, 'interface', 'port', 'server_port')
-  try:
-    # Delete filters first so it frees the class.
-    _DeleteFilter(config['interface'], config['port'])
-  finally:
-    try:
-      # Deleting the class deletes attached qdisc as well.
-      _ConfigureClass('del', config)
-    finally:
-      _DeleteIptableRule(config['interface'], config['port'],
-                         config['server_port'])
-
-
-def TearDown(config):
-  """Deletes the root qdisc and all iptables rules.
-
-  Args:
-    config: Constraint configuration dictionary, format:
-      interface: Network interface name (string).
-
-  Raises:
-    TrafficControlError: If any operation fails. The message in the exception
-    describes what failed.
-  """
-  _CheckArgsExist(config, 'interface')
-
-  command = ['sudo', 'tc', 'qdisc', 'del', 'dev', config['interface'], 'root']
-  try:
-    _Exec(command, msg='Could not delete root qdisc.')
-  finally:
-    _DeleteAllIpTableRules()
-
-
-def _CheckArgsExist(config, *args):
-  """Check that the args exist in config dictionary and are not None.
-
-  Args:
-    config: Any dictionary.
-    *args: The list of key names to check.
-
-  Raises:
-    TrafficControlError: If any key name does not exist in config or is None.
-  """
-  for key in args:
-    if key not in config.keys() or config[key] is None:
-      raise TrafficControlError('Missing "%s" parameter.' % key)
-
-
-def _AddRootQdisc(interface):
-  """Sets up the default root qdisc.
-
-  Args:
-    interface: Network interface name.
-
-  Raises:
-    TrafficControlError: If adding the root qdisc fails for a reason other than
-    it already exists.
-  """
-  command = ['sudo', 'tc', 'qdisc', 'add', 'dev', interface, 'root', 'handle',
-             '1:', 'htb']
-  try:
-    _Exec(command, msg=('Error creating root qdisc. '
-                        'Make sure you have root access'))
-  except TrafficControlError as e:
-    # Ignore the error if root already exists.
-    if not 'File exists' in e.error:
-      raise e
-
-
-def _ConfigureClass(option, config):
-  """Adds or deletes a class and qdisc attached to the root.
-
-  The class specifies bandwidth, and qdisc specifies delay and packet loss. The
-  class ID is based on the config port.
-
-  Args:
-    option: Adds or deletes a class option [add|del].
-    config: Constraint configuration dictionary, format:
-      port: Port to constrain (integer 1-65535).
-      interface: Network interface name (string).
-      bandwidth: Maximum allowed upload bandwidth (integer in kbit/s).
-  """
-  # Use constrained port as class ID so we can attach the qdisc and filter to
-  # it, as well as delete the class, using only the port number.
-  class_id = '1:%x' % config['port']
-  if 'bandwidth' not in config.keys() or not config['bandwidth']:
-    bandwidth = _DEFAULT_MAX_BANDWIDTH_KBIT
-  else:
-    bandwidth = config['bandwidth']
-
-  bandwidth = '%dkbit' % bandwidth
-  command = ['sudo', 'tc', 'class', option, 'dev', config['interface'],
-             'parent', '1:', 'classid', class_id, 'htb', 'rate', bandwidth,
-             'ceil', bandwidth]
-  _Exec(command, msg=('Error configuring class ID %s using "%s" command.' %
-                      (class_id, option)))
-
-
-def _AddSubQdisc(config):
-  """Adds a qdisc attached to the class identified by the config port.
-
-  Args:
-    config: Constraint configuration dictionary, format:
-      port: Port to constrain (integer 1-65535).
-      interface: Network interface name (string).
-      latency: Delay added on each packet sent (integer in ms).
-      loss: Percentage of packets to drop (integer 0-100).
-  """
-  port_hex = '%x' % config['port']
-  class_id = '1:%x' % config['port']
-  command = ['sudo', 'tc', 'qdisc', 'add', 'dev', config['interface'], 'parent',
-             class_id, 'handle', port_hex + ':0', 'netem']
-
-  # Check if packet-loss is set in the configuration.
-  if 'loss' in config.keys() and config['loss']:
-    loss = '%d%%' % config['loss']
-    command.extend(['loss', loss])
-  # Check if latency is set in the configuration.
-  if 'latency' in config.keys() and config['latency']:
-    latency = '%dms' % config['latency']
-    command.extend(['delay', latency])
-
-  _Exec(command, msg='Could not attach qdisc to class ID %s.' % class_id)
-
-
-def _AddFilter(interface, port):
-  """Redirects packets coming to a specified port into the constrained class.
-
-  Args:
-    interface: Interface name to attach the filter to (string).
-    port: Port number to filter packets with (integer 1-65535).
-  """
-  class_id = '1:%x' % port
-
-  command = ['sudo', 'tc', 'filter', 'add', 'dev', interface, 'protocol', 'ip',
-             'parent', '1:', 'prio', '1', 'u32', 'match', 'ip', 'sport', port,
-             '0xffff', 'flowid', class_id]
-  _Exec(command, msg='Error adding filter on port %d.' % port)
-
-
-def _DeleteFilter(interface, port):
-  """Deletes the filter attached to the configured port.
-
-  Args:
-    interface: Interface name the filter is attached to (string).
-    port: Port number being filtered (integer 1-65535).
-  """
-  handle_id = _GetFilterHandleId(interface, port)
-  command = ['sudo', 'tc', 'filter', 'del', 'dev', interface, 'protocol', 'ip',
-             'parent', '1:0', 'handle', handle_id, 'prio', '1', 'u32']
-  _Exec(command, msg='Error deleting filter on port %d.' % port)
-
-
-def _GetFilterHandleId(interface, port):
-  """Searches for the handle ID of the filter identified by the config port.
-
-  Args:
-    interface: Interface name the filter is attached to (string).
-    port: Port number being filtered (integer 1-65535).
-
-  Returns:
-    The handle ID.
-
-  Raises:
-    TrafficControlError: If handle ID was not found.
-  """
-  command = ['sudo', 'tc', 'filter', 'list', 'dev', interface, 'parent', '1:']
-  output = _Exec(command, msg='Error listing filters.')
-  # Search for the filter handle ID associated with class ID '1:port'.
-  handle_id_re = re.search(
-      '([0-9a-fA-F]{3}::[0-9a-fA-F]{3}).*(?=flowid 1:%x\s)' % port, output)
-  if handle_id_re:
-    return handle_id_re.group(1)
-  raise TrafficControlError(('Could not find filter handle ID for class ID '
-                             '1:%x.') % port)
-
-
-def _AddIptableRule(interface, port, server_port):
-  """Forwards traffic from constrained port to a specified server port.
-
-  Args:
-    interface: Interface name to attach the filter to (string).
-    port: Port of incoming packets (integer 1-65535).
-    server_port: Server port to forward the packets to (integer 1-65535).
-  """
-  # Preroute rules for accessing the port through external connections.
-  command = ['sudo', 'iptables', '-t', 'nat', '-A', 'PREROUTING', '-i',
-             interface, '-p', 'tcp', '--dport', port, '-j', 'REDIRECT',
-             '--to-port', server_port]
-  _Exec(command, msg='Error adding iptables rule for port %d.' % port)
-
-  # Output rules for accessing the rule through localhost or 127.0.0.1
-  command = ['sudo', 'iptables', '-t', 'nat', '-A', 'OUTPUT', '-p', 'tcp',
-             '--dport', port, '-j', 'REDIRECT', '--to-port', server_port]
-  _Exec(command, msg='Error adding iptables rule for port %d.' % port)
-
-
-def _DeleteIptableRule(interface, port, server_port):
-  """Deletes the iptable rule associated with specified port number.
-
-  Args:
-    interface: Interface name to attach the filter to (string).
-    port: Port of incoming packets (integer 1-65535).
-    server_port: Server port packets are forwarded to (integer 1-65535).
-  """
-  command = ['sudo', 'iptables', '-t', 'nat', '-D', 'PREROUTING', '-i',
-             interface, '-p', 'tcp', '--dport', port, '-j', 'REDIRECT',
-             '--to-port', server_port]
-  _Exec(command, msg='Error deleting iptables rule for port %d.' % port)
-
-  command = ['sudo', 'iptables', '-t', 'nat', '-D', 'OUTPUT', '-p', 'tcp',
-             '--dport', port, '-j', 'REDIRECT', '--to-port', server_port]
-  _Exec(command, msg='Error adding iptables rule for port %d.' % port)
-
-
-def _DeleteAllIpTableRules():
-  """Deletes all iptables rules."""
-  command = ['sudo', 'iptables', '-t', 'nat', '-F']
-  _Exec(command, msg='Error deleting all iptables rules.')
-
-
-def _Exec(command, msg=None):
-  """Executes a command.
-
-  Args:
-    command: Command list to execute.
-    msg: Message describing the error in case the command fails.
-
-  Returns:
-    The standard output from running the command.
-
-  Raises:
-    TrafficControlError: If command fails. Message is set by the msg parameter.
-  """
-  cmd_list = [str(x) for x in command]
-  cmd = ' '.join(cmd_list)
-  logging.debug('Running command: %s', cmd)
-
-  p = subprocess.Popen(cmd_list, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-  output, error = p.communicate()
-  if p.returncode != 0:
-    raise TrafficControlError(msg, cmd, p.returncode, output, error)
-  return output.strip()
diff --git a/media/tools/constrained_network_server/traffic_control_test.py b/media/tools/constrained_network_server/traffic_control_test.py
deleted file mode 100755
index d641253..0000000
--- a/media/tools/constrained_network_server/traffic_control_test.py
+++ /dev/null
@@ -1,173 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""End-to-end tests for traffic control library."""
-import os
-import re
-import sys
-import unittest
-
-import traffic_control
-
-
-class TrafficControlTests(unittest.TestCase):
-  """System tests for traffic_control functions.
-
-  These tests require root access.
-  """
-  # A dummy interface name to use instead of real interface.
-  _INTERFACE = 'myeth'
-
-  def setUp(self):
-    """Setup a dummy interface."""
-    # If we update to python version 2.7 or newer we can use setUpClass() or
-    # unittest.skipIf().
-    if os.getuid() != 0:
-      sys.exit('You need root access to run these tests.')
-
-    command = ['ip', 'link', 'add', 'name', self._INTERFACE, 'type', 'dummy']
-    traffic_control._Exec(command, 'Error creating dummy interface %s.' %
-                          self._INTERFACE)
-
-  def tearDown(self):
-    """Teardown the dummy interface and any network constraints on it."""
-    # Deleting the dummy interface deletes all associated constraints.
-    command = ['ip', 'link', 'del', self._INTERFACE]
-    traffic_control._Exec(command)
-
-  def testExecOutput(self):
-    output = traffic_control._Exec(['echo', '    Test    '])
-    self.assertEqual(output, 'Test')
-
-  def testExecException(self):
-    self.assertRaises(traffic_control.TrafficControlError,
-                      traffic_control._Exec, command=['ls', '!doesntExist!'])
-
-  def testExecErrorCustomMsg(self):
-    try:
-      traffic_control._Exec(['ls', '!doesntExist!'], msg='test_msg')
-      self.fail('No exception raised for invalid command.')
-    except traffic_control.TrafficControlError as e:
-      self.assertEqual(e.msg, 'test_msg')
-
-  def testAddRootQdisc(self):
-    """Checks adding a root qdisc is successful."""
-    config = {'interface': self._INTERFACE}
-    root_detail = 'qdisc htb 1: root'
-    # Assert no htb root at startup.
-    command = ['tc', 'qdisc', 'ls', 'dev', config['interface']]
-    output = traffic_control._Exec(command)
-    self.assertFalse(root_detail in output)
-
-    traffic_control._AddRootQdisc(config['interface'])
-    output = traffic_control._Exec(command)
-    # Assert htb root is added.
-    self.assertTrue(root_detail in output)
-
-  def testConfigureClassAdd(self):
-    """Checks adding and deleting a class to the root qdisc."""
-    config = {
-        'interface': self._INTERFACE,
-        'port': 12345,
-        'server_port': 33333,
-        'bandwidth': 2000
-    }
-    class_detail = ('class htb 1:%x root prio 0 rate %dKbit ceil %dKbit' %
-                    (config['port'], config['bandwidth'], config['bandwidth']))
-
-    # Add root qdisc.
-    traffic_control._AddRootQdisc(config['interface'])
-
-    # Assert class does not exist prior to adding it.
-    command = ['tc', 'class', 'ls', 'dev', config['interface']]
-    output = traffic_control._Exec(command)
-    self.assertFalse(class_detail in output)
-
-    # Add class to root.
-    traffic_control._ConfigureClass('add', config)
-
-    # Assert class is added.
-    command = ['tc', 'class', 'ls', 'dev', config['interface']]
-    output = traffic_control._Exec(command)
-    self.assertTrue(class_detail in output)
-
-    # Delete class.
-    traffic_control._ConfigureClass('del', config)
-
-    # Assert class is deleted.
-    command = ['tc', 'class', 'ls', 'dev', config['interface']]
-    output = traffic_control._Exec(command)
-    self.assertFalse(class_detail in output)
-
-  def testAddSubQdisc(self):
-    """Checks adding a sub qdisc to existing class."""
-    config = {
-        'interface': self._INTERFACE,
-        'port': 12345,
-        'server_port': 33333,
-        'bandwidth': 2000,
-        'latency': 250,
-        'loss': 5
-    }
-    qdisc_re_detail = ('qdisc netem %x: parent 1:%x .* delay %d.0ms loss %d%%' %
-                       (config['port'], config['port'], config['latency'],
-                        config['loss']))
-    # Add root qdisc.
-    traffic_control._AddRootQdisc(config['interface'])
-
-    # Add class to root.
-    traffic_control._ConfigureClass('add', config)
-
-    # Assert qdisc does not exist prior to adding it.
-    command = ['tc', 'qdisc', 'ls', 'dev', config['interface']]
-    output = traffic_control._Exec(command)
-    handle_id_re = re.search(qdisc_re_detail, output)
-    self.assertEqual(handle_id_re, None)
-
-    # Add qdisc to class.
-    traffic_control._AddSubQdisc(config)
-
-    # Assert qdisc is added.
-    command = ['tc', 'qdisc', 'ls', 'dev', config['interface']]
-    output = traffic_control._Exec(command)
-    handle_id_re = re.search(qdisc_re_detail, output)
-    self.assertNotEqual(handle_id_re, None)
-
-  def testAddDeleteFilter(self):
-    config = {
-        'interface': self._INTERFACE,
-        'port': 12345,
-        'bandwidth': 2000
-    }
-    # Assert no filter exists.
-    command = ['tc', 'filter', 'list', 'dev', config['interface'], 'parent',
-               '1:0']
-    output = traffic_control._Exec(command)
-    self.assertEqual(output, '')
-
-    # Create the root and class to which the filter will be attached.
-    # Add root qdisc.
-    traffic_control._AddRootQdisc(config['interface'])
-
-    # Add class to root.
-    traffic_control._ConfigureClass('add', config)
-
-    # Add the filter.
-    traffic_control._AddFilter(config['interface'], config['port'])
-    handle_id = traffic_control._GetFilterHandleId(config['interface'],
-                                                   config['port'])
-    self.assertNotEqual(handle_id, None)
-
-    # Delete the filter.
-    # The output of tc filter list is not None because tc adds default filters.
-    traffic_control._DeleteFilter(config['interface'], config['port'])
-    self.assertRaises(traffic_control.TrafficControlError,
-                      traffic_control._GetFilterHandleId, config['interface'],
-                      config['port'])
-
-
-if __name__ == '__main__':
-  unittest.main()
diff --git a/media/tools/constrained_network_server/traffic_control_unittest.py b/media/tools/constrained_network_server/traffic_control_unittest.py
deleted file mode 100755
index a6781e9d..0000000
--- a/media/tools/constrained_network_server/traffic_control_unittest.py
+++ /dev/null
@@ -1,145 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Tests for traffic control library."""
-import unittest
-
-import traffic_control
-
-
-class TrafficControlUnitTests(unittest.TestCase):
-  """Unit tests for traffic control."""
-
-  # Stores commands called by the traffic control _Exec function.
-  commands = []
-
-  def _ExecMock(self, command, **kwargs):
-    """Mocks traffic_control._Exec and adds the command to commands list."""
-    cmd_list = [str(x) for x in command]
-    self.commands.append(' '.join(cmd_list))
-    return ''
-
-  def setUp(self):
-    """Resets the commands list and set the _Exec mock function."""
-    self.commands = []
-    self._old_Exec = traffic_control._Exec
-    traffic_control._Exec = self._ExecMock
-
-  def tearDown(self):
-    """Resets the _Exec mock function to the original."""
-    traffic_control._Exec = self._old_Exec
-
-  def testCreateConstrainedPort(self):
-    config = {
-        'interface': 'fakeeth',
-        'port': 12345,
-        'server_port': 8888,
-        'bandwidth': 256,
-        'latency': 100,
-        'loss': 2
-    }
-    traffic_control.CreateConstrainedPort(config)
-    expected = [
-        'sudo tc qdisc add dev fakeeth root handle 1: htb',
-        'sudo tc class add dev fakeeth parent 1: classid 1:3039 htb rate '
-        '256kbit ceil 256kbit',
-        'sudo tc qdisc add dev fakeeth parent 1:3039 handle 3039:0 netem loss '
-        '2% delay 100ms',
-        'sudo tc filter add dev fakeeth protocol ip parent 1: prio 1 u32 match '
-        'ip sport 12345 0xffff flowid 1:3039',
-        'sudo iptables -t nat -A PREROUTING -i fakeeth -p tcp --dport 12345 -j '
-        'REDIRECT --to-port 8888',
-        'sudo iptables -t nat -A OUTPUT -p tcp --dport 12345 -j REDIRECT '
-        '--to-port 8888'
-    ]
-    self.assertEqual(expected, self.commands)
-
-  def testCreateConstrainedPortDefaults(self):
-    config = {
-        'interface': 'fakeeth',
-        'port': 12345,
-        'server_port': 8888,
-        'latency': None
-    }
-    traffic_control.CreateConstrainedPort(config)
-    expected = [
-        'sudo tc qdisc add dev fakeeth root handle 1: htb',
-        'sudo tc class add dev fakeeth parent 1: classid 1:3039 htb rate '
-        '%dkbit ceil %dkbit' % (traffic_control._DEFAULT_MAX_BANDWIDTH_KBIT,
-                                traffic_control._DEFAULT_MAX_BANDWIDTH_KBIT),
-        'sudo tc qdisc add dev fakeeth parent 1:3039 handle 3039:0 netem',
-        'sudo tc filter add dev fakeeth protocol ip parent 1: prio 1 u32 '
-        'match ip sport 12345 0xffff flowid 1:3039',
-        'sudo iptables -t nat -A PREROUTING -i fakeeth -p tcp --dport 12345 -j '
-        'REDIRECT --to-port 8888',
-        'sudo iptables -t nat -A OUTPUT -p tcp --dport 12345 -j REDIRECT '
-        '--to-port 8888'
-    ]
-    self.assertEqual(expected, self.commands)
-
-  def testDeleteConstrainedPort(self):
-    config = {
-        'interface': 'fakeeth',
-        'port': 12345,
-        'server_port': 8888,
-        'bandwidth': 256,
-    }
-    _old_GetFilterHandleId = traffic_control._GetFilterHandleId
-    traffic_control._GetFilterHandleId = lambda interface, port: '800::800'
-
-    try:
-      traffic_control.DeleteConstrainedPort(config)
-      expected = [
-          'sudo tc filter del dev fakeeth protocol ip parent 1:0 handle '
-          '800::800 prio 1 u32',
-          'sudo tc class del dev fakeeth parent 1: classid 1:3039 htb rate '
-          '256kbit ceil 256kbit',
-          'sudo iptables -t nat -D PREROUTING -i fakeeth -p tcp --dport 12345 '
-          '-j REDIRECT --to-port 8888',
-          'sudo iptables -t nat -D OUTPUT -p tcp --dport 12345 -j REDIRECT '
-          '--to-port 8888']
-      self.assertEqual(expected, self.commands)
-    finally:
-      traffic_control._GetFilterHandleId = _old_GetFilterHandleId
-
-  def testTearDown(self):
-    config = {'interface': 'fakeeth'}
-
-    traffic_control.TearDown(config)
-    expected = [
-        'sudo tc qdisc del dev fakeeth root',
-        'sudo iptables -t nat -F'
-    ]
-    self.assertEqual(expected, self.commands)
-
-  def testGetFilterHandleID(self):
-    # Check seach for handle ID command.
-    self.assertRaises(traffic_control.TrafficControlError,
-                      traffic_control._GetFilterHandleId, 'fakeeth', 1)
-    self.assertEquals(self.commands, ['sudo tc filter list dev fakeeth parent '
-                                      '1:'])
-
-    # Check with handle ID available.
-    traffic_control._Exec = (lambda command, msg:
-      'filter parent 1: protocol ip pref 1 u32 fh 800::800 order 2048 key ht '
-      '800 bkt 0 flowid 1:1\nmatch 08ae0000/ffff0000 at 20')
-    output = traffic_control._GetFilterHandleId('fakeeth', 1)
-    self.assertEqual(output, '800::800')
-
-    # Check with handle ID not available.
-    traffic_control._Exec = (lambda command, msg:
-      'filter parent 1: protocol ip pref 1 u32 fh 800::800 order 2048 key ht '
-      '800 bkt 0 flowid 1:11\nmatch 08ae0000/ffff0000 at 20')
-    self.assertRaises(traffic_control.TrafficControlError,
-                      traffic_control._GetFilterHandleId, 'fakeeth', 1)
-
-    traffic_control._Exec = lambda command, msg: 'NO ID IN HERE'
-    self.assertRaises(traffic_control.TrafficControlError,
-                      traffic_control._GetFilterHandleId, 'fakeeth', 1)
-
-
-if __name__ == '__main__':
-  unittest.main()
diff --git a/net/cookies/cookie_monster.cc b/net/cookies/cookie_monster.cc
index b44e3eb..0bfad8d 100644
--- a/net/cookies/cookie_monster.cc
+++ b/net/cookies/cookie_monster.cc
@@ -1564,11 +1564,11 @@
       CookieSource cookie_source_sample =
           (source_url.SchemeIsCryptographic()
                ? (cc->IsSecure()
-                      ? COOKIE_SOURCE_SECURE_COOKIE_CRYPTOGRAPHIC_SCHEME
-                      : COOKIE_SOURCE_NONSECURE_COOKIE_CRYPTOGRAPHIC_SCHEME)
+                      ? CookieSource::kSecureCookieCryptographicScheme
+                      : CookieSource::kNonsecureCookieCryptographicScheme)
                : (cc->IsSecure()
-                      ? COOKIE_SOURCE_SECURE_COOKIE_NONCRYPTOGRAPHIC_SCHEME
-                      : COOKIE_SOURCE_NONSECURE_COOKIE_NONCRYPTOGRAPHIC_SCHEME));
+                      ? CookieSource::kSecureCookieNoncryptographicScheme
+                      : CookieSource::kNonsecureCookieNoncryptographicScheme));
       UMA_HISTOGRAM_ENUMERATION("Cookie.CookieSourceScheme",
                                 cookie_source_sample);
 
diff --git a/net/cookies/cookie_monster.h b/net/cookies/cookie_monster.h
index 7f94ea94..af03c70 100644
--- a/net/cookies/cookie_monster.h
+++ b/net/cookies/cookie_monster.h
@@ -344,17 +344,17 @@
   // entries. New items MUST be added at the end of the list, and kMaxValue
   // should be updated to the last value.
   //
-  // COOKIE_SOURCE_(NON)SECURE_COOKIE_(NON)CRYPTOGRAPHIC_SCHEME means
+  // CookieSource::k(Non)SecureCookie(Non)CryptographicScheme means
   // that a cookie was set or overwritten from a URL with the given type
   // of scheme. This enum should not be used when cookies are *cleared*,
   // because its purpose is to understand if Chrome can deprecate the
   // ability of HTTP urls to set/overwrite Secure cookies.
-  enum CookieSource : uint8_t {
-    COOKIE_SOURCE_SECURE_COOKIE_CRYPTOGRAPHIC_SCHEME = 0,
-    COOKIE_SOURCE_SECURE_COOKIE_NONCRYPTOGRAPHIC_SCHEME,
-    COOKIE_SOURCE_NONSECURE_COOKIE_CRYPTOGRAPHIC_SCHEME,
-    COOKIE_SOURCE_NONSECURE_COOKIE_NONCRYPTOGRAPHIC_SCHEME,
-    kMaxValue = COOKIE_SOURCE_NONSECURE_COOKIE_NONCRYPTOGRAPHIC_SCHEME
+  enum class CookieSource : uint8_t {
+    kSecureCookieCryptographicScheme = 0,
+    kSecureCookieNoncryptographicScheme,
+    kNonsecureCookieCryptographicScheme,
+    kNonsecureCookieNoncryptographicScheme,
+    kMaxValue = kNonsecureCookieNoncryptographicScheme
   };
 
   // Enum for collecting metrics on how frequently a cookie is sent to the same
diff --git a/net/cookies/cookie_monster_unittest.cc b/net/cookies/cookie_monster_unittest.cc
index 27290b91a..0d4cd3ce 100644
--- a/net/cookies/cookie_monster_unittest.cc
+++ b/net/cookies/cookie_monster_unittest.cc
@@ -3323,21 +3323,21 @@
   histograms.ExpectTotalCount(cookie_source_histogram, 1);
   histograms.ExpectBucketCount(
       cookie_source_histogram,
-      CookieMonster::COOKIE_SOURCE_SECURE_COOKIE_CRYPTOGRAPHIC_SCHEME, 1);
+      CookieMonster::CookieSource::kSecureCookieCryptographicScheme, 1);
 
   // Set a non-secure cookie on a cryptographic scheme.
   EXPECT_TRUE(SetCookie(cm.get(), https_www_foo_.url(), "C=D; path=/;"));
   histograms.ExpectTotalCount(cookie_source_histogram, 2);
   histograms.ExpectBucketCount(
       cookie_source_histogram,
-      CookieMonster::COOKIE_SOURCE_NONSECURE_COOKIE_CRYPTOGRAPHIC_SCHEME, 1);
+      CookieMonster::CookieSource::kNonsecureCookieCryptographicScheme, 1);
 
   // Set a secure cookie on a non-cryptographic scheme.
   EXPECT_FALSE(SetCookie(cm.get(), http_www_foo_.url(), "D=E; path=/; Secure"));
   histograms.ExpectTotalCount(cookie_source_histogram, 2);
   histograms.ExpectBucketCount(
       cookie_source_histogram,
-      CookieMonster::COOKIE_SOURCE_SECURE_COOKIE_NONCRYPTOGRAPHIC_SCHEME, 0);
+      CookieMonster::CookieSource::kSecureCookieNoncryptographicScheme, 0);
 
   // Overwrite a secure cookie (set by a cryptographic scheme) on a
   // non-cryptographic scheme.
@@ -3345,10 +3345,10 @@
   histograms.ExpectTotalCount(cookie_source_histogram, 2);
   histograms.ExpectBucketCount(
       cookie_source_histogram,
-      CookieMonster::COOKIE_SOURCE_SECURE_COOKIE_CRYPTOGRAPHIC_SCHEME, 1);
+      CookieMonster::CookieSource::kSecureCookieCryptographicScheme, 1);
   histograms.ExpectBucketCount(
       cookie_source_histogram,
-      CookieMonster::COOKIE_SOURCE_SECURE_COOKIE_NONCRYPTOGRAPHIC_SCHEME, 0);
+      CookieMonster::CookieSource::kSecureCookieNoncryptographicScheme, 0);
 
   // Test that attempting to clear a secure cookie on a http:// URL does
   // nothing.
@@ -3367,7 +3367,7 @@
   histograms.ExpectTotalCount(cookie_source_histogram, 4);
   histograms.ExpectBucketCount(
       cookie_source_histogram,
-      CookieMonster::COOKIE_SOURCE_NONSECURE_COOKIE_NONCRYPTOGRAPHIC_SCHEME, 1);
+      CookieMonster::CookieSource::kNonsecureCookieNoncryptographicScheme, 1);
 }
 
 // Test that inserting the first cookie for a key and deleting the last cookie
diff --git a/net/test/embedded_test_server/DEPS b/net/test/embedded_test_server/DEPS
index b307e7d..f2b76e93 100644
--- a/net/test/embedded_test_server/DEPS
+++ b/net/test/embedded_test_server/DEPS
@@ -1,3 +1,3 @@
 include_rules = [
-  "+absl"
-]
\ No newline at end of file
+  "+third_party/abseil-cpp/absl/strings/escaping.h"
+]
diff --git a/net/test/embedded_test_server/http2_connection.cc b/net/test/embedded_test_server/http2_connection.cc
index 12632bd..6c26af3 100644
--- a/net/test/embedded_test_server/http2_connection.cc
+++ b/net/test/embedded_test_server/http2_connection.cc
@@ -6,7 +6,6 @@
 
 #include <memory>
 
-#include "absl/strings/escaping.h"
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/debug/stack_trace.h"
@@ -20,6 +19,7 @@
 #include "net/ssl/ssl_info.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
+#include "third_party/abseil-cpp/absl/strings/escaping.h"
 
 namespace net {
 
diff --git a/net/test/embedded_test_server/http_response.h b/net/test/embedded_test_server/http_response.h
index ff4df35..1d3f762 100644
--- a/net/test/embedded_test_server/http_response.h
+++ b/net/test/embedded_test_server/http_response.h
@@ -7,7 +7,6 @@
 
 #include <string>
 
-#include "absl/types/optional.h"
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/callback_helpers.h"
@@ -18,6 +17,7 @@
 #include "base/strings/string_split.h"
 #include "base/time/time.h"
 #include "net/http/http_status_code.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net::test_server {
 
diff --git a/remoting/host/client_session.cc b/remoting/host/client_session.cc
index 355600c..0f84d0d 100644
--- a/remoting/host/client_session.cc
+++ b/remoting/host/client_session.cc
@@ -577,8 +577,6 @@
 }
 
 void ClientSession::CreatePerMonitorVideoStreams() {
-  DCHECK(desktop_display_info_.NumDisplays() > 0);
-
   // Create new streams for any monitors that don't already have streams.
   for (int i = 0; i < desktop_display_info_.NumDisplays(); i++) {
     auto id = desktop_display_info_.GetDisplayInfo(i)->id;
diff --git a/storage/browser/file_system/obfuscated_file_util.cc b/storage/browser/file_system/obfuscated_file_util.cc
index 20ac649..9ab4349 100644
--- a/storage/browser/file_system/obfuscated_file_util.cc
+++ b/storage/browser/file_system/obfuscated_file_util.cc
@@ -29,6 +29,7 @@
 #include "storage/browser/file_system/file_observers.h"
 #include "storage/browser/file_system/file_system_context.h"
 #include "storage/browser/file_system/file_system_operation_context.h"
+#include "storage/browser/file_system/file_system_util.h"
 #include "storage/browser/file_system/obfuscated_file_util_disk_delegate.h"
 #include "storage/browser/file_system/obfuscated_file_util_memory_delegate.h"
 #include "storage/browser/file_system/quota/quota_limit_type.h"
@@ -74,11 +75,6 @@
 const int64_t kPathByteQuotaCost =
     2;  // Bytes per byte of path length in UTF-8.
 
-// TODO(https://crbug.com/1344157): Refactor to compare by Quota types rather
-// than string representations of FileSystem types. The string representation of
-// a kTemporary type.
-const char kTemporary[] = "t";
-
 int64_t UsageForPath(size_t length) {
   return kPathCreationQuotaCost +
          static_cast<int64_t>(length) * kPathByteQuotaCost;
@@ -315,7 +311,6 @@
     scoped_refptr<SpecialStoragePolicy> special_storage_policy,
     const base::FilePath& file_system_directory,
     leveldb::Env* env_override,
-    GetTypeStringForURLCallback get_type_string_for_url,
     const std::set<std::string>& known_type_strings,
     SandboxFileSystemBackendDelegate* sandbox_delegate,
     bool is_incognito)
@@ -324,10 +319,8 @@
       env_override_(env_override),
       is_incognito_(is_incognito),
       db_flush_delay_seconds_(10 * 60),  // 10 mins.
-      get_type_string_for_url_(std::move(get_type_string_for_url)),
       known_type_strings_(known_type_strings),
       sandbox_delegate_(sandbox_delegate) {
-  DCHECK(!get_type_string_for_url_.is_null());
   DETACH_FROM_SEQUENCE(sequence_checker_);
   DCHECK(!is_incognito_ ||
          (env_override && leveldb_chrome::IsMemEnv(env_override)));
@@ -954,16 +947,18 @@
 
 bool ObfuscatedFileUtil::DeleteDirectoryForStorageKeyAndType(
     const blink::StorageKey& storage_key,
-    const std::string& type_string) {
+    const absl::optional<FileSystemType>& type) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DestroyDirectoryDatabaseForStorageKey(storage_key, type_string);
+  DestroyDirectoryDatabaseForStorageKey(storage_key, type);
 
   base::FileErrorOr<base::FilePath> origin_path =
       GetDirectoryForStorageKey(storage_key, false);
   if (origin_path.is_error() || origin_path->empty())
     return true;
 
-  if (!type_string.empty()) {
+  if (type) {
+    const std::string type_string =
+        SandboxFileSystemBackendDelegate::GetTypeString(type.value());
     // Delete the filesystem type directory.
     const base::FileErrorOr<base::FilePath> origin_type_path =
         GetDirectoryForStorageKeyAndType(storage_key, type_string, false);
@@ -980,10 +975,10 @@
     // At this point we are sure we had successfully deleted the origin/type
     // directory (i.e. we're ready to just return true).
     // See if we have other directories in this origin directory.
-    for (const std::string& type : known_type_strings_) {
-      if (type == type_string)
+    for (const std::string& known_type : known_type_strings_) {
+      if (known_type == type_string)
         continue;
-      if (delegate_->DirectoryExists(origin_path->AppendASCII(type))) {
+      if (delegate_->DirectoryExists(origin_path->AppendASCII(known_type))) {
         // Other type's directory exists; just return true here.
         return true;
       }
@@ -1005,14 +1000,14 @@
 
 bool ObfuscatedFileUtil::DeleteDirectoryForBucketAndType(
     const BucketLocator& bucket_locator,
-    const std::string& type_string) {
+    const absl::optional<FileSystemType>& type) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   if (bucket_locator.is_default &&
       bucket_locator.storage_key.IsFirstPartyContext())
     return DeleteDirectoryForStorageKeyAndType(bucket_locator.storage_key,
-                                               type_string);
+                                               type);
 
-  DestroyDirectoryDatabaseForBucket(bucket_locator, type_string);
+  DestroyDirectoryDatabaseForBucket(bucket_locator, type);
 
   // Get the base path for the bucket without the type string appended.
   base::FilePath path =
@@ -1022,7 +1017,9 @@
   if (error != base::File::FILE_OK || path.empty())
     return true;
 
-  if (!type_string.empty()) {
+  if (type) {
+    const std::string type_string =
+        SandboxFileSystemBackendDelegate::GetTypeString(type.value());
     // Delete the filesystem type directory.
     const base::FileErrorOr<base::FilePath> path_with_type =
         GetDirectoryForBucketAndType(bucket_locator, type_string, false);
@@ -1038,10 +1035,10 @@
     // directory. Now we need to see if we have other sub-type-directories under
     // the higher-level `path` directory. If so, we need to return early to
     // avoid deleting the higher-level `path` directory.
-    for (const std::string& type : known_type_strings_) {
-      if (type == type_string)
+    for (const std::string& known_type : known_type_strings_) {
+      if (known_type == type_string)
         continue;
-      if (delegate_->DirectoryExists(path.AppendASCII(type))) {
+      if (delegate_->DirectoryExists(path.AppendASCII(known_type))) {
         // Other type's directory exists; return to avoid deleting the higher
         // level directory.
         return true;
@@ -1070,31 +1067,33 @@
 
 void ObfuscatedFileUtil::DestroyDirectoryDatabaseForStorageKey(
     const blink::StorageKey& storage_key,
-    const std::string& type_string) {
-  DestroyDirectoryDatabaseHelper(absl::nullopt, storage_key, type_string);
+    const absl::optional<FileSystemType>& type) {
+  DestroyDirectoryDatabaseHelper(absl::nullopt, storage_key, type);
 }
 
 void ObfuscatedFileUtil::DestroyDirectoryDatabaseForBucket(
     const BucketLocator& bucket_locator,
-    const std::string& type_string) {
+    const absl::optional<FileSystemType>& type) {
   DestroyDirectoryDatabaseHelper(bucket_locator, bucket_locator.storage_key,
-                                 type_string);
+                                 type);
 }
 
 void ObfuscatedFileUtil::DestroyDirectoryDatabaseHelper(
     const absl::optional<BucketLocator>& bucket_locator,
     const blink::StorageKey& storage_key,
-    const std::string& type_string) {
+    const absl::optional<FileSystemType>& type) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   DatabaseKey key_prefix;
-  // TODO(https://crbug.com/1344157): Refactor to compare by Quota types rather
-  // than string representations of FileSystem types. `key.bucket()` is
-  // absl::nullopt for all non-kTemporary types.
-  if (type_string == kTemporary) {
+  const std::string type_string =
+      type ? SandboxFileSystemBackendDelegate::GetTypeString(type.value())
+           : std::string();
+  // `key.bucket()` is absl::nullopt for all non-kTemporary types.
+  if (type && (FileSystemTypeToQuotaStorageType(type.value()) ==
+               ::blink::mojom::StorageType::kTemporary)) {
     if (bucket_locator.has_value()) {
-      key_prefix = DatabaseKey(bucket_locator->storage_key,
-                               bucket_locator.value(), type_string);
+      key_prefix =
+          DatabaseKey(bucket_locator->storage_key, bucket_locator, type_string);
     } else {
       // If we are not provided a custom bucket value we must find the default
       // bucket corresponding to the StorageKey.
@@ -1111,13 +1110,13 @@
     key_prefix = DatabaseKey(storage_key, absl::nullopt, type_string);
   }
 
-  // If `type_string` is empty, delete all filesystem types under `storage_key`.
+  // If `type` is empty, delete all filesystem types under `storage_key`.
   for (auto iter = directories_.lower_bound(key_prefix);
        iter != directories_.end();) {
-    // If the key matches exactly or `type_string` is empty and just the
+    // If the key matches exactly or `type` is absl::nullopt and just the
     // StorageKey and BucketLocator match exactly, delete the database.
     if (iter->first == key_prefix ||
-        (type_string == std::string() &&
+        (type == absl::nullopt &&
          iter->first.storage_key() == key_prefix.storage_key() &&
          iter->first.bucket() == key_prefix.bucket())) {
       std::unique_ptr<SandboxDirectoryDatabase> database =
@@ -1142,17 +1141,13 @@
   if (!url.bucket().has_value()) {
     // Access the SandboxDirectoryDatabase to construct the file path.
     return GetDirectoryForStorageKeyAndType(
-        url.storage_key(), CallGetTypeStringForURL(url), create);
+        url.storage_key(),
+        SandboxFileSystemBackendDelegate::GetTypeString(url.type()), create);
   }
   // Construct the file path using the provided bucket information.
-  return GetDirectoryForBucketAndType(url.bucket().value(),
-                                      CallGetTypeStringForURL(url), create);
-}
-
-std::string ObfuscatedFileUtil::CallGetTypeStringForURL(
-    const FileSystemURL& url) {
-  DCHECK(!get_type_string_for_url_.is_null());
-  return get_type_string_for_url_.Run(url);
+  return GetDirectoryForBucketAndType(
+      url.bucket().value(),
+      SandboxFileSystemBackendDelegate::GetTypeString(url.type()), create);
 }
 
 QuotaErrorOr<BucketLocator> ObfuscatedFileUtil::GetOrCreateDefaultBucket(
@@ -1361,11 +1356,11 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   DatabaseKey key;
-  std::string type_string = CallGetTypeStringForURL(url);
-  // TODO(https://crbug.com/1344157): Refactor to compare by Quota types rather
-  // than string representations of FileSystem types. `key.bucket()` is
-  // absl::nullopt for all non-kTemporary types.
-  if (type_string == kTemporary) {
+  const std::string type_string =
+      SandboxFileSystemBackendDelegate::GetTypeString(url.type());
+  // `key.bucket()` is absl::nullopt for all non-kTemporary types.
+  if (FileSystemTypeToQuotaStorageType(url.type()) ==
+      ::blink::mojom::StorageType::kTemporary) {
     if (url.bucket().has_value()) {
       key = DatabaseKey(url.storage_key(), url.bucket().value(), type_string);
     } else {
@@ -1507,8 +1502,11 @@
   BucketLocator default_bucket = default_buckets_[storage_key];
   // Ensure that all directories with that StorageKey and bucket have been
   // erased.
-  DCHECK(directories_.find(DatabaseKey(storage_key, default_bucket,
-                                       kTemporary)) == directories_.end());
+  DCHECK(directories_.find(
+             DatabaseKey(storage_key, default_bucket,
+                         SandboxFileSystemBackendDelegate::GetTypeString(
+                             FileSystemType::kFileSystemTypeTemporary))) ==
+         directories_.end());
   default_buckets_.erase(default_bucket_iter);
 }
 
@@ -1525,8 +1523,11 @@
   DCHECK(default_bucket == bucket_locator);
   // Ensure that all directories with that StorageKey and bucket have been
   // erased.
-  DCHECK(directories_.find(DatabaseKey(storage_key, default_bucket,
-                                       kTemporary)) == directories_.end());
+  DCHECK(directories_.find(
+             DatabaseKey(storage_key, default_bucket,
+                         SandboxFileSystemBackendDelegate::GetTypeString(
+                             FileSystemType::kFileSystemTypeTemporary))) ==
+         directories_.end());
   default_buckets_.erase(default_bucket_iter);
 }
 
diff --git a/storage/browser/file_system/obfuscated_file_util.h b/storage/browser/file_system/obfuscated_file_util.h
index 7f1658a..dfe9385b 100644
--- a/storage/browser/file_system/obfuscated_file_util.h
+++ b/storage/browser/file_system/obfuscated_file_util.h
@@ -34,10 +34,6 @@
 class StorageKey;
 }  // namespace blink
 
-namespace url {
-class Origin;
-}  // namespace url
-
 namespace storage {
 
 class FileSystemOperationContext;
@@ -46,12 +42,18 @@
 class SandboxOriginDatabaseInterface;
 class SpecialStoragePolicy;
 
-// Class representing the key for directories_. NOTE: The BucketLocator value is
+// Class representing the key for directories_. NOTE: The `bucket` value is
 // optional due to usage of ObfuscatedFileUtil where the type is not kTemporary
 // (i.e. kPersistent or kSyncable). For all non-temporary types, expect the
 // bucket member value to be absl::nullopt. The class is implemented as such to
 // avoid mapping the same StorageKey to potentially different bucket values,
-// which would cause directories_ lookup errors.
+// which would cause directories_ lookup errors. NOTE: The `type_string` value
+// is empty when designating a "top-level directory" or a directory that
+// contains one or more subdirectories with a non-empty type. This class stores
+// a string rather than the FileSystemType itself because multiple
+// FileSystemTypes can map to the same `type_string`, and preserving this
+// behavior is necessary to retrieving and deleting ObfuscatedFilePaths
+// correctly.
 class DatabaseKey {
  public:
   DatabaseKey();
@@ -65,7 +67,7 @@
 
   DatabaseKey(const blink::StorageKey& storage_key,
               const absl::optional<BucketLocator>& bucket,
-              const std::string& type);
+              const std::string& type_string);
 
   const blink::StorageKey& storage_key() const { return storage_key_; }
   const absl::optional<BucketLocator>& bucket() const { return bucket_; }
@@ -135,20 +137,16 @@
   using GetTypeStringForURLCallback =
       base::RepeatingCallback<std::string(const FileSystemURL&)>;
 
-  // `get_type_string_for_url` is user-defined callback that should return
-  // a type string for the given FileSystemURL.  The type string is used
-  // to provide per-type isolation in the sandboxed filesystem directory.
-  //
-  // `known_type_strings` are known type string names that this file system
-  // should care about.
-  // This info is used to determine whether we could delete the entire
-  // origin directory or not in DeleteDirectoryForStorageKeyAndType. If no
-  // directory for any known type exists the origin directory may get
-  // deleted when one StorageKey/type pair is deleted.
+  // The type string is used to provide per-type isolation in the sandboxed
+  // filesystem directory. `known_type_strings` are known type string names that
+  // this file system should care about. This info is used to determine whether
+  // we could delete the entire origin directory or not in
+  // DeleteDirectoryForStorageKeyAndType. If no directory for any known type
+  // exists the origin directory may get deleted when one StorageKey/type pair
+  // is deleted.
   ObfuscatedFileUtil(scoped_refptr<SpecialStoragePolicy> special_storage_policy,
                      const base::FilePath& file_system_directory,
                      leveldb::Env* env_override,
-                     GetTypeStringForURLCallback get_type_string_for_url,
                      const std::set<std::string>& known_type_strings,
                      SandboxFileSystemBackendDelegate* sandbox_delegate,
                      bool is_incognito);
@@ -234,15 +232,17 @@
 
   // Deletes the topmost directory specific to this StorageKey and type. This
   // will delete its directory database. Deletes the topmost StorageKey
-  // directory if `type_string` is empty.
-  bool DeleteDirectoryForStorageKeyAndType(const blink::StorageKey& storage_key,
-                                           const std::string& type_string);
+  // directory if `type` is absl::nullopt.
+  bool DeleteDirectoryForStorageKeyAndType(
+      const blink::StorageKey& storage_key,
+      const absl::optional<FileSystemType>& type);
 
   // Deletes the topmost directory specific to this BucketLocator and type. This
   // will delete its directory database. Deletes the topmost bucket
-  // directory if `type_string` is empty.
-  bool DeleteDirectoryForBucketAndType(const BucketLocator& bucket_locator,
-                                       const std::string& type_string);
+  // directory if `type` is absl::nullopt.
+  bool DeleteDirectoryForBucketAndType(
+      const BucketLocator& bucket_locator,
+      const absl::optional<FileSystemType>& type);
 
   // This method and all methods of its returned class must be called only on
   // the FILE thread.  The caller is responsible for deleting the returned
@@ -253,12 +253,13 @@
   // database on the disk corresponding to the provided StorageKey and type.
   void DestroyDirectoryDatabaseForStorageKey(
       const blink::StorageKey& storage_key,
-      const std::string& type_string);
+      const absl::optional<FileSystemType>& type);
 
   // Deletes a directory database from the database list and destroys the
   // database on the disk corresponding to the provided bucket locator and type.
-  void DestroyDirectoryDatabaseForBucket(const BucketLocator& bucket_locator,
-                                         const std::string& type_string);
+  void DestroyDirectoryDatabaseForBucket(
+      const BucketLocator& bucket_locator,
+      const absl::optional<FileSystemType>& type);
 
   // Computes a cost for storing a given file in the obfuscated FSFU.
   // As the cost of a file is independent of the cost of its parent directories,
@@ -310,9 +311,6 @@
   base::FileErrorOr<base::FilePath> GetDirectoryForURL(const FileSystemURL& url,
                                                        bool create);
 
-  // This just calls get_type_string_for_url_ callback that is given in ctor.
-  std::string CallGetTypeStringForURL(const FileSystemURL& url);
-
   base::File::Error GetFileInfoInternal(SandboxDirectoryDatabase* db,
                                         FileSystemOperationContext* context,
                                         const FileSystemURL& url,
@@ -359,7 +357,7 @@
   void DestroyDirectoryDatabaseHelper(
       const absl::optional<BucketLocator>& bucket_locator,
       const blink::StorageKey& storage_key,
-      const std::string& type_string);
+      const absl::optional<FileSystemType>& type);
 
   // This returns nullptr if `create` flag is false and a filesystem does not
   // exist for the given `url`.
@@ -428,7 +426,6 @@
 
   base::OneShotTimer timer_;
 
-  GetTypeStringForURLCallback get_type_string_for_url_;
   std::set<std::string> known_type_strings_;
 
   // Not owned.
diff --git a/storage/browser/file_system/obfuscated_file_util_unittest.cc b/storage/browser/file_system/obfuscated_file_util_unittest.cc
index ceba012..d79d11d 100644
--- a/storage/browser/file_system/obfuscated_file_util_unittest.cc
+++ b/storage/browser/file_system/obfuscated_file_util_unittest.cc
@@ -859,11 +859,10 @@
     ASSERT_TRUE(db != nullptr);
 
     // Destroy it.
-    (is_non_default_bucket())
-        ? ofu()->DestroyDirectoryDatabaseForBucket(url.bucket().value(),
-                                                   GetTypeString(url.type()))
-        : ofu()->DestroyDirectoryDatabaseForStorageKey(
-              url.storage_key(), GetTypeString(url.type()));
+    (is_non_default_bucket()) ? ofu()->DestroyDirectoryDatabaseForBucket(
+                                    url.bucket().value(), url.type())
+                              : ofu()->DestroyDirectoryDatabaseForStorageKey(
+                                    url.storage_key(), url.type());
     ASSERT_TRUE(ofu()->directories_.empty());
   }
 
@@ -1863,9 +1862,8 @@
 
   // Destroy database to make inconsistency between database and filesystem.
   (is_non_default_bucket())
-      ? ofu()->DestroyDirectoryDatabaseForBucket(custom_bucket_, type_string())
-      : ofu()->DestroyDirectoryDatabaseForStorageKey(storage_key(),
-                                                     type_string());
+      ? ofu()->DestroyDirectoryDatabaseForBucket(custom_bucket_, type())
+      : ofu()->DestroyDirectoryDatabaseForStorageKey(storage_key(), type());
 
   // Try to get file info of broken file.
   EXPECT_FALSE(PathExists(kPath1));
@@ -1886,9 +1884,8 @@
 
   // Destroy again.
   (is_non_default_bucket())
-      ? ofu()->DestroyDirectoryDatabaseForBucket(custom_bucket_, type_string())
-      : ofu()->DestroyDirectoryDatabaseForStorageKey(storage_key(),
-                                                     type_string());
+      ? ofu()->DestroyDirectoryDatabaseForBucket(custom_bucket_, type())
+      : ofu()->DestroyDirectoryDatabaseForStorageKey(storage_key(), type());
 
   // Repair broken `kPath1`.
   context = NewContext(nullptr);
@@ -1907,9 +1904,8 @@
                                   true /* copy */));
 
   (is_non_default_bucket())
-      ? ofu()->DestroyDirectoryDatabaseForBucket(custom_bucket_, type_string())
-      : ofu()->DestroyDirectoryDatabaseForStorageKey(storage_key(),
-                                                     type_string());
+      ? ofu()->DestroyDirectoryDatabaseForBucket(custom_bucket_, type())
+      : ofu()->DestroyDirectoryDatabaseForStorageKey(storage_key(), type());
   context = NewContext(nullptr);
   created = false;
   EXPECT_EQ(base::File::FILE_OK,
@@ -2582,7 +2578,7 @@
 
   // Delete a directory for default_bucket_'s persistent filesystem.
   ASSERT_TRUE(ofu()->DeleteDirectoryForBucketAndType(
-      default_bucket_, GetTypeString(kFileSystemTypePersistent)));
+      default_bucket_, kFileSystemTypePersistent));
 
   // The directory for default_bucket_'s temporary filesystem should not be
   // removed.
@@ -2615,7 +2611,7 @@
 
   // Deleting directories which don't exist is not an error.
   ASSERT_TRUE(ofu()->DeleteDirectoryForBucketAndType(
-      alternate_custom_bucket_, GetTypeString(kFileSystemTypePersistent)));
+      alternate_custom_bucket_, kFileSystemTypePersistent));
 }
 
 TEST_P(ObfuscatedFileUtilTest, DeleteDirectoryForStorageKeyAndType) {
@@ -2664,7 +2660,7 @@
 
   // Delete a directory for storage_key1's persistent filesystem.
   ASSERT_TRUE(ofu()->DeleteDirectoryForStorageKeyAndType(
-      storage_key1, GetTypeString(kFileSystemTypePersistent)));
+      storage_key1, kFileSystemTypePersistent));
 
   // The directory for storage_key1's temporary filesystem should not be
   // removed.
@@ -2710,9 +2706,9 @@
 
   // Deleting directories which don't exist is not an error.
   ASSERT_TRUE(ofu()->DeleteDirectoryForStorageKeyAndType(
-      storage_key3, GetTypeString(kFileSystemTypeTemporary)));
+      storage_key3, kFileSystemTypeTemporary));
   ASSERT_TRUE(ofu()->DeleteDirectoryForStorageKeyAndType(
-      storage_key3, GetTypeString(kFileSystemTypePersistent)));
+      storage_key3, kFileSystemTypePersistent));
 }
 
 TEST_P(ObfuscatedFileUtilTest, DeleteDirectoryForBucketAndType_DeleteAll) {
@@ -2756,7 +2752,7 @@
                    .is_error());
 
   // Delete all directories for default_bucket_.
-  ofu()->DeleteDirectoryForBucketAndType(default_bucket_, std::string());
+  ofu()->DeleteDirectoryForBucketAndType(default_bucket_, absl::nullopt);
 
   // The directories for default_bucket_ should be removed.
   ASSERT_EQ(ofu()
@@ -2828,7 +2824,7 @@
                    .is_error());
 
   // Delete all directories for storage_key1.
-  ofu()->DeleteDirectoryForStorageKeyAndType(storage_key1, std::string());
+  ofu()->DeleteDirectoryForStorageKeyAndType(storage_key1, absl::nullopt);
 
   // The directories for storage_key1 should be removed.
   ASSERT_EQ(ofu()
diff --git a/storage/browser/file_system/sandbox_file_system_backend_delegate.cc b/storage/browser/file_system/sandbox_file_system_backend_delegate.cc
index f981988..fd415a1 100644
--- a/storage/browser/file_system/sandbox_file_system_backend_delegate.cc
+++ b/storage/browser/file_system/sandbox_file_system_backend_delegate.cc
@@ -81,10 +81,6 @@
     FILE_PATH_LITERAL('\\'),
 };
 
-std::string GetTypeStringForURL(const FileSystemURL& url) {
-  return SandboxFileSystemBackendDelegate::GetTypeString(url.type());
-}
-
 std::set<std::string> GetKnownTypeStrings() {
   std::set<std::string> known_type_strings;
   known_type_strings.insert(kTemporaryDirectoryName);
@@ -203,7 +199,6 @@
               special_storage_policy,
               profile_path.Append(kFileSystemDirectory),
               env_override,
-              base::BindRepeating(&GetTypeStringForURL),
               GetKnownTypeStrings(),
               this,
               file_system_options.is_incognito()))),
@@ -368,7 +363,7 @@
                                                      storage_key, type);
   usage_cache()->CloseCacheFiles();
   bool result = obfuscated_file_util()->DeleteDirectoryForStorageKeyAndType(
-      storage_key, GetTypeString(type));
+      storage_key, type);
   if (result && proxy && usage) {
     proxy->NotifyStorageModified(
         QuotaClientType::kFileSystem, storage_key,
@@ -401,7 +396,7 @@
                           : 0;
   usage_cache()->CloseCacheFiles();
   bool result = obfuscated_file_util()->DeleteDirectoryForBucketAndType(
-      bucket_locator, GetTypeString(type));
+      bucket_locator, type);
   if (result && proxy && usage) {
     proxy->NotifyBucketModified(QuotaClientType::kFileSystem, bucket_locator.id,
                                 -usage, base::Time::Now(),
@@ -820,8 +815,7 @@
     bool is_incognito) {
   return std::make_unique<ObfuscatedFileUtil>(
       std::move(special_storage_policy), file_system_directory, env_override,
-      base::BindRepeating(&GetTypeStringForURL), GetKnownTypeStrings(),
-      /*sandbox_delegate=*/nullptr, is_incognito);
+      GetKnownTypeStrings(), /*sandbox_delegate=*/nullptr, is_incognito);
 }
 
 }  // namespace storage
diff --git a/testing/buildbot/chrome.json b/testing/buildbot/chrome.json
index 6b1d5bd..7588080 100644
--- a/testing/buildbot/chrome.json
+++ b/testing/buildbot/chrome.json
@@ -2256,7 +2256,7 @@
       {
         "args": [],
         "cros_board": "cherry",
-        "cros_img": "cherry64-release/R106-14998.0.0",
+        "cros_img": "cherry64-release/R106-14997.0.0",
         "name": "lacros_all_tast_tests CHERRY64_RELEASE_LKGM",
         "resultdb": {
           "enable": true,
@@ -2272,7 +2272,7 @@
       {
         "args": [],
         "cros_board": "jacuzzi",
-        "cros_img": "jacuzzi64-release/R106-14998.0.0",
+        "cros_img": "jacuzzi64-release/R106-14997.0.0",
         "name": "lacros_all_tast_tests JACUZZI64_RELEASE_LKGM",
         "resultdb": {
           "enable": true,
diff --git a/testing/buildbot/filters/fuchsia.unit_tests.filter b/testing/buildbot/filters/fuchsia.unit_tests.filter
index 0419f10..3693cf2 100644
--- a/testing/buildbot/filters/fuchsia.unit_tests.filter
+++ b/testing/buildbot/filters/fuchsia.unit_tests.filter
@@ -1,7 +1,6 @@
 -All/PasswordManagerPorterStoreTest.Import/2
 -CartServiceTest.TestExpiredDataDeleted
 -CartServiceTest.TestHiddenFlipedByCartAction
--DevToolsFileWatcher*
 -DiagnosticsController*
 -DiagnosticsModelTest.Run*
 -DialServiceImplTest.TestMultiple*
@@ -30,5 +29,8 @@
 -UDPSocketUnitTest.TestUDPMulticastJoin*
 -UDPSocketUnitTest.TestUDPMulticastRecv
 
+# https://crbug.com/851641
+-DevToolsFileWatcher*
+
 # https://crbug.com/1315834
 -GalleryWatchManagerTest.Basic
diff --git a/testing/buildbot/filters/mac.mac12-arm64-rel.browser_tests.filter b/testing/buildbot/filters/mac.mac12-arm64-rel.browser_tests.filter
index afa24340..286d4a3b 100644
--- a/testing/buildbot/filters/mac.mac12-arm64-rel.browser_tests.filter
+++ b/testing/buildbot/filters/mac.mac12-arm64-rel.browser_tests.filter
@@ -98,7 +98,6 @@
 -SaveAsMhtml/SavePageOriginalVsSavedComparisonTest.NestedFrames/0
 -SavePageOriginalVsSavedComparisonTest.AboutBlank/0
 -SavePageOriginalVsSavedComparisonTest.CrossSiteObject/0
--SelectAllScreensTest.SelectAllScreensDisabledByDefault
 -SitePerProcessWebViewTest.ContentScript
 -SitePerProcessWebViewTest.ContentScriptInOOPIF
 -SSLUITest.BadCertFollowedByGoodCert
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl
index c8ecb2b..1affd53 100644
--- a/testing/buildbot/variants.pyl
+++ b/testing/buildbot/variants.pyl
@@ -927,7 +927,7 @@
     'skylab': {
       'cros_board': 'cherry',
       'cros_chrome_version': '105.0.5190.0',
-      'cros_img': 'cherry64-release/R106-14998.0.0',
+      'cros_img': 'cherry64-release/R106-14997.0.0',
     },
     'enabled': True,
     'identifier': 'CHERRY64_RELEASE_LKGM',
@@ -1017,7 +1017,7 @@
     'skylab': {
       'cros_board': 'jacuzzi',
       'cros_chrome_version': '105.0.5190.0',
-      'cros_img': 'jacuzzi64-release/R106-14998.0.0',
+      'cros_img': 'jacuzzi64-release/R106-14997.0.0',
     },
     'enabled': True,
     'identifier': 'JACUZZI64_RELEASE_LKGM',
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index a3021c30..3f967f3 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -3897,9 +3897,9 @@
             ],
             "experiments": [
                 {
-                    "name": "Enabled_MovementThreshold_24_20220711",
+                    "name": "Enabled_MovementThreshold_60_20220802",
                     "params": {
-                        "DragAndDropMovementThresholdDipParam": "24"
+                        "DragAndDropMovementThresholdDipParam": "60"
                     },
                     "enable_features": [
                         "ContextMenuPopupStyle",
@@ -7219,6 +7219,30 @@
             ]
         }
     ],
+    "Prerender2Desktop": [
+        {
+            "platforms": [
+                "windows",
+                "mac",
+                "linux",
+                "chromeos",
+                "chromeos_lacros"
+            ],
+            "experiments": [
+                {
+                    "name": "EnabledPrerenderSpecRulesAndDUI_20220804",
+                    "enable_features": [
+                        "OmniboxTriggerForPrerender2",
+                        "Prerender2"
+                    ],
+                    "disable_features": [
+                        "OmniboxTriggerForNoStatePrefetch",
+                        "SupportSearchSuggestionForPrerender2"
+                    ]
+                }
+            ]
+        }
+    ],
     "PrewarmDefaultFontFamilies": [
         {
             "platforms": [
diff --git a/third_party/blink/common/client_hints/DEPS b/third_party/blink/common/client_hints/DEPS
index 3bdeaae..5aa1b88d9 100644
--- a/third_party/blink/common/client_hints/DEPS
+++ b/third_party/blink/common/client_hints/DEPS
@@ -1,4 +1,3 @@
 include_rules = [
     "+services/network/public/mojom/web_client_hints_types.mojom-shared.h",
-    "+absl/types/optional.h",
 ]
diff --git a/third_party/blink/common/client_hints/enabled_client_hints_unittest.cc b/third_party/blink/common/client_hints/enabled_client_hints_unittest.cc
index bdbfa35..a6cf195 100644
--- a/third_party/blink/common/client_hints/enabled_client_hints_unittest.cc
+++ b/third_party/blink/common/client_hints/enabled_client_hints_unittest.cc
@@ -4,12 +4,12 @@
 
 #include "third_party/blink/public/common/client_hints/enabled_client_hints.h"
 
-#include "absl/types/optional.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/test/scoped_feature_list.h"
 #include "net/http/http_response_headers.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/common/features.h"
 #include "third_party/blink/public/common/origin_trials/origin_trial_policy.h"
 #include "third_party/blink/public/common/origin_trials/origin_trial_public_key.h"
diff --git a/third_party/blink/renderer/core/css/css_primitive_value_mappings.h b/third_party/blink/renderer/core/css/css_primitive_value_mappings.h
index ac85e6b7..d747b856 100644
--- a/third_party/blink/renderer/core/css/css_primitive_value_mappings.h
+++ b/third_party/blink/renderer/core/css/css_primitive_value_mappings.h
@@ -1650,8 +1650,6 @@
       return kContainerTypeInlineSize;
     case CSSValueID::kSize:
       return kContainerTypeSize;
-    case CSSValueID::kStyle:
-      return kContainerTypeStyle;
     default:
       break;
   }
diff --git a/third_party/blink/renderer/core/css/css_properties.json5 b/third_party/blink/renderer/core/css/css_properties.json5
index 8df34d86..3dbc54f 100644
--- a/third_party/blink/renderer/core/css/css_properties.json5
+++ b/third_party/blink/renderer/core/css/css_properties.json5
@@ -2359,9 +2359,9 @@
     {
       name: "container-type",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
-      keywords: ["normal", "inline-size", "size", "style"],
+      keywords: ["normal", "inline-size", "size"],
       field_group: "*",
-      field_size: 3,
+      field_size: 2,
       field_template: "primitive",
       default_value: "kContainerTypeNormal",
       type_name: "unsigned",
diff --git a/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc b/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc
index 8ffd4d9..7c2066b 100644
--- a/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc
+++ b/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc
@@ -5672,32 +5672,18 @@
   if (CSSValue* value = ConsumeIdent<CSSValueID::kNormal>(range))
     return value;
 
-  CSSValue* style = nullptr;
-  CSSValue* size = nullptr;
-  while (!range.AtEnd()) {
-    if (!size) {
-      size = ConsumeIdent<CSSValueID::kSize, CSSValueID::kInlineSize>(range);
-      if (size)
-        continue;
-    }
-    if (RuntimeEnabledFeatures::CSSStyleQueriesEnabled()) {
-      if (!style) {
-        style = ConsumeIdent<CSSValueID::kStyle>(range);
-        if (style)
-          continue;
-      }
-    }
-    return nullptr;
+  if (CSSValue* value =
+          ConsumeIdent<CSSValueID::kSize, CSSValueID::kInlineSize>(range)) {
+    // Note that StyleBuilderConverter::ConvertFlags requires that values
+    // other than the ZeroValue appear in a CSSValueList, hence we return a list
+    // with one item here. Also note that the full grammar will require multiple
+    // list items in the future, if we add support for non-size container types.
+    CSSValueList* list = CSSValueList::CreateSpaceSeparated();
+    list->Append(*value);
+    return list;
   }
-  if (!size && !style)
-    return nullptr;
 
-  CSSValueList* list = CSSValueList::CreateSpaceSeparated();
-  if (style)
-    list->Append(*style);
-  if (size)
-    list->Append(*size);
-  return list;
+  return nullptr;
 }
 
 CSSValue* ConsumeSVGPaint(CSSParserTokenRange& range,
diff --git a/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
index 1c909d3..401ec07 100644
--- a/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
+++ b/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
@@ -2036,17 +2036,12 @@
             kContainerTypeBlockSize);
   if (style.ContainerType() == kContainerTypeNormal)
     return CSSIdentifierValue::Create(CSSValueID::kNormal);
-
-  CSSValueList* list = CSSValueList::CreateSpaceSeparated();
-  if (style.ContainerType() & kContainerTypeStyle)
-    list->Append(*CSSIdentifierValue::Create(CSSValueID::kStyle));
-  if ((style.ContainerType() & kContainerTypeSize) == kContainerTypeSize) {
-    list->Append(*CSSIdentifierValue::Create(CSSValueID::kSize));
-  } else if ((style.ContainerType() & kContainerTypeSize) ==
-             kContainerTypeInlineSize) {
-    list->Append(*CSSIdentifierValue::Create(CSSValueID::kInlineSize));
-  }
-  return list;
+  if (style.ContainerType() == kContainerTypeSize)
+    return CSSIdentifierValue::Create(CSSValueID::kSize);
+  if (style.ContainerType() == kContainerTypeInlineSize)
+    return CSSIdentifierValue::Create(CSSValueID::kInlineSize);
+  NOTREACHED();
+  return nullptr;
 }
 
 namespace {
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
index 34fd5a0..07cb67e 100644
--- a/third_party/blink/renderer/core/dom/document.cc
+++ b/third_party/blink/renderer/core/dom/document.cc
@@ -4810,6 +4810,7 @@
 }
 
 void Document::SetHoverElement(Element* new_hover_element) {
+  Element::HoveredElementChanged(hover_element_, new_hover_element);
   hover_element_ = new_hover_element;
 }
 
@@ -7566,12 +7567,12 @@
   Element* new_hover_element =
       SkipDisplayNoneAncestors(inner_element_in_document);
 
-  // Update our current hover element.
-  SetHoverElement(new_hover_element);
-
   if (old_hover_element == new_hover_element)
     return;
 
+  // Update our current hover element.
+  SetHoverElement(new_hover_element);
+
   Node* ancestor_element = nullptr;
   if (old_hover_element && old_hover_element->isConnected() &&
       new_hover_element) {
@@ -8068,6 +8069,7 @@
   visitor->Trace(popup_hint_showing_);
   visitor->Trace(popup_stack_);
   visitor->Trace(popups_waiting_to_hide_);
+  visitor->Trace(all_open_pop_ups_);
   visitor->Trace(load_event_delay_timer_);
   visitor->Trace(plugin_loading_timer_);
   visitor->Trace(elem_sheet_);
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h
index 1aaaa90..bb66aed3 100644
--- a/third_party/blink/renderer/core/dom/document.h
+++ b/third_party/blink/renderer/core/dom/document.h
@@ -1523,6 +1523,7 @@
   HeapVector<Member<Element>>& PopupStack() { return popup_stack_; }
   const HeapVector<Member<Element>>& PopupStack() const { return popup_stack_; }
   bool PopupAutoShowing() const { return !popup_stack_.IsEmpty(); }
+  HeapHashSet<Member<Element>>& AllOpenPopUps() { return all_open_pop_ups_; }
   Element* TopmostPopupAutoOrHint() const;
   HeapHashSet<Member<Element>>& PopupsWaitingToHide() {
     return popups_waiting_to_hide_;
@@ -2336,6 +2337,8 @@
   // A set of popups for which hidePopUp() has been called, but animations are
   // still running.
   HeapHashSet<Member<Element>> popups_waiting_to_hide_;
+  // A set of all open pop-ups, of all types.
+  HeapHashSet<Member<Element>> all_open_pop_ups_;
 
   int load_event_delay_count_;
 
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
index cc9e15d..c7671e2 100644
--- a/third_party/blink/renderer/core/dom/element.cc
+++ b/third_party/blink/renderer/core/dom/element.cc
@@ -2556,6 +2556,8 @@
       document.SetPopupHintShowing(this);
     }
   }
+  DCHECK(!document.AllOpenPopUps().Contains(this));
+  document.AllOpenPopUps().insert(this);
 
   // Fire the show event (bubbles, not cancelable).
   Event* event = Event::CreateBubble(event_type_names::kShow);
@@ -2586,6 +2588,12 @@
   GetPopupData()->setVisibilityState(PopupVisibilityState::kShowing);
   PseudoStateChanged(CSSSelector::kPseudoTopLayer);
 
+  // Queue a delayed hide event, if necessary.
+  if (!GetDocument().HoverElement() ||
+      !IsNodePopUpDescendant(*GetDocument().HoverElement())) {
+    MaybeQueuePopupHideEvent();
+  }
+
   SetPopupFocusOnShow();
 }
 
@@ -2627,7 +2635,7 @@
     DCHECK(!endpoint || endpoint->PopupType() == PopupValueType::kAuto);
     const Element* hint_ancestor = nullptr;
     if (document.PopupHintShowing()) {
-      // If there is a hint showing that is a descendent of something on the
+      // If there is a hint showing that is a descendant of something on the
       // stack, then the hint should be hidden before that ancestor is hidden,
       // regardless of popup_independence.
       hint_ancestor = NearestOpenAncestralPopup(document.PopupHintShowing());
@@ -2675,7 +2683,7 @@
 // Hiding a pop-up happens in phases, to facilitate animations and
 // transitions:
 // 1. Capture any already-running animations via getAnimations(), including
-//    animations on descendent elements.
+//    animations on descendant elements.
 // 2. Remove the :top-layer pseudo class.
 // 3. Fire the 'hide' event.
 // 4. If the hidePopup() call is *not* the result of the pop-up being "forced
@@ -2717,6 +2725,7 @@
       document.SetPopupHintShowing(nullptr);
     }
   }
+  document.AllOpenPopUps().erase(this);
   document.PopupsWaitingToHide().insert(this);
 
   bool force_hide = forcing_level == HidePopupForcingLevel::kHideImmediately;
@@ -2909,6 +2918,8 @@
     if (auto* form_control = DynamicTo<HTMLFormControlElement>(element)) {
       recurse_and_update(form_control->popupTargetElement().element);
     }
+    if (auto* hover_popup_element = element->HoverPopupElement())
+      recurse_and_update(hover_popup_element);
     // Include the anchor elements for all showing pop-ups.
     if (anchors_to_popups.Contains(element)) {
       recurse_and_update(anchors_to_popups.at(element));
@@ -2940,6 +2951,7 @@
 // starting pop- up will be returned.
 const Element* Element::NearestOpenAncestralPopup(const Node* node,
                                                   bool inclusive) {
+  DCHECK(RuntimeEnabledFeatures::HTMLPopupAttributeEnabled());
   DCHECK(node);
   // popup_positions is a map from all showing (or about-to-show) pop-ups to
   // their position in the pop-up stack.
@@ -3062,55 +3074,164 @@
   return GetTreeScope().getElementById(anchor_id);  // may be null
 }
 
-void Element::MaybeTriggerHoverPopup(Element* popup_element) {
+Element* Element::HoverPopupElement() const {
   DCHECK(RuntimeEnabledFeatures::HTMLPopupAttributeEnabled());
+  if (!FastHasAttribute(html_names::kHoverpopupAttr))
+    return nullptr;
+  Element* popup_element = GetTreeScope().getElementById(
+      FastGetAttribute(html_names::kHoverpopupAttr));
   if (!popup_element || !popup_element->HasValidPopupAttribute())
+    return nullptr;
+  return popup_element;
+}
+
+// Must be called on an Element that is a pop-up. Returns true if |node| is a
+// descendant of this pop-up. This includes the case where |node| is contained
+// within another pop-up, and the container pop-up is a descendant of this
+// pop_up. For the special case of popup=manual pop-ups, which do not have
+// ancestral relationships, this function checks pure DOM tree descendants of
+// popup=manual pop-ups. This is important for the `hover-pop-up-hide-delay` CSS
+// property, which works for all pop-up types, and needs to keep pop-ups open
+// when a descendant is hovered.
+bool Element::IsNodePopUpDescendant(const Node& node) const {
+  DCHECK(RuntimeEnabledFeatures::HTMLPopupAttributeEnabled());
+  DCHECK(HasValidPopupAttribute());
+  if (PopupType() == PopupValueType::kManual) {
+    for (const Node& ancestor : FlatTreeTraversal::InclusiveAncestorsOf(node)) {
+      if (ancestor == this)
+        return true;
+    }
+  } else {
+    for (const Element* ancestor =
+             NearestOpenAncestralPopup(&node, /*inclusive*/ true);
+         ancestor; ancestor = NearestOpenAncestralPopup(ancestor)) {
+      if (ancestor == this)
+        return true;
+    }
+  }
+  return false;
+}
+
+void Element::MaybeQueuePopupHideEvent() {
+  DCHECK(RuntimeEnabledFeatures::HTMLPopupAttributeEnabled());
+  DCHECK(HasValidPopupAttribute());
+  // If the pop-up isn't showing, or it has an infinite HoverPopUpHideDelay, do
+  // nothing.
+  if (GetPopupData()->visibilityState() == PopupVisibilityState::kHidden)
     return;
-  // Remove this element from hoverPopupTasks always.
-  popup_element->GetPopupData()->hoverPopupTasks().erase(this);
-  // Only trigger the pop-up if the hoverpopup attribute still points to the
-  // same pop-up, and the pop-up is in the tree and still not showing.
-  if (popup_element->IsInTreeScope() && !popup_element->popupOpen() &&
-      popup_element == GetTreeScope().getElementById(
-                           FastGetAttribute(html_names::kHoverpopupAttr))) {
-    popup_element->showPopUp(ASSERT_NO_EXCEPTION);
+  float hide_delay_seconds = GetComputedStyle()->HoverPopUpHideDelay();
+  // If the value is infinite or NaN, don't hide the pop-up.
+  if (!std::isfinite(hide_delay_seconds))
+    return;
+  // Queue the task to hide this pop-up.
+  GetPopupData()->setHoverHideTask(PostDelayedCancellableTask(
+      *GetExecutionContext()->GetTaskRunner(TaskType::kInternalDefault),
+      FROM_HERE,
+      WTF::Bind(
+          [](Element* pop_up) {
+            // Always remove this element from hoverPopupTasks.
+            if (pop_up->GetPopupData())
+              pop_up->GetPopupData()->hoverPopupTasks().erase(pop_up);
+            if (pop_up->popupOpen()) {
+              DCHECK(pop_up->IsInTreeScope());
+              pop_up->HidePopUpInternal(
+                  HidePopupFocusBehavior::kFocusPreviousElement,
+                  HidePopupForcingLevel::kHideAfterAnimations);
+            }
+          },
+          WrapWeakPersistent(this)),
+      base::Seconds(hide_delay_seconds)));
+}
+
+// static
+void Element::HoveredElementChanged(Element* old_element,
+                                    Element* new_element) {
+  if (!RuntimeEnabledFeatures::HTMLPopupAttributeEnabled())
+    return;
+  if (old_element) {
+    // For the previously-hovered element: loop through all showing popups
+    // (including popup=manual) and see if the element that just lost focus was
+    // an ancestor. If so, queue a task to hide it after a delay.
+    for (auto& pop_up : old_element->GetDocument().AllOpenPopUps()) {
+      if (pop_up->IsNodePopUpDescendant(*old_element))
+        pop_up->MaybeQueuePopupHideEvent();
+    }
+  }
+  // It is possible that both old_element and new_element are descendants of
+  // the same open pop_up, in which case we'll queue a hide task and then
+  // immediately cancel it, resulting in no change.
+  if (new_element) {
+    // For the newly-hovered element: loop through all showing popups and see if
+    // the newly-focused element is an ancestor. If so, cancel that pop-up's
+    // hide-after-delay task.
+    for (auto& pop_up : new_element->GetDocument().AllOpenPopUps()) {
+      if (pop_up->IsNodePopUpDescendant(*new_element))
+        pop_up->GetPopupData()->setHoverHideTask(TaskHandle());
+    }
   }
 }
 
 void Element::HandlePopupHovered(bool hovered) {
   if (!RuntimeEnabledFeatures::HTMLPopupAttributeEnabled())
     return;
-  if (!FastHasAttribute(html_names::kHoverpopupAttr) || !IsInTreeScope())
-    return;
-  Element* popup_element = GetTreeScope().getElementById(
-      FastGetAttribute(html_names::kHoverpopupAttr));
-  if (!popup_element || !popup_element->HasValidPopupAttribute())
+  if (!IsInTreeScope())
     return;
   if (hovered) {
-    auto& hover_tasks = popup_element->GetPopupData()->hoverPopupTasks();
-    DCHECK(!hover_tasks.Contains(this));
+    // If we've just hovered an element (or the descendant of an element), see
+    // if it has a hoverpopup attribute that points to a valid pop-up element.
+    // If so, queue a task to show the pop-up after a timeout.
+    if (Element* popup_element = HoverPopupElement()) {
+      auto& hover_tasks = popup_element->GetPopupData()->hoverPopupTasks();
+      DCHECK(!hover_tasks.Contains(this));
 
-    // When we enter an element, we'll post a delayed task for the pop-up we're
-    // targeting. It's possible that multiple nested elements have hoverpopup
-    // attributes pointing to the same pop-up, and in that case, we want to
-    // trigger on the first of them that reaches its timeout threshold.
-    hover_tasks.insert(
-        this,
-        PostDelayedCancellableTask(
-            *GetExecutionContext()->GetTaskRunner(TaskType::kInternalDefault),
-            FROM_HERE,
-            WTF::Bind(&Element::MaybeTriggerHoverPopup,
-                      WrapWeakPersistent(this),
-                      WrapWeakPersistent(popup_element)),
-            base::Seconds(GetComputedStyle()->HoverPopUpDelay())));
+      float hover_delay_seconds = GetComputedStyle()->HoverPopUpDelay();
+      // If the value is infinite or NaN, don't queue a task at all.
+      DCHECK_GE(hover_delay_seconds, 0);
+      if (std::isfinite(hover_delay_seconds)) {
+        // It's possible that multiple nested elements have hoverpopup
+        // attributes pointing to the same pop-up, and in that case, we want to
+        // trigger on the first of them that reaches its timeout threshold.
+        hover_tasks.insert(
+            this,
+            PostDelayedCancellableTask(
+                *GetExecutionContext()->GetTaskRunner(
+                    TaskType::kInternalDefault),
+                FROM_HERE,
+                WTF::Bind(
+                    [](Element* trigger_element, Element* popup_element) {
+                      if (!popup_element ||
+                          !popup_element->HasValidPopupAttribute())
+                        return;
+                      // Remove this element from hoverPopupTasks always.
+                      popup_element->GetPopupData()->hoverPopupTasks().erase(
+                          trigger_element);
+                      // Only trigger the pop-up if the hoverpopup attribute
+                      // still points to the same pop-up, and the pop-up is in
+                      // the tree and still not showing.
+                      if (popup_element->IsInTreeScope() &&
+                          !popup_element->popupOpen() &&
+                          popup_element ==
+                              trigger_element->GetTreeScope().getElementById(
+                                  trigger_element->FastGetAttribute(
+                                      html_names::kHoverpopupAttr))) {
+                        popup_element->InvokePopup(trigger_element);
+                      }
+                    },
+                    WrapWeakPersistent(this),
+                    WrapWeakPersistent(popup_element)),
+                base::Seconds(hover_delay_seconds)));
+      }
+    }
   } else {
-    // If we have a task still waiting, cancel it.
-    popup_element->GetPopupData()->hoverPopupTasks().Take(this).Cancel();
-    // TODO(masonf): Still need to implement the code to hide this pop-up after
-    // a configurable delay. That needs to work even if the pop-up wasn't
-    // triggered by a hoverpopup attribute. E.g. a regular pop-up that gets
-    // hidden after it has not been hovered for n seconds. This should connect
-    // to the HoverPopUpHideDelay() computed style value.
+    // If we have a hoverpopup task still waiting, cancel it. Based on this
+    // logic, if you hover a hoverpopup element, then remove the hoverpopup
+    // attribute, there will be no way to stop the pop-up from being shown after
+    // the delay, even if you subsequently de-hover the element.
+    if (Element* hover_pop_up = HoverPopupElement()) {
+      auto& hover_tasks = hover_pop_up->GetPopupData()->hoverPopupTasks();
+      if (hover_tasks.Contains(this))
+        hover_tasks.Take(this).Cancel();
+    }
   }
 }
 
@@ -5449,6 +5570,30 @@
   return GetElementData()->Attributes().Find(q_name);
 }
 
+void Element::DefaultEventHandler(Event& event) {
+  if (event.type() == event_type_names::kDOMActivate) {
+    // IsFocusableStyleAfterUpdate() may change the result of
+    // GetComputedStyle(), but it's also potentially expensive and we only
+    // want to call it if we have a toggle-trigger.
+    if (const ComputedStyle* style_before_update = GetComputedStyle()) {
+      if (style_before_update->ToggleTrigger() &&
+          IsFocusableStyleAfterUpdate() &&
+          !IsClickableControl(event.target()->ToNode())) {
+        if (const ComputedStyle* style = GetComputedStyle()) {
+          if (const ToggleTriggerList* toggle_triggers =
+                  style->ToggleTrigger()) {
+            for (const ToggleTrigger& trigger : toggle_triggers->Triggers()) {
+              FireToggleActivation(trigger);
+            }
+          }
+        }
+      }
+    }
+  }
+
+  ContainerNode::DefaultEventHandler(event);
+}
+
 bool Element::DelegatesFocus() const {
   return AuthorShadowRoot() && AuthorShadowRoot()->delegatesFocus();
 }
@@ -5812,6 +5957,23 @@
          FastHasAttribute(html_names::kAutofocusAttr);
 }
 
+bool Element::IsClickableControl(Node* node) {
+  auto* element = DynamicTo<Element>(node);
+  if (!element)
+    return false;
+  if (element->IsFormControlElement())
+    return true;
+  Element* host = element->OwnerShadowHost();
+  if (host && host->IsFormControlElement())
+    return true;
+  while (node && this != node) {
+    if (node->HasActivationBehavior())
+      return true;
+    node = node->ParentOrShadowHostNode();
+  }
+  return false;
+}
+
 bool Element::ActivateDisplayLockIfNeeded(DisplayLockActivationReason reason) {
   auto& state = GetDocument().GetDisplayLockDocumentState();
   state.UnlockShapingDeferredElements(*this);
diff --git a/third_party/blink/renderer/core/dom/element.h b/third_party/blink/renderer/core/dom/element.h
index 50f5ab2..b3fb8cd 100644
--- a/third_party/blink/renderer/core/dom/element.h
+++ b/third_party/blink/renderer/core/dom/element.h
@@ -575,6 +575,8 @@
   // attributes in a start tag were added to the element.
   virtual void ParseAttribute(const AttributeModificationParams&);
 
+  void DefaultEventHandler(Event&) override;
+
   // Popup API related functions.
   void UpdatePopupAttribute(String);
   bool HasValidPopupAttribute() const;
@@ -601,7 +603,10 @@
                                  HidePopupFocusBehavior,
                                  HidePopupForcingLevel,
                                  HidePopupIndependence);
-  void MaybeTriggerHoverPopup(Element* popup_element);
+  Element* HoverPopupElement() const;
+  bool IsNodePopUpDescendant(const Node& node) const;
+  void MaybeQueuePopupHideEvent();
+  static void HoveredElementChanged(Element* old_element, Element* new_element);
   void HandlePopupHovered(bool hovered);
 
   // TODO(crbug.com/1197720): The popup position should be provided by the new
@@ -1276,6 +1281,10 @@
   // work to create layout objects is completed (e.g. in display-locked trees).
   bool IsFocusableStyleAfterUpdate() const;
 
+  // Is the node descendant of this in something clickable/activatable, such
+  // that we shouldn't handle events targeting it?
+  bool IsClickableControl(Node*);
+
   // ClassAttributeChanged() and UpdateClassList() exist to share code between
   // ParseAttribute (called via setAttribute()) and SvgAttributeChanged (called
   // when element.className.baseVal is set or when the 'class' attribute is
diff --git a/third_party/blink/renderer/core/dom/popup_data.h b/third_party/blink/renderer/core/dom/popup_data.h
index d49b7ef..d6123f5 100644
--- a/third_party/blink/renderer/core/dom/popup_data.h
+++ b/third_party/blink/renderer/core/dom/popup_data.h
@@ -81,10 +81,16 @@
     animation_finished_listener_ = listener;
   }
 
-  HeapHashMap<WeakMember<Element>, TaskHandle>& hoverPopupTasks() {
+  HeapHashMap<WeakMember<const Element>, TaskHandle>& hoverPopupTasks() {
     return hover_popup_tasks_;
   }
 
+  void setHoverHideTask(TaskHandle&& task) {
+    if (hover_hide_task_.IsActive())
+      hover_hide_task_.Cancel();
+    hover_hide_task_ = std::move(task);
+  }
+
   HTMLSelectMenuElement* ownerSelectMenuElement() const {
     return owner_select_menu_element_;
   }
@@ -110,9 +116,11 @@
   // We hold a strong reference to the animation finished listener, so that we
   // can confirm that the listeners get removed before cleanup.
   Member<PopupAnimationFinishedEventListener> animation_finished_listener_;
-  // Map from triggering elements to a TaskHandle for the task that will invoke
-  // the pop-up.
-  HeapHashMap<WeakMember<Element>, TaskHandle> hover_popup_tasks_;
+  // Map from elements with the 'hoverpopup' attribute to a task that will show
+  // the pop-up after a delay.
+  HeapHashMap<WeakMember<const Element>, TaskHandle> hover_popup_tasks_;
+  // A task that hide the pop-up after a delay.
+  TaskHandle hover_hide_task_;
 
   // TODO(crbug.com/1197720): The popup position should be provided by the new
   // anchored positioning scheme.
diff --git a/third_party/blink/renderer/core/frame/attribution_src_loader.cc b/third_party/blink/renderer/core/frame/attribution_src_loader.cc
index c1b0cc2..1a153aee 100644
--- a/third_party/blink/renderer/core/frame/attribution_src_loader.cc
+++ b/third_party/blink/renderer/core/frame/attribution_src_loader.cc
@@ -410,7 +410,7 @@
     absl::optional<net::structured_headers::Dictionary> dict =
         net::structured_headers::ParseDictionary(
             StringUTF8Adaptor(header_value).AsStringPiece());
-    if (!dict) {
+    if (!dict || dict->contains(kAttributionEligibleNavigationSource)) {
       LogAuditIssue(local_frame_->DomWindow(),
                     AttributionReportingIssueType::kInvalidEligibleHeader,
                     /*element=*/nullptr, request_id,
@@ -420,14 +420,10 @@
 
     const bool allows_event_source =
         dict->contains(kAttributionEligibleEventSource);
-    const bool allows_navigation_source =
-        dict->contains(kAttributionEligibleNavigationSource);
     const bool allows_trigger = dict->contains(kAttributionEligibleTrigger);
 
     // TODO(johnidel): Consider logging a devtools issue here for early exits.
-    if (allows_navigation_source) {
-      return false;
-    } else if (allows_event_source && allows_trigger) {
+    if (allows_event_source && allows_trigger) {
       // We use an undetermined SrcType which indicates either a source or
       // trigger may be registered.
       src_type = SrcType::kUndetermined;
diff --git a/third_party/blink/renderer/core/html/html_summary_element.cc b/third_party/blink/renderer/core/html/html_summary_element.cc
index 738341a..472ba4c 100644
--- a/third_party/blink/renderer/core/html/html_summary_element.cc
+++ b/third_party/blink/renderer/core/html/html_summary_element.cc
@@ -63,23 +63,6 @@
   return false;
 }
 
-bool HTMLSummaryElement::IsClickableControl(Node* node) {
-  auto* element = DynamicTo<Element>(node);
-  if (!element)
-    return false;
-  if (element->IsFormControlElement())
-    return true;
-  Element* host = element->OwnerShadowHost();
-  if (host && host->IsFormControlElement())
-    return true;
-  while (node && this != node) {
-    if (node->HasActivationBehavior())
-      return true;
-    node = node->ParentOrShadowHostNode();
-  }
-  return false;
-}
-
 bool HTMLSummaryElement::SupportsFocus() const {
   return IsMainSummary() || HTMLElement::SupportsFocus();
 }
diff --git a/third_party/blink/renderer/core/html/html_summary_element.h b/third_party/blink/renderer/core/html/html_summary_element.h
index 40233df..0a2c049562 100644
--- a/third_party/blink/renderer/core/html/html_summary_element.h
+++ b/third_party/blink/renderer/core/html/html_summary_element.h
@@ -42,7 +42,6 @@
 
   bool SupportsFocus() const override;
   int DefaultTabIndex() const override;
-  bool IsClickableControl(Node*);
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc
index bc69428..cd0238a 100644
--- a/third_party/blink/renderer/core/loader/document_loader.cc
+++ b/third_party/blink/renderer/core/loader/document_loader.cc
@@ -1275,13 +1275,11 @@
   DCHECK(!IsReloadLoadType(frame_load_type));
   DCHECK(frame_->GetDocument());
   DCHECK(!is_browser_initiated || !is_synchronously_committed);
+  CHECK(frame_->IsNavigationAllowed());
 
   if (Page* page = frame_->GetPage())
     page->HistoryNavigationVirtualTimePauser().UnpauseVirtualTime();
 
-  if (!frame_->IsNavigationAllowed())
-    return mojom::blink::CommitResult::Aborted;
-
   if (frame_->GetDocument()->IsFrameSet()) {
     // Navigations in a frameset are always cross-document. Renderer-initiated
     // navigations in a frameset will be deferred to the browser, and all
diff --git a/third_party/blink/renderer/core/style/computed_style_constants.h b/third_party/blink/renderer/core/style/computed_style_constants.h
index eb81590..2306221 100644
--- a/third_party/blink/renderer/core/style/computed_style_constants.h
+++ b/third_party/blink/renderer/core/style/computed_style_constants.h
@@ -248,13 +248,12 @@
   return a = a | b;
 }
 
-static const size_t kContainerTypeBits = 3;
+static const size_t kContainerTypeBits = 2;
 enum EContainerType {
   kContainerTypeNormal = 0x0,
   kContainerTypeInlineSize = 0x1,
   kContainerTypeBlockSize = 0x2,
   kContainerTypeSize = kContainerTypeInlineSize | kContainerTypeBlockSize,
-  kContainerTypeStyle = 0x4,
 };
 inline EContainerType operator|(EContainerType a, EContainerType b) {
   return EContainerType(int(a) | int(b));
diff --git a/third_party/blink/renderer/core/style/toggle_root.h b/third_party/blink/renderer/core/style/toggle_root.h
index 6219180..0b7e3c1 100644
--- a/third_party/blink/renderer/core/style/toggle_root.h
+++ b/third_party/blink/renderer/core/style/toggle_root.h
@@ -125,7 +125,7 @@
   bool operator!=(const ToggleRoot& other) const { return !(*this == other); }
 
   const AtomicString& Name() const { return name_; }
-  States StateSet() const { return states_; }
+  const States& StateSet() const { return states_; }
   State InitialState() const { return value_; }
   ToggleOverflow Overflow() const { return overflow_; }
   bool IsGroup() const { return is_group_; }
diff --git a/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc b/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc
index 6f2aa15..f90f2902 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc
@@ -82,6 +82,18 @@
   }
 }
 
+void AXMenuList::SetNeedsToUpdateChildren() const {
+  if (!children_.IsEmpty()) {
+    if (AXObject* child_popup = children_[0]) {
+      // If we have a child popup, update its children at the same time.
+      DCHECK(IsA<AXMenuListPopup>(child_popup));
+      child_popup->SetNeedsToUpdateChildren();
+    }
+  }
+
+  AXObject::SetNeedsToUpdateChildren();
+}
+
 void AXMenuList::ClearChildren() const {
   if (children_.IsEmpty())
     return;
diff --git a/third_party/blink/renderer/modules/accessibility/ax_menu_list.h b/third_party/blink/renderer/modules/accessibility/ax_menu_list.h
index efdc162..0cceefb 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_menu_list.h
+++ b/third_party/blink/renderer/modules/accessibility/ax_menu_list.h
@@ -41,6 +41,7 @@
 
   AccessibilityExpanded IsExpanded() const final;
   bool OnNativeClickAction() override;
+  void SetNeedsToUpdateChildren() const override;
   void ClearChildren() const override;
   void Detach() override;
 
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.h b/third_party/blink/renderer/modules/accessibility/ax_object.h
index e204c79..8cee3c4 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object.h
+++ b/third_party/blink/renderer/modules/accessibility/ax_object.h
@@ -1137,7 +1137,7 @@
   virtual bool CanHaveChildren() const { return true; }
   void UpdateChildrenIfNecessary();
   bool NeedsToUpdateChildren() const;
-  void SetNeedsToUpdateChildren() const;
+  virtual void SetNeedsToUpdateChildren() const;
   virtual void ClearChildren() const;
   void DetachFromParent() { parent_ = nullptr; }
   virtual void SelectedOptions(AXObjectVector&) const {}
diff --git a/third_party/blink/renderer/modules/mediasource/media_source.cc b/third_party/blink/renderer/modules/mediasource/media_source.cc
index d1ae754..756e357 100644
--- a/third_party/blink/renderer/modules/mediasource/media_source.cc
+++ b/third_party/blink/renderer/modules/mediasource/media_source.cc
@@ -582,12 +582,58 @@
     return false;
   }
 
+  String codecs = content_type.Parameter("codecs");
+  ContentType filtered_content_type = content_type;
+
+#if BUILDFLAG(ENABLE_PLATFORM_ENCRYPTED_DOLBY_VISION)
+  // Here, we special-case when encrypted Dolby Vision (DV) is supported but
+  // clear DV is not supported. isTypeSupported(fully qualified type with DV
+  // codec) should say false on such platform, but addSourceBuffer(same) and
+  // changeType(same) shouldn't fail just due to having DV codec. We use
+  // `enforce_codec_specificity` to understand if we are servicing
+  // isTypeSupported (if true) vs addSourceBuffer or changeType (if false). When
+  // `enforce_codec_specificity` is false, we'll remove any detected DV codec
+  // from the codecs in the `filtered_content_type`.
+  if (!enforce_codec_specificity) {
+    // Remove any detected DolbyVision codec from the query to GetSupportsType.
+    std::string filtered_codecs;
+    std::vector<std::string> parsed_codec_ids;
+    media::SplitCodecs(codecs.Ascii(), &parsed_codec_ids);
+    bool first = true;
+    for (const auto& codec_id : parsed_codec_ids) {
+      bool is_codec_ambiguous;
+      media::VideoCodec video_codec = media::VideoCodec::kUnknown;
+      media::VideoCodecProfile profile;
+      uint8_t level = 0;
+      media::VideoColorSpace color_space;
+      if (media::ParseVideoCodecString(mime_type.Ascii(), codec_id,
+                                       &is_codec_ambiguous, &video_codec,
+                                       &profile, &level, &color_space) &&
+          !is_codec_ambiguous &&
+          video_codec == media::VideoCodec::kDolbyVision) {
+        continue;
+      }
+      if (first)
+        first = false;
+      else
+        filtered_codecs += ",";
+      filtered_codecs += codec_id;
+    }
+
+    std::string filtered_type =
+        mime_type.Ascii() + "; codecs=\"" + filtered_codecs + "\"";
+    DVLOG(1) << __func__ << " filtered_type=" << filtered_type;
+    filtered_content_type =
+        ContentType(String::FromUTF8(filtered_type.c_str()));
+  }
+#endif  // BUILDFLAG(ENABLE_PLATFORM_ENCRYPTED_DOLBY_VISION)
+
   // Note: MediaSource.isTypeSupported() returning true implies that
   // HTMLMediaElement.canPlayType() will return "maybe" or "probably" since it
   // does not make sense for a MediaSource to support a type the
   // HTMLMediaElement knows it cannot play.
   auto get_supports_type_result =
-      HTMLMediaElement::GetSupportsType(content_type);
+      HTMLMediaElement::GetSupportsType(filtered_content_type);
   if (get_supports_type_result == MIMETypeRegistry::kNotSupported) {
     DVLOG(1) << __func__ << "(" << type << ", "
              << (enforce_codec_specificity ? "true" : "false")
@@ -612,7 +658,6 @@
   // specificity is and will be retained for isTypeSupported.
   // TODO(crbug.com/535738): Actually relax the codec-specifity for aSB() and
   // cT() (which is when |enforce_codec_specificity| is false).
-  String codecs = content_type.Parameter("codecs");
   MIMETypeRegistry::SupportsType supported =
       MIMETypeRegistry::SupportsMediaSourceMIMEType(mime_type, codecs);
 
diff --git a/third_party/blink/renderer/platform/media/key_system_config_selector.cc b/third_party/blink/renderer/platform/media/key_system_config_selector.cc
index 5c8583f6..fe8070f 100644
--- a/third_party/blink/renderer/platform/media/key_system_config_selector.cc
+++ b/third_party/blink/renderer/platform/media/key_system_config_selector.cc
@@ -150,6 +150,32 @@
   std::vector<std::string> codec_vector;
   media::SplitCodecs(codecs, &codec_vector);
 
+#if BUILDFLAG(ENABLE_PLATFORM_ENCRYPTED_DOLBY_VISION)
+  // Encrypted DolbyVision (DV) is supported under this build flag, but it is
+  // not supported for clear playback or when using ClearKey. Remove the DV
+  // codec strings to avoid asking IsSupported*MediaFormat() about DV. EME
+  // support for DV is described via KeySystemProperties::GetSupportedCodecs().
+  // TODO(crbug.com/1156282): Decouple the rest of clear vs EME codec support.
+  if (!use_aes_decryptor &&
+      base::ToLowerASCII(container_mime_type) == "video/mp4" &&
+      !codec_vector.empty()) {
+    std::vector<std::string> filtered_codec_vector;
+    for (const auto& codec : codec_vector) {
+      media::VideoCodecProfile profile;
+      uint8_t level_idc;
+      if (!ParseDolbyVisionCodecId(codec, &profile, &level_idc))
+        filtered_codec_vector.push_back(codec);
+    }
+    codec_vector = std::move(filtered_codec_vector);
+
+    // Avoid calling IsSupported*MediaFormat() with an empty vector. For
+    // "video/mp4", this will return MaybeSupported, which we would otherwise
+    // consider "false" below.
+    if (codec_vector.empty())
+      return true;
+  }
+#endif  // BUILDFLAG(ENABLE_PLATFORM_ENCRYPTED_DOLBY_VISION)
+
   // AesDecryptor decrypts the stream in the demuxer before it reaches the
   // decoder so check whether the media format is supported when clear.
   media::SupportsType support_result =
diff --git a/third_party/blink/renderer/platform/scheduler/BUILD.gn b/third_party/blink/renderer/platform/scheduler/BUILD.gn
index 68f2b26..7ace185 100644
--- a/third_party/blink/renderer/platform/scheduler/BUILD.gn
+++ b/third_party/blink/renderer/platform/scheduler/BUILD.gn
@@ -6,6 +6,10 @@
 import("//third_party/blink/renderer/platform/platform.gni")
 import("//third_party/protobuf/proto_library.gni")
 
+if (is_android) {
+  import("//build/config/android/rules.gni")
+}
+
 blink_platform_sources("scheduler") {
   sources = [
     "common/back_forward_cache_disabling_feature_tracker.cc",
@@ -329,3 +333,19 @@
 proto_library("sequence_manager_test_description_proto") {
   sources = [ "test/fuzzer/proto/sequence_manager_test_description.proto" ]
 }
+
+if (is_android) {
+  java_cpp_features("java_features_srcjar") {
+    # External code should depend on ":blink_scheduler_java" instead.
+    visibility = [ ":*" ]
+    sources =
+        [ "//third_party/blink/renderer/platform/scheduler/common/features.cc" ]
+    template = "//third_party/blink/renderer/platform/scheduler/common/android/java_templates/BlinkSchedulerFeatures.java.tmpl"
+  }
+
+  android_library("blink_scheduler_java") {
+    # Right now, this only includes the Java features. But if we need more Java
+    # files, they should be added here as necessary.
+    srcjar_deps = [ ":java_features_srcjar" ]
+  }
+}
diff --git a/third_party/blink/renderer/platform/scheduler/common/android/java_templates/BlinkSchedulerFeatures.java.tmpl b/third_party/blink/renderer/platform/scheduler/common/android/java_templates/BlinkSchedulerFeatures.java.tmpl
new file mode 100644
index 0000000..ebc5515
--- /dev/null
+++ b/third_party/blink/renderer/platform/scheduler/common/android/java_templates/BlinkSchedulerFeatures.java.tmpl
@@ -0,0 +1,16 @@
+// 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.blink_scheduler;
+
+/**
+ * Constants for the names of Blink Scheduler Features.
+ */
+public final class BlinkSchedulerFeatures {{
+
+{NATIVE_FEATURES}
+
+    // Do not instantiate this class.
+    private BlinkSchedulerFeatures() {{}}
+}}
diff --git a/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility b/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility
index 0e10d7d..dec96f5 100644
--- a/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility
+++ b/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility
@@ -56,7 +56,7 @@
 fast/forms/month/month-picker-ax.html [ Skip ]
 fast/forms/select-popup/popup-menu-appearance-texttransform.html [ Skip ]
 fast/forms/suggested-value.html [ Skip ]
-fast/loader/iframe-navigation-stealing-focus.html [ Timeout Pass ]
+fast/loader/iframe-navigation-stealing-focus.html [ Pass Timeout ]
 fast/spatial-navigation/snav-div-in-anchor.html [ Skip ]
 http/tests/devtools/console/console-format.js [ Skip ]
 http/tests/inspector-protocol/accessibility/accessibility-ignoredNodesModal.js [ Skip ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index fe30dcca1..776d191 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -5026,15 +5026,6 @@
 crbug.com/1008483 virtual/backface-visibility-interop/paint/invalidation/stacking-context-lost.html [ Failure ]
 crbug.com/1008483 virtual/backface-visibility-interop/paint/invalidation/multicol/multicol-as-paint-container.html [ Failure ]
 
-# TODO(https://crbug.com/1250716): These tests are being added as part of the
-# CL with the code relevant for them, but they need all of the current set of
-# CLs to land before they can pass.  So they are temporarily (within this
-# patch stack) marked as failing, and will be unmarked in the final patch.
-crbug.com/1250716 external/wpt/css/css-toggle/toggle-creation.tentative.html [ Failure ]
-crbug.com/1250716 external/wpt/css/css-toggle/toggle-activation.tentative.html [ Failure ]
-crbug.com/1250716 external/wpt/css/css-toggle/toggle-activation-with-groups.tentative.html [ Failure ]
-crbug.com/1250716 external/wpt/css/css-toggle/toggle-pseudo-class.tentative.html [ Failure ]
-
 # Swiftshader issue.
 crbug.com/1048149 external/wpt/html/browsers/the-window-object/open-close/open-features-non-integer-innerwidth.html [ Crash Timeout ]
 crbug.com/1048149 external/wpt/html/browsers/the-window-object/open-close/open-features-non-integer-screeny.html [ Crash Timeout ]
diff --git a/third_party/blink/web_tests/external/Version b/third_party/blink/web_tests/external/Version
index 1f76a67..d1f3986 100644
--- a/third_party/blink/web_tests/external/Version
+++ b/third_party/blink/web_tests/external/Version
@@ -1 +1 @@
-Version: 74bb58e7a47f364354407fc102c89aa7ad1ccf58
+Version: 9f072679c6f3367ea1685254ff5f5cc84f6e8d9d
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 4831d4bb..43321cd 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
@@ -152304,6 +152304,19 @@
        {}
       ]
      ],
+     "highlight-painting-soft-hyphens-001.html": [
+      "17b5f6a37c4c2489959f41bed4ca53c352a20a4d",
+      [
+       null,
+       [
+        [
+         "/css/css-pseudo/highlight-painting-soft-hyphens-001-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
      "highlight-paired-cascade-001.html": [
       "09e5abf9a3285ff219044a84b61bbc239f405689",
       [
@@ -284093,6 +284106,10 @@
       "39d26e8387204840d89318ef917d5df0c4021df4",
       []
      ],
+     "highlight-painting-soft-hyphens-001-ref.html": [
+      "f1485ca9226683ac303facb5dadbd38b475c042e",
+      []
+     ],
      "highlight-paired-cascade-001-ref.html": [
       "14687acb841d2b85becead81a0c82b4e4b5b8e9d",
       []
@@ -290982,6 +290999,12 @@
         []
        ]
       }
+     },
+     "support": {
+      "toggle-helpers.js": [
+       "098bf481a169ba920622eb2c5a69bdb81011563e",
+       []
+      ]
      }
     },
     "css-transforms": {
@@ -299309,7 +299332,7 @@
      []
     ],
     "META.yml": [
-     "b8dd4761adff3e18b6552d4a8f02abdcd30a3ea6",
+     "390013487f674fd6973762bbae4c46720b89051a",
      []
     ],
     "OWNERS": [
@@ -316510,7 +316533,7 @@
       ],
       "resources": {
        "popup-styles.css": [
-        "2e603066dfb51acca20f8de5b5e2a2631c412b88",
+        "1a99019f060dfc5218eb42904893ebf3366b8ded",
         []
        ],
        "popup-utils.js": [
@@ -390429,7 +390452,7 @@
        ]
       ],
       "auto-005.html": [
-       "4a920ac806006524bea9f12f3e0d41ff4aa5d4dc",
+       "2b7e03192dc701ebc675a79646cd683fe25081c6",
        [
         null,
         {}
@@ -394361,6 +394384,34 @@
        ]
       ]
      },
+     "toggle-activation-with-groups.tentative.html": [
+      "d026ab368e00eff2157dd07989b7f5480fe590b7",
+      [
+       null,
+       {}
+      ]
+     ],
+     "toggle-activation.tentative.html": [
+      "b087f07fd8109ab52bf7e786442e95d63f54316f",
+      [
+       null,
+       {}
+      ]
+     ],
+     "toggle-creation.tentative.html": [
+      "583e1631d3c8da97bd8682415507d8c306ec08db",
+      [
+       null,
+       {}
+      ]
+     ],
+     "toggle-pseudo-class.tentative.html": [
+      "7fb5c26d91b847dab9f3fa597bbab535fc38afe3",
+      [
+       null,
+       {}
+      ]
+     ],
      "toggle-shorthand-serialization.tentative.html": [
       "682945c2e2bf930f8cbba606a1c7e7be37d6e7a4",
       [
@@ -591058,6 +591109,20 @@
        null,
        {}
       ]
+     ],
+     "nested-multicol-with-spanner-and-oof-crash-004.html": [
+      "5db9163398a7fcbcf1ec76b69471d83891ece3bf",
+      [
+       null,
+       {}
+      ]
+     ],
+     "nested-multicol-with-spanner-and-oof-crash-005.html": [
+      "f7b56c1c985f43dca8b8849d78a8bba95f7a7b94",
+      [
+       null,
+       {}
+      ]
      ]
     },
     "css-counter-styles": {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/container-computed.html b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/container-computed.html
index d83f361..2be3044 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/container-computed.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/container-computed.html
@@ -18,8 +18,6 @@
 test_computed_value('container', 'none / size');
 test_computed_value('container', 'inline-size / inline-size');
 test_computed_value('container', 'block-size / size');
-test_computed_value('container', 'name / size style', 'name / style size');
-test_computed_value('container', 'name /inline-size style', 'name / style inline-size');
 test_computed_value('container', 'foo / inline-size');
 test_computed_value('container', 'foo /inline-size', 'foo / inline-size');
 test_computed_value('container', 'foo/ inline-size', 'foo / inline-size');
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/container-parsing.html b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/container-parsing.html
index 9f1293f5..44989c2 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/container-parsing.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/container-parsing.html
@@ -23,7 +23,6 @@
 test_valid_value('container', 'block-size / size');
 test_valid_value('container', 'inline-size / inline-size');
 test_valid_value('container', 'size / size');
-test_valid_value('container', 'none / size style', 'none / style size');
 test_valid_value('container', 'foo');
 test_valid_value('container', 'foo / normal', 'foo');
 test_valid_value('container', 'foo bar / size');
@@ -60,4 +59,5 @@
 test_invalid_value('container', ' NAME  / block-size', 'NAME / block-size');
 test_invalid_value('container', 'NAME/block-size','NAME / block-size');
 test_invalid_value('container', 'block-size / block-size');
+test_invalid_value('container', 'none / size style');
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/container-type-parsing.html b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/container-type-parsing.html
index 34023cbc..5805a92 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/container-type-parsing.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/container-type-parsing.html
@@ -15,14 +15,9 @@
 test_valid_value('container-type', 'unset');
 test_valid_value('container-type', 'revert');
 test_valid_value('container-type', 'normal');
-test_valid_value('container-type', 'style');
 test_valid_value('container-type', 'size');
 test_valid_value('container-type', 'inline-size');
 
-test_valid_value('container-type', 'inline-size style', 'style inline-size');
-test_valid_value('container-type', 'style inline-size');
-test_valid_value('container-type', 'style size');
-
 test_invalid_value('container-type', 'none');
 test_invalid_value('container-type', 'auto');
 test_invalid_value('container-type', 'block-size');
@@ -42,4 +37,8 @@
 test_invalid_value('container-type', '1px');
 test_invalid_value('container-type', 'default');
 test_invalid_value('container-type', 'size nonsense');
+test_invalid_value('container-type', 'style');
+test_invalid_value('container-type', 'inline-size style', 'style inline-size');
+test_invalid_value('container-type', 'style inline-size');
+test_invalid_value('container-type', 'style size');
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-typed-om/the-stylepropertymap/properties/container-type.html b/third_party/blink/web_tests/external/wpt/css/css-typed-om/the-stylepropertymap/properties/container-type.html
index c823ffb..23474abf 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-typed-om/the-stylepropertymap/properties/container-type.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-typed-om/the-stylepropertymap/properties/container-type.html
@@ -15,11 +15,6 @@
   { syntax: 'normal' },
   { syntax: 'size' },
   { syntax: 'inline-size' },
-  { syntax: 'style' },
-]);
-
-runUnsupportedPropertyTests('container-type', [
-  'inline-size style',
 ]);
 
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/device-memory/META.yml b/third_party/blink/web_tests/external/wpt/device-memory/META.yml
index b8dd476..3900134 100644
--- a/third_party/blink/web_tests/external/wpt/device-memory/META.yml
+++ b/third_party/blink/web_tests/external/wpt/device-memory/META.yml
@@ -1,3 +1,3 @@
-spec: https://w3c.github.io/device-memory/
+spec: https://www.w3.org/TR/device-memory/
 suggested_reviewers:
   - npm1
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/popups/popup-hover-hide.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/popups/popup-hover-hide.tentative.html
new file mode 100644
index 0000000..e04c538f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/popups/popup-hover-hide.tentative.html
@@ -0,0 +1,128 @@
+<!DOCTYPE html>
+<meta charset="utf-8" />
+<title>The pop-up-hide-delay CSS property</title>
+<link rel="author" href="mailto:masonf@chromium.org">
+<link rel=help href="https://open-ui.org/components/popup.research.explainer">
+<meta name="timeout" content="long">
+<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/popup-utils.js"></script>
+
+<style>
+  [popup] {
+    top:100px;
+    hover-pop-up-hide-delay: 100ms;
+  }
+  [hoverpopup] {
+    top:200px;
+    hover-pop-up-delay: 100ms;
+  }
+  #unrelated {top: 300px;}
+  div {
+    /* Fixed position everything to ensure nothing overlaps */
+    position: fixed;
+  }
+</style>
+<div id=unrelated>Unrelated element</div>
+
+<div popup id=example1>Pop-up</div>
+<div hoverpopup=example1 id=invoker1>Hover me</div>
+
+<script>
+const hoverDelays = 100; // This needs to match the style block above.
+const hoverWaitTime = 200; // How long to wait to cover the delay for sure.
+
+// NOTE about testing methodology:
+// This test checks whether pop-ups are hidden *after* the appropriate de-hover
+// delay. The delay used for testing is kept low, to avoid this test taking too
+// long, but that means that sometimes on a slow bot/client, the delay can
+// elapse before we are able to check the pop-up status. And that can make this
+// test flaky. To avoid that, the msSinceMouseOver() function is used to check
+// that not-too-much time has passed, and if it has, the test is simply skipped.
+
+const unrelated = document.getElementById('unrelated');
+
+function getComputedStyleTimeMs(element,property) {
+  // Times are in seconds, so just strip off the 's'.
+  return Number(getComputedStyle(element)[property].slice(0,-1))*1000;
+}
+
+promise_test(async (t) => {
+  await mouseOver(unrelated);
+  const popUp = document.getElementById('example1');
+  assert_false(popUp.matches(':top-layer'));
+  popUp.showPopUp();
+  assert_true(popUp.matches(':top-layer'));
+  await waitForHoverTime(hoverWaitTime);
+  assert_false(popUp.matches(':top-layer'));
+  assert_true(msSinceMouseOver() >= hoverWaitTime,'waitForHoverTime should wait the specified time');
+  assert_true(hoverWaitTime > hoverDelays,'hoverDelays is the value from CSS, hoverWaitTime should be longer than that');
+  assert_equals(getComputedStyleTimeMs(invoker1,'hoverPopUpDelay'),hoverDelays,'hover-pop-up-delay is incorrect');
+  assert_equals(getComputedStyleTimeMs(popUp,'hoverPopUpHideDelay'),hoverDelays,'hover-pop-up-hide-delay is incorrect');
+},`The hover-pop-up-hide-delay causes a pop-up to be hidden after a delay`);
+
+promise_test(async (t) => {
+  await mouseOver(unrelated);
+  const popUp = document.getElementById('example1');
+  assert_false(popUp.matches(':top-layer'));
+  popUp.showPopUp();
+  await mouseOver(popUp);
+  await waitForHoverTime(hoverWaitTime);
+  assert_true(popUp.matches(':top-layer'),'hovering the pop-up should keep it showing');
+  await mouseOver(unrelated);
+  let showing = popUp.matches(':top-layer');
+  if (msSinceMouseOver() >= hoverDelays)
+    return; // The WPT runner was too slow.
+  assert_true(showing,'hovering unrelated element shouldn\'t immediately hide the pop-up');
+  await waitForHoverTime(hoverWaitTime);
+  assert_false(popUp.matches(':top-layer'),'hovering unrelated element should hide pop-up after delay');
+},`hovering the pop-up keeps it from being hidden`);
+
+promise_test(async (t) => {
+  await mouseOver(unrelated);
+  const popUp = document.getElementById('example1');
+  const invoker = document.getElementById('invoker1');
+  assert_false(popUp.matches(':top-layer'));
+  await mouseOver(invoker);
+  await waitForHoverTime(hoverWaitTime);
+  assert_true(popUp.matches(':top-layer'));
+  await waitForHoverTime(hoverWaitTime);
+  assert_true(popUp.matches(':top-layer'),'While still hovering the invoker, pop-up should not be hidden');
+  await mouseOver(popUp);
+  await waitForHoverTime(hoverWaitTime);
+  await mouseOver(invoker);
+  await waitForHoverTime(hoverWaitTime);
+  assert_true(popUp.matches(':top-layer'),'Moving hover between invoker and pop-up should keep pop-up from being hidden');
+  await mouseOver(unrelated);
+  await waitForHoverTime(hoverWaitTime);
+  assert_false(popUp.matches(':top-layer'),'Moving hover to unrelated should finally hide the pop-up');
+},`hovering a hoverpopup invoking element keeps the pop-up from being hidden`);
+</script>
+
+<div popup id=example2>Pop-up</div>
+<button popuptoggletarget=example2><span><span data-note=nested_element id=invoker2>Click me</span></span></button>
+
+<script>
+promise_test(async (t) => {
+  await mouseOver(unrelated);
+  const popUp = document.getElementById('example2');
+  const invoker = document.getElementById('invoker2');
+  assert_equals(getComputedStyleTimeMs(popUp,'hoverPopUpHideDelay'),hoverDelays,'hover-pop-up-hide-delay is incorrect');
+  assert_false(popUp.matches(':top-layer'));
+  await mouseOver(invoker);
+  popUp.showPopUp();
+  await waitForHoverTime(hoverWaitTime);
+  assert_true(popUp.matches(':top-layer'),'While hovering an invoker element, pop-up should not be hidden');
+  await mouseOver(popUp);
+  await waitForHoverTime(hoverWaitTime);
+  await mouseOver(invoker);
+  await waitForHoverTime(hoverWaitTime);
+  assert_true(popUp.matches(':top-layer'),'Moving hover between invoker and pop-up should keep pop-up from being hidden');
+  await mouseOver(unrelated);
+  await waitForHoverTime(hoverWaitTime);
+  assert_false(popUp.matches(':top-layer'),'Moving hover to unrelated should finally hide the pop-up');
+},`hovering a popuptoggletarget invoking element keeps the pop-up from being hidden`);
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/popups/popup-hoverpopup-attribute.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/popups/popup-hoverpopup-attribute.tentative.html
index 3f1ce38..b34e6df 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/popups/popup-hoverpopup-attribute.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/popups/popup-hoverpopup-attribute.tentative.html
@@ -18,6 +18,7 @@
 [popup] {top: 200px;}
 .offset-child {top:300px; left:300px;}
 </style>
+
 <script>
 const hoverPopUpDelay = 100; // The CSS delay setting.
 const hoverWaitTime = 200; // How long to wait to cover the delay for sure.
@@ -30,8 +31,10 @@
   let invoker = document.createElement('div');
   invoker.setAttribute('class','invoker');
   invoker.setAttribute('hoverpopup',popUp.id);
-  invoker.setAttribute('style',`hover-pop-up-delay: ${delayMs}ms;`);
+  invoker.setAttribute('style',`hover-pop-up-delay: ${delayMs}ms; hover-pop-up-hide-delay: 1000s;`);
   document.body.appendChild(invoker);
+  const actualHoverDelay = Number(getComputedStyle(invoker)['hoverPopUpDelay'].slice(0,-1))*1000;
+  assert_equals(actualHoverDelay,delayMs,'hover-pop-up-delay is incorrect');
   const originalInvoker = invoker;
   const reassignPopupFn = (p) => originalInvoker.setAttribute('hoverpopup',p.id);
   switch (invokerType) {
@@ -75,20 +78,6 @@
   await waitForRender();
   return {popUp,invoker,reassignPopupFn};
 }
-let mouseOverStarted;
-function mouseOver(element) {
-  mouseOverStarted = performance.now();
-  return (new test_driver.Actions())
-    .pointerMove(0, 0, {origin: element})
-    .send();
-}
-function msSinceMouseOver() {
-  return performance.now() - mouseOverStarted;
-}
-async function waitForHoverTime() {
-  await new Promise(resolve => step_timeout(resolve,hoverWaitTime));
-  await waitForRender();
-};
 
 // NOTE about testing methodology:
 // This test checks whether pop-ups are triggered *after* the appropriate hover
@@ -108,10 +97,10 @@
       // See NOTE above.
       if (msSinceMouseOver() < hoverPopUpDelay)
         assert_false(showing,'pop-up should not show immediately');
-      await waitForHoverTime();
-      assert_true(hoverWaitTime > hoverPopUpDelay,'hoverPopUpDelay is the CSS setting, hoverWaitTime should be longer than that');
-      assert_true(msSinceMouseOver() >= hoverPopUpDelay,'waitForHoverTime should wait longer than hoverPopUpDelay');
+      await waitForHoverTime(hoverWaitTime);
+      assert_true(msSinceMouseOver() >= hoverWaitTime,'waitForHoverTime should wait the specified time');
       assert_true(popUp.matches(':top-layer'),'pop-up should show after delay');
+      assert_true(hoverWaitTime > hoverPopUpDelay,'hoverPopUpDelay is the CSS setting, hoverWaitTime should be longer than that');
       popUp.hidePopUp(); // Cleanup
     },`hoverpopup attribute shows a pop-up with popup=${type}, invokerType=${invokerType}`);
 
@@ -124,7 +113,7 @@
       if (msSinceMouseOver() >= longerHoverDelay)
         return; // The WPT runner was too slow.
       assert_false(showing,'pop-up should not show immediately');
-      await waitForHoverTime();
+      await waitForHoverTime(hoverWaitTime);
       showing = popUp.matches(':top-layer');
       if (msSinceMouseOver() >= longerHoverDelay)
         return; // The WPT runner was too slow.
@@ -137,7 +126,7 @@
       assert_true(popUp.matches(':top-layer'));
       await mouseOver(invoker);
       assert_true(popUp.matches(':top-layer'),'pop-up should stay showing on mouseover');
-      await waitForHoverTime();
+      await waitForHoverTime(hoverWaitTime);
       assert_true(popUp.matches(':top-layer'),'pop-up should stay showing after delay');
       popUp.hidePopUp(); // Cleanup
     },`hoverpopup attribute does nothing when pop-up is already showing (popup=${type}, invokerType=${invokerType})`);
@@ -151,11 +140,11 @@
       if (msSinceMouseOver() >= hoverPopUpDelay)
         return; // The WPT runner was too slow.
       assert_false(showing,'pop-up should not show immediately');
-      await waitForHoverTime();
+      await waitForHoverTime(hoverWaitTime);
       assert_false(popUp.matches(':top-layer'),'pop-up should not show even after a delay');
       // Now put it back in the document and make sure it doesn't trigger.
       document.body.appendChild(popUp);
-      await waitForHoverTime();
+      await waitForHoverTime(hoverWaitTime);
       assert_false(popUp.matches(':top-layer'),'pop-up should not show even when returned to the document');
     },`hoverpopup attribute does nothing when pop-up is moved out of the document (popup=${type}, invokerType=${invokerType})`);
 
@@ -171,7 +160,7 @@
       if (msSinceMouseOver() >= hoverPopUpDelay)
         return; // The WPT runner was too slow.
       assert_false(eitherShowing,'pop-up should not show immediately');
-      await waitForHoverTime();
+      await waitForHoverTime(hoverWaitTime);
       assert_false(popUp.matches(':top-layer'),'pop-up #1 should not show since hoverpopup was reassigned');
       assert_false(popUp2.matches(':top-layer'),'pop-up #2 should not show since hoverpopup was reassigned');
     },`hoverpopup attribute does nothing when target changes (popup=${type}, invokerType=${invokerType})`);
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/popups/resources/popup-utils.js b/third_party/blink/web_tests/external/wpt/html/semantics/popups/resources/popup-utils.js
index 886a2302..f91b8cd 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/popups/resources/popup-utils.js
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/popups/resources/popup-utils.js
@@ -27,3 +27,17 @@
   popUp.getAnimations({subtree: true}).forEach(animation => animation.finish());
   await waitForRender();
 }
+let mouseOverStarted;
+function mouseOver(element) {
+  mouseOverStarted = performance.now();
+  return (new test_driver.Actions())
+    .pointerMove(0, 0, {origin: element})
+    .send();
+}
+function msSinceMouseOver() {
+  return performance.now() - mouseOverStarted;
+}
+async function waitForHoverTime(hoverWaitTimeMs) {
+  await new Promise(resolve => step_timeout(resolve,hoverWaitTimeMs));
+  await waitForRender();
+};
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/attribution-reporting/invalid-eligible-header-navigation-source.js b/third_party/blink/web_tests/http/tests/inspector-protocol/attribution-reporting/invalid-eligible-header-navigation-source.js
new file mode 100644
index 0000000..de82ff6
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/attribution-reporting/invalid-eligible-header-navigation-source.js
@@ -0,0 +1,22 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(async function(testRunner) {
+  const {page, dp} = await testRunner.startBlank(
+      `Test that an attributionsrc request whose Attribution-Reporting-Eligible header contains navigation-source triggers an issue.`);
+
+  await dp.Audits.enable();
+  await page.navigate(
+      'https://devtools.test:8443/inspector-protocol/attribution-reporting/resources/impression.html');
+  await page.loadHTML(`<body>`);
+
+  const issuePromise = dp.Audits.onceIssueAdded();
+  await dp.Runtime.evaluate({
+    expression:
+        `fetch('/inspector-protocol/attribution-reporting/resources/register-trigger.php',{headers:{'Attribution-Reporting-Eligible':'navigation-source'}})`,
+  });
+  const issue = await issuePromise;
+  testRunner.log(issue.params.issue, 'Issue reported: ', ['request']);
+  testRunner.completeTest();
+})
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/issues/navigate-event-restore-scroll-issue.js b/third_party/blink/web_tests/http/tests/inspector-protocol/issues/navigate-event-restore-scroll-issue.js
new file mode 100644
index 0000000..05e8eba9
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/issues/navigate-event-restore-scroll-issue.js
@@ -0,0 +1,9 @@
+(async function (testRunner) {
+  const { session, dp } = await testRunner.startBlank(`Tests that NavigateEventRestoreScroll deprecation issue is reported`);
+  await dp.Audits.enable();
+  const promise = dp.Audits.onceIssueAdded();
+  session.evaluate("navigation.onnavigate = e => { e.intercept(); e.restoreScroll(); }; navigation.navigate('#');");
+  const result = await promise;
+  testRunner.log(result.params, "Inspector issue: ");
+  testRunner.completeTest();
+})
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/issues/navigate-event-transition-while-issue.js b/third_party/blink/web_tests/http/tests/inspector-protocol/issues/navigate-event-transition-while-issue.js
new file mode 100644
index 0000000..2fc1867
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/issues/navigate-event-transition-while-issue.js
@@ -0,0 +1,9 @@
+(async function (testRunner) {
+  const { session, dp } = await testRunner.startBlank(`Tests that NavigateEventTransitionWhile deprecation issue is reported`);
+  await dp.Audits.enable();
+  const promise = dp.Audits.onceIssueAdded();
+  session.evaluate("navigation.onnavigate = e => e.transitionWhile(Promise.resolve()); navigation.navigate('#');");
+  const result = await promise;
+  testRunner.log(result.params, "Inspector issue: ");
+  testRunner.completeTest();
+})
diff --git a/third_party/blink/web_tests/platform/generic/http/tests/inspector-protocol/attribution-reporting/invalid-eligible-header-navigation-source-expected.txt b/third_party/blink/web_tests/platform/generic/http/tests/inspector-protocol/attribution-reporting/invalid-eligible-header-navigation-source-expected.txt
new file mode 100644
index 0000000..7a3421a
--- /dev/null
+++ b/third_party/blink/web_tests/platform/generic/http/tests/inspector-protocol/attribution-reporting/invalid-eligible-header-navigation-source-expected.txt
@@ -0,0 +1,12 @@
+Test that an attributionsrc request whose Attribution-Reporting-Eligible header contains navigation-source triggers an issue.
+Issue reported: {
+    code : AttributionReportingIssue
+    details : {
+        attributionReportingIssueDetails : {
+            invalidParameter : navigation-source
+            request : <object>
+            violationType : InvalidEligibleHeader
+        }
+    }
+}
+
diff --git a/third_party/blink/web_tests/platform/generic/http/tests/inspector-protocol/issues/navigate-event-restore-scroll-issue-expected.txt b/third_party/blink/web_tests/platform/generic/http/tests/inspector-protocol/issues/navigate-event-restore-scroll-issue-expected.txt
new file mode 100644
index 0000000..bbd0673
--- /dev/null
+++ b/third_party/blink/web_tests/platform/generic/http/tests/inspector-protocol/issues/navigate-event-restore-scroll-issue-expected.txt
@@ -0,0 +1,21 @@
+Tests that NavigateEventRestoreScroll deprecation issue is reported
+Inspector issue: {
+    issue : {
+        code : DeprecationIssue
+        details : {
+            deprecationIssueDetails : {
+                affectedFrame : {
+                    frameId : <string>
+                }
+                sourceCodeLocation : {
+                    columnNumber : 49
+                    lineNumber : 0
+                    scriptId : <string>
+                    url : 
+                }
+                type : NavigateEventRestoreScroll
+            }
+        }
+    }
+}
+
diff --git a/third_party/blink/web_tests/platform/generic/http/tests/inspector-protocol/issues/navigate-event-transition-while-issue-expected.txt b/third_party/blink/web_tests/platform/generic/http/tests/inspector-protocol/issues/navigate-event-transition-while-issue-expected.txt
new file mode 100644
index 0000000..a61a7d0e
--- /dev/null
+++ b/third_party/blink/web_tests/platform/generic/http/tests/inspector-protocol/issues/navigate-event-transition-while-issue-expected.txt
@@ -0,0 +1,21 @@
+Tests that NavigateEventTransitionWhile deprecation issue is reported
+Inspector issue: {
+    issue : {
+        code : DeprecationIssue
+        details : {
+            deprecationIssueDetails : {
+                affectedFrame : {
+                    frameId : <string>
+                }
+                sourceCodeLocation : {
+                    columnNumber : 32
+                    lineNumber : 0
+                    scriptId : <string>
+                    url : 
+                }
+                type : NavigateEventTransitionWhile
+            }
+        }
+    }
+}
+
diff --git a/third_party/blink/web_tests/platform/generic/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/platform/generic/virtual/stable/webexposed/global-interface-listing-expected.txt
index 42727dc1..8a891fc1 100644
--- a/third_party/blink/web_tests/platform/generic/virtual/stable/webexposed/global-interface-listing-expected.txt
+++ b/third_party/blink/web_tests/platform/generic/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -1496,6 +1496,7 @@
     getter onpointerover
     getter onpointerrawupdate
     getter onpointerup
+    getter onprerenderingchange
     getter onprogress
     getter onratechange
     getter onreadystatechange
@@ -1538,6 +1539,7 @@
     getter pictureInPictureEnabled
     getter plugins
     getter pointerLockElement
+    getter prerendering
     getter readyState
     getter referrer
     getter rootElement
@@ -1699,6 +1701,7 @@
     setter onpointerover
     setter onpointerrawupdate
     setter onpointerup
+    setter onprerenderingchange
     setter onprogress
     setter onratechange
     setter onreadystatechange
@@ -5537,6 +5540,7 @@
     method toJSON
 interface PerformanceNavigationTiming : PerformanceResourceTiming
     attribute @@toStringTag
+    getter activationStart
     getter domComplete
     getter domContentLoadedEventEnd
     getter domContentLoadedEventStart
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 434e815..cf65feb3 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
@@ -1859,6 +1859,7 @@
     getter onpointerover
     getter onpointerrawupdate
     getter onpointerup
+    getter onprerenderingchange
     getter onprogress
     getter onratechange
     getter onreadystatechange
@@ -1902,6 +1903,7 @@
     getter pictureInPictureEnabled
     getter plugins
     getter pointerLockElement
+    getter prerendering
     getter readyState
     getter referrer
     getter rootElement
@@ -2068,6 +2070,7 @@
     setter onpointerover
     setter onpointerrawupdate
     setter onpointerup
+    setter onprerenderingchange
     setter onprogress
     setter onratechange
     setter onreadystatechange
@@ -6481,6 +6484,7 @@
     method toJSON
 interface PerformanceNavigationTiming : PerformanceResourceTiming
     attribute @@toStringTag
+    getter activationStart
     getter domComplete
     getter domContentLoadedEventEnd
     getter domContentLoadedEventStart
diff --git a/third_party/closure_compiler/externs/metrics_private.js b/third_party/closure_compiler/externs/metrics_private.js
index cb6ae7e..37aea13 100644
--- a/third_party/closure_compiler/externs/metrics_private.js
+++ b/third_party/closure_compiler/externs/metrics_private.js
@@ -141,6 +141,14 @@
 
 /**
  * Increments the count associated with the hash of |value| in the sparse
+ * histogram defined by the |metricName| using base::PersistentHash(value).
+ * @param {string} metricName
+ * @param {string} value
+ */
+ chrome.metricsPrivate.recordSparseHashable = function(metricName, value) {};
+
+/**
+ * Increments the count associated with the hash of |value| in the sparse
  * histogram defined by the |metricName| using base::HashMetricName(value).
  * @param {string} metricName
  * @param {string} value
diff --git a/third_party/freetype/README.chromium b/third_party/freetype/README.chromium
index 1f085e3..bb6d224 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-73-gd53c11416
-Revision: d53c114165b152d58b8b86d3c25a2bd27b006136
+Version: VER-2-12-1-74-gdcb5fc5bc
+Revision: dcb5fc5bcd1d73b6510ce20579ccbd8e96b639c5
 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/gvr-android-sdk/BUILD.gn b/third_party/gvr-android-sdk/BUILD.gn
index 7b07a46a..780d68c 100644
--- a/third_party/gvr-android-sdk/BUILD.gn
+++ b/third_party/gvr-android-sdk/BUILD.gn
@@ -55,12 +55,7 @@
   if (enable_chrome_android_internal && !is_official_build) {
     deps = [ "//clank/third_party/gvr_shim" ]
   } else {
-    if (libcxx_is_shared) {
-      cxx_abi_version = "Cr"
-    } else {
-      cxx_abi_version = "1"
-    }
-    library = "//third_party/gvr-android-sdk/libgvr_shim_static_${current_cpu}_${cxx_abi_version}.a"
+    library = "//third_party/gvr-android-sdk/libgvr_shim_static_${current_cpu}_Cr.a"
     libs += [ library ]
 
     if (libcxx_is_shared) {
diff --git a/third_party/gvr-android-sdk/libgvr_shim_static_arm64_1.a.sha1 b/third_party/gvr-android-sdk/libgvr_shim_static_arm64_1.a.sha1
deleted file mode 100644
index 94ff4f6..0000000
--- a/third_party/gvr-android-sdk/libgvr_shim_static_arm64_1.a.sha1
+++ /dev/null
@@ -1 +0,0 @@
-34b8e73adb38effd8b8313e7d40b5f01e92a9832
\ No newline at end of file
diff --git a/third_party/gvr-android-sdk/libgvr_shim_static_arm64_ndk1.a.sha1 b/third_party/gvr-android-sdk/libgvr_shim_static_arm64_ndk1.a.sha1
deleted file mode 100644
index 6479982..0000000
--- a/third_party/gvr-android-sdk/libgvr_shim_static_arm64_ndk1.a.sha1
+++ /dev/null
@@ -1 +0,0 @@
-7177b03a8557fc93f9bb122e5e813a65894e5ca7
\ No newline at end of file
diff --git a/third_party/gvr-android-sdk/libgvr_shim_static_arm_1.a.sha1 b/third_party/gvr-android-sdk/libgvr_shim_static_arm_1.a.sha1
deleted file mode 100644
index f9fadde..0000000
--- a/third_party/gvr-android-sdk/libgvr_shim_static_arm_1.a.sha1
+++ /dev/null
@@ -1 +0,0 @@
-dfb077f18d0bf3b02a2bac00fc112d37a177e56c
\ No newline at end of file
diff --git a/third_party/gvr-android-sdk/libgvr_shim_static_arm_ndk1.a.sha1 b/third_party/gvr-android-sdk/libgvr_shim_static_arm_ndk1.a.sha1
deleted file mode 100644
index 364121f..0000000
--- a/third_party/gvr-android-sdk/libgvr_shim_static_arm_ndk1.a.sha1
+++ /dev/null
@@ -1 +0,0 @@
-c5fef74bcd300424c17d95fc9aebf30f3b4541fa
\ No newline at end of file
diff --git a/third_party/tflite/README.chromium b/third_party/tflite/README.chromium
index 34bd4d3f..7c9e3646 100644
--- a/third_party/tflite/README.chromium
+++ b/third_party/tflite/README.chromium
@@ -1,8 +1,8 @@
 Name: TensorFlow Lite
 Short Name: tflite
 URL: https://github.com/tensorflow/tensorflow
-Version: 66b1a1f6d88f5e205c7001a4b5794a5182abffca
-Date: 2022/07/25
+Version: 179fbbab3fc38152be53b519376f0067736fd934
+Date: 2022/08/02
 License: Apache 2.0
 License File: LICENSE
 Security Critical: Yes
diff --git a/third_party/wayland-protocols/unstable/text-input/text-input-extension-unstable-v1.xml b/third_party/wayland-protocols/unstable/text-input/text-input-extension-unstable-v1.xml
index ca07b25..8fb4856b 100644
--- a/third_party/wayland-protocols/unstable/text-input/text-input-extension-unstable-v1.xml
+++ b/third_party/wayland-protocols/unstable/text-input/text-input-extension-unstable-v1.xml
@@ -24,7 +24,7 @@
     DEALINGS IN THE SOFTWARE.
   </copyright>
 
-  <interface name="zcr_text_input_extension_v1" version="4">
+  <interface name="zcr_text_input_extension_v1" version="5">
     <description summary="extends text_input to support richer operations">
       Allows a text_input to sends more variation of operations to support
       richer features, such as set_preedit_region.
@@ -57,7 +57,7 @@
 
   </interface>
 
-  <interface name="zcr_extended_text_input_v1" version="4">
+  <interface name="zcr_extended_text_input_v1" version="5">
     <description summary="extension of text_input protocol">
       The zcr_extended_text_input_v1 interface extends the text_input interface
       to support more rich operations on text_input.
@@ -259,5 +259,26 @@
       <arg name="height" type="uint" />
     </request>
 
+    <!-- Version 5 -->
+
+    <event name="set_virtual_keyboard_occluded_bounds" since="5">
+      <description summary="Sets the virtual keyboard's occluded bounds.">
+        This event tells the client about the part of the virtual keyboard's
+        bounds that occludes the text input's window, in screen DIP coordinates.
+        In order for the text input to make proper use of this information, it
+        needs to know its window's screen DIP bounds via another interface such
+        as the aura-shell.
+
+        The occluded bounds may be smaller than the keyboard's visual bounds.
+
+        When the virtual keyboard is hidden or floating, empty bounds are sent,
+        i.e. with zero width and height.
+      </description>
+      <arg name="x" type="int"/>
+      <arg name="y" type="int"/>
+      <arg name="width" type="int"/>
+      <arg name="height" type="int"/>
+    </event>
+
   </interface>
 </protocol>
diff --git a/third_party/wpt_tools/update_certs.py b/third_party/wpt_tools/update_certs.py
index 1a9dc17..b75af61 100755
--- a/third_party/wpt_tools/update_certs.py
+++ b/third_party/wpt_tools/update_certs.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env vpython
+#!/usr/bin/env vpython3
 # Copyright 2018 The Chromium Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -18,14 +18,14 @@
 def main():
     cert_dir = os.path.join(_THIS_DIR, 'certs')
 
-    print '===> Removing old files...'
+    print('===> Removing old files...')
     old_files = filter(lambda filename: '.sxg.' not in filename,
                        os.listdir(cert_dir))
     old_files = [os.path.join(cert_dir, fn) for fn in old_files]
     if subprocess.call(['git', 'rm'] + old_files) != 0:
         sys.exit(1)
 
-    print '\n===> Regenerating keys and certificates...'
+    print('\n===> Regenerating keys and certificates...')
     env = OpenSSLEnvironment(logging.getLogger(__name__),
                              base_path=cert_dir,
                              force_regenerate=True,
@@ -42,7 +42,7 @@
         if subprocess.call('git add -v ' + os.path.join(cert_dir, '*'), shell=True) != 0:
             sys.exit(1)
 
-        print '\n===> Updating wpt.config.json and base.py...'
+        print('\n===> Updating wpt.config.json and base.py...')
         key_basename = os.path.basename(key_path)
         pem_basename = os.path.basename(pem_path)
         config_path = os.path.join(_THIS_DIR, 'wpt.config.json')
@@ -65,7 +65,7 @@
         if subprocess.call(['git', 'add', '-v', config_path, base_py_path]) != 0:
             sys.exit(1)
 
-        print '\n===> Certificate validity:'
+        print('\n===> Certificate validity:')
         subprocess.call(['grep', 'Not After', pem_path])
 
 
diff --git a/third_party/xnnpack/BUILD.gn b/third_party/xnnpack/BUILD.gn
index 05e26a0..7339050 100644
--- a/third_party/xnnpack/BUILD.gn
+++ b/third_party/xnnpack/BUILD.gn
@@ -53,6 +53,7 @@
     "src/src/log.c",
     "src/src/memory-planner.c",
     "src/src/memory.c",
+    "src/src/microparams-init.c",
     "src/src/mutex.c",
     "src/src/node-type.c",
     "src/src/normalization.c",
@@ -61,7 +62,6 @@
     "src/src/operator-strings.c",
     "src/src/operator-utils.c",
     "src/src/packing.c",
-    "src/src/params-init.c",
     "src/src/params.c",
     "src/src/runtime.c",
     "src/src/subgraph.c",
diff --git a/third_party/xnnpack/README.chromium b/third_party/xnnpack/README.chromium
index 9653938..4b61fca 100644
--- a/third_party/xnnpack/README.chromium
+++ b/third_party/xnnpack/README.chromium
@@ -1,8 +1,8 @@
 Name: XNNPACK
 Short Name: xnnpack
 URL: https://github.com/google/xnnpack
-Version: a33b227047def29b79853ef688b6dda6c6fc5386
-Date: 2022/07/06
+Version: 8e3d3359f9bec608e09fac1f7054a2a14b1bd73c
+Date: 2022/08/02
 License: BSD
 Security Critical: Yes
 
diff --git a/tools/buildstate.py b/tools/buildstate.py
index b7eeff7..05cb567 100755
--- a/tools/buildstate.py
+++ b/tools/buildstate.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env vpython
+#!/usr/bin/env vpython3
 # Copyright 2021 The Chromium Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -9,18 +9,9 @@
 The idea is that if the build is serialized (not many build steps running) then
 you can run this to see what it is serialized on.
 
-This uses python3 on Linux and vpython elsewhere (for psutil).
+This uses python3 on Windows and vpython elsewhere (for psutil).
 """
 
-# [VPYTHON:BEGIN]
-# wheel: <
-#   name: "infra/python/wheels/psutil/${vpython_platform}"
-#   version: "version:5.6.2"
-# >
-# [VPYTHON:END]
-
-from __future__ import print_function
-
 import sys
 
 
diff --git a/tools/clang/scripts/build.py b/tools/clang/scripts/build.py
index f065f4b..16ee674 100755
--- a/tools/clang/scripts/build.py
+++ b/tools/clang/scripts/build.py
@@ -556,15 +556,6 @@
 
   global CLANG_REVISION, PACKAGE_VERSION, LLVM_BUILD_DIR
 
-  # TODO(crbug.com/1347737): Remove in next Clang roll.
-  if args.llvm_force_head_revision:
-    global RELEASE_VERSION
-    RELEASE_VERSION = '16.0.0'
-    old_lib_dir = os.path.join(LLVM_BUILD_DIR, 'lib', 'clang', '15.0.0')
-    if (os.path.isdir(old_lib_dir)):
-      print('Removing old lib dir: ', old_lib_dir)
-      RmTree(old_lib_dir)
-
   if (args.pgo or args.thinlto) and not args.bootstrap:
     print('--pgo/--thinlto requires --bootstrap')
     return 1
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py
index 87b706a29..f25be7d1 100755
--- a/tools/clang/scripts/update.py
+++ b/tools/clang/scripts/update.py
@@ -40,7 +40,6 @@
 
 PACKAGE_VERSION = '%s-%s' % (CLANG_REVISION, CLANG_SUB_REVISION)
 RELEASE_VERSION = '16.0.0'
-# TODO(crbug.com/1347737): Bump to 16.0.0 in next Clang roll.
 
 CDS_URL = os.environ.get('CDS_CLANG_BUCKET_OVERRIDE',
     'https://commondatastorage.googleapis.com/chromium-browser-clang')
@@ -331,11 +330,6 @@
                       help='Verify that clang has the passed-in version.')
   args = parser.parse_args()
 
-  # TODO(crbug.com/1347737): Bump to 16.0.0 in next Clang roll.
-  if args.llvm_force_head_revision:
-    global RELEASE_VERSION
-    RELEASE_VERSION = '16.0.0'
-
   if args.verify_version and args.verify_version != RELEASE_VERSION:
     print('RELEASE_VERSION is %s but --verify-version argument was %s.' % (
         RELEASE_VERSION, args.verify_version))
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 4e7080c..a17c7d0 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -3189,7 +3189,7 @@
     ],
 
     'official_goma_chromeos_include_unwind_tables': [
-      'official', 'goma', 'chromeos', 'include_unwind_tables',
+      'official', 'goma', 'chromeos', 'minimal_symbols', 'include_unwind_tables',
     ],
 
     'official_goma_fuchsia_arm64_perf': [
diff --git a/tools/mb/mb_config_expectations/chrome.json b/tools/mb/mb_config_expectations/chrome.json
index e21d37f6..94356962 100644
--- a/tools/mb/mb_config_expectations/chrome.json
+++ b/tools/mb/mb_config_expectations/chrome.json
@@ -253,6 +253,7 @@
       "exclude_unwind_tables": false,
       "is_chrome_branded": true,
       "is_official_build": true,
+      "symbol_level": 1,
       "target_os": "chromeos",
       "use_goma": true
     }
diff --git a/tools/mb/mb_config_expectations/tryserver.chrome.json b/tools/mb/mb_config_expectations/tryserver.chrome.json
index 18a1713..6f98b05 100644
--- a/tools/mb/mb_config_expectations/tryserver.chrome.json
+++ b/tools/mb/mb_config_expectations/tryserver.chrome.json
@@ -328,6 +328,7 @@
       "exclude_unwind_tables": false,
       "is_chrome_branded": true,
       "is_official_build": true,
+      "symbol_level": 1,
       "target_os": "chromeos",
       "use_goma": true
     }
diff --git a/tools/metrics/actions/extract_actions.py b/tools/metrics/actions/extract_actions.py
index d7d5541c..e05cb2c 100755
--- a/tools/metrics/actions/extract_actions.py
+++ b/tools/metrics/actions/extract_actions.py
@@ -307,7 +307,8 @@
   else:
     action_re = USER_METRICS_ACTION_RE
 
-  finder = ActionNameFinder(path, open(path).read(), action_re)
+  finder = ActionNameFinder(path,
+                            open(path, encoding='utf-8').read(), action_re)
   while True:
     try:
       action_name = finder.FindNextAction()
@@ -321,7 +322,7 @@
     return
 
   line_number = 0
-  for line in open(path):
+  for line in open(path, encoding='utf-8'):
     line_number = line_number + 1
     if COMPUTED_ACTION_RE.search(line):
       # Warn if this file shouldn't be calling RecordComputedAction.
@@ -376,7 +377,7 @@
   close_called = False
   try:
     parser = WebUIActionsParser(actions)
-    parser.feed(open(path).read())
+    parser.feed(open(path, encoding='utf-8').read())
     # An exception can be thrown by parser.close(), so do it in the try to
     # ensure the path of the file being parsed gets printed if that happens.
     close_called = True
@@ -402,8 +403,9 @@
   if ext != '.js':
     return
 
-  finder = ActionNameFinder(path, open(path).read(),
-      USER_METRICS_ACTION_RE_DEVTOOLS)
+  finder = ActionNameFinder(path,
+                            open(path, encoding='utf-8').read(),
+                            USER_METRICS_ACTION_RE_DEVTOOLS)
   while True:
     try:
       action_name = finder.FindNextAction()
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index cecdeeb..12c1fb3 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -13273,6 +13273,11 @@
   <int value="1" label="Yes"/>
 </enum>
 
+<enum name="BooleanZipHasAES">
+  <int value="0" label="Zip does not have AES"/>
+  <int value="1" label="Zip has AES"/>
+</enum>
+
 <enum name="BootstrapTaskRunnerType">
   <int value="0" label="Posts at back of queue"/>
   <int value="1" label="Posts at front of queue"/>
@@ -21436,46 +21441,46 @@
 </enum>
 
 <enum name="CrosDisksClientMountError">
-  <int value="0" label="Success">MOUNT_ERROR_NONE</int>
-  <int value="1" label="Unknown">MOUNT_ERROR_UNKNOWN</int>
-  <int value="2" label="Internal">MOUNT_ERROR_INTERNAL</int>
-  <int value="3" label="Invalid argument">MOUNT_ERROR_INVALID_ARGUMENT</int>
-  <int value="4" label="Invalid path">MOUNT_ERROR_INVALID_PATH</int>
+  <int value="0" label="Success">MountError::kNone</int>
+  <int value="1" label="Unknown">MountError::kUnknown</int>
+  <int value="2" label="Internal">MountError::kInternal</int>
+  <int value="3" label="Invalid argument">MountError::kInvalidArgument</int>
+  <int value="4" label="Invalid path">MountError::kInvalidPath</int>
   <int value="5" label="Path already mounted">
-    MOUNT_ERROR_PATH_ALREADY_MOUNTED
+    MountError::kPathAlreadyMounted
   </int>
-  <int value="6" label="Path not mounted">MOUNT_ERROR_PATH_NOT_MOUNTED</int>
+  <int value="6" label="Path not mounted">MountError::kPathNotMounted</int>
   <int value="7" label="Directory creation failed">
-    MOUNT_ERROR_DIRECTORY_CREATION_FAILED
+    MountError::kDirectoryCreationFailed
   </int>
   <int value="8" label="Invalid mount options">
-    MOUNT_ERROR_INVALID_MOUNT_OPTIONS
+    MountError::kInvalidMountOptions
   </int>
   <int value="9" label="Invalid unmount options">
-    MOUNT_ERROR_INVALID_UNMOUNT_OPTIONS
+    MountError::kInvalidUnmountOptions
   </int>
   <int value="10" label="Insufficient permissions">
-    MOUNT_ERROR_INSUFFICIENT_PERMISSIONS
+    MountError::kInsufficientPermissions
   </int>
   <int value="11" label="Mount program not found">
-    MOUNT_ERROR_MOUNT_PROGRAM_NOT_FOUND
+    MountError::kMountProgramNotFound
   </int>
   <int value="12" label="Mount program failed">
-    MOUNT_ERROR_MOUNT_PROGRAM_FAILED
+    MountError::kMountProgramFailed
   </int>
   <int value="13" label="Invalid device path">
-    MOUNT_ERROR_INVALID_DEVICE_PATH
+    MountError::kInvalidDevicePath
   </int>
   <int value="14" label="Unknown filesystem">
-    MOUNT_ERROR_UNKNOWN_FILESYSTEM
+    MountError::kUnknownFilesystem
   </int>
   <int value="15" label="Unsupported filesystem">
-    MOUNT_ERROR_UNSUPPORTED_FILESYSTEM
+    MountError::kUnsupportedFilesystem
   </int>
-  <int value="16" label="Invalid archive">MOUNT_ERROR_INVALID_ARCHIVE</int>
-  <int value="17" label="Need password">MOUNT_ERROR_NEED_PASSWORD</int>
-  <int value="18" label="In progress">MOUNT_ERROR_IN_PROGRESS</int>
-  <int value="19" label="Cancelled">MOUNT_ERROR_CANCELLED</int>
+  <int value="16" label="Invalid archive">MountError::kInvalidArchive</int>
+  <int value="17" label="Need password">MountError::kNeedPassword</int>
+  <int value="18" label="In progress">MountError::kInProgress</int>
+  <int value="19" label="Cancelled">MountError::kCancelled</int>
 </enum>
 
 <enum name="CrosDisksDeviceMediaType">
@@ -21503,244 +21508,244 @@
 
 <enum name="CrosDisksMountTypeError">
   <int value="0" label="Invalid - Success">
-    100 * MountType::kInvalid + MOUNT_ERROR_NONE
+    100 * MountType::kInvalid + MountError::kNone
   </int>
   <int value="1" label="Invalid - Unknown">
-    100 * MountType::kInvalid + MOUNT_ERROR_UNKNOWN
+    100 * MountType::kInvalid + MountError::kUnknown
   </int>
   <int value="2" label="Invalid - Internal">
-    100 * MountType::kInvalid + MOUNT_ERROR_INTERNAL
+    100 * MountType::kInvalid + MountError::kInternal
   </int>
   <int value="3" label="Invalid - Invalid argument">
-    100 * MountType::kInvalid + MOUNT_ERROR_INVALID_ARGUMENT
+    100 * MountType::kInvalid + MountError::kInvalidArgument
   </int>
   <int value="4" label="Invalid - Invalid path">
-    100 * MountType::kInvalid + MOUNT_ERROR_INVALID_PATH
+    100 * MountType::kInvalid + MountError::kInvalidPath
   </int>
   <int value="5" label="Invalid - Path already mounted">
-    100 * MountType::kInvalid + MOUNT_ERROR_PATH_ALREADY_MOUNTED
+    100 * MountType::kInvalid + MountError::kPathAlreadyMounted
   </int>
   <int value="6" label="Invalid - Path not mounted">
-    100 * MountType::kInvalid + MOUNT_ERROR_PATH_NOT_MOUNTED
+    100 * MountType::kInvalid + MountError::kPathNotMounted
   </int>
   <int value="7" label="Invalid - Directory creation failed">
-    100 * MountType::kInvalid + MOUNT_ERROR_DIRECTORY_CREATION_FAILED
+    100 * MountType::kInvalid + MountError::kDirectoryCreationFailed
   </int>
   <int value="8" label="Invalid - Invalid mount options">
-    100 * MountType::kInvalid + MOUNT_ERROR_INVALID_MOUNT_OPTIONS
+    100 * MountType::kInvalid + MountError::kInvalidMountOptions
   </int>
   <int value="9" label="Invalid - Invalid unmount options">
-    100 * MountType::kInvalid + MOUNT_ERROR_INVALID_UNMOUNT_OPTIONS
+    100 * MountType::kInvalid + MountError::kInvalidUnmountOptions
   </int>
   <int value="10" label="Invalid - Insufficient permissions">
-    100 * MountType::kInvalid + MOUNT_ERROR_INSUFFICIENT_PERMISSIONS
+    100 * MountType::kInvalid + MountError::kInsufficientPermissions
   </int>
   <int value="11" label="Invalid - Mount program not found">
-    100 * MountType::kInvalid + MOUNT_ERROR_MOUNT_PROGRAM_NOT_FOUND
+    100 * MountType::kInvalid + MountError::kMountProgramNotFound
   </int>
   <int value="12" label="Invalid - Mount program failed">
-    100 * MountType::kInvalid + MOUNT_ERROR_MOUNT_PROGRAM_FAILED
+    100 * MountType::kInvalid + MountError::kMountProgramFailed
   </int>
   <int value="13" label="Invalid - Invalid device path">
-    100 * MountType::kInvalid + MOUNT_ERROR_INVALID_DEVICE_PATH
+    100 * MountType::kInvalid + MountError::kInvalidDevicePath
   </int>
   <int value="14" label="Invalid - Unknown filesystem">
-    100 * MountType::kInvalid + MOUNT_ERROR_UNKNOWN_FILESYSTEM
+    100 * MountType::kInvalid + MountError::kUnknownFilesystem
   </int>
   <int value="15" label="Invalid - Unsupported filesystem">
-    100 * MountType::kInvalid + MOUNT_ERROR_UNSUPPORTED_FILESYSTEM
+    100 * MountType::kInvalid + MountError::kUnsupportedFilesystem
   </int>
   <int value="16" label="Invalid - Invalid archive">
-    100 * MountType::kInvalid + MOUNT_ERROR_INVALID_ARCHIVE
+    100 * MountType::kInvalid + MountError::kInvalidArchive
   </int>
   <int value="17" label="Invalid - Need password">
-    100 * MountType::kInvalid + MOUNT_ERROR_NEED_PASSWORD
+    100 * MountType::kInvalid + MountError::kNeedPassword
   </int>
   <int value="18" label="Invalid - In progress">
-    100 * MountType::kInvalid + MOUNT_ERROR_IN_PROGRESS
+    100 * MountType::kInvalid + MountError::kInProgress
   </int>
   <int value="19" label="Invalid - Cancelled">
-    100 * MountType::kInvalid + MOUNT_ERROR_CANCELLED
+    100 * MountType::kInvalid + MountError::kCancelled
   </int>
   <int value="100" label="Device - Success">
-    100 * MountType::kDevice + MOUNT_ERROR_NONE
+    100 * MountType::kDevice + MountError::kNone
   </int>
   <int value="101" label="Device - Unknown">
-    100 * MountType::kDevice + MOUNT_ERROR_UNKNOWN
+    100 * MountType::kDevice + MountError::kUnknown
   </int>
   <int value="102" label="Device - Internal">
-    100 * MountType::kDevice + MOUNT_ERROR_INTERNAL
+    100 * MountType::kDevice + MountError::kInternal
   </int>
   <int value="103" label="Device - Invalid argument">
-    100 * MountType::kDevice + MOUNT_ERROR_INVALID_ARGUMENT
+    100 * MountType::kDevice + MountError::kInvalidArgument
   </int>
   <int value="104" label="Device - Invalid path">
-    100 * MountType::kDevice + MOUNT_ERROR_INVALID_PATH
+    100 * MountType::kDevice + MountError::kInvalidPath
   </int>
   <int value="105" label="Device - Path already mounted">
-    100 * MountType::kDevice + MOUNT_ERROR_PATH_ALREADY_MOUNTED
+    100 * MountType::kDevice + MountError::kPathAlreadyMounted
   </int>
   <int value="106" label="Device - Path not mounted">
-    100 * MountType::kDevice + MOUNT_ERROR_PATH_NOT_MOUNTED
+    100 * MountType::kDevice + MountError::kPathNotMounted
   </int>
   <int value="107" label="Device - Directory creation failed">
-    100 * MountType::kDevice + MOUNT_ERROR_DIRECTORY_CREATION_FAILED
+    100 * MountType::kDevice + MountError::kDirectoryCreationFailed
   </int>
   <int value="108" label="Device - Invalid mount options">
-    100 * MountType::kDevice + MOUNT_ERROR_INVALID_MOUNT_OPTIONS
+    100 * MountType::kDevice + MountError::kInvalidMountOptions
   </int>
   <int value="109" label="Device - Invalid unmount options">
-    100 * MountType::kDevice + MOUNT_ERROR_INVALID_UNMOUNT_OPTIONS
+    100 * MountType::kDevice + MountError::kInvalidUnmountOptions
   </int>
   <int value="110" label="Device - Insufficient permissions">
-    100 * MountType::kDevice + MOUNT_ERROR_INSUFFICIENT_PERMISSIONS
+    100 * MountType::kDevice + MountError::kInsufficientPermissions
   </int>
   <int value="111" label="Device - Mount program not found">
-    100 * MountType::kDevice + MOUNT_ERROR_MOUNT_PROGRAM_NOT_FOUND
+    100 * MountType::kDevice + MountError::kMountProgramNotFound
   </int>
   <int value="112" label="Device - Mount program failed">
-    100 * MountType::kDevice + MOUNT_ERROR_MOUNT_PROGRAM_FAILED
+    100 * MountType::kDevice + MountError::kMountProgramFailed
   </int>
   <int value="113" label="Device - Invalid device path">
-    100 * MountType::kDevice + MOUNT_ERROR_INVALID_DEVICE_PATH
+    100 * MountType::kDevice + MountError::kInvalidDevicePath
   </int>
   <int value="114" label="Device - Unknown filesystem">
-    100 * MountType::kDevice + MOUNT_ERROR_UNKNOWN_FILESYSTEM
+    100 * MountType::kDevice + MountError::kUnknownFilesystem
   </int>
   <int value="115" label="Device - Unsupported filesystem">
-    100 * MountType::kDevice + MOUNT_ERROR_UNSUPPORTED_FILESYSTEM
+    100 * MountType::kDevice + MountError::kUnsupportedFilesystem
   </int>
   <int value="116" label="Device - Invalid archive">
-    100 * MountType::kDevice + MOUNT_ERROR_INVALID_ARCHIVE
+    100 * MountType::kDevice + MountError::kInvalidArchive
   </int>
   <int value="117" label="Device - Needs password">
-    100 * MountType::kDevice + MOUNT_ERROR_NEED_PASSWORD
+    100 * MountType::kDevice + MountError::kNeedPassword
   </int>
   <int value="118" label="Device - In progress">
-    100 * MountType::kDevice + MOUNT_ERROR_IN_PROGRESS
+    100 * MountType::kDevice + MountError::kInProgress
   </int>
   <int value="119" label="Device - Cancelled">
-    100 * MountType::kDevice + MOUNT_ERROR_CANCELLED
+    100 * MountType::kDevice + MountError::kCancelled
   </int>
   <int value="200" label="Archive - Success">
-    100 * MountType::kArchive + MOUNT_ERROR_NONE
+    100 * MountType::kArchive + MountError::kNone
   </int>
   <int value="201" label="Archive - Unknown">
-    100 * MountType::kArchive + MOUNT_ERROR_UNKNOWN
+    100 * MountType::kArchive + MountError::kUnknown
   </int>
   <int value="202" label="Archive - Internal">
-    100 * MountType::kArchive + MOUNT_ERROR_INTERNAL
+    100 * MountType::kArchive + MountError::kInternal
   </int>
   <int value="203" label="Archive - Invalid argument">
-    100 * MountType::kArchive + MOUNT_ERROR_INVALID_ARGUMENT
+    100 * MountType::kArchive + MountError::kInvalidArgument
   </int>
   <int value="204" label="Archive - Invalid path">
-    100 * MountType::kArchive + MOUNT_ERROR_INVALID_PATH
+    100 * MountType::kArchive + MountError::kInvalidPath
   </int>
   <int value="205" label="Archive - Path already mounted">
-    100 * MountType::kArchive + MOUNT_ERROR_PATH_ALREADY_MOUNTED
+    100 * MountType::kArchive + MountError::kPathAlreadyMounted
   </int>
   <int value="206" label="Archive - Path not mounted">
-    100 * MountType::kArchive + MOUNT_ERROR_PATH_NOT_MOUNTED
+    100 * MountType::kArchive + MountError::kPathNotMounted
   </int>
   <int value="207" label="Archive - Directory creation failed">
-    100 * MountType::kArchive + MOUNT_ERROR_DIRECTORY_CREATION_FAILED
+    100 * MountType::kArchive + MountError::kDirectoryCreationFailed
   </int>
   <int value="208" label="Archive - Invalid mount options">
-    100 * MountType::kArchive + MOUNT_ERROR_INVALID_MOUNT_OPTIONS
+    100 * MountType::kArchive + MountError::kInvalidMountOptions
   </int>
   <int value="209" label="Archive - Invalid unmount options">
-    100 * MountType::kArchive + MOUNT_ERROR_INVALID_UNMOUNT_OPTIONS
+    100 * MountType::kArchive + MountError::kInvalidUnmountOptions
   </int>
   <int value="210" label="Archive - Insufficient permissions">
-    100 * MountType::kArchive + MOUNT_ERROR_INSUFFICIENT_PERMISSIONS
+    100 * MountType::kArchive + MountError::kInsufficientPermissions
   </int>
   <int value="211" label="Archive - Mount program not found">
-    100 * MountType::kArchive + MOUNT_ERROR_MOUNT_PROGRAM_NOT_FOUND
+    100 * MountType::kArchive + MountError::kMountProgramNotFound
   </int>
   <int value="212" label="Archive - Mount program failed">
-    100 * MountType::kArchive + MOUNT_ERROR_MOUNT_PROGRAM_FAILED
+    100 * MountType::kArchive + MountError::kMountProgramFailed
   </int>
   <int value="213" label="Archive - Invalid device path">
-    100 * MountType::kArchive + MOUNT_ERROR_INVALID_DEVICE_PATH
+    100 * MountType::kArchive + MountError::kInvalidDevicePath
   </int>
   <int value="214" label="Archive - Unknown filesystem">
-    100 * MountType::kArchive + MOUNT_ERROR_UNKNOWN_FILESYSTEM
+    100 * MountType::kArchive + MountError::kUnknownFilesystem
   </int>
   <int value="215" label="Archive - Unsupported filesystem">
-    100 * MountType::kArchive + MOUNT_ERROR_UNSUPPORTED_FILESYSTEM
+    100 * MountType::kArchive + MountError::kUnsupportedFilesystem
   </int>
   <int value="216" label="Archive - Invalid archive">
-    100 * MountType::kArchive + MOUNT_ERROR_INVALID_ARCHIVE
+    100 * MountType::kArchive + MountError::kInvalidArchive
   </int>
   <int value="217" label="Archive - Need password">
-    100 * MountType::kArchive + MOUNT_ERROR_NEED_PASSWORD
+    100 * MountType::kArchive + MountError::kNeedPassword
   </int>
   <int value="218" label="Archive - In progress">
-    100 * MountType::kArchive + MOUNT_ERROR_IN_PROGRESS
+    100 * MountType::kArchive + MountError::kInProgress
   </int>
   <int value="219" label="Archive - Cancelled">
-    100 * MountType::kArchive + MOUNT_ERROR_CANCELLED
+    100 * MountType::kArchive + MountError::kCancelled
   </int>
   <int value="300" label="Network - Success">
-    100 * MountType::kNetworkStorage + MOUNT_ERROR_NONE
+    100 * MountType::kNetworkStorage + MountError::kNone
   </int>
   <int value="301" label="Network - Unknown">
-    100 * MountType::kNetworkStorage + MOUNT_ERROR_UNKNOWN
+    100 * MountType::kNetworkStorage + MountError::kUnknown
   </int>
   <int value="302" label="Network - Internal">
-    100 * MountType::kNetworkStorage + MOUNT_ERROR_INTERNAL
+    100 * MountType::kNetworkStorage + MountError::kInternal
   </int>
   <int value="303" label="Network - Invalid argument">
-    100 * MountType::kNetworkStorage + MOUNT_ERROR_INVALID_ARGUMENT
+    100 * MountType::kNetworkStorage + MountError::kInvalidArgument
   </int>
   <int value="304" label="Network - Invalid path">
-    100 * MountType::kNetworkStorage + MOUNT_ERROR_INVALID_PATH
+    100 * MountType::kNetworkStorage + MountError::kInvalidPath
   </int>
   <int value="305" label="Network - Path already mounted">
-    100 * MountType::kNetworkStorage + MOUNT_ERROR_PATH_ALREADY_MOUNTED
+    100 * MountType::kNetworkStorage + MountError::kPathAlreadyMounted
   </int>
   <int value="306" label="Network - Path not mounted">
-    100 * MountType::kNetworkStorage + MOUNT_ERROR_PATH_NOT_MOUNTED
+    100 * MountType::kNetworkStorage + MountError::kPathNotMounted
   </int>
   <int value="307" label="Network - Directory creation failed">
-    100 * MountType::kNetworkStorage + MOUNT_ERROR_DIRECTORY_CREATION_FAILED
+    100 * MountType::kNetworkStorage + MountError::kDirectoryCreationFailed
   </int>
   <int value="308" label="Network - Invalid mount options">
-    100 * MountType::kNetworkStorage + MOUNT_ERROR_INVALID_MOUNT_OPTIONS
+    100 * MountType::kNetworkStorage + MountError::kInvalidMountOptions
   </int>
   <int value="309" label="Network - Invalid unmount options">
-    100 * MountType::kNetworkStorage + MOUNT_ERROR_INVALID_UNMOUNT_OPTIONS
+    100 * MountType::kNetworkStorage + MountError::kInvalidUnmountOptions
   </int>
   <int value="310" label="Network - Insufficient permissions">
-    100 * MountType::kNetworkStorage + MOUNT_ERROR_INSUFFICIENT_PERMISSIONS
+    100 * MountType::kNetworkStorage + MountError::kInsufficientPermissions
   </int>
   <int value="311" label="Network - Mount program not found">
-    100 * MountType::kNetworkStorage + MOUNT_ERROR_MOUNT_PROGRAM_NOT_FOUND
+    100 * MountType::kNetworkStorage + MountError::kMountProgramNotFound
   </int>
   <int value="312" label="Network - Mount program failed">
-    100 * MountType::kNetworkStorage + MOUNT_ERROR_MOUNT_PROGRAM_FAILED
+    100 * MountType::kNetworkStorage + MountError::kMountProgramFailed
   </int>
   <int value="313" label="Network - Invalid device path">
-    100 * MountType::kNetworkStorage + MOUNT_ERROR_INVALID_DEVICE_PATH
+    100 * MountType::kNetworkStorage + MountError::kInvalidDevicePath
   </int>
   <int value="314" label="Network - Unknown filesystem">
-    100 * MountType::kNetworkStorage + MOUNT_ERROR_UNKNOWN_FILESYSTEM
+    100 * MountType::kNetworkStorage + MountError::kUnknownFilesystem
   </int>
   <int value="315" label="Network - Unsupported filesystem">
-    100 * MountType::kNetworkStorage + MOUNT_ERROR_UNSUPPORTED_FILESYSTEM
+    100 * MountType::kNetworkStorage + MountError::kUnsupportedFilesystem
   </int>
   <int value="316" label="Network - Invalid archive">
-    100 * MountType::kNetworkStorage + MOUNT_ERROR_INVALID_ARCHIVE
+    100 * MountType::kNetworkStorage + MountError::kInvalidArchive
   </int>
   <int value="317" label="Network - Needs password">
-    100 * MountType::kNetworkStorage + MOUNT_ERROR_NEED_PASSWORD
+    100 * MountType::kNetworkStorage + MountError::kNeedPassword
   </int>
   <int value="318" label="Network - In progress">
-    100 * MountType::kNetworkStorage + MOUNT_ERROR_IN_PROGRESS
+    100 * MountType::kNetworkStorage + MountError::kInProgress
   </int>
   <int value="319" label="Network - Cancelled">
-    100 * MountType::kNetworkStorage + MOUNT_ERROR_CANCELLED
+    100 * MountType::kNetworkStorage + MountError::kCancelled
   </int>
 </enum>
 
@@ -34686,7 +34691,7 @@
   <int value="1189" label="FILEMANAGERPRIVATE_GETRECENTFILES"/>
   <int value="1190" label="FILEMANAGERPRIVATE_RENAMEVOLUME"/>
   <int value="1191" label="AUTOTESTPRIVATE_SETMOUSEREVERSESCROLL"/>
-  <int value="1192" label="DELETED_METRICSPRIVATE_RECORDSPARSEHASHABLE"/>
+  <int value="1192" label="METRICSPRIVATE_RECORDSPARSEHASHABLE"/>
   <int value="1193" label="NETWORKINGPRIVATE_SELECTCELLULARMOBILENETWORK"/>
   <int value="1194" label="PASSWORDSPRIVATE_IMPORTPASSWORDS"/>
   <int value="1195" label="PASSWORDSPRIVATE_EXPORTPASSWORDS"/>
@@ -57533,6 +57538,8 @@
   <int value="-871784177" label="DeprecateMenagerieAPI:enabled"/>
   <int value="-871520682"
       label="AccessibilityInternalsPageImprovements:enabled"/>
+  <int value="-871450829"
+      label="ThreadedScrollPreventRenderingStarvation:disabled"/>
   <int value="-870994173" label="NtpChromeCartModule:enabled"/>
   <int value="-870120067" label="EnableSearchBoxSelection:enabled"/>
   <int value="-868138290" label="CrostiniPortForwarding:disabled"/>
@@ -58132,6 +58139,7 @@
   <int value="-496989565"
       label="DesktopPWAsFlashAppNameInsteadOfOrigin:disabled"/>
   <int value="-496119023" label="WebXR:enabled"/>
+  <int value="-495991146" label="CustomizeChromeSidePanel:disabled"/>
   <int value="-495585885" label="enable-spdy-proxy-dev-auth-origin"/>
   <int value="-494722408" label="ContentSuggestionsLargeThumbnail:enabled"/>
   <int value="-494595710" label="LargeFaviconFromGoogle:disabled"/>
@@ -58666,6 +58674,7 @@
   <int value="-131257916" label="OmniboxCompactSuggestions:disabled"/>
   <int value="-130318058" label="ExoGamepadVibration:enabled"/>
   <int value="-129823932" label="HardwareSecureDecryptionFallback:disabled"/>
+  <int value="-129384450" label="CustomizeChromeSidePanel:enabled"/>
   <int value="-129061954"
       label="AutofillEnableManualFallbackForVirtualCards:enabled"/>
   <int value="-128687277"
@@ -59006,6 +59015,7 @@
   <int value="79503461" label="disable-account-consistency"/>
   <int value="79595680" label="OmniboxTabSwitchSuggestions:enabled"/>
   <int value="79729295" label="WebBundles:enabled"/>
+  <int value="80036427" label="AutofillEnableCardProductName:disabled"/>
   <int value="82303171" label="AccountIdMigration:disabled"/>
   <int value="82489049" label="AutofillSaveCardUiExperiment:enabled"/>
   <int value="83422372"
@@ -60284,6 +60294,8 @@
   <int value="890560037" label="always-enable-hdcp"/>
   <int value="892899792" label="MaterialDesignIncognitoNTP:disabled"/>
   <int value="894434593" label="TabRestoreSubMenus:enabled"/>
+  <int value="895337957"
+      label="ThreadedScrollPreventRenderingStarvation:enabled"/>
   <int value="896506516"
       label="enable-canvas-context-lost-in-background (obsolete)"/>
   <int value="898311758" label="ReaderMode:disabled"/>
@@ -61228,6 +61240,7 @@
   <int value="1499163193" label="PostScriptPrinting:disabled"/>
   <int value="1500390299" label="NtpCustomizationMenuV2:disabled"/>
   <int value="1502417134" label="BulkTabRestore:disabled"/>
+  <int value="1504393761" label="AutofillEnableCardProductName:enabled"/>
   <int value="1505194447" label="disable-transition-compositing"/>
   <int value="1506372577" label="NearbySharingSelfShare:disabled"/>
   <int value="1507233295" label="FilesTrash:disabled"/>
@@ -80402,6 +80415,7 @@
   <int value="4" label="Open Privacy Guide"/>
   <int value="5" label="Start Tab Group Tutorial"/>
   <int value="6" label="Open Password Manager"/>
+  <int value="7" label="NoOp Command"/>
 </enum>
 
 <enum name="ProtectorError">
diff --git a/tools/metrics/histograms/metadata/media/histograms.xml b/tools/metrics/histograms/metadata/media/histograms.xml
index 8e99550..4bbb9a3c 100644
--- a/tools/metrics/histograms/metadata/media/histograms.xml
+++ b/tools/metrics/histograms/metadata/media/histograms.xml
@@ -3254,9 +3254,9 @@
 </histogram>
 
 <histogram name="Media.MediaFoundation.VideoColorSpace.TransferID"
-    enum="VideoColorSpace.TransferID" expires_after="2022-08-30">
+    enum="VideoColorSpace.TransferID" expires_after="2023-08-02">
   <owner>dalecurtis@chromium.org</owner>
-  <owner>macrabil@microsoft.com</owner>
+  <owner>wicarr@microsoft.com</owner>
   <owner>media-dev@chromium.org</owner>
   <summary>
     Recorded when the VideoColorSpace TransferFunction value is passed to
diff --git a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
index a37e4c6..11dbe20e 100644
--- a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
+++ b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
@@ -2162,7 +2162,7 @@
 </histogram>
 
 <histogram name="SafeBrowsing.V4Database.SizeLinear{ThreatType}" units="MB"
-    expires_after="2022-08-28">
+    expires_after="2023-01-01">
   <owner>richche@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/sb_client/histograms.xml b/tools/metrics/histograms/metadata/sb_client/histograms.xml
index dec28656..7a86950 100644
--- a/tools/metrics/histograms/metadata/sb_client/histograms.xml
+++ b/tools/metrics/histograms/metadata/sb_client/histograms.xml
@@ -263,6 +263,16 @@
   </summary>
 </histogram>
 
+<histogram name="SBClientDownload.EncryptedZipUsesAes" enum="BooleanZipHasAES"
+    expires_after="2023-01-15">
+  <owner>drubery@chromium.org</owner>
+  <owner>chrome-counter-abuse-alerts@google.com</owner>
+  <summary>
+    Records whether a downloaded ZIP contains any AES-encryped content. This is
+    logged once for every downloaded ZIP containing any encrypted content.
+  </summary>
+</histogram>
+
 <histogram name="SBClientDownload.ExtractDocumentFeaturesTimeMedium" units="ms"
     expires_after="2022-10-16">
   <obsolete>
diff --git a/tools/metrics/histograms/metadata/tab/histograms.xml b/tools/metrics/histograms/metadata/tab/histograms.xml
index 3713f02..2868c7d 100644
--- a/tools/metrics/histograms/metadata/tab/histograms.xml
+++ b/tools/metrics/histograms/metadata/tab/histograms.xml
@@ -324,7 +324,7 @@
 </histogram>
 
 <histogram name="Tab.CloseAllTabsDialog.ClosedAllTabs.{CloseType}"
-    enum="Boolean" expires_after="2022-09-11">
+    enum="Boolean" expires_after="2023-03-11">
   <owner>ckitagawa@chromium.org</owner>
   <owner>fredmello@chromium.org</owner>
   <summary>
diff --git a/ui/base/ime/input_method.h b/ui/base/ime/input_method.h
index 7b6aa7a8..8c6fd773 100644
--- a/ui/base/ime/input_method.h
+++ b/ui/base/ime/input_method.h
@@ -146,8 +146,8 @@
   virtual void AddObserver(InputMethodObserver* observer) = 0;
   virtual void RemoveObserver(InputMethodObserver* observer) = 0;
 
-  // Set screen bounds of a on-screen keyboard.
-  virtual void SetOnScreenKeyboardBounds(const gfx::Rect& new_bounds) {}
+  // Set screen bounds of the virtual keyboard.
+  virtual void SetVirtualKeyboardBounds(const gfx::Rect& new_bounds) {}
 
   // Return the keyboard controller.
   virtual VirtualKeyboardController* GetVirtualKeyboardController() = 0;
diff --git a/ui/base/ime/input_method_base.cc b/ui/base/ime/input_method_base.cc
index 2801fb2..3beaa67 100644
--- a/ui/base/ime/input_method_base.cc
+++ b/ui/base/ime/input_method_base.cc
@@ -76,7 +76,7 @@
   return text_input_client_;
 }
 
-void InputMethodBase::SetOnScreenKeyboardBounds(const gfx::Rect& new_bounds) {
+void InputMethodBase::SetVirtualKeyboardBounds(const gfx::Rect& new_bounds) {
   keyboard_bounds_ = new_bounds;
   if (text_input_client_)
     text_input_client_->EnsureCaretNotInRect(keyboard_bounds_);
diff --git a/ui/base/ime/input_method_base.h b/ui/base/ime/input_method_base.h
index 5d048c0..040c4eb8 100644
--- a/ui/base/ime/input_method_base.h
+++ b/ui/base/ime/input_method_base.h
@@ -56,7 +56,7 @@
   void SetFocusedTextInputClient(TextInputClient* client) override;
   void DetachTextInputClient(TextInputClient* client) override;
   TextInputClient* GetTextInputClient() const override;
-  void SetOnScreenKeyboardBounds(const gfx::Rect& new_bounds) override;
+  void SetVirtualKeyboardBounds(const gfx::Rect& new_bounds) override;
 
   // If a derived class overrides this method, it should call parent's
   // implementation.
diff --git a/ui/base/ime/linux/input_method_auralinux.cc b/ui/base/ime/linux/input_method_auralinux.cc
index e9c9b98..2162e046 100644
--- a/ui/base/ime/linux/input_method_auralinux.cc
+++ b/ui/base/ime/linux/input_method_auralinux.cc
@@ -550,6 +550,11 @@
 #endif
 }
 
+void InputMethodAuraLinux::OnSetVirtualKeyboardOccludedBounds(
+    const gfx::Rect& screen_bounds) {
+  SetVirtualKeyboardBounds(screen_bounds);
+}
+
 // Overridden from InputMethodBase.
 
 void InputMethodAuraLinux::OnWillChangeFocusedClient(
diff --git a/ui/base/ime/linux/input_method_auralinux.h b/ui/base/ime/linux/input_method_auralinux.h
index ae389de..bae76f5 100644
--- a/ui/base/ime/linux/input_method_auralinux.h
+++ b/ui/base/ime/linux/input_method_auralinux.h
@@ -50,6 +50,8 @@
   void OnClearGrammarFragments(const gfx::Range& range) override;
   void OnAddGrammarFragment(const ui::GrammarFragment& fragment) override;
   void OnSetAutocorrectRange(const gfx::Range& range) override;
+  void OnSetVirtualKeyboardOccludedBounds(
+      const gfx::Rect& screen_bounds) override;
 
  protected:
   // Overridden from InputMethodBase.
diff --git a/ui/base/ime/linux/input_method_auralinux_unittest.cc b/ui/base/ime/linux/input_method_auralinux_unittest.cc
index b8d5b0b..357c68f 100644
--- a/ui/base/ime/linux/input_method_auralinux_unittest.cc
+++ b/ui/base/ime/linux/input_method_auralinux_unittest.cc
@@ -13,6 +13,7 @@
 #include "base/strings/string_split.h"
 #include "base/strings/utf_string_conversions.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/base/ime/dummy_text_input_client.h"
 #include "ui/base/ime/ime_key_event_dispatcher.h"
 #include "ui/base/ime/init/input_method_initializer.h"
@@ -229,6 +230,8 @@
   gfx::Range selection_range;
   std::u16string surrounding_text;
 
+  absl::optional<gfx::Rect> caret_not_in_rect;
+
  protected:
   void SetCompositionText(const CompositionText& composition) override {
     composition_text = composition.text;
@@ -289,6 +292,10 @@
     *text = surrounding_text.substr(range.GetMin(), range.length());
     return true;
   }
+
+  void EnsureCaretNotInRect(const gfx::Rect& rect) override {
+    caret_not_in_rect = rect;
+  }
 };
 
 class InputMethodAuraLinuxTest : public testing::Test {
@@ -1066,6 +1073,17 @@
   test_result_->Verify();
 }
 
+TEST_F(InputMethodAuraLinuxTest, OnSetVirtualKeyboardOccludedBounds) {
+  auto client =
+      std::make_unique<TextInputClientForTesting>(TEXT_INPUT_TYPE_TEXT);
+  input_method_auralinux_->SetFocusedTextInputClient(client.get());
+
+  constexpr gfx::Rect kBounds(10, 20, 300, 400);
+  input_method_auralinux_->OnSetVirtualKeyboardOccludedBounds(kBounds);
+
+  EXPECT_EQ(client->caret_not_in_rect, kBounds);
+}
+
 TEST_F(InputMethodAuraLinuxTest, GetVirtualKeyboardController) {
   EXPECT_EQ(input_method_auralinux_->GetVirtualKeyboardController(),
             context_->GetVirtualKeyboardController());
diff --git a/ui/base/ime/linux/linux_input_method_context.h b/ui/base/ime/linux/linux_input_method_context.h
index c0421a2..695b54ce 100644
--- a/ui/base/ime/linux/linux_input_method_context.h
+++ b/ui/base/ime/linux/linux_input_method_context.h
@@ -120,6 +120,10 @@
   // Sets the autocorrect range in the text input client.
   // |range| is in UTF-16 code range.
   virtual void OnSetAutocorrectRange(const gfx::Range& range) = 0;
+
+  // Sets the virtual keyboard's occluded bounds in screen DIP.
+  virtual void OnSetVirtualKeyboardOccludedBounds(
+      const gfx::Rect& screen_bounds) = 0;
 };
 
 }  // namespace ui
diff --git a/ui/file_manager/file_manager/background/js/test_util.js b/ui/file_manager/file_manager/background/js/test_util.js
index 466672f..713db29 100644
--- a/ui/file_manager/file_manager/background/js/test_util.js
+++ b/ui/file_manager/file_manager/background/js/test_util.js
@@ -109,7 +109,7 @@
     test.util.sync.fakeKeyDown(
         contentWindow, '#file-list', 'ArrowDown', false, false, false);
   }
-  console.error('Failed to select file "' + filename + '"');
+  console.warn('Failed to select file "' + filename + '"');
   return false;
 };
 
diff --git a/ui/file_manager/integration_tests/file_manager/background.js b/ui/file_manager/integration_tests/file_manager/background.js
index 9f29ed2..95c3d45 100644
--- a/ui/file_manager/integration_tests/file_manager/background.js
+++ b/ui/file_manager/integration_tests/file_manager/background.js
@@ -373,8 +373,7 @@
  * @return {Promise} Promise fulfilled on success.
  */
 export async function createShortcut(appId, directoryName) {
-  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
-      'selectFile', appId, [directoryName]));
+  await remoteCall.waitUntilSelected(appId, directoryName);
 
   await remoteCall.waitForElement(appId, ['.table-row[selected]']);
   chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
diff --git a/ui/file_manager/integration_tests/file_manager/context_menu.js b/ui/file_manager/integration_tests/file_manager/context_menu.js
index a5a7ec1..33dc0d4 100644
--- a/ui/file_manager/integration_tests/file_manager/context_menu.js
+++ b/ui/file_manager/integration_tests/file_manager/context_menu.js
@@ -26,9 +26,7 @@
   if (!/^paste/.test(commandId)) {
     return;
   }
-  chrome.test.assertTrue(
-      !!await remoteCall.callRemoteTestUtil('selectFile', appId, [file]),
-      'selectFile failed');
+  await remoteCall.waitUntilSelected(appId, file);
   chrome.test.assertTrue(
       !!await remoteCall.callRemoteTestUtil('execCommand', appId, ['copy']),
       'execCommand failed');
@@ -42,8 +40,7 @@
  */
 async function selectFile(appId, path) {
   // Select the file |path|.
-  chrome.test.assertTrue(
-      !!await remoteCall.callRemoteTestUtil('selectFile', appId, [path]));
+  await remoteCall.waitUntilSelected(appId, path);
 
   // Wait for the file to be selected.
   await remoteCall.waitForElement(appId, '.table-row[selected]');
@@ -82,8 +79,7 @@
   await maybeCopyToClipboard(appId, commandId);
 
   // Select the file |path|.
-  chrome.test.assertTrue(
-      !!await remoteCall.callRemoteTestUtil('selectFile', appId, [path]));
+  await remoteCall.waitUntilSelected(appId, path);
 
   // Wait for the file to be selected.
   await remoteCall.waitForElement(appId, '.table-row[selected]');
@@ -433,9 +429,7 @@
   const appId = await setupAndWaitUntilReady(RootPath.DOWNLOADS);
 
   // Select the file.
-  chrome.test.assertTrue(
-      await remoteCall.callRemoteTestUtil('selectFile', appId, ['hello.txt']),
-      'selectFile failed');
+  await remoteCall.waitUntilSelected(appId, 'hello.txt');
 
   // Press Ctrl+Enter key to rename the file.
   const key = ['#file-list', 'Enter', true, false, false];
@@ -586,8 +580,7 @@
       {ignoreFileSize: true, ignoreLastModifiedTime: true});
 
   // Select the item.
-  chrome.test.assertTrue(
-      !!await remoteCall.callRemoteTestUtil('selectFile', appId, [itemName]));
+  await remoteCall.waitUntilSelected(appId, itemName);
 
   // Wait for the file to be selected.
   await remoteCall.waitForElement(appId, '.table-row[selected]');
@@ -699,8 +692,7 @@
   await remoteCall.waitForFiles(appId, files, {ignoreLastModifiedTime: true});
 
   // Select the file |path|.
-  chrome.test.assertTrue(
-      !!await remoteCall.callRemoteTestUtil('selectFile', appId, [path]));
+  await remoteCall.waitUntilSelected(appId, path);
 
   // Wait for the file to be selected.
   await remoteCall.waitForElement(appId, '.table-row[selected]');
@@ -792,8 +784,7 @@
     await remoteCall.waitForElement(appId, '#file-list li[selected]');
   } else {
     // Select the item.
-    chrome.test.assertTrue(
-        !!await remoteCall.callRemoteTestUtil('selectFile', appId, [fileName]));
+    await remoteCall.waitUntilSelected(appId, fileName);
 
     // Wait for the file to be selected.
     await remoteCall.waitForElement(appId, '.table-row[selected]');
@@ -850,8 +841,7 @@
   const appId = await setupAndWaitUntilReady(RootPath.DOWNLOADS);
 
   // Select the file |path|.
-  chrome.test.assertTrue(!!await remoteCall.callRemoteTestUtil(
-      'selectFile', appId, ['hello.txt']));
+  await remoteCall.waitUntilSelected(appId, 'hello.txt');
 
   // Wait for the file to be selected.
   await remoteCall.waitForElement(appId, '.table-row[selected]');
diff --git a/ui/file_manager/integration_tests/file_manager/copy_between_windows.js b/ui/file_manager/integration_tests/file_manager/copy_between_windows.js
index d3fda8c..643257477 100644
--- a/ui/file_manager/integration_tests/file_manager/copy_between_windows.js
+++ b/ui/file_manager/integration_tests/file_manager/copy_between_windows.js
@@ -47,9 +47,7 @@
 
   await remoteCall.waitForFiles(window1, [file.getExpectedRow()]);
 
-  chrome.test.assertTrue(
-      !!await remoteCall.callRemoteTestUtil('selectFile', window1, [name]),
-      'Failed: selectFile ' + name);
+  await remoteCall.waitUntilSelected(window1, name);
 
   await remoteCall.callRemoteTestUtil('execCommand', window1, ['copy']);
 
diff --git a/ui/file_manager/integration_tests/file_manager/directory_tree_context_menu.js b/ui/file_manager/integration_tests/file_manager/directory_tree_context_menu.js
index f458dcc..cc6ab935 100644
--- a/ui/file_manager/integration_tests/file_manager/directory_tree_context_menu.js
+++ b/ui/file_manager/integration_tests/file_manager/directory_tree_context_menu.js
@@ -839,10 +839,7 @@
       RootPath.DOWNLOADS, [ENTRIES.zipArchive], []);
 
   // Select the ZIP file.
-  chrome.test.assertTrue(
-      !!await remoteCall.callRemoteTestUtil(
-          'selectFile', appId, ['archive.zip']),
-      'selectFile failed');
+  await remoteCall.waitUntilSelected(appId, ENTRIES.zipArchive.nameText);
 
   // Press the Enter key to mount the ZIP file.
   const key = ['#file-list', 'Enter', false, false, false];
@@ -878,10 +875,7 @@
       RootPath.DOWNLOADS, [ENTRIES.zipArchive], []);
 
   // Select the ZIP file.
-  chrome.test.assertTrue(
-      !!await remoteCall.callRemoteTestUtil(
-          'selectFile', appId, ['archive.zip']),
-      'selectFile failed');
+  await remoteCall.waitUntilSelected(appId, ENTRIES.zipArchive.nameText);
 
   // Press the Enter key to mount the ZIP file.
   const key = ['#file-list', 'Enter', false, false, false];
@@ -1001,9 +995,7 @@
   {
     // Select and copy photos directory into the clipboard to test
     // paste-into-folder command.
-    chrome.test.assertTrue(
-        !!await remoteCall.callRemoteTestUtil('selectFile', appId, ['photos']),
-        'selectFile failed');
+    await remoteCall.waitUntilSelected(appId, ENTRIES.photos.nameText);
     chrome.test.assertTrue(
         !!await remoteCall.callRemoteTestUtil('execCommand', appId, ['copy']),
         'execCommand failed');
@@ -1046,9 +1038,7 @@
     await navigateWithDirectoryTree(appId, '/My files/Downloads');
     // Select and copy photosT file into the clipboard to test
     // paste-into-folder command.
-    chrome.test.assertTrue(
-        !!await remoteCall.callRemoteTestUtil('selectFile', appId, ['photosT']),
-        'selectFile failed');
+    await remoteCall.waitUntilSelected(appId, 'photosT');
     chrome.test.assertTrue(
         !!await remoteCall.callRemoteTestUtil('execCommand', appId, ['copy']),
         'execCommand failed');
@@ -1647,9 +1637,7 @@
 
   // Select and copy hello.txt into the clipboard to test paste-into-folder
   // command.
-  chrome.test.assertTrue(
-      !!await remoteCall.callRemoteTestUtil('selectFile', appId, ['hello.txt']),
-      'selectFile failed');
+  await remoteCall.waitUntilSelected(appId, 'hello.txt');
   chrome.test.assertTrue(
       !!await remoteCall.callRemoteTestUtil('execCommand', appId, ['copy']),
       'execCommand failed');
@@ -1726,9 +1714,7 @@
 
   // Select and copy hello.txt into the clipboard to test paste-into-folder
   // command.
-  chrome.test.assertTrue(
-      !!await remoteCall.callRemoteTestUtil('selectFile', appId, ['hello.txt']),
-      'selectFile failed');
+  await remoteCall.waitUntilSelected(appId, 'hello.txt');
   chrome.test.assertTrue(
       !!await remoteCall.callRemoteTestUtil('execCommand', appId, ['copy']),
       'execCommand failed');
@@ -1874,9 +1860,7 @@
 
   // Select and copy hello.txt into the clipboard to test paste-into-folder
   // command.
-  chrome.test.assertTrue(
-      !!await remoteCall.callRemoteTestUtil('selectFile', appId, ['hello.txt']),
-      'selectFile failed');
+  await remoteCall.waitUntilSelected(appId, 'hello.txt');
   chrome.test.assertTrue(
       !!await remoteCall.callRemoteTestUtil('execCommand', appId, ['copy']),
       'execCommand failed');
diff --git a/ui/file_manager/integration_tests/file_manager/dlp.js b/ui/file_manager/integration_tests/file_manager/dlp.js
index 89278a0e..0f59b21 100644
--- a/ui/file_manager/integration_tests/file_manager/dlp.js
+++ b/ui/file_manager/integration_tests/file_manager/dlp.js
@@ -29,8 +29,7 @@
   await remoteCall.waitForElement(appId, usbVolumeQuery);
 
   // Select the file.
-  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
-      'selectFile', appId, [entry.nameText]));
+  await remoteCall.waitUntilSelected(appId, entry.nameText);
 
   // Copy the file.
   chrome.test.assertTrue(
diff --git a/ui/file_manager/integration_tests/file_manager/drive_specific.js b/ui/file_manager/integration_tests/file_manager/drive_specific.js
index e373ab43..f864ac3 100644
--- a/ui/file_manager/integration_tests/file_manager/drive_specific.js
+++ b/ui/file_manager/integration_tests/file_manager/drive_specific.js
@@ -396,7 +396,7 @@
   const appId = await setupAndWaitUntilReady(RootPath.DRIVE);
   const caller = getCaller();
   await sendTestMessage({name: 'useCellularNetwork'});
-  await remoteCall.callRemoteTestUtil('selectFile', appId, ['hello.txt']);
+  await remoteCall.waitUntilSelected(appId, 'hello.txt');
   await repeatUntil(() => {
     return navigator.connection.type != 'cellular' ?
         pending(caller, 'Network state is not changed to cellular.') :
@@ -591,9 +591,7 @@
   const appId = await setupAndWaitUntilReady(RootPath.DRIVE, []);
 
   // Select a file.
-  chrome.test.assertTrue(
-      !!await remoteCall.callRemoteTestUtil('selectFile', appId, ['hello.txt']),
-      'selectFile failed');
+  await remoteCall.waitUntilSelected(appId, 'hello.txt');
 
   // Wait for the entry to be selected.
   await remoteCall.waitForElement(appId, '.table-row[selected]');
@@ -629,9 +627,7 @@
   const appId = await setupAndWaitUntilReady(RootPath.DRIVE, []);
 
   // Select a file.
-  chrome.test.assertTrue(
-      !!await remoteCall.callRemoteTestUtil('selectFile', appId, ['photos']),
-      'selectFile failed');
+  await remoteCall.waitUntilSelected(appId, 'photos');
 
   // Wait for the entry to be selected.
   await remoteCall.waitForElement(appId, '.table-row[selected]');
@@ -748,9 +744,7 @@
       ]));
 
   // Select the link
-  chrome.test.assertTrue(
-      !!await remoteCall.callRemoteTestUtil('selectFile', appId, ['G']),
-      'selectFile failed');
+  await remoteCall.waitUntilSelected(appId, 'G');
   await remoteCall.waitForElement(appId, '.table-row[selected]');
 
   // Open the link
diff --git a/ui/file_manager/integration_tests/file_manager/file_dialog.js b/ui/file_manager/integration_tests/file_manager/file_dialog.js
index 26f00b22..e790841 100644
--- a/ui/file_manager/integration_tests/file_manager/file_dialog.js
+++ b/ui/file_manager/integration_tests/file_manager/file_dialog.js
@@ -18,7 +18,7 @@
  * @return {!Promise} Promise to be fulfilled on success.
  */
 async function sendOpenFileDialogKey(name, key, dialog) {
-  await remoteCall.callRemoteTestUtil('selectFile', dialog, [name]);
+  await remoteCall.waitUntilSelected(dialog, name);
   await remoteCall.callRemoteTestUtil('fakeKeyDown', dialog, key);
 }
 
@@ -32,7 +32,7 @@
  * @return {!Promise} Promise to be fulfilled on success.
  */
 async function clickOpenFileDialogButton(name, button, dialog) {
-  await remoteCall.callRemoteTestUtil('selectFile', dialog, [name]);
+  await remoteCall.waitUntilSelected(dialog, name);
   await remoteCall.waitForElement(dialog, button);
   const event = [button, 'click'];
   await remoteCall.callRemoteTestUtil('fakeEvent', dialog, event);
@@ -132,7 +132,7 @@
   const caller = getCaller();
 
   const closer = async (appId) => {
-    await remoteCall.callRemoteTestUtil('selectFile', appId, [name]);
+    await remoteCall.waitUntilSelected(appId, name);
     await repeatUntil(async () => {
       const element =
           await remoteCall.waitForElement(appId, '#filename-input-textbox');
@@ -175,9 +175,9 @@
   const disabledOkButton = '.button-panel button.ok:disabled';
   const cancelButton = '.button-panel button.cancel';
   const closer = async (dialog) => {
-    await remoteCall.callRemoteTestUtil('selectFile', dialog, [enabledName]);
+    await remoteCall.waitUntilSelected(dialog, enabledName);
     await remoteCall.waitForElement(dialog, okButton);
-    await remoteCall.callRemoteTestUtil('selectFile', dialog, [name]);
+    await remoteCall.waitUntilSelected(dialog, name);
     await remoteCall.waitForElement(dialog, disabledOkButton);
     clickOpenFileDialogButton(name, cancelButton, dialog);
   };
diff --git a/ui/file_manager/integration_tests/file_manager/file_display.js b/ui/file_manager/integration_tests/file_manager/file_display.js
index 0cdac58..a144e3f0 100644
--- a/ui/file_manager/integration_tests/file_manager/file_display.js
+++ b/ui/file_manager/integration_tests/file_manager/file_display.js
@@ -916,8 +916,7 @@
       await setupAndWaitUntilReady(RootPath.DOWNLOADS, [ENTRIES.hello], []);
 
   // Select ENTRIES.hello.
-  chrome.test.assertTrue(
-      await remoteCall.callRemoteTestUtil('selectFile', appId, ['hello.txt']));
+  await remoteCall.waitUntilSelected(appId, ENTRIES.hello.nameText);
 
   // Select all.
   const ctrlA = ['#file-list', 'a', true, false, false];
diff --git a/ui/file_manager/integration_tests/file_manager/format_dialog.js b/ui/file_manager/integration_tests/file_manager/format_dialog.js
index d88f950..5f38eac 100644
--- a/ui/file_manager/integration_tests/file_manager/format_dialog.js
+++ b/ui/file_manager/integration_tests/file_manager/format_dialog.js
@@ -360,8 +360,7 @@
   await remoteCall.callRemoteTestUtil('focus', appId, ['#file-list']);
 
   // Click an item in the list.
-  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
-      'selectFile', appId, [ENTRIES.hello.nameText]));
+  await remoteCall.waitUntilSelected(appId, ENTRIES.hello.nameText);
 
   // Click on the gear menu button.
   await remoteCall.waitAndClickElement(appId, '#gear-button:not([hidden])');
diff --git a/ui/file_manager/integration_tests/file_manager/gear_menu.js b/ui/file_manager/integration_tests/file_manager/gear_menu.js
index f8ae65b4..3c4cdf50 100644
--- a/ui/file_manager/integration_tests/file_manager/gear_menu.js
+++ b/ui/file_manager/integration_tests/file_manager/gear_menu.js
@@ -288,8 +288,7 @@
   await remoteCall.waitForElement(appId, '#gear-menu[hidden]');
 
   // 2. Selecting a single regular file
-  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
-      'selectFile', appId, [ENTRIES.hello.nameText]));
+  await remoteCall.waitUntilSelected(appId, ENTRIES.hello.nameText);
 
   chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
       'fakeMouseClick', appId, ['#gear-button']));
@@ -307,8 +306,7 @@
   await remoteCall.waitForElement(appId, '#gear-menu[hidden]');
 
   // 3. When ready to paste a file
-  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
-      'selectFile', appId, [ENTRIES.hello.nameText]));
+  await remoteCall.waitUntilSelected(appId, ENTRIES.hello.nameText);
 
   // Ctrl-C to copy the selected file
   await remoteCall.fakeKeyDown(appId, '#file-list', 'c', true, false, false);
diff --git a/ui/file_manager/integration_tests/file_manager/keyboard_operations.js b/ui/file_manager/integration_tests/file_manager/keyboard_operations.js
index 7221ae0..1b5b183 100644
--- a/ui/file_manager/integration_tests/file_manager/keyboard_operations.js
+++ b/ui/file_manager/integration_tests/file_manager/keyboard_operations.js
@@ -169,9 +169,7 @@
   const textInput = '#file-list .table-row[renaming] input.rename';
 
   // Select the file.
-  chrome.test.assertTrue(
-      await remoteCall.callRemoteTestUtil('selectFile', appId, [oldName]),
-      'selectFile failed');
+  await remoteCall.waitUntilSelected(appId, oldName);
 
   // Press Ctrl+Enter key to rename the file.
   const key = ['#file-list', 'Enter', true, false, false];
@@ -545,9 +543,7 @@
       await setupAndWaitUntilReady(RootPath.DRIVE, [], [ENTRIES.hello]);
 
   // Select a file for deletion.
-  chrome.test.assertTrue(
-      !!await remoteCall.callRemoteTestUtil('selectFile', appId, ['hello.txt']),
-      'selectFile failed');
+  await remoteCall.waitUntilSelected(appId, ENTRIES.hello.nameText);
   await remoteCall.waitForElement(appId, '.table-row[selected]');
 
   // Click delete button in the toolbar.
diff --git a/ui/file_manager/integration_tests/file_manager/metadata.js b/ui/file_manager/integration_tests/file_manager/metadata.js
index d54d86a..2e46ba5 100644
--- a/ui/file_manager/integration_tests/file_manager/metadata.js
+++ b/ui/file_manager/integration_tests/file_manager/metadata.js
@@ -349,10 +349,7 @@
   await remoteCall.waitForFiles(appId, files, {ignoreLastModifiedTime: true});
 
   // Select file hello.txt in the file list.
-  chrome.test.assertTrue(
-      !!await remoteCall.callRemoteTestUtil(
-          'selectFile', appId, [ENTRIES.hello.nameText]),
-      'selectFile failed');
+  await remoteCall.waitUntilSelected(appId, ENTRIES.hello.nameText);
 
   // Check that a request for content metadata completes.
   const result = await await remoteCall.callRemoteTestUtil(
diff --git a/ui/file_manager/integration_tests/file_manager/metrics.js b/ui/file_manager/integration_tests/file_manager/metrics.js
index 55b2c74..2f5c1dc 100644
--- a/ui/file_manager/integration_tests/file_manager/metrics.js
+++ b/ui/file_manager/integration_tests/file_manager/metrics.js
@@ -118,7 +118,7 @@
   await remoteCall.callRemoteTestUtil('overrideTasks', appId, [fakeTasks]);
 
   // Select the file.
-  await remoteCall.callRemoteTestUtil('selectFile', appId, ['file-1.txt']);
+  await remoteCall.waitUntilSelected(appId, 'file-1.txt');
 
   // Wait for the tasks calculation to complete, updating the "Open" button.
   await remoteCall.waitForElement(appId, '#tasks[get-tasks-completed]');
diff --git a/ui/file_manager/integration_tests/file_manager/my_files.js b/ui/file_manager/integration_tests/file_manager/my_files.js
index 72625a9..1f82b02d 100644
--- a/ui/file_manager/integration_tests/file_manager/my_files.js
+++ b/ui/file_manager/integration_tests/file_manager/my_files.js
@@ -219,10 +219,7 @@
   await selectMyFiles(appId);
 
   // Select Downloads via file list.
-  const downloads = ['Downloads'];
-  chrome.test.assertTrue(
-      !!await remoteCall.callRemoteTestUtil('selectFile', appId, downloads),
-      'selectFile failed');
+  await remoteCall.waitUntilSelected(appId, 'Downloads');
 
   // Open Downloads via file list.
   const fileListItem = '#file-list .table-row';
@@ -235,10 +232,7 @@
   await remoteCall.waitForFiles(appId, [ENTRIES.photos.getExpectedRow()]);
 
   // Select photos via file list.
-  const folder = ['photos'];
-  chrome.test.assertTrue(
-      !!await remoteCall.callRemoteTestUtil('selectFile', appId, folder),
-      'selectFile failed');
+  await remoteCall.waitUntilSelected(appId, 'photos');
 
   // Press Ctrl+Enter for start renaming.
   const key2 = [fileListItem, 'Enter', true, false, false];
@@ -371,16 +365,14 @@
   await selectMyFiles(appId);
 
   // Select Downloads folder in list.
-  chrome.test.assertTrue(
-      await remoteCall.callRemoteTestUtil('selectFile', appId, ['Downloads']));
+  await remoteCall.waitUntilSelected(appId, 'Downloads');
 
   // Test that the delete button isn't visible.
   const hiddenDeleteButton = '#delete-button[hidden]';
   await remoteCall.waitForElement(appId, hiddenDeleteButton);
 
   // Select fake entry Linux files folder in list.
-  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
-      'selectFile', appId, ['Linux files']));
+  await remoteCall.waitUntilSelected(appId, 'Linux files');
 
   // Test that the delete button isn't visible.
   await remoteCall.waitForElement(appId, hiddenDeleteButton);
@@ -392,8 +384,7 @@
   await selectMyFiles(appId);
 
   // Select real Linux files folder in list.
-  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
-      'selectFile', appId, ['Linux files']));
+  await remoteCall.waitUntilSelected(appId, 'Linux files');
 
   // Test that the delete button isn't visible.
   await remoteCall.waitForElement(appId, hiddenDeleteButton);
diff --git a/ui/file_manager/integration_tests/file_manager/open_sniffed_files.js b/ui/file_manager/integration_tests/file_manager/open_sniffed_files.js
index 899bea5..4306c2d6 100644
--- a/ui/file_manager/integration_tests/file_manager/open_sniffed_files.js
+++ b/ui/file_manager/integration_tests/file_manager/open_sniffed_files.js
@@ -32,10 +32,7 @@
     // in the browser.
 
     // Select the file.
-    chrome.test.assertTrue(
-        !!await remoteCall.callRemoteTestUtil(
-            'selectFile', appId, [entry.targetPath]),
-        'selectFile failed');
+    await remoteCall.waitUntilSelected(appId, entry.targetPath);
 
     // Right-click the selected file.
     await remoteCall.waitAndRightClick(appId, '.table-row[selected]');
diff --git a/ui/file_manager/integration_tests/file_manager/quick_view.js b/ui/file_manager/integration_tests/file_manager/quick_view.js
index acae453..adb296b 100644
--- a/ui/file_manager/integration_tests/file_manager/quick_view.js
+++ b/ui/file_manager/integration_tests/file_manager/quick_view.js
@@ -160,9 +160,7 @@
  */
 async function openQuickView(appId, name) {
   // Select file |name| in the file list.
-  chrome.test.assertTrue(
-      !!await remoteCall.callRemoteTestUtil('selectFile', appId, [name]),
-      'selectFile failed');
+  await remoteCall.waitUntilSelected(appId, name);
 
   // Press the space key.
   const space = ['#file-list', ' ', false, false, false];
@@ -395,10 +393,7 @@
       RootPath.DOWNLOADS, BASIC_LOCAL_ENTRY_SET, []);
 
   // Select the file in the file list.
-  chrome.test.assertTrue(
-      !!await remoteCall.callRemoteTestUtil(
-          'selectFile', appId, [ENTRIES.hello.nameText]),
-      'selectFile failed');
+  await remoteCall.waitUntilSelected(appId, ENTRIES.hello.nameText);
 
   // Check: clicking the context menu "Get Info" should open Quick View.
   await openQuickViewViaContextMenu(appId, ENTRIES.hello.nameText);
diff --git a/ui/file_manager/integration_tests/file_manager/recents.js b/ui/file_manager/integration_tests/file_manager/recents.js
index 67d47f4c..6d389eb 100644
--- a/ui/file_manager/integration_tests/file_manager/recents.js
+++ b/ui/file_manager/integration_tests/file_manager/recents.js
@@ -227,8 +227,7 @@
  */
 async function rightClickContextMenu(appId, fileName, commandId) {
   // Select the item.
-  chrome.test.assertTrue(
-      !!await remoteCall.callRemoteTestUtil('selectFile', appId, [fileName]));
+  await remoteCall.waitUntilSelected(appId, fileName);
 
   // Right-click the selected file.
   await remoteCall.waitAndRightClick(appId, '.table-row[selected]');
@@ -893,8 +892,8 @@
   await remoteCall.waitForFiles(appId, files);
 
   // Select the item.
-  chrome.test.assertTrue(!!await remoteCall.callRemoteTestUtil(
-      'selectFile', appId, [RECENT_MODIFIED_ANDROID_DOCUMENT.nameText]));
+  await remoteCall.waitUntilSelected(
+      appId, RECENT_MODIFIED_ANDROID_DOCUMENT.nameText);
 
   // Right-click the selected file.
   await remoteCall.waitAndRightClick(appId, '.table-row[selected]');
@@ -912,7 +911,7 @@
 testcase.recentsAllowCutForDownloads = async () => {
   const appId = await setupAndWaitUntilReady(
       RootPath.DOWNLOADS, [ENTRIES.beautiful, ENTRIES.directoryA], []);
-  const files = TestEntryInfo.getExpectedRows([ENTRIES.beautiful]);
+  const files = [ENTRIES.beautiful.getExpectedRow()];
   const newFolderBreadcrumb =
       `/My files/Downloads/${ENTRIES.directoryA.nameText}`;
 
diff --git a/ui/file_manager/integration_tests/file_manager/search.js b/ui/file_manager/integration_tests/file_manager/search.js
index 46b1cfc..53d53dd 100644
--- a/ui/file_manager/integration_tests/file_manager/search.js
+++ b/ui/file_manager/integration_tests/file_manager/search.js
@@ -151,8 +151,7 @@
   const appId = await setupAndWaitUntilReady(RootPath.DOWNLOADS, [entry], []);
 
   // Select an entry in the file list.
-  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
-      'selectFile', appId, [entry.nameText]));
+  await remoteCall.waitUntilSelected(appId, entry.nameText);
 
   // Click the toolbar search button.
   await remoteCall.waitAndClickElement(appId, '#search-button');
diff --git a/ui/file_manager/integration_tests/file_manager/share_and_manage_dialog.js b/ui/file_manager/integration_tests/file_manager/share_and_manage_dialog.js
index 7802b1d..44ae16c 100644
--- a/ui/file_manager/integration_tests/file_manager/share_and_manage_dialog.js
+++ b/ui/file_manager/integration_tests/file_manager/share_and_manage_dialog.js
@@ -32,9 +32,7 @@
   }
 
   // Select the given |path|.
-  chrome.test.assertTrue(
-      !!await remoteCall.callRemoteTestUtil('selectFile', appId, [path]),
-      'selectFile failed');
+  await remoteCall.waitUntilSelected(appId, path);
 
   // Right-click to show the context menu.
   chrome.test.assertTrue(
@@ -79,9 +77,7 @@
   }
 
   // Select the given |path|.
-  chrome.test.assertTrue(
-      !!await remoteCall.callRemoteTestUtil('selectFile', appId, [path]),
-      'selectFile failed');
+  await remoteCall.waitUntilSelected(appId, path);
 
   // Wait for the entry to be selected.
   chrome.test.assertTrue(
@@ -188,9 +184,7 @@
   await remoteCall.waitForFileListChange(appId, BASIC_DRIVE_ENTRY_SET.length);
 
   // Select the given |path|.
-  chrome.test.assertTrue(
-      !!await remoteCall.callRemoteTestUtil('selectFile', appId, [path]),
-      'selectFile failed');
+  await remoteCall.waitUntilSelected(appId, path);
 
   // Wait for the entry to be selected.
   chrome.test.assertTrue(
diff --git a/ui/file_manager/integration_tests/file_manager/tab_index.js b/ui/file_manager/integration_tests/file_manager/tab_index.js
index a46f426..637ba06 100644
--- a/ui/file_manager/integration_tests/file_manager/tab_index.js
+++ b/ui/file_manager/integration_tests/file_manager/tab_index.js
@@ -135,8 +135,7 @@
   await remoteCall.callRemoteTestUtil('foregroundFake', appId, [fakeData]);
 
   // Select the directory named 'photos'.
-  chrome.test.assertTrue(
-      await remoteCall.callRemoteTestUtil('selectFile', appId, ['photos']));
+  await remoteCall.waitUntilSelected(appId, 'photos');
 
   await Promise.all([
 
@@ -256,7 +255,7 @@
   ];
   return tabindexFocus(
       {type: 'openFile'}, 'downloads', BASIC_LOCAL_ENTRY_SET, async (appId) => {
-        await remoteCall.callRemoteTestUtil('selectFile', appId, ['hello.txt']);
+        await remoteCall.waitUntilSelected(appId, 'hello.txt');
         await remoteCall.isolateBannerForTesting(
             appId, 'holding-space-welcome-banner');
       }, ['#ok-button:not([disabled])'], tabindexIds);
@@ -281,7 +280,7 @@
   ];
   return tabindexFocus(
       {type: 'openFile'}, 'drive', BASIC_DRIVE_ENTRY_SET, async (appId) => {
-        await remoteCall.callRemoteTestUtil('selectFile', appId, ['hello.txt']);
+        await remoteCall.waitUntilSelected(appId, 'hello.txt');
         await remoteCall.isolateBannerForTesting(appId, 'drive-welcome-banner');
       }, ['#ok-button:not([disabled])'], tabindexIds);
 };
diff --git a/ui/file_manager/integration_tests/file_manager/tasks.js b/ui/file_manager/integration_tests/file_manager/tasks.js
index afd2fef..d0ec114 100644
--- a/ui/file_manager/integration_tests/file_manager/tasks.js
+++ b/ui/file_manager/integration_tests/file_manager/tasks.js
@@ -112,8 +112,7 @@
  */
 async function executeDefaultTask(appId, descriptor) {
   // Select file.
-  chrome.test.assertTrue(
-      await remoteCall.callRemoteTestUtil('selectFile', appId, ['hello.txt']));
+  await remoteCall.waitUntilSelected(appId, 'hello.txt');
 
   // Double-click the file.
   chrome.test.assertTrue(!!await remoteCall.callRemoteTestUtil(
@@ -141,7 +140,7 @@
   ];
 
   // Select file.
-  await remoteCall.callRemoteTestUtil('selectFile', appId, ['hello.txt']);
+  await remoteCall.waitUntilSelected(appId, 'hello.txt');
 
   // Click the change default menu.
   await remoteCall.waitForElement(appId, '#tasks[multiple]');
@@ -276,7 +275,7 @@
   const appId = await setupTaskTest(RootPath.DOWNLOADS, tasks);
 
   // Select file.
-  await remoteCall.callRemoteTestUtil('selectFile', appId, ['hello.txt']);
+  await remoteCall.waitUntilSelected(appId, 'hello.txt');
 
   // Click the change default task menu.
   await remoteCall.waitForElement(appId, '#tasks[multiple]');
@@ -350,11 +349,11 @@
   const appId = await setupTaskTest(RootPath.DOWNLOADS, tasks);
 
   // Select file and ensure action bar open is shown.
-  await remoteCall.callRemoteTestUtil('selectFile', appId, ['hello.txt']);
+  await remoteCall.waitUntilSelected(appId, 'hello.txt');
   await remoteCall.waitForElement(appId, '#tasks:not([hidden])');
 
   // Select dir and ensure action bar open is hidden, but context menu is shown.
-  await remoteCall.callRemoteTestUtil('selectFile', appId, ['photos']);
+  await remoteCall.waitUntilSelected(appId, 'photos');
   await remoteCall.waitForElement(appId, '#tasks[hidden]');
   chrome.test.assertTrue(!!await remoteCall.callRemoteTestUtil(
       'fakeMouseRightClick', appId, ['#file-list .table-row[selected]']));
diff --git a/ui/file_manager/integration_tests/file_manager/toolbar.js b/ui/file_manager/integration_tests/file_manager/toolbar.js
index 39293807..e970c7b 100644
--- a/ui/file_manager/integration_tests/file_manager/toolbar.js
+++ b/ui/file_manager/integration_tests/file_manager/toolbar.js
@@ -41,8 +41,7 @@
       await setupAndWaitUntilReady(RootPath.DRIVE, [], [ENTRIES.desktop]);
 
   // Select My Desktop Background.png
-  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
-      'selectFile', appId, [ENTRIES.desktop.nameText]));
+  await remoteCall.waitUntilSelected(appId, ENTRIES.desktop.nameText);
 
   // Click the toolbar Delete button.
   await remoteCall.simulateUiClick(appId, '#delete-button');
@@ -85,8 +84,7 @@
   await remoteCall.waitForFiles(appId, files, {ignoreLastModifiedTime: true});
 
   // Select hello.txt
-  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
-      'selectFile', appId, [ENTRIES.hello.nameText]));
+  await remoteCall.waitUntilSelected(appId, ENTRIES.hello.nameText);
 
   // Click the toolbar Delete button.
   await remoteCall.simulateUiClick(appId, '#delete-button');
@@ -136,8 +134,7 @@
       appId, beforeDeletion, {ignoreLastModifiedTime: true});
 
   // Select My Desktop Background.png
-  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
-      'selectFile', appId, ['My Desktop Background.png']));
+  await remoteCall.waitUntilSelected(appId, 'My Desktop Background.png');
 
   // Click delete button in the toolbar.
   if (await sendTestMessage({name: 'isTrashEnabled'}) === 'true') {
@@ -256,8 +253,7 @@
       'overrideTasks', appId, [DOWNLOADS_FAKE_TASKS]);
 
   // Select an entry in the file list.
-  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
-      'selectFile', appId, [entry.nameText]));
+  await remoteCall.waitUntilSelected(appId, entry.nameText);
 
   // Click the toolbar search button.
   await remoteCall.waitAndClickElement(appId, '#search-button');
@@ -309,8 +305,7 @@
   const entry = ENTRIES.hello;
 
   // Select an entry in the file list.
-  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
-      'selectFile', appId, [entry.nameText]));
+  await remoteCall.waitUntilSelected(appId, entry.nameText);
 
   await remoteCall.waitAndClickElement(
       appId, '#sharesheet-button:not([hidden])');
@@ -350,8 +345,7 @@
   const entry = ENTRIES.hello;
 
   // Select an entry in the file list.
-  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
-      'selectFile', appId, [entry.nameText]));
+  await remoteCall.waitUntilSelected(appId, entry.nameText);
 
   chrome.test.assertTrue(!!await remoteCall.waitAndRightClick(
       appId, '#file-list .table-row[selected]'));
diff --git a/ui/file_manager/integration_tests/file_manager/transfer.js b/ui/file_manager/integration_tests/file_manager/transfer.js
index 2e6f8c5..aa4b904 100644
--- a/ui/file_manager/integration_tests/file_manager/transfer.js
+++ b/ui/file_manager/integration_tests/file_manager/transfer.js
@@ -170,8 +170,8 @@
       'focus', appId, ['#file-list:not([hidden])']);
 
   // Select the source file.
-  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
-      'selectFile', appId, [transferInfo.fileToTransfer.nameText]));
+  await remoteCall.waitUntilSelected(
+      appId, transferInfo.fileToTransfer.nameText);
 
   // Copy the file.
   const transferCommand = transferInfo.isMove ? 'cut' : 'copy';
@@ -988,8 +988,7 @@
   const appId = await setupAndWaitUntilReady(RootPath.DOWNLOADS, [entry], []);
 
   // Select the file.
-  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
-      'selectFile', appId, [entry.nameText]));
+  await remoteCall.waitUntilSelected(appId, entry.nameText);
 
   // Copy the file.
   chrome.test.assertTrue(
@@ -1044,8 +1043,7 @@
   let appId = await setupAndWaitUntilReady(RootPath.DOWNLOADS, [entry], []);
 
   // Select the file.
-  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
-      'selectFile', appId, [entry.nameText]));
+  await remoteCall.waitUntilSelected(appId, entry.nameText);
 
   // Copy the file.
   chrome.test.assertTrue(
@@ -1095,8 +1093,7 @@
   await remoteCall.waitForElement(appId, USB_VOLUME_QUERY);
 
   // Select the file.
-  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
-      'selectFile', appId, [entry.nameText]));
+  await remoteCall.waitUntilSelected(appId, entry.nameText);
 
   // Copy the file.
   chrome.test.assertTrue(
@@ -1138,8 +1135,7 @@
   let appId = await setupAndWaitUntilReady(RootPath.DOWNLOADS, [entry], []);
 
   // Select a file to copy.
-  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
-      'selectFile', appId, [entry.nameText]));
+  await remoteCall.waitUntilSelected(appId, entry.nameText);
 
   // Copy the file.
   chrome.test.assertTrue(
diff --git a/ui/file_manager/integration_tests/file_manager/trash.js b/ui/file_manager/integration_tests/file_manager/trash.js
index 6e9e9bf1..cc58051 100644
--- a/ui/file_manager/integration_tests/file_manager/trash.js
+++ b/ui/file_manager/integration_tests/file_manager/trash.js
@@ -237,10 +237,7 @@
   await navigateWithDirectoryTree(appId, '/Trash');
 
   // Select file.
-  const deleted = ['My files › Downloads › hello.txt'];
-  chrome.test.assertTrue(
-      !!await remoteCall.callRemoteTestUtil('selectFile', appId, deleted),
-      'selectFile failed');
+  await remoteCall.waitUntilSelected(appId, 'My files › Downloads › hello.txt');
 
   // Press 'Delete' key.
   chrome.test.assertTrue(!!await remoteCall.callRemoteTestUtil(
diff --git a/ui/file_manager/integration_tests/file_manager/zip_files.js b/ui/file_manager/integration_tests/file_manager/zip_files.js
index e89aa197..a8873f83 100644
--- a/ui/file_manager/integration_tests/file_manager/zip_files.js
+++ b/ui/file_manager/integration_tests/file_manager/zip_files.js
@@ -50,10 +50,7 @@
       RootPath.DOWNLOADS, [ENTRIES.zipArchive], []);
 
   // Select the zip file.
-  chrome.test.assertTrue(
-      !!await remoteCall.callRemoteTestUtil(
-          'selectFile', appId, ['archive.zip']),
-      'selectFile failed');
+  await remoteCall.waitUntilSelected(appId, ENTRIES.zipArchive.nameText);
 
   // Press the Enter key.
   const key = ['#file-list', 'Enter', false, false, false];
@@ -104,10 +101,7 @@
       await setupAndWaitUntilReady(RootPath.DRIVE, [], [ENTRIES.zipArchive]);
 
   // Select the zip file.
-  chrome.test.assertTrue(
-      !!await remoteCall.callRemoteTestUtil(
-          'selectFile', appId, ['archive.zip']),
-      'selectFile failed');
+  await remoteCall.waitUntilSelected(appId, ENTRIES.zipArchive.nameText);
 
   // Press the Enter key.
   const key = ['#file-list', 'Enter', false, false, false];
@@ -154,10 +148,7 @@
   await remoteCall.waitForFiles(appId, archive);
 
   // Select the zip file.
-  chrome.test.assertTrue(
-      !!await remoteCall.callRemoteTestUtil(
-          'selectFile', appId, ['archive.zip']),
-      'selectFile failed');
+  await remoteCall.waitUntilSelected(appId, ENTRIES.zipArchive.nameText);
 
   // Press the Enter key.
   const key = ['#file-list', 'Enter', false, false, false];
@@ -190,9 +181,7 @@
       await setupAndWaitUntilReady(RootPath.DOWNLOADS, [ENTRIES.photos], []);
 
   // Select the file.
-  chrome.test.assertTrue(
-      !!await remoteCall.callRemoteTestUtil('selectFile', appId, ['photos']),
-      'selectFile failed');
+  await remoteCall.waitUntilSelected(appId, ENTRIES.photos.nameText);
 
   // Right-click the selected file.
   chrome.test.assertTrue(
@@ -226,9 +215,7 @@
       await setupAndWaitUntilReady(RootPath.DRIVE, [], [ENTRIES.photos]);
 
   // Select the file.
-  chrome.test.assertTrue(
-      !!await remoteCall.callRemoteTestUtil('selectFile', appId, ['photos']),
-      'selectFile failed');
+  await remoteCall.waitUntilSelected(appId, ENTRIES.photos.nameText);
 
   // Right-click the selected file.
   chrome.test.assertTrue(
@@ -281,9 +268,7 @@
   await remoteCall.waitForFiles(appId, photos);
 
   // Select the photos file list entry.
-  chrome.test.assertTrue(
-      !!await remoteCall.callRemoteTestUtil('selectFile', appId, ['photos']),
-      'selectFile failed');
+  await remoteCall.waitUntilSelected(appId, ENTRIES.photos.nameText);
 
   // Right-click the selected file.
   chrome.test.assertTrue(
@@ -326,8 +311,7 @@
   const appId = await setupAndWaitUntilReady(RootPath.DOWNLOADS, [entry], []);
 
   // Select the file.
-  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
-      'selectFile', appId, [entry.nameText]));
+  await remoteCall.waitUntilSelected(appId, entry.nameText);
 
   // Right-click the selected file.
   chrome.test.assertTrue(
@@ -453,8 +437,7 @@
   const appId = await setupAndWaitUntilReady(RootPath.DOWNLOADS, entries, []);
 
   // Select the first file (ENTRIES.hello).
-  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
-      'selectFile', appId, [entries[0].nameText]));
+  await remoteCall.waitUntilSelected(appId, entries[0].nameText);
 
   // Right-click the selected file.
   chrome.test.assertTrue(
@@ -479,8 +462,7 @@
       'fakeMouseClick failed');
 
   // Select the third file (ENTRIES.zipArchive).
-  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
-      'selectFile', appId, [entries[2].nameText]));
+  await remoteCall.waitUntilSelected(appId, entries[2].nameText);
 
   // Right-click the selected file.
   chrome.test.assertTrue(
@@ -574,8 +556,7 @@
   const appId = await setupAndWaitUntilReady(RootPath.DOWNLOADS, [entry], []);
 
   // Select the file.
-  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
-      'selectFile', appId, [entry.nameText]));
+  await remoteCall.waitUntilSelected(appId, entry.nameText);
 
   // Right-click the selected file.
   chrome.test.assertTrue(
@@ -626,8 +607,7 @@
   const appId = await setupAndWaitUntilReady(RootPath.DOWNLOADS, [entry], []);
 
   // Select the file.
-  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
-      'selectFile', appId, [entry.nameText]));
+  await remoteCall.waitUntilSelected(appId, entry.nameText);
 
   // Right-click the selected file.
   chrome.test.assertTrue(
@@ -703,8 +683,7 @@
   const appId = await setupAndWaitUntilReady(RootPath.DOWNLOADS, [entry], []);
 
   // Select the file.
-  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
-      'selectFile', appId, [entry.nameText]));
+  await remoteCall.waitUntilSelected(appId, entry.nameText);
 
   // Right-click the selected file.
   chrome.test.assertTrue(
@@ -749,8 +728,7 @@
   const appId = await setupAndWaitUntilReady(RootPath.DOWNLOADS, [entry], []);
 
   // Select the file.
-  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
-      'selectFile', appId, [entry.nameText]));
+  await remoteCall.waitUntilSelected(appId, entry.nameText);
 
   // Right-click the selected file.
   chrome.test.assertTrue(
@@ -777,8 +755,7 @@
   const appId = await setupAndWaitUntilReady(RootPath.DOWNLOADS, [entry], []);
 
   // Select the file.
-  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
-      'selectFile', appId, [entry.nameText]));
+  await remoteCall.waitUntilSelected(appId, entry.nameText);
 
   // Right-click the selected file.
   chrome.test.assertTrue(
@@ -848,8 +825,7 @@
   await remoteCall.waitForFiles(appId, [entry.getExpectedRow()]);
 
   // Select the ZIP file.
-  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
-      'selectFile', appId, [entry.nameText]));
+  await remoteCall.waitUntilSelected(appId, entry.nameText);
 
   // Right-click the selected file.
   chrome.test.assertTrue(
diff --git a/ui/file_manager/integration_tests/remote_call.js b/ui/file_manager/integration_tests/remote_call.js
index 4d396b58..651fad61 100644
--- a/ui/file_manager/integration_tests/remote_call.js
+++ b/ui/file_manager/integration_tests/remote_call.js
@@ -754,6 +754,30 @@
   }
 
   /**
+   * Returns a promise that repeatedly checks for a file with the given
+   * name to be selected in the app window with the given ID. Typical
+   * use
+   *
+   * await remoteCall.waitUntilSelected('file#0', 'hello.txt');
+   * ... // either the test timed out or hello.txt is currently selected.
+   *
+   * @param {string} appId App window Id.
+   * @param {string} fileName the name of the file to be selected.
+   * @return {Promise<boolean>} Promise that indicates if selection was
+   *     successful.
+   */
+  waitUntilSelected(appId, fileName) {
+    const caller = getCaller();
+    return repeatUntil(async () => {
+      const selected =
+          await this.callRemoteTestUtil('selectFile', appId, [fileName]);
+      if (!selected) {
+        return pending(caller, `File ${fileName} not yet selected`);
+      }
+    });
+  }
+
+  /**
    * Waits until the current directory is changed.
    * @param {string} appId App window Id.
    * @param {string} expectedPath Path to be changed to.
diff --git a/ui/ozone/platform/wayland/host/wayland_connection.cc b/ui/ozone/platform/wayland/host/wayland_connection.cc
index b8e77c1..e3058a7 100644
--- a/ui/ozone/platform/wayland/host/wayland_connection.cc
+++ b/ui/ozone/platform/wayland/host/wayland_connection.cc
@@ -80,7 +80,7 @@
 constexpr uint32_t kMaxWpPresentationVersion = 1;
 constexpr uint32_t kMaxWpViewporterVersion = 1;
 constexpr uint32_t kMaxTextInputManagerVersion = 1;
-constexpr uint32_t kMaxTextInputExtensionVersion = 4;
+constexpr uint32_t kMaxTextInputExtensionVersion = 5;
 constexpr uint32_t kMaxExplicitSyncVersion = 2;
 constexpr uint32_t kMaxAlphaCompositingVersion = 1;
 constexpr uint32_t kMaxXdgDecorationVersion = 1;
diff --git a/ui/ozone/platform/wayland/host/wayland_input_method_context.cc b/ui/ozone/platform/wayland/host/wayland_input_method_context.cc
index 23ef3fa..778dfc0 100644
--- a/ui/ozone/platform/wayland/host/wayland_input_method_context.cc
+++ b/ui/ozone/platform/wayland/host/wayland_input_method_context.cc
@@ -133,8 +133,8 @@
 
 WaylandInputMethodContext::~WaylandInputMethodContext() {
   if (text_input_) {
+    DismissVirtualKeyboard();
     text_input_->Deactivate();
-    text_input_->HideInputPanel();
   }
   connection_->wayland_window_manager()->RemoveObserver(this);
 }
@@ -207,20 +207,24 @@
 void WaylandInputMethodContext::UpdateFocus(bool has_client,
                                             TextInputType old_type,
                                             TextInputType new_type) {
+  // This prevents unnecessarily hiding/showing the virtual keyboard.
+  bool skip_vk_update =
+      old_type != TEXT_INPUT_TYPE_NONE && new_type != TEXT_INPUT_TYPE_NONE;
+
   if (old_type != TEXT_INPUT_TYPE_NONE)
-    Blur();
+    Blur(skip_vk_update);
   if (new_type != TEXT_INPUT_TYPE_NONE)
-    Focus();
+    Focus(skip_vk_update);
 }
 
-void WaylandInputMethodContext::Focus() {
+void WaylandInputMethodContext::Focus(bool skip_virtual_keyboard_update) {
   focused_ = true;
-  MaybeUpdateActivated();
+  MaybeUpdateActivated(skip_virtual_keyboard_update);
 }
 
-void WaylandInputMethodContext::Blur() {
+void WaylandInputMethodContext::Blur(bool skip_virtual_keyboard_update) {
   focused_ = false;
-  MaybeUpdateActivated();
+  MaybeUpdateActivated(skip_virtual_keyboard_update);
 }
 
 void WaylandInputMethodContext::SetCursorLocation(const gfx::Rect& rect) {
@@ -629,6 +633,11 @@
   ime_delegate_->OnSetAutocorrectRange(range);
 }
 
+void WaylandInputMethodContext::OnSetVirtualKeyboardOccludedBounds(
+    const gfx::Rect& screen_bounds) {
+  ime_delegate_->OnSetVirtualKeyboardOccludedBounds(screen_bounds);
+}
+
 void WaylandInputMethodContext::OnInputPanelState(uint32_t state) {
   virtual_keyboard_visible_ = (state & 1) != 0;
   // Note: Currently there's no support of VirtualKeyboardControllerObserver.
@@ -643,10 +652,11 @@
 }
 
 void WaylandInputMethodContext::OnKeyboardFocusedWindowChanged() {
-  MaybeUpdateActivated();
+  MaybeUpdateActivated(false);
 }
 
-void WaylandInputMethodContext::MaybeUpdateActivated() {
+void WaylandInputMethodContext::MaybeUpdateActivated(
+    bool skip_virtual_keyboard_update) {
   if (!text_input_)
     return;
 
@@ -666,10 +676,12 @@
   activated_ = activated;
   if (activated) {
     text_input_->Activate(window);
-    text_input_->ShowInputPanel();
+    if (!skip_virtual_keyboard_update)
+      DisplayVirtualKeyboard();
   } else {
+    if (!skip_virtual_keyboard_update)
+      DismissVirtualKeyboard();
     text_input_->Deactivate();
-    text_input_->HideInputPanel();
   }
 }
 
diff --git a/ui/ozone/platform/wayland/host/wayland_input_method_context.h b/ui/ozone/platform/wayland/host/wayland_input_method_context.h
index 859039d..24d0a57 100644
--- a/ui/ozone/platform/wayland/host/wayland_input_method_context.h
+++ b/ui/ozone/platform/wayland/host/wayland_input_method_context.h
@@ -82,19 +82,23 @@
   void OnSetPreeditRegion(int32_t index,
                           uint32_t length,
                           const std::vector<SpanStyle>& spans) override;
-
   void OnClearGrammarFragments(const gfx::Range& range) override;
   void OnAddGrammarFragment(const GrammarFragment& fragment) override;
   void OnSetAutocorrectRange(const gfx::Range& range) override;
-
+  void OnSetVirtualKeyboardOccludedBounds(
+      const gfx::Rect& screen_bounds) override;
   void OnInputPanelState(uint32_t state) override;
   void OnModifiersMap(std::vector<std::string> modifiers_map) override;
 
  private:
-  void Focus();
-  void Blur();
+  void Focus(bool skip_virtual_keyboard_update);
+  void Blur(bool skip_virtual_keyboard_update);
   void UpdatePreeditText(const std::u16string& preedit_text);
-  void MaybeUpdateActivated();
+  // If |skip_virtual_keyboard_update| is true, no virtual keyboard show/hide
+  // requests will be sent. This is used to prevent flickering the virtual
+  // keyboard when it would be immediately reshown anyway, e.g. when changing
+  // focus from one text input to another.
+  void MaybeUpdateActivated(bool skip_virtual_keyboard_update);
 
   const raw_ptr<WaylandConnection>
       connection_;  // TODO(jani) Handle this better
diff --git a/ui/ozone/platform/wayland/host/wayland_input_method_context_unittest.cc b/ui/ozone/platform/wayland/host/wayland_input_method_context_unittest.cc
index 0d4580b..62d47f9 100644
--- a/ui/ozone/platform/wayland/host/wayland_input_method_context_unittest.cc
+++ b/ui/ozone/platform/wayland/host/wayland_input_method_context_unittest.cc
@@ -28,6 +28,7 @@
 
 using ::testing::_;
 using ::testing::DoAll;
+using ::testing::InSequence;
 using ::testing::Mock;
 using ::testing::SaveArg;
 using ::testing::Values;
@@ -85,6 +86,11 @@
     was_on_set_preedit_region_called_ = true;
   }
 
+  void OnSetVirtualKeyboardOccludedBounds(
+      const gfx::Rect& screen_bounds) override {
+    virtual_keyboard_bounds_ = screen_bounds;
+  }
+
   bool was_on_commit_called() const { return was_on_commit_called_; }
 
   bool was_on_confirm_composition_text_called() const {
@@ -116,6 +122,10 @@
     return last_on_delete_surrounding_text_args_;
   }
 
+  const absl::optional<gfx::Rect>& virtual_keyboard_bounds() const {
+    return virtual_keyboard_bounds_;
+  }
+
  private:
   bool was_on_commit_called_ = false;
   bool was_on_confirm_composition_text_called_ = false;
@@ -126,6 +136,7 @@
   bool was_on_set_autocorrect_range_called_ = false;
   absl::optional<std::pair<size_t, size_t>>
       last_on_delete_surrounding_text_args_;
+  absl::optional<gfx::Rect> virtual_keyboard_bounds_;
 };
 
 class WaylandInputMethodContextTest : public WaylandTest {
@@ -190,6 +201,7 @@
   // Scenario 1: InputMethod focus is set, then Keyboard focus is set.
   // Unset them in the reversed order.
 
+  InSequence s;
   EXPECT_CALL(*zwp_text_input_, Activate(surface_->resource())).Times(0);
   EXPECT_CALL(*zwp_text_input_, ShowInputPanel()).Times(0);
   input_method_context_->UpdateFocus(true, ui::TEXT_INPUT_TYPE_NONE,
@@ -206,15 +218,15 @@
   Sync();
   Mock::VerifyAndClearExpectations(zwp_text_input_);
 
-  EXPECT_CALL(*zwp_text_input_, Deactivate());
   EXPECT_CALL(*zwp_text_input_, HideInputPanel());
+  EXPECT_CALL(*zwp_text_input_, Deactivate());
   connection_->wayland_window_manager()->SetKeyboardFocusedWindow(nullptr);
   connection_->ScheduleFlush();
   Sync();
   Mock::VerifyAndClearExpectations(zwp_text_input_);
 
-  EXPECT_CALL(*zwp_text_input_, Deactivate()).Times(0);
   EXPECT_CALL(*zwp_text_input_, HideInputPanel()).Times(0);
+  EXPECT_CALL(*zwp_text_input_, Deactivate()).Times(0);
   input_method_context_->UpdateFocus(true, ui::TEXT_INPUT_TYPE_TEXT,
                                      ui::TEXT_INPUT_TYPE_NONE);
   connection_->ScheduleFlush();
@@ -239,16 +251,16 @@
   Sync();
   Mock::VerifyAndClearExpectations(zwp_text_input_);
 
-  EXPECT_CALL(*zwp_text_input_, Deactivate());
   EXPECT_CALL(*zwp_text_input_, HideInputPanel());
+  EXPECT_CALL(*zwp_text_input_, Deactivate());
   input_method_context_->UpdateFocus(true, ui::TEXT_INPUT_TYPE_TEXT,
                                      ui::TEXT_INPUT_TYPE_NONE);
   connection_->ScheduleFlush();
   Sync();
   Mock::VerifyAndClearExpectations(zwp_text_input_);
 
-  EXPECT_CALL(*zwp_text_input_, Deactivate()).Times(0);
   EXPECT_CALL(*zwp_text_input_, HideInputPanel()).Times(0);
+  EXPECT_CALL(*zwp_text_input_, Deactivate()).Times(0);
   connection_->wayland_window_manager()->SetKeyboardFocusedWindow(nullptr);
   connection_->ScheduleFlush();
   Sync();
@@ -589,6 +601,13 @@
       input_method_context_delegate_->was_on_set_autocorrect_range_called());
 }
 
+TEST_P(WaylandInputMethodContextTest, OnSetVirtualKeyboardOccludedBounds) {
+  const gfx::Rect bounds(10, 20, 300, 400);
+  input_method_context_->OnSetVirtualKeyboardOccludedBounds(bounds);
+  Sync();
+  EXPECT_EQ(input_method_context_delegate_->virtual_keyboard_bounds(), bounds);
+}
+
 TEST_P(WaylandInputMethodContextTest, DisplayVirtualKeyboard) {
   EXPECT_CALL(*zwp_text_input_, ShowInputPanel());
   EXPECT_TRUE(input_method_context_->DisplayVirtualKeyboard());
@@ -635,6 +654,7 @@
   // Because there is no keyboard, Activate is called as soon as InputMethod's
   // TextInputClient focus is met.
 
+  InSequence s;
   EXPECT_CALL(*zwp_text_input_, Activate(surface_->resource()));
   EXPECT_CALL(*zwp_text_input_, ShowInputPanel());
   input_method_context_->UpdateFocus(true, ui::TEXT_INPUT_TYPE_NONE,
@@ -643,8 +663,8 @@
   Sync();
   Mock::VerifyAndClearExpectations(zwp_text_input_);
 
-  EXPECT_CALL(*zwp_text_input_, Deactivate());
   EXPECT_CALL(*zwp_text_input_, HideInputPanel());
+  EXPECT_CALL(*zwp_text_input_, Deactivate());
   input_method_context_->UpdateFocus(false, ui::TEXT_INPUT_TYPE_TEXT,
                                      ui::TEXT_INPUT_TYPE_NONE);
   connection_->ScheduleFlush();
@@ -652,6 +672,31 @@
   Mock::VerifyAndClearExpectations(zwp_text_input_);
 }
 
+TEST_P(WaylandInputMethodContextNoKeyboardTest, UpdateFocusBetweenTextFields) {
+  // Because there is no keyboard, Activate is called as soon as InputMethod's
+  // TextInputClient focus is met.
+
+  InSequence s;
+  EXPECT_CALL(*zwp_text_input_, Activate(surface_->resource()));
+  EXPECT_CALL(*zwp_text_input_, ShowInputPanel());
+  input_method_context_->UpdateFocus(true, ui::TEXT_INPUT_TYPE_NONE,
+                                     ui::TEXT_INPUT_TYPE_TEXT);
+  connection_->ScheduleFlush();
+  Sync();
+  Mock::VerifyAndClearExpectations(zwp_text_input_);
+
+  // Make sure virtual keyboard is not unnecessarily hidden.
+  EXPECT_CALL(*zwp_text_input_, HideInputPanel()).Times(0);
+  EXPECT_CALL(*zwp_text_input_, Deactivate());
+  EXPECT_CALL(*zwp_text_input_, Activate(surface_->resource()));
+  EXPECT_CALL(*zwp_text_input_, ShowInputPanel()).Times(0);
+  input_method_context_->UpdateFocus(false, ui::TEXT_INPUT_TYPE_TEXT,
+                                     ui::TEXT_INPUT_TYPE_TEXT);
+  connection_->ScheduleFlush();
+  Sync();
+  Mock::VerifyAndClearExpectations(zwp_text_input_);
+}
+
 INSTANTIATE_TEST_SUITE_P(XdgVersionStableTest,
                          WaylandInputMethodContextTest,
                          Values(wl::ServerConfig{
diff --git a/ui/ozone/platform/wayland/host/zwp_text_input_wrapper.h b/ui/ozone/platform/wayland/host/zwp_text_input_wrapper.h
index 6796ace..f885230 100644
--- a/ui/ozone/platform/wayland/host/zwp_text_input_wrapper.h
+++ b/ui/ozone/platform/wayland/host/zwp_text_input_wrapper.h
@@ -86,6 +86,11 @@
   // |range| is in UTF-16 code range.
   virtual void OnSetAutocorrectRange(const gfx::Range& range) = 0;
 
+  // Called when the virtual keyboard's occluded bounds is updated.
+  // The bounds are in screen DIP.
+  virtual void OnSetVirtualKeyboardOccludedBounds(
+      const gfx::Rect& screen_bounds) = 0;
+
   // Called when the visibility state of the input panel changed.
   // There's no detailed spec of |state|, and no actual implementor except
   // components/exo is found in the world at this moment.
diff --git a/ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v1.cc b/ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v1.cc
index e72e404..97eda7d 100644
--- a/ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v1.cc
+++ b/ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v1.cc
@@ -125,6 +125,7 @@
           &OnClearGrammarFragments,  // extended_text_input_clear_grammar_fragments,
           &OnAddGrammarFragment,   // extended_text_input_add_grammar_fragment,
           &OnSetAutocorrectRange,  // extended_text_input_set_autocorrect_range,
+          &OnSetVirtualKeyboardOccludedBounds,  // extended_text_input_set_virtual_keyboard_occluded_bounds,
       };
 
   auto* text_input =
@@ -408,4 +409,17 @@
   self->client_->OnSetAutocorrectRange(gfx::Range(start, end));
 }
 
+// static
+void ZWPTextInputWrapperV1::OnSetVirtualKeyboardOccludedBounds(
+    void* data,
+    struct zcr_extended_text_input_v1* extended_text_input,
+    int32_t x,
+    int32_t y,
+    int32_t width,
+    int32_t height) {
+  auto* self = static_cast<ZWPTextInputWrapperV1*>(data);
+  gfx::Rect screen_bounds(x, y, width, height);
+  self->client_->OnSetVirtualKeyboardOccludedBounds(screen_bounds);
+}
+
 }  // namespace ui
diff --git a/ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v1.h b/ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v1.h
index 80aeea4..fd17d52 100644
--- a/ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v1.h
+++ b/ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v1.h
@@ -116,25 +116,29 @@
       struct zcr_extended_text_input_v1* extended_text_input,
       int32_t index,
       uint32_t length);
-
   static void OnClearGrammarFragments(
       void* data,
       struct zcr_extended_text_input_v1* extended_text_input,
       uint32_t start,
       uint32_t end);
-
   static void OnAddGrammarFragment(
       void* data,
       struct zcr_extended_text_input_v1* extended_text_input,
       uint32_t start,
       uint32_t end,
       const char* suggestion);
-
   static void OnSetAutocorrectRange(
       void* data,
       struct zcr_extended_text_input_v1* extended_text_input,
       uint32_t start,
       uint32_t end);
+  static void OnSetVirtualKeyboardOccludedBounds(
+      void* data,
+      struct zcr_extended_text_input_v1* extended_text_input,
+      int32_t x,
+      int32_t y,
+      int32_t width,
+      int32_t height);
 
   const raw_ptr<WaylandConnection> connection_;
   wl::Object<zwp_text_input_v1> obj_;
diff --git a/ui/views/controls/textfield/textfield_unittest.cc b/ui/views/controls/textfield/textfield_unittest.cc
index 4954d47..876e872 100644
--- a/ui/views/controls/textfield/textfield_unittest.cc
+++ b/ui/views/controls/textfield/textfield_unittest.cc
@@ -3534,7 +3534,7 @@
   EXPECT_EQ(widget_->GetNativeView()->bounds(), orig_widget_bounds);
 
   // Simulate virtual keyboard.
-  input_method_->SetOnScreenKeyboardBounds(keyboard_view_bounds);
+  input_method_->SetVirtualKeyboardBounds(keyboard_view_bounds);
 
   // Window should be shifted.
   EXPECT_EQ(widget_->GetNativeView()->bounds(), shifted_widget_bounds);
diff --git a/ui/webui/resources/js/browser_command/browser_command.mojom b/ui/webui/resources/js/browser_command/browser_command.mojom
index a0cc369..749b01eb 100644
--- a/ui/webui/resources/js/browser_command/browser_command.mojom
+++ b/ui/webui/resources/js/browser_command/browser_command.mojom
@@ -22,6 +22,7 @@
   kOpenPrivacyGuide = 4,
   kStartTabGroupTutorial = 5,
   kOpenPasswordManager = 6,
+  kNoOpCommand = 7,
 };
 
 // Click information needed to determine user's desired window disposition using