diff --git a/DEPS b/DEPS
index 8617c31..2e6d65a 100644
--- a/DEPS
+++ b/DEPS
@@ -303,15 +303,15 @@
   # 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': '63bed826008ee7e0170ce9224c6aaab1b2f720f7',
+  'skia_revision': '6dc3b52777daccbaf1f3a28b2e2bd39c7a4d38e1',
   # 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': '457c0cbb2f97c9a56941eb48b95e0234d0739cd3',
+  'v8_revision': 'a6128e4e5e13d5352e267b2824f0835b2cbe4a70',
   # 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': 'd704273d78967f286c300d445bdc0eb9f43b2389',
+  'angle_revision': 'bd5dce9a8e8525527501da49d7807130bb9e39a1',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -330,7 +330,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:17.20231211.2.1',
+  'fuchsia_version': 'version:17.20231218.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.
@@ -378,7 +378,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling chromium_variations
   # and whatever else without interference from each other.
-  'chromium_variations_revision': '6a94fae344833b2e4c170955c9b10fa3a40c5550',
+  'chromium_variations_revision': '118eb368c73b8895223c9614b11b48ec5d3ec851',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling CrossBench
   # and whatever else without interference from each other.
@@ -394,7 +394,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling devtools-frontend
   # and whatever else without interference from each other.
-  'devtools_frontend_revision': '891806c2cf2bfe370e5e865269042afafbf9a569',
+  'devtools_frontend_revision': 'abd45dd7ffc41e93c8c3d7bf82ca7bcb420d94a1',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libprotobuf-mutator
   # and whatever else without interference from each other.
@@ -450,7 +450,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling nearby
   # and whatever else without interference from each other.
-  'nearby_revision': '85091845a8471a776df9461d476f733304b13c8e',
+  'nearby_revision': '32740f8591a568a2e3a6f54b018cd0874e5af2ff',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling securemessage
   # and whatever else without interference from each other.
@@ -462,7 +462,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.
-  'cros_components_revision': 'f448b44c03202bdb5fb1305216d4723724d5288b',
+  'cros_components_revision': 'e8ae400644fdede4c5bbaa6e8157e6411c6b0b7e',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -818,7 +818,7 @@
 
   'src/clank': {
     'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' +
-    '81557d351b8541438b80a494040df59f3eec95fd',
+    '07122eaa37ba1580a2f75247c51ee4ee4c650ba4',
     'condition': 'checkout_android and checkout_src_internal',
   },
 
@@ -1196,7 +1196,7 @@
     Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'),
 
   'src/third_party/devtools-frontend-internal': {
-      'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '6b248f365bc8723b398e68704df495ecfbf3f8ee',
+      'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '1b8b0c8770a2e7a17e0b9297b464364d5a363839',
     'condition': 'checkout_src_internal',
   },
 
@@ -1793,7 +1793,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' + '@' + '40fde191ba7aedececf64b73854a74b344bccdb7',
+    Var('chromium_git') + '/external/github.com/tensorflow/tensorflow.git' + '@' + '6ecc7e35b190face7769a9eb29f21aed7ea077cc',
 
   'src/third_party/turbine': {
       'packages': [
@@ -3949,7 +3949,7 @@
 
   'src/components/optimization_guide/internal': {
       'url': Var('chrome_git') + '/chrome/components/optimization_guide.git' + '@' +
-        'c5958b418ccfabbc5d4c216aada60902fd1c4784',
+        'd2162208bcf500cdd93945ddc7ee633361f9dfa5',
       'condition': 'checkout_src_internal',
   },
 
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc
index f550dd55..547800c2 100644
--- a/ash/constants/ash_features.cc
+++ b/ash/constants/ash_features.cc
@@ -1337,6 +1337,11 @@
              "HandwritingLegacyRecognition",
              base::FEATURE_ENABLED_BY_DEFAULT);
 
+// Enables downloading the handwriting libraries via DLC.
+BASE_FEATURE(kHandwritingLibraryDlc,
+             "HandwritingLibraryDlc",
+             base::FEATURE_ENABLED_BY_DEFAULT);
+
 // If enabled, the Help app will render the App Detail Page and entry point.
 BASE_FEATURE(kHelpAppAppDetailPage,
              "HelpAppAppDetailPage",
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h
index 5fc4f1f..217b263 100644
--- a/ash/constants/ash_features.h
+++ b/ash/constants/ash_features.h
@@ -438,6 +438,7 @@
 COMPONENT_EXPORT(ASH_CONSTANTS)
 BASE_DECLARE_FEATURE(kProductivityLauncherImageSearch);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kLauncherItemColorSync);
+COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kHandwritingLibraryDlc);
 COMPONENT_EXPORT(ASH_CONSTANTS)
 BASE_DECLARE_FEATURE(kHelpAppAppDetailPage);
 COMPONENT_EXPORT(ASH_CONSTANTS)
diff --git a/ash/system/time/calendar_event_list_item_view.cc b/ash/system/time/calendar_event_list_item_view.cc
index 3623bde..78a36a1 100644
--- a/ash/system/time/calendar_event_list_item_view.cc
+++ b/ash/system/time/calendar_event_list_item_view.cc
@@ -5,6 +5,7 @@
 #include "ash/system/time/calendar_event_list_item_view.h"
 
 #include <string>
+#include <string_view>
 
 #include "ash/bubble/bubble_utils.h"
 #include "ash/public/cpp/system_tray_client.h"
@@ -91,7 +92,7 @@
                                               : SK_AlphaOPAQUE) {
     DCHECK(color_id.empty() || kEventHexColorCodes.count(color_id));
 
-    base::BasicStringPiece<char> hex_code = LookupColorId(color_id);
+    std::string_view hex_code = LookupColorId(color_id);
     base::HexStringToInt(hex_code, &color_);
     SetPreferredSize(gfx::Size(
         kColorDotViewSize,
@@ -113,7 +114,7 @@
   }
 
  private:
-  base::BasicStringPiece<char> LookupColorId(std::string color_id) {
+  std::string_view LookupColorId(std::string color_id) {
     const auto* iter = kEventHexColorCodes.find(color_id);
     if (iter == kEventHexColorCodes.end()) {
       return kEventHexColorCodes.at(kDefaultColorId);
diff --git a/ash/webui/camera_app_ui/resources/js/barcode_chip.ts b/ash/webui/camera_app_ui/resources/js/barcode_chip.ts
index ef7c559..f9acc308 100644
--- a/ash/webui/camera_app_ui/resources/js/barcode_chip.ts
+++ b/ash/webui/camera_app_ui/resources/js/barcode_chip.ts
@@ -22,7 +22,6 @@
   securityType: string;
   ssid: string|null;
   password: string|null;
-  hidden: boolean;
   eapMethod: string|null;     // EAP only
   anonIdentity: string|null;  // EAP only
   identity: string|null;      // EAP only
@@ -108,7 +107,6 @@
     securityType: 'nopass',
     ssid: null,
     password: null,
-    hidden: false,
     eapMethod: null,
     anonIdentity: null,
     identity: null,
@@ -139,9 +137,7 @@
             wifiConfig.eapMethod = val;
             break;
           case 'H':
-            if (val === 'true') {
-              wifiConfig.hidden = true;
-            } else if (val !== 'false') {
+            if (val !== 'true' && val !== 'false') {
               wifiConfig.phase2method = val;
             }
             break;
diff --git a/ash/webui/camera_app_ui/resources/js/lit/components/mode-selector.ts b/ash/webui/camera_app_ui/resources/js/lit/components/mode-selector.ts
index 9cc2318..9db2223f 100644
--- a/ash/webui/camera_app_ui/resources/js/lit/components/mode-selector.ts
+++ b/ash/webui/camera_app_ui/resources/js/lit/components/mode-selector.ts
@@ -241,8 +241,10 @@
         repeat(shownModes, (mode) => mode, (mode) => this.renderModeItem(mode));
     return html`
       <div id="modes-group"
+          role="radiogroup"
           @click=${this.handleClick}
-          @change=${this.handleChange}>
+          @change=${this.handleChange}
+          aria-label=${getI18nMessage(I18nString.ARIA_CAMERA_MODE_GROUP)}>
         ${modeItems}
       </div>
     `;
diff --git a/ash/webui/camera_app_ui/resources/js/lit/components/switch-device-button.ts b/ash/webui/camera_app_ui/resources/js/lit/components/switch-device-button.ts
index 67b7324eb..1b11995 100644
--- a/ash/webui/camera_app_ui/resources/js/lit/components/switch-device-button.ts
+++ b/ash/webui/camera_app_ui/resources/js/lit/components/switch-device-button.ts
@@ -26,7 +26,6 @@
         align-items: center;
         border-radius: 50%;
         display: flex;
-        flex-shrink: 0;
         height: var(--big-icon);
         justify-content: center;
         outline-offset: 8px;
diff --git a/ash/webui/camera_app_ui/resources/js/test/cca_test.ts b/ash/webui/camera_app_ui/resources/js/test/cca_test.ts
index 7a67b33..49272b00 100644
--- a/ash/webui/camera_app_ui/resources/js/test/cca_test.ts
+++ b/ash/webui/camera_app_ui/resources/js/test/cca_test.ts
@@ -404,6 +404,15 @@
   }
 
   /**
+   * Gets the cover image URL of the gallery button.
+   */
+  static getGalleryButtonCoverURL(): string {
+    return assertExists(resolveElement('galleryButton').querySelector('img'))
+               .getAttribute('src') ??
+        '';
+  }
+
+  /**
    * Performs mouse hold by sending pointerdown and pointerup events.
    */
   static async hold(component: UIComponent, ms: number, index?: number):
diff --git a/base/android/scoped_java_ref.h b/base/android/scoped_java_ref.h
index 326e012..8ebe75a 100644
--- a/base/android/scoped_java_ref.h
+++ b/base/android/scoped_java_ref.h
@@ -8,7 +8,7 @@
 #include <jni.h>
 #include <stddef.h>
 
-#include <type_traits>
+#include <concepts>
 #include <utility>
 
 #include "base/base_export.h"
@@ -123,9 +123,8 @@
   // Only defined for JavaRef<jobjectArray>.
   // You must pass the type of the array elements (usually jobject) as the
   // template parameter.
-  template <typename ElementType,
-            typename T_ = T,
-            typename = std::enable_if_t<std::is_same_v<T_, jobjectArray>>>
+  template <typename ElementType>
+    requires(std::same_as<T, jobjectArray>)
   JavaObjectArrayReader<ElementType> ReadElements() const {
     return JavaObjectArrayReader<ElementType>(*this);
   }
@@ -191,8 +190,8 @@
   }
 
   // Copy conversion constructor.
-  template <typename U,
-            typename = std::enable_if_t<std::is_convertible_v<U, T>>>
+  template <typename U>
+    requires(std::convertible_to<U, T>)
   ScopedJavaLocalRef(const ScopedJavaLocalRef<U>& other) : env_(other.env_) {
     JavaRef<T>::SetNewLocalRef(env_, other.obj());
   }
@@ -204,8 +203,8 @@
   }
 
   // Move conversion constructor.
-  template <typename U,
-            typename = std::enable_if_t<std::is_convertible_v<U, T>>>
+  template <typename U>
+    requires(std::convertible_to<U, T>)
   ScopedJavaLocalRef(ScopedJavaLocalRef<U>&& other) : env_(other.env_) {
     JavaRef<T>::steal(std::move(other));
   }
@@ -234,16 +233,16 @@
   }
 
   // Copy conversion assignment.
-  template <typename U,
-            typename = std::enable_if_t<std::is_convertible_v<U, T>>>
+  template <typename U>
+    requires(std::convertible_to<U, T>)
   ScopedJavaLocalRef& operator=(const ScopedJavaLocalRef<U>& other) {
     Reset(other);
     return *this;
   }
 
   // Move assignment.
-  template <typename U,
-            typename = std::enable_if_t<std::is_convertible_v<U, T>>>
+  template <typename U>
+    requires(std::convertible_to<U, T>)
   ScopedJavaLocalRef& operator=(ScopedJavaLocalRef<U>&& other) {
     env_ = other.env_;
     Reset();
@@ -259,8 +258,8 @@
 
   void Reset() { JavaRef<T>::ResetLocalRef(env_); }
 
-  template <typename U,
-            typename = std::enable_if_t<std::is_convertible_v<U, T>>>
+  template <typename U>
+    requires(std::convertible_to<U, T>)
   void Reset(const ScopedJavaLocalRef<U>& other) {
     // We can copy over env_ here as |other| instance must be from the same
     // thread as |this| local ref. (See class comment for multi-threading
@@ -315,8 +314,8 @@
   ScopedJavaGlobalRef(const ScopedJavaGlobalRef& other) { Reset(other); }
 
   // Copy conversion constructor.
-  template <typename U,
-            typename = std::enable_if_t<std::is_convertible_v<U, T>>>
+  template <typename U>
+    requires(std::convertible_to<U, T>)
   ScopedJavaGlobalRef(const ScopedJavaGlobalRef<U>& other) {
     Reset(other);
   }
@@ -328,8 +327,8 @@
   }
 
   // Move conversion constructor.
-  template <typename U,
-            typename = std::enable_if_t<std::is_convertible_v<U, T>>>
+  template <typename U>
+    requires(std::convertible_to<U, T>)
   ScopedJavaGlobalRef(ScopedJavaGlobalRef<U>&& other) {
     JavaRef<T>::steal(std::move(other));
   }
@@ -356,16 +355,16 @@
   }
 
   // Copy conversion assignment.
-  template <typename U,
-            typename = std::enable_if_t<std::is_convertible_v<U, T>>>
+  template <typename U>
+    requires(std::convertible_to<U, T>)
   ScopedJavaGlobalRef& operator=(const ScopedJavaGlobalRef<U>& other) {
     Reset(other);
     return *this;
   }
 
   // Move assignment.
-  template <typename U,
-            typename = std::enable_if_t<std::is_convertible_v<U, T>>>
+  template <typename U>
+    requires(std::convertible_to<U, T>)
   ScopedJavaGlobalRef& operator=(ScopedJavaGlobalRef<U>&& other) {
     Reset();
     JavaRef<T>::steal(std::move(other));
@@ -380,8 +379,8 @@
 
   void Reset() { JavaRef<T>::ResetGlobalRef(); }
 
-  template <typename U,
-            typename = std::enable_if_t<std::is_convertible_v<U, T>>>
+  template <typename U>
+    requires(std::convertible_to<U, T>)
   void Reset(const ScopedJavaGlobalRef<U>& other) {
     Reset(nullptr, other.obj());
   }
diff --git a/base/command_line.h b/base/command_line.h
index ee76887..7be8e5e4 100644
--- a/base/command_line.h
+++ b/base/command_line.h
@@ -21,6 +21,7 @@
 #include <map>
 #include <memory>
 #include <string>
+#include <string_view>
 #include <vector>
 
 #include "base/base_export.h"
@@ -48,7 +49,7 @@
 #endif
 
   using CharType = StringType::value_type;
-  using StringPieceType = base::BasicStringPiece<CharType>;
+  using StringPieceType = std::basic_string_view<CharType>;
   using StringVector = std::vector<StringType>;
   using SwitchMap = std::map<std::string, StringType, std::less<>>;
 
diff --git a/base/files/file_path.h b/base/files/file_path.h
index e8c5022..2a7fdfd 100644
--- a/base/files/file_path.h
+++ b/base/files/file_path.h
@@ -105,6 +105,7 @@
 #include <cstddef>
 #include <iosfwd>
 #include <string>
+#include <string_view>
 #include <vector>
 
 #include "base/base_export.h"
@@ -166,7 +167,7 @@
 #endif  // BUILDFLAG(IS_WIN)
 
   typedef StringType::value_type CharType;
-  typedef BasicStringPiece<CharType> StringPieceType;
+  typedef std::basic_string_view<CharType> StringPieceType;
 
   // Null-terminated array of separators used to separate components in paths.
   // Each character in this array is a valid separator, but kSeparators[0] is
diff --git a/base/functional/bind_internal.h b/base/functional/bind_internal.h
index 142ef1c7..6101dc8 100644
--- a/base/functional/bind_internal.h
+++ b/base/functional/bind_internal.h
@@ -32,32 +32,31 @@
 #include "build/build_config.h"
 #include "third_party/abseil-cpp/absl/functional/function_ref.h"
 
-// See base/functional/callback.h for user documentation.
+// See docs/callback.md for user documentation.
 //
-//
-// CONCEPTS:
+// Concepts:
 //  Functor -- A movable type representing something that should be called.
-//             All function pointers and Callback<> are functors even if the
+//             All function pointers and `Callback<>` are functors even if the
 //             invocation syntax differs.
 //  RunType -- A function type (as opposed to function _pointer_ type) for
-//             a Callback<>::Run().  Usually just a convenience typedef.
+//             a `Callback<>::Run()`.  Usually just a convenience typedef.
 //  (Bound)Args -- A set of types that stores the arguments.
 //
 // Types:
-//  ForceVoidReturn<> -- Helper class for translating function signatures to
-//                       equivalent forms with a "void" return type.
-//  FunctorTraits<> -- Type traits used to determine the correct RunType and
-//                     invocation manner for a Functor.  This is where function
-//                     signature adapters are applied.
-//  StorageTraits<> -- Type traits that determine how a bound argument is
-//                     stored in BindState.
-//  InvokeHelper<> -- Take a Functor + arguments and actually invokes it.
-//                    Handle the differing syntaxes needed for WeakPtr<>
-//                    support.  This is separate from Invoker to avoid creating
-//                    multiple version of Invoker<>.
-//  Invoker<> -- Unwraps the curried parameters and executes the Functor.
-//  BindState<> -- Stores the curried parameters, and is the main entry point
-//                 into the Bind() system.
+//  `ForceVoidReturn<>` -- Helper class for translating function signatures to
+//                         equivalent forms with a `void` return type.
+//  `FunctorTraits<>` -- Type traits used to determine the correct RunType and
+//                       invocation manner for a Functor.  This is where
+//                       function signature adapters are applied.
+//  `StorageTraits<>` -- Type traits that determine how a bound argument is
+//                       stored in `BindState<>`.
+//  `InvokeHelper<>` -- Takes a Functor + arguments and actually invokes it.
+//                      Handles the differing syntaxes needed for `WeakPtr<>`
+//                      support.  This is separate from `Invoker<>` to avoid
+//                      creating multiple versions of `Invoker<>`.
+//  `Invoker<>` -- Unwraps the curried parameters and executes the Functor.
+//  `BindState<>` -- Stores the curried parameters, and is the main entry point
+//                   into the `Bind()` system.
 
 #if BUILDFLAG(IS_WIN)
 namespace Microsoft {
@@ -84,18 +83,18 @@
 
 namespace unretained_traits {
 
-// UnretainedWrapper will check and report if pointer is dangling upon
+// `UnretainedWrapper` will check and report if pointer is dangling upon
 // invocation.
 struct MayNotDangle {};
-// UnretainedWrapper won't check if pointer is dangling upon invocation. For
-// extra safety, the receiver must be of type MayBeDangling<>.
+// `UnretainedWrapper` won't check if pointer is dangling upon invocation. For
+// extra safety, the receiver must be of type `MayBeDangling<>`.
 struct MayDangle {};
-// UnretainedWrapper won't check if pointer is dangling upon invocation. The
-// receiver doesn't have to be a raw_ptr<>. This is just a temporary state, to
-// allow dangling pointers that would otherwise crash if MayNotDangle was used.
-// It should be replaced ASAP with MayNotDangle (after fixing the dangling
-// pointers) or with MayDangle if there is really no other way (after making
-// receivers MayBeDangling<>).
+// `UnretainedWrapper` won't check if pointer is dangling upon invocation. The
+// receiver doesn't have to be a `raw_ptr<>`. This is just a temporary state, to
+// allow dangling pointers that would otherwise crash if `MayNotDangle` was
+// used. It should be replaced ASAP with `MayNotDangle` (after fixing the
+// dangling pointers) or with `MayDangle` if there is really no other way (after
+// making receivers `MayBeDangling<>`).
 struct MayDangleUntriaged {};
 
 }  // namespace unretained_traits
@@ -109,7 +108,7 @@
           typename UnretainedTrait,
           RawPtrTraits PtrTraits = RawPtrTraits::kEmpty>
 class UnretainedWrapper {
-  // Note that if PtrTraits already includes MayDangle, DanglingRawPtrType
+  // Note that if `PtrTraits` already includes `MayDangle`, `DanglingRawPtrType`
   // will be identical to `raw_ptr<T, PtrTraits>`.
   using DanglingRawPtrType = MayBeDangling<T, PtrTraits>;
 
@@ -133,7 +132,7 @@
                 "type is annotated with DISALLOW_UNRETAINED(). Please see "
                 "base/functional/disallow_unretained.h for alternatives.");
 
-  // Raw pointer makes sense only if there are no PtrTraits. If there are,
+  // Raw pointer makes sense only if there are no `PtrTrait`s. If there are,
   // it means that a `raw_ptr` is being passed, so use the ctors below instead.
 
   explicit UnretainedWrapper(T* o)
@@ -187,14 +186,14 @@
   StorageType ptr_;
 };
 
-// Storage type for std::reference_wrapper so `BindState` can internally store
-// unprotected references using raw_ref.
+// Storage type for `std::reference_wrapper` so `BindState` can internally store
+// unprotected references using `raw_ref`.
 //
-// std::reference_wrapper<T> and T& do not work, since the reference lifetime is
-// not safely protected by MiraclePtr.
+// `std::reference_wrapper<T>` and `T&` do not work, since the reference
+// lifetime is not safely protected by MiraclePtr.
 //
-// UnretainedWrapper<T> and raw_ptr<T> do not work, since BindUnwrapTraits would
-// try to pass by T* rather than T&.
+// `UnretainedWrapper<T>` and `raw_ptr<T>` do not work, since `BindUnwrapTraits`
+// would try to pass by `T*` rather than `T&`.
 template <typename T,
           typename UnretainedTrait,
           RawPtrTraits PtrTraits = RawPtrTraits::kEmpty>
@@ -206,7 +205,7 @@
       "type is annotated with DISALLOW_UNRETAINED(). Please see "
       "base/functional/disallow_unretained.h for alternatives.");
 
-  // Raw reference makes sense only if there are no PtrTraits. If there are,
+  // Raw reference makes sense only if there are no `PtrTrait`s. If there are,
   // it means that a `raw_ref` is being passed, so use the ctors below instead.
 
   explicit UnretainedRefWrapper(T& o)
@@ -236,16 +235,17 @@
     // The ultimate goal is to crash when a callback is invoked with a
     // dangling pointer. This is checked here. For now, it is configured to
     // either crash, DumpWithoutCrashing or be ignored. This depends on the
-    // PartitionAllocUnretainedDanglingPtr feature.
+    // `PartitionAllocUnretainedDanglingPtr` feature.
     if constexpr (std::is_same_v<UnretainedTrait,
                                  unretained_traits::MayNotDangle>) {
       ref.ReportIfDangling();
     }
-    // We can't use operator* here, we need to use raw_ptr's GetForExtraction
-    // instead of GetForDereference. If we did use GetForDereference then we'd
-    // crash in ASAN builds on calling a bound callback with a dangling
-    // reference parameter even if that parameter is not used. This could hide
-    // a later unprotected issue that would be reached in release builds.
+    // We can't use `operator*` here, we need to use `raw_ptr`'s
+    // `GetForExtraction` instead of `GetForDereference`. If we did use
+    // `GetForDereference` then we'd crash in ASAN builds on calling a bound
+    // callback with a dangling reference parameter even if that parameter is
+    // not used. This could hide a later unprotected issue that would be reached
+    // in release builds.
     return ref.get();
   }
 
@@ -300,21 +300,21 @@
   UnretainedRefWrapper<T, UnretainedTrait, PtrTraits> obj_;
 };
 
-// MethodReceiverStorageType converts the current receiver type to its stored
+// `MethodReceiverStorage` converts the current receiver type to its stored
 // type. For instance, it converts pointers to `scoped_refptr`, and wraps
 // `UnretainedRefWrapper` to make it compliant with the internal callback
 // invocation mechanism.
 template <typename T>
-struct MethodReceiverStorageType {
+struct MethodReceiverStorage {
   using Type =
       std::conditional_t<IsPointerV<T>, scoped_refptr<RemovePointerT<T>>, T>;
 };
 
 template <typename T, typename UnretainedTrait, RawPtrTraits PtrTraits>
-struct MethodReceiverStorageType<
+struct MethodReceiverStorage<
     UnretainedRefWrapper<T, UnretainedTrait, PtrTraits>> {
-  // We can't use UnretainedRefWrapper as a receiver directly (see
-  // UnretainedRefWrapperReceiver for why).
+  // We can't use `UnretainedRefWrapper` as a receiver directly (see
+  // `UnretainedRefWrapperReceiver` for why).
   using Type = UnretainedRefWrapperReceiver<T, UnretainedTrait, PtrTraits>;
 };
 
@@ -360,29 +360,32 @@
   mutable T t_;
 };
 
-// PassedWrapper is a copyable adapter for a scoper that ignores const.
+// `PassedWrapper` is a copyable adapter for a scoper that ignores `const`.
 //
-// It is needed to get around the fact that Bind() takes a const reference to
-// all its arguments.  Because Bind() takes a const reference to avoid
+// It is needed to get around the fact that `Bind()` takes a const reference to
+// all its arguments.  Because `Bind()` takes a const reference to avoid
 // unnecessary copies, it is incompatible with movable-but-not-copyable
-// types; doing a destructive "move" of the type into Bind() would violate
+// types; doing a destructive "move" of the type into `Bind()` would violate
 // the const correctness.
 //
-// This conundrum cannot be solved without either C++11 rvalue references or
-// a O(2^n) blowup of Bind() templates to handle each combination of regular
-// types and movable-but-not-copyable types.  Thus we introduce a wrapper type
-// that is copyable to transmit the correct type information down into
-// BindState<>. Ignoring const in this type makes sense because it is only
-// created when we are explicitly trying to do a destructive move.
+// This conundrum cannot be solved without either rvalue references or an O(2^n)
+// blowup of `Bind()` templates to handle each combination of regular types and
+// movable-but-not-copyable types.  Thus we introduce a wrapper type that is
+// copyable to transmit the correct type information down into `BindState<>`.
+// Ignoring `const` in this type makes sense because it is only created when we
+// are explicitly trying to do a destructive move.
 //
 // Two notes:
-//  1) PassedWrapper supports any type that has a move constructor, however
+//  1) `PassedWrapper` supports any type that has a move constructor, however
 //     the type will need to be specifically allowed in order for it to be
-//     bound to a Callback. We guard this explicitly at the call of Passed()
-//     to make for clear errors. Things not given to Passed() will be forwarded
-//     and stored by value which will not work for general move-only types.
-//  2) is_valid_ is distinct from NULL because it is valid to bind a "NULL"
-//     scoper to a Callback and allow the Callback to execute once.
+//     bound to a `Callback`. We guard this explicitly at the call of `Passed()`
+//     to make for clear errors. Things not given to `Passed()` will be
+//     forwarded and stored by value which will not work for general move-only
+//     types.
+//  2) `is_valid_` is distinct from `nullptr` because it is valid to bind a null
+//     scoper to a `Callback` and allow the `Callback` to execute once.
+//
+// TODO(crbug.com/1326449): We have rvalue references and such now. Remove.
 template <typename T>
 class PassedWrapper {
  public:
@@ -408,10 +411,10 @@
   return Unwrapper<T>::Unwrap(std::forward<T>(o));
 }
 
-// `kIsWeakMethod` is a helper that determine if we are binding a WeakPtr<> to a
-// method.  It is used internally by Bind() to select the correct
-// InvokeHelper that will no-op itself in the event the WeakPtr<> for
-// the target object is invalidated.
+// `kIsWeakMethod` is a helper that determines if we are binding a `WeakPtr<>`
+// to a method. It is used internally by `Bind()` to select the correct
+// `InvokeHelper` that will no-op itself in the event the `WeakPtr<>` for the
+// target object is invalidated.
 //
 // The first argument should be the type of the object that will be received by
 // the method.
@@ -426,7 +429,7 @@
 template <typename... Types>
 struct TypeList {};
 
-// Used for DropTypeListItem implementation.
+// Implements `DropTypeListItem`.
 template <size_t n, typename List>
   requires is_instantiation<TypeList, List>
 struct DropTypeListItemImpl {
@@ -438,11 +441,11 @@
 struct DropTypeListItemImpl<n, TypeList<T, List...>>
     : DropTypeListItemImpl<n - 1, TypeList<List...>> {};
 
-// A type-level function that drops |n| list item from given TypeList.
+// A type-level function that drops `n` list items from a given `TypeList`.
 template <size_t n, typename List>
 using DropTypeListItem = typename DropTypeListItemImpl<n, List>::Type;
 
-// Used for TakeTypeListItem implementation.
+// Implements `TakeTypeListItem`.
 template <size_t n, typename List, typename... Accum>
   requires is_instantiation<TypeList, List>
 struct TakeTypeListItemImpl {
@@ -454,9 +457,8 @@
 struct TakeTypeListItemImpl<n, TypeList<T, List...>, Accum...>
     : TakeTypeListItemImpl<n - 1, TypeList<List...>, Accum..., T> {};
 
-// A type-level function that takes first |n| list item from given TypeList.
-// E.g. TakeTypeListItem<3, TypeList<A, B, C, D>> is evaluated to
-// TypeList<A, B, C>.
+// A type-level function that takes the first `n` items from a given `TypeList`;
+// e.g. `TakeTypeListItem<3, TypeList<A, B, C, D>>` -> `TypeList<A, B, C>`.
 template <size_t n, typename List>
 using TakeTypeListItem = typename TakeTypeListItemImpl<n, List>::Type;
 
@@ -473,7 +475,7 @@
 template <typename List1, typename List2>
 using ConcatTypeLists = typename ConcatTypeListsImpl<List1, List2>::Type;
 
-// Used for MakeFunctionType implementation.
+// Implements `MakeFunctionType`.
 template <typename R, typename ArgList>
 struct MakeFunctionTypeImpl;
 
@@ -482,12 +484,12 @@
   using Type = R(Args...);
 };
 
-// A type-level function that constructs a function type that has |R| as its
-// return type and has TypeLists items as its arguments.
+// A type-level function that constructs a function type that has `R` as its
+// return type and has a `TypeList`'s items as its arguments.
 template <typename R, typename ArgList>
 using MakeFunctionType = typename MakeFunctionTypeImpl<R, ArgList>::Type;
 
-// Used for ExtractArgs and ExtractReturnType.
+// Implements `ExtractArgs` and `ExtractReturnType`.
 template <typename Signature>
 struct ExtractArgsImpl;
 
@@ -497,13 +499,13 @@
   using ArgsList = TypeList<Args...>;
 };
 
-// A type-level function that extracts function arguments into a TypeList.
-// E.g. ExtractArgs<R(A, B, C)> is evaluated to TypeList<A, B, C>.
+// A type-level function that extracts function arguments into a `TypeList`;
+// e.g. `ExtractArgs<R(A, B, C)>` -> `TypeList<A, B, C>`.
 template <typename Signature>
 using ExtractArgs = typename ExtractArgsImpl<Signature>::ArgsList;
 
 // A type-level function that extracts the return type of a function.
-// E.g. ExtractReturnType<R(A, B, C)> is evaluated to R.
+// e.g. `ExtractReturnType<R(A, B, C)>` -> `R`.
 template <typename Signature>
 using ExtractReturnType = typename ExtractArgsImpl<Signature>::ReturnType;
 
@@ -532,28 +534,32 @@
   using Type = R(Args...);
 };
 
-// Evaluated to RunType of the given callable type.
-// Example:
-//   auto f = [](int, char*) { return 0.1; };
-//   ExtractCallableRunType<decltype(f)>
-//   is evaluated to
-//   double(int, char*);
+// Evaluated to the RunType of the given callable type; e.g.
+// `ExtractCallableRunType<decltype([](int, char*) { return 0.1; })>` ->
+//     `double(int, char*)`.
 template <typename Callable>
 using ExtractCallableRunType =
     typename ExtractCallableRunTypeImpl<Callable>::Type;
 
-// IsCallableObject<Functor> is true if `Functor` has a non-overloaded
-// `operator()`. This means it fails on some real callable objects, e.g. with
-// templated or overloaded `operator()`s.
-// Example:
-//   IsCallableObject<void(*)()> is false.
+// `IsCallableObject` is true iff `Functor` has a non-overloaded `operator()`.
+// This means it fails on some real callable objects, e.g. with templated or
+// overloaded `operator()`s. E.g.:
+//   static_assert(!IsCallableObject<void(*)()>);
 //
 //   struct Foo {};
-//   IsCallableObject<void(Foo::*)()> is false.
+//   static_assert(!IsCallableObject<void(Foo::*)()>);
 //
 //   int i = 0;
 //   auto f = [i] {};
-//   IsCallableObject<decltype(f)> is false.
+//   static_assert(!IsCallableObject<decltype(f)>);
+//
+//   // TODO(crbug.com/1409914): Support.
+//   struct S {
+//     int operator()(int);
+//     char operator()(char);
+//   };
+//   static_assert(!IsCallableObject<S>);
+// ```
 template <typename Functor>
 concept IsCallableObject = requires { &Functor::operator(); };
 
@@ -563,9 +569,7 @@
 concept HasRefCountedTypeAsRawPtr =
     std::disjunction_v<NeedsScopedRefptrButGetsRawPtr<Ts>...>;
 
-// ForceVoidReturn<>
-//
-// Set of templates that support forcing the function return type to void.
+// `ForceVoidReturn<>` converts a signature to have a `void` return type.
 template <typename Sig>
 struct ForceVoidReturn;
 
@@ -574,31 +578,30 @@
   using RunType = void(Args...);
 };
 
-// FunctorTraits<>
+// `FunctorTraits<>`
 //
 // See description at top of file.
 template <typename Functor>
 struct FunctorTraits;
 
-// For callable types.
+// Callable types.
 // This specialization handles lambdas (captureless and capturing) and functors
 // with a call operator. Capturing lambdas and stateful functors are explicitly
-// disallowed by `BindHelper<>::Bind()`.
-//
-// Example:
-//
-//   // Captureless lambdas are allowed.
+// disallowed by `BindHelper<>::Bind()`; e.g.:
+// ```
+//   // Captureless lambda: Allowed
 //   [] { return 42; };
 //
-//   // Capturing lambdas are *not* allowed.
+//   // Capturing lambda: Disallowed
 //   int x;
 //   [x] { return x; };
 //
-//   // Any empty class with operator() is allowed.
+//   // Empty class with `operator()()`: Allowed
 //   struct Foo {
 //     void operator()() const {}
-//     // No non-static member variable and no virtual functions.
+//     // No non-`static` member variables and no virtual functions.
 //   };
+// ```
 template <typename Functor>
   requires IsCallableObject<Functor>
 struct FunctorTraits<Functor> {
@@ -615,7 +618,7 @@
   }
 };
 
-// For functions.
+// Functions.
 template <typename R, typename... Args>
 struct FunctorTraits<R (*)(Args...)> {
   using RunType = R(Args...);
@@ -636,7 +639,7 @@
 
 #if BUILDFLAG(IS_WIN) && !defined(ARCH_CPU_64_BITS)
 
-// For functions.
+// `__stdcall` functions.
 template <typename R, typename... Args>
 struct FunctorTraits<R(__stdcall*)(Args...)> {
   using RunType = R(Args...);
@@ -655,7 +658,7 @@
 struct FunctorTraits<R(__stdcall*)(Args...) noexcept>
     : FunctorTraits<R (*)(Args...)> {};
 
-// For functions.
+// `__fastcall` functions.
 template <typename R, typename... Args>
 struct FunctorTraits<R(__fastcall*)(Args...)> {
   using RunType = R(Args...);
@@ -694,10 +697,10 @@
   template <typename BlockType, typename... RunArgs>
   static R Invoke(BlockType&& block, RunArgs&&... args) {
     // According to LLVM documentation (§ 6.3), "local variables of automatic
-    // storage duration do not have precise lifetime." Use objc_precise_lifetime
-    // to ensure that the Objective-C block is not deallocated until it has
-    // finished executing even if the Callback<> is destroyed during the block
-    // execution.
+    // storage duration do not have precise lifetime." Use
+    // `objc_precise_lifetime` to ensure that the Objective-C block is not
+    // deallocated until it has finished executing even if the `Callback<>` is
+    // destroyed during the block execution.
     // https://clang.llvm.org/docs/AutomaticReferenceCounting.html#precise-lifetime-semantics
     __attribute__((objc_precise_lifetime)) R (^scoped_block)(Args...) = block;
     return scoped_block(std::forward<RunArgs>(args)...);
@@ -707,7 +710,7 @@
 #endif  // HAS_FEATURE(objc_arc)
 #endif  // __OBJC__
 
-// For methods.
+// Methods.
 template <typename R, typename Receiver, typename... Args>
 struct FunctorTraits<R (Receiver::*)(Args...)> {
   using RunType = R(Receiver*, Args...);
@@ -728,7 +731,6 @@
 struct FunctorTraits<R (Receiver::*)(Args...) noexcept>
     : FunctorTraits<R (Receiver::*)(Args...)> {};
 
-// For const methods.
 template <typename R, typename Receiver, typename... Args>
 struct FunctorTraits<R (Receiver::*)(Args...) const> {
   using RunType = R(const Receiver*, Args...);
@@ -751,7 +753,7 @@
 
 #if BUILDFLAG(IS_WIN) && !defined(ARCH_CPU_64_BITS)
 
-// For __stdcall methods.
+// `__stdcall` methods.
 template <typename R, typename Receiver, typename... Args>
 struct FunctorTraits<R (__stdcall Receiver::*)(Args...)>
     : public FunctorTraits<R (Receiver::*)(Args...)> {};
@@ -770,7 +772,7 @@
 
 #endif  // BUILDFLAG(IS_WIN) && !defined(ARCH_CPU_64_BITS)
 
-// For IgnoreResults.
+// `IgnoreResult`s.
 template <typename T>
 struct FunctorTraits<IgnoreResultHelper<T>> : FunctorTraits<T> {
   using RunType =
@@ -785,7 +787,7 @@
   }
 };
 
-// For OnceCallbacks.
+// `OnceCallback`s.
 template <typename R, typename... Args>
 struct FunctorTraits<OnceCallback<R(Args...)>> {
   using RunType = R(Args...);
@@ -802,7 +804,7 @@
   }
 };
 
-// For RepeatingCallbacks.
+// `RepeatingCallback`s.
 template <typename R, typename... Args>
 struct FunctorTraits<RepeatingCallback<R(Args...)>> {
   using RunType = R(Args...);
@@ -822,7 +824,7 @@
 template <typename Functor>
 using MakeFunctorTraits = FunctorTraits<std::decay_t<Functor>>;
 
-// StorageTraits<>
+// `StorageTraits<>`
 //
 // See description at top of file.
 template <typename T>
@@ -830,23 +832,23 @@
   using Type = T;
 };
 
-// For T*, store as UnretainedWrapper<T> for safety, as it internally uses
-// raw_ptr<T> (when possible).
+// For `T*`, store as `UnretainedWrapper<T>` for safety, as it internally uses
+// `raw_ptr<T>` (when possible).
 template <typename T>
 struct StorageTraits<T*> {
   using Type = UnretainedWrapper<T, unretained_traits::MayNotDangle>;
 };
 
-// For raw_ptr<T>, store as UnretainedWrapper<T> for safety. This may seem
+// For `raw_ptr<T>`, store as `UnretainedWrapper<T>` for safety. This may seem
 // contradictory, but this ensures guaranteed protection for the pointer even
-// during execution of callbacks with parameters of type raw_ptr<T>.
+// during execution of callbacks with parameters of type `raw_ptr<T>`.
 template <typename T, RawPtrTraits PtrTraits>
 struct StorageTraits<raw_ptr<T, PtrTraits>> {
   using Type = UnretainedWrapper<T, unretained_traits::MayNotDangle, PtrTraits>;
 };
 
-// Unwrap std::reference_wrapper and store it in a custom wrapper so that
-// references are also protected with raw_ptr<T>.
+// Unwrap `std::reference_wrapper` and store it in a custom wrapper so that
+// references are also protected with `raw_ptr<T>`.
 template <typename T>
 struct StorageTraits<std::reference_wrapper<T>> {
   using Type = UnretainedRefWrapper<T, unretained_traits::MayNotDangle>;
@@ -855,13 +857,13 @@
 template <typename T>
 using MakeStorageType = typename StorageTraits<std::decay_t<T>>::Type;
 
-// InvokeHelper<>
+// `InvokeHelper<>`
 //
-// There are 2 logical InvokeHelper<> specializations: normal, WeakCalls.
+// There are 2 logical `InvokeHelper<>` specializations: normal, weak.
 //
 // The normal type just calls the underlying runnable.
 //
-// WeakCalls need special syntax that is applied to the first argument to check
+// Weak calls need special syntax that is applied to the first argument to check
 // if they should no-op themselves.
 template <bool is_weak_call, typename ReturnType, size_t... indices>
 struct InvokeHelper;
@@ -882,9 +884,11 @@
 
 template <typename ReturnType, size_t index_target, size_t... index_tail>
 struct InvokeHelper<true, ReturnType, index_target, index_tail...> {
-  // WeakCalls are only supported for functions with a void return type.
-  // Otherwise, the function result would be undefined if the WeakPtr<>
-  // is invalidated.
+  // Weak calls are only supported for functions with a `void` return type.
+  // Otherwise, the desired function result would be unclear if the `WeakPtr<>`
+  // is invalidated. In theory, we could support default-constructible return
+  // types (and return the default value) or allow callers to specify a default
+  // return value via a template arg. It's not clear these are necessary.
   static_assert(std::is_void_v<ReturnType>,
                 "WeakPtrs can only bind to methods without return values.");
 
@@ -895,7 +899,7 @@
     static_assert(index_target == 0);
     // Note the validity of the weak pointer should be tested _after_ it is
     // unwrapped, otherwise it creates a race for weak pointer implementations
-    // that allow cross-thread usage and perform `Lock()` in Unwrap() traits.
+    // that allow cross-thread usage and perform `Lock()` in `Unwrap()` traits.
     const auto& target = Unwrap(std::get<0>(bound));
     if (!target) {
       return;
@@ -908,7 +912,7 @@
   }
 };
 
-// Invoker<>
+// `Invoker<>`
 //
 // See description at the top of the file.
 template <typename StorageType, typename UnboundRunType>
@@ -918,9 +922,6 @@
 struct Invoker<StorageType, R(UnboundArgs...)> {
   static R RunOnce(BindStateBase* base,
                    PassingType<UnboundArgs>... unbound_args) {
-    // Local references to make debugger stepping easier. If in a debugger,
-    // you really want to warp ahead and step through the
-    // InvokeHelper<>::MakeItSo() call below.
     StorageType* storage = static_cast<StorageType*>(base);
     static constexpr size_t num_bound_args =
         std::tuple_size_v<decltype(storage->bound_args_)>;
@@ -931,9 +932,6 @@
   }
 
   static R Run(BindStateBase* base, PassingType<UnboundArgs>... unbound_args) {
-    // Local references to make debugger stepping easier. If in a debugger,
-    // you really want to warp ahead and step through the
-    // InvokeHelper<>::MakeItSo() call below.
     const StorageType* storage = static_cast<StorageType*>(base);
     static constexpr size_t num_bound_args =
         std::tuple_size_v<decltype(storage->bound_args_)>;
@@ -963,7 +961,7 @@
     // Do not `Unwrap()` here, as that immediately triggers dangling pointer
     // detection. Dangling pointer detection should only be triggered if the
     // callback is not cancelled, but cancellation status is not determined
-    // until later inside the InvokeHelper::MakeItSo specialization for weak
+    // until later inside the `InvokeHelper::MakeItSo()` specialization for weak
     // calls.
     //
     // Dangling pointers when invoking a cancelled callback are not considered
@@ -983,48 +981,48 @@
 
 template <typename Receiver, typename... Unused>
 void VerifyMethodReceiver(Receiver&& receiver, Unused&&...) {
-  // Asserts that Callback is not the first owner of a ref-counted receiver.
+  // Asserts that a callback is not the first owner of a ref-counted receiver.
   if constexpr (IsPointerV<std::decay_t<Receiver>> &&
                 IsRefCountedType<RemovePointerT<std::decay_t<Receiver>>>) {
     DCHECK(receiver);
 
     // It's error prone to make the implicit first reference to ref-counted
-    // types. In the example below, base::BindOnce() would make the implicit
-    // first reference to the ref-counted Foo. If PostTask() failed or the
-    // posted task ran fast enough, the newly created instance could be
-    // destroyed before `oo` makes another reference.
+    // types. In the example below, `BindOnce()` would make the implicit first
+    // reference to the ref-counted `Foo`. If `PostTask()` failed or the posted
+    // task ran fast enough, the newly created instance could be destroyed
+    // before `oo` makes another reference.
+    // ```
     //   Foo::Foo() {
-    //     base::ThreadPool::PostTask(FROM_HERE,
-    //                                base::BindOnce(&Foo::Bar, this));
+    //     ThreadPool::PostTask(FROM_HERE, BindOnce(&Foo::Bar, this));
     //   }
     //
     //   scoped_refptr<Foo> oo = new Foo();
+    // ```
     //
-    // Hence, base::Bind{Once,Repeating}() refuses to create the first reference
-    // to ref-counted objects, and DCHECK()s otherwise. As above, that typically
-    // happens around PostTask() in their constructor, and such objects can be
-    // destroyed before `new` returns if the task resolves fast enough.
+    // Hence, `Bind()` refuses to create the first reference to ref-counted
+    // objects, and `DCHECK()`s otherwise. As above, that typically happens
+    // around `PostTask()` in their constructors, and such objects can be
+    // destroyed before `new` returns if the tasks resolve fast enough.
     //
-    // Instead of doing the above, please consider adding a static constructor,
-    // and keep the first reference alive explicitly.
+    // Instead, consider adding a static factory, and keeping the first
+    // reference alive explicitly.
+    // ```
     //   // static
     //   scoped_refptr<Foo> Foo::Create() {
     //     auto foo = base::WrapRefCounted(new Foo());
-    //     base::ThreadPool::PostTask(FROM_HERE,
-    //                                base::BindOnce(&Foo::Bar, foo));
+    //     ThreadPool::PostTask(FROM_HERE, BindOnce(&Foo::Bar, foo));
     //     return foo;
     //   }
     //
-    //   Foo::Foo() {}
-    //
     //   scoped_refptr<Foo> oo = Foo::Create();
+    // ```
     DCHECK(receiver->HasAtLeastOneRef());
   }
 }
 
-// BindState<>
+// `BindState<>`
 //
-// This stores all the state passed into Bind().
+// This stores all the state passed into `Bind()`.
 template <typename Functor, typename... BoundArgs>
 struct BindState final : BindStateBase {
  private:
@@ -1059,10 +1057,10 @@
         functor_(std::forward<ForwardFunctor>(functor)),
         bound_args_(std::forward<ForwardBoundArgs>(bound_args)...) {
     if constexpr (FunctorTraits::is_nullable) {
-      // We check the validity of nested callbacks (e.g., Bind(callback, ...))
-      // in release builds to avoid null pointers from ending up in posted
-      // tasks, causing hard-to-diagnose crashes. Ideally we'd do this for all
-      // functors here, but that would have a large binary size impact.
+      // Check the validity of `functor_` to avoid hard-to-diagnose crashes.
+      // Ideally we'd do this unconditionally, but release builds limit this to
+      // the case of nested callbacks (e.g. `Bind(callback, ...)`) to limit
+      // binary size impact.
       if constexpr (FunctorTraits::is_callback) {
         CHECK(!!functor_);
       } else {
@@ -1119,8 +1117,8 @@
   }
 };
 
-// Used to implement MakeBindStateType. The specializations below cover all
-// cases. Each has the following public members:
+// Used to determine and validate the appropriate `BindState`. The
+// specializations below cover all cases. Each has the following public members:
 //   // The appropriate `BindState` specialization for the given params.
 //   using Type = BindState<std::decay_t<Functor>,
 //                          MakeStorageType<BoundArgs>...>;
@@ -1131,10 +1129,10 @@
 //   // struct with a lambda that asserts" pattern used to do this.
 //   static constexpr bool value = false;
 template <bool is_method, typename Functor, typename... BoundArgs>
-struct MakeBindStateTypeImpl;
+struct ValidateBindStateType;
 
 template <typename Functor, typename... BoundArgs>
-struct MakeBindStateTypeImpl<false, Functor, BoundArgs...> {
+struct ValidateBindStateType<false, Functor, BoundArgs...> {
  private:
   // This "templated struct with a lambda that asserts" pattern is used
   // repeatedly in Bind/Callback code to verify compile-time preconditions. The
@@ -1148,10 +1146,11 @@
   //      complete. As a result, code that needs to know if the assertion failed
   //      can read the variable's value and get the right answer. (If we instead
   //      placed the assertion at struct scope, the resulting type would be
-  //      incomplete when the assertion failed; in practice, reading a constexpr
-  //      member of an incomplete type seems to return the default value
-  //      regardless of what the code tried to set the value to, which makes it
-  //      impossible for other code to check whether the assertion failed.)
+  //      incomplete when the assertion failed; in practice, reading a
+  //      `constexpr` member of an incomplete type seems to return the default
+  //      value regardless of what the code tried to set the value to, which
+  //      makes it impossible for other code to check whether the assertion
+  //      failed.)
   //   2. Code that will not successfully compile unless the assertion holds is
   //      guarded by a constexpr if that checks the variable.
   //   3. By placing the variable inside an independent, templated struct and
@@ -1183,17 +1182,17 @@
 };
 
 template <typename Functor>
-struct MakeBindStateTypeImpl<true, Functor> {
+struct ValidateBindStateType<true, Functor> {
   using Type = BindState<std::decay_t<Functor>>;
   static constexpr bool value = true;
 };
 
 template <typename Functor, typename Receiver, typename... BoundArgs>
-struct MakeBindStateTypeImpl<true, Functor, Receiver, BoundArgs...> {
+struct ValidateBindStateType<true, Functor, Receiver, BoundArgs...> {
  private:
   using DecayedReceiver = std::decay_t<Receiver>;
   using ReceiverStorageType =
-      typename MethodReceiverStorageType<DecayedReceiver>::Type;
+      typename MethodReceiverStorage<DecayedReceiver>::Type;
 
   template <bool v = !std::is_array_v<std::remove_reference_t<Receiver>>>
   struct FirstBoundArgIsNotArray {
@@ -1245,22 +1244,16 @@
                          NoRawPtrsToRefCountedTypes<>>;
 };
 
-template <typename Functor, typename... BoundArgs>
-using MakeBindStateType =
-    MakeBindStateTypeImpl<MakeFunctorTraits<Functor>::is_method,
-                          Functor,
-                          BoundArgs...>;
-
-// Transform |T| into `Unwrapped` type, which is passed to the target function.
-// Example:
-//   In is_once == true case,
-//     `int&&` -> `int&&`,
-//     `const int&` -> `int&&`,
-//     `OwnedWrapper<int>&` -> `int*&&`.
-//   In is_once == false case,
-//     `int&&` -> `const int&`,
-//     `const int&` -> `const int&`,
-//     `OwnedWrapper<int>&` -> `int* const &`.
+// Transforms `T` into an unwrapped type, which is passed to the target
+// function; e.g.:
+// * `is_once` cases:
+// ** `TransformToUnwrappedType<true, int&&>` -> `int&&`
+// ** `TransformToUnwrappedType<true, const int&>` -> `int&&`
+// ** `TransformToUnwrappedType<true, OwnedWrapper<int>&>` -> `int*&&`
+// * `!is_once` cases:
+// ** `TransformToUnwrappedType<false, int&&>` -> `const int&`
+// ** `TransformToUnwrappedType<false, const int&>` -> `const int&`
+// ** `TransformToUnwrappedType<false, OwnedWrapper<int>&>` -> `int* const &`
 template <bool is_once,
           typename T,
           typename StoredType = std::decay_t<T>,
@@ -1269,12 +1262,12 @@
 using TransformToUnwrappedType =
     decltype(Unwrap(std::declval<ForwardedType>()));
 
-// Converts `this` arguments to underlying pointer types. E.g.
+// Used to convert `this` arguments to underlying pointer types; e.g.:
 //   `int*` -> `int*`
 //   `std::unique_ptr<int>` -> `int*`
 //   `int` -> (assertion failure; `this` must be a pointer-like object)
 template <typename T>
-struct UnderlyingReceiverType {
+struct ValidateReceiverType {
  private:
   // Pointer-like receivers use a different specialization, so this never
   // succeeds.
@@ -1297,54 +1290,49 @@
 
 template <typename T>
   requires requires(T&& t) { std::to_address(t); }
-struct UnderlyingReceiverType<T> {
+struct ValidateReceiverType<T> {
   using Type = decltype(std::to_address(std::declval<T>()));
   static constexpr bool value = true;
 };
 
-// Transforms |Args| into `Unwrapped` types, and packs them into a TypeList.
-// If |is_method| is true, tries to dereference the first argument to support
-// smart pointers.
+// Transforms `Args` into unwrapped types, and packs them into a `TypeList`. If
+// `is_method` is true, tries to dereference the first argument to support smart
+// pointers.
 template <bool is_once, bool is_method, typename... Args>
-struct MakeUnwrappedTypeList {
+struct ValidateUnwrappedTypeList {
   // These members are similar in intent to those in `MakeBindStateTypeImpl`;
   // see comments there.
   using Type = TypeList<TransformToUnwrappedType<is_once, Args>...>;
   static constexpr bool value = true;
 };
 
-// Performs special handling for this pointers.
-// Example:
-//   int* -> int*,
-//   std::unique_ptr<int> -> int*.
 template <bool is_once, typename Receiver, typename... Args>
-struct MakeUnwrappedTypeList<is_once, true, Receiver, Args...> {
+struct ValidateUnwrappedTypeList<is_once, true, Receiver, Args...> {
  private:
   using ReceiverStorageType =
-      typename MethodReceiverStorageType<std::decay_t<Receiver>>::Type;
+      typename MethodReceiverStorage<std::decay_t<Receiver>>::Type;
   using UnwrappedReceiver =
       TransformToUnwrappedType<is_once, ReceiverStorageType>;
-  using UnderlyingReceiver = UnderlyingReceiverType<UnwrappedReceiver>;
+  using ValidatedReceiver = ValidateReceiverType<UnwrappedReceiver>;
 
  public:
-  using Type = TypeList<typename UnderlyingReceiver::Type,
+  using Type = TypeList<typename ValidatedReceiver::Type,
                         TransformToUnwrappedType<is_once, Args>...>;
-  static constexpr bool value = UnderlyingReceiver::value;
+  static constexpr bool value = ValidatedReceiver::value;
 };
 
-// IsUnretainedMayDangle is true if StorageType is of type
-// `UnretainedWrapper<T, unretained_traits::MayDangle, PtrTraits>.
-// Note that it is false for unretained_traits::MayDangleUntriaged.
+// `IsUnretainedMayDangle` is true iff `StorageType` is marked with
+// `unretained_traits::MayDangle`. Note that it is false for
+// `unretained_traits::MayDangleUntriaged`.
 template <typename StorageType>
 inline constexpr bool IsUnretainedMayDangle = false;
 template <typename T, RawPtrTraits PtrTraits>
 inline constexpr bool IsUnretainedMayDangle<
     UnretainedWrapper<T, unretained_traits::MayDangle, PtrTraits>> = true;
 
-// UnretainedAndRawPtrHaveCompatibleTraits is true if StorageType is of type
-// `UnretainedWrapper<T, unretained_traits::MayDangle, PtrTraits1>` and
-// FunctionParamType is of type `raw_ptr<T, PtrTraits2>`, and the former's
-// ::GetPtrType is the same type as the latter.
+// `UnretainedAndRawPtrHaveCompatibleTraits` is true iff `StorageType` is marked
+// with `unretained_traits::MayDangle`, `FunctionParamType` is a `raw_ptr`, and
+// `StorageType::GetPtrType` is the same type as `FunctionParamType`.
 template <typename StorageType, typename FunctionParamType>
 inline constexpr bool UnretainedAndRawPtrHaveCompatibleTraits = false;
 template <typename T,
@@ -1371,18 +1359,18 @@
       static constexpr bool kCanBeForwardedToBoundFunctor =
           std::is_convertible_v<ForwardingType, FunctorParamType>;
 
-      // If the bound type can't be forwarded then test if `FunctorParamType` is
-      // a non-const lvalue reference and a reference to the unwrapped type
-      // *could* have been successfully forwarded.
+      // If the bound type can't be forwarded, then test if `FunctorParamType`
+      // is a non-const lvalue reference and a reference to the unwrapped type
+      // could have been successfully forwarded.
       static constexpr bool kIsUnwrappedForwardableNonConstReference =
           std::is_lvalue_reference_v<FunctorParamType> &&
           !std::is_const_v<std::remove_reference_t<FunctorParamType>> &&
           std::is_convertible_v<std::decay_t<ForwardingType>&,
                                 FunctorParamType>;
 
-      // Note that this intentionally drops the const qualifier from
-      // `ForwardingType`, to test if it *could* have been successfully
-      // forwarded if `Passed()` had been used.
+      // Also intentionally drop the `const` qualifier from `ForwardingType`, to
+      // test if it could have been successfully forwarded if `Passed()` had
+      // been used.
       static constexpr bool kWouldBeForwardableWithPassed =
           std::is_convertible_v<std::decay_t<ForwardingType>&&,
                                 FunctorParamType>;
@@ -1396,9 +1384,9 @@
       static constexpr bool kBindArgumentCanBeCaptured =
           std::constructible_from<StorageType, BoundAsType>;
 
-      // Note that this intentionally drops the const qualifier from
-      // `BoundAsType`, to test if it *could* have been successfully bound if
-      // `std::move()` had been used.
+      // If the argument can't be captured, intentionally drop the `const`
+      // qualifier from `BoundAsType`, to test if it could have been
+      // successfully captured if `std::move()` had been used.
       static constexpr bool kWouldBeCapturableWithStdMove =
           std::constructible_from<StorageType, std::decay_t<BoundAsType>&&>;
     };
@@ -1418,9 +1406,9 @@
   };
 };
 
-// Helper to assert that parameter |i| of type |Arg| can be bound, which means:
-// - |Arg| can be retained internally as |Storage|.
-// - |Arg| can be forwarded as |Unwrapped| to |Param|.
+// Helper to assert that parameter `i` of type `Arg` can be bound, which means:
+// * `Arg` can be retained internally as `Storage`
+// * `Arg` can be forwarded as `Unwrapped` to `Param`
 template <int i,
           bool is_method,
           typename Arg,
@@ -1473,14 +1461,14 @@
     }();
   };
 
-  // With `BindRepeating`, there are two decision points for how to handle a
+  // With `BindRepeating()`, there are two decision points for how to handle a
   // move-only type:
   //
   // 1. Whether the move-only argument should be moved into the internal
-  //    `BindState`. Either `std::move()` or `Passed` is sufficient to trigger
+  //    `BindState`. Either `std::move()` or `Passed()` is sufficient to trigger
   //    move-only semantics.
   // 2. Whether or not the bound, move-only argument should be moved to the
-  //    bound functor when invoked. When the argument is bound with `Passed`,
+  //    bound functor when invoked. When the argument is bound with `Passed()`,
   //    invoking the callback will destructively move the bound, move-only
   //    argument to the bound functor. In contrast, if the argument is bound
   //    with `std::move()`, `RepeatingCallback` will attempt to call the bound
@@ -1492,7 +1480,7 @@
   // In contrast, `BindOnce()` only has one decision point. Once a move-only
   // type is captured by value into the internal `BindState`, the bound,
   // move-only argument will always be moved to the functor when invoked.
-  // Failure to use std::move will simply fail the
+  // Failure to use `std::move()` will simply fail the
   // `MoveOnlyTypeMustUseStdMove` assertion below instead.
   //
   // Note: `Passed()` is a legacy of supporting move-only types when repeating
@@ -1522,6 +1510,8 @@
     }();
   };
 
+  // Generic failed-to-forward message for cases that didn't match one of the
+  // two assertions above.
   template <bool v = UnwrappedParam::kCanBeForwardedToBoundFunctor>
   struct CanBeForwardedToBoundFunctor {
     static constexpr bool value = [] {
@@ -1532,6 +1522,8 @@
     }();
   };
 
+  // The most common reason for failing to capture a parameter is attempting to
+  // pass a move-only type as an lvalue.
   template <bool v = BoundStorage::kBindArgumentCanBeCaptured ||
                      !BoundStorage::kWouldBeCapturableWithStdMove>
   struct MoveOnlyTypeMustUseStdMove {
@@ -1543,12 +1535,12 @@
     }();
   };
 
+  // Any other reason the parameter could not be captured.
   template <bool v = BoundStorage::kBindArgumentCanBeCaptured>
   struct BindArgumentCanBeCaptured {
     static constexpr bool value = [] {
       // In practice, failing this precondition should be rare, as the storage
-      // type is deduced from the arguments passed to
-      // `BindOnce()`/`BindRepeating()`.
+      // type is deduced from the arguments passed to `Bind()`.
       static_assert(
           v, "Cannot capture argument: is the argument copyable or movable?");
       return v;
@@ -1597,8 +1589,8 @@
                                          Params>...>;
 };
 
-// Core implementation of Bind variants, which checks common preconditions
-// before returning an appropriate callback.
+// Core implementation of `Bind()`, which checks common preconditions before
+// returning an appropriate callback.
 template <template <typename> class CallbackT>
 struct BindHelper {
  private:
@@ -1658,14 +1650,14 @@
     //     static constexpr bool is_stateless = true;
     //     ...
     //   };
-    //   using UnwrappedArgsList = struct {
+    //   using ValidatedUnwrappedTypes = struct {
     //     using Type = TypeList<S*, int16_t>;
     //     static constexpr bool value = true;
     //   };
     //   using BoundArgsList = TypeList<S*, int16_t>;
     //   using RunParamsList = TypeList<S*, int, const std::string&>;
     //   using BoundParamsList = TypeList<S*, int>;
-    //   using BindStateType = struct {
+    //   using ValidatedBindState = struct {
     //     using Type =
     //         BindState<double (S::*)(int, const std::string&),
     //                   UnretainedWrapper<S, unretained_traits::MayNotDangle>,
@@ -1680,33 +1672,35 @@
     static constexpr bool kIsOnce =
         is_instantiation<OnceCallback, CallbackT<void()>>;
     using FunctorTraits = MakeFunctorTraits<Functor>;
-    using UnwrappedArgsList =
-        MakeUnwrappedTypeList<kIsOnce, FunctorTraits::is_method, Args&&...>;
+    using ValidatedUnwrappedTypes =
+        ValidateUnwrappedTypeList<kIsOnce, FunctorTraits::is_method, Args&&...>;
     using BoundArgsList = TypeList<Args...>;
     using RunParamsList = ExtractArgs<typename FunctorTraits::RunType>;
     using BoundParamsList = TakeTypeListItem<sizeof...(Args), RunParamsList>;
-    using BindStateType = MakeBindStateType<Functor, Args...>;
+    using ValidatedBindState =
+        ValidateBindStateType<FunctorTraits::is_method, Functor, Args...>;
     // This conditional checks if each of the `args` matches to the
     // corresponding param of the target function. This check does not affect
     // the behavior of `Bind()`, but its error message should be more readable.
     if constexpr (std::conjunction_v<
                       NotFunctionRef<Functor>, IsStateless<Functor>,
-                      UnwrappedArgsList,
+                      ValidatedUnwrappedTypes,
                       ParamsCanBeBound<
                           FunctorTraits::is_method,
                           std::make_index_sequence<sizeof...(Args)>,
-                          BoundArgsList, typename UnwrappedArgsList::Type,
+                          BoundArgsList, typename ValidatedUnwrappedTypes::Type,
                           BoundParamsList>,
-                      BindStateType>) {
+                      ValidatedBindState>) {
       using UnboundRunType =
           MakeFunctionType<ExtractReturnType<typename FunctorTraits::RunType>,
                            DropTypeListItem<sizeof...(Args), RunParamsList>>;
       using CallbackType = CallbackT<UnboundRunType>;
 
-      // Store the invoke func into PolymorphicInvoke before casting it to
-      // InvokeFuncStorage, so that we can ensure its type matches to
-      // PolymorphicInvoke, to which CallbackType will cast back.
-      using Invoker = Invoker<typename BindStateType::Type, UnboundRunType>;
+      // Store the invoke func into `PolymorphicInvoke` before casting it to
+      // `InvokeFuncStorage`, so that we can ensure its type matches to
+      // `PolymorphicInvoke`, to which `CallbackType` will cast back.
+      using Invoker =
+          Invoker<typename ValidatedBindState::Type, UnboundRunType>;
       using PolymorphicInvoke = typename CallbackType::PolymorphicInvoke;
       PolymorphicInvoke invoke_func;
       if constexpr (kIsOnce) {
@@ -1716,22 +1710,21 @@
       }
 
       using InvokeFuncStorage = BindStateBase::InvokeFuncStorage;
-      return CallbackType(BindStateType::Type::Create(
+      return CallbackType(ValidatedBindState::Type::Create(
           reinterpret_cast<InvokeFuncStorage>(invoke_func),
           std::forward<Functor>(functor), std::forward<Args>(args)...));
     }
   }
 
-  // Special cases for binding to a base::{Once, Repeating}Callback without
-  // extra bound arguments. We CHECK() the validity of callback to guard against
-  // null pointers accidentally ending up in posted tasks, causing hard-to-debug
-  // crashes.
+  // Special cases for binding to a `Callback` without extra bound arguments.
 
   // `OnceCallback` passed to `OnceCallback`, or `RepeatingCallback` passed to
   // `RepeatingCallback`.
   template <typename T>
     requires is_instantiation<CallbackT, T>
   static T Bind(T callback) {
+    // Guard against null pointers accidentally ending up in posted tasks,
+    // causing hard-to-debug crashes.
     CHECK(callback);
     return callback;
   }
@@ -1809,17 +1802,17 @@
 
 }  // namespace internal
 
-// An injection point to control |this| pointer behavior on a method invocation.
-// If IsWeakReceiver<> is true_type for |T| and |T| is used for a receiver of a
-// method, base::Bind cancels the method invocation if the receiver is tested as
-// false.
-// E.g. Foo::bar() is not called:
-//   struct Foo : base::SupportsWeakPtr<Foo> {
-//     void bar() {}
+// An injection point to control `this` pointer behavior on a method invocation.
+// If `IsWeakReceiver<T>::value` is `true` and `T` is used as a method receiver,
+// `Bind()` cancels the method invocation if the receiver tests as false.
+// ```
+//   struct S : SupportsWeakPtr<S> {
+//     void f() {}
 //   };
 //
-//   WeakPtr<Foo> oo = nullptr;
-//   base::BindOnce(&Foo::bar, oo).Run();
+//   WeakPtr<S> weak_s = nullptr;
+//   BindOnce(&S::f, weak_s).Run();  // `S::f()` is not called.
+// ```
 template <typename T>
 struct IsWeakReceiver : std::bool_constant<is_instantiation<WeakPtr, T>> {};
 
@@ -1837,8 +1830,8 @@
 };
 
 // An injection point to control how bound objects passed to the target
-// function. BindUnwrapTraits<>::Unwrap() is called for each bound objects right
-// before the target function is invoked.
+// function. `BindUnwrapTraits<>::Unwrap()` is called for each bound object
+// right before the target function is invoked.
 template <typename>
 struct BindUnwrapTraits {
   template <typename T>
@@ -1869,16 +1862,18 @@
 };
 #endif
 
-// CallbackCancellationTraits allows customization of Callback's cancellation
-// semantics. By default, callbacks are not cancellable. A specialization should
-// set is_cancellable = true and implement an IsCancelled() that returns if the
-// callback should be cancelled.
+// `CallbackCancellationTraits` allows customization of `Callback`'s
+// cancellation semantics. By default, callbacks are not cancellable. A
+// specialization should set `is_cancellable` and implement an `IsCancelled()`
+// that returns whether the callback should be cancelled, as well as a
+// `MaybeValid()` that returns whether the underlying functor/object is maybe
+// valid.
 template <typename Functor, typename BoundArgsTuple>
 struct CallbackCancellationTraits {
   static constexpr bool is_cancellable = false;
 };
 
-// Specialization for method bound to weak pointer receiver.
+// Specialization for a weak receiver.
 template <typename Functor, typename... BoundArgs>
   requires internal::kIsWeakMethod<internal::FunctorTraits<Functor>::is_method,
                                    BoundArgs...>
@@ -1900,7 +1895,7 @@
   }
 };
 
-// Specialization for a nested bind.
+// Specialization for a nested `Bind()`.
 template <typename Functor, typename... BoundArgs>
   requires is_instantiation<OnceCallback, Functor> ||
            is_instantiation<RepeatingCallback, Functor>
diff --git a/base/strings/string_number_conversions_internal.h b/base/strings/string_number_conversions_internal.h
index 3642ec2c..983c9cd 100644
--- a/base/strings/string_number_conversions_internal.h
+++ b/base/strings/string_number_conversions_internal.h
@@ -9,6 +9,7 @@
 #include <stdlib.h>
 
 #include <limits>
+#include <string_view>
 
 #include "base/check.h"
 #include "base/logging.h"
@@ -152,7 +153,7 @@
 };
 
 template <typename Number, int kBase, typename CharT>
-auto StringToNumber(BasicStringPiece<CharT> input) {
+auto StringToNumber(std::basic_string_view<CharT> input) {
   using Parser = StringToNumberParser<Number, kBase>;
   using Result = typename Parser::Result;
 
diff --git a/base/strings/string_piece.h b/base/strings/string_piece.h
index 13bccd9e..8ef94e51 100644
--- a/base/strings/string_piece.h
+++ b/base/strings/string_piece.h
@@ -14,8 +14,6 @@
 
 namespace base {
 
-template <typename CharT, typename Traits = std::char_traits<CharT>>
-using BasicStringPiece = std::basic_string_view<CharT, Traits>;
 using StringPiece = std::string_view;
 using StringPiece16 = std::u16string_view;
 
diff --git a/base/strings/string_piece_unittest.cc b/base/strings/string_piece_unittest.cc
index 7685950..7a082f0 100644
--- a/base/strings/string_piece_unittest.cc
+++ b/base/strings/string_piece_unittest.cc
@@ -38,30 +38,30 @@
 TYPED_TEST_SUITE(CommonStringPieceTest, SupportedCharTypes);
 
 TYPED_TEST(CommonStringPieceTest, CheckComparisonOperators) {
-#define CMP_Y(op, x, y)                                                   \
-  {                                                                       \
-    std::basic_string<TypeParam> lhs(TestFixture::as_string(x));          \
-    std::basic_string<TypeParam> rhs(TestFixture::as_string(y));          \
-    ASSERT_TRUE((BasicStringPiece<TypeParam>((lhs.c_str()))               \
-                     op BasicStringPiece<TypeParam>((rhs.c_str()))));     \
-    ASSERT_TRUE(BasicStringPiece<TypeParam>(lhs) op rhs);                 \
-    ASSERT_TRUE(lhs op BasicStringPiece<TypeParam>(rhs));                 \
-    ASSERT_TRUE((BasicStringPiece<TypeParam>((lhs.c_str()))               \
-                     .compare(BasicStringPiece<TypeParam>((rhs.c_str()))) \
-                         op 0));                                          \
+#define CMP_Y(op, x, y)                                                        \
+  {                                                                            \
+    std::basic_string<TypeParam> lhs(TestFixture::as_string(x));               \
+    std::basic_string<TypeParam> rhs(TestFixture::as_string(y));               \
+    ASSERT_TRUE((std::basic_string_view<TypeParam>((lhs.c_str()))              \
+                     op std::basic_string_view<TypeParam>((rhs.c_str()))));    \
+    ASSERT_TRUE(std::basic_string_view<TypeParam>(lhs) op rhs);                \
+    ASSERT_TRUE(lhs op std::basic_string_view<TypeParam>(rhs));                \
+    ASSERT_TRUE((                                                              \
+        std::basic_string_view<TypeParam>((lhs.c_str()))                       \
+            .compare(std::basic_string_view<TypeParam>((rhs.c_str()))) op 0)); \
   }
 
-#define CMP_N(op, x, y)                                                    \
-  {                                                                        \
-    std::basic_string<TypeParam> lhs(TestFixture::as_string(x));           \
-    std::basic_string<TypeParam> rhs(TestFixture::as_string(y));           \
-    ASSERT_FALSE((BasicStringPiece<TypeParam>((lhs.c_str()))               \
-                      op BasicStringPiece<TypeParam>((rhs.c_str()))));     \
-    ASSERT_FALSE(BasicStringPiece<TypeParam>(lhs) op rhs);                 \
-    ASSERT_FALSE(lhs op BasicStringPiece<TypeParam>(rhs));                 \
-    ASSERT_FALSE((BasicStringPiece<TypeParam>((lhs.c_str()))               \
-                      .compare(BasicStringPiece<TypeParam>((rhs.c_str()))) \
-                          op 0));                                          \
+#define CMP_N(op, x, y)                                                        \
+  {                                                                            \
+    std::basic_string<TypeParam> lhs(TestFixture::as_string(x));               \
+    std::basic_string<TypeParam> rhs(TestFixture::as_string(y));               \
+    ASSERT_FALSE((std::basic_string_view<TypeParam>((lhs.c_str()))             \
+                      op std::basic_string_view<TypeParam>((rhs.c_str()))));   \
+    ASSERT_FALSE(std::basic_string_view<TypeParam>(lhs) op rhs);               \
+    ASSERT_FALSE(lhs op std::basic_string_view<TypeParam>(rhs));               \
+    ASSERT_FALSE((                                                             \
+        std::basic_string_view<TypeParam>((lhs.c_str()))                       \
+            .compare(std::basic_string_view<TypeParam>((rhs.c_str()))) op 0)); \
   }
 
   CMP_Y(==, "", "")
@@ -145,15 +145,15 @@
   std::basic_string<TypeParam> xyz(TestFixture::as_string("xyz"));
   std::basic_string<TypeParam> foobar(TestFixture::as_string("foobar"));
 
-  BasicStringPiece<TypeParam> a(alphabet);
-  BasicStringPiece<TypeParam> b(abc);
-  BasicStringPiece<TypeParam> c(xyz);
-  BasicStringPiece<TypeParam> d(foobar);
-  BasicStringPiece<TypeParam> e;
+  std::basic_string_view<TypeParam> a(alphabet);
+  std::basic_string_view<TypeParam> b(abc);
+  std::basic_string_view<TypeParam> c(xyz);
+  std::basic_string_view<TypeParam> d(foobar);
+  std::basic_string_view<TypeParam> e;
   std::basic_string<TypeParam> temp(TestFixture::as_string("123"));
   temp += static_cast<TypeParam>(0);
   temp += TestFixture::as_string("456");
-  BasicStringPiece<TypeParam> f(temp);
+  std::basic_string_view<TypeParam> f(temp);
 
   ASSERT_EQ(a[6], static_cast<TypeParam>('g'));
   ASSERT_EQ(b[0], static_cast<TypeParam>('a'));
@@ -188,7 +188,7 @@
   ASSERT_TRUE(e.empty());
   ASSERT_EQ(e.begin(), e.end());
 
-  d = BasicStringPiece<TypeParam>();
+  d = std::basic_string_view<TypeParam>();
   ASSERT_EQ(d.size(), 0U);
   ASSERT_TRUE(d.empty());
   ASSERT_EQ(d.data(), nullptr);
@@ -198,7 +198,7 @@
 }
 
 TYPED_TEST(CommonStringPieceTest, CheckFind) {
-  typedef BasicStringPiece<TypeParam> Piece;
+  typedef std::basic_string_view<TypeParam> Piece;
 
   std::basic_string<TypeParam> alphabet(
       TestFixture::as_string("abcdefghijklmnopqrstuvwxyz"));
@@ -206,10 +206,10 @@
   std::basic_string<TypeParam> xyz(TestFixture::as_string("xyz"));
   std::basic_string<TypeParam> foobar(TestFixture::as_string("foobar"));
 
-  BasicStringPiece<TypeParam> a(alphabet);
-  BasicStringPiece<TypeParam> b(abc);
-  BasicStringPiece<TypeParam> c(xyz);
-  BasicStringPiece<TypeParam> d(foobar);
+  std::basic_string_view<TypeParam> a(alphabet);
+  std::basic_string_view<TypeParam> b(abc);
+  std::basic_string_view<TypeParam> c(xyz);
+  std::basic_string_view<TypeParam> d(foobar);
 
   d = Piece();
   Piece e;
@@ -514,16 +514,16 @@
 
 TYPED_TEST(CommonStringPieceTest, CheckCustom) {
   std::basic_string<TypeParam> foobar(TestFixture::as_string("foobar"));
-  BasicStringPiece<TypeParam> a(foobar);
+  std::basic_string_view<TypeParam> a(foobar);
   std::basic_string<TypeParam> s1(TestFixture::as_string("123"));
   s1 += static_cast<TypeParam>('\0');
   s1 += TestFixture::as_string("456");
-  [[maybe_unused]] BasicStringPiece<TypeParam> b(s1);
-  BasicStringPiece<TypeParam> e;
+  [[maybe_unused]] std::basic_string_view<TypeParam> b(s1);
+  std::basic_string_view<TypeParam> e;
   std::basic_string<TypeParam> s2;
 
   // remove_prefix
-  BasicStringPiece<TypeParam> c(a);
+  std::basic_string_view<TypeParam> c(a);
   c.remove_prefix(3);
   ASSERT_EQ(c, TestFixture::as_string("bar"));
   c = a;
@@ -579,7 +579,7 @@
 }
 
 TYPED_TEST(CommonStringPieceTest, CheckNULL) {
-  BasicStringPiece<TypeParam> s;
+  std::basic_string_view<TypeParam> s;
   ASSERT_EQ(s.data(), nullptr);
   ASSERT_EQ(s.size(), 0U);
 
@@ -595,17 +595,17 @@
       TestFixture::as_string("abcdefghijklmnopqrstuvwxyzz"));
   std::basic_string<TypeParam> alphabet_y(
       TestFixture::as_string("abcdefghijklmnopqrstuvwxyy"));
-  BasicStringPiece<TypeParam> abc(alphabet);
+  std::basic_string_view<TypeParam> abc(alphabet);
 
   // check comparison operations on strings longer than 4 bytes.
-  ASSERT_EQ(abc, BasicStringPiece<TypeParam>(alphabet));
-  ASSERT_EQ(abc.compare(BasicStringPiece<TypeParam>(alphabet)), 0);
+  ASSERT_EQ(abc, std::basic_string_view<TypeParam>(alphabet));
+  ASSERT_EQ(abc.compare(std::basic_string_view<TypeParam>(alphabet)), 0);
 
-  ASSERT_TRUE(abc < BasicStringPiece<TypeParam>(alphabet_z));
-  ASSERT_LT(abc.compare(BasicStringPiece<TypeParam>(alphabet_z)), 0);
+  ASSERT_TRUE(abc < std::basic_string_view<TypeParam>(alphabet_z));
+  ASSERT_LT(abc.compare(std::basic_string_view<TypeParam>(alphabet_z)), 0);
 
-  ASSERT_TRUE(abc > BasicStringPiece<TypeParam>(alphabet_y));
-  ASSERT_GT(abc.compare(BasicStringPiece<TypeParam>(alphabet_y)), 0);
+  ASSERT_TRUE(abc > std::basic_string_view<TypeParam>(alphabet_y));
+  ASSERT_GT(abc.compare(std::basic_string_view<TypeParam>(alphabet_y)), 0);
 }
 
 TYPED_TEST(CommonStringPieceTest, StringCompareNotAmbiguous) {
@@ -618,8 +618,8 @@
 TYPED_TEST(CommonStringPieceTest, HeterogenousStringPieceEquals) {
   std::basic_string<TypeParam> hello(TestFixture::as_string("hello"));
 
-  ASSERT_EQ(BasicStringPiece<TypeParam>(hello), hello);
-  ASSERT_EQ(hello.c_str(), BasicStringPiece<TypeParam>(hello));
+  ASSERT_EQ(std::basic_string_view<TypeParam>(hello), hello);
+  ASSERT_EQ(hello.c_str(), std::basic_string_view<TypeParam>(hello));
 }
 
 // std::u16string-specific stuff
@@ -648,23 +648,25 @@
   std::basic_string<TypeParam> str(TestFixture::as_string("hello world"));
   std::basic_string<TypeParam> empty;
 
-  ASSERT_EQ(str, BasicStringPiece<TypeParam>(str));
-  ASSERT_EQ(str, BasicStringPiece<TypeParam>(str.c_str()));
+  ASSERT_EQ(str, std::basic_string_view<TypeParam>(str));
+  ASSERT_EQ(str, std::basic_string_view<TypeParam>(str.c_str()));
   ASSERT_TRUE(TestFixture::as_string("hello") ==
-              BasicStringPiece<TypeParam>(str.c_str(), 5));
+              std::basic_string_view<TypeParam>(str.c_str(), 5));
   ASSERT_EQ(
       empty,
-      BasicStringPiece<TypeParam>(
+      std::basic_string_view<TypeParam>(
           str.c_str(),
-          static_cast<typename BasicStringPiece<TypeParam>::size_type>(0)));
-  ASSERT_EQ(empty, BasicStringPiece<TypeParam>());
+          static_cast<typename std::basic_string_view<TypeParam>::size_type>(
+              0)));
+  ASSERT_EQ(empty, std::basic_string_view<TypeParam>());
   ASSERT_TRUE(
       empty ==
-      BasicStringPiece<TypeParam>(
+      std::basic_string_view<TypeParam>(
           nullptr,
-          static_cast<typename BasicStringPiece<TypeParam>::size_type>(0)));
-  ASSERT_EQ(empty, BasicStringPiece<TypeParam>());
-  ASSERT_EQ(empty, BasicStringPiece<TypeParam>(empty));
+          static_cast<typename std::basic_string_view<TypeParam>::size_type>(
+              0)));
+  ASSERT_EQ(empty, std::basic_string_view<TypeParam>());
+  ASSERT_EQ(empty, std::basic_string_view<TypeParam>(empty));
 }
 
 TEST(StringPieceTest, ConstexprCtor) {
diff --git a/base/strings/string_split_internal.h b/base/strings/string_split_internal.h
index 8858d4e8..dc07da3 100644
--- a/base/strings/string_split_internal.h
+++ b/base/strings/string_split_internal.h
@@ -16,7 +16,7 @@
 
 // Returns either the ASCII or UTF-16 whitespace.
 template <typename CharT>
-BasicStringPiece<CharT> WhitespaceForType();
+std::basic_string_view<CharT> WhitespaceForType();
 
 template <>
 inline StringPiece16 WhitespaceForType<char16_t>() {
@@ -44,7 +44,7 @@
   while (start != std::basic_string<CharT>::npos) {
     size_t end = str.find_first_of(delimiter, start);
 
-    BasicStringPiece<CharT> piece;
+    std::basic_string_view<CharT> piece;
     if (end == std::basic_string<CharT>::npos) {
       piece = str.substr(start);
       start = std::basic_string<CharT>::npos;
@@ -70,7 +70,7 @@
     T delimiter,
     WhitespaceHandling whitespace,
     SplitResult result_type) {
-  using Piece = BasicStringPiece<CharT>;
+  using Piece = std::basic_string_view<CharT>;
   using size_type = typename Piece::size_type;
 
   std::vector<OutputStringType> result;
diff --git a/base/strings/string_tokenizer.h b/base/strings/string_tokenizer.h
index 65a51a4..e4a24bd 100644
--- a/base/strings/string_tokenizer.h
+++ b/base/strings/string_tokenizer.h
@@ -7,6 +7,7 @@
 
 #include <algorithm>
 #include <string>
+#include <string_view>
 
 #include "base/check.h"
 #include "base/strings/string_piece.h"
@@ -191,7 +192,7 @@
   const_iterator token_begin() const { return token_begin_; }
   const_iterator token_end() const { return token_end_; }
   str token() const { return str(token_begin_, token_end_); }
-  BasicStringPiece<char_type> token_piece() const {
+  std::basic_string_view<char_type> token_piece() const {
     return MakeBasicStringPiece<char_type>(token_begin_, token_end_);
   }
 
diff --git a/base/strings/string_util.h b/base/strings/string_util.h
index 554e90e..04a56dcd 100644
--- a/base/strings/string_util.h
+++ b/base/strings/string_util.h
@@ -91,7 +91,8 @@
 // Simplified implementation of C++20's std::basic_string_view(It, End).
 // Reference: https://wg21.link/string.view.cons
 template <typename CharT, typename Iter>
-constexpr BasicStringPiece<CharT> MakeBasicStringPiece(Iter begin, Iter end) {
+constexpr std::basic_string_view<CharT> MakeBasicStringPiece(Iter begin,
+                                                             Iter end) {
   DCHECK_GE(end - begin, 0);
   return {std::to_address(begin), static_cast<size_t>(end - begin)};
 }
diff --git a/base/strings/string_util_impl_helpers.h b/base/strings/string_util_impl_helpers.h
index da4148a..e328fdd1 100644
--- a/base/strings/string_util_impl_helpers.h
+++ b/base/strings/string_util_impl_helpers.h
@@ -6,6 +6,7 @@
 #define BASE_STRINGS_STRING_UTIL_IMPL_HELPERS_H_
 
 #include <algorithm>
+#include <string_view>
 
 #include "base/check.h"
 #include "base/check_op.h"
@@ -220,7 +221,7 @@
   if (search_for.size() > str.size())
     return false;
 
-  BasicStringPiece<CharT> source = str.substr(0, search_for.size());
+  std::basic_string_view<CharT> source = str.substr(0, search_for.size());
 
   switch (case_sensitivity) {
     case CompareCase::SENSITIVE:
@@ -237,7 +238,7 @@
   if (search_for.size() > str.size())
     return false;
 
-  BasicStringPiece<CharT> source =
+  std::basic_string_view<CharT> source =
       str.substr(str.size() - search_for.size(), search_for.size());
 
   switch (case_sensitivity) {
@@ -253,7 +254,7 @@
 // A Matcher for DoReplaceMatchesAfterOffset() that matches substrings.
 template <class CharT>
 struct SubstringMatcher {
-  BasicStringPiece<CharT> find_this;
+  std::basic_string_view<CharT> find_this;
 
   size_t Find(const std::basic_string<CharT>& input, size_t pos) {
     return input.find(find_this.data(), pos, find_this.length());
@@ -270,7 +271,7 @@
 // A Matcher for DoReplaceMatchesAfterOffset() that matches single characters.
 template <class CharT>
 struct CharacterMatcher {
-  BasicStringPiece<CharT> find_any_of_these;
+  std::basic_string_view<CharT> find_any_of_these;
 
   size_t Find(const std::basic_string<CharT>& input, size_t pos) {
     return input.find_first_of(find_any_of_these.data(), pos,
diff --git a/base/strings/string_util_internal.h b/base/strings/string_util_internal.h
index 2a850e4..7a98e84 100644
--- a/base/strings/string_util_internal.h
+++ b/base/strings/string_util_internal.h
@@ -6,6 +6,7 @@
 #define BASE_STRINGS_STRING_UTIL_INTERNAL_H_
 
 #include <concepts>
+#include <string_view>
 #include <type_traits>
 
 #include "base/ranges/algorithm.h"
@@ -51,8 +52,8 @@
 }
 
 template <typename CharT, typename CharU>
-inline bool EqualsCaseInsensitiveASCIIT(BasicStringPiece<CharT> a,
-                                        BasicStringPiece<CharU> b) {
+inline bool EqualsCaseInsensitiveASCIIT(std::basic_string_view<CharT> a,
+                                        std::basic_string_view<CharU> b) {
   return ranges::equal(a, b, [](auto lhs, auto rhs) {
     return ToLowerASCII(lhs) == ToLowerASCII(rhs);
   });
diff --git a/base/strings/sys_string_conversions_apple.mm b/base/strings/sys_string_conversions_apple.mm
index 8d656df6..710490c 100644
--- a/base/strings/sys_string_conversions_apple.mm
+++ b/base/strings/sys_string_conversions_apple.mm
@@ -7,6 +7,7 @@
 #import <Foundation/Foundation.h>
 #include <stddef.h>
 
+#include <string_view>
 #include <vector>
 
 #include "base/apple/bridging.h"
@@ -99,7 +100,7 @@
 // it as a CFStringRef. Returns null on failure.
 template <typename CharT>
 apple::ScopedCFTypeRef<CFStringRef> StringPieceToCFStringWithEncodingsT(
-    BasicStringPiece<CharT> in,
+    std::basic_string_view<CharT> in,
     CFStringEncoding in_encoding) {
   const auto in_length = in.length();
   if (in_length == 0) {
diff --git a/build/android/pylib/local/device/local_device_instrumentation_test_run.py b/build/android/pylib/local/device/local_device_instrumentation_test_run.py
index 892e6aa..ba30c86 100644
--- a/build/android/pylib/local/device/local_device_instrumentation_test_run.py
+++ b/build/android/pylib/local/device/local_device_instrumentation_test_run.py
@@ -783,7 +783,8 @@
 
       if self._env.force_main_user:
         coverage_directory = device.ResolveSpecialPath(coverage_directory)
-      if not device.PathExists(coverage_directory):
+      if not device.PathExists(coverage_directory,
+                               as_root=self._env.force_main_user):
         # Root permission is needed when accessing a secondary user's path.
         device.RunShellCommand(['mkdir', '-p', coverage_directory],
                                check_return=True,
@@ -1346,7 +1347,7 @@
     device_file_path = trace_device_file.name
     if self._env.force_main_user:
       device_file_path = device.ResolveSpecialPath(device_file_path)
-    if device.FileExists(device_file_path, as_root=self._env.force_main_user):
+    if device.PathExists(device_file_path, as_root=self._env.force_main_user):
       try:
         java_trace_json = device.ReadFile(device_file_path,
                                           as_root=self._env.force_main_user)
@@ -1410,7 +1411,7 @@
     device_file_path = screenshot_device_file.name
     if self._env.force_main_user:
       device_file_path = device.ResolveSpecialPath(device_file_path)
-    if device.FileExists(device_file_path):
+    if device.PathExists(device_file_path, as_root=self._env.force_main_user):
       with self._env.output_manager.ArchivedTempfile(
           screenshot_filename, 'screenshot',
           output_manager.Datatype.PNG) as screenshot_host_file:
@@ -1440,7 +1441,7 @@
     logging.info('Starting Gold directory existence check')
     start_time = time.time()
     try:
-      if not device.FileExists(gold_dir):
+      if not device.PathExists(gold_dir):
         return
     finally:
       logging.info('Gold directory existence check took %fs',
diff --git a/build/config/clang/BUILD.gn b/build/config/clang/BUILD.gn
index d4de2e0c..d3054d1 100644
--- a/build/config/clang/BUILD.gn
+++ b/build/config/clang/BUILD.gn
@@ -36,13 +36,6 @@
       "-Xclang",
       "check-raw-ptr-to-stack-allocated",
 
-      # TODO(https://crbug.com/1449812): This option should be removed after
-      #   next clang roll.
-      "-Xclang",
-      "-plugin-arg-find-bad-constructs",
-      "-Xclang",
-      "raw-ptr-fix-crbug-1449812",
-
       # TODO(https://crbug.com/1504043): Remove when raw_ptr check has been enabled for the dawn repo.
       "-Xclang",
       "-plugin-arg-find-bad-constructs",
diff --git a/chrome/VERSION b/chrome/VERSION
index 27a82d9..c29092c0 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=122
 MINOR=0
-BUILD=6194
+BUILD=6195
 PATCH=0
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/TabDragSource.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/TabDragSource.java
index 6cb9979..7c0e00b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/TabDragSource.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/TabDragSource.java
@@ -9,6 +9,7 @@
 import android.content.ClipDescription;
 import android.content.Context;
 import android.content.Intent;
+import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Point;
 import android.graphics.PointF;
@@ -62,22 +63,23 @@
     private Supplier<TabContentManager> mTabContentManagerSupplier;
     private Supplier<LayerTitleCache> mLayerTitleCacheSupplier;
     private BrowserControlsStateProvider mBrowserControlStateProvider;
-    private View mDragSourceView;
-    private StripTabDragShadowView mShadowView;
-    private PointF mDragShadowDefaultOffset = new PointF(0, 0);
     private float mPxToDp;
     private final ObservableSupplier<Integer> mTabStripHeightSupplier;
+    @Nullable private TabModelSelector mTabModelSelector;
+
+    /** Drag shadow properties * */
+    @Nullable private StripTabDragShadowView mShadowView;
+
+    @Nullable private Drawable mAppIcon;
 
     /** Drag Event Listener trackers * */
     // Drag start screen position.
     private PointF mStartScreenPos;
-
     // Last drag positions relative to the source view. Set when drag starts or is moved within
     // view.
     private float mLastXDp;
     private float mLastYDp;
     private int mLastAction;
-    @Nullable private TabModelSelector mTabModelSelector;
 
     /**
      * Prepares the toolbar view to listen to the drag events and data drop after the drag is
@@ -113,18 +115,21 @@
         mDragAndDropDelegate = dragAndDropDelegate;
         mBrowserControlStateProvider = browserControlStateProvider;
         mWindowAndroid = windowAndroid;
+        if (TabUiFeatureUtilities.isTabDragAsWindowEnabled()) {
+            mAppIcon = context.getPackageManager().getApplicationIcon(context.getApplicationInfo());
+        }
     }
 
     /**
      * Starts the tab drag action by initiating the process by calling @{link
      * View.startDragAndDrop}.
      *
-     * @param toolbarContainerView @{link View} used to create the drag shadow.
+     * @param dragSourceView @{link View} used to create the drag shadow.
      * @param tabBeingDragged @{link Tab} is the selected tab being dragged.
      * @param startPoint Position of the drag start point in view coordinates.
      */
     public boolean startTabDragAction(
-            @NonNull View toolbarContainerView,
+            @NonNull View dragSourceView,
             @NonNull Tab tabBeingDragged,
             @NonNull PointF startPoint) {
         if (!TabUiFeatureUtilities.isTabDragEnabled()
@@ -138,38 +143,34 @@
         }
 
         setGlobalState(tabBeingDragged);
+        updateShadowView(tabBeingDragged, dragSourceView);
 
+        DropDataAndroid dropData =
+                new ChromeDropDataAndroid.Builder().withTabId(tabBeingDragged.getId()).build();
+        DragShadowBuilder builder = createDragShadowBuilder(dragSourceView, startPoint);
+        DragDropGlobalState.getInstance().dragShadowBuilder = builder;
+        return mDragAndDropDelegate.startDragAndDrop(dragSourceView, builder, dropData);
+    }
+
+    @VisibleForTesting
+    void updateShadowView(@NonNull Tab tabBeingDragged, @NonNull View dragSourceView) {
+        // Shadow view is unused for drag as window.
+        if (TabUiFeatureUtilities.isTabDragAsWindowEnabled()) return;
         if (mShadowView == null) {
             View rootView =
                     View.inflate(
-                            toolbarContainerView.getContext(),
+                            dragSourceView.getContext(),
                             R.layout.strip_tab_drag_shadow_view,
-                            (ViewGroup) toolbarContainerView.getRootView());
+                            (ViewGroup) dragSourceView.getRootView());
             mShadowView = rootView.findViewById(R.id.strip_tab_drag_shadow_view);
 
             mShadowView.initialize(
                     mBrowserControlStateProvider,
                     mTabContentManagerSupplier,
                     mLayerTitleCacheSupplier,
-                    () -> {
-                        if (DragDropGlobalState.getInstance().dragShadowShowing) {
-                            showDragShadow(true);
-                        }
-                    });
+                    () -> showDragShadow(true));
         }
         mShadowView.setTab(tabBeingDragged);
-
-        mDragSourceView = toolbarContainerView;
-        mDragShadowDefaultOffset =
-                TabUiFeatureUtilities.isTabDragAsWindowEnabled()
-                        ? getPositionOnScreen(toolbarContainerView, startPoint)
-                        : new PointF(0f, 0f);
-
-        DropDataAndroid dropData =
-                new ChromeDropDataAndroid.Builder().withTabId(tabBeingDragged.getId()).build();
-        DragShadowBuilder builder =
-                createTabDragShadowBuilder(toolbarContainerView.getContext(), false);
-        return mDragAndDropDelegate.startDragAndDrop(toolbarContainerView, builder, dropData);
     }
 
     @Override
@@ -249,7 +250,13 @@
     }
 
     private boolean onDragEnter() {
-        if (!isDragSource()) return false;
+        if (!isDragSource()) {
+            if (TabUiFeatureUtilities.isTabDragAsWindowEnabled()) {
+                showDragShadow(false);
+                return true;
+            }
+            return false;
+        }
         mStripLayoutHelperSupplier
                 .get()
                 .dragActiveClickedTabOntoStrip(LayoutManagerImpl.time(), mLastXDp);
@@ -314,24 +321,28 @@
         DragDropGlobalState.getInstance().reset();
         // TODO (crbug.com/1497784): Remove this method.
         mStripLayoutHelperSupplier.get().clearActiveClickedTab();
-        mShadowView.clear();
+        if (mShadowView != null) {
+            mShadowView.clear();
+        }
         return true;
     }
 
     private boolean onDragExit() {
-        if (!isDragSource()) return false;
         // Show drag shadow when drag exits strip.
-        // TODO (crbug.com/1497784): Call this once on first drag exit. Reset on drag end.
         showDragShadow(true);
-        mStripLayoutHelperSupplier.get().dragActiveClickedTabOutOfStrip(LayoutManagerImpl.time());
+        if (isDragSource()) {
+            mStripLayoutHelperSupplier
+                    .get()
+                    .dragActiveClickedTabOutOfStrip(LayoutManagerImpl.time());
+        }
         return true;
     }
 
     private void showDragShadow(boolean show) {
-        assert mDragSourceView != null;
-        DragDropGlobalState.getInstance().dragShadowShowing = show;
-        DragShadowBuilder builder = createTabDragShadowBuilder(mDragSourceView.getContext(), show);
-        mDragSourceView.updateDragShadow(builder);
+        TabDragShadowBuilder builder =
+                (TabDragShadowBuilder) DragDropGlobalState.getInstance().dragShadowBuilder;
+        if (builder == null) return;
+        builder.update(show);
     }
 
     private boolean isDragSource() {
@@ -395,13 +406,63 @@
                 mMultiInstanceManager.getCurrentInstanceId();
     }
 
-    private static class TabDragShadowBuilder extends View.DragShadowBuilder {
+    @VisibleForTesting
+    static class TabDragShadowBuilder extends View.DragShadowBuilder {
+        // Touch offset for drag shadow view.
         private PointF mDragShadowOffset;
+        // Source initiating drag - to call updateDragShadow().
+        private View mDragSourceView;
+        // Content to add to shadowView.
+        @Nullable private Drawable mViewContent;
+        // Whether drag shadow should be shown.
+        private boolean mShowDragShadow;
 
-        public TabDragShadowBuilder(View view, PointF dragShadowOffset) {
+        public TabDragShadowBuilder(
+                View dragSourceView,
+                View shadowView,
+                PointF dragShadowOffset,
+                Drawable viewContent) {
             // Store the View parameter.
-            super(view);
+            super(shadowView);
             mDragShadowOffset = dragShadowOffset;
+            mDragSourceView = dragSourceView;
+            mViewContent = viewContent;
+        }
+
+        public TabDragShadowBuilder(View dragSourceView, View shadowView) {
+            this(dragSourceView, shadowView, new PointF(0f, 0f), null);
+        }
+
+        public void update(boolean show) {
+            if (show == mShowDragShadow) return;
+            mShowDragShadow = show;
+            mDragSourceView.updateDragShadow(this);
+        }
+
+        @Override
+        public void onDrawShadow(@NonNull Canvas canvas) {
+            View shadowView = getView();
+            if (mShowDragShadow) {
+                if (TabUiFeatureUtilities.isTabDragAsWindowEnabled()) {
+                    assert mViewContent != null;
+                    ((ImageView) shadowView).setImageDrawable(mViewContent);
+                    shadowView.setBackgroundDrawable(new ColorDrawable(Color.LTGRAY));
+                    // Pad content to the center of the drag shadow.
+                    int paddingHorizontal =
+                            (shadowView.getWidth() - mViewContent.getIntrinsicWidth()) / 2;
+                    int paddingVertical =
+                            (shadowView.getHeight() - mViewContent.getIntrinsicHeight()) / 2;
+                    shadowView.setPadding(
+                            paddingHorizontal, paddingVertical, paddingHorizontal, paddingVertical);
+                    shadowView.layout(0, 0, shadowView.getWidth(), shadowView.getHeight());
+                }
+                shadowView.draw(canvas);
+            } else {
+                // When drag shadow should hide, replace with empty ImageView.
+                ImageView imageView = new ImageView(shadowView.getContext());
+                imageView.layout(0, 0, shadowView.getWidth(), shadowView.getHeight());
+                imageView.draw(canvas);
+            }
         }
 
         // Defines a callback that sends the drag shadow dimensions and touch point
@@ -425,55 +486,21 @@
             touch.set(Math.round(mDragShadowOffset.x), Math.round(mDragShadowOffset.y));
             Log.d(TAG, "DnD onProvideShadowMetrics: " + mDragShadowOffset);
         }
+
+        boolean getShadowShownForTesting() {
+            return mShowDragShadow;
+        }
     }
 
-    @NonNull
-    @VisibleForTesting
-    DragShadowBuilder createTabDragShadowBuilder(Context context, boolean show) {
-        int shadowWidthPx;
-        int shadowHeightPx;
-        ImageView imageView = new ImageView(context);
-        if (TabUiFeatureUtilities.isTabDragAsWindowEnabled()) {
-            // View is empty and nothing is shown for now.
-            // Get Chrome window dimensions and set the view to that size.
-            View decorView = getDecorView();
-            shadowWidthPx = decorView.getWidth();
-            shadowHeightPx = decorView.getHeight();
-            if (show) {
-                addAppIconToShadow(imageView, context, shadowWidthPx, shadowHeightPx);
-            }
-        } else {
-            if (show) {
-                return new TabDragShadowBuilder(mShadowView, mDragShadowDefaultOffset);
-            }
-            shadowWidthPx = mShadowView.getWidth();
-            shadowHeightPx = mShadowView.getHeight();
+    DragShadowBuilder createDragShadowBuilder(View dragSourceView, PointF startPoint) {
+        if (!TabUiFeatureUtilities.isTabDragAsWindowEnabled()) {
+            return new TabDragShadowBuilder(dragSourceView, mShadowView);
         }
-        if (show) {
-            imageView.setBackgroundDrawable(new ColorDrawable(Color.LTGRAY));
-        }
-        imageView.layout(0, 0, shadowWidthPx, shadowHeightPx);
-        return new TabDragShadowBuilder(imageView, mDragShadowDefaultOffset);
-    }
-
-    private void addAppIconToShadow(
-            ImageView imageView, Context context, int shadowWidth, int shadowHeight) {
-        try {
-            Drawable icon =
-                    context.getPackageManager().getApplicationIcon(context.getApplicationInfo());
-            imageView.setImageDrawable(icon);
-
-            // Add app icon in the center of the drag shadow.
-            int iconWidth = icon.getIntrinsicWidth();
-            int iconHeight = icon.getIntrinsicHeight();
-            int paddingHorizontal = (shadowWidth - iconWidth) / 2;
-            int paddingVertical = (shadowHeight - iconHeight) / 2;
-            imageView.setPadding(
-                    paddingHorizontal, paddingVertical, paddingHorizontal, paddingVertical);
-            imageView.layout(0, 0, shadowWidth, shadowHeight);
-        } catch (Exception e) {
-            Log.e(TAG, "DnD Failed to create drag shadow image view: " + e.getMessage());
-        }
+        ImageView imageView = new ImageView(dragSourceView.getContext());
+        View decorView = getDecorView();
+        imageView.layout(0, 0, decorView.getWidth(), decorView.getHeight());
+        PointF dragShadowOffset = getPositionOnScreen(dragSourceView, startPoint);
+        return new TabDragShadowBuilder(dragSourceView, imageView, dragShadowOffset, mAppIcon);
     }
 
     private void sendPositionInfoToSysUI(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/dragdrop/DragDropGlobalState.java b/chrome/android/java/src/org/chromium/chrome/browser/dragdrop/DragDropGlobalState.java
index f55dc1e..6ee70d3 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/dragdrop/DragDropGlobalState.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/dragdrop/DragDropGlobalState.java
@@ -4,6 +4,8 @@
 
 package org.chromium.chrome.browser.dragdrop;
 
+import android.view.View.DragShadowBuilder;
+
 import org.chromium.chrome.browser.multiwindow.MultiWindowUtils;
 import org.chromium.chrome.browser.tab.Tab;
 
@@ -12,17 +14,17 @@
 
     private static DragDropGlobalState sInstance = new DragDropGlobalState();
 
-    public boolean dragShadowShowing;
     public int dragSourceInstanceId = MultiWindowUtils.INVALID_INSTANCE_ID;
     public Tab tabBeingDragged;
+    public DragShadowBuilder dragShadowBuilder;
 
     public static DragDropGlobalState getInstance() {
         return sInstance;
     }
 
     public void reset() {
-        dragShadowShowing = false;
         dragSourceInstanceId = MultiWindowUtils.INVALID_INSTANCE_ID;
         tabBeingDragged = null;
+        dragShadowBuilder = null;
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhoneTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhoneTest.java
index bb26821d5..a3a18cd 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhoneTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhoneTest.java
@@ -1068,8 +1068,7 @@
         TestThreadUtils.runOnUiThreadBlocking(
                 () -> {
                     mToolbar.setNtpSearchBoxScrollFractionForTesting(1);
-                    mToolbar.updateLocationBarForSurfacePolish(
-                            VisualState.NEW_TAB_NORMAL, /* hasFocus= */ false);
+                    mToolbar.updateLocationBarForSurfacePolish(VisualState.NEW_TAB_NORMAL, false);
                 });
         if (nightModeEnabled) {
             assertEquals(View.INVISIBLE, iconBackground.getVisibility());
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/TabDragSourceTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/TabDragSourceTest.java
index b657cd49f..30b1325 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/TabDragSourceTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/TabDragSourceTest.java
@@ -7,6 +7,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
@@ -14,10 +15,12 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
 import android.app.Activity;
@@ -52,6 +55,7 @@
 import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider;
 import org.chromium.chrome.browser.compositor.LayerTitleCache;
 import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
+import org.chromium.chrome.browser.compositor.overlays.strip.TabDragSource.TabDragShadowBuilder;
 import org.chromium.chrome.browser.dragdrop.DragDropGlobalState;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.multiwindow.MultiInstanceManager;
@@ -78,21 +82,22 @@
 @Config(qualifiers = "sw600dp", sdk = VERSION_CODES.S)
 public class TabDragSourceTest {
 
-    public static final int CURR_INSTANCE_ID = 100;
-    public static final int TAB_ID = 1;
+    private static final int CURR_INSTANCE_ID = 100;
+    private static final int ANOTHER_INSTANCE_ID = 200;
+    private static final int TAB_ID = 1;
+    private static final int TAB_ID_NOT_DRAGGED = 2;
+    private static final float TAB_WIDTH = 5f;
+    private static final int TAB_INDEX = 2;
     private static final float POS_X = 20f;
     private static final float DRAG_MOVE_DISTANCE = 5f;
     private static final String[] SUPPORTED_MIME_TYPES = {"chrome/tab"};
-    private static final int TAB_ID_NOT_DRAGGED = 2;
     private float mPosY;
     @Rule public MockitoRule mMockitoProcessorRule = MockitoJUnit.rule();
     @Rule public TestRule mFeaturesProcessorRule = new Features.JUnitProcessor();
-    @Mock private MultiInstanceManager mMultiInstanceManager;
     @Mock private DragAndDropDelegate mDragDropDelegate;
     @Mock private BrowserControlsStateProvider mBrowserControlsStateProvider;
     @Mock private TabContentManager mTabContentManager;
     @Mock private LayerTitleCache mLayerTitleCache;
-    @Mock private StripLayoutHelper mStripLayoutHelper;
     @Mock private Profile mProfile;
     @Mock private TabModelSelector mTabModelSelector;
     @Mock private TestTabModel mTabModel;
@@ -100,12 +105,17 @@
     @Mock private MultiWindowUtils mMultiWindowUtils;
     @Mock private ObservableSupplier<Integer> mTabStripHeightSupplier;
 
+    // Instances that differ for source and destination for invocations and verifications.
+    @Mock private StripLayoutHelper mSourceStripLayoutHelper;
+    @Mock private StripLayoutHelper mDestStripLayoutHelper;
+    @Mock private MultiInstanceManager mSourceMultiInstanceManager;
+    @Mock private MultiInstanceManager mDestMultiInstanceManager;
+    private TabDragSource mSourceInstance;
+    private TabDragSource mDestInstance;
+
     private Activity mActivity;
-    private TabDragSource mTabDragSource;
     private ViewGroup mTabsToolbarView;
     private Tab mTabBeingDragged;
-    private static final float DROP_X_SCREEN_POS = 1000.f;
-    private static final float DROP_Y_SCREEN_POS = 500.f;
     private static final PointF DRAG_START_POINT = new PointF(0, 0);
     private int mTabStripHeight;
 
@@ -123,28 +133,43 @@
 
         PriceTrackingFeatures.setPriceTrackingEnabledForTesting(false);
         mTabBeingDragged = MockTab.createAndInitialize(TAB_ID, mProfile);
-        when(mMultiInstanceManager.getCurrentInstanceId()).thenReturn(CURR_INSTANCE_ID);
+        when(mSourceMultiInstanceManager.getCurrentInstanceId()).thenReturn(CURR_INSTANCE_ID);
+        when(mDestMultiInstanceManager.getCurrentInstanceId()).thenReturn(ANOTHER_INSTANCE_ID);
+
         when(mWindowAndroid.getActivity()).thenReturn(new WeakReference<>(mActivity));
 
         when(mMultiWindowUtils.isMoveToOtherWindowSupported(any(), any())).thenReturn(true);
         MultiWindowUtils.setInstanceForTesting(mMultiWindowUtils);
         MultiWindowTestUtils.enableMultiInstance();
+        when(mTabModelSelector.getCurrentModel()).thenReturn(mTabModel);
 
         when(mTabStripHeightSupplier.get()).thenReturn(mTabStripHeight);
 
-        mTabDragSource =
+        mSourceInstance =
                 new TabDragSource(
                         mActivity,
-                        () -> mStripLayoutHelper,
+                        () -> mSourceStripLayoutHelper,
                         () -> mTabContentManager,
                         () -> mLayerTitleCache,
-                        mMultiInstanceManager,
+                        mSourceMultiInstanceManager,
                         mDragDropDelegate,
                         mBrowserControlsStateProvider,
                         mWindowAndroid,
                         mTabStripHeightSupplier);
-        when(mTabModelSelector.getCurrentModel()).thenReturn(mTabModel);
-        mTabDragSource.setTabModelSelector(mTabModelSelector);
+        mSourceInstance.setTabModelSelector(mTabModelSelector);
+
+        mDestInstance =
+                new TabDragSource(
+                        mActivity,
+                        () -> mDestStripLayoutHelper,
+                        () -> mTabContentManager,
+                        () -> mLayerTitleCache,
+                        mDestMultiInstanceManager,
+                        mDragDropDelegate,
+                        mBrowserControlsStateProvider,
+                        mWindowAndroid,
+                        mTabStripHeightSupplier);
+        mDestInstance.setTabModelSelector(mTabModelSelector);
     }
 
     @After
@@ -155,7 +180,7 @@
     @EnableFeatures({ChromeFeatureList.TAB_DRAG_DROP_ANDROID})
     @DisableFeatures(ChromeFeatureList.TAB_LINK_DRAG_DROP_ANDROID)
     @Test
-    public void test_startTabDragAction_withTabDragDropFF_ReturnsTrueForValidTab() {
+    public void test_startTabDragAction_withTabDragDropFF_returnsTrueForValidTab() {
         when(mDragDropDelegate.startDragAndDrop(
                         eq(mTabsToolbarView),
                         any(DragShadowBuilder.class),
@@ -163,7 +188,7 @@
                 .thenReturn(true);
         // Act and verify.
         boolean res =
-                mTabDragSource.startTabDragAction(
+                mSourceInstance.startTabDragAction(
                         mTabsToolbarView, mTabBeingDragged, DRAG_START_POINT);
         assertTrue("startTabDragAction returned false.", res);
         verify(mDragDropDelegate)
@@ -179,14 +204,13 @@
                 "Global state tabBeingDragged not set.",
                 mTabBeingDragged,
                 DragDropGlobalState.getInstance().tabBeingDragged);
-        assertNotNull(
-                "Shadow view is unexpectedly null.", mTabDragSource.getShadowViewForTesting());
+        assertNull("Shadow view should be null.", mSourceInstance.getShadowViewForTesting());
     }
 
     @DisableFeatures(ChromeFeatureList.TAB_DRAG_DROP_ANDROID)
     @EnableFeatures(ChromeFeatureList.TAB_LINK_DRAG_DROP_ANDROID)
     @Test
-    public void test_startTabDragAction_withTabLinkDragDropFF_ReturnsTrueForValidTab() {
+    public void test_startTabDragAction_withTabLinkDragDropFF_returnsTrueForValidTab() {
         when(mDragDropDelegate.startDragAndDrop(
                         eq(mTabsToolbarView),
                         any(DragShadowBuilder.class),
@@ -194,7 +218,7 @@
                 .thenReturn(true);
         // Act and verify.
         boolean res =
-                mTabDragSource.startTabDragAction(
+                mSourceInstance.startTabDragAction(
                         mTabsToolbarView, mTabBeingDragged, DRAG_START_POINT);
         assertTrue("startTabDragAction returned false.", res);
         verify(mDragDropDelegate)
@@ -211,14 +235,14 @@
                 mTabBeingDragged,
                 DragDropGlobalState.getInstance().tabBeingDragged);
         assertNotNull(
-                "Shadow view is unexpectedly null.", mTabDragSource.getShadowViewForTesting());
+                "Shadow view is unexpectedly null.", mSourceInstance.getShadowViewForTesting());
     }
 
     @Test
-    public void test_startTabDragAction_ExceptionForInvalidTab() {
+    public void test_startTabDragAction_exceptionForInvalidTab() {
         assertThrows(
                 NullPointerException.class,
-                () -> mTabDragSource.startTabDragAction(mTabsToolbarView, null, DRAG_START_POINT));
+                () -> mSourceInstance.startTabDragAction(mTabsToolbarView, null, DRAG_START_POINT));
     }
 
     @EnableFeatures({ChromeFeatureList.TAB_DRAG_DROP_ANDROID})
@@ -228,240 +252,11 @@
         when(mMultiWindowUtils.isMoveToOtherWindowSupported(any(), any())).thenReturn(false);
         assertFalse(
                 "Should not startTabDragAction when move to other window is not supported",
-                mTabDragSource.startTabDragAction(
+                mSourceInstance.startTabDragAction(
                         mTabsToolbarView, mTabBeingDragged, DRAG_START_POINT));
     }
 
     @Test
-    public void test_DragDropWithinStrip_ReturnsSuccess() {
-        // Call startDrag to set class variables.
-        mTabDragSource.startTabDragAction(mTabsToolbarView, mTabBeingDragged, DRAG_START_POINT);
-
-        /**
-         * Perform drag n drop simulation actions for movement within the strip layout. Drag start
-         * -> enter -> 2 moves within strip -> drop -> end.
-         */
-        triggerDragEvent(DragEvent.ACTION_DRAG_STARTED, POS_X, mPosY);
-        triggerDragEvent(DragEvent.ACTION_DRAG_ENTERED, POS_X, mPosY);
-        triggerDragEvent(DragEvent.ACTION_DRAG_LOCATION, POS_X + DRAG_MOVE_DISTANCE, mPosY);
-        triggerDragEvent(DragEvent.ACTION_DRAG_LOCATION, POS_X + 2 * DRAG_MOVE_DISTANCE, mPosY);
-        triggerDragEvent(DragEvent.ACTION_DROP, POS_X, mPosY);
-        triggerDragEvent(DragEvent.ACTION_DRAG_ENDED, 0f, 0f);
-
-        // Verify appropriate events are generated to simulate movement within the strip layout.
-        // Drag tab onto strip on drag enter.
-        verify(mStripLayoutHelper, times(1)).dragActiveClickedTabOntoStrip(anyLong(), anyFloat());
-        // Invoke drag on drag moves.
-        verify(mStripLayoutHelper, times(1)).drag(anyLong(), anyFloat(), anyFloat(), anyFloat());
-        // Stop reorder on drop.
-        verify(mStripLayoutHelper, times(1)).onUpOrCancel(anyLong());
-        // Verify tab is not moved.
-        verify(mMultiInstanceManager, times(0)).moveTabToNewWindow(mTabBeingDragged);
-        verify(mMultiInstanceManager, times(0)).moveTabToWindow(any(), any(), anyInt());
-        // Verify clear.
-        verify(mStripLayoutHelper, times(1)).clearActiveClickedTab();
-    }
-
-    @Test
-    @DisableFeatures(ChromeFeatureList.TAB_LINK_DRAG_DROP_ANDROID)
-    @EnableFeatures(ChromeFeatureList.TAB_DRAG_DROP_ANDROID)
-    public void test_DragOutsideStrip_ReturnsSuccess() {
-        // Call startDrag to set class variables.
-        mTabDragSource.startTabDragAction(mTabsToolbarView, mTabBeingDragged, DRAG_START_POINT);
-
-        /**
-         * Perform drag n drop simulation actions for movement outside the strip area. Drag start ->
-         * enter -> move within strip -> move out of strip but within toolbar -> move back to strip
-         * -> exit.
-         */
-        triggerDragEvent(DragEvent.ACTION_DRAG_STARTED, POS_X, mPosY);
-        triggerDragEvent(DragEvent.ACTION_DRAG_ENTERED, POS_X, mPosY);
-        // Move within the tab strip area to trigger the #onDragEnter.
-        triggerDragEvent(DragEvent.ACTION_DRAG_LOCATION, POS_X, mPosY + DRAG_MOVE_DISTANCE);
-        // Move within the tab strip area again after entering to trigger the #onDragLocation.
-        triggerDragEvent(DragEvent.ACTION_DRAG_LOCATION, POS_X, mPosY + DRAG_MOVE_DISTANCE);
-        // Move outside the tab strip area but inside the toolbar.
-        triggerDragEvent(DragEvent.ACTION_DRAG_LOCATION, POS_X, mPosY + 3 * DRAG_MOVE_DISTANCE);
-        triggerDragEvent(
-                DragEvent.ACTION_DRAG_LOCATION,
-                POS_X,
-                mPosY + 2 * DRAG_MOVE_DISTANCE); // Back to within the tabs area.
-        triggerDragEvent(
-                DragEvent.ACTION_DRAG_EXITED, POS_X, mTabStripHeight + 10 * DRAG_MOVE_DISTANCE);
-        triggerDragEvent(DragEvent.ACTION_DRAG_ENDED, DROP_X_SCREEN_POS, DROP_Y_SCREEN_POS);
-
-        // Verify appropriate events are generated to simulate movement outside the strip area.
-        // Drag tab onto strip on drag enter. Enter occurs twice.
-        verify(mStripLayoutHelper, times(2)).dragActiveClickedTabOntoStrip(anyLong(), anyFloat());
-        // Move within strip.
-        verify(mStripLayoutHelper, times(1)).drag(anyLong(), anyFloat(), anyFloat(), anyFloat());
-        // Drag tab out of strip on drag exit. Exit occurs twice.
-        verify(mStripLayoutHelper, times(2)).dragActiveClickedTabOutOfStrip(anyLong());
-        // Verify Since the drop is outside the TabToolbar area the tab will be move to a new
-        // Chrome Window.
-        verify(mMultiInstanceManager, times(1)).moveTabToNewWindow(mTabBeingDragged);
-        // Verify tab cleared.
-        verify(mStripLayoutHelper, times(1)).clearActiveClickedTab();
-    }
-
-    @Test
-    public void test_DropInSourceTabStrip_DontMoveTabToOtherWindow() {
-        triggerDragEvent(DragEvent.ACTION_DRAG_STARTED, POS_X, mPosY);
-        triggerDragEvent(DragEvent.ACTION_DROP, POS_X, mPosY);
-        triggerDragEvent(DragEvent.ACTION_DRAG_ENDED, POS_X, mPosY);
-
-        // Verify - Move tab is not invoked.
-        verify(mMultiInstanceManager, times(0)).moveTabToNewWindow(mTabBeingDragged);
-        verify(mMultiInstanceManager, times(0)).moveTabToWindow(any(), any(), anyInt());
-    }
-
-    @Test
-    public void test_DropInSourceToolbar_NoOp() {
-        triggerDragEvent(DragEvent.ACTION_DRAG_STARTED, POS_X, mPosY);
-        triggerDragEvent(DragEvent.ACTION_DROP, POS_X, mTabStripHeight + 5);
-        triggerDragEvent(DragEvent.ACTION_DRAG_ENDED, POS_X, mTabStripHeight + 5);
-
-        verifyNoInteractions(mStripLayoutHelper);
-        verify(mMultiInstanceManager, times(0)).moveTabToWindow(any(), any(), anyInt());
-        verify(mMultiInstanceManager, times(0)).moveTabToNewWindow(any());
-    }
-
-    @Test
-    public void test_DropInDestinationStripOnFirstHalfOfTab_MoveTabToDestinationAtIndex() {
-        // Set state.
-        mTabDragSource.setGlobalState(mTabBeingDragged);
-        // Simulate destination instance.
-        when(mMultiInstanceManager.getCurrentInstanceId()).thenReturn(CURR_INSTANCE_ID + 1);
-        // Mock strip actions.
-        StripLayoutTab stripTab = mock(StripLayoutTab.class);
-        float tabWidth = 5f;
-        when(stripTab.getWidth()).thenReturn(tabWidth);
-        // Tab drop POS_X is at left half of tab.
-        when(stripTab.getDrawX()).thenReturn(POS_X - (tabWidth / 2));
-        when(stripTab.getId()).thenReturn(10);
-        when(mStripLayoutHelper.findIndexForTab(10)).thenReturn(2);
-        when(mStripLayoutHelper.getTabAtPosition(POS_X)).thenReturn(stripTab);
-
-        // Trigger drop in tab strip.
-        triggerDragEvent(DragEvent.ACTION_DRAG_STARTED, POS_X, mPosY);
-        triggerDragEvent(DragEvent.ACTION_DROP, POS_X, mPosY);
-        triggerDragEvent(DragEvent.ACTION_DRAG_ENDED, POS_X, mPosY);
-
-        // Verify - Tab moved to destination window at index.
-        verify(mMultiInstanceManager, times(1)).moveTabToWindow(any(), eq(mTabBeingDragged), eq(2));
-        verify(mMultiInstanceManager, times(0)).moveTabToNewWindow(mTabBeingDragged);
-    }
-
-    @Test
-    @DisableFeatures(ChromeFeatureList.TAB_LINK_DRAG_DROP_ANDROID)
-    @EnableFeatures(ChromeFeatureList.TAB_DRAG_DROP_ANDROID)
-    public void test_DropInDestinationStripOnLaterHalfOfTab_MoveTabToDestinationAtIndex() {
-        // Set state.
-        mTabDragSource.setGlobalState(mTabBeingDragged);
-        // Simulate destination instance.
-        when(mMultiInstanceManager.getCurrentInstanceId()).thenReturn(CURR_INSTANCE_ID + 1);
-        // Mock strip actions.
-        StripLayoutTab stripTab = mock(StripLayoutTab.class);
-        float tabWidth = 5f;
-        when(stripTab.getWidth()).thenReturn(tabWidth);
-        // Tab drop POS_X is at right half of tab.
-        when(stripTab.getDrawX()).thenReturn(POS_X - (tabWidth / 2 + 1));
-        when(stripTab.getId()).thenReturn(10);
-        when(mStripLayoutHelper.findIndexForTab(10)).thenReturn(2);
-        when(mStripLayoutHelper.getTabAtPosition(POS_X)).thenReturn(stripTab);
-
-        // Trigger drop in tab strip.
-        triggerDragEvent(DragEvent.ACTION_DRAG_STARTED, POS_X, mPosY);
-        triggerDragEvent(DragEvent.ACTION_DROP, POS_X, mPosY);
-        triggerDragEvent(DragEvent.ACTION_DRAG_ENDED, POS_X, mPosY);
-
-        // Verify - Tab moved to destination window at index.
-        verify(mMultiInstanceManager, times(1)).moveTabToWindow(any(), eq(mTabBeingDragged), eq(3));
-        verify(mMultiInstanceManager, times(0)).moveTabToNewWindow(mTabBeingDragged);
-    }
-
-    @Test
-    public void test_DropInDestinationTabStripOnNonTab_MoveTabToDestinationWindowAtEnd() {
-        // Set state.
-        mTabDragSource.setGlobalState(mTabBeingDragged);
-        // Simulate destination instance.
-        when(mMultiInstanceManager.getCurrentInstanceId()).thenReturn(CURR_INSTANCE_ID + 1);
-        // Mock strip actions.
-        when(mStripLayoutHelper.getTabAtPosition(POS_X)).thenReturn(null);
-        when(mTabModel.getCount()).thenReturn(10);
-
-        // Trigger drop in tab strip.
-        triggerDragEvent(DragEvent.ACTION_DRAG_STARTED, POS_X, mPosY);
-        triggerDragEvent(DragEvent.ACTION_DROP, POS_X, mPosY);
-        triggerDragEvent(DragEvent.ACTION_DRAG_ENDED, POS_X, mPosY);
-
-        // Verify - Tab moved to destination window at index.
-        verify(mMultiInstanceManager, times(1))
-                .moveTabToWindow(any(), eq(mTabBeingDragged), eq(10));
-        verify(mMultiInstanceManager, times(0)).moveTabToNewWindow(mTabBeingDragged);
-    }
-
-    @Test
-    public void test_DropInDestination_WithIncorrectClipData_DoesNotMoveTab() {
-        // Call startDrag to set class variables.
-        mTabDragSource.startTabDragAction(mTabsToolbarView, mTabBeingDragged, DRAG_START_POINT);
-        // Simulate destination instance.
-        when(mMultiInstanceManager.getCurrentInstanceId()).thenReturn(CURR_INSTANCE_ID + 1);
-
-        // Trigger drop.
-        triggerDragEvent(DragEvent.ACTION_DRAG_STARTED, POS_X, mPosY);
-        triggerDragEvent(DragEvent.ACTION_DROP, POS_X, mPosY, TAB_ID_NOT_DRAGGED);
-        triggerDragEvent(DragEvent.ACTION_DRAG_ENDED, POS_X, mPosY);
-
-        // Verify - Move to new window not invoked.
-        verify(mMultiInstanceManager, times(0)).moveTabToNewWindow(mTabBeingDragged);
-        verifyNoInteractions(mStripLayoutHelper);
-    }
-
-    @Test
-    public void test_DropInDestinationWithDifferentModel_MoveTabToDestinationAtEnd() {
-        // Set selector
-        mTabDragSource.setTabModelSelector(mTabModelSelector);
-        // Set state - tab created in standard model.
-        mTabDragSource.setGlobalState(mTabBeingDragged);
-        // Simulate destination instance.
-        when(mMultiInstanceManager.getCurrentInstanceId()).thenReturn(CURR_INSTANCE_ID + 1);
-        // Destination tab model is incognito.
-        when(mTabModel.isIncognito()).thenReturn(true);
-        TabModel standardModelDestination = mock(TabModel.class);
-        when(mTabModelSelector.getModel(false)).thenReturn(standardModelDestination);
-        when(standardModelDestination.getCount()).thenReturn(5);
-
-        // Mock strip actions - tab exists at drop position.
-        StripLayoutTab stripTab = mock(StripLayoutTab.class);
-        when(mStripLayoutHelper.getTabAtPosition(POS_X)).thenReturn(stripTab);
-
-        // Trigger drop in tab strip.
-        triggerDragEvent(DragEvent.ACTION_DRAG_STARTED, POS_X, mPosY);
-        triggerDragEvent(DragEvent.ACTION_DROP, POS_X, mPosY);
-        triggerDragEvent(DragEvent.ACTION_DRAG_ENDED, POS_X, mPosY);
-
-        // Verify - Tab moved to destination window at end.
-        verify(mMultiInstanceManager, times(1)).moveTabToWindow(any(), eq(mTabBeingDragged), eq(5));
-        verify(mMultiInstanceManager, times(0)).moveTabToNewWindow(mTabBeingDragged);
-    }
-
-    @Test
-    public void test_DragStartWithInvalidMime_ReturnsFalse() {
-        // Set state.
-        mTabDragSource.setGlobalState(mTabBeingDragged);
-
-        DragEvent event = mock(DragEvent.class);
-        when(event.getAction()).thenReturn(DragEvent.ACTION_DRAG_STARTED);
-        when(event.getX()).thenReturn(POS_X);
-        when(event.getY()).thenReturn(mPosY);
-        when(event.getClipDescription())
-                .thenReturn(new ClipDescription("", new String[] {"some_value"}));
-
-        assertFalse(mTabDragSource.onDrag(mTabsToolbarView, event));
-    }
-
-    @Test
     @EnableFeatures(ChromeFeatureList.TAB_DRAG_DROP_ANDROID)
     @DisableFeatures(ChromeFeatureList.TAB_LINK_DRAG_DROP_ANDROID)
     public void test_onProvideShadowMetrics_WithDesiredStartPosition_ReturnsSuccess() {
@@ -470,10 +265,10 @@
         final float dragStartYPosition = 45f;
         final PointF dragStartPoint = new PointF(dragStartXPosition, dragStartYPosition);
         // Call startDrag to set class variables.
-        mTabDragSource.startTabDragAction(mTabsToolbarView, mTabBeingDragged, dragStartPoint);
+        mSourceInstance.startTabDragAction(mTabsToolbarView, mTabBeingDragged, dragStartPoint);
 
         View.DragShadowBuilder tabDragShadowBuilder =
-                mTabDragSource.createTabDragShadowBuilder(mActivity, true);
+                mSourceInstance.createDragShadowBuilder(mTabsToolbarView, dragStartPoint);
 
         // Perform asking the TabDragShadowBuilder what is the anchor point.
         Point dragSize = new Point(0, 0);
@@ -491,29 +286,393 @@
                 dragAnchor.y);
     }
 
+    /**
+     * Below tests test end to end tab drag drop flow for following combinations:
+     *
+     * <pre>
+     * A] drop in tab strip - source instance (ie: reorder within strip).
+     * B] drop in toolbar container (but outside of tab strip) - source instance.
+     * C] drop outside of toolbar container with sub flows:
+     *  C.1] With drag as tab FF - no-op.
+     *  C.2] With drag as window FF - open new window.
+     * D] Test (A) for drop in destination instance with sub flows:
+     *  D.1] drop on a tab with drop location within first half of droppedOn tab. Move dragged tab to before droppedOn tab.
+     *  D.2] drop on a tab with drop location within second half of droppedOn tab. Move dragged tab to after droppedOn tab.
+     *  D.3] drop on non-tab area.
+     *  D.4] drop in different model (ie: drop standard tab on incognito strip).
+     *  D.5] With drag as window FF - hide shadow on drag enter.
+     * E] Test (B) for drops in destination instance.
+     * F] drag from strip to toolbar container and back to strip, drop in strip (to test re-enter).
+     * G] error cases:
+     *  G.1] invalid mimetype.
+     *  G.2] invalid clip data.
+     *  </pre>
+     */
+    private static final String ONDRAG_TEST_CASES = "";
+
+    /** Test for {@link #ONDRAG_TEST_CASES} - Scenario A */
     @Test
+    public void test_onDrag_dropInStrip_source() {
+        new DragEventInvoker().drop(mSourceInstance).end();
+
+        // Verify appropriate events are generated.
+        // Drag tab onto strip on drag enter.
+        verify(mSourceStripLayoutHelper, times(1))
+                .dragActiveClickedTabOntoStrip(anyLong(), anyFloat());
+        // Stop reorder on drop.
+        verify(mSourceStripLayoutHelper, times(1)).onUpOrCancel(anyLong());
+        // Verify tab is not moved.
+        verify(mSourceMultiInstanceManager, times(0)).moveTabToNewWindow(mTabBeingDragged);
+        verify(mSourceMultiInstanceManager, times(0)).moveTabToWindow(any(), any(), anyInt());
+        // Verify clear.
+        verify(mSourceStripLayoutHelper, times(1)).clearActiveClickedTab();
+        // Verify destination strip not invoked.
+        verifyNoInteractions(mDestStripLayoutHelper);
+    }
+
+    /** Test for {@link #ONDRAG_TEST_CASES} - Scenario B */
+    @Test
+    public void test_onDrag_dropInToolbarContainer_source() {
+        new DragEventInvoker()
+                // Drag our of strip but within toolbar container.
+                .dragLocationY(mSourceInstance, 3 * DRAG_MOVE_DISTANCE)
+                // Shadow visible when drag moves out of strip.
+                .verifyShadowVisibility(true)
+                .drop(mSourceInstance)
+                .end();
+
+        // Verify appropriate events are generated.
+        // Drag tab onto strip on drag enter.
+        verify(mSourceStripLayoutHelper, times(1))
+                .dragActiveClickedTabOntoStrip(anyLong(), anyFloat());
+        // Drag tab out of strip on drag exit from strip.
+        verify(mSourceStripLayoutHelper, times(1)).dragActiveClickedTabOutOfStrip(anyLong());
+        // Verify tab is not moved since drop is on source toolbar.
+        verify(mSourceMultiInstanceManager, times(0)).moveTabToNewWindow(mTabBeingDragged);
+        verify(mSourceMultiInstanceManager, times(0)).moveTabToWindow(any(), any(), anyInt());
+        // Verify tab cleared.
+        verify(mSourceStripLayoutHelper, times(1)).clearActiveClickedTab();
+        // Verify destination strip not invoked.
+        verifyNoInteractions(mDestStripLayoutHelper);
+    }
+
+    /** Test for {@link #ONDRAG_TEST_CASES} - Scenario C.1 */
+    @Test
+    public void test_onDrag_dropOutsideToolbarContainer() {
+        new DragEventInvoker().dragExit(mSourceInstance).verifyShadowVisibility(true).end();
+
+        // Verify appropriate events are generated.
+        // Drag tab onto strip on drag enter.
+        verify(mSourceStripLayoutHelper, times(1))
+                .dragActiveClickedTabOntoStrip(anyLong(), anyFloat());
+        // Drag tab out of strip on drag exit.
+        verify(mSourceStripLayoutHelper, times(1)).dragActiveClickedTabOutOfStrip(anyLong());
+        // Verify tab is not moved since drop is outside strip.
+        verify(mSourceMultiInstanceManager, times(0)).moveTabToNewWindow(mTabBeingDragged);
+        verify(mSourceMultiInstanceManager, times(0)).moveTabToWindow(any(), any(), anyInt());
+        // Verify tab cleared.
+        verify(mSourceStripLayoutHelper, times(1)).clearActiveClickedTab();
+        // Verify destination strip not invoked.
+        verifyNoInteractions(mDestStripLayoutHelper);
+    }
+
+    /** Test for {@link #ONDRAG_TEST_CASES} - Scenario C.2 */
     @DisableFeatures(ChromeFeatureList.TAB_LINK_DRAG_DROP_ANDROID)
     @EnableFeatures(ChromeFeatureList.TAB_DRAG_DROP_ANDROID)
-    public void test_OnDragEndAfterExit_NewWindowIsOpened() {
-        // Call startDrag to set class variables.
-        mTabDragSource.startTabDragAction(mTabsToolbarView, mTabBeingDragged, DRAG_START_POINT);
+    @Test
+    public void test_onDrag_dropOutsideToolbarContainer_dragAsWindow() {
+        new DragEventInvoker().dragExit(mSourceInstance).verifyShadowVisibility(true).end();
 
-        // Perform drag n drop simulation actions for movement outside the strip layout.
-        triggerDragEvent(DragEvent.ACTION_DRAG_STARTED, POS_X, mPosY);
-        triggerDragEvent(DragEvent.ACTION_DRAG_ENTERED, POS_X, mPosY);
-        triggerDragEvent(DragEvent.ACTION_DRAG_EXITED, DROP_X_SCREEN_POS, DROP_Y_SCREEN_POS);
-        triggerDragEvent(DragEvent.ACTION_DRAG_ENDED, DROP_X_SCREEN_POS, DROP_Y_SCREEN_POS);
-
-        // Verify Since the drop is outside the TabToolbar area verify new window opened
-        // TODO (crbug.com/1495815): check if intent is send to SysUI to position the window.
-        verify(mMultiInstanceManager).moveTabToNewWindow(mTabBeingDragged);
+        // Verify appropriate events are generated.
+        // Drag tab onto strip on drag enter.
+        verify(mSourceStripLayoutHelper, times(1))
+                .dragActiveClickedTabOntoStrip(anyLong(), anyFloat());
+        // Drag tab out of strip on drag exit.
+        verify(mSourceStripLayoutHelper, times(1)).dragActiveClickedTabOutOfStrip(anyLong());
+        // Verify Since the drop is outside the TabToolbar area the tab will be move to a new
+        // Chrome Window.
+        verify(mSourceMultiInstanceManager, times(1)).moveTabToNewWindow(mTabBeingDragged);
+        // Verify tab cleared.
+        verify(mSourceStripLayoutHelper, times(1)).clearActiveClickedTab();
+        // Verify destination strip not invoked.
+        verifyNoInteractions(mDestStripLayoutHelper);
     }
 
-    private void triggerDragEvent(int action, float x, float y) {
-        triggerDragEvent(action, x, y, TAB_ID);
+    /** Test for {@link #ONDRAG_TEST_CASES} - Scenario D.1 */
+    @Test
+    public void test_onDrag_dropInStrip_firstHalfTab_destination() {
+        mockStripTabPosition(TAB_WIDTH, POS_X - (TAB_WIDTH / 2), TAB_INDEX);
+
+        invokeDropInDestinationStrip();
+
+        // Verify - Tab moved to destination window at TAB_INDEX.
+        verify(mDestMultiInstanceManager, times(1))
+                .moveTabToWindow(any(), eq(mTabBeingDragged), eq(TAB_INDEX));
+        verify(mSourceMultiInstanceManager, atLeastOnce()).getCurrentInstanceId();
+        verifyNoMoreInteractions(mSourceMultiInstanceManager);
+        // Verify tab cleared.
+        verify(mSourceStripLayoutHelper, times(1)).clearActiveClickedTab();
+        // Verify destination strip calls.
+        verify(mDestStripLayoutHelper).getTabAtPosition(anyFloat());
+        verify(mDestStripLayoutHelper).findIndexForTab(anyInt());
     }
 
-    private void triggerDragEvent(int action, float x, float y, int tabId) {
+    /** Test for {@link #ONDRAG_TEST_CASES} - Scenario D.2 */
+    @Test
+    public void test_onDrag_dropInStrip_secondHalfTab_destination() {
+        mockStripTabPosition(TAB_WIDTH, POS_X - (TAB_WIDTH / 2 + 1), TAB_INDEX);
+
+        invokeDropInDestinationStrip();
+
+        // Verify - Tab moved to destination window at TAB_INDEX+1.
+        verify(mDestMultiInstanceManager, times(1))
+                .moveTabToWindow(any(), eq(mTabBeingDragged), eq(TAB_INDEX + 1));
+        verify(mSourceMultiInstanceManager, atLeastOnce()).getCurrentInstanceId();
+        verifyNoMoreInteractions(mSourceMultiInstanceManager);
+        // Verify tab cleared.
+        verify(mSourceStripLayoutHelper, times(1)).clearActiveClickedTab();
+        // Verify destination strip calls.
+        verify(mDestStripLayoutHelper).getTabAtPosition(anyFloat());
+        verify(mDestStripLayoutHelper).findIndexForTab(anyInt());
+    }
+
+    /** Test for {@link #ONDRAG_TEST_CASES} - Scenario D.3 */
+    @Test
+    public void test_onDrag_dropInStrip_nonTab_destination() {
+        // Mock strip actions.
+        when(mSourceStripLayoutHelper.getTabAtPosition(POS_X)).thenReturn(null);
+        int tabCount = 10;
+        when(mTabModel.getCount()).thenReturn(tabCount);
+
+        invokeDropInDestinationStrip();
+
+        // Verify - Tab moved to destination window at end.
+        verify(mDestMultiInstanceManager, times(1))
+                .moveTabToWindow(any(), eq(mTabBeingDragged), eq(tabCount));
+        verify(mSourceMultiInstanceManager, atLeastOnce()).getCurrentInstanceId();
+        verifyNoMoreInteractions(mSourceMultiInstanceManager);
+        // Verify tab cleared.
+        verify(mSourceStripLayoutHelper, times(1)).clearActiveClickedTab();
+        // Verify destination strip calls.
+        verify(mDestStripLayoutHelper).getTabAtPosition(anyFloat());
+        verifyNoMoreInteractions(mDestStripLayoutHelper);
+    }
+
+    /** Test for {@link #ONDRAG_TEST_CASES} - Scenario D.4 */
+    @Test
+    public void test_onDrag_dropInStrip_differentModel_Destination() {
+        // Destination tab model is incognito.
+        when(mTabModel.isIncognito()).thenReturn(true);
+        TabModel standardModelDestination = mock(TabModel.class);
+        when(mTabModelSelector.getModel(false)).thenReturn(standardModelDestination);
+        when(standardModelDestination.getCount()).thenReturn(5);
+
+        invokeDropInDestinationStrip();
+
+        // Verify - Tab moved to destination window at end.
+        verify(mDestMultiInstanceManager, times(1))
+                .moveTabToWindow(any(), eq(mTabBeingDragged), eq(5));
+        verify(mSourceMultiInstanceManager, atLeastOnce()).getCurrentInstanceId();
+        verifyNoMoreInteractions(mSourceMultiInstanceManager);
+    }
+
+    /** Test for {@link #ONDRAG_TEST_CASES} - Scenario D.5 */
+    @DisableFeatures(ChromeFeatureList.TAB_LINK_DRAG_DROP_ANDROID)
+    @EnableFeatures(ChromeFeatureList.TAB_DRAG_DROP_ANDROID)
+    @Test
+    public void test_onDrag_dropInStrip_withDragAsWindowFF_destination() {
+        mockStripTabPosition(TAB_WIDTH, POS_X - (TAB_WIDTH / 2), TAB_INDEX);
+
+        new DragEventInvoker()
+                .dragExit(mSourceInstance)
+                .verifyShadowVisibility(true)
+                .dragEnter(mDestInstance)
+                .verifyShadowVisibility(false)
+                .drop(mDestInstance)
+                .end();
+    }
+
+    /** Test for {@link #ONDRAG_TEST_CASES} - Scenario E */
+    @Test
+    public void test_onDrag_dropInToolbarContainer_destination() {
+        new DragEventInvoker()
+                .dragExit(mSourceInstance)
+                .verifyShadowVisibility(true)
+                .dragEnter(mDestInstance)
+                // Move to toolbar container outside of tab strip.
+                .dragLocationY(mDestInstance, 3 * DRAG_MOVE_DISTANCE)
+                .verifyShadowVisibility(true)
+                .drop(mDestInstance)
+                .end();
+
+        // Verify appropriate events are generated.
+        // Drag tab onto strip on drag enter.
+        verify(mSourceStripLayoutHelper, times(1))
+                .dragActiveClickedTabOntoStrip(anyLong(), anyFloat());
+        // Drag tab out of strip on drag exit from strip.
+        verify(mSourceStripLayoutHelper, times(1)).dragActiveClickedTabOutOfStrip(anyLong());
+        // Verify tab is not moved since drop is on source toolbar.
+        verify(mSourceMultiInstanceManager, times(0)).moveTabToNewWindow(mTabBeingDragged);
+        verify(mSourceMultiInstanceManager, times(0)).moveTabToWindow(any(), any(), anyInt());
+        // Verify tab cleared.
+        verify(mSourceStripLayoutHelper, times(1)).clearActiveClickedTab();
+        // Verify destination strip not invoked.
+        verifyNoInteractions(mDestStripLayoutHelper);
+    }
+
+    /** Test for {@link #ONDRAG_TEST_CASES} - Scenario F */
+    @Test
+    public void test_onDrag_exitIntoToolbarAndRenterStripAndDrop_source() {
+        new DragEventInvoker()
+                .dragLocationY(mSourceInstance, 3 * DRAG_MOVE_DISTANCE) // move to toolbar
+                .verifyShadowVisibility(true)
+                .dragLocationY(mSourceInstance, -3 * DRAG_MOVE_DISTANCE) // move back to strip
+                .verifyShadowVisibility(false)
+                .drop(mSourceInstance)
+                .end();
+
+        // Verify appropriate events are generated.
+        // Drag tab onto strip on drag enter. Entered twice.
+        verify(mSourceStripLayoutHelper, times(2))
+                .dragActiveClickedTabOntoStrip(anyLong(), anyFloat());
+        // Stop reorder on drop.
+        verify(mSourceStripLayoutHelper, times(1)).onUpOrCancel(anyLong());
+        // Verify tab is not moved.
+        verify(mSourceMultiInstanceManager, times(0)).moveTabToNewWindow(mTabBeingDragged);
+        verify(mSourceMultiInstanceManager, times(0)).moveTabToWindow(any(), any(), anyInt());
+        // Verify clear.
+        verify(mSourceStripLayoutHelper, times(1)).clearActiveClickedTab();
+        // Verify destination strip not invoked.
+        verifyNoInteractions(mDestStripLayoutHelper);
+    }
+
+    /** Test for {@link #ONDRAG_TEST_CASES} - Scenario G.1 */
+    @Test
+    public void test_onDrag_invalidMimeType() {
+        // Set state.
+        mSourceInstance.setGlobalState(mTabBeingDragged);
+
+        DragEvent event = mock(DragEvent.class);
+        when(event.getAction()).thenReturn(DragEvent.ACTION_DRAG_STARTED);
+        when(event.getX()).thenReturn(POS_X);
+        when(event.getY()).thenReturn(mPosY);
+        when(event.getClipDescription())
+                .thenReturn(new ClipDescription("", new String[] {"some_value"}));
+
+        assertFalse(mSourceInstance.onDrag(mTabsToolbarView, event));
+    }
+
+    /** Test for {@link #ONDRAG_TEST_CASES} - Scenario G.2 */
+    @Test
+    public void test_onDrag_invalidClipData() {
+        // Set state.
+        mSourceInstance.setGlobalState(mTabBeingDragged);
+
+        // Trigger drop with invalid tabId.
+        mSourceInstance.onDrag(
+                mTabsToolbarView, mockDragEvent(DragEvent.ACTION_DRAG_STARTED, POS_X, mPosY));
+        mSourceInstance.onDrag(
+                mTabsToolbarView,
+                mockDragEvent(DragEvent.ACTION_DROP, POS_X, mPosY, TAB_ID_NOT_DRAGGED));
+        mSourceInstance.onDrag(
+                mTabsToolbarView, mockDragEvent(DragEvent.ACTION_DRAG_ENDED, POS_X, mPosY));
+
+        // Verify - Move to new window not invoked.
+        verify(mSourceMultiInstanceManager, atLeastOnce()).getCurrentInstanceId();
+        verifyNoMoreInteractions(mSourceMultiInstanceManager);
+    }
+
+    private void invokeDropInDestinationStrip() {
+        new DragEventInvoker()
+                .dragExit(mSourceInstance)
+                .verifyShadowVisibility(true)
+                .dragEnter(mDestInstance)
+                .verifyShadowVisibility(true)
+                .drop(mDestInstance)
+                .end();
+    }
+
+    private void mockStripTabPosition(float tabWidth, float drawX, int tabIndex) {
+        StripLayoutTab stripTab = mock(StripLayoutTab.class);
+        when(stripTab.getWidth()).thenReturn(tabWidth);
+        when(stripTab.getDrawX()).thenReturn(drawX);
+        when(stripTab.getId()).thenReturn(10);
+        when(mDestStripLayoutHelper.findIndexForTab(10)).thenReturn(tabIndex);
+        when(mDestStripLayoutHelper.getTabAtPosition(POS_X)).thenReturn(stripTab);
+    }
+
+    class DragEventInvoker {
+        DragEventInvoker() {
+            // Start tab drag action.
+            mSourceInstance.startTabDragAction(
+                    mTabsToolbarView, mTabBeingDragged, new PointF(POS_X, mPosY));
+            // drag invokes DRAG_START and DRAG_ENTER on source and DRAG_START on destination.
+            mSourceInstance.onDrag(
+                    mTabsToolbarView, mockDragEvent(DragEvent.ACTION_DRAG_STARTED, POS_X, mPosY));
+            mDestInstance.onDrag(
+                    mTabsToolbarView, mockDragEvent(DragEvent.ACTION_DRAG_STARTED, POS_X, mPosY));
+
+            mSourceInstance.onDrag(
+                    mTabsToolbarView, mockDragEvent(DragEvent.ACTION_DRAG_ENTERED, POS_X, mPosY));
+            // Move within the tab strip area to set lastX / lastY.
+            mSourceInstance.onDrag(
+                    mTabsToolbarView,
+                    mockDragEvent(DragEvent.ACTION_DRAG_LOCATION, POS_X + 10, mPosY));
+            // Verify shadow is not visible.
+            verifyShadowVisibility(false);
+        }
+
+        public DragEventInvoker dragLocationY(TabDragSource instance, float distance) {
+            mPosY += distance;
+            instance.onDrag(
+                    mTabsToolbarView, mockDragEvent(DragEvent.ACTION_DRAG_LOCATION, POS_X, mPosY));
+            return this;
+        }
+
+        public DragEventInvoker dragExit(TabDragSource instance) {
+            instance.onDrag(mTabsToolbarView, mockDragEvent(DragEvent.ACTION_DRAG_EXITED, 0, 0));
+            return this;
+        }
+
+        public DragEventInvoker dragEnter(TabDragSource instance) {
+            mPosY = mTabStripHeight - 2 * DRAG_MOVE_DISTANCE;
+            instance.onDrag(
+                    mTabsToolbarView, mockDragEvent(DragEvent.ACTION_DRAG_ENTERED, POS_X, mPosY));
+            // Also trigger DRAG_LOCATION following DRAG_ENTERED since enter is no-op in
+            // implementation.
+            instance.onDrag(
+                    mTabsToolbarView, mockDragEvent(DragEvent.ACTION_DRAG_LOCATION, POS_X, mPosY));
+            return this;
+        }
+
+        public DragEventInvoker drop(TabDragSource instance) {
+            instance.onDrag(mTabsToolbarView, mockDragEvent(DragEvent.ACTION_DROP, POS_X, mPosY));
+            return this;
+        }
+
+        public DragEventInvoker end() {
+            mSourceInstance.onDrag(
+                    mTabsToolbarView, mockDragEvent(DragEvent.ACTION_DRAG_ENDED, 0, 0));
+            mDestInstance.onDrag(
+                    mTabsToolbarView, mockDragEvent(DragEvent.ACTION_DRAG_ENDED, 0, 0));
+            return this;
+        }
+
+        public DragEventInvoker verifyShadowVisibility(boolean visible) {
+            assertEquals(
+                    "Drag shadow visibility does not match.",
+                    visible,
+                    ((TabDragShadowBuilder) DragDropGlobalState.getInstance().dragShadowBuilder)
+                            .getShadowShownForTesting());
+            return this;
+        }
+    }
+
+    private DragEvent mockDragEvent(int action, float x, float y) {
+        return mockDragEvent(action, x, y, TAB_ID);
+    }
+
+    private DragEvent mockDragEvent(int action, float x, float y, int tabId) {
         DragEvent event = mock(DragEvent.class);
         when(event.getAction()).thenReturn(action);
         when(event.getX()).thenReturn(x);
@@ -522,6 +681,6 @@
                 .thenReturn(
                         new ClipData(null, SUPPORTED_MIME_TYPES, new Item("TabId=" + tabId, null)));
         when(event.getClipDescription()).thenReturn(new ClipDescription("", SUPPORTED_MIME_TYPES));
-        mTabDragSource.onDrag(mTabsToolbarView, event);
+        return event;
     }
 }
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index b076446..4afc11f 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -5006,6 +5006,16 @@
 #endif  // BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
 
 #if BUILDFLAG(IS_LINUX)
+    {"pulseaudio-loopback-for-cast",
+     flag_descriptions::kPulseaudioLoopbackForCastName,
+     flag_descriptions::kPulseaudioLoopbackForCastDescription, kOsLinux,
+     FEATURE_VALUE_TYPE(media::kPulseaudioLoopbackForCast)},
+
+    {"pulseaudio-loopback-for-screen-share",
+     flag_descriptions::kPulseaudioLoopbackForScreenShareName,
+     flag_descriptions::kPulseaudioLoopbackForScreenShareDescription, kOsLinux,
+     FEATURE_VALUE_TYPE(media::kPulseaudioLoopbackForScreenShare)},
+
     {"ozone-platform-hint", flag_descriptions::kOzonePlatformHintName,
      flag_descriptions::kOzonePlatformHintDescription, kOsLinux,
      MULTI_VALUE_TYPE(kOzonePlatformHintRuntimeChoices)},
@@ -6337,6 +6347,9 @@
      flag_descriptions::kHandwritingLegacyRecognitionName,
      flag_descriptions::kHandwritingLegacyRecognitionDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(ash::features::kHandwritingLegacyRecognition)},
+    {"handwriting-library-dlc", flag_descriptions::kHandwritingLibraryDlcName,
+     flag_descriptions::kHandwritingLibraryDlcDescription, kOsCrOS,
+     FEATURE_VALUE_TYPE(ash::features::kHandwritingLibraryDlc)},
     {"language-packs-in-settings",
      flag_descriptions::kLanguagePacksInSettingsName,
      flag_descriptions::kLanguagePacksInSettingsDescription, kOsCrOS,
diff --git a/chrome/browser/apps/app_service/app_icon/app_icon_factory.cc b/chrome/browser/apps/app_service/app_icon/app_icon_factory.cc
index 7dbf1453d..ca31815 100644
--- a/chrome/browser/apps/app_service/app_icon/app_icon_factory.cc
+++ b/chrome/browser/apps/app_service/app_icon/app_icon_factory.cc
@@ -320,8 +320,9 @@
 
 gfx::ImageSkia ApplyBackgroundAndMask(const gfx::ImageSkia& image) {
   TRACE_EVENT0("ui", "apps::ApplyBackgroundAndMask");
-  if (image.isNull())
+  if (image.isNull()) {
     return gfx::ImageSkia();
+  }
   return gfx::ImageSkiaOperations::CreateButtonBackground(
       SK_ColorWHITE, image, LoadMaskImage(GetScaleToSize(image)));
 }
diff --git a/chrome/browser/apps/app_service/app_icon/app_icon_loader.cc b/chrome/browser/apps/app_service/app_icon/app_icon_loader.cc
index 8f88605..0b78d7a4 100644
--- a/chrome/browser/apps/app_service/app_icon/app_icon_loader.cc
+++ b/chrome/browser/apps/app_service/app_icon/app_icon_loader.cc
@@ -392,8 +392,9 @@
                                      const std::optional<std::string>& app_id,
                                      IconValuePtr iv) {
   TRACE_EVENT0("ui", "AppIconLoader::ApplyIconEffects");
-  if (!iv || iv->uncompressed.isNull())
+  if (!iv || iv->uncompressed.isNull()) {
     return;
+  }
 
   if (!standard_icon_task_runner_) {
     standard_icon_task_runner_ = base::ThreadPool::CreateSequencedTaskRunner(
diff --git a/chrome/browser/apps/app_service/app_icon/app_icon_source.cc b/chrome/browser/apps/app_service/app_icon/app_icon_source.cc
index f942ab4..c878d06a 100644
--- a/chrome/browser/apps/app_service/app_icon/app_icon_source.cc
+++ b/chrome/browser/apps/app_service/app_icon/app_icon_source.cc
@@ -85,8 +85,9 @@
   // Check whether data is of correct type, load default image if not.
   std::string size_param = base::ToLowerASCII(path_parts[1]);
   size_t query_position = size_param.find("?");
-  if (query_position != std::string::npos)
+  if (query_position != std::string::npos) {
     size_param = size_param.substr(0, query_position);
+  }
   int size_in_dip = 0;
   if (!base::StringToInt(size_param, &size_in_dip) || size_in_dip < 1) {
     LoadDefaultImage(std::move(callback));
diff --git a/chrome/browser/apps/app_service/app_service_proxy_ash.cc b/chrome/browser/apps/app_service/app_service_proxy_ash.cc
index 49a0343..5335777 100644
--- a/chrome/browser/apps/app_service/app_service_proxy_ash.cc
+++ b/chrome/browser/apps/app_service/app_service_proxy_ash.cc
@@ -500,8 +500,9 @@
           files_controller->CheckIfLaunchAllowed(update, std::move(intent_copy),
                                                  std::move(launch_callback));
         });
-    if (!app_found)
+    if (!app_found) {
       std::move(launch_callback).Run(/*is_allowed=*/true);
+    }
   } else {
     std::move(launch_callback).Run(/*is_allowed=*/true);
   }
@@ -1203,8 +1204,9 @@
     InstanceRegistry().ForOneInstance(
         instance_id,
         [&exists](const apps::InstanceUpdate& update) { exists = true; });
-    if (!exists)
+    if (!exists) {
       return false;
+    }
   }
 
   return true;
diff --git a/chrome/browser/apps/app_service/app_service_proxy_base.cc b/chrome/browser/apps/app_service/app_service_proxy_base.cc
index 7a984b86..0517c70f 100644
--- a/chrome/browser/apps/app_service/app_service_proxy_base.cc
+++ b/chrome/browser/apps/app_service/app_service_proxy_base.cc
@@ -345,44 +345,43 @@
                                               WindowInfoPtr window_info,
                                               LaunchCallback callback) {
   CHECK(intent);
-  app_registry_cache_.ForOneApp(
-      app_id,
-      [this, event_flags, &intent, launch_source, &window_info,
-       callback = std::move(callback)](const AppUpdate& update) mutable {
-        auto* publisher = GetPublisher(update.AppType());
-        if (!publisher) {
-          std::unique_ptr<LaunchParams> params =
-              std::make_unique<LaunchParams>();
-          params->event_flags_ = event_flags;
-          params->intent_ = std::move(intent);
-          params->launch_source_ = launch_source;
-          params->window_info_ = std::move(window_info);
-          params->call_back_ = std::move(callback);
-          OnPublisherNotReadyForLaunch(update.AppId(), std::move(params));
-          return;
-        }
+  app_registry_cache_.ForOneApp(app_id, [this, event_flags, &intent,
+                                         launch_source, &window_info,
+                                         callback = std::move(callback)](
+                                            const AppUpdate& update) mutable {
+    auto* publisher = GetPublisher(update.AppType());
+    if (!publisher) {
+      std::unique_ptr<LaunchParams> params = std::make_unique<LaunchParams>();
+      params->event_flags_ = event_flags;
+      params->intent_ = std::move(intent);
+      params->launch_source_ = launch_source;
+      params->window_info_ = std::move(window_info);
+      params->call_back_ = std::move(callback);
+      OnPublisherNotReadyForLaunch(update.AppId(), std::move(params));
+      return;
+    }
 
-        if (MaybeShowLaunchPreventionDialog(update)) {
-          std::move(callback).Run(LaunchResult(State::FAILED));
-          return;
-        }
+    if (MaybeShowLaunchPreventionDialog(update)) {
+      std::move(callback).Run(LaunchResult(State::FAILED));
+      return;
+    }
 
-        // TODO(crbug/1117655): File manager records metrics for apps it
-        // launched. So we only record launches from other places. We should
-        // eventually move those metrics here, after AppService supports all
-        // app types launched by file manager.
-        if (launch_source != LaunchSource::kFromFileManager) {
-          RecordAppLaunch(update.AppId(), launch_source);
-        }
-        RecordAppPlatformMetrics(profile_, update, launch_source,
-                                 LaunchContainer::kLaunchContainerNone);
+    // TODO(crbug/1117655): File manager records metrics for apps it
+    // launched. So we only record launches from other places. We should
+    // eventually move those metrics here, after AppService supports all
+    // app types launched by file manager.
+    if (launch_source != LaunchSource::kFromFileManager) {
+      RecordAppLaunch(update.AppId(), launch_source);
+    }
+    RecordAppPlatformMetrics(profile_, update, launch_source,
+                             LaunchContainer::kLaunchContainerNone);
 
-        publisher->LaunchAppWithIntent(
-            update.AppId(), event_flags, std::move(intent), launch_source,
-            std::move(window_info), std::move(callback));
+    publisher->LaunchAppWithIntent(update.AppId(), event_flags,
+                                   std::move(intent), launch_source,
+                                   std::move(window_info), std::move(callback));
 
-        PerformPostLaunchTasks(launch_source);
-      });
+    PerformPostLaunchTasks(launch_source);
+  });
 }
 
 void AppServiceProxyBase::LaunchAppWithUrl(const std::string& app_id,
diff --git a/chrome/browser/apps/app_service/app_service_test.cc b/chrome/browser/apps/app_service/app_service_test.cc
index bae6728..8670c9d 100644
--- a/chrome/browser/apps/app_service/app_service_test.cc
+++ b/chrome/browser/apps/app_service/app_service_test.cc
@@ -45,8 +45,9 @@
 
 std::string AppServiceTest::GetAppName(const std::string& app_id) const {
   std::string name;
-  if (!app_service_proxy_)
+  if (!app_service_proxy_) {
     return name;
+  }
   app_service_proxy_->AppRegistryCache().ForOneApp(
       app_id, [&name](const AppUpdate& update) { name = update.Name(); });
   return name;
diff --git a/chrome/browser/apps/app_service/browser_app_instance_tracker.cc b/chrome/browser/apps/app_service/browser_app_instance_tracker.cc
index f8cb4c5..f171d19 100644
--- a/chrome/browser/apps/app_service/browser_app_instance_tracker.cc
+++ b/chrome/browser/apps/app_service/browser_app_instance_tracker.cc
@@ -61,8 +61,9 @@
 
 Browser* GetBrowserWithTabStripModel(TabStripModel* tab_strip_model) {
   for (auto* browser : *BrowserList::GetInstance()) {
-    if (browser->tab_strip_model() == tab_strip_model)
+    if (browser->tab_strip_model() == tab_strip_model) {
       return browser;
+    }
   }
   return nullptr;
 }
@@ -122,8 +123,9 @@
   auto* registry = extensions::ExtensionRegistry::Get(browser->profile());
   auto* extension = registry->GetInstalledExtension(app_id);
   // This is a web-app.
-  if (!extension)
+  if (!extension) {
     return app_id;
+  }
 
   if (extension->is_hosted_app() || extension->is_legacy_packaged_app()) {
     return app_id;
diff --git a/chrome/browser/apps/app_service/browser_app_instance_tracker_browsertest.cc b/chrome/browser/apps/app_service/browser_app_instance_tracker_browsertest.cc
index 60647206..cfc32d21 100644
--- a/chrome/browser/apps/app_service/browser_app_instance_tracker_browsertest.cc
+++ b/chrome/browser/apps/app_service/browser_app_instance_tracker_browsertest.cc
@@ -117,8 +117,7 @@
 bool operator==(const TestInstance& e1, const TestInstance& e2) {
   return e1.name == e2.name && e1.id == e2.id && e1.type == e2.type &&
          e1.app_id == e2.app_id && e1.window == e2.window &&
-         e1.title == e2.title &&
-         e1.is_browser_active == e2.is_browser_active &&
+         e1.title == e2.title && e1.is_browser_active == e2.is_browser_active &&
          e1.is_web_contents_active == e2.is_web_contents_active;
 }
 
diff --git a/chrome/browser/apps/app_service/extension_apps_utils.cc b/chrome/browser/apps/app_service/extension_apps_utils.cc
index 1656654..fa00a77c 100644
--- a/chrome/browser/apps/app_service/extension_apps_utils.cc
+++ b/chrome/browser/apps/app_service/extension_apps_utils.cc
@@ -29,8 +29,9 @@
 
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
 bool ShouldHostedAppsRunInLacros() {
-  if (g_enable_hosted_apps_in_lacros_for_testing)
+  if (g_enable_hosted_apps_in_lacros_for_testing) {
     return true;
+  }
 
   return chromeos::BrowserParamsProxy::Get()->PublishHostedApps();
 }
diff --git a/chrome/browser/apps/app_service/intent_util.h b/chrome/browser/apps/app_service/intent_util.h
index 93d60eb..f8322dd 100644
--- a/chrome/browser/apps/app_service/intent_util.h
+++ b/chrome/browser/apps/app_service/intent_util.h
@@ -25,7 +25,7 @@
 namespace arc {
 class ArcIntentHelperBridge;
 class IntentFilter;
-}
+}  // namespace arc
 #endif
 
 class Profile;
diff --git a/chrome/browser/apps/app_service/launch_result_type.cc b/chrome/browser/apps/app_service/launch_result_type.cc
index 2a2b788..d3c4f06 100644
--- a/chrome/browser/apps/app_service/launch_result_type.cc
+++ b/chrome/browser/apps/app_service/launch_result_type.cc
@@ -50,8 +50,9 @@
     crosapi::mojom::LaunchResultPtr mojom_launch_result) {
   auto launch_result = LaunchResult();
   if (mojom_launch_result->instance_ids) {
-    for (auto token : *mojom_launch_result->instance_ids)
+    for (auto token : *mojom_launch_result->instance_ids) {
       launch_result.instance_ids.push_back(std::move(token));
+    }
   } else {
     launch_result.instance_ids.push_back(
         std::move(mojom_launch_result->instance_id));
diff --git a/chrome/browser/apps/app_service/launch_utils.cc b/chrome/browser/apps/app_service/launch_utils.cc
index f1acfa4c..33fb123 100644
--- a/chrome/browser/apps/app_service/launch_utils.cc
+++ b/chrome/browser/apps/app_service/launch_utils.cc
@@ -170,12 +170,14 @@
 #else
     GURL url(arg);
 #endif
-    if (url.is_valid() && !url.SchemeIsFile())
+    if (url.is_valid() && !url.SchemeIsFile()) {
       continue;
+    }
 
     base::FilePath path(arg);
-    if (path.empty())
+    if (path.empty()) {
       continue;
+    }
 
     launch_files.push_back(path);
   }
diff --git a/chrome/browser/apps/app_service/media_access_browsertest.cc b/chrome/browser/apps/app_service/media_access_browsertest.cc
index 290861b8..f6d6a8e 100644
--- a/chrome/browser/apps/app_service/media_access_browsertest.cc
+++ b/chrome/browser/apps/app_service/media_access_browsertest.cc
@@ -638,10 +638,8 @@
 class MediaAccessBrowserShortcutsTest : public MediaAccessWebAppsTest {
  public:
   std::string CreateShortcut(const GURL& url) const {
-    auto web_app_info = std::make_unique<web_app::WebAppInstallInfo>();
-    web_app_info->start_url = url;
-    return web_app::test::InstallWebApp(browser()->profile(),
-                                        std::move(web_app_info));
+    return web_app::test::InstallShortcut(browser()->profile(), "Shortcut Name",
+                                          url);
   }
 
  private:
diff --git a/chrome/browser/apps/app_service/menu_util.cc b/chrome/browser/apps/app_service/menu_util.cc
index efd3774..c9a002b 100644
--- a/chrome/browser/apps/app_service/menu_util.cc
+++ b/chrome/browser/apps/app_service/menu_util.cc
@@ -151,8 +151,9 @@
                                        int* launch_new_string_id) {
   DCHECK_EQ(menu_item->command_id, ash::LAUNCH_NEW);
 
-  if (launch_new_string_id)
+  if (launch_new_string_id) {
     *launch_new_string_id = menu_item->string_id;
+  }
 
   switch (menu_item->type) {
     case apps::MenuItemType::kCommand: {
@@ -210,10 +211,12 @@
 }
 
 MenuType MenuTypeFromString(base::StringPiece menu_type) {
-  if (base::EqualsCaseInsensitiveASCII(menu_type, "shelf"))
+  if (base::EqualsCaseInsensitiveASCII(menu_type, "shelf")) {
     return MenuType::kShelf;
-  if (base::EqualsCaseInsensitiveASCII(menu_type, "applist"))
+  }
+  if (base::EqualsCaseInsensitiveASCII(menu_type, "applist")) {
     return MenuType::kAppList;
+  }
   return MenuType::kShelf;
 }
 
diff --git a/chrome/browser/apps/app_service/notifications_browsertest.cc b/chrome/browser/apps/app_service/notifications_browsertest.cc
index b7264eb2..5985978 100644
--- a/chrome/browser/apps/app_service/notifications_browsertest.cc
+++ b/chrome/browser/apps/app_service/notifications_browsertest.cc
@@ -174,8 +174,9 @@
 
     std::set<std::string> notifications =
         GetDisplayHelper()->GetNotificationIdsForExtension(extension->url());
-    if (notifications.size() != 1)
+    if (notifications.size() != 1) {
       return nullptr;
+    }
 
     return GetDisplayHelper()->GetByNotificationId(*notifications.begin());
   }
@@ -856,8 +857,9 @@
   }
 
   void StopInstance() {
-    if (app_instance_)
+    if (app_instance_) {
       arc_bridge_service()->app()->CloseInstance(app_instance_.get());
+    }
     arc_session_manager()->Shutdown();
   }
 
diff --git a/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc b/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc
index 383ac05..8817f26 100644
--- a/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc
+++ b/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc
@@ -783,8 +783,9 @@
   // In the App Service world, there should be a unique app publisher for any
   // given app. In this case, the ArcApps publisher publishes the Play Store
   // app, and the ExtensionApps publisher does not.
-  if (app_id == arc::kPlayStoreAppId)
+  if (app_id == arc::kPlayStoreAppId) {
     return true;
+  }
 
   // If lacros chrome apps is enabled, a small list of extension apps or
   // extensions on ash extension keeplist is allowed to run in both ash and
diff --git a/chrome/browser/apps/app_service/publishers/guest_os_apps.cc b/chrome/browser/apps/app_service/publishers/guest_os_apps.cc
index 9d26d46..dbb59db 100644
--- a/chrome/browser/apps/app_service/publishers/guest_os_apps.cc
+++ b/chrome/browser/apps/app_service/publishers/guest_os_apps.cc
@@ -233,7 +233,7 @@
   // them with a single "text/*" mime type.
   if (base::Contains(mime_types, "text/plain")) {
     base::EraseIf(mime_types, [](const std::string& s) {
-        return base::StartsWith(s, "text/");
+      return base::StartsWith(s, "text/");
     });
     mime_types.push_back("text/*");
   }
diff --git a/chrome/browser/apps/app_service/publishers/standalone_browser_apps.cc b/chrome/browser/apps/app_service/publishers/standalone_browser_apps.cc
index 901fc9a4..b5c78985 100644
--- a/chrome/browser/apps/app_service/publishers/standalone_browser_apps.cc
+++ b/chrome/browser/apps/app_service/publishers/standalone_browser_apps.cc
@@ -92,8 +92,9 @@
       InstallSource::kSystem);
   app->short_name = short_name;
 
-  if (crosapi::browser_util::IsAshWebBrowserEnabled())
+  if (crosapi::browser_util::IsAshWebBrowserEnabled()) {
     app->additional_search_terms.push_back("chrome");
+  }
 
   app->icon_key = std::move(*CreateIconKey(/*is_browser_load_success=*/true));
   app->searchable = true;
@@ -110,8 +111,9 @@
 void StandaloneBrowserApps::Initialize() {
   auto* browser_manager = crosapi::BrowserManager::Get();
   // |browser_manager| may be null in tests. For tests, assume Lacros is ready.
-  if (browser_manager && !observation_.IsObserving())
+  if (browser_manager && !observation_.IsObserving()) {
     observation_.Observe(browser_manager);
+  }
 
   RegisterPublisher(AppType::kStandaloneBrowser);
 
@@ -148,8 +150,9 @@
 void StandaloneBrowserApps::OpenNativeSettings(const std::string& app_id) {
   auto* browser_manager = crosapi::BrowserManager::Get();
   // `browser_manager` may be null in tests.
-  if (!browser_manager)
+  if (!browser_manager) {
     return;
+  }
   browser_manager->SwitchToTab(
       chrome::GetSettingsUrl(chrome::kContentSettingsSubPage),
       /*path_behavior=*/NavigateParams::RESPECT);
diff --git a/chrome/browser/apps/app_service/publishers/standalone_browser_extension_apps.cc b/chrome/browser/apps/app_service/publishers/standalone_browser_extension_apps.cc
index d3564ac..fc49ce31 100644
--- a/chrome/browser/apps/app_service/publishers/standalone_browser_extension_apps.cc
+++ b/chrome/browser/apps/app_service/publishers/standalone_browser_extension_apps.cc
@@ -36,8 +36,9 @@
 // Returns true if app's launch info should be saved to full restore.
 bool ShouldSaveToFullRestore(AppServiceProxy* proxy,
                              const std::string& app_id) {
-  if (!::full_restore::features::IsFullRestoreForLacrosEnabled())
+  if (!::full_restore::features::IsFullRestoreForLacrosEnabled()) {
     return false;
+  }
 
   bool is_platform_app = true;
   proxy->AppRegistryCache().ForOneApp(
@@ -99,8 +100,9 @@
                                             WindowInfoPtr window_info) {
   // It is possible that Lacros is briefly unavailable, for example if it shuts
   // down for an update.
-  if (!controller_.is_bound())
+  if (!controller_.is_bound()) {
     return;
+  }
 
   // The following code assumes |app_type_| must be
   // AppType::kStandaloneBrowserChromeApp. Therefore, the app must be either
@@ -130,8 +132,9 @@
     std::vector<base::FilePath> file_paths) {
   // It is possible that Lacros is briefly unavailable, for example if it shuts
   // down for an update.
-  if (!controller_.is_bound())
+  if (!controller_.is_bound()) {
     return;
+  }
 
   std::vector<base::FilePath> file_paths_for_restore = file_paths;
   auto launch_params = crosapi::mojom::LaunchParams::New();
@@ -213,8 +216,9 @@
                                                bool report_abuse) {
   // It is possible that Lacros is briefly unavailable, for example if it shuts
   // down for an update.
-  if (!controller_.is_bound())
+  if (!controller_.is_bound()) {
     return;
+  }
 
   controller_->Uninstall(app_id, uninstall_source, clear_site_data,
                          report_abuse);
@@ -271,8 +275,9 @@
                                                    WindowMode window_mode) {
   // It is possible that Lacros is briefly unavailable, for example if it shuts
   // down for an update.
-  if (!controller_.is_bound())
+  if (!controller_.is_bound()) {
     return;
+  }
 
   controller_->SetWindowMode(app_id, window_mode);
 }
@@ -280,8 +285,9 @@
 void StandaloneBrowserExtensionApps::StopApp(const std::string& app_id) {
   // It is possible that Lacros is briefly unavailable, for example if it shuts
   // down for an update.
-  if (!controller_.is_bound())
+  if (!controller_.is_bound()) {
     return;
+  }
 
   controller_->StopApp(app_id);
 }
@@ -300,8 +306,9 @@
     const std::string& app_id) {
   // It is possible that Lacros is briefly unavailable, for example if it shuts
   // down for an update.
-  if (!controller_.is_bound())
+  if (!controller_.is_bound()) {
     return;
+  }
 
   controller_->OpenNativeSettings(app_id);
 }
diff --git a/chrome/browser/apps/app_service/publishers/web_apps_crosapi.cc b/chrome/browser/apps/app_service/publishers/web_apps_crosapi.cc
index d018f55..f76ed52 100644
--- a/chrome/browser/apps/app_service/publishers/web_apps_crosapi.cc
+++ b/chrome/browser/apps/app_service/publishers/web_apps_crosapi.cc
@@ -310,8 +310,9 @@
 }
 
 void WebAppsCrosapi::OnApps(std::vector<AppPtr> deltas) {
-  if (!web_app::IsWebAppsCrosapiEnabled())
+  if (!web_app::IsWebAppsCrosapiEnabled()) {
     return;
+  }
 
   on_initial_apps_received_ = true;
 
diff --git a/chrome/browser/apps/app_service/publishers/web_apps_crosapi_factory.cc b/chrome/browser/apps/app_service/publishers/web_apps_crosapi_factory.cc
index 01538920..75f1d9f 100644
--- a/chrome/browser/apps/app_service/publishers/web_apps_crosapi_factory.cc
+++ b/chrome/browser/apps/app_service/publishers/web_apps_crosapi_factory.cc
@@ -44,9 +44,8 @@
 std::unique_ptr<KeyedService>
 WebAppsCrosapiFactory::BuildServiceInstanceForBrowserContext(
     content::BrowserContext* context) const {
-  return std::make_unique<WebAppsCrosapi>(
-      AppServiceProxyFactory::GetForProfile(
-          Profile::FromBrowserContext(context)));
+  return std::make_unique<WebAppsCrosapi>(AppServiceProxyFactory::GetForProfile(
+      Profile::FromBrowserContext(context)));
 }
 
 }  // namespace apps
diff --git a/chrome/browser/apps/app_service/publishers/web_apps_crosapi_factory.h b/chrome/browser/apps/app_service/publishers/web_apps_crosapi_factory.h
index 6de86b23..edc5782a 100644
--- a/chrome/browser/apps/app_service/publishers/web_apps_crosapi_factory.h
+++ b/chrome/browser/apps/app_service/publishers/web_apps_crosapi_factory.h
@@ -34,7 +34,7 @@
 
   // BrowserContextKeyedServiceFactory overrides.
   std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext(
-    content::BrowserContext* context) const override;
+      content::BrowserContext* context) const override;
 };
 
 }  // namespace apps
diff --git a/chrome/browser/apps/app_service/uninstall_dialog.cc b/chrome/browser/apps/app_service/uninstall_dialog.cc
index dec6832..ffe9a56 100644
--- a/chrome/browser/apps/app_service/uninstall_dialog.cc
+++ b/chrome/browser/apps/app_service/uninstall_dialog.cc
@@ -28,8 +28,9 @@
       app_name_(app_name),
       parent_window_(parent_window),
       uninstall_callback_(std::move(uninstall_callback)) {
-  if (parent_window)
+  if (parent_window) {
     parent_window_tracker_ = views::NativeWindowTracker::Create(parent_window);
+  }
 }
 
 UninstallDialog::~UninstallDialog() = default;
diff --git a/chrome/browser/apps/app_service/web_contents_app_id_utils.cc b/chrome/browser/apps/app_service/web_contents_app_id_utils.cc
index 1559762..32e8f85 100644
--- a/chrome/browser/apps/app_service/web_contents_app_id_utils.cc
+++ b/chrome/browser/apps/app_service/web_contents_app_id_utils.cc
@@ -125,8 +125,9 @@
 std::string GetAppIdForWebContents(content::WebContents* web_contents) {
   const webapps::AppId* app_id =
       web_app::WebAppTabHelper::GetAppId(web_contents);
-  if (app_id)
+  if (app_id) {
     return *app_id;
+  }
 
   extensions::TabHelper* extensions_tab_helper =
       extensions::TabHelper::FromWebContents(web_contents);
diff --git a/chrome/browser/apps/app_service/webapk/webapk_prefs.cc b/chrome/browser/apps/app_service/webapk/webapk_prefs.cc
index c8e66782..cbc3610 100644
--- a/chrome/browser/apps/app_service/webapk/webapk_prefs.cc
+++ b/chrome/browser/apps/app_service/webapk/webapk_prefs.cc
@@ -121,8 +121,9 @@
   ScopedDictPrefUpdate generated_webapks(profile->GetPrefs(),
                                          kGeneratedWebApksPref);
   base::Value::Dict* app_dict = generated_webapks->FindDict(app_id);
-  if (app_dict)
+  if (app_dict) {
     app_dict->Set(kUpdateNeededKey, update_needed);
+  }
 }
 
 base::flat_set<std::string> GetUpdateNeededAppIds(Profile* profile) {
diff --git a/chrome/browser/ash/app_list/app_service/app_service_shortcut_item_browsertest.cc b/chrome/browser/ash/app_list/app_service/app_service_shortcut_item_browsertest.cc
index d31596d..5cf1b66c 100644
--- a/chrome/browser/ash/app_list/app_service/app_service_shortcut_item_browsertest.cc
+++ b/chrome/browser/ash/app_list/app_service/app_service_shortcut_item_browsertest.cc
@@ -91,15 +91,9 @@
       const GURL& shortcut_url,
       const std::u16string& shortcut_name,
       bool is_policy_install = false) {
-    // Create web app based shortcut.
-    auto web_app_info = std::make_unique<web_app::WebAppInstallInfo>();
-    web_app_info->start_url = shortcut_url;
-    web_app_info->title = shortcut_name;
-    auto local_shortcut_id = web_app::test::InstallWebApp(
-        profile(), std::move(web_app_info),
-        /*overwrite_existing_manifest_fields=*/true,
-        is_policy_install ? webapps::WebappInstallSource::EXTERNAL_POLICY
-                          : webapps::WebappInstallSource::OMNIBOX_INSTALL_ICON);
+    webapps::AppId local_shortcut_id = web_app::test::InstallShortcut(
+        profile(), base::UTF16ToUTF8(shortcut_name), shortcut_url,
+        /*create_default_icon =*/true, is_policy_install);
     return apps::GenerateShortcutId(app_constants::kChromeAppId,
                                     local_shortcut_id);
   }
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_download_observer.cc b/chrome/browser/chromeos/policy/dlp/dlp_download_observer.cc
index 2e7153b..f63831a 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_download_observer.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_download_observer.cc
@@ -23,12 +23,14 @@
 GURL GeneralizeURL(const GURL& url, const download::DownloadItem& item) {
   // data: urls cannot be matched against dlp rules. We use the embedding tab
   // url as source.
+  GURL generalized_url = url;
   if (url.SchemeIs(url::kDataScheme)) {
-    return item.GetTabUrl();
-  } else if (url.SchemeIs(url::kBlobScheme)) {
-    return url::Origin::Create(url).GetURL();
+    generalized_url = item.GetTabUrl();
   }
-  return url;
+  if (generalized_url.SchemeIs(url::kBlobScheme)) {
+    return url::Origin::Create(generalized_url).GetURL();
+  }
+  return generalized_url;
 }
 
 }  // namespace
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_download_observer_unittest.cc b/chrome/browser/chromeos/policy/dlp/dlp_download_observer_unittest.cc
index 0ad3eb0..26dbf3d1 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_download_observer_unittest.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_download_observer_unittest.cc
@@ -150,4 +150,41 @@
   observer.OnDownloadUpdated(&item);
 }
 
+// Test if we request the file access for a data: url, while the tab is a blob:
+// url, the origin of the tab is used as source.
+TEST_F(DlpDownloadObserverTest, TestDataSchemeInBlobTabRewrite) {
+  base::MockRepeatingCallback<void(const dlp::AddFilesRequest,
+                                   chromeos::DlpClient::AddFilesCallback)>
+      add_files_cb;
+  EXPECT_CALL(
+      add_files_cb,
+      Run(testing::Property(&dlp::AddFilesRequest::add_file_requests,
+                            testing::ElementsAre(testing::Property(
+                                &dlp::AddFileRequest::source_url, kOriginUrl))),
+          _))
+      .WillOnce(base::test::RunOnceCallback<1>(
+          dlp::AddFilesResponse::default_instance()));
+  auto* dlp_client = chromeos::DlpClient::Get()->GetTestInterface();
+  dlp_client->SetAddFilesMock(add_files_cb.Get());
+
+  auto key = SimpleFactoryKey(base::FilePath(), false);
+  DlpDownloadObserver observer(&key);
+  testing::NiceMock<download::MockDownloadItem> item;
+  base::FilePath file_path(kFilePath);
+  GURL blob_url(kBlobUrl);
+  GURL referrer_url(kReferrerUrl);
+  GURL data_url(kDataUrl);
+
+  ON_CALL(item, IsSavePackageDownload).WillByDefault(testing::Return(false));
+  ON_CALL(item, GetState)
+      .WillByDefault(
+          testing::Return(download::DownloadItem::DownloadState::COMPLETE));
+  ON_CALL(item, GetFullPath).WillByDefault(testing::ReturnRef(file_path));
+  ON_CALL(item, GetURL).WillByDefault(testing::ReturnRef(data_url));
+  ON_CALL(item, GetReferrerUrl).WillByDefault(testing::ReturnRef(referrer_url));
+  ON_CALL(item, GetTabUrl).WillByDefault(testing::ReturnRef(blob_url));
+
+  observer.OnDownloadUpdated(&item);
+}
+
 }  // namespace policy
diff --git a/chrome/browser/download/download_file_picker.cc b/chrome/browser/download/download_file_picker.cc
index 2a6e8ef..f5bb7570 100644
--- a/chrome/browser/download/download_file_picker.cc
+++ b/chrome/browser/download/download_file_picker.cc
@@ -91,8 +91,17 @@
   }
 #endif
 
-  const GURL caller = download::BaseFile::GetEffectiveAuthorityURL(
+  GURL caller = download::BaseFile::GetEffectiveAuthorityURL(
       download_item_->GetURL(), download_item_->GetReferrerUrl());
+  // Blob URLs are not set as referrer of downloads of them. If the download url
+  // itself has no authority part, their is no authority url. For dlp we want to
+  // use the blob's origin in that case.
+  auto* render_frame_host =
+      content::DownloadItemUtils::GetRenderFrameHost(download_item_);
+  if (!caller.is_valid() && render_frame_host &&
+      render_frame_host->GetLastCommittedURL().SchemeIsBlob()) {
+    caller = render_frame_host->GetLastCommittedOrigin().GetURL();
+  }
 
   select_file_dialog_->SelectFile(
       ui::SelectFileDialog::SELECT_SAVEAS_FILE, std::u16string(),
diff --git a/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc b/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc
index e46a227..8ea70a5 100644
--- a/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc
+++ b/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc
@@ -527,11 +527,9 @@
   features.Append(GenerateFeatureFlag(
       "autocorrectparamstuning",
       base::FeatureList::IsEnabled(ash::features::kAutocorrectParamsTuning)));
-
-  // TODO(b/316429185): Remove "handwritinglibrarydlc" when no longer referenced
-  // in CrOS virtual keyboard's internal code base.
-  features.Append(GenerateFeatureFlag("handwritinglibrarydlc", true));
-
+  features.Append(GenerateFeatureFlag(
+      "handwritinglibrarydlc",
+      base::FeatureList::IsEnabled(ash::features::kHandwritingLibraryDlc)));
   features.Append(
       GenerateFeatureFlag("jelly", chromeos::features::IsJellyEnabled()));
   features.Append(GenerateFeatureFlag(
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index 7a0c7c0..97e4010 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -4540,6 +4540,11 @@
     "expiry_milestone": 118
   },
   {
+    "name": "handwriting-library-dlc",
+    "owners": [ "shend@google.com", "essential-inputs-team@google.com" ],
+    "expiry_milestone": 118
+  },
+  {
     "name": "happiness-tracking-surveys-for-desktop-demo",
     "owners": [ "//chrome/browser/ui/hats/OWNERS" ],
     // A debugging and demo flag to allow UI/dev/testing team to always show the UI
@@ -6651,6 +6656,16 @@
     "expiry_milestone": 99
   },
   {
+    "name": "pulseaudio-loopback-for-cast",
+    "owners": [ "mfoltz@chromium.org", "olka@chromium.org", "takumif@chromium.org"],
+    "expiry_milestone": 133
+  },
+  {
+    "name": "pulseaudio-loopback-for-screen-share",
+    "owners": [ "mfoltz@chromium.org", "olka@chromium.org", "eladalon@chromium.org"],
+    "expiry_milestone": 133
+  },
+  {
     "name": "pwa-restore-ui",
     "owners": [ "finnur@chromium.org", "beverloo@chromium.org" ],
     "expiry_milestone": 140
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index b4f7532..886096e 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -1949,6 +1949,12 @@
 const char kHandwritingLegacyRecognitionDescription[] =
     "Enables new on-device recognition for handwriting legacy paths.";
 
+const char kHandwritingLibraryDlcName[] =
+    "Handwriting recognition with library from DLC";
+const char kHandwritingLibraryDlcDescription[] =
+    "Enables new on-device recognition with the handwriting library installed "
+    "from DLC";
+
 const char kHardwareMediaKeyHandling[] = "Hardware Media Key Handling";
 const char kHardwareMediaKeyHandlingDescription[] =
     "Enables using media keys to control the active media session. This "
@@ -7448,12 +7454,31 @@
 #endif  // defined(ARCH_CPU_ARM_FAMILY)
 #endif  // BUILDFLAG(IS_CHROMEOS) && BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION)
 
-#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
-const char kZeroCopyVideoCaptureName[] = "Enable Zero-Copy Video Capture";
-const char kZeroCopyVideoCaptureDescription[] =
-    "Camera produces a gpu friendly buffer on capture and, if there is, "
-    "hardware accelerated video encoder consumes the buffer";
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
+// Linux -----------------------------------------------------------------------
+
+#if BUILDFLAG(IS_LINUX)
+const char kOzonePlatformHintChoiceDefault[] = "Default";
+const char kOzonePlatformHintChoiceAuto[] = "Auto";
+const char kOzonePlatformHintChoiceX11[] = "X11";
+const char kOzonePlatformHintChoiceWayland[] = "Wayland";
+
+const char kOzonePlatformHintName[] = "Preferred Ozone platform";
+const char kOzonePlatformHintDescription[] =
+    "Selects the preferred platform backend used on Linux. The default one is "
+    "\"X11\". \"Auto\" selects Wayland if possible, X11 otherwise. ";
+
+const char kPulseaudioLoopbackForCastName[] =
+    "Linux System Audio Loopback for Cast (pulseaudio)";
+const char kPulseaudioLoopbackForCastDescription[] =
+    "Enable system audio mirroring when casting a screen on Linux with "
+    "pulseaudio.";
+
+const char kPulseaudioLoopbackForScreenShareName[] =
+    "Linux System Audio Loopback for Screen Sharing (pulseaudio)";
+const char kPulseaudioLoopbackForScreenShareDescription[] =
+    "Enable system audio sharing when screen sharing on Linux with pulseaudio.";
+
+#endif  // BUILDFLAG(IS_LINUX)
 
 // All views-based platforms --------------------------------------------------
 
@@ -7471,6 +7496,13 @@
 
 // Random platform combinations -----------------------------------------------
 
+#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
+const char kZeroCopyVideoCaptureName[] = "Enable Zero-Copy Video Capture";
+const char kZeroCopyVideoCaptureDescription[] =
+    "Camera produces a gpu friendly buffer on capture and, if there is, "
+    "hardware accelerated video encoder consumes the buffer";
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
+
 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \
     BUILDFLAG(IS_FUCHSIA)
 const char kQuickCommandsName[] = "Quick Commands";
@@ -7520,18 +7552,6 @@
     "platforms.";
 #endif  // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC)
 
-#if BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS)
-const char kOzonePlatformHintChoiceDefault[] = "Default";
-const char kOzonePlatformHintChoiceAuto[] = "Auto";
-const char kOzonePlatformHintChoiceX11[] = "X11";
-const char kOzonePlatformHintChoiceWayland[] = "Wayland";
-
-const char kOzonePlatformHintName[] = "Preferred Ozone platform";
-const char kOzonePlatformHintDescription[] =
-    "Selects the preferred platform backend used on Linux. The default one is "
-    "\"X11\". \"Auto\" selects Wayland if possible, X11 otherwise. ";
-#endif  // BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS)
-
 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX)
 const char kWebBluetoothConfirmPairingSupportName[] =
     "Web Bluetooth confirm pairing support";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 65b8bcb..b247d3cf 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -1092,6 +1092,9 @@
 extern const char kHandwritingLegacyRecognitionName[];
 extern const char kHandwritingLegacyRecognitionDescription[];
 
+extern const char kHandwritingLibraryDlcName[];
+extern const char kHandwritingLibraryDlcDescription[];
+
 extern const char kHardwareMediaKeyHandling[];
 extern const char kHardwareMediaKeyHandlingDescription[];
 
@@ -4281,10 +4284,22 @@
 #endif  // defined(ARCH_CPU_ARM_FAMILY
 #endif  // BUILDFLAG(IS_CHROMEOS) && BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION)
 
-#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
-extern const char kZeroCopyVideoCaptureName[];
-extern const char kZeroCopyVideoCaptureDescription[];
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
+// Linux ---------------------------------------------------------------------
+
+#if BUILDFLAG(IS_LINUX)
+extern const char kOzonePlatformHintChoiceDefault[];
+extern const char kOzonePlatformHintChoiceAuto[];
+extern const char kOzonePlatformHintChoiceX11[];
+extern const char kOzonePlatformHintChoiceWayland[];
+
+extern const char kOzonePlatformHintName[];
+extern const char kOzonePlatformHintDescription[];
+
+extern const char kPulseaudioLoopbackForCastName[];
+extern const char kPulseaudioLoopbackForCastDescription[];
+extern const char kPulseaudioLoopbackForScreenShareName[];
+extern const char kPulseaudioLoopbackForScreenShareDescription[];
+#endif  // BUILDFLAG(IS_LINUX)
 
 // All views-based platforms --------------------------------------------------
 
@@ -4298,6 +4313,11 @@
 
 // Random platform combinations -----------------------------------------------
 
+#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
+extern const char kZeroCopyVideoCaptureName[];
+extern const char kZeroCopyVideoCaptureDescription[];
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
+
 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \
     BUILDFLAG(IS_FUCHSIA)
 extern const char kQuickCommandsName[];
@@ -4316,16 +4336,6 @@
 extern const char kWebBluetoothConfirmPairingSupportDescription[];
 #endif  // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX)
 
-#if BUILDFLAG(IS_LINUX)
-extern const char kOzonePlatformHintChoiceDefault[];
-extern const char kOzonePlatformHintChoiceAuto[];
-extern const char kOzonePlatformHintChoiceX11[];
-extern const char kOzonePlatformHintChoiceWayland[];
-
-extern const char kOzonePlatformHintName[];
-extern const char kOzonePlatformHintDescription[];
-#endif  // BUILDFLAG(IS_LINUX)
-
 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC)
 extern const char kSkipUndecryptablePasswordsName[];
 extern const char kSkipUndecryptablePasswordsDescription[];
diff --git a/chrome/browser/media/webrtc/desktop_media_picker_controller.cc b/chrome/browser/media/webrtc/desktop_media_picker_controller.cc
index eb6236d6..8c689a96 100644
--- a/chrome/browser/media/webrtc/desktop_media_picker_controller.cc
+++ b/chrome/browser/media/webrtc/desktop_media_picker_controller.cc
@@ -30,6 +30,7 @@
 #include "desktop_media_picker.h"
 #include "extensions/common/manifest.h"
 #include "extensions/common/switches.h"
+#include "media/audio/audio_features.h"
 #include "media/base/media_switches.h"
 #include "ui/base/l10n/l10n_util.h"
 
@@ -85,18 +86,27 @@
 
 // static
 bool DesktopMediaPickerController::IsSystemAudioCaptureSupported(
-    Params::RequestSource request_sourcce) {
+    Params::RequestSource request_source) {
 #if BUILDFLAG(IS_WIN) || defined(USE_CRAS)
   return true;
 #elif BUILDFLAG(IS_MAC)
   // Only supported on macOS 13.0+.
   if (base::mac::MacOSVersion() < 13'00'00) {
     return false;
-  } else if (request_sourcce == Params::RequestSource::kCast) {
+  } else if (request_source == Params::RequestSource::kCast) {
     return base::FeatureList::IsEnabled(media::kMacLoopbackAudioForCast);
   } else {
     return base::FeatureList::IsEnabled(media::kMacLoopbackAudioForScreenShare);
   }
+#elif BUILDFLAG(IS_LINUX)
+  if (!media::IsPulseaudioLoopbackCaptureSupported()) {
+    return false;
+  } else if (request_source == Params::RequestSource::kCast) {
+    return base::FeatureList::IsEnabled(media::kPulseaudioLoopbackForCast);
+  } else {
+    return base::FeatureList::IsEnabled(
+        media::kPulseaudioLoopbackForScreenShare);
+  }
 #else
   return false;
 #endif  // BUILDFLAG(IS_WIN) || defined(USE_CRAS)
diff --git a/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc b/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc
index f3192587..baefdba 100644
--- a/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc
+++ b/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc
@@ -905,8 +905,8 @@
 };
 
 // (https://crbug.com/1385713): Flaky on mac12-arm64-rel M1 Mac CQ.
-// (https://crbug.com/1405307): Flaky on ChromeOS as well.
-#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_CHROMEOS)
+// (https://crbug.com/1405307): Flaky on ChromeOS and Linux as well.
+#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
 #define MAYBE_DataURIType_Video DISABLED_DataURIType_Video
 #else
 #define MAYBE_DataURIType_Video DataURIType_Video
diff --git a/chrome/browser/resources/chromeos/accessibility/BUILD.gn b/chrome/browser/resources/chromeos/accessibility/BUILD.gn
index 0390035..e8e5611 100644
--- a/chrome/browser/resources/chromeos/accessibility/BUILD.gn
+++ b/chrome/browser/resources/chromeos/accessibility/BUILD.gn
@@ -7,16 +7,12 @@
 import("//chrome/browser/resources/accessibility/tools/manifest.gni")
 import("//chrome/common/features.gni")
 import("//chrome/test/base/ash/js2gtest.gni")
-import("//tools/typescript/ts_library.gni")
 import("strings/accessibility_strings.gni")
 import("tools/run_jsbundler.gni")
 
 assert(is_chromeos_ash)
 
 accessibility_out_dir = "$root_out_dir/resources/chromeos/accessibility/"
-tsc_out_dir = "$target_gen_dir/tsc"
-
-loader_files = [ "switch_access_loader.ts" ]
 
 group("build") {
   deps = [
@@ -48,30 +44,10 @@
   }
 }
 
-ts_library("ts_build") {
-  out_dir = tsc_out_dir
-  definitions = [
-    "definitions/automation.d.ts",
-    "definitions/command_line_private.d.ts",
-    "definitions/extension_types.d.ts",
-    "definitions/extensions.d.ts",
-    "definitions/runtime.d.ts",
-    "definitions/tabs.d.ts",
-    "//tools/typescript/definitions/windows.d.ts",
-  ]
-
-  in_files = loader_files
-  tsconfig_base = "tsconfig.base.json"
-}
-
 run_jsbundler("copied_loader_files") {
   mode = "copy"
-  deps = [ ":ts_build" ]
   dest_dir = accessibility_out_dir
-  sources = []
-  foreach(_ts_file, loader_files) {
-    sources += [ "$tsc_out_dir/" + get_path_info(_ts_file, "name") + ".js" ]
-  }
+  sources = [ "switch_access_loader.js" ]
   rewrite_rules = [ rebase_path(".", root_build_dir) + ":" ]
 }
 
diff --git a/chrome/browser/resources/chromeos/accessibility/switch_access/BUILD.gn b/chrome/browser/resources/chromeos/accessibility/switch_access/BUILD.gn
index 980933c..3ae1a7f 100644
--- a/chrome/browser/resources/chromeos/accessibility/switch_access/BUILD.gn
+++ b/chrome/browser/resources/chromeos/accessibility/switch_access/BUILD.gn
@@ -18,7 +18,7 @@
 tsc_out_dir = "$target_gen_dir/tsc"
 
 # TS files to compile.
-ts_modules = [ "switch_access_constants.ts" ]
+ts_modules = []
 
 # JS files needed to compile TS.
 js_deps = []
@@ -27,6 +27,7 @@
 ts_library("ts_build") {
   root_dir = "../"
   out_dir = tsc_out_dir
+  deps = [ "../common:ts_build" ]
   definitions = []
 
   in_files = []
@@ -107,6 +108,7 @@
     "point_scan_manager.js",
     "settings_manager.js",
     "switch_access.js",
+    "switch_access_constants.js",
     "switch_access_predicate.js",
     "text_navigation_manager.js",
   ]
diff --git a/chrome/browser/resources/chromeos/accessibility/switch_access/switch_access_constants.js b/chrome/browser/resources/chromeos/accessibility/switch_access/switch_access_constants.js
new file mode 100644
index 0000000..52e1bbc
--- /dev/null
+++ b/chrome/browser/resources/chromeos/accessibility/switch_access/switch_access_constants.js
@@ -0,0 +1,69 @@
+// Copyright 2019 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview Constants used in Switch Access.
+ */
+const AutomationNode = chrome.automation.AutomationNode;
+
+/**
+ * When an action is performed, how the menu should respond.
+ * @enum {number}
+ */
+export const ActionResponse = {
+  NO_ACTION_TAKEN: -1,
+  REMAIN_OPEN: 0,
+  CLOSE_MENU: 1,
+  EXIT_SUBMENU: 2,
+  RELOAD_MENU: 3,
+  OPEN_TEXT_NAVIGATION_MENU: 4,
+};
+
+/**
+ * The types of error or unexpected state that can be encountered by Switch
+ * Access.
+ * These values are persisted to logs and should not be renumbered or re-used.
+ * See tools/metrics/histograms/enums.xml.
+ * @enum {number}
+ */
+export const ErrorType = {
+  UNKNOWN: 0,
+  PREFERENCE_TYPE: 1,
+  UNTRANSLATED_STRING: 2,
+  INVALID_COLOR: 3,
+  NEXT_UNDEFINED: 4,
+  PREVIOUS_UNDEFINED: 5,
+  NULL_CHILD: 6,
+  NO_CHILDREN: 7,
+  MALFORMED_DESKTOP: 8,
+  MISSING_LOCATION: 9,
+  MISSING_KEYBOARD: 10,
+  ROW_TOO_SHORT: 11,
+  MISSING_BASE_NODE: 12,
+  NEXT_INVALID: 13,
+  PREVIOUS_INVALID: 14,
+  INVALID_SELECTION_BOUNDS: 15,
+  UNINITIALIZED: 16,
+  DUPLICATE_INITIALIZATION: 17,
+};
+
+/**
+ * The different types of menus and sub-menus that can be shown.
+ * @enum {number}
+ */
+export const MenuType = {
+  MAIN_MENU: 0,
+  TEXT_NAVIGATION: 1,
+  POINT_SCAN_MENU: 2,
+};
+
+/**
+ * The modes of interaction the user can select for how to interact with the
+ * device.
+ * @enum {number}
+ */
+export const Mode = {
+  ITEM_SCAN: 0,
+  POINT_SCAN: 1,
+};
diff --git a/chrome/browser/resources/chromeos/accessibility/switch_access/switch_access_constants.ts b/chrome/browser/resources/chromeos/accessibility/switch_access/switch_access_constants.ts
deleted file mode 100644
index 63d40317..0000000
--- a/chrome/browser/resources/chromeos/accessibility/switch_access/switch_access_constants.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2019 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/** When an action is performed, how the menu should respond. */
-export enum ActionResponse {
-  NO_ACTION_TAKEN = -1,
-  REMAIN_OPEN = 0,
-  CLOSE_MENU = 1,
-  EXIT_SUBMENU = 2,
-  RELOAD_MENU = 3,
-  OPEN_TEXT_NAVIGATION_MENU = 4,
-}
-
-/**
- * The types of error or unexpected state that can be encountered by Switch
- * Access.
- * These values are persisted to logs and should not be renumbered or re-used.
- * See tools/metrics/histograms/enums.xml.
- */
-export enum ErrorType {
-  UNKNOWN = 0,
-  PREFERENCE_TYPE = 1,
-  UNTRANSLATED_STRING = 2,
-  INVALID_COLOR = 3,
-  NEXT_UNDEFINED = 4,
-  PREVIOUS_UNDEFINED = 5,
-  NULL_CHILD = 6,
-  NO_CHILDREN = 7,
-  MALFORMED_DESKTOP = 8,
-  MISSING_LOCATION = 9,
-  MISSING_KEYBOARD = 10,
-  ROW_TOO_SHORT = 11,
-  MISSING_BASE_NODE = 12,
-  NEXT_INVALID = 13,
-  PREVIOUS_INVALID = 14,
-  INVALID_SELECTION_BOUNDS = 15,
-  UNINITIALIZED = 16,
-  DUPLICATE_INITIALIZATION = 17,
-}
-
-/** The different types of menus and sub-menus that can be shown. */
-export enum MenuType {
-  MAIN_MENU = 0,
-  TEXT_NAVIGATION = 1,
-  POINT_SCAN_MENU = 2,
-}
-
-/**
- * The modes of interaction the user can select for how to interact with the
- * device.
- */
-export enum Mode {
-  ITEM_SCAN = 0,
-  POINT_SCAN = 1,
-}
diff --git a/chrome/browser/resources/chromeos/accessibility/switch_access_loader.ts b/chrome/browser/resources/chromeos/accessibility/switch_access_loader.js
similarity index 95%
rename from chrome/browser/resources/chromeos/accessibility/switch_access_loader.ts
rename to chrome/browser/resources/chromeos/accessibility/switch_access_loader.js
index 7d92f7a2..ecfcc956 100644
--- a/chrome/browser/resources/chromeos/accessibility/switch_access_loader.ts
+++ b/chrome/browser/resources/chromeos/accessibility/switch_access_loader.js
@@ -14,7 +14,7 @@
 
 InstanceChecker.closeExtraInstances();
 
-async function initAll(): Promise<void> {
+async function initAll() {
   await Flags.init();
   const desktop = await AsyncUtil.getDesktop();
   await SwitchAccess.init(desktop);
diff --git a/chrome/browser/sync/test/integration/ash_trusted_vault_keys_sharing_sync_test.cc b/chrome/browser/sync/test/integration/ash_trusted_vault_keys_sharing_sync_test.cc
index f1bd1ab9..22f95f3 100644
--- a/chrome/browser/sync/test/integration/ash_trusted_vault_keys_sharing_sync_test.cc
+++ b/chrome/browser/sync/test/integration/ash_trusted_vault_keys_sharing_sync_test.cc
@@ -233,8 +233,10 @@
   EXPECT_THAT(FetchKeysThroughCrosapi(), ElementsAre(kTestTrustedVaultKey));
 }
 
-IN_PROC_BROWSER_TEST_F(AshTrustedVaultKeysSharingSyncTest,
-                       ShouldAcceptKeysFromTheWebAndFetchThemThroughCrosapi) {
+// TODO(https://crbug.com/1513038): Flaky on bots.
+IN_PROC_BROWSER_TEST_F(
+    AshTrustedVaultKeysSharingSyncTest,
+    DISABLED_ShouldAcceptKeysFromTheWebAndFetchThemThroughCrosapi) {
   // Mimic the account being already using a trusted vault passphrase.
   SetNigoriInFakeServer(
       syncer::BuildTrustedVaultNigoriSpecifics({kTestTrustedVaultKey}),
diff --git a/chrome/browser/sync/test/integration/wallet_helper.cc b/chrome/browser/sync/test/integration/wallet_helper.cc
index 2aae4e14..9800c4f 100644
--- a/chrome/browser/sync/test/integration/wallet_helper.cc
+++ b/chrome/browser/sync/test/integration/wallet_helper.cc
@@ -18,6 +18,7 @@
 #include "components/autofill/core/browser/data_model/autofill_metadata.h"
 #include "components/autofill/core/browser/payments/payments_customer_data.h"
 #include "components/autofill/core/browser/personal_data_manager.h"
+#include "components/autofill/core/browser/webdata/autofill_sync_metadata_table.h"
 #include "components/autofill/core/browser/webdata/autofill_table.h"
 #include "components/keyed_service/core/service_access_type.h"
 #include "components/sync/model/metadata_batch.h"
@@ -173,7 +174,7 @@
                                    sync_pb::ModelTypeState* model_type_state) {
   DCHECK(wds->GetDBTaskRunner()->RunsTasksInCurrentSequence());
   syncer::MetadataBatch metadata_batch;
-  AutofillTable::FromWebDatabase(wds->GetDatabase())
+  autofill::AutofillSyncMetadataTable::FromWebDatabase(wds->GetDatabase())
       ->GetAllSyncMetadata(model_type, &metadata_batch);
   *model_type_state = metadata_batch.GetModelTypeState();
 }
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarCoordinator.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarCoordinator.java
index 7c5c5b7..30f69ea 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarCoordinator.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarCoordinator.java
@@ -8,6 +8,7 @@
 import android.animation.ObjectAnimator;
 import android.content.Context;
 import android.content.res.Configuration;
+import android.graphics.Typeface;
 import android.view.ActionMode;
 import android.view.View;
 
@@ -814,25 +815,26 @@
     }
 
     /**
-     * @see LocationBarMediator#updateUrlBarHintTextColor(boolean)
+     * @see LocationBarMediator#setUrlBarHintTextColor(boolean)
      */
-    public void updateUrlBarHintTextColor(boolean useDefaultUrlBarHintTextColor) {
-        mLocationBarMediator.updateUrlBarHintTextColor(useDefaultUrlBarHintTextColor);
+    public void setUrlBarHintTextColor(boolean isStartOrNtp) {
+        mLocationBarMediator.setUrlBarHintTextColor(isStartOrNtp);
     }
 
     /**
-     * @see LocationBarMediator#updateUrlBarTypeface(boolean)
+     * @see LocationBarMediator#setUrlBarTypeface(Typeface)
      */
-    public void updateUrlBarTypeface(boolean useDefaultUrlBarTypeface) {
-        mLocationBarMediator.updateUrlBarTypeface(useDefaultUrlBarTypeface);
+    public void setUrlBarTypeface(Typeface typeface) {
+        mLocationBarMediator.setUrlBarTypeface(typeface);
     }
 
     /**
-     * @see LocationBarMediator#updateUrlActionContainerEndMargin(boolean)
+     * Updates the value for the end margin of the url action container in the search box.
+     *
+     * @param endMargin The end margin for the url action container in the search box.
      */
-    public void updateUrlActionContainerEndMargin(boolean useDefaultUrlActionContainerEndMargin) {
-        mLocationBarMediator.updateUrlActionContainerEndMargin(
-                useDefaultUrlActionContainerEndMargin);
+    public void updateUrlActionContainerEndMargin(int endMargin) {
+        mLocationBarMediator.updateUrlActionContainerEndMargin(endMargin);
     }
 
     public int getUrlActionContainerEndMarginForTesting() {
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java
index 9dd5f41..4b36079 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java
@@ -559,7 +559,7 @@
         boolean isInSingleUrlBarMode =
                 isNtpOnPhone
                         && mSearchEngineUtils != null
-                        && mSearchEngineUtils.doesDefaultSearchEngineHaveLogo();
+                        && mSearchEngineUtils.isDefaultSearchEngineGoogle();
         if (mIsSurfacePolishEnabled && isInSingleUrlBarMode) {
             translationX +=
                     (getResources().getDimensionPixelSize(R.dimen.fake_search_box_start_padding)
@@ -602,18 +602,10 @@
     /**
      * Updates the value for the end margin of the url action container in the search box.
      *
-     * @param useDefaultUrlActionContainerEndMargin Whether to use the default end margin for the
-     *     url action container in the search box. If not we will use the specific end margin value
-     *     for surface polish.
+     * @param endMargin The end margin for the url action container in the search box.
      */
-    public void updateUrlActionContainerEndMargin(boolean useDefaultUrlActionContainerEndMargin) {
-        mUrlActionContainerEndMargin =
-                useDefaultUrlActionContainerEndMargin
-                        ? getResources()
-                                .getDimensionPixelSize(R.dimen.location_bar_url_action_offset)
-                        : getResources()
-                                .getDimensionPixelSize(
-                                        R.dimen.location_bar_url_action_offset_polish);
+    public void updateUrlActionContainerEndMargin(int endMargin) {
+        mUrlActionContainerEndMargin = endMargin;
     }
 
     int getUrlActionContainerEndMarginForTesting() {
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediator.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediator.java
index d6330f3..74ea094 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediator.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediator.java
@@ -13,6 +13,7 @@
 import android.content.res.ColorStateList;
 import android.content.res.Configuration;
 import android.graphics.Rect;
+import android.graphics.Typeface;
 import android.text.TextUtils;
 import android.util.FloatProperty;
 import android.view.KeyEvent;
@@ -1594,38 +1595,34 @@
     }
 
     /**
-     * Updates the color of the hint text in the search box.
+     * Sets the search box hint text color, depending on whether or not the the current page is
+     * Start Surface or NTP.
      *
-     * @param useDefaultUrlBarHintTextColor Whether to use the default color for the search text in
-     *     the search box. If not we will use specific color for surface polish.
+     * @param isStartOrNtp Whether the current page is Start Surface or NTP. If true, then a
+     *     colorful theme may be applied.
      */
-    public void updateUrlBarHintTextColor(boolean useDefaultUrlBarHintTextColor) {
-        if (useDefaultUrlBarHintTextColor) {
-            mUrlCoordinator.setUrlBarHintTextColorForDefault(mBrandedColorScheme);
-        } else {
+    public void setUrlBarHintTextColor(boolean isStartOrNtp) {
+        if (isStartOrNtp) {
             mUrlCoordinator.setUrlBarHintTextColorForSurfacePolish(
                     mIsSurfacePolishOmniboxColorEnabled);
+        } else {
+            mUrlCoordinator.setUrlBarHintTextColorForDefault(mBrandedColorScheme);
         }
     }
 
     /**
-     * Updates the typeface and style of the search text in the search box.
+     * Sets the typeface and style of the search text in the search box.
      *
-     * @param useDefaultUrlBarTypeface Whether to use the default typeface for the search text in
-     *     the search box. If not we will use medium Google sans typeface for surface polish.
+     * @param typeface The typeface for the search text in the search box.
      */
-    public void updateUrlBarTypeface(boolean useDefaultUrlBarTypeface) {
-        mUrlCoordinator.updateUrlBarTypeface(useDefaultUrlBarTypeface);
+    public void setUrlBarTypeface(Typeface typeface) {
+        mUrlCoordinator.setUrlBarTypeface(typeface);
     }
 
     /**
-     * Updates the value for the end margin of the url action container in the search box.
-     *
-     * @param useDefaultUrlActionContainerEndMargin Whether to use the default end margin for the
-     *     url action container in the search box. If not we will use the specific end margin value
-     *     for surface polish.
+     * @see LocationBarCoordinator#updateUrlActionContainerEndMargin(int)
      */
-    public void updateUrlActionContainerEndMargin(boolean useDefaultUrlActionContainerEndMargin) {
-        mLocationBarLayout.updateUrlActionContainerEndMargin(useDefaultUrlActionContainerEndMargin);
+    public void updateUrlActionContainerEndMargin(int endMargin) {
+        mLocationBarLayout.updateUrlActionContainerEndMargin(endMargin);
     }
 }
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/SearchEngineUtils.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/SearchEngineUtils.java
index f2cdb08..1f6e25d9 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/SearchEngineUtils.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/SearchEngineUtils.java
@@ -43,7 +43,7 @@
     private final @NonNull FaviconHelper mFaviconHelper;
     private final int mSearchEngineLogoTargetSizePixels;
     private Boolean mNeedToCheckForSearchEnginePromo;
-    private boolean mDoesDefaultSearchEngineHaveLogo;
+    private boolean mDefaultSearchEngineIsGoogle;
     private @Nullable StatusIconResource mSearchEngineLogo;
 
     /**
@@ -105,9 +105,9 @@
 
     @Override
     public void onTemplateURLServiceChanged() {
-        mDoesDefaultSearchEngineHaveLogo = mTemplateUrlService.doesDefaultSearchEngineHaveLogo();
+        mDefaultSearchEngineIsGoogle = mTemplateUrlService.isDefaultSearchEngineGoogle();
 
-        if (mTemplateUrlService.isDefaultSearchEngineGoogle()) {
+        if (mDefaultSearchEngineIsGoogle) {
             mSearchEngineLogo = new StatusIconResource(R.drawable.ic_logo_googleg_20dp, 0);
         } else {
             mSearchEngineLogo = null;
@@ -227,9 +227,9 @@
     }
 
     /*
-     * Returns whether the current search provider has Logo.
+     * Returns whether the current search provider is Google.
      */
-    boolean doesDefaultSearchEngineHaveLogo() {
-        return mDoesDefaultSearchEngineHaveLogo;
+    boolean isDefaultSearchEngineGoogle() {
+        return mDefaultSearchEngineIsGoogle;
     }
 }
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/UrlBarCoordinator.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/UrlBarCoordinator.java
index a48477b..90fcee3 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/UrlBarCoordinator.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/UrlBarCoordinator.java
@@ -5,6 +5,7 @@
 package org.chromium.chrome.browser.omnibox;
 
 import android.content.Context;
+import android.graphics.Typeface;
 import android.view.ActionMode;
 import android.view.inputmethod.InputMethodManager;
 
@@ -328,9 +329,9 @@
     }
 
     /**
-     * @see UrlBarMediator#updateUrlBarTypeface(boolean)
+     * @see UrlBarMediator#setUrlBarTypeface(Typeface)
      */
-    public void updateUrlBarTypeface(boolean useDefaultUrlBarTypeface) {
-        mMediator.updateUrlBarTypeface(useDefaultUrlBarTypeface);
+    public void setUrlBarTypeface(Typeface typeface) {
+        mMediator.setUrlBarTypeface(typeface);
     }
 }
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/UrlBarMediator.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/UrlBarMediator.java
index b22285b..2b794f1 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/UrlBarMediator.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/UrlBarMediator.java
@@ -400,17 +400,11 @@
     }
 
     /**
-     * Updates the typeface and style of the search text in the search box.
+     * Sets the typeface and style of the search text in the search box.
      *
-     * @param useDefaultUrlBarTypeface Whether to use the default typeface for the search text in
-     *     the search box. If not we will use medium Google sans typeface for surface polish.
+     * @param typeface The typeface for the search text in the search box.
      */
-    void updateUrlBarTypeface(boolean useDefaultUrlBarTypeface) {
-        // TODO(crbug.com/1487760): Use TextAppearance style instead.
-        Typeface typeface =
-                useDefaultUrlBarTypeface
-                        ? Typeface.defaultFromStyle(Typeface.NORMAL)
-                        : Typeface.create("google-sans-medium", Typeface.NORMAL);
+    void setUrlBarTypeface(Typeface typeface) {
         mModel.set(UrlBarProperties.TYPEFACE, typeface);
     }
 }
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java
index 91531f1..64ab84eb 100644
--- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java
+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java
@@ -17,6 +17,7 @@
 import android.graphics.Color;
 import android.graphics.Point;
 import android.graphics.Rect;
+import android.graphics.Typeface;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.GradientDrawable;
@@ -2138,7 +2139,7 @@
                     updateToNtpBackground();
                 }
             } else {
-                // Update the location bar background when entering the focus state or other
+                // Update the location bar background when entering the search results page or other
                 // non-NTP tabs from the Start Surface.
                 mActiveLocationBarBackground = mLocationBarBackground;
             }
@@ -2681,15 +2682,15 @@
 
     /**
      * Update the appearance (logo background, search text's color and style) of the location bar
-     * based on the state of the current page. For Start Surface and NTP, while not on the focus
-     * state, the real search box's search text has a particular color and style. The style would be
-     * "google-sans-medium" and the color would be colorOnSurface or colorOnPrimaryContainer based
-     * on whether the variant SURFACE_POLISH_OMNIBOX_COLOR is enabled or not. When being in light
-     * mode, there is also a round white background for the G logo. For other situations such as
-     * browser tabs, and search result pages, the real search box will stay the same.
-     *
+     * based on the state of the current page.
+     * For Start Surface and NTP, while not on the search results page, the real search box's search
+     * text has a particular color and style. The style would be "google-sans-medium" and the color
+     * would be colorOnSurface or colorOnPrimaryContainer based on whether the variant
+     * SURFACE_POLISH_OMNIBOX_COLOR is enabled or not. When being in light mode, there is also a
+     * round white background for the G logo. For other situations such as browser tabs, and search
+     * result pages, the real search box will stay the same.
      * @param visualState The Visual State of the current page.
-     * @param hasFocus True if the current page is the focus state.
+     * @param hasFocus True if the current page is search results page.
      */
     @VisibleForTesting
     void updateLocationBarForSurfacePolish(@VisualState int visualState, boolean hasFocus) {
@@ -2699,54 +2700,42 @@
 
         // Detect whether state has changed and update only when that happens.
         boolean prevIsStartOrNtpWithSurfacePolish = mIsStartOrNtpWithSurfacePolish;
-
-        // Check whether the current page is NTP (the focus state is not included) and the
+        // Check whether the current page is NTP (the search results page is not included) and the
         // real omnibox is pinned on the top of the screen. We need to make sure the real omnibox is
         // visible here to forbid the situation that the background of the G logo shows and then
-        // vanishes during the un-focus animation(from focus state to NTP). This situation
+        // vanishes during the un-focus animation(from search results page to NTP). This situation
         // won't happen in Start Surface, so we don't need to check the scroll fraction for Start
         // Surface.
         boolean isNtpShowingWithRealOmnibox =
                 visualState == VisualState.NEW_TAB_NORMAL && mNtpSearchBoxScrollFraction > 0;
         mIsStartOrNtpWithSurfacePolish =
                 (isNtpShowingWithRealOmnibox || mIsShowingStartSurfaceHomepage) && !hasFocus;
-
         if (mIsStartOrNtpWithSurfacePolish == prevIsStartOrNtpWithSurfacePolish) {
             return;
         }
 
+        // TODO(crbug.com/1487760): Use TextAppearance style instead.
+        Typeface typeface;
+        int urlActionContainerEndMargin;
         if (mIsStartOrNtpWithSurfacePolish) {
-            updateLocationBarForSurfacePolishImpl(
-                    !ColorUtils.inNightMode(getContext()),
-                    /* useDefaultUrlBarAndUrlActionContainerAppearance= */ false);
+            boolean isNightMode = ColorUtils.inNightMode(getContext());
+            mLocationBar.setStatusIconBackgroundVisibility(!isNightMode);
+            typeface = Typeface.create("google-sans-medium", Typeface.NORMAL);
+            urlActionContainerEndMargin =
+                    getResources()
+                            .getDimensionPixelOffset(R.dimen.location_bar_url_action_offset_polish);
         } else {
             // Restore the appearance of the real search box when transitioning from Start Surface
-            // or NTP to other pages.
-            updateLocationBarForSurfacePolishImpl(
-                    /* statusIconBackgroundVisibility= */ false,
-                    /* useDefaultUrlBarAndUrlActionContainerAppearance= */ true);
+            // or NTP to the search results page.
+            mLocationBar.setStatusIconBackgroundVisibility(false);
+            typeface = Typeface.defaultFromStyle(Typeface.NORMAL);
+            urlActionContainerEndMargin =
+                    getResources().getDimensionPixelOffset(R.dimen.location_bar_url_action_offset);
         }
-    }
-
-    /**
-     * Update the appearance (logo background, search text's color and style) of the location bar
-     * based on the value provided.
-     *
-     * @param statusIconBackgroundVisibility The visibility of the status icon background.
-     * @param useDefaultUrlBarAndUrlActionContainerAppearance Whether to use the default typeface
-     *     and color for the search text in the search box and use the default end margin for the
-     *     url action container in the search box. If not we will use specific settings for surface
-     *     polish.
-     */
-    private void updateLocationBarForSurfacePolishImpl(
-            boolean statusIconBackgroundVisibility,
-            boolean useDefaultUrlBarAndUrlActionContainerAppearance) {
-        mLocationBar.setStatusIconBackgroundVisibility(statusIconBackgroundVisibility);
-        mLocationBar.updateUrlBarTypeface(useDefaultUrlBarAndUrlActionContainerAppearance);
-        mLocationBar.updateUrlBarHintTextColor(useDefaultUrlBarAndUrlActionContainerAppearance);
-        mLocationBar.updateUrlActionContainerEndMargin(
-                useDefaultUrlBarAndUrlActionContainerAppearance);
+        mLocationBar.setUrlBarTypeface(typeface);
+        mLocationBar.setUrlBarHintTextColor(mIsStartOrNtpWithSurfacePolish);
         mLocationBar.updateButtonTints();
+        mLocationBar.updateUrlActionContainerEndMargin(urlActionContainerEndMargin);
     }
 
     private void updateVisualsForLocationBarState() {
diff --git a/chrome/browser/ui/ash/capture_mode/recording_service_browsertest.cc b/chrome/browser/ui/ash/capture_mode/recording_service_browsertest.cc
index cbb668687..b5586865 100644
--- a/chrome/browser/ui/ash/capture_mode/recording_service_browsertest.cc
+++ b/chrome/browser/ui/ash/capture_mode/recording_service_browsertest.cc
@@ -216,7 +216,13 @@
   std::unique_ptr<ui::test::EventGenerator> event_generator_;
 };
 
-IN_PROC_BROWSER_TEST_F(RecordingServiceBrowserTest, RecordFullscreen) {
+// TODO(b/252343017): Flaky on MSAN bots.
+#if defined(MEMORY_SANITIZER)
+#define MAYBE_RecordFullscreen DISABLED_RecordFullscreen
+#else
+#define MAYBE_RecordFullscreen RecordFullscreen
+#endif
+IN_PROC_BROWSER_TEST_F(RecordingServiceBrowserTest, MAYBE_RecordFullscreen) {
   ash::CaptureModeTestApi test_api;
   test_api.StartForFullscreen(/*for_video=*/true);
   FinishVideoRecordingTest(&test_api);
diff --git a/chrome/browser/ui/ash/shelf/app_service/app_service_shortcut_shelf_item_controller_browsertest.cc b/chrome/browser/ui/ash/shelf/app_service/app_service_shortcut_shelf_item_controller_browsertest.cc
index ad96105..8761e234 100644
--- a/chrome/browser/ui/ash/shelf/app_service/app_service_shortcut_shelf_item_controller_browsertest.cc
+++ b/chrome/browser/ui/ash/shelf/app_service/app_service_shortcut_shelf_item_controller_browsertest.cc
@@ -46,15 +46,9 @@
       const GURL& shortcut_url,
       const std::u16string& shortcut_name,
       bool is_policy_install = false) {
-    // Create web app based shortcut.
-    auto web_app_info = std::make_unique<web_app::WebAppInstallInfo>();
-    web_app_info->start_url = shortcut_url;
-    web_app_info->title = shortcut_name;
-    auto local_shortcut_id = web_app::test::InstallWebApp(
-        browser()->profile(), std::move(web_app_info),
-        /*overwrite_existing_manifest_fields=*/true,
-        is_policy_install ? webapps::WebappInstallSource::EXTERNAL_POLICY
-                          : webapps::WebappInstallSource::OMNIBOX_INSTALL_ICON);
+    webapps::AppId local_shortcut_id = web_app::test::InstallShortcut(
+        browser()->profile(), base::UTF16ToUTF8(shortcut_name), shortcut_url,
+        /*create_default_icon =*/true, is_policy_install);
     return apps::GenerateShortcutId(app_constants::kChromeAppId,
                                     local_shortcut_id);
   }
diff --git a/chrome/browser/ui/exclusive_access/fullscreen_controller.cc b/chrome/browser/ui/exclusive_access/fullscreen_controller.cc
index 147dd07..e108057 100644
--- a/chrome/browser/ui/exclusive_access/fullscreen_controller.cc
+++ b/chrome/browser/ui/exclusive_access/fullscreen_controller.cc
@@ -299,12 +299,12 @@
 void FullscreenController::FullscreenTabOpeningPopup(
     content::WebContents* opener,
     content::WebContents* popup) {
-  if (popunder_preventer_) {
-    DCHECK_EQ(exclusive_access_tab(), opener);
-    popunder_preventer_->AddPotentialPopunder(popup);
-  } else {
-    DCHECK(IsFullscreenWithinTab(opener));
+  if (!popunder_preventer_) {
+    return;
   }
+
+  DCHECK_EQ(exclusive_access_tab(), opener);
+  popunder_preventer_->AddPotentialPopunder(popup);
 }
 
 void FullscreenController::OnTabDeactivated(
diff --git a/chrome/browser/ui/global_error/global_error_service_browsertest.cc b/chrome/browser/ui/global_error/global_error_service_browsertest.cc
index f59a9ea..cbdba87 100644
--- a/chrome/browser/ui/global_error/global_error_service_browsertest.cc
+++ b/chrome/browser/ui/global_error/global_error_service_browsertest.cc
@@ -120,8 +120,14 @@
 // This uses the deprecated "unowned" API to the GlobalErrorService to maintain
 // coverage. When those calls are eventually removed (http://crbug.com/673578)
 // these uses should be switched to the non-deprecated API.
+// TODO(https://crbug.com/1513012): Flaky on asan lacros.
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+#define MAYBE_BubbleViewDismissedOnRemove DISABLED_BubbleViewDismissedOnRemove
+#else
+#define MAYBE_BubbleViewDismissedOnRemove BubbleViewDismissedOnRemove
+#endif
 IN_PROC_BROWSER_TEST_F(GlobalErrorServiceBrowserTest,
-                       BubbleViewDismissedOnRemove) {
+                       MAYBE_BubbleViewDismissedOnRemove) {
   std::unique_ptr<BubbleViewError> error(new BubbleViewError);
 
   GlobalErrorService* service =
diff --git a/chrome/browser/ui/views/apps/app_dialog/shortcut_removal_dialog_view_browsertest.cc b/chrome/browser/ui/views/apps/app_dialog/shortcut_removal_dialog_view_browsertest.cc
index 3bc2ebcf..5574297 100644
--- a/chrome/browser/ui/views/apps/app_dialog/shortcut_removal_dialog_view_browsertest.cc
+++ b/chrome/browser/ui/views/apps/app_dialog/shortcut_removal_dialog_view_browsertest.cc
@@ -47,12 +47,8 @@
   apps::ShortcutId CreateWebAppBasedShortcut(
       const GURL& shortcut_url,
       const std::u16string& shortcut_name) {
-    // Create web app based shortcut.
-    auto web_app_info = std::make_unique<web_app::WebAppInstallInfo>();
-    web_app_info->start_url = shortcut_url;
-    web_app_info->title = shortcut_name;
-    auto local_shortcut_id = web_app::test::InstallWebApp(
-        browser()->profile(), std::move(web_app_info));
+    webapps::AppId local_shortcut_id = web_app::test::InstallShortcut(
+        browser()->profile(), base::UTF16ToUTF8(shortcut_name), shortcut_url);
     return apps::GenerateShortcutId(app_constants::kChromeAppId,
                                     local_shortcut_id);
   }
@@ -110,10 +106,10 @@
 };
 
 IN_PROC_BROWSER_TEST_F(ShortcutRemovalDialogViewBrowserTest, InvokeUi) {
-  GURL app_url = GURL("https://example.org/");
+  GURL shortcut_url = GURL("https://example.org/");
   std::u16string shortcut_name = u"Example";
   apps::ShortcutId shortcut_id =
-      CreateWebAppBasedShortcut(app_url, shortcut_name);
+      CreateWebAppBasedShortcut(shortcut_url, shortcut_name);
   SetStubIconLoaders(shortcut_id, app_constants::kChromeAppId);
   EXPECT_EQ(0, NumLoadShortcutIcon());
   EXPECT_EQ(0, NumLoadBadgeIcon());
diff --git a/chrome/browser/ui/views/eye_dropper/eye_dropper_view_aura_browsertest.cc b/chrome/browser/ui/views/eye_dropper/eye_dropper_view_aura_browsertest.cc
deleted file mode 100644
index 47d2ec9..0000000
--- a/chrome/browser/ui/views/eye_dropper/eye_dropper_view_aura_browsertest.cc
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/views/eye_dropper/eye_dropper.h"
-#include "chrome/test/base/in_process_browser_test.h"
-#include "chrome/test/base/ui_test_utils.h"
-#include "components/eye_dropper/eye_dropper_view.h"
-#include "content/public/browser/eye_dropper.h"
-#include "content/public/browser/render_widget_host_view.h"
-#include "content/public/test/browser_test.h"
-
-class EyeDropperViewAuraBrowserTest : public InProcessBrowserTest {
- public:
-  EyeDropperViewAuraBrowserTest() = default;
-
-  class EyeDropperListener : public content::EyeDropperListener {
-   public:
-    void ColorSelected(SkColor color) override {}
-    void ColorSelectionCanceled() override { is_canceled_ = true; }
-    bool IsCanceled() const { return is_canceled_; }
-
-   private:
-    bool is_canceled_ = false;
-  };
-};
-
-IN_PROC_BROWSER_TEST_F(EyeDropperViewAuraBrowserTest, ActiveChangeCancel) {
-  EyeDropperListener listener;
-  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
-      browser(), GURL("about:blank"), 1);
-  content::WebContents* web_contents =
-      browser()->tab_strip_model()->GetActiveWebContents();
-  std::unique_ptr<content::EyeDropper> eye_dropper =
-      ShowEyeDropper(web_contents->GetPrimaryMainFrame(), &listener);
-  EXPECT_FALSE(listener.IsCanceled());
-  web_contents->GetRenderWidgetHostView()->Hide();
-  EXPECT_TRUE(listener.IsCanceled());
-}
-
-IN_PROC_BROWSER_TEST_F(EyeDropperViewAuraBrowserTest, InactiveWindow) {
-  EyeDropperListener listener;
-  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
-      browser(), GURL("about:blank"), 1);
-  content::WebContents* web_contents =
-      browser()->tab_strip_model()->GetActiveWebContents();
-  web_contents->GetRenderWidgetHostView()->Hide();
-  std::unique_ptr<content::EyeDropper> eye_dropper =
-      ShowEyeDropper(web_contents->GetPrimaryMainFrame(), &listener);
-  EXPECT_EQ(eye_dropper, nullptr);
-}
diff --git a/chrome/browser/ui/views/eye_dropper/eye_dropper_view_aura_interactive_uitest.cc b/chrome/browser/ui/views/eye_dropper/eye_dropper_view_aura_interactive_uitest.cc
new file mode 100644
index 0000000..192cb7c
--- /dev/null
+++ b/chrome/browser/ui/views/eye_dropper/eye_dropper_view_aura_interactive_uitest.cc
@@ -0,0 +1,97 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/views/eye_dropper/eye_dropper.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "components/eye_dropper/eye_dropper_view.h"
+#include "content/public/browser/eye_dropper.h"
+#include "content/public/browser/render_widget_host_view.h"
+#include "content/public/test/browser_test.h"
+
+class EyeDropperViewAuraInteractiveTest : public InProcessBrowserTest {
+ public:
+  EyeDropperViewAuraInteractiveTest() = default;
+
+  class EyeDropperListener : public content::EyeDropperListener {
+   public:
+    void ColorSelected(SkColor color) override {}
+    void ColorSelectionCanceled() override { is_canceled_ = true; }
+    bool IsCanceled() const { return is_canceled_; }
+
+   private:
+    bool is_canceled_ = false;
+  };
+};
+
+IN_PROC_BROWSER_TEST_F(EyeDropperViewAuraInteractiveTest, ActiveChangeCancel) {
+  EyeDropperListener listener;
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  web_contents->Focus();
+  ASSERT_TRUE(web_contents->GetPrimaryMainFrame()->GetView()->HasFocus());
+  std::unique_ptr<content::EyeDropper> eye_dropper =
+      ShowEyeDropper(web_contents->GetPrimaryMainFrame(), &listener);
+  ASSERT_TRUE(eye_dropper);
+  EXPECT_FALSE(listener.IsCanceled());
+  web_contents->GetRenderWidgetHostView()->Hide();
+  EXPECT_TRUE(listener.IsCanceled());
+}
+
+IN_PROC_BROWSER_TEST_F(EyeDropperViewAuraInteractiveTest, InactiveWindow) {
+  EyeDropperListener listener;
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  web_contents->GetRenderWidgetHostView()->Hide();
+  ASSERT_FALSE(web_contents->GetPrimaryMainFrame()->GetView()->HasFocus());
+  std::unique_ptr<content::EyeDropper> eye_dropper =
+      ShowEyeDropper(web_contents->GetPrimaryMainFrame(), &listener);
+  EXPECT_EQ(eye_dropper, nullptr);
+}
+
+IN_PROC_BROWSER_TEST_F(EyeDropperViewAuraInteractiveTest, MoveMouseAndTouch) {
+  EyeDropperListener listener;
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+
+  // EyeDropper should open at cursor.
+  web_contents->Focus();
+  ASSERT_TRUE(web_contents->GetPrimaryMainFrame()->GetView()->HasFocus());
+  std::unique_ptr<content::EyeDropper> eye_dropper =
+      ShowEyeDropper(web_contents->GetPrimaryMainFrame(), &listener);
+  ASSERT_TRUE(eye_dropper);
+  auto* view = static_cast<eye_dropper::EyeDropperView*>(eye_dropper.get());
+  EXPECT_EQ(display::Screen::GetScreen()->GetCursorScreenPoint(),
+            view->GetWidget()->GetWindowBoundsInScreen().CenterPoint());
+
+  // EyeDropper should move as cursor moves.
+  constexpr gfx::Point kCursorPosition1(101, 102);
+  view->OnCursorPositionUpdate(kCursorPosition1);
+  EXPECT_EQ(kCursorPosition1,
+            view->GetWidget()->GetWindowBoundsInScreen().CenterPoint());
+
+  // EyeDropper should move on touch events.
+  constexpr gfx::Point kTouchStart(100, 100);
+  const ui::PointerDetails kDetails(ui::EventPointerType::kTouch, 1);
+  ui::TouchEvent press(ui::ET_TOUCH_PRESSED, kTouchStart,
+                       base::TimeTicks::Now(), kDetails);
+  view->GetEventHandlerForTesting()->OnTouchEvent(&press);
+  constexpr gfx::Point kTouchEnd(110, 110);
+  ui::TouchEvent move(ui::ET_TOUCH_MOVED, kTouchEnd, base::TimeTicks::Now(),
+                      kDetails);
+  view->GetEventHandlerForTesting()->OnTouchEvent(&move);
+
+  gfx::Vector2d kTouchMoved(kTouchEnd - kTouchStart);
+  EXPECT_EQ(kCursorPosition1 + kTouchMoved,
+            view->GetWidget()->GetWindowBoundsInScreen().CenterPoint());
+
+  // EyeDropper should not move back to cursor until it moves.
+  view->OnCursorPositionUpdate(kCursorPosition1);
+  EXPECT_EQ(kCursorPosition1 + kTouchMoved,
+            view->GetWidget()->GetWindowBoundsInScreen().CenterPoint());
+  constexpr gfx::Point kCursorPosition2(122, 133);
+  view->OnCursorPositionUpdate(kCursorPosition2);
+  EXPECT_EQ(kCursorPosition2,
+            view->GetWidget()->GetWindowBoundsInScreen().CenterPoint());
+}
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
index 2af30a6..bfb94d4 100644
--- a/chrome/browser/ui/views/frame/browser_view.cc
+++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -2606,8 +2606,11 @@
 }
 
 void BrowserView::OnWidgetShowStateChanged(views::Widget* widget) {
+// TODO(crbug.com/1503145): Investigate and fix on MacOS.
+#if !BUILDFLAG(IS_MAC)
   // `display-state` @media feature value in renderer needs to be updated.
   SynchronizeRenderWidgetHostVisualPropertiesForMainFrame();
+#endif
 }
 
 void BrowserView::PrimaryPageChanged(content::Page& page) {
diff --git a/chrome/browser/ui/views/web_apps/web_app_integration_browsertest_cros.cc b/chrome/browser/ui/views/web_apps/web_app_integration_browsertest_cros.cc
index 9eec6bc..a18f9a3 100644
--- a/chrome/browser/ui/views/web_apps/web_app_integration_browsertest_cros.cc
+++ b/chrome/browser/ui/views/web_apps/web_app_integration_browsertest_cros.cc
@@ -881,9 +881,17 @@
   helper_.CheckWindowControlsOverlay(Site::kWco, IsOn::kOn);
 }
 
+// TODO(crbug/1481727): Flaky on lacros.
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+#define MAYBE_WAI_32WcoWithShortcutWindowedWebApp_34Wco_112WcoShown_168_169 \
+  DISABLED_WAI_32WcoWithShortcutWindowedWebApp_34Wco_112WcoShown_168_169
+#else
+#define MAYBE_WAI_32WcoWithShortcutWindowedWebApp_34Wco_112WcoShown_168_169 \
+  WAI_32WcoWithShortcutWindowedWebApp_34Wco_112WcoShown_168_169
+#endif
 IN_PROC_BROWSER_TEST_F(
     WebAppIntegration,
-    WAI_32WcoWithShortcutWindowedWebApp_34Wco_112WcoShown_168_169) {
+    MAYBE_WAI_32WcoWithShortcutWindowedWebApp_34Wco_112WcoShown_168_169) {
   // Test contents are generated by script. Please do not modify!
   // See `docs/webapps/why-is-this-test-failing.md` or
   // `docs/webapps/integration-testing-framework` for more info.
@@ -1145,9 +1153,17 @@
   helper_.CheckWindowControlsOverlay(Site::kWco, IsOn::kOn);
 }
 
+// TODO(crbug.com/1481727): Flaky on Lacros.
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+#define MAYBE_WAI_32WcoNoShortcutWindowedWebApp_34Wco_112WcoShown_168_169 \
+  DISABLED_WAI_32WcoNoShortcutWindowedWebApp_34Wco_112WcoShown_168_169
+#else
+#define MAYBE_WAI_32WcoNoShortcutWindowedWebApp_34Wco_112WcoShown_168_169 \
+  WAI_32WcoNoShortcutWindowedWebApp_34Wco_112WcoShown_168_169
+#endif
 IN_PROC_BROWSER_TEST_F(
     WebAppIntegration,
-    WAI_32WcoNoShortcutWindowedWebApp_34Wco_112WcoShown_168_169) {
+    MAYBE_WAI_32WcoNoShortcutWindowedWebApp_34Wco_112WcoShown_168_169) {
   // Test contents are generated by script. Please do not modify!
   // See `docs/webapps/why-is-this-test-failing.md` or
   // `docs/webapps/integration-testing-framework` for more info.
diff --git a/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc b/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc
index d19a6b1..c601dca4 100644
--- a/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc
+++ b/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc
@@ -1616,11 +1616,13 @@
 
 void WebAppPublisherHelper::Init() {
   // Allow for web app migration tests.
-  if (!AreWebAppsEnabled(profile_)) {
+  // In some tests, WebAppPublisherHelper could be created during the shutdown
+  // stage as the web app publisher is created async by AppServiceProxy. So
+  // provider_ could be null in some tests.
+  if (!AreWebAppsEnabled(profile_) || !provider_) {
     return;
   }
 
-  DCHECK(provider_);
   provider_->on_registry_ready().Post(
       FROM_HERE, base::BindOnce(&WebAppPublisherHelper::ObserveWebAppSubsystems,
                                 weak_ptr_factory_.GetWeakPtr()));
diff --git a/chrome/browser/web_applications/app_service/web_apps.cc b/chrome/browser/web_applications/app_service/web_apps.cc
index 32f875ddb..bb61221 100644
--- a/chrome/browser/web_applications/app_service/web_apps.cc
+++ b/chrome/browser/web_applications/app_service/web_apps.cc
@@ -72,12 +72,14 @@
 
 void WebApps::Initialize() {
   DCHECK(profile_);
-  if (!AreWebAppsEnabled(profile_)) {
+
+  // In some tests, WebAppPublisherHelper could be created during the shutdown
+  // stage as the web app publisher is created async by AppServiceProxy. So
+  // provider_ could be null in some tests.
+  if (!AreWebAppsEnabled(profile_) || !provider_) {
     return;
   }
 
-  DCHECK(provider_);
-
   provider_->on_registry_ready().Post(
       FROM_HERE, base::BindOnce(&WebApps::InitWebApps, AsWeakPtr()));
 }
diff --git a/chrome/browser/web_applications/test/web_app_install_test_utils.cc b/chrome/browser/web_applications/test/web_app_install_test_utils.cc
index 7cc6bde..c72cc6de 100644
--- a/chrome/browser/web_applications/test/web_app_install_test_utils.cc
+++ b/chrome/browser/web_applications/test/web_app_install_test_utils.cc
@@ -117,7 +117,8 @@
 webapps::AppId InstallShortcut(Profile* profile,
                                const std::string& shortcut_name,
                                const GURL& start_url,
-                               bool create_default_icon) {
+                               bool create_default_icon,
+                               bool is_policy_install) {
   auto web_app_info = std::make_unique<WebAppInstallInfo>();
 
   web_app_info->start_url = start_url;
@@ -144,18 +145,19 @@
   // `WebAppInstallCommand` to install the web app.
   provider->scheduler().InstallFromInfo(
       std::move(web_app_info), /*overwrite_existing_manifest_fields =*/true,
-      webapps::WebappInstallSource::MENU_CREATE_SHORTCUT, future.GetCallback());
+      is_policy_install ? webapps::WebappInstallSource::EXTERNAL_POLICY
+                        : webapps::WebappInstallSource::MENU_CREATE_SHORTCUT,
+      future.GetCallback());
 
-  webapps::AppId app_id = future.Get<0>();
-  webapps::InstallResultCode code = future.Get<1>();
-
-  EXPECT_EQ(webapps::InstallResultCode::kSuccessNewInstall, code);
+  EXPECT_EQ(webapps::InstallResultCode::kSuccessNewInstall,
+            future.Get<webapps::InstallResultCode>());
 
   // Allow updates to be published to App Service listeners.
   base::RunLoop().RunUntilIdle();
 
-  CHECK(provider->registrar_unsafe().IsShortcutApp(app_id));
-  return app_id;
+  CHECK(
+      provider->registrar_unsafe().IsShortcutApp(future.Get<webapps::AppId>()));
+  return future.Get<webapps::AppId>();
 }
 
 void UninstallWebApp(Profile* profile, const webapps::AppId& app_id) {
diff --git a/chrome/browser/web_applications/test/web_app_install_test_utils.h b/chrome/browser/web_applications/test/web_app_install_test_utils.h
index 8f38f226..7543b92 100644
--- a/chrome/browser/web_applications/test/web_app_install_test_utils.h
+++ b/chrome/browser/web_applications/test/web_app_install_test_utils.h
@@ -61,7 +61,8 @@
 webapps::AppId InstallShortcut(Profile* profile,
                                const std::string& shortcut_name,
                                const GURL& start_url,
-                               bool create_default_icon = true);
+                               bool create_default_icon = true,
+                               bool is_policy_install = false);
 
 // Synchronously uninstall a web app. May be used in unit tests and browser
 // tests.
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index 7f364a03..7c92ef8 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-main-1702555132-faf4c349eb7e02bb4fa156ef2538a7a5839027d6.profdata
+chrome-linux-main-1702964670-14086d4116485d885d285077c2cfd61e5d591f42.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt
index 71c71d52..b149162 100644
--- a/chrome/build/mac-arm.pgo.txt
+++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@
-chrome-mac-arm-main-1702936733-e22c65059657a9d5898e430eda02afdeb3cd9963.profdata
+chrome-mac-arm-main-1702964670-c9c1eafc30a8138f697fefd6092ebbe2ffde101e.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index bc4210e..d64d042 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-main-1702555132-0206c651e7f5e372d256707c857a2c2e329c7b0a.profdata
+chrome-mac-main-1702964670-58dd920b70bada0e4212a305918b68577b64a726.profdata
diff --git a/chrome/build/win-arm64.pgo.txt b/chrome/build/win-arm64.pgo.txt
index d904620c..ba31f92ad 100644
--- a/chrome/build/win-arm64.pgo.txt
+++ b/chrome/build/win-arm64.pgo.txt
@@ -1 +1 @@
-chrome-win-arm64-main-1702555132-df0787bd7fd1b8df386ee9f24b09327c73ec7840.profdata
+chrome-win-arm64-main-1702964670-b2c612ca730cd6b7904f4e06bdcd026af7a45352.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 205de180..1717f022 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1702933089-95bda8e015b301e2b0b631fe6b8c0e7a9c936e8e.profdata
+chrome-win64-main-1702964670-40425cd9017c07ad3bbdbc6003148437bfe8443f.profdata
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 09cf5b9..bfdb8ed 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -3017,7 +3017,6 @@
       sources += [
         "../browser/accessibility/live_caption/live_caption_unavailability_notifier_browsertest.cc",
         "../browser/ui/views/device_id/pen_id_browsertest_win.cc",
-        "../browser/ui/views/eye_dropper/eye_dropper_view_aura_browsertest.cc",
         "../browser/ui/views/web_apps/web_app_integration_browsertest_win.cc",
       ]
       sources -= [ "../browser/ui/views/tabs/tab_search_button_browsertest.cc" ]
@@ -11004,6 +11003,12 @@
       ]
     }
 
+    # LaCrOS opens EyeDropper in ash via crosapi. Tests only work for ash.
+    if (use_aura && !is_chromeos_lacros) {
+      sources += [ "../browser/ui/views/eye_dropper/eye_dropper_view_aura_interactive_uitest.cc" ]
+      deps += [ "//components/eye_dropper" ]
+    }
+
     if (toolkit_views) {
       sources += [
         "../browser/media/webrtc/conditional_focus_browsertest.cc",
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM
index f76666d..44ba5de 100644
--- a/chromeos/CHROMEOS_LKGM
+++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@
-15714.0.0
\ No newline at end of file
+15715.0.0
\ No newline at end of file
diff --git a/chromeos/ash/components/dbus/fwupd/BUILD.gn b/chromeos/ash/components/dbus/fwupd/BUILD.gn
index 58c71df..a1e90bdf 100644
--- a/chromeos/ash/components/dbus/fwupd/BUILD.gn
+++ b/chromeos/ash/components/dbus/fwupd/BUILD.gn
@@ -28,8 +28,6 @@
     "fwupd_device.h",
     "fwupd_properties.cc",
     "fwupd_properties.h",
-    "fwupd_request.cc",
-    "fwupd_request.h",
     "fwupd_update.cc",
     "fwupd_update.h",
   ]
diff --git a/chromeos/ash/components/dbus/fwupd/fwupd_client.h b/chromeos/ash/components/dbus/fwupd/fwupd_client.h
index 15da595..72313d8 100644
--- a/chromeos/ash/components/dbus/fwupd/fwupd_client.h
+++ b/chromeos/ash/components/dbus/fwupd/fwupd_client.h
@@ -14,7 +14,6 @@
 #include "base/observer_list.h"
 #include "chromeos/ash/components/dbus/fwupd/fwupd_device.h"
 #include "chromeos/ash/components/dbus/fwupd/fwupd_properties.h"
-#include "chromeos/ash/components/dbus/fwupd/fwupd_request.h"
 #include "chromeos/ash/components/dbus/fwupd/fwupd_update.h"
 #include "chromeos/dbus/common/dbus_client.h"
 
@@ -33,7 +32,6 @@
                                       FwupdUpdateList* updates) = 0;
     virtual void OnInstallResponse(bool success) = 0;
     virtual void OnPropertiesChangedResponse(FwupdProperties* properties) = 0;
-    virtual void OnDeviceRequestResponse(FwupdRequest* request) = 0;
   };
 
   void AddObserver(Observer* observer);
diff --git a/chromeos/ash/components/dbus/fwupd/fwupd_client_unittest.cc b/chromeos/ash/components/dbus/fwupd/fwupd_client_unittest.cc
index 7e6f58b5..85284a7 100644
--- a/chromeos/ash/components/dbus/fwupd/fwupd_client_unittest.cc
+++ b/chromeos/ash/components/dbus/fwupd/fwupd_client_unittest.cc
@@ -12,7 +12,6 @@
 #include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
 #include "chromeos/ash/components/dbus/fwupd/fwupd_properties.h"
-#include "chromeos/ash/components/dbus/fwupd/fwupd_request.h"
 #include "dbus/message.h"
 #include "dbus/mock_bus.h"
 #include "dbus/mock_object_proxy.h"
@@ -68,10 +67,6 @@
               OnPropertiesChangedResponse,
               (ash::FwupdProperties * properties),
               (override));
-  MOCK_METHOD(void,
-              OnDeviceRequestResponse,
-              (ash::FwupdRequest * request),
-              (override));
 };
 
 }  // namespace
diff --git a/chromeos/ash/components/dbus/fwupd/fwupd_request.cc b/chromeos/ash/components/dbus/fwupd/fwupd_request.cc
deleted file mode 100644
index 4a08c88..0000000
--- a/chromeos/ash/components/dbus/fwupd/fwupd_request.cc
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chromeos/ash/components/dbus/fwupd/fwupd_request.h"
-
-namespace ash {
-
-FwupdRequest::FwupdRequest() = default;
-
-FwupdRequest::FwupdRequest(uint32_t id, uint32_t kind) : id(id), kind(kind) {}
-
-FwupdRequest::FwupdRequest(const FwupdRequest& other) = default;
-FwupdRequest::~FwupdRequest() = default;
-
-}  // namespace ash
diff --git a/chromeos/ash/components/dbus/fwupd/fwupd_request.h b/chromeos/ash/components/dbus/fwupd/fwupd_request.h
deleted file mode 100644
index 181be43..0000000
--- a/chromeos/ash/components/dbus/fwupd/fwupd_request.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROMEOS_ASH_COMPONENTS_DBUS_FWUPD_FWUPD_REQUEST_H_
-#define CHROMEOS_ASH_COMPONENTS_DBUS_FWUPD_FWUPD_REQUEST_H_
-
-#include <stdint.h>
-#include "base/component_export.h"
-
-namespace ash {
-
-// Structure to hold FwupdRequest data received from fwupd.
-struct COMPONENT_EXPORT(ASH_DBUS_FWUPD) FwupdRequest {
-  FwupdRequest();
-  FwupdRequest(uint32_t id, uint32_t kind);
-  FwupdRequest(const FwupdRequest& other);
-  ~FwupdRequest();
-
-  // The ID of the Request; corresponds to the enum values found in
-  // https://github.com/fwupd/fwupd/blob/main/libfwupd/fwupd-request.h
-  uint32_t id;
-  // The Kind of the Request; corresponds to the enum values found in
-  // https://github.com/fwupd/fwupd/blob/main/libfwupd/fwupd-request.h
-  uint32_t kind;
-};
-
-}  // namespace ash
-
-#endif  // CHROMEOS_ASH_COMPONENTS_DBUS_FWUPD_FWUPD_REQUEST_H_
diff --git a/chromeos/ash/components/fwupd/firmware_update_manager.cc b/chromeos/ash/components/fwupd/firmware_update_manager.cc
index 3599903..7424e1f 100644
--- a/chromeos/ash/components/fwupd/firmware_update_manager.cc
+++ b/chromeos/ash/components/fwupd/firmware_update_manager.cc
@@ -254,14 +254,6 @@
                                  kAllowedFilepathChars);
 }
 
-// Converts a FwupdRequest into a mojom DeviceRequest.
-firmware_update::mojom::DeviceRequestPtr GetDeviceRequest(
-    FwupdRequest request) {
-  return firmware_update::mojom::DeviceRequest::New(
-      static_cast<firmware_update::mojom::DeviceRequestId>(request.id),
-      static_cast<firmware_update::mojom::DeviceRequestKind>(request.kind));
-}
-
 }  // namespace
 
 FirmwareUpdateManager::FirmwareUpdateManager()
@@ -709,17 +701,6 @@
   receiver_.Bind(std::move(pending_receiver));
 }
 
-void FirmwareUpdateManager::OnDeviceRequestResponse(FwupdRequest* request) {
-  if (!request || !device_request_observer_.is_bound()) {
-    LOG(ERROR) << "OnDeviceRequestResponse triggered with unbound observer or "
-                  "nullptr request.";
-    return;
-  }
-  // Convert the FwupdRequest into a mojom DeviceRequest, then pass that
-  // request to observers.
-  device_request_observer_->OnDeviceRequest(GetDeviceRequest(*request));
-}
-
 void FirmwareUpdateManager::OnPropertiesChangedResponse(
     FwupdProperties* properties) {
   if (!properties || !update_progress_observer_.is_bound()) {
diff --git a/chromeos/ash/components/fwupd/firmware_update_manager.h b/chromeos/ash/components/fwupd/firmware_update_manager.h
index e53cb5d..e0127897 100644
--- a/chromeos/ash/components/fwupd/firmware_update_manager.h
+++ b/chromeos/ash/components/fwupd/firmware_update_manager.h
@@ -22,7 +22,6 @@
 #include "chromeos/ash/components/dbus/fwupd/fwupd_client.h"
 #include "chromeos/ash/components/dbus/fwupd/fwupd_device.h"
 #include "chromeos/ash/components/dbus/fwupd/fwupd_properties.h"
-#include "chromeos/ash/components/dbus/fwupd/fwupd_request.h"
 #include "chromeos/ash/components/dbus/fwupd/fwupd_update.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/receiver.h"
@@ -94,8 +93,6 @@
   // it calls this function and passes the response.
   void OnDeviceListResponse(FwupdDeviceList* devices) override;
 
-  void OnDeviceRequestResponse(FwupdRequest* request) override;
-
   // When the fwupd DBus client gets a response with updates from fwupd,
   // it calls this function and passes the response.
   void OnUpdateListResponse(const std::string& device_id,
diff --git a/chromeos/ash/components/fwupd/firmware_update_manager_unittest.cc b/chromeos/ash/components/fwupd/firmware_update_manager_unittest.cc
index dca1cbb..f84436ce 100644
--- a/chromeos/ash/components/fwupd/firmware_update_manager_unittest.cc
+++ b/chromeos/ash/components/fwupd/firmware_update_manager_unittest.cc
@@ -22,7 +22,6 @@
 #include "base/test/task_environment.h"
 #include "base/test/test_future.h"
 #include "chromeos/ash/components/dbus/fwupd/fwupd_client.h"
-#include "chromeos/ash/components/dbus/fwupd/fwupd_request.h"
 #include "chromeos/ash/components/fwupd/fake_fwupd_download_client.h"
 #include "chromeos/ash/components/fwupd/histogram_util.h"
 #include "dbus/message.h"
@@ -238,11 +237,6 @@
     base::RunLoop().RunUntilIdle();
   }
 
-  void TriggerOnDeviceRequestResponse(FwupdRequest* request) {
-    firmware_update_manager_->OnDeviceRequestResponse(request);
-    base::RunLoop().RunUntilIdle();
-  }
-
   void SetFakeUrlForTesting(const std::string& fake_url) {
     firmware_update_manager_->SetFakeUrlForTesting(fake_url);
   }
@@ -1088,35 +1082,4 @@
   SetupDeviceRequestObserver(&device_request_observer);
 }
 
-TEST_F(FirmwareUpdateManagerTest, DeviceRequestObserver) {
-  EXPECT_TRUE(PrepareForUpdate(std::string(kFakeDeviceIdForTesting)));
-  FakeDeviceRequestObserver device_request_observer;
-  SetupDeviceRequestObserver(&device_request_observer);
-
-  // For each combination of DeviceRequestId and DeviceRequestKind, call
-  // OnDeviceRequestResponse on firmware_update_manager and then verify that the
-  // observer received the correct DeviceRequest.
-  int device_request_id_size =
-      static_cast<int>(firmware_update::mojom::DeviceRequestId::kMaxValue) + 1;
-  int device_request_kind_size =
-      static_cast<int>(firmware_update::mojom::DeviceRequestKind::kMaxValue) +
-      1;
-
-  for (int id_index = 0; id_index < device_request_id_size; id_index++) {
-    for (int kind_index = 0; kind_index < device_request_kind_size;
-         kind_index++) {
-      firmware_update::mojom::DeviceRequestId id =
-          static_cast<firmware_update::mojom::DeviceRequestId>(id_index);
-      firmware_update::mojom::DeviceRequestKind kind =
-          static_cast<firmware_update::mojom::DeviceRequestKind>(kind_index);
-
-      TriggerOnDeviceRequestResponse(new FwupdRequest(
-          static_cast<uint32_t>(id), static_cast<uint32_t>(kind)));
-
-      EXPECT_EQ(id, device_request_observer.GetLatestRequest()->id);
-      EXPECT_EQ(kind, device_request_observer.GetLatestRequest()->kind);
-    }
-  }
-}
-
 }  // namespace ash
diff --git a/chromeos/profiles/atom.afdo.newest.txt b/chromeos/profiles/atom.afdo.newest.txt
index 6dc13c0..08dc9c97 100644
--- a/chromeos/profiles/atom.afdo.newest.txt
+++ b/chromeos/profiles/atom.afdo.newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-atom-121-6167.9-1702295304-benchmark-122.0.6190.0-r1-redacted.afdo.xz
+chromeos-chrome-amd64-atom-122-6167.14-1702898748-benchmark-122.0.6192.0-r1-redacted.afdo.xz
diff --git a/clank b/clank
index 81557d3..07122ea 160000
--- a/clank
+++ b/clank
@@ -1 +1 @@
-Subproject commit 81557d351b8541438b80a494040df59f3eec95fd
+Subproject commit 07122eaa37ba1580a2f75247c51ee4ee4c650ba4
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn
index 7a3dfd6..e4391ca6 100644
--- a/components/autofill/core/browser/BUILD.gn
+++ b/components/autofill/core/browser/BUILD.gn
@@ -345,6 +345,8 @@
     "metrics/payments/virtual_card_standalone_cvc_suggestion_metrics.h",
     "metrics/payments/wallet_usage_data_metrics.cc",
     "metrics/payments/wallet_usage_data_metrics.h",
+    "metrics/placeholder_metrics.cc",
+    "metrics/placeholder_metrics.h",
     "metrics/precedence_over_autocomplete_metrics.cc",
     "metrics/precedence_over_autocomplete_metrics.h",
     "metrics/profile_import_metrics.cc",
@@ -532,6 +534,8 @@
     "webdata/autofill_profile_sync_difference_tracker.h",
     "webdata/autofill_sync_bridge_util.cc",
     "webdata/autofill_sync_bridge_util.h",
+    "webdata/autofill_sync_metadata_table.cc",
+    "webdata/autofill_sync_metadata_table.h",
     "webdata/autofill_table.cc",
     "webdata/autofill_table.h",
     "webdata/autofill_table_encryptor.h",
@@ -1151,6 +1155,7 @@
     "webdata/autofill_profile_sync_bridge_unittest.cc",
     "webdata/autofill_profile_sync_difference_tracker_unittest.cc",
     "webdata/autofill_sync_bridge_util_unittest.cc",
+    "webdata/autofill_sync_metadata_table_unittest.cc",
     "webdata/autofill_table_unittest.cc",
     "webdata/autofill_wallet_credential_sync_bridge_unittest.cc",
     "webdata/autofill_wallet_metadata_sync_bridge_unittest.cc",
diff --git a/components/autofill/core/browser/metrics/payments/card_unmask_flow_metrics.h b/components/autofill/core/browser/metrics/payments/card_unmask_flow_metrics.h
index 5194c915..6556f9f3 100644
--- a/components/autofill/core/browser/metrics/payments/card_unmask_flow_metrics.h
+++ b/components/autofill/core/browser/metrics/payments/card_unmask_flow_metrics.h
@@ -47,7 +47,9 @@
   kNoInteractiveAuthentication = 0,
   // CVC filled with FIDO authentication.
   kFido = 1,
-  kMaxValue = kFido,
+  // CVC filled with mandatory re-auth.
+  kMandatoryReauth = 2,
+  kMaxValue = kMandatoryReauth,
 };
 
 enum class ServerCardUnmaskFlowType {
diff --git a/components/autofill/core/browser/metrics/payments/iban_metrics.cc b/components/autofill/core/browser/metrics/payments/iban_metrics.cc
index 9e4f5ca..cbbcca3b 100644
--- a/components/autofill/core/browser/metrics/payments/iban_metrics.cc
+++ b/components/autofill/core/browser/metrics/payments/iban_metrics.cc
@@ -114,4 +114,11 @@
   base::UmaHistogramEnumeration(sync_subhistogram_metric, metric);
 }
 
+void LogServerIbanUnmaskLatency(base::TimeDelta latency, bool is_successful) {
+  base::UmaHistogramTimes(base::StrCat({"Autofill.Iban.UnmaskIbanDuration.",
+                                        is_successful ? "Success" : "Failure"}),
+                          latency);
+  base::UmaHistogramTimes("Autofill.Iban.UnmaskIbanDuration", latency);
+}
+
 }  // namespace autofill::autofill_metrics
diff --git a/components/autofill/core/browser/metrics/payments/iban_metrics.h b/components/autofill/core/browser/metrics/payments/iban_metrics.h
index 4306ee8..6cc65baf 100644
--- a/components/autofill/core/browser/metrics/payments/iban_metrics.h
+++ b/components/autofill/core/browser/metrics/payments/iban_metrics.h
@@ -5,6 +5,7 @@
 #ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_PAYMENTS_IBAN_METRICS_H_
 #define COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_PAYMENTS_IBAN_METRICS_H_
 
+#include "base/time/time.h"
 #include "components/autofill/core/browser/autofill_client.h"
 #include "components/autofill/core/browser/data_model/iban.h"
 #include "components/autofill/core/browser/metrics/autofill_metrics.h"
@@ -140,6 +141,9 @@
     IbanUploadEnabledStatus metric,
     AutofillMetrics::PaymentsSigninState sync_state);
 
+// Logs the latency for fetching a server IBAN in IbanAccessManager.
+void LogServerIbanUnmaskLatency(base::TimeDelta latency, bool is_successful);
+
 }  // namespace autofill::autofill_metrics
 
 #endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_PAYMENTS_IBAN_METRICS_H_
diff --git a/components/autofill/core/browser/metrics/placeholder_metrics.cc b/components/autofill/core/browser/metrics/placeholder_metrics.cc
new file mode 100644
index 0000000..01989f5
--- /dev/null
+++ b/components/autofill/core/browser/metrics/placeholder_metrics.cc
@@ -0,0 +1,21 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/metrics/placeholder_metrics.h"
+
+#include "base/metrics/histogram_functions.h"
+#include "base/strings/strcat.h"
+
+namespace autofill::autofill_metrics {
+
+void LogPreFilledFields(const std::string_view form_type_name,
+                        const std::optional<bool> initial_value_changed) {
+  base::UmaHistogramEnumeration(
+      base::StrCat({"Autofill.PreFilledFields.", form_type_name}),
+      initial_value_changed.has_value()
+          ? AutofillPreFilledFields::kPreFilledOnPageLoad
+          : AutofillPreFilledFields::kEmptyOnPageLoad);
+}
+
+}  // namespace autofill::autofill_metrics
diff --git a/components/autofill/core/browser/metrics/placeholder_metrics.h b/components/autofill/core/browser/metrics/placeholder_metrics.h
new file mode 100644
index 0000000..11fcfbc9
--- /dev/null
+++ b/components/autofill/core/browser/metrics/placeholder_metrics.h
@@ -0,0 +1,32 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_PLACEHOLDER_METRICS_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_PLACEHOLDER_METRICS_H_
+
+#include <string>
+#include <string_view>
+
+#include "components/autofill/core/browser/autofill_field.h"
+
+namespace autofill::autofill_metrics {
+
+// Log the number of fields that are pre-filled or empty on page load.
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused.
+enum class AutofillPreFilledFields {
+  // The field had a pre-filled value on page load.
+  kPreFilledOnPageLoad = 0,
+  // The field was empty on page load.
+  kEmptyOnPageLoad = 1,
+  kMaxValue = kEmptyOnPageLoad
+};
+
+// Log how many fields were autofilled, or not, and pre-filled, or not.
+void LogPreFilledFields(const std::string_view form_type_name,
+                        const std::optional<bool> initial_value_changed);
+
+}  // namespace autofill::autofill_metrics
+
+#endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_PLACEHOLDER_METRICS_H_
diff --git a/components/autofill/core/browser/metrics/quality_metrics.cc b/components/autofill/core/browser/metrics/quality_metrics.cc
index 91c6b59..46d4278 100644
--- a/components/autofill/core/browser/metrics/quality_metrics.cc
+++ b/components/autofill/core/browser/metrics/quality_metrics.cc
@@ -12,6 +12,7 @@
 #include "components/autofill/core/browser/metrics/autofill_metrics_utils.h"
 #include "components/autofill/core/browser/metrics/field_filling_stats_and_score_metrics.h"
 #include "components/autofill/core/browser/metrics/granular_filling_metrics_utils.h"
+#include "components/autofill/core/browser/metrics/placeholder_metrics.h"
 #include "components/autofill/core/browser/metrics/precedence_over_autocomplete_metrics.h"
 #include "components/autofill/core/browser/metrics/shadow_prediction_metrics.h"
 #include "components/autofill/core/browser/validation.h"
@@ -199,6 +200,10 @@
           AddFillingStatsForAutofillFillingMethod(
               *field, address_field_stats_by_filling_method);
         }
+
+        LogPreFilledFields(
+            std::string(FormTypeToStringView(form_type_of_field)),
+            field->initial_value_changed());
       }
     }
 
diff --git a/components/autofill/core/browser/metrics/quality_metrics_unittest.cc b/components/autofill/core/browser/metrics/quality_metrics_unittest.cc
index 08a8a9f..52737aa7 100644
--- a/components/autofill/core/browser/metrics/quality_metrics_unittest.cc
+++ b/components/autofill/core/browser/metrics/quality_metrics_unittest.cc
@@ -11,6 +11,7 @@
 #include "components/autofill/core/browser/autofill_test_utils.h"
 #include "components/autofill/core/browser/browser_autofill_manager_test_api.h"
 #include "components/autofill/core/browser/metrics/autofill_metrics_test_base.h"
+#include "components/autofill/core/browser/metrics/placeholder_metrics.h"
 #include "components/autofill/core/browser/metrics/ukm_metrics_test_utils.h"
 #include "services/metrics/public/cpp/ukm_builders.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -924,6 +925,43 @@
                          Bucket(country_field.label_source, 1)));
 }
 
+TEST_F(QualityMetricsTest, EmitsUmaAutofillPreFilledFields) {
+  base::test::ScopedFeatureList features{
+      features::kAutofillOverwritePlaceholdersOnly};
+
+  base::HistogramTester histogram_tester;
+  test::FormDescription form_description = {
+      .fields = {{.role = NAME_FIRST,
+                  .heuristic_type = NAME_FIRST,
+                  .value = u"pre-filled"},
+                 {.role = NAME_LAST, .heuristic_type = NAME_LAST}}};
+  FormData form = test::GetFormData(form_description);
+
+  // Simulate page load.
+  autofill_manager().AddSeenForm(form,
+                                 test::GetHeuristicTypes(form_description),
+                                 test::GetServerTypes(form_description),
+                                 /*preserve_values_in_form_structure=*/true);
+  // Simluate interacting with the form.
+  autofill_manager().OnAskForValuesToFillTest(form, form.fields[0]);
+  // Get cached form and modify fields.
+  FormStructure* cached_form;
+  AutofillField* cached_triggering_field;
+  ASSERT_TRUE(autofill_manager().GetCachedFormAndField(
+      form, form.fields[0], &cached_form, &cached_triggering_field));
+  cached_form->fields()[1]->set_may_use_prefilled_placeholder(false);
+  // Fill form.
+  FillTestProfile(form);
+  // Submit form.
+  SubmitForm(form);
+
+  ResetDriverToCommitMetrics();
+  EXPECT_THAT(
+      histogram_tester.GetAllSamples("Autofill.PreFilledFields.Address"),
+      BucketsAre(base::Bucket(AutofillPreFilledFields::kPreFilledOnPageLoad, 1),
+                 base::Bucket(AutofillPreFilledFields::kEmptyOnPageLoad, 1)));
+}
+
 }  // namespace autofill_metrics
 
 }  // namespace autofill
diff --git a/components/autofill/core/browser/payments/credit_card_access_manager.cc b/components/autofill/core/browser/payments/credit_card_access_manager.cc
index 94ee944..1f3dcf8 100644
--- a/components/autofill/core/browser/payments/credit_card_access_manager.cc
+++ b/components/autofill/core/browser/payments/credit_card_access_manager.cc
@@ -1641,20 +1641,25 @@
     payments::MandatoryReauthAuthenticationMethod authentication_method,
     const CreditCard* card,
     bool successful_auth) {
+  CHECK(card);
+  CreditCard::RecordType record_type = card->record_type();
+
   autofill_metrics::LogMandatoryReauthCheckoutFlowUsageEvent(
-      card->record_type(), authentication_method,
+      record_type, authentication_method,
       successful_auth
           ? autofill_metrics::MandatoryReauthAuthenticationFlowEvent::
                 kFlowSucceeded
           : autofill_metrics::MandatoryReauthAuthenticationFlowEvent::
                 kFlowFailed);
-  CHECK(card);
+  if (successful_auth && !card->cvc().empty()) {
+    autofill_metrics::LogCvcFilling(
+        autofill_metrics::CvcFillingFlowType::kMandatoryReauth, record_type);
+  }
   autofill_metrics::LogServerCardUnmaskResult(
       successful_auth
           ? autofill_metrics::ServerCardUnmaskResult::kAuthenticationUnmasked
           : autofill_metrics::ServerCardUnmaskResult::kAuthenticationError,
-      card->record_type(),
-      autofill_metrics::ServerCardUnmaskFlowType::kDeviceUnlock);
+      record_type, autofill_metrics::ServerCardUnmaskFlowType::kDeviceUnlock);
 
   std::move(on_credit_card_fetched_callback_)
       .Run(successful_auth ? CreditCardFetchResult::kSuccess
diff --git a/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc b/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc
index 0c574599..62f1db1 100644
--- a/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc
+++ b/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc
@@ -32,6 +32,7 @@
 #include "components/autofill/core/browser/payments/card_unmask_challenge_option.h"
 #include "components/autofill/core/browser/payments/credit_card_cvc_authenticator.h"
 #include "components/autofill/core/browser/payments/credit_card_risk_based_authenticator.h"
+#include "components/autofill/core/browser/payments/mandatory_reauth_manager.h"
 #include "components/autofill/core/browser/payments/test/test_credit_card_otp_authenticator.h"
 #include "components/autofill/core/browser/payments/test_payments_network_interface.h"
 #include "components/autofill/core/browser/test_autofill_client.h"
@@ -565,25 +566,14 @@
 
 #if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) || \
     BUILDFLAG(IS_IOS)
-// Parameters of the CreditCardAccessManagerMandatoryReauthTest:
-// - bool feature_flag_is_on: Whether the mandatory re-auth feature flag is
-// turned on or off.
-// - bool pref_is_enabled: Whether the mandatory re-auth pref is turned on or
-// off.
-// - bool mandatory_reauth_response_is_success: Whether the response from the
-// mandatory re-auth is a success or failure.
-// - bool authentication_method: The authentication method that is supported.
+
 class CreditCardAccessManagerMandatoryReauthTest
-    : public CreditCardAccessManagerTest,
-      public testing::WithParamInterface<
-          std::tuple<bool,
-                     bool,
-                     bool,
-                     payments::MandatoryReauthAuthenticationMethod>> {
+    : public CreditCardAccessManagerTest {
  public:
   CreditCardAccessManagerMandatoryReauthTest() = default;
   ~CreditCardAccessManagerMandatoryReauthTest() override = default;
 
+ protected:
   void SetUp() override {
     CreditCardAccessManagerTest::SetUp();
     feature_list_.InitWithFeatureStates(
@@ -602,33 +592,6 @@
         /*value=*/PrefIsEnabled());
   }
 
-  bool FeatureFlagIsOn() const { return std::get<0>(GetParam()); }
-
-  bool PrefIsEnabled() const { return std::get<1>(GetParam()); }
-
-  bool MandatoryReauthResponseIsSuccess() const {
-    return std::get<2>(GetParam());
-  }
-
-  bool HasAuthenticator() const {
-    return std::get<3>(GetParam()) !=
-           payments::MandatoryReauthAuthenticationMethod::kUnsupportedMethod;
-  }
-
-  payments::MandatoryReauthAuthenticationMethod GetAuthenticationMethod()
-      const {
-    return std::get<3>(GetParam());
-  }
-
-  bool IsMandatoryReauthEnabled() {
-#if BUILDFLAG(IS_ANDROID)
-    if (base::android::BuildInfo::GetInstance()->is_automotive()) {
-      return true;
-    }
-#endif
-    return FeatureFlagIsOn() && PrefIsEnabled();
-  }
-
   void SetUpDeviceAuthenticatorResponseMock() {
     ON_CALL(mandatory_reauth_manager(), GetAuthenticationMethod)
         .WillByDefault(testing::Return(GetAuthenticationMethod()));
@@ -660,6 +623,71 @@
     }
   }
 
+  payments::MockMandatoryReauthManager& mandatory_reauth_manager() {
+    return *static_cast<payments::MockMandatoryReauthManager*>(
+        autofill_client_.GetOrCreatePaymentsMandatoryReauthManager());
+  }
+
+  virtual bool FeatureFlagIsOn() const = 0;
+
+  virtual bool PrefIsEnabled() const = 0;
+
+  virtual bool MandatoryReauthResponseIsSuccess() const = 0;
+
+  virtual bool HasAuthenticator() const = 0;
+
+  virtual payments::MandatoryReauthAuthenticationMethod
+  GetAuthenticationMethod() const = 0;
+
+  bool IsMandatoryReauthEnabled() {
+#if BUILDFLAG(IS_ANDROID)
+    if (base::android::BuildInfo::GetInstance()->is_automotive()) {
+      return true;
+    }
+#endif
+    return FeatureFlagIsOn() && PrefIsEnabled();
+  }
+
+  base::test::ScopedFeatureList feature_list_;
+};
+
+// Parameters of the CreditCardAccessManagerMandatoryReauthFunctionalTest:
+// - bool feature_flag_is_on: Whether the mandatory re-auth feature flag is
+// turned on or off.
+// - bool pref_is_enabled: Whether the mandatory re-auth pref is turned on or
+// off.
+// - bool mandatory_reauth_response_is_success: Whether the response from the
+// mandatory re-auth is a success or failure.
+// - bool authentication_method: The authentication method that is supported.
+class CreditCardAccessManagerMandatoryReauthFunctionalTest
+    : public CreditCardAccessManagerMandatoryReauthTest,
+      public testing::WithParamInterface<
+          std::tuple<bool,
+                     bool,
+                     bool,
+                     payments::MandatoryReauthAuthenticationMethod>> {
+ public:
+  CreditCardAccessManagerMandatoryReauthFunctionalTest() = default;
+  ~CreditCardAccessManagerMandatoryReauthFunctionalTest() override = default;
+
+  bool FeatureFlagIsOn() const override { return std::get<0>(GetParam()); }
+
+  bool PrefIsEnabled() const override { return std::get<1>(GetParam()); }
+
+  bool MandatoryReauthResponseIsSuccess() const override {
+    return std::get<2>(GetParam());
+  }
+
+  bool HasAuthenticator() const override {
+    return std::get<3>(GetParam()) !=
+           payments::MandatoryReauthAuthenticationMethod::kUnsupportedMethod;
+  }
+
+  payments::MandatoryReauthAuthenticationMethod GetAuthenticationMethod()
+      const override {
+    return std::get<3>(GetParam());
+  }
+
   std::string GetStringForAuthenticationMethod() const {
     switch (GetAuthenticationMethod()) {
       case payments::MandatoryReauthAuthenticationMethod::kUnsupportedMethod:
@@ -673,19 +701,11 @@
         return "";
     }
   }
-
- private:
-  payments::MockMandatoryReauthManager& mandatory_reauth_manager() {
-    return *static_cast<payments::MockMandatoryReauthManager*>(
-        autofill_client_.GetOrCreatePaymentsMandatoryReauthManager());
-  }
-
-  base::test::ScopedFeatureList feature_list_;
 };
 
 // Tests that retrieving local cards works correctly in the context of the
 // Mandatory Re-Auth feature.
-TEST_P(CreditCardAccessManagerMandatoryReauthTest,
+TEST_P(CreditCardAccessManagerMandatoryReauthFunctionalTest,
        MandatoryReauth_FetchLocalCard) {
   base::HistogramTester histogram_tester;
   CreateLocalCard(kTestGUID, kTestNumber);
@@ -696,7 +716,7 @@
   WaitForCallbacks();
 
   // TODO(crbug/1489440): Extract shared boilerplate code out for
-  // CreditCardAccessManagerMandatoryReauthTest tests.
+  // CreditCardAccessManagerMandatoryReauthFunctionalTest tests.
   SetUpDeviceAuthenticatorResponseMock();
   credit_card_access_manager().FetchCreditCard(
       card, base::BindOnce(&TestAccessor::OnCreditCardFetched,
@@ -755,7 +775,7 @@
 
 // Tests that retrieving virtual cards works correctly in the context of the
 // Mandatory Re-Auth feature.
-TEST_P(CreditCardAccessManagerMandatoryReauthTest,
+TEST_P(CreditCardAccessManagerMandatoryReauthFunctionalTest,
        MandatoryReauth_FetchVirtualCard) {
   base::HistogramTester histogram_tester;
   CreateServerCard(kTestGUID, kTestNumber, /*masked=*/false, kTestServerId);
@@ -779,7 +799,7 @@
   response.card_type = AutofillClient::PaymentsRpcCardType::kVirtualCard;
 
   // TODO(crbug/1489440): Extract shared boilerplate code out for
-  // CreditCardAccessManagerMandatoryReauthTest tests.
+  // CreditCardAccessManagerMandatoryReauthFunctionalTest tests.
   SetUpDeviceAuthenticatorResponseMock();
   credit_card_access_manager()
       .OnVirtualCardRiskBasedAuthenticationResponseReceived(
@@ -815,6 +835,10 @@
                     kFlowFailed,
           1);
       histogram_tester.ExpectUniqueSample(
+          "Autofill.CvcStorage.CvcFilling.VirtualCard",
+          autofill_metrics::CvcFillingFlowType::kMandatoryReauth,
+          MandatoryReauthResponseIsSuccess() ? 1 : 0);
+      histogram_tester.ExpectUniqueSample(
           "Autofill.ServerCardUnmask.VirtualCard.Result.DeviceUnlock",
           MandatoryReauthResponseIsSuccess()
               ? autofill_metrics::ServerCardUnmaskResult::
@@ -838,7 +862,7 @@
 
 // Tests that retrieving masked server cards triggers mandatory reauth (if
 // applicable) when risk-based auth returned the card.
-TEST_P(CreditCardAccessManagerMandatoryReauthTest,
+TEST_P(CreditCardAccessManagerMandatoryReauthFunctionalTest,
        MandatoryReauth_FetchMaskedServerCard) {
   std::string test_number = "4444333322221111";
   base::HistogramTester histogram_tester;
@@ -860,7 +884,7 @@
   card.set_record_type(CreditCard::RecordType::kFullServerCard);
 
   // TODO(crbug/1489440): Extract shared boilerplate code out for
-  // CreditCardAccessManagerMandatoryReauthTest tests.
+  // CreditCardAccessManagerMandatoryReauthFunctionalTest tests.
   SetUpDeviceAuthenticatorResponseMock();
   credit_card_access_manager().OnRiskBasedAuthenticationResponseReceived(
       CreditCardRiskBasedAuthenticator::RiskBasedAuthenticationResponse()
@@ -919,7 +943,7 @@
 
 INSTANTIATE_TEST_SUITE_P(
     ,
-    CreditCardAccessManagerMandatoryReauthTest,
+    CreditCardAccessManagerMandatoryReauthFunctionalTest,
     testing::Combine(
         testing::Bool(),
         testing::Bool(),
@@ -930,6 +954,157 @@
 #endif
             payments::MandatoryReauthAuthenticationMethod::kBiometric,
             payments::MandatoryReauthAuthenticationMethod::kScreenLock)));
+
+// Test suite built for testing mandatory re-auth's functionality as an
+// integration with other projects.
+// -- bool mandatory_reauth_response_is_success: Whether or not the re-auth
+// authentication was successful.
+class CreditCardAccessManagerMandatoryReauthIntegrationTest
+    : public CreditCardAccessManagerMandatoryReauthTest,
+      public testing::WithParamInterface<bool> {
+ public:
+  CreditCardAccessManagerMandatoryReauthIntegrationTest() = default;
+  ~CreditCardAccessManagerMandatoryReauthIntegrationTest() override = default;
+
+ protected:
+  bool FeatureFlagIsOn() const override { return true; }
+
+  bool PrefIsEnabled() const override { return true; }
+
+  bool MandatoryReauthResponseIsSuccess() const override { return GetParam(); }
+
+  bool HasAuthenticator() const override { return true; }
+
+  payments::MandatoryReauthAuthenticationMethod GetAuthenticationMethod()
+      const override {
+    return payments::MandatoryReauthAuthenticationMethod::kBiometric;
+  }
+};
+
+// Tests that when retrieving local cards with a CVC stored, the CVC is filled.
+// This test is in the context of the Mandatory Re-Auth feature.
+TEST_P(CreditCardAccessManagerMandatoryReauthIntegrationTest,
+       MandatoryReauth_FetchLocalCard_CvcFillWorksCorrectly) {
+  base::HistogramTester histogram_tester;
+  CreateLocalCard(kTestGUID, kTestNumber);
+  CreditCard* card = personal_data().GetCreditCardByGUID(kTestGUID);
+
+  credit_card_access_manager().PrepareToFetchCreditCard();
+  WaitForCallbacks();
+
+  // TODO(crbug/1489440): Extract shared boilerplate code out for
+  // CreditCardAccessManagerMandatoryReauthTest tests.
+  SetUpDeviceAuthenticatorResponseMock();
+  credit_card_access_manager().FetchCreditCard(
+      card, base::BindOnce(&TestAccessor::OnCreditCardFetched,
+                           accessor_->GetWeakPtr()));
+
+  EXPECT_EQ(accessor_->cvc(),
+            MandatoryReauthResponseIsSuccess() ? kTestCvc16 : u"");
+  histogram_tester.ExpectBucketCount(
+      "Autofill.CvcStorage.CvcFilling.LocalCard",
+      autofill_metrics::CvcFillingFlowType::kMandatoryReauth,
+      MandatoryReauthResponseIsSuccess() ? 1 : 0);
+}
+
+// Tests that when retrieving local cards without a CVC stored, the CVC is not
+// filled. This test is in the context of the Mandatory Re-Auth feature.
+TEST_P(CreditCardAccessManagerMandatoryReauthIntegrationTest,
+       MandatoryReauth_FetchLocalCard_NoCvcFillWorksCorrectly) {
+  base::HistogramTester histogram_tester;
+  CreateLocalCard(kTestGUID, kTestNumber);
+  CreditCard* card = personal_data().GetCreditCardByGUID(kTestGUID);
+  card->set_cvc(u"");
+
+  credit_card_access_manager().PrepareToFetchCreditCard();
+  WaitForCallbacks();
+
+  // TODO(crbug/1489440): Extract shared boilerplate code out for
+  // CreditCardAccessManagerMandatoryReauthTest tests.
+  SetUpDeviceAuthenticatorResponseMock();
+  credit_card_access_manager().FetchCreditCard(
+      card, base::BindOnce(&TestAccessor::OnCreditCardFetched,
+                           accessor_->GetWeakPtr()));
+
+  EXPECT_EQ(accessor_->cvc(), u"");
+  histogram_tester.ExpectBucketCount(
+      "Autofill.CvcStorage.CvcFilling.LocalCard",
+      autofill_metrics::CvcFillingFlowType::kMandatoryReauth, 0);
+}
+
+// Tests that when retrieving masked server cards with a CVC stored, the CVC is
+// filled.  This test is in the context of the Mandatory Re-Auth feature.
+TEST_P(CreditCardAccessManagerMandatoryReauthIntegrationTest,
+       MandatoryReauth_FetchMaskedServerCard_CvcFillWorksCorrectly) {
+  base::HistogramTester histogram_tester;
+  std::string test_number = "4444333322221111";
+  CreateServerCard(kTestGUID, test_number, /*masked=*/true, kTestServerId);
+  CreditCard* masked_server_card =
+      personal_data().GetCreditCardByGUID(kTestGUID);
+
+  credit_card_access_manager().PrepareToFetchCreditCard();
+  WaitForCallbacks();
+
+  credit_card_access_manager().FetchCreditCard(
+      masked_server_card, base::BindOnce(&TestAccessor::OnCreditCardFetched,
+                                         accessor_->GetWeakPtr()));
+
+  // TODO(crbug/1489440): Extract shared boilerplate code out for
+  // CreditCardAccessManagerMandatoryReauthTest tests.
+  SetUpDeviceAuthenticatorResponseMock();
+  credit_card_access_manager().OnRiskBasedAuthenticationResponseReceived(
+      CreditCardRiskBasedAuthenticator::RiskBasedAuthenticationResponse()
+          .with_result(CreditCardRiskBasedAuthenticator::
+                           RiskBasedAuthenticationResponse::Result::
+                               kNoAuthenticationRequired)
+          .with_card(*masked_server_card));
+
+  EXPECT_EQ(accessor_->cvc(),
+            MandatoryReauthResponseIsSuccess() ? kTestCvc16 : u"");
+  histogram_tester.ExpectBucketCount(
+      "Autofill.CvcStorage.CvcFilling.ServerCard",
+      autofill_metrics::CvcFillingFlowType::kMandatoryReauth,
+      MandatoryReauthResponseIsSuccess() ? 1 : 0);
+}
+
+// Tests that when retrieving masked server cards without a CVC stored, the CVC
+// is not filled. This test is in the context of the Mandatory Re-Auth feature.
+TEST_P(CreditCardAccessManagerMandatoryReauthIntegrationTest,
+       MandatoryReauth_FetchMaskedServerCard_NoCvcFillWorksCorrectly) {
+  base::HistogramTester histogram_tester;
+  std::string test_number = "4444333322221111";
+  CreateServerCard(kTestGUID, test_number, /*masked=*/true, kTestServerId);
+  CreditCard* masked_server_card =
+      personal_data().GetCreditCardByGUID(kTestGUID);
+  masked_server_card->set_cvc(u"");
+
+  credit_card_access_manager().PrepareToFetchCreditCard();
+  WaitForCallbacks();
+
+  credit_card_access_manager().FetchCreditCard(
+      masked_server_card, base::BindOnce(&TestAccessor::OnCreditCardFetched,
+                                         accessor_->GetWeakPtr()));
+
+  // TODO(crbug/1489440): Extract shared boilerplate code out for
+  // CreditCardAccessManagerMandatoryReauthTest tests.
+  SetUpDeviceAuthenticatorResponseMock();
+  credit_card_access_manager().OnRiskBasedAuthenticationResponseReceived(
+      CreditCardRiskBasedAuthenticator::RiskBasedAuthenticationResponse()
+          .with_result(CreditCardRiskBasedAuthenticator::
+                           RiskBasedAuthenticationResponse::Result::
+                               kNoAuthenticationRequired)
+          .with_card(*masked_server_card));
+
+  EXPECT_EQ(accessor_->cvc(), u"");
+  histogram_tester.ExpectBucketCount(
+      "Autofill.CvcStorage.CvcFilling.ServerCard",
+      autofill_metrics::CvcFillingFlowType::kMandatoryReauth, 0);
+}
+
+INSTANTIATE_TEST_SUITE_P(,
+                         CreditCardAccessManagerMandatoryReauthIntegrationTest,
+                         testing::Bool());
+
 #endif  // BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) ||
         // BUILDFLAG(IS_IOS)
 
diff --git a/components/autofill/core/browser/payments/iban_access_manager.cc b/components/autofill/core/browser/payments/iban_access_manager.cc
index d51db8b..a33a593 100644
--- a/components/autofill/core/browser/payments/iban_access_manager.cc
+++ b/components/autofill/core/browser/payments/iban_access_manager.cc
@@ -4,6 +4,7 @@
 
 #include "components/autofill/core/browser/payments/iban_access_manager.h"
 
+#include "components/autofill/core/browser/metrics/payments/iban_metrics.h"
 #include "components/autofill/core/browser/payments/autofill_error_dialog_context.h"
 #include "components/autofill/core/browser/payments/payments_network_interface.h"
 #include "components/autofill/core/browser/payments/payments_util.h"
@@ -54,20 +55,25 @@
       payments::GetBillingCustomerId(client_->GetPersonalDataManager());
   request_details.instrument_id =
       suggestion.GetBackendId<Suggestion::InstrumentId>().value();
+  base::TimeTicks unmask_request_timestamp = AutofillTickClock::NowTicks();
   client_->GetPaymentsNetworkInterface()->UnmaskIban(
       request_details,
       base::BindOnce(&IbanAccessManager::OnUnmaskResponseReceived,
-                     weak_ptr_factory_.GetWeakPtr(),
-                     std::move(on_iban_fetched)));
+                     weak_ptr_factory_.GetWeakPtr(), std::move(on_iban_fetched),
+                     unmask_request_timestamp));
 }
 
 void IbanAccessManager::OnUnmaskResponseReceived(
     OnIbanFetchedCallback on_iban_fetched,
+    base::TimeTicks unmask_request_timestamp,
     AutofillClient::PaymentsRpcResult result,
     const std::u16string& value) {
   client_->CloseAutofillProgressDialog(
       /*show_confirmation_before_closing=*/false);
-  if (result == AutofillClient::PaymentsRpcResult::kSuccess && !value.empty()) {
+  bool is_successful = result == AutofillClient::PaymentsRpcResult::kSuccess;
+  autofill_metrics::LogServerIbanUnmaskLatency(
+      AutofillTickClock::NowTicks() - unmask_request_timestamp, is_successful);
+  if (is_successful) {
     std::move(on_iban_fetched).Run(value);
     return;
   }
diff --git a/components/autofill/core/browser/payments/iban_access_manager.h b/components/autofill/core/browser/payments/iban_access_manager.h
index c55a16b..062b9bc 100644
--- a/components/autofill/core/browser/payments/iban_access_manager.h
+++ b/components/autofill/core/browser/payments/iban_access_manager.h
@@ -10,6 +10,7 @@
 #include "base/functional/callback_forward.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
+#include "base/time/time.h"
 #include "components/autofill/core/browser/autofill_client.h"
 
 namespace autofill {
@@ -45,6 +46,7 @@
   // Called when an UnmaskIban call is completed. The full IBAN value will be
   // returned via `value`.
   void OnUnmaskResponseReceived(OnIbanFetchedCallback on_iban_fetched,
+                                base::TimeTicks unmask_request_timestamp,
                                 AutofillClient::PaymentsRpcResult result,
                                 const std::u16string& value);
 
diff --git a/components/autofill/core/browser/payments/iban_access_manager_unittest.cc b/components/autofill/core/browser/payments/iban_access_manager_unittest.cc
index 1abacdc7..0f4e2b6 100644
--- a/components/autofill/core/browser/payments/iban_access_manager_unittest.cc
+++ b/components/autofill/core/browser/payments/iban_access_manager_unittest.cc
@@ -4,14 +4,17 @@
 
 #include "components/autofill/core/browser/payments/iban_access_manager.h"
 
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/mock_callback.h"
 #include "base/test/task_environment.h"
 #include "components/autofill/core/browser/autofill_test_utils.h"
 #include "components/autofill/core/browser/payments/mock_test_payments_network_interface.h"
 #include "components/autofill/core/browser/test_autofill_client.h"
+#include "components/autofill/core/browser/test_autofill_tick_clock.h"
 #include "components/autofill/core/browser/test_personal_data_manager.h"
 #include "components/autofill/core/browser/ui/popup_item_ids.h"
 #include "components/autofill/core/browser/ui/suggestion.h"
+#include "components/autofill/core/common/autofill_tick_clock.h"
 #include "components/sync/test/test_sync_service.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -22,6 +25,7 @@
 
 constexpr char16_t kFullIbanValue[] = u"CH5604835012345678009";
 constexpr int64_t kInstrumentId = 12345678;
+constexpr int kDefaultUnmaskIbanLatencyMs = 200;
 
 }  // namespace
 
@@ -48,14 +52,17 @@
         std::make_unique<IbanAccessManager>(&autofill_client_);
   }
 
-  void SetUpUnmaskIbanCall(bool is_successful, const std::u16string& value) {
+  void SetUpUnmaskIbanCall(bool is_successful,
+                           const std::u16string& value,
+                           int latency_ms = 0) {
     ON_CALL(*payments_network_interface(), UnmaskIban)
         .WillByDefault(
-            [is_successful, value](
+            [=, this](
                 const payments::PaymentsNetworkInterface::
                     UnmaskIbanRequestDetails&,
                 base::OnceCallback<void(AutofillClient::PaymentsRpcResult,
                                         const std::u16string&)> callback) {
+              test_clock_.Advance(base::Milliseconds(latency_ms));
               std::move(callback).Run(
                   is_successful
                       ? AutofillClient::PaymentsRpcResult::kSuccess
@@ -79,6 +86,7 @@
   test::AutofillUnitTestEnvironment autofill_test_environment_;
   syncer::TestSyncService sync_service_;
   TestAutofillClient autofill_client_;
+  TestAutofillTickClock test_clock_;
   std::unique_ptr<IbanAccessManager> iban_access_manager_;
 };
 
@@ -155,24 +163,6 @@
   EXPECT_CALL(*payments_network_interface(), UnmaskIban).Times(0);
 }
 
-// Verify that a failed `UnmaskIban` call results in the method `OnIbanFetched`
-// not being called.
-TEST_F(IbanAccessManagerTest, ServerIban_BackendId_SuccessButEmptyValue) {
-  SetUpUnmaskIbanCall(/*is_successful=*/true, /*value=*/u"");
-
-  Iban server_iban = test::GetServerIban();
-  server_iban.set_identifier(Iban::InstrumentId(kInstrumentId));
-  personal_data().AddServerIban(server_iban);
-  Suggestion suggestion(PopupItemId::kIbanEntry);
-  suggestion.payload = Suggestion::InstrumentId(kInstrumentId);
-
-  base::MockCallback<IbanAccessManager::OnIbanFetchedCallback> callback;
-  EXPECT_CALL(callback, Run).Times(0);
-  iban_access_manager_->FetchValue(suggestion, callback.Get());
-
-  EXPECT_CALL(*payments_network_interface(), UnmaskIban).Times(0);
-}
-
 // Verify that there will be no progress dialog when unmasking a local IBAN.
 TEST_F(IbanAccessManagerTest, FetchValue_LocalIbanNoProgressDialog) {
   Suggestion suggestion(PopupItemId::kIbanEntry);
@@ -219,4 +209,49 @@
   EXPECT_TRUE(autofill_client_.autofill_error_dialog_shown());
 }
 
+// Verify that the duration of successful `UnmaskIban` call is logged correctly.
+TEST_F(IbanAccessManagerTest, UnmaskServerIban_Success_Metric) {
+  base::HistogramTester histogram_tester;
+  test_clock_.SetNowTicks(AutofillTickClock::NowTicks());
+  SetUpUnmaskIbanCall(/*is_successful=*/true, /*value=*/kFullIbanValue,
+                      /*latency_ms=*/kDefaultUnmaskIbanLatencyMs);
+
+  Iban server_iban = test::GetServerIban();
+  server_iban.set_identifier(Iban::InstrumentId(kInstrumentId));
+  personal_data().AddServerIban(server_iban);
+  Suggestion suggestion(PopupItemId::kIbanEntry);
+  suggestion.payload = Suggestion::InstrumentId(kInstrumentId);
+
+  base::MockCallback<IbanAccessManager::OnIbanFetchedCallback> callback;
+  iban_access_manager_->FetchValue(suggestion, callback.Get());
+
+  histogram_tester.ExpectUniqueSample(
+      "Autofill.Iban.UnmaskIbanDuration.Success", kDefaultUnmaskIbanLatencyMs,
+      1);
+  histogram_tester.ExpectUniqueSample("Autofill.Iban.UnmaskIbanDuration",
+                                      kDefaultUnmaskIbanLatencyMs, 1);
+}
+
+// Verify that duration of failed `UnmaskIban` call is logged correctly.
+TEST_F(IbanAccessManagerTest, UnmaskServerIban_Failure_Metric) {
+  base::HistogramTester histogram_tester;
+  test_clock_.SetNowTicks(AutofillTickClock::NowTicks());
+  SetUpUnmaskIbanCall(/*is_successful=*/false, /*value=*/kFullIbanValue,
+                      /*latency_ms=*/kDefaultUnmaskIbanLatencyMs);
+
+  Iban server_iban = test::GetServerIban();
+  server_iban.set_identifier(Iban::InstrumentId(kInstrumentId));
+  personal_data().AddServerIban(server_iban);
+  Suggestion suggestion(PopupItemId::kIbanEntry);
+  suggestion.payload = Suggestion::InstrumentId(kInstrumentId);
+
+  iban_access_manager_->FetchValue(suggestion, base::DoNothing());
+
+  histogram_tester.ExpectUniqueSample(
+      "Autofill.Iban.UnmaskIbanDuration.Failure", kDefaultUnmaskIbanLatencyMs,
+      1);
+  histogram_tester.ExpectUniqueSample("Autofill.Iban.UnmaskIbanDuration",
+                                      kDefaultUnmaskIbanLatencyMs, 1);
+}
+
 }  // namespace autofill
diff --git a/components/autofill/core/browser/webdata/autocomplete_sync_bridge.cc b/components/autofill/core/browser/webdata/autocomplete_sync_bridge.cc
index 0f7939c..137f4e01 100644
--- a/components/autofill/core/browser/webdata/autocomplete_sync_bridge.cc
+++ b/components/autofill/core/browser/webdata/autocomplete_sync_bridge.cc
@@ -19,8 +19,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
 #include "components/autofill/core/browser/proto/autofill_sync.pb.h"
-#include "components/autofill/core/browser/webdata/autocomplete_table.h"
-#include "components/autofill/core/browser/webdata/autofill_table.h"
+#include "components/autofill/core/browser/webdata/autofill_sync_metadata_table.h"
 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
 #include "components/sync/model/client_tag_based_model_type_processor.h"
 #include "components/sync/model/model_type_change_processor.h"
@@ -528,8 +527,9 @@
   return AutocompleteTable::FromWebDatabase(web_data_backend_->GetDatabase());
 }
 
-AutofillTable* AutocompleteSyncBridge::GetSyncMetadataStore() {
-  return AutofillTable::FromWebDatabase(web_data_backend_->GetDatabase());
+AutofillSyncMetadataTable* AutocompleteSyncBridge::GetSyncMetadataStore() {
+  return AutofillSyncMetadataTable::FromWebDatabase(
+      web_data_backend_->GetDatabase());
 }
 
 }  // namespace autofill
diff --git a/components/autofill/core/browser/webdata/autocomplete_sync_bridge.h b/components/autofill/core/browser/webdata/autocomplete_sync_bridge.h
index 2c74f0fe..1c7baccb 100644
--- a/components/autofill/core/browser/webdata/autocomplete_sync_bridge.h
+++ b/components/autofill/core/browser/webdata/autocomplete_sync_bridge.h
@@ -24,7 +24,7 @@
 
 namespace autofill {
 
-class AutofillTable;
+class AutofillSyncMetadataTable;
 class AutofillWebDataService;
 
 class AutocompleteSyncBridge
@@ -71,9 +71,7 @@
   // Returns the table associated with the |web_data_backend_|.
   AutocompleteTable* GetAutocompleteTable();
 
-  // AutofillTable acts as the metadata storage for all components/autofill-
-  // related sync code.
-  AutofillTable* GetSyncMetadataStore();
+  AutofillSyncMetadataTable* GetSyncMetadataStore();
 
   // Respond to local autocomplete entries changing by notifying sync of the
   // changes.
diff --git a/components/autofill/core/browser/webdata/autocomplete_sync_bridge_unittest.cc b/components/autofill/core/browser/webdata/autocomplete_sync_bridge_unittest.cc
index ab29d61..b0e6a82 100644
--- a/components/autofill/core/browser/webdata/autocomplete_sync_bridge_unittest.cc
+++ b/components/autofill/core/browser/webdata/autocomplete_sync_bridge_unittest.cc
@@ -21,7 +21,7 @@
 #include "base/time/time.h"
 #include "components/autofill/core/browser/webdata/autocomplete_entry.h"
 #include "components/autofill/core/browser/webdata/autocomplete_table.h"
-#include "components/autofill/core/browser/webdata/autofill_table.h"
+#include "components/autofill/core/browser/webdata/autofill_sync_metadata_table.h"
 #include "components/autofill/core/browser/webdata/mock_autofill_webdata_backend.h"
 #include "components/sync/base/client_tag_hash.h"
 #include "components/sync/base/model_type.h"
@@ -304,7 +304,9 @@
   }
 
   AutocompleteTable* table() { return &table_; }
-  AutofillTable* sync_metadata_table() { return &sync_metadata_table_; }
+  AutofillSyncMetadataTable* sync_metadata_table() {
+    return &sync_metadata_table_;
+  }
 
   MockAutofillWebDataBackend* backend() { return &backend_; }
 
@@ -313,7 +315,7 @@
   base::test::SingleThreadTaskEnvironment task_environment_;
   testing::NiceMock<MockAutofillWebDataBackend> backend_;
   AutocompleteTable table_;
-  AutofillTable sync_metadata_table_;
+  AutofillSyncMetadataTable sync_metadata_table_;
   WebDatabase db_;
   std::unique_ptr<AutocompleteSyncBridge> bridge_;
   testing::NiceMock<MockModelTypeChangeProcessor> mock_processor_;
diff --git a/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.cc b/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.cc
index 67c930a..f7ab88f 100644
--- a/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.cc
+++ b/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.cc
@@ -17,7 +17,7 @@
 #include "components/autofill/core/browser/proto/autofill_sync.pb.h"
 #include "components/autofill/core/browser/webdata/addresses/address_autofill_table.h"
 #include "components/autofill/core/browser/webdata/autofill_profile_sync_difference_tracker.h"
-#include "components/autofill/core/browser/webdata/autofill_table.h"
+#include "components/autofill/core/browser/webdata/autofill_sync_metadata_table.h"
 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
 #include "components/sync/model/client_tag_based_model_type_processor.h"
 #include "components/sync/model/metadata_change_list.h"
@@ -304,8 +304,9 @@
       web_data_backend_->GetDatabase());
 }
 
-AutofillTable* AutofillProfileSyncBridge::GetSyncMetadataStore() {
-  return AutofillTable::FromWebDatabase(web_data_backend_->GetDatabase());
+AutofillSyncMetadataTable* AutofillProfileSyncBridge::GetSyncMetadataStore() {
+  return AutofillSyncMetadataTable::FromWebDatabase(
+      web_data_backend_->GetDatabase());
 }
 
 }  // namespace autofill
diff --git a/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.h b/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.h
index 8204d74..33ca4c90 100644
--- a/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.h
+++ b/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.h
@@ -28,7 +28,7 @@
 
 class AddressAutofillTable;
 class AutofillProfileSyncDifferenceTracker;
-class AutofillTable;
+class AutofillSyncMetadataTable;
 class AutofillWebDataService;
 enum class AutofillProfileSyncChangeOrigin;
 
@@ -90,9 +90,7 @@
   // Returns the table associated with the |web_data_backend_|.
   AddressAutofillTable* GetAutofillTable();
 
-  // AutofillTable acts as the metadata storage for all components/autofill-
-  // related sync code.
-  AutofillTable* GetSyncMetadataStore();
+  AutofillSyncMetadataTable* GetSyncMetadataStore();
 
   // Respond to local autofill profile entry changing by notifying sync of the
   // changes.
diff --git a/components/autofill/core/browser/webdata/autofill_profile_sync_bridge_unittest.cc b/components/autofill/core/browser/webdata/autofill_profile_sync_bridge_unittest.cc
index 7e7d4790..0d71d02 100644
--- a/components/autofill/core/browser/webdata/autofill_profile_sync_bridge_unittest.cc
+++ b/components/autofill/core/browser/webdata/autofill_profile_sync_bridge_unittest.cc
@@ -27,7 +27,7 @@
 #include "components/autofill/core/browser/test_autofill_clock.h"
 #include "components/autofill/core/browser/webdata/addresses/address_autofill_table.h"
 #include "components/autofill/core/browser/webdata/autofill_change.h"
-#include "components/autofill/core/browser/webdata/autofill_table.h"
+#include "components/autofill/core/browser/webdata/autofill_sync_metadata_table.h"
 #include "components/autofill/core/browser/webdata/mock_autofill_webdata_backend.h"
 #include "components/autofill/core/common/autofill_constants.h"
 #include "components/autofill/core/common/autofill_features.h"
@@ -373,7 +373,7 @@
   base::test::SingleThreadTaskEnvironment task_environment_;
   testing::NiceMock<MockAutofillWebDataBackend> backend_;
   AddressAutofillTable table_;
-  AutofillTable sync_metadata_table_;
+  AutofillSyncMetadataTable sync_metadata_table_;
   WebDatabase db_;
   testing::NiceMock<MockModelTypeChangeProcessor> mock_processor_;
   std::unique_ptr<syncer::ClientTagBasedModelTypeProcessor> real_processor_;
diff --git a/components/autofill/core/browser/webdata/autofill_sync_metadata_table.cc b/components/autofill/core/browser/webdata/autofill_sync_metadata_table.cc
new file mode 100644
index 0000000..8afb0fd3b
--- /dev/null
+++ b/components/autofill/core/browser/webdata/autofill_sync_metadata_table.cc
@@ -0,0 +1,230 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/webdata/autofill_sync_metadata_table.h"
+
+#include "components/autofill/core/browser/webdata/autofill_table_utils.h"
+#include "components/sync/base/model_type.h"
+#include "components/sync/model/metadata_batch.h"
+#include "components/sync/protocol/entity_metadata.pb.h"
+#include "components/sync/protocol/model_type_state.pb.h"
+#include "components/webdata/common/web_database.h"
+#include "sql/statement.h"
+
+namespace autofill {
+
+namespace {
+
+constexpr std::string_view kAutofillSyncMetadataTable =
+    "autofill_sync_metadata";
+constexpr std::string_view kModelType = "model_type";
+constexpr std::string_view kStorageKey = "storage_key";
+constexpr std::string_view kValue = "value";
+
+constexpr std::string_view kAutofillModelTypeStateTable =
+    "autofill_model_type_state";
+// kModelType = "model_type"
+// kValue = "value"
+
+WebDatabaseTable::TypeKey GetKey() {
+  // We just need a unique constant. Use the address of a static that
+  // COMDAT folding won't touch in an optimizing linker.
+  static int table_key = 0;
+  return reinterpret_cast<void*>(&table_key);
+}
+
+}  // namespace
+
+AutofillSyncMetadataTable::AutofillSyncMetadataTable() = default;
+
+AutofillSyncMetadataTable::~AutofillSyncMetadataTable() = default;
+
+// static
+AutofillSyncMetadataTable* AutofillSyncMetadataTable::FromWebDatabase(
+    WebDatabase* db) {
+  return static_cast<AutofillSyncMetadataTable*>(db->GetTable(GetKey()));
+}
+
+WebDatabaseTable::TypeKey AutofillSyncMetadataTable::GetTypeKey() const {
+  return GetKey();
+}
+
+bool AutofillSyncMetadataTable::CreateTablesIfNecessary() {
+  return InitAutofillSyncMetadataTable() && InitModelTypeStateTable();
+}
+
+bool AutofillSyncMetadataTable::MigrateToVersion(
+    int version,
+    bool* update_compatible_version) {
+  if (!db_->is_open()) {
+    return false;
+  }
+  return true;
+}
+
+bool AutofillSyncMetadataTable::GetAllSyncMetadata(
+    syncer::ModelType model_type,
+    syncer::MetadataBatch* metadata_batch) {
+  DCHECK(SupportsMetadataForModelType(model_type))
+      << "Model type " << model_type << " not supported for metadata";
+  DCHECK(metadata_batch);
+  if (!GetAllSyncEntityMetadata(model_type, metadata_batch)) {
+    return false;
+  }
+
+  sync_pb::ModelTypeState model_type_state;
+  if (!GetModelTypeState(model_type, &model_type_state)) {
+    return false;
+  }
+
+  metadata_batch->SetModelTypeState(model_type_state);
+  return true;
+}
+
+bool AutofillSyncMetadataTable::DeleteAllSyncMetadata(
+    syncer::ModelType model_type) {
+  return DeleteWhereColumnEq(db_, kAutofillSyncMetadataTable, kModelType,
+                             GetKeyValueForModelType(model_type));
+}
+
+bool AutofillSyncMetadataTable::UpdateEntityMetadata(
+    syncer::ModelType model_type,
+    const std::string& storage_key,
+    const sync_pb::EntityMetadata& metadata) {
+  DCHECK(SupportsMetadataForModelType(model_type))
+      << "Model type " << model_type << " not supported for metadata";
+
+  sql::Statement s;
+  InsertBuilder(db_, s, kAutofillSyncMetadataTable,
+                {kModelType, kStorageKey, kValue},
+                /*or_replace=*/true);
+  s.BindInt(0, GetKeyValueForModelType(model_type));
+  s.BindString(1, storage_key);
+  s.BindString(2, metadata.SerializeAsString());
+
+  return s.Run();
+}
+
+bool AutofillSyncMetadataTable::ClearEntityMetadata(
+    syncer::ModelType model_type,
+    const std::string& storage_key) {
+  DCHECK(SupportsMetadataForModelType(model_type))
+      << "Model type " << model_type << " not supported for metadata";
+
+  sql::Statement s;
+  DeleteBuilder(db_, s, kAutofillSyncMetadataTable,
+                "model_type=? AND storage_key=?");
+  s.BindInt(0, GetKeyValueForModelType(model_type));
+  s.BindString(1, storage_key);
+
+  return s.Run();
+}
+
+bool AutofillSyncMetadataTable::UpdateModelTypeState(
+    syncer::ModelType model_type,
+    const sync_pb::ModelTypeState& model_type_state) {
+  DCHECK(SupportsMetadataForModelType(model_type))
+      << "Model type " << model_type << " not supported for metadata";
+
+  // Hardcode the id to force a collision, ensuring that there remains only a
+  // single entry.
+  sql::Statement s;
+  InsertBuilder(db_, s, kAutofillModelTypeStateTable, {kModelType, kValue},
+                /*or_replace=*/true);
+  s.BindInt(0, GetKeyValueForModelType(model_type));
+  s.BindString(1, model_type_state.SerializeAsString());
+
+  return s.Run();
+}
+
+bool AutofillSyncMetadataTable::ClearModelTypeState(
+    syncer::ModelType model_type) {
+  DCHECK(SupportsMetadataForModelType(model_type))
+      << "Model type " << model_type << " not supported for metadata";
+
+  sql::Statement s;
+  DeleteBuilder(db_, s, kAutofillModelTypeStateTable, "model_type=?");
+  s.BindInt(0, GetKeyValueForModelType(model_type));
+
+  return s.Run();
+}
+
+bool AutofillSyncMetadataTable::SupportsMetadataForModelType(
+    syncer::ModelType model_type) const {
+  return (model_type == syncer::AUTOFILL ||
+          model_type == syncer::AUTOFILL_PROFILE ||
+          model_type == syncer::AUTOFILL_WALLET_CREDENTIAL ||
+          model_type == syncer::AUTOFILL_WALLET_DATA ||
+          model_type == syncer::AUTOFILL_WALLET_METADATA ||
+          model_type == syncer::AUTOFILL_WALLET_OFFER ||
+          model_type == syncer::AUTOFILL_WALLET_USAGE ||
+          model_type == syncer::CONTACT_INFO);
+}
+
+int AutofillSyncMetadataTable::GetKeyValueForModelType(
+    syncer::ModelType model_type) const {
+  return syncer::ModelTypeToStableIdentifier(model_type);
+}
+
+bool AutofillSyncMetadataTable::GetAllSyncEntityMetadata(
+    syncer::ModelType model_type,
+    syncer::MetadataBatch* metadata_batch) {
+  DCHECK(SupportsMetadataForModelType(model_type))
+      << "Model type " << model_type << " not supported for metadata";
+  DCHECK(metadata_batch);
+
+  sql::Statement s;
+  SelectBuilder(db_, s, kAutofillSyncMetadataTable, {kStorageKey, kValue},
+                "WHERE model_type=?");
+  s.BindInt(0, GetKeyValueForModelType(model_type));
+
+  while (s.Step()) {
+    std::string storage_key = s.ColumnString(0);
+    std::string serialized_metadata = s.ColumnString(1);
+    auto entity_metadata = std::make_unique<sync_pb::EntityMetadata>();
+    if (entity_metadata->ParseFromString(serialized_metadata)) {
+      metadata_batch->AddMetadata(storage_key, std::move(entity_metadata));
+    } else {
+      DLOG(WARNING) << "Failed to deserialize AUTOFILL model type "
+                       "sync_pb::EntityMetadata.";
+      return false;
+    }
+  }
+  return true;
+}
+
+bool AutofillSyncMetadataTable::GetModelTypeState(
+    syncer::ModelType model_type,
+    sync_pb::ModelTypeState* state) {
+  DCHECK(SupportsMetadataForModelType(model_type))
+      << "Model type " << model_type << " not supported for metadata";
+
+  sql::Statement s;
+  SelectBuilder(db_, s, kAutofillModelTypeStateTable, {kValue},
+                "WHERE model_type=?");
+  s.BindInt(0, GetKeyValueForModelType(model_type));
+
+  if (!s.Step()) {
+    return true;
+  }
+
+  std::string serialized_state = s.ColumnString(0);
+  return state->ParseFromString(serialized_state);
+}
+
+bool AutofillSyncMetadataTable::InitAutofillSyncMetadataTable() {
+  return CreateTableIfNotExists(db_, kAutofillSyncMetadataTable,
+                                {{kModelType, "INTEGER NOT NULL"},
+                                 {kStorageKey, "VARCHAR NOT NULL"},
+                                 {kValue, "BLOB"}},
+                                {kModelType, kStorageKey});
+}
+
+bool AutofillSyncMetadataTable::InitModelTypeStateTable() {
+  return CreateTableIfNotExists(
+      db_, kAutofillModelTypeStateTable,
+      {{kModelType, "INTEGER NOT NULL PRIMARY KEY"}, {kValue, "BLOB"}});
+}
+
+}  // namespace autofill
diff --git a/components/autofill/core/browser/webdata/autofill_sync_metadata_table.h b/components/autofill/core/browser/webdata/autofill_sync_metadata_table.h
new file mode 100644
index 0000000..3b14de8
--- /dev/null
+++ b/components/autofill/core/browser/webdata/autofill_sync_metadata_table.h
@@ -0,0 +1,96 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_AUTOFILL_SYNC_METADATA_TABLE_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_AUTOFILL_SYNC_METADATA_TABLE_H_
+
+#include "components/sync/base/model_type.h"
+#include "components/sync/model/sync_metadata_store.h"
+#include "components/webdata/common/web_database_table.h"
+
+class WebDatabase;
+
+namespace syncer {
+class MetadataBatch;
+}
+
+namespace autofill {
+
+// This class acts as a SyncMetadataStore for components/autofill. It stores the
+// metadata in two tables inside the SQLite database passed to the constructor.
+// It expects the following schemas:
+//
+// autofill_sync_metadata
+//                      Sync-specific metadata for autofill records.
+//
+//   model_type         An int value corresponding to syncer::ModelType enum.
+//                      Added in version 78.
+//   storage_key        A string that uniquely identifies the metadata record
+//                      as well as the corresponding autofill record.
+//   value              The serialized EntityMetadata record.
+//
+// autofill_model_type_state
+//                      Contains sync ModelTypeStates for autofill model types.
+//
+//   model_type         An int value corresponding to syncer::ModelType enum.
+//                      Added in version 78. Previously, the table was used only
+//                      for one model type, there was an id column with value 1
+//                      for the single entry.
+//   value              The serialized ModelTypeState record.
+//
+class AutofillSyncMetadataTable : public WebDatabaseTable,
+                                  public syncer::SyncMetadataStore {
+ public:
+  AutofillSyncMetadataTable();
+
+  AutofillSyncMetadataTable(const AutofillSyncMetadataTable&) = delete;
+  AutofillSyncMetadataTable& operator=(const AutofillSyncMetadataTable&) =
+      delete;
+
+  ~AutofillSyncMetadataTable() override;
+
+  // Retrieves the AutofillSyncMetadataTable* owned by |db|.
+  static AutofillSyncMetadataTable* FromWebDatabase(WebDatabase* db);
+
+  // WebDatabaseTable:
+  WebDatabaseTable::TypeKey GetTypeKey() const override;
+  bool CreateTablesIfNecessary() override;
+  bool MigrateToVersion(int version, bool* update_compatible_version) override;
+
+  // Read all the stored metadata for |model_type| and fill |metadata_batch|
+  // with it.
+  bool GetAllSyncMetadata(syncer::ModelType model_type,
+                          syncer::MetadataBatch* metadata_batch);
+
+  // Deletes all metadata for |model_type|.
+  bool DeleteAllSyncMetadata(syncer::ModelType model_type);
+
+  // syncer::SyncMetadataStore:
+  bool UpdateEntityMetadata(syncer::ModelType model_type,
+                            const std::string& storage_key,
+                            const sync_pb::EntityMetadata& metadata) override;
+  bool ClearEntityMetadata(syncer::ModelType model_type,
+                           const std::string& storage_key) override;
+  bool UpdateModelTypeState(
+      syncer::ModelType model_type,
+      const sync_pb::ModelTypeState& model_type_state) override;
+  bool ClearModelTypeState(syncer::ModelType model_type) override;
+
+ private:
+  bool SupportsMetadataForModelType(syncer::ModelType model_type) const;
+  int GetKeyValueForModelType(syncer::ModelType model_type) const;
+
+  bool GetAllSyncEntityMetadata(syncer::ModelType model_type,
+                                syncer::MetadataBatch* metadata_batch);
+
+  bool GetModelTypeState(syncer::ModelType model_type,
+                         sync_pb::ModelTypeState* state);
+
+  bool InitAutofillSyncMetadataTable();
+  bool InitModelTypeStateTable();
+};
+
+}  // namespace autofill
+
+#endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_AUTOFILL_SYNC_METADATA_TABLE_H_
diff --git a/components/autofill/core/browser/webdata/autofill_sync_metadata_table_unittest.cc b/components/autofill/core/browser/webdata/autofill_sync_metadata_table_unittest.cc
new file mode 100644
index 0000000..78bc4c4
--- /dev/null
+++ b/components/autofill/core/browser/webdata/autofill_sync_metadata_table_unittest.cc
@@ -0,0 +1,163 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/webdata/autofill_sync_metadata_table.h"
+
+#include <string>
+
+#include "base/files/file_util.h"
+#include "base/files/scoped_temp_dir.h"
+#include "components/sync/model/metadata_batch.h"
+#include "components/sync/protocol/entity_metadata.pb.h"
+#include "components/sync/protocol/model_type_state.pb.h"
+#include "components/webdata/common/web_database.h"
+#include "sql/statement.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace autofill {
+
+namespace {
+
+using sync_pb::EntityMetadata;
+using sync_pb::ModelTypeState;
+using syncer::EntityMetadataMap;
+using syncer::MetadataBatch;
+using testing::ElementsAre;
+using testing::UnorderedElementsAre;
+
+class AutfillSyncMetadataTableTest
+    : public testing::Test,
+      public testing::WithParamInterface<syncer::ModelType> {
+ protected:
+  void SetUp() override {
+    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+    file_ = temp_dir_.GetPath().AppendASCII("TestWebDatabase");
+    table_ = std::make_unique<AutofillSyncMetadataTable>();
+    db_ = std::make_unique<WebDatabase>();
+    db_->AddTable(table_.get());
+    ASSERT_EQ(sql::INIT_OK, db_->Init(file_));
+  }
+
+  base::FilePath file_;
+  base::ScopedTempDir temp_dir_;
+  std::unique_ptr<AutofillSyncMetadataTable> table_;
+  std::unique_ptr<WebDatabase> db_;
+};
+
+TEST_P(AutfillSyncMetadataTableTest, AutofillNoMetadata) {
+  syncer::ModelType model_type = GetParam();
+  MetadataBatch metadata_batch;
+  EXPECT_TRUE(table_->GetAllSyncMetadata(model_type, &metadata_batch));
+  EXPECT_EQ(0u, metadata_batch.TakeAllMetadata().size());
+  EXPECT_EQ(ModelTypeState().SerializeAsString(),
+            metadata_batch.GetModelTypeState().SerializeAsString());
+}
+
+TEST_P(AutfillSyncMetadataTableTest, AutofillGetAllSyncMetadata) {
+  syncer::ModelType model_type = GetParam();
+  EntityMetadata metadata;
+  std::string storage_key = "storage_key";
+  std::string storage_key2 = "storage_key2";
+  metadata.set_sequence_number(1);
+
+  EXPECT_TRUE(table_->UpdateEntityMetadata(model_type, storage_key, metadata));
+
+  ModelTypeState model_type_state;
+  model_type_state.set_initial_sync_state(
+      sync_pb::ModelTypeState_InitialSyncState_INITIAL_SYNC_DONE);
+
+  EXPECT_TRUE(table_->UpdateModelTypeState(model_type, model_type_state));
+
+  metadata.set_sequence_number(2);
+  EXPECT_TRUE(table_->UpdateEntityMetadata(model_type, storage_key2, metadata));
+
+  MetadataBatch metadata_batch;
+  EXPECT_TRUE(table_->GetAllSyncMetadata(model_type, &metadata_batch));
+
+  EXPECT_EQ(metadata_batch.GetModelTypeState().initial_sync_state(),
+            sync_pb::ModelTypeState_InitialSyncState_INITIAL_SYNC_DONE);
+
+  EntityMetadataMap metadata_records = metadata_batch.TakeAllMetadata();
+
+  EXPECT_EQ(metadata_records.size(), 2u);
+  EXPECT_EQ(metadata_records[storage_key]->sequence_number(), 1);
+  EXPECT_EQ(metadata_records[storage_key2]->sequence_number(), 2);
+
+  // Now check that a model type state update replaces the old value
+  model_type_state.set_initial_sync_state(
+      sync_pb::ModelTypeState_InitialSyncState_INITIAL_SYNC_STATE_UNSPECIFIED);
+  EXPECT_TRUE(table_->UpdateModelTypeState(model_type, model_type_state));
+
+  EXPECT_TRUE(table_->GetAllSyncMetadata(model_type, &metadata_batch));
+  EXPECT_EQ(
+      metadata_batch.GetModelTypeState().initial_sync_state(),
+      sync_pb::ModelTypeState_InitialSyncState_INITIAL_SYNC_STATE_UNSPECIFIED);
+}
+
+TEST_P(AutfillSyncMetadataTableTest, AutofillWriteThenDeleteSyncMetadata) {
+  syncer::ModelType model_type = GetParam();
+  EntityMetadata metadata;
+  MetadataBatch metadata_batch;
+  std::string storage_key = "storage_key";
+  ModelTypeState model_type_state;
+
+  model_type_state.set_initial_sync_state(
+      sync_pb::ModelTypeState_InitialSyncState_INITIAL_SYNC_DONE);
+
+  metadata.set_client_tag_hash("client_hash");
+
+  // Write the data into the store.
+  EXPECT_TRUE(table_->UpdateEntityMetadata(model_type, storage_key, metadata));
+  EXPECT_TRUE(table_->UpdateModelTypeState(model_type, model_type_state));
+  // Delete the data we just wrote.
+  EXPECT_TRUE(table_->ClearEntityMetadata(model_type, storage_key));
+  // It shouldn't be there any more.
+  EXPECT_TRUE(table_->GetAllSyncMetadata(model_type, &metadata_batch));
+
+  EntityMetadataMap metadata_records = metadata_batch.TakeAllMetadata();
+  EXPECT_EQ(metadata_records.size(), 0u);
+
+  // Now delete the model type state.
+  EXPECT_TRUE(table_->ClearModelTypeState(model_type));
+  EXPECT_TRUE(table_->GetAllSyncMetadata(model_type, &metadata_batch));
+  EXPECT_EQ(ModelTypeState().SerializeAsString(),
+            metadata_batch.GetModelTypeState().SerializeAsString());
+}
+
+TEST_P(AutfillSyncMetadataTableTest, AutofillCorruptSyncMetadata) {
+  syncer::ModelType model_type = GetParam();
+  MetadataBatch metadata_batch;
+  sql::Statement s(db_->GetSQLConnection()->GetUniqueStatement(
+      "INSERT OR REPLACE INTO autofill_sync_metadata "
+      "(model_type, storage_key, value) VALUES(?, ?, ?)"));
+  s.BindInt(0, syncer::ModelTypeToStableIdentifier(model_type));
+  s.BindString(1, "storage_key");
+  s.BindString(2, "unparseable");
+  EXPECT_TRUE(s.Run());
+
+  EXPECT_FALSE(table_->GetAllSyncMetadata(model_type, &metadata_batch));
+}
+
+TEST_P(AutfillSyncMetadataTableTest, AutofillCorruptModelTypeState) {
+  syncer::ModelType model_type = GetParam();
+  MetadataBatch metadata_batch;
+  sql::Statement s(db_->GetSQLConnection()->GetUniqueStatement(
+      "INSERT OR REPLACE INTO autofill_model_type_state "
+      "(model_type, value) VALUES(?, ?)"));
+  s.BindInt(0, syncer::ModelTypeToStableIdentifier(model_type));
+  s.BindString(1, "unparseable");
+  EXPECT_TRUE(s.Run());
+
+  EXPECT_FALSE(table_->GetAllSyncMetadata(model_type, &metadata_batch));
+}
+
+INSTANTIATE_TEST_SUITE_P(AutofillTableTest,
+                         AutfillSyncMetadataTableTest,
+                         testing::Values(syncer::AUTOFILL,
+                                         syncer::AUTOFILL_PROFILE));
+
+}  // namespace
+
+}  // namespace autofill
diff --git a/components/autofill/core/browser/webdata/autofill_table.cc b/components/autofill/core/browser/webdata/autofill_table.cc
index 0a638d9..813352d 100644
--- a/components/autofill/core/browser/webdata/autofill_table.cc
+++ b/components/autofill/core/browser/webdata/autofill_table.cc
@@ -52,10 +52,6 @@
 #include "components/autofill/core/common/autofill_payments_features.h"
 #include "components/autofill/core/common/autofill_switches.h"
 #include "components/autofill/core/common/autofill_util.h"
-#include "components/sync/base/model_type.h"
-#include "components/sync/model/metadata_batch.h"
-#include "components/sync/protocol/entity_metadata.pb.h"
-#include "components/sync/protocol/model_type_state.pb.h"
 #include "components/webdata/common/web_database.h"
 #include "sql/statement.h"
 #include "sql/transaction.h"
@@ -129,6 +125,8 @@
 // kUseCount = "use_count"
 // kUseDate = "use_date"
 constexpr std::string_view kValueEncrypted = "value_encrypted";
+// In an older version of the table, the value used to be unencrypted.
+constexpr std::string_view kValue = "value";
 // kNickname = "nickname"
 
 constexpr std::string_view kMaskedIbansTable = "masked_ibans";
@@ -143,17 +141,6 @@
 // kUseCount = "use_count"
 // kUseDate = "use_date"
 
-constexpr std::string_view kAutofillSyncMetadataTable =
-    "autofill_sync_metadata";
-constexpr std::string_view kModelType = "model_type";
-constexpr std::string_view kStorageKey = "storage_key";
-constexpr std::string_view kValue = "value";
-
-constexpr std::string_view kAutofillModelTypeStateTable =
-    "autofill_model_type_state";
-// kModelType = "model_type"
-// kValue = "value"
-
 constexpr std::string_view kPaymentsCustomerDataTable =
     "payments_customer_data";
 constexpr std::string_view kCustomerId = "customer_id";
@@ -512,8 +499,7 @@
 bool AutofillTable::CreateTablesIfNecessary() {
   return InitCreditCardsTable() && InitLocalIbansTable() &&
          InitMaskedCreditCardsTable() && InitUnmaskedCreditCardsTable() &&
-         InitServerCardMetadataTable() && InitAutofillSyncMetadataTable() &&
-         InitModelTypeStateTable() && InitPaymentsCustomerDataTable() &&
+         InitServerCardMetadataTable() && InitPaymentsCustomerDataTable() &&
          InitServerCreditCardCloudTokenDataTable() && InitOfferDataTable() &&
          InitOfferEligibleInstrumentTable() && InitOfferMerchantDomainTable() &&
          InitVirtualCardUsageDataTable() && InitStoredCvcTable() &&
@@ -1963,88 +1949,6 @@
   Delete(db_, kLocalIbansTable);
 }
 
-bool AutofillTable::GetAllSyncMetadata(syncer::ModelType model_type,
-                                       syncer::MetadataBatch* metadata_batch) {
-  DCHECK(SupportsMetadataForModelType(model_type))
-      << "Model type " << model_type << " not supported for metadata";
-  DCHECK(metadata_batch);
-  if (!GetAllSyncEntityMetadata(model_type, metadata_batch)) {
-    return false;
-  }
-
-  sync_pb::ModelTypeState model_type_state;
-  if (!GetModelTypeState(model_type, &model_type_state))
-    return false;
-
-  metadata_batch->SetModelTypeState(model_type_state);
-  return true;
-}
-
-bool AutofillTable::DeleteAllSyncMetadata(syncer::ModelType model_type) {
-  return DeleteWhereColumnEq(db_, kAutofillSyncMetadataTable, kModelType,
-                             GetKeyValueForModelType(model_type));
-}
-
-bool AutofillTable::UpdateEntityMetadata(
-    syncer::ModelType model_type,
-    const std::string& storage_key,
-    const sync_pb::EntityMetadata& metadata) {
-  DCHECK(SupportsMetadataForModelType(model_type))
-      << "Model type " << model_type << " not supported for metadata";
-
-  sql::Statement s;
-  InsertBuilder(db_, s, kAutofillSyncMetadataTable,
-                {kModelType, kStorageKey, kValue},
-                /*or_replace=*/true);
-  s.BindInt(0, GetKeyValueForModelType(model_type));
-  s.BindString(1, storage_key);
-  s.BindString(2, metadata.SerializeAsString());
-
-  return s.Run();
-}
-
-bool AutofillTable::ClearEntityMetadata(syncer::ModelType model_type,
-                                        const std::string& storage_key) {
-  DCHECK(SupportsMetadataForModelType(model_type))
-      << "Model type " << model_type << " not supported for metadata";
-
-  sql::Statement s;
-  DeleteBuilder(db_, s, kAutofillSyncMetadataTable,
-                "model_type=? AND storage_key=?");
-  s.BindInt(0, GetKeyValueForModelType(model_type));
-  s.BindString(1, storage_key);
-
-  return s.Run();
-}
-
-bool AutofillTable::UpdateModelTypeState(
-    syncer::ModelType model_type,
-    const sync_pb::ModelTypeState& model_type_state) {
-  DCHECK(SupportsMetadataForModelType(model_type))
-      << "Model type " << model_type << " not supported for metadata";
-
-  // Hardcode the id to force a collision, ensuring that there remains only a
-  // single entry.
-  sql::Statement s;
-  InsertBuilder(db_, s, kAutofillModelTypeStateTable, {kModelType, kValue},
-                /*or_replace=*/true);
-  s.BindInt(0, GetKeyValueForModelType(model_type));
-  s.BindString(1, model_type_state.SerializeAsString());
-
-  return s.Run();
-}
-
-bool AutofillTable::ClearModelTypeState(syncer::ModelType model_type) {
-  DCHECK(SupportsMetadataForModelType(model_type))
-      << "Model type " << model_type << " not supported for metadata";
-
-  sql::Statement s;
-  DeleteBuilder(db_, s, kAutofillModelTypeStateTable, "model_type=?");
-  s.BindInt(0, GetKeyValueForModelType(model_type));
-
-  return s.Run();
-}
-
 bool AutofillTable::MigrateToVersion83RemoveServerCardTypeColumn() {
   sql::Transaction transaction(db_);
   return transaction.Begin() &&
@@ -2305,67 +2209,6 @@
          transaction.Commit();
 }
 
-bool AutofillTable::SupportsMetadataForModelType(
-    syncer::ModelType model_type) const {
-  return (model_type == syncer::AUTOFILL ||
-          model_type == syncer::AUTOFILL_PROFILE ||
-          model_type == syncer::AUTOFILL_WALLET_CREDENTIAL ||
-          model_type == syncer::AUTOFILL_WALLET_DATA ||
-          model_type == syncer::AUTOFILL_WALLET_METADATA ||
-          model_type == syncer::AUTOFILL_WALLET_OFFER ||
-          model_type == syncer::AUTOFILL_WALLET_USAGE ||
-          model_type == syncer::CONTACT_INFO);
-}
-
-int AutofillTable::GetKeyValueForModelType(syncer::ModelType model_type) const {
-  return syncer::ModelTypeToStableIdentifier(model_type);
-}
-
-bool AutofillTable::GetAllSyncEntityMetadata(
-    syncer::ModelType model_type,
-    syncer::MetadataBatch* metadata_batch) {
-  DCHECK(SupportsMetadataForModelType(model_type))
-      << "Model type " << model_type << " not supported for metadata";
-  DCHECK(metadata_batch);
-
-  sql::Statement s;
-  SelectBuilder(db_, s, kAutofillSyncMetadataTable, {kStorageKey, kValue},
-                "WHERE model_type=?");
-  s.BindInt(0, GetKeyValueForModelType(model_type));
-
-  while (s.Step()) {
-    std::string storage_key = s.ColumnString(0);
-    std::string serialized_metadata = s.ColumnString(1);
-    auto entity_metadata = std::make_unique<sync_pb::EntityMetadata>();
-    if (entity_metadata->ParseFromString(serialized_metadata)) {
-      metadata_batch->AddMetadata(storage_key, std::move(entity_metadata));
-    } else {
-      DLOG(WARNING) << "Failed to deserialize AUTOFILL model type "
-                       "sync_pb::EntityMetadata.";
-      return false;
-    }
-  }
-  return true;
-}
-
-bool AutofillTable::GetModelTypeState(syncer::ModelType model_type,
-                                      sync_pb::ModelTypeState* state) {
-  DCHECK(SupportsMetadataForModelType(model_type))
-      << "Model type " << model_type << " not supported for metadata";
-
-  sql::Statement s;
-  SelectBuilder(db_, s, kAutofillModelTypeStateTable, {kValue},
-                "WHERE model_type=?");
-  s.BindInt(0, GetKeyValueForModelType(model_type));
-
-  if (!s.Step()) {
-    return true;
-  }
-
-  std::string serialized_state = s.ColumnString(0);
-  return state->ParseFromString(serialized_state);
-}
-
 void AutofillTable::AddMaskedCreditCards(
     const std::vector<CreditCard>& credit_cards) {
   DCHECK_GT(db_->transaction_nesting(), 0);
@@ -2511,20 +2354,6 @@
                                  {kBillingAddressId, "VARCHAR"}});
 }
 
-bool AutofillTable::InitAutofillSyncMetadataTable() {
-  return CreateTableIfNotExists(db_, kAutofillSyncMetadataTable,
-                                {{kModelType, "INTEGER NOT NULL"},
-                                 {kStorageKey, "VARCHAR NOT NULL"},
-                                 {kValue, "BLOB"}},
-                                {kModelType, kStorageKey});
-}
-
-bool AutofillTable::InitModelTypeStateTable() {
-  return CreateTableIfNotExists(
-      db_, kAutofillModelTypeStateTable,
-      {{kModelType, "INTEGER NOT NULL PRIMARY KEY"}, {kValue, "BLOB"}});
-}
-
 bool AutofillTable::InitPaymentsCustomerDataTable() {
   return CreateTableIfNotExists(db_, kPaymentsCustomerDataTable,
                                 {{kCustomerId, "VARCHAR"}});
diff --git a/components/autofill/core/browser/webdata/autofill_table.h b/components/autofill/core/browser/webdata/autofill_table.h
index cf08c64..88fcb7d 100644
--- a/components/autofill/core/browser/webdata/autofill_table.h
+++ b/components/autofill/core/browser/webdata/autofill_table.h
@@ -17,7 +17,6 @@
 #include "base/time/time.h"
 #include "components/autofill/core/browser/data_model/payment_instrument.h"
 #include "components/sync/base/model_type.h"
-#include "components/sync/model/sync_metadata_store.h"
 #include "components/webdata/common/web_database_table.h"
 
 class WebDatabase;
@@ -26,10 +25,6 @@
 class Time;
 }
 
-namespace syncer {
-class MetadataBatch;
-}
-
 namespace autofill {
 
 struct AutofillMetadata;
@@ -240,24 +235,6 @@
 //   use_date           The date this IBAN was last used to fill a form,
 //                      in time_t.
 //
-// autofill_sync_metadata
-//                      Sync-specific metadata for autofill records.
-//
-//   model_type         An int value corresponding to syncer::ModelType enum.
-//                      Added in version 78.
-//   storage_key        A string that uniquely identifies the metadata record
-//                      as well as the corresponding autofill record.
-//   value              The serialized EntityMetadata record.
-//
-// autofill_model_type_state
-//                      Contains sync ModelTypeStates for autofill model types.
-//
-//   model_type         An int value corresponding to syncer::ModelType enum.
-//                      Added in version 78. Previously, the table was used only
-//                      for one model type, there was an id column with value 1
-//                      for the single entry.
-//   value              The serialized ModelTypeState record.
-//
 // payments_customer_data
 //                      Contains Google Payments customer data.
 //
@@ -435,8 +412,7 @@
 //   merchant_domain    Origin for merchant websites on which this benefit
 //                      would apply.
 //
-class AutofillTable : public WebDatabaseTable,
-                      public syncer::SyncMetadataStore {
+class AutofillTable : public WebDatabaseTable {
  public:
   AutofillTable();
 
@@ -649,25 +625,6 @@
   // Clear all local payment methods (credit cards and IBANs).
   void ClearLocalPaymentMethodsData();
 
-  // Read all the stored metadata for |model_type| and fill |metadata_batch|
-  // with it.
-  bool GetAllSyncMetadata(syncer::ModelType model_type,
-                          syncer::MetadataBatch* metadata_batch);
-
-  // Deletes all metadata for |model_type|.
-  bool DeleteAllSyncMetadata(syncer::ModelType model_type);
-
-  // syncer::SyncMetadataStore implementation.
-  bool UpdateEntityMetadata(syncer::ModelType model_type,
-                            const std::string& storage_key,
-                            const sync_pb::EntityMetadata& metadata) override;
-  bool ClearEntityMetadata(syncer::ModelType model_type,
-                           const std::string& storage_key) override;
-  bool UpdateModelTypeState(
-      syncer::ModelType model_type,
-      const sync_pb::ModelTypeState& model_type_state) override;
-  bool ClearModelTypeState(syncer::ModelType model_type) override;
-
   // Table migration functions. NB: These do not and should not rely on other
   // functions in this class. The implementation of a function such as
   // GetCreditCard may change over time, but MigrateToVersionXX should never
@@ -696,15 +653,6 @@
   bool MigrateToVersion123AddProductTermsUrlColumnAndAddCardBenefitsTables();
 
  private:
-  bool SupportsMetadataForModelType(syncer::ModelType model_type) const;
-  int GetKeyValueForModelType(syncer::ModelType model_type) const;
-
-  bool GetAllSyncEntityMetadata(syncer::ModelType model_type,
-                                syncer::MetadataBatch* metadata_batch);
-
-  bool GetModelTypeState(syncer::ModelType model_type,
-                         sync_pb::ModelTypeState* state);
-
   // Adds to |masked_credit_cards| and updates |server_card_metadata|.
   // Must already be in a transaction.
   void AddMaskedCreditCards(const std::vector<CreditCard>& credit_cards);
@@ -751,8 +699,6 @@
   bool InitMaskedIbansMetadataTable();
   bool InitUnmaskedCreditCardsTable();
   bool InitServerCardMetadataTable();
-  bool InitAutofillSyncMetadataTable();
-  bool InitModelTypeStateTable();
   bool InitPaymentsCustomerDataTable();
   bool InitServerCreditCardCloudTokenDataTable();
   bool InitStoredCvcTable();
diff --git a/components/autofill/core/browser/webdata/autofill_table_unittest.cc b/components/autofill/core/browser/webdata/autofill_table_unittest.cc
index 608cc667..bf0854d 100644
--- a/components/autofill/core/browser/webdata/autofill_table_unittest.cc
+++ b/components/autofill/core/browser/webdata/autofill_table_unittest.cc
@@ -41,9 +41,6 @@
 #include "components/autofill/core/common/autofill_switches.h"
 #include "components/autofill/core/common/autofill_util.h"
 #include "components/os_crypt/sync/os_crypt_mocker.h"
-#include "components/sync/model/metadata_batch.h"
-#include "components/sync/protocol/entity_metadata.pb.h"
-#include "components/sync/protocol/model_type_state.pb.h"
 #include "components/webdata/common/web_database.h"
 #include "sql/statement.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -51,10 +48,6 @@
 #include "url/origin.h"
 
 using base::Time;
-using sync_pb::EntityMetadata;
-using sync_pb::ModelTypeState;
-using syncer::EntityMetadataMap;
-using syncer::MetadataBatch;
 using testing::ElementsAre;
 using testing::UnorderedElementsAre;
 
@@ -1544,129 +1537,6 @@
   EXPECT_TRUE(output.empty());
 }
 
-class AutofillTableTestPerModelType
-    : public AutofillTableTest,
-      public testing::WithParamInterface<syncer::ModelType> {
- public:
-  AutofillTableTestPerModelType() = default;
-  AutofillTableTestPerModelType(const AutofillTableTestPerModelType&) = delete;
-  AutofillTableTestPerModelType& operator=(
-      const AutofillTableTestPerModelType&) = delete;
-  ~AutofillTableTestPerModelType() override = default;
-};
-
-TEST_P(AutofillTableTestPerModelType, AutofillNoMetadata) {
-  syncer::ModelType model_type = GetParam();
-  MetadataBatch metadata_batch;
-  EXPECT_TRUE(table_->GetAllSyncMetadata(model_type, &metadata_batch));
-  EXPECT_EQ(0u, metadata_batch.TakeAllMetadata().size());
-  EXPECT_EQ(ModelTypeState().SerializeAsString(),
-            metadata_batch.GetModelTypeState().SerializeAsString());
-}
-
-TEST_P(AutofillTableTestPerModelType, AutofillGetAllSyncMetadata) {
-  syncer::ModelType model_type = GetParam();
-  EntityMetadata metadata;
-  std::string storage_key = "storage_key";
-  std::string storage_key2 = "storage_key2";
-  metadata.set_sequence_number(1);
-
-  EXPECT_TRUE(table_->UpdateEntityMetadata(model_type, storage_key, metadata));
-
-  ModelTypeState model_type_state;
-  model_type_state.set_initial_sync_state(
-      sync_pb::ModelTypeState_InitialSyncState_INITIAL_SYNC_DONE);
-
-  EXPECT_TRUE(table_->UpdateModelTypeState(model_type, model_type_state));
-
-  metadata.set_sequence_number(2);
-  EXPECT_TRUE(table_->UpdateEntityMetadata(model_type, storage_key2, metadata));
-
-  MetadataBatch metadata_batch;
-  EXPECT_TRUE(table_->GetAllSyncMetadata(model_type, &metadata_batch));
-
-  EXPECT_EQ(metadata_batch.GetModelTypeState().initial_sync_state(),
-            sync_pb::ModelTypeState_InitialSyncState_INITIAL_SYNC_DONE);
-
-  EntityMetadataMap metadata_records = metadata_batch.TakeAllMetadata();
-
-  EXPECT_EQ(metadata_records.size(), 2u);
-  EXPECT_EQ(metadata_records[storage_key]->sequence_number(), 1);
-  EXPECT_EQ(metadata_records[storage_key2]->sequence_number(), 2);
-
-  // Now check that a model type state update replaces the old value
-  model_type_state.set_initial_sync_state(
-      sync_pb::ModelTypeState_InitialSyncState_INITIAL_SYNC_STATE_UNSPECIFIED);
-  EXPECT_TRUE(table_->UpdateModelTypeState(model_type, model_type_state));
-
-  EXPECT_TRUE(table_->GetAllSyncMetadata(model_type, &metadata_batch));
-  EXPECT_EQ(
-      metadata_batch.GetModelTypeState().initial_sync_state(),
-      sync_pb::ModelTypeState_InitialSyncState_INITIAL_SYNC_STATE_UNSPECIFIED);
-}
-
-TEST_P(AutofillTableTestPerModelType, AutofillWriteThenDeleteSyncMetadata) {
-  syncer::ModelType model_type = GetParam();
-  EntityMetadata metadata;
-  MetadataBatch metadata_batch;
-  std::string storage_key = "storage_key";
-  ModelTypeState model_type_state;
-
-  model_type_state.set_initial_sync_state(
-      sync_pb::ModelTypeState_InitialSyncState_INITIAL_SYNC_DONE);
-
-  metadata.set_client_tag_hash("client_hash");
-
-  // Write the data into the store.
-  EXPECT_TRUE(table_->UpdateEntityMetadata(model_type, storage_key, metadata));
-  EXPECT_TRUE(table_->UpdateModelTypeState(model_type, model_type_state));
-  // Delete the data we just wrote.
-  EXPECT_TRUE(table_->ClearEntityMetadata(model_type, storage_key));
-  // It shouldn't be there any more.
-  EXPECT_TRUE(table_->GetAllSyncMetadata(model_type, &metadata_batch));
-
-  EntityMetadataMap metadata_records = metadata_batch.TakeAllMetadata();
-  EXPECT_EQ(metadata_records.size(), 0u);
-
-  // Now delete the model type state.
-  EXPECT_TRUE(table_->ClearModelTypeState(model_type));
-  EXPECT_TRUE(table_->GetAllSyncMetadata(model_type, &metadata_batch));
-  EXPECT_EQ(ModelTypeState().SerializeAsString(),
-            metadata_batch.GetModelTypeState().SerializeAsString());
-}
-
-TEST_P(AutofillTableTestPerModelType, AutofillCorruptSyncMetadata) {
-  syncer::ModelType model_type = GetParam();
-  MetadataBatch metadata_batch;
-  sql::Statement s(db_->GetSQLConnection()->GetUniqueStatement(
-      "INSERT OR REPLACE INTO autofill_sync_metadata "
-      "(model_type, storage_key, value) VALUES(?, ?, ?)"));
-  s.BindInt(0, syncer::ModelTypeToStableIdentifier(model_type));
-  s.BindString(1, "storage_key");
-  s.BindString(2, "unparseable");
-  EXPECT_TRUE(s.Run());
-
-  EXPECT_FALSE(table_->GetAllSyncMetadata(model_type, &metadata_batch));
-}
-
-TEST_P(AutofillTableTestPerModelType, AutofillCorruptModelTypeState) {
-  syncer::ModelType model_type = GetParam();
-  MetadataBatch metadata_batch;
-  sql::Statement s(db_->GetSQLConnection()->GetUniqueStatement(
-      "INSERT OR REPLACE INTO autofill_model_type_state "
-      "(model_type, value) VALUES(?, ?)"));
-  s.BindInt(0, syncer::ModelTypeToStableIdentifier(model_type));
-  s.BindString(1, "unparseable");
-  EXPECT_TRUE(s.Run());
-
-  EXPECT_FALSE(table_->GetAllSyncMetadata(model_type, &metadata_batch));
-}
-
-INSTANTIATE_TEST_SUITE_P(AutofillTableTest,
-                         AutofillTableTestPerModelType,
-                         testing::Values(syncer::AUTOFILL,
-                                         syncer::AUTOFILL_PROFILE));
-
 TEST_F(AutofillTableTest, SetAndGetCreditCardOfferData) {
   // Set Offer ID.
   int64_t offer_id_1 = 1;
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_credential_sync_bridge.cc b/components/autofill/core/browser/webdata/autofill_wallet_credential_sync_bridge.cc
index 26d8c8c..03a7aab4 100644
--- a/components/autofill/core/browser/webdata/autofill_wallet_credential_sync_bridge.cc
+++ b/components/autofill/core/browser/webdata/autofill_wallet_credential_sync_bridge.cc
@@ -12,6 +12,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "components/autofill/core/browser/webdata/autofill_change.h"
 #include "components/autofill/core/browser/webdata/autofill_sync_bridge_util.h"
+#include "components/autofill/core/browser/webdata/autofill_sync_metadata_table.h"
 #include "components/autofill/core/browser/webdata/autofill_webdata_backend.h"
 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
 #include "components/sync/base/model_type.h"
@@ -72,7 +73,7 @@
 AutofillWalletCredentialSyncBridge::CreateMetadataChangeList() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   return std::make_unique<syncer::SyncMetadataStoreChangeList>(
-      GetAutofillTable(), syncer::AUTOFILL_WALLET_CREDENTIAL,
+      GetSyncMetadataStore(), syncer::AUTOFILL_WALLET_CREDENTIAL,
       base::BindRepeating(&syncer::ModelTypeChangeProcessor::ReportError,
                           change_processor()->GetWeakPtr()));
 }
@@ -241,10 +242,16 @@
   ActOnLocalChange(change);
 }
 
-AutofillTable* AutofillWalletCredentialSyncBridge::GetAutofillTable() const {
+AutofillTable* AutofillWalletCredentialSyncBridge::GetAutofillTable() {
   return AutofillTable::FromWebDatabase(web_data_backend_->GetDatabase());
 }
 
+AutofillSyncMetadataTable*
+AutofillWalletCredentialSyncBridge::GetSyncMetadataStore() {
+  return AutofillSyncMetadataTable::FromWebDatabase(
+      web_data_backend_->GetDatabase());
+}
+
 void AutofillWalletCredentialSyncBridge::ActOnLocalChange(
     const ServerCvcChange& change) {
   // If sync isn't ready yet (most likely because the data type is disabled),
@@ -276,10 +283,10 @@
 
 void AutofillWalletCredentialSyncBridge::LoadMetadata() {
   CHECK(web_data_backend_->GetDatabase()) << "Failed to get database.";
-  CHECK(GetAutofillTable()) << "Failed to load Autofill table.";
+  CHECK(GetSyncMetadataStore()) << "Failed to load metadata table.";
 
   auto batch = std::make_unique<syncer::MetadataBatch>();
-  if (!GetAutofillTable()->GetAllSyncMetadata(
+  if (!GetSyncMetadataStore()->GetAllSyncMetadata(
           syncer::AUTOFILL_WALLET_CREDENTIAL, batch.get())) {
     change_processor()->ReportError(
         {FROM_HERE,
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_credential_sync_bridge.h b/components/autofill/core/browser/webdata/autofill_wallet_credential_sync_bridge.h
index 4f77360a..fd595b0 100644
--- a/components/autofill/core/browser/webdata/autofill_wallet_credential_sync_bridge.h
+++ b/components/autofill/core/browser/webdata/autofill_wallet_credential_sync_bridge.h
@@ -13,7 +13,6 @@
 #include "base/sequence_checker.h"
 #include "base/supports_user_data.h"
 #include "components/autofill/core/browser/webdata/autofill_change.h"
-#include "components/autofill/core/browser/webdata/autofill_table.h"
 #include "components/autofill/core/browser/webdata/autofill_webdata_service_observer.h"
 #include "components/sync/model/conflict_resolution.h"
 #include "components/sync/model/metadata_change_list.h"
@@ -24,6 +23,7 @@
 
 namespace autofill {
 
+class AutofillSyncMetadataTable;
 class AutofillTable;
 class AutofillWebDataBackend;
 class AutofillWebDataService;
@@ -83,7 +83,9 @@
   const raw_ptr<AutofillWebDataBackend> web_data_backend_;
 
   // Returns the table associated with the `web_data_backend_`.
-  AutofillTable* GetAutofillTable() const;
+  AutofillTable* GetAutofillTable();
+
+  AutofillSyncMetadataTable* GetSyncMetadataStore();
 
   // Syncing the changes on the local storage related to Wallet credentials aka
   // CVC to the Chrome Sync server. `change` has the data which was updated in
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_credential_sync_bridge_unittest.cc b/components/autofill/core/browser/webdata/autofill_wallet_credential_sync_bridge_unittest.cc
index 3ec0cde..e7e9c445 100644
--- a/components/autofill/core/browser/webdata/autofill_wallet_credential_sync_bridge_unittest.cc
+++ b/components/autofill/core/browser/webdata/autofill_wallet_credential_sync_bridge_unittest.cc
@@ -14,6 +14,7 @@
 #include "base/test/task_environment.h"
 #include "components/autofill/core/browser/autofill_test_utils.h"
 #include "components/autofill/core/browser/webdata/autofill_sync_bridge_util.h"
+#include "components/autofill/core/browser/webdata/autofill_sync_metadata_table.h"
 #include "components/autofill/core/browser/webdata/autofill_table.h"
 #include "components/autofill/core/browser/webdata/mock_autofill_webdata_backend.h"
 #include "components/os_crypt/sync/os_crypt_mocker.h"
@@ -59,6 +60,7 @@
  public:
   void SetUp() override {
     OSCryptMocker::SetUp();
+    db_.AddTable(&sync_metadata_table_);
     db_.AddTable(&table_);
     db_.Init(base::FilePath(WebDatabase::kInMemoryPath));
     ON_CALL(backend_, GetDatabase()).WillByDefault(Return(&db_));
@@ -146,6 +148,7 @@
 
  private:
   NiceMock<MockAutofillWebDataBackend> backend_;
+  AutofillSyncMetadataTable sync_metadata_table_;
   AutofillTable table_;
   WebDatabase db_;
   NiceMock<MockModelTypeChangeProcessor> mock_processor_;
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.cc b/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.cc
index 4b1089f..5ad4395 100644
--- a/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.cc
+++ b/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.cc
@@ -19,6 +19,7 @@
 #include "components/autofill/core/browser/data_model/autofill_metadata.h"
 #include "components/autofill/core/browser/data_model/credit_card.h"
 #include "components/autofill/core/browser/webdata/autofill_sync_bridge_util.h"
+#include "components/autofill/core/browser/webdata/autofill_sync_metadata_table.h"
 #include "components/autofill/core/browser/webdata/autofill_table.h"
 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
 #include "components/autofill/core/common/autofill_clock.h"
@@ -333,7 +334,7 @@
 AutofillWalletMetadataSyncBridge::CreateMetadataChangeList() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   return std::make_unique<syncer::SyncMetadataStoreChangeList>(
-      GetAutofillTable(), syncer::AUTOFILL_WALLET_METADATA,
+      GetSyncMetadataStore(), syncer::AUTOFILL_WALLET_METADATA,
       base::BindRepeating(&syncer::ModelTypeChangeProcessor::ReportError,
                           change_processor()->GetWeakPtr()));
 }
@@ -435,9 +436,15 @@
   return AutofillTable::FromWebDatabase(web_data_backend_->GetDatabase());
 }
 
+AutofillSyncMetadataTable*
+AutofillWalletMetadataSyncBridge::GetSyncMetadataStore() {
+  return AutofillSyncMetadataTable::FromWebDatabase(
+      web_data_backend_->GetDatabase());
+}
+
 void AutofillWalletMetadataSyncBridge::LoadDataCacheAndMetadata() {
   if (!web_data_backend_ || !web_data_backend_->GetDatabase() ||
-      !GetAutofillTable()) {
+      !GetAutofillTable() || !GetSyncMetadataStore()) {
     change_processor()->ReportError(
         {FROM_HERE, "Failed to load AutofillWebDatabase."});
     return;
@@ -457,8 +464,8 @@
 
   // Load the metadata and send to the processor.
   auto batch = std::make_unique<syncer::MetadataBatch>();
-  if (!GetAutofillTable()->GetAllSyncMetadata(syncer::AUTOFILL_WALLET_METADATA,
-                                              batch.get())) {
+  if (!GetSyncMetadataStore()->GetAllSyncMetadata(
+          syncer::AUTOFILL_WALLET_METADATA, batch.get())) {
     change_processor()->ReportError(
         {FROM_HERE, "Failed reading autofill metadata from WebDatabase."});
     return;
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.h b/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.h
index 1d9fdd0..4cf385ea 100644
--- a/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.h
+++ b/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.h
@@ -27,6 +27,7 @@
 
 namespace autofill {
 
+class AutofillSyncMetadataTable;
 class AutofillTable;
 class AutofillWebDataService;
 
@@ -86,6 +87,8 @@
   // Returns the table associated with the |web_data_backend_|.
   AutofillTable* GetAutofillTable();
 
+  AutofillSyncMetadataTable* GetSyncMetadataStore();
+
   // Synchronously load the sync data into |cache_| and sync metadata from the
   // autofill table and pass the latter to the processor so that it can start
   // tracking changes.
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge_unittest.cc b/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge_unittest.cc
index eb511ac7..5d2c95a0 100644
--- a/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge_unittest.cc
+++ b/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge_unittest.cc
@@ -25,6 +25,7 @@
 #include "components/autofill/core/browser/test_autofill_clock.h"
 #include "components/autofill/core/browser/webdata/autofill_sync_bridge_test_util.h"
 #include "components/autofill/core/browser/webdata/autofill_sync_bridge_util.h"
+#include "components/autofill/core/browser/webdata/autofill_sync_metadata_table.h"
 #include "components/autofill/core/browser/webdata/autofill_table.h"
 #include "components/autofill/core/browser/webdata/mock_autofill_webdata_backend.h"
 #include "components/autofill/core/common/autofill_constants.h"
@@ -232,6 +233,7 @@
     // Fix a time for implicitly constructed use_dates in AutofillProfile.
     test_clock_.SetNow(kDefaultTime);
     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+    db_.AddTable(&sync_metadata_table_);
     db_.AddTable(&table_);
     db_.Init(temp_dir_.GetPath().AppendASCII("SyncTestWebDatabase"));
     ON_CALL(*backend(), GetDatabase()).WillByDefault(Return(&db_));
@@ -255,8 +257,8 @@
     model_type_state.mutable_progress_marker()->set_data_type_id(
         GetSpecificsFieldNumberFromModelType(syncer::AUTOFILL_WALLET_METADATA));
     model_type_state.set_cache_guid(kDefaultCacheGuid);
-    EXPECT_TRUE(table()->UpdateModelTypeState(syncer::AUTOFILL_WALLET_METADATA,
-                                              model_type_state));
+    EXPECT_TRUE(sync_metadata_table_.UpdateModelTypeState(
+        syncer::AUTOFILL_WALLET_METADATA, model_type_state));
     bridge_ = std::make_unique<AutofillWalletMetadataSyncBridge>(
         mock_processor_.CreateForwardingProcessor(), &backend_);
   }
@@ -390,10 +392,9 @@
 
   std::vector<std::string> GetLocalSyncMetadataStorageKeys() {
     std::vector<std::string> storage_keys;
-
-    AutofillTable* table = AutofillTable::FromWebDatabase(&db_);
     syncer::MetadataBatch batch;
-    if (table->GetAllSyncMetadata(syncer::AUTOFILL_WALLET_METADATA, &batch)) {
+    if (sync_metadata_table_.GetAllSyncMetadata(
+            syncer::AUTOFILL_WALLET_METADATA, &batch)) {
       for (const auto& [storage_key, metadata] : batch.GetAllMetadata()) {
         storage_keys.push_back(storage_key);
       }
@@ -425,6 +426,7 @@
   ScopedTempDir temp_dir_;
   base::test::SingleThreadTaskEnvironment task_environment_;
   testing::NiceMock<MockAutofillWebDataBackend> backend_;
+  AutofillSyncMetadataTable sync_metadata_table_;
   AutofillTable table_;
   WebDatabase db_;
   testing::NiceMock<MockModelTypeChangeProcessor> mock_processor_;
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_offer_sync_bridge.cc b/components/autofill/core/browser/webdata/autofill_wallet_offer_sync_bridge.cc
index f14ddbb7..0e8e1f34 100644
--- a/components/autofill/core/browser/webdata/autofill_wallet_offer_sync_bridge.cc
+++ b/components/autofill/core/browser/webdata/autofill_wallet_offer_sync_bridge.cc
@@ -13,6 +13,7 @@
 #include "components/autofill/core/browser/metrics/autofill_metrics.h"
 #include "components/autofill/core/browser/metrics/payments/offers_metrics.h"
 #include "components/autofill/core/browser/webdata/autofill_sync_bridge_util.h"
+#include "components/autofill/core/browser/webdata/autofill_sync_metadata_table.h"
 #include "components/autofill/core/browser/webdata/autofill_table.h"
 #include "components/autofill/core/browser/webdata/autofill_webdata_backend.h"
 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
@@ -81,7 +82,7 @@
 AutofillWalletOfferSyncBridge::CreateMetadataChangeList() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   return std::make_unique<syncer::SyncMetadataStoreChangeList>(
-      GetAutofillTable(), syncer::AUTOFILL_WALLET_OFFER,
+      GetSyncMetadataStore(), syncer::AUTOFILL_WALLET_OFFER,
       base::BindRepeating(&syncer::ModelTypeChangeProcessor::ReportError,
                           change_processor()->GetWeakPtr()));
 }
@@ -207,16 +208,23 @@
   return AutofillTable::FromWebDatabase(web_data_backend_->GetDatabase());
 }
 
+AutofillSyncMetadataTable*
+AutofillWalletOfferSyncBridge::GetSyncMetadataStore() {
+  return AutofillSyncMetadataTable::FromWebDatabase(
+      web_data_backend_->GetDatabase());
+}
+
 void AutofillWalletOfferSyncBridge::LoadAutofillOfferMetadata() {
-  if (!web_data_backend_->GetDatabase() || !GetAutofillTable()) {
+  if (!web_data_backend_->GetDatabase() || !GetAutofillTable() ||
+      !GetSyncMetadataStore()) {
     change_processor()->ReportError(
         {FROM_HERE, "Failed to load Autofill table."});
     return;
   }
 
   auto batch = std::make_unique<syncer::MetadataBatch>();
-  if (!GetAutofillTable()->GetAllSyncMetadata(syncer::AUTOFILL_WALLET_OFFER,
-                                              batch.get())) {
+  if (!GetSyncMetadataStore()->GetAllSyncMetadata(syncer::AUTOFILL_WALLET_OFFER,
+                                                  batch.get())) {
     change_processor()->ReportError(
         {FROM_HERE,
          "Failed reading autofill offer metadata from WebDatabase."});
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_offer_sync_bridge.h b/components/autofill/core/browser/webdata/autofill_wallet_offer_sync_bridge.h
index 9c6de42..5591c8e 100644
--- a/components/autofill/core/browser/webdata/autofill_wallet_offer_sync_bridge.h
+++ b/components/autofill/core/browser/webdata/autofill_wallet_offer_sync_bridge.h
@@ -17,6 +17,8 @@
 #include "components/sync/model/model_type_sync_bridge.h"
 
 namespace autofill {
+
+class AutofillSyncMetadataTable;
 class AutofillTable;
 class AutofillWebDataBackend;
 class AutofillWebDataService;
@@ -72,6 +74,8 @@
   // Returns the table associated with the |web_data_backend_|.
   AutofillTable* GetAutofillTable();
 
+  AutofillSyncMetadataTable* GetSyncMetadataStore();
+
   // Synchronously load sync metadata from the autofill table and pass it to the
   // processor so that it can start tracking changes.
   void LoadAutofillOfferMetadata();
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_offer_sync_bridge_unittest.cc b/components/autofill/core/browser/webdata/autofill_wallet_offer_sync_bridge_unittest.cc
index 6010ef58..3e69b77d 100644
--- a/components/autofill/core/browser/webdata/autofill_wallet_offer_sync_bridge_unittest.cc
+++ b/components/autofill/core/browser/webdata/autofill_wallet_offer_sync_bridge_unittest.cc
@@ -21,6 +21,7 @@
 #include "components/autofill/core/browser/autofill_test_utils.h"
 #include "components/autofill/core/browser/test_autofill_clock.h"
 #include "components/autofill/core/browser/webdata/autofill_sync_bridge_util.h"
+#include "components/autofill/core/browser/webdata/autofill_sync_metadata_table.h"
 #include "components/autofill/core/browser/webdata/autofill_table.h"
 #include "components/autofill/core/browser/webdata/autofill_webdata_backend.h"
 #include "components/autofill/core/browser/webdata/mock_autofill_webdata_backend.h"
@@ -134,6 +135,7 @@
 
   void SetUp() override {
     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+    db_.AddTable(&sync_metadata_table_);
     db_.AddTable(&table_);
     db_.Init(temp_dir_.GetPath().AppendASCII("SyncTestWebDatabase"));
     ON_CALL(backend_, GetDatabase()).WillByDefault(Return(&db_));
@@ -160,8 +162,8 @@
     model_type_state.mutable_progress_marker()->set_data_type_id(
         GetSpecificsFieldNumberFromModelType(syncer::AUTOFILL_WALLET_OFFER));
     model_type_state.set_cache_guid(kDefaultCacheGuid);
-    EXPECT_TRUE(table()->UpdateModelTypeState(syncer::AUTOFILL_WALLET_OFFER,
-                                              model_type_state));
+    EXPECT_TRUE(sync_metadata_table_.UpdateModelTypeState(
+        syncer::AUTOFILL_WALLET_OFFER, model_type_state));
     bridge_ = std::make_unique<AutofillWalletOfferSyncBridge>(
         mock_processor_.CreateForwardingProcessor(), &backend_);
   }
@@ -239,6 +241,7 @@
   ScopedTempDir temp_dir_;
   base::test::SingleThreadTaskEnvironment task_environment_;
   NiceMock<MockAutofillWebDataBackend> backend_;
+  AutofillSyncMetadataTable sync_metadata_table_;
   AutofillTable table_;
   WebDatabase db_;
   NiceMock<MockModelTypeChangeProcessor> mock_processor_;
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.cc b/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.cc
index 38de37c..80bf94c 100644
--- a/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.cc
+++ b/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.cc
@@ -17,6 +17,7 @@
 #include "components/autofill/core/browser/metrics/autofill_metrics.h"
 #include "components/autofill/core/browser/payments/payments_customer_data.h"
 #include "components/autofill/core/browser/webdata/autofill_sync_bridge_util.h"
+#include "components/autofill/core/browser/webdata/autofill_sync_metadata_table.h"
 #include "components/autofill/core/browser/webdata/autofill_table.h"
 #include "components/autofill/core/browser/webdata/autofill_webdata_backend.h"
 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
@@ -170,7 +171,7 @@
 AutofillWalletSyncBridge::CreateMetadataChangeList() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   return std::make_unique<syncer::SyncMetadataStoreChangeList>(
-      GetAutofillTable(), syncer::AUTOFILL_WALLET_DATA,
+      GetSyncMetadataStore(), syncer::AUTOFILL_WALLET_DATA,
       base::BindRepeating(&syncer::ModelTypeChangeProcessor::ReportError,
                           change_processor()->GetWeakPtr()));
 }
@@ -464,17 +465,22 @@
   return AutofillTable::FromWebDatabase(web_data_backend_->GetDatabase());
 }
 
+AutofillSyncMetadataTable* AutofillWalletSyncBridge::GetSyncMetadataStore() {
+  return AutofillSyncMetadataTable::FromWebDatabase(
+      web_data_backend_->GetDatabase());
+}
+
 void AutofillWalletSyncBridge::LoadMetadata() {
   if (!web_data_backend_ || !web_data_backend_->GetDatabase() ||
-      !GetAutofillTable()) {
+      !GetAutofillTable() || !GetSyncMetadataStore()) {
     change_processor()->ReportError(
         {FROM_HERE, "Failed to load AutofillWebDatabase."});
     return;
   }
 
   auto batch = std::make_unique<syncer::MetadataBatch>();
-  if (!GetAutofillTable()->GetAllSyncMetadata(syncer::AUTOFILL_WALLET_DATA,
-                                              batch.get())) {
+  if (!GetSyncMetadataStore()->GetAllSyncMetadata(syncer::AUTOFILL_WALLET_DATA,
+                                                  batch.get())) {
     change_processor()->ReportError(
         {FROM_HERE, "Failed reading autofill metadata from WebDatabase."});
     return;
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.h b/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.h
index 803d2b9..b21027e 100644
--- a/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.h
+++ b/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.h
@@ -20,6 +20,7 @@
 
 namespace autofill {
 
+class AutofillSyncMetadataTable;
 class AutofillTable;
 class AutofillWebDataBackend;
 class AutofillWebDataService;
@@ -113,6 +114,8 @@
   // Returns the table associated with the |web_data_backend_|.
   AutofillTable* GetAutofillTable();
 
+  AutofillSyncMetadataTable* GetSyncMetadataStore();
+
   // Synchronously load sync metadata from the autofill table and pass it to the
   // processor so that it can start tracking changes.
   void LoadMetadata();
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge_unittest.cc b/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge_unittest.cc
index 1bcdfa86..c2194c4 100644
--- a/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge_unittest.cc
+++ b/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge_unittest.cc
@@ -30,6 +30,7 @@
 #include "components/autofill/core/browser/test_autofill_clock.h"
 #include "components/autofill/core/browser/webdata/autofill_sync_bridge_test_util.h"
 #include "components/autofill/core/browser/webdata/autofill_sync_bridge_util.h"
+#include "components/autofill/core/browser/webdata/autofill_sync_metadata_table.h"
 #include "components/autofill/core/browser/webdata/autofill_table.h"
 #include "components/autofill/core/browser/webdata/autofill_webdata_backend.h"
 #include "components/autofill/core/browser/webdata/mock_autofill_webdata_backend.h"
@@ -257,6 +258,7 @@
     // Fix a time for implicitly constructed use_dates in AutofillProfile.
     test_clock_.SetNow(kJune2017);
     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+    db_.AddTable(&sync_metadata_table_);
     db_.AddTable(&table_);
     db_.Init(temp_dir_.GetPath().AppendASCII("SyncTestWebDatabase"));
     ON_CALL(*backend(), GetDatabase()).WillByDefault(Return(&db_));
@@ -283,8 +285,8 @@
     model_type_state.mutable_progress_marker()->set_data_type_id(
         GetSpecificsFieldNumberFromModelType(syncer::AUTOFILL_WALLET_DATA));
     model_type_state.set_cache_guid(kDefaultCacheGuid);
-    EXPECT_TRUE(table()->UpdateModelTypeState(syncer::AUTOFILL_WALLET_DATA,
-                                              model_type_state));
+    EXPECT_TRUE(sync_metadata_table()->UpdateModelTypeState(
+        syncer::AUTOFILL_WALLET_DATA, model_type_state));
     bridge_ = std::make_unique<AutofillWalletSyncBridge>(
         mock_processor_.CreateForwardingProcessor(), &backend_);
   }
@@ -364,6 +366,9 @@
   }
 
   AutofillTable* table() { return &table_; }
+  AutofillSyncMetadataTable* sync_metadata_table() {
+    return &sync_metadata_table_;
+  }
 
   MockAutofillWebDataBackend* backend() { return &backend_; }
 
@@ -372,6 +377,7 @@
   ScopedTempDir temp_dir_;
   base::test::SingleThreadTaskEnvironment task_environment_;
   NiceMock<MockAutofillWebDataBackend> backend_;
+  AutofillSyncMetadataTable sync_metadata_table_;
   AutofillTable table_;
   WebDatabase db_;
   testing::NiceMock<MockModelTypeChangeProcessor> mock_processor_;
@@ -940,8 +946,8 @@
 }
 
 TEST_F(AutofillWalletSyncBridgeTest, LoadMetadataCalled) {
-  EXPECT_TRUE(table()->UpdateEntityMetadata(syncer::AUTOFILL_WALLET_DATA, "key",
-                                            EntityMetadata()));
+  EXPECT_TRUE(sync_metadata_table()->UpdateEntityMetadata(
+      syncer::AUTOFILL_WALLET_DATA, "key", EntityMetadata()));
 
   ResetProcessor();
   EXPECT_CALL(mock_processor(), ModelReadyToSync(MetadataBatchContains(
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_usage_data_sync_bridge.cc b/components/autofill/core/browser/webdata/autofill_wallet_usage_data_sync_bridge.cc
index 6c387a2..fd0d749 100644
--- a/components/autofill/core/browser/webdata/autofill_wallet_usage_data_sync_bridge.cc
+++ b/components/autofill/core/browser/webdata/autofill_wallet_usage_data_sync_bridge.cc
@@ -11,6 +11,7 @@
 #include "components/autofill/core/browser/data_model/autofill_wallet_usage_data.h"
 #include "components/autofill/core/browser/metrics/payments/wallet_usage_data_metrics.h"
 #include "components/autofill/core/browser/webdata/autofill_sync_bridge_util.h"
+#include "components/autofill/core/browser/webdata/autofill_sync_metadata_table.h"
 #include "components/autofill/core/browser/webdata/autofill_table.h"
 #include "components/autofill/core/browser/webdata/autofill_webdata_backend.h"
 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
@@ -68,7 +69,7 @@
 AutofillWalletUsageDataSyncBridge::CreateMetadataChangeList() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   return std::make_unique<syncer::SyncMetadataStoreChangeList>(
-      GetAutofillTable(), syncer::AUTOFILL_WALLET_USAGE,
+      GetSyncMetadataStore(), syncer::AUTOFILL_WALLET_USAGE,
       base::BindRepeating(&syncer::ModelTypeChangeProcessor::ReportError,
                           change_processor()->GetWeakPtr()));
 }
@@ -201,16 +202,23 @@
   return AutofillTable::FromWebDatabase(web_data_backend_->GetDatabase());
 }
 
+AutofillSyncMetadataTable*
+AutofillWalletUsageDataSyncBridge::GetSyncMetadataStore() {
+  return AutofillSyncMetadataTable::FromWebDatabase(
+      web_data_backend_->GetDatabase());
+}
+
 void AutofillWalletUsageDataSyncBridge::LoadMetadata() {
-  if (!web_data_backend_->GetDatabase() || !GetAutofillTable()) {
+  if (!web_data_backend_->GetDatabase() || !GetAutofillTable() ||
+      !GetSyncMetadataStore()) {
     change_processor()->ReportError(
         {FROM_HERE, "Failed to load Autofill table."});
     return;
   }
 
   auto batch = std::make_unique<syncer::MetadataBatch>();
-  if (!GetAutofillTable()->GetAllSyncMetadata(syncer::AUTOFILL_WALLET_USAGE,
-                                              batch.get())) {
+  if (!GetSyncMetadataStore()->GetAllSyncMetadata(syncer::AUTOFILL_WALLET_USAGE,
+                                                  batch.get())) {
     change_processor()->ReportError(
         {FROM_HERE,
          "Failed reading Autofill Wallet usage metadata from WebDatabase."});
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_usage_data_sync_bridge.h b/components/autofill/core/browser/webdata/autofill_wallet_usage_data_sync_bridge.h
index dcf0e89..5ee6d02 100644
--- a/components/autofill/core/browser/webdata/autofill_wallet_usage_data_sync_bridge.h
+++ b/components/autofill/core/browser/webdata/autofill_wallet_usage_data_sync_bridge.h
@@ -18,6 +18,7 @@
 
 namespace autofill {
 
+class AutofillSyncMetadataTable;
 class AutofillTable;
 class AutofillWebDataBackend;
 class AutofillWebDataService;
@@ -69,6 +70,8 @@
   // Returns the table associated with the |web_data_backend_|.
   AutofillTable* GetAutofillTable();
 
+  AutofillSyncMetadataTable* GetSyncMetadataStore();
+
   // Synchronously load sync metadata from the autofill table and pass it to the
   // processor so that it can start tracking changes.
   void LoadMetadata();
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_usage_data_sync_bridge_unittest.cc b/components/autofill/core/browser/webdata/autofill_wallet_usage_data_sync_bridge_unittest.cc
index b0ba599..69a9547 100644
--- a/components/autofill/core/browser/webdata/autofill_wallet_usage_data_sync_bridge_unittest.cc
+++ b/components/autofill/core/browser/webdata/autofill_wallet_usage_data_sync_bridge_unittest.cc
@@ -18,6 +18,7 @@
 #include "components/autofill/core/browser/autofill_test_utils.h"
 #include "components/autofill/core/browser/test_autofill_clock.h"
 #include "components/autofill/core/browser/webdata/autofill_sync_bridge_util.h"
+#include "components/autofill/core/browser/webdata/autofill_sync_metadata_table.h"
 #include "components/autofill/core/browser/webdata/autofill_table.h"
 #include "components/autofill/core/browser/webdata/autofill_webdata_backend.h"
 #include "components/autofill/core/browser/webdata/mock_autofill_webdata_backend.h"
@@ -63,6 +64,7 @@
  public:
   void SetUp() override {
     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+    db_.AddTable(&sync_metadata_table_);
     db_.AddTable(&table_);
     db_.Init(temp_dir_.GetPath().AppendASCII("SyncTestWebDatabase"));
     ON_CALL(backend_, GetDatabase()).WillByDefault(Return(&db_));
@@ -113,6 +115,7 @@
   ScopedTempDir temp_dir_;
   base::test::SingleThreadTaskEnvironment task_environment_;
   NiceMock<MockAutofillWebDataBackend> backend_;
+  AutofillSyncMetadataTable sync_metadata_table_;
   AutofillTable table_;
   WebDatabase db_;
   NiceMock<MockModelTypeChangeProcessor> mock_processor_;
diff --git a/components/autofill/core/browser/webdata/contact_info_sync_bridge.cc b/components/autofill/core/browser/webdata/contact_info_sync_bridge.cc
index e6938cb..1abbf49 100644
--- a/components/autofill/core/browser/webdata/contact_info_sync_bridge.cc
+++ b/components/autofill/core/browser/webdata/contact_info_sync_bridge.cc
@@ -278,8 +278,9 @@
       web_data_backend_->GetDatabase());
 }
 
-AutofillTable* ContactInfoSyncBridge::GetSyncMetadataStore() {
-  return AutofillTable::FromWebDatabase(web_data_backend_->GetDatabase());
+AutofillSyncMetadataTable* ContactInfoSyncBridge::GetSyncMetadataStore() {
+  return AutofillSyncMetadataTable::FromWebDatabase(
+      web_data_backend_->GetDatabase());
 }
 
 std::unique_ptr<syncer::MutableDataBatch>
diff --git a/components/autofill/core/browser/webdata/contact_info_sync_bridge.h b/components/autofill/core/browser/webdata/contact_info_sync_bridge.h
index 174338b..31f26675 100644
--- a/components/autofill/core/browser/webdata/contact_info_sync_bridge.h
+++ b/components/autofill/core/browser/webdata/contact_info_sync_bridge.h
@@ -16,7 +16,7 @@
 #include "base/supports_user_data.h"
 #include "components/autofill/core/browser/contact_info_sync_util.h"
 #include "components/autofill/core/browser/webdata/addresses/address_autofill_table.h"
-#include "components/autofill/core/browser/webdata/autofill_table.h"
+#include "components/autofill/core/browser/webdata/autofill_sync_metadata_table.h"
 #include "components/autofill/core/browser/webdata/autofill_webdata_backend.h"
 #include "components/autofill/core/browser/webdata/autofill_webdata_service_observer.h"
 #include "components/sync/model/entity_change.h"
@@ -84,9 +84,7 @@
   // Returns the `AutofillTable` associated with the `web_data_backend_`.
   AddressAutofillTable* GetAutofillTable();
 
-  // AutofillTable acts as the metadata storage for all components/autofill-
-  // related sync code.
-  AutofillTable* GetSyncMetadataStore();
+  AutofillSyncMetadataTable* GetSyncMetadataStore();
 
   // Queries all `Source::kAccount` profiles from `GetAutofillTable()` and
   // restricts the result to profiles where `filter(guid)` is true.
diff --git a/components/autofill/core/browser/webdata/contact_info_sync_bridge_unittest.cc b/components/autofill/core/browser/webdata/contact_info_sync_bridge_unittest.cc
index c3bc7d08..8aa0b4ec 100644
--- a/components/autofill/core/browser/webdata/contact_info_sync_bridge_unittest.cc
+++ b/components/autofill/core/browser/webdata/contact_info_sync_bridge_unittest.cc
@@ -16,7 +16,7 @@
 #include "components/autofill/core/browser/data_model/autofill_profile.h"
 #include "components/autofill/core/browser/test_autofill_clock.h"
 #include "components/autofill/core/browser/webdata/addresses/address_autofill_table.h"
-#include "components/autofill/core/browser/webdata/autofill_table.h"
+#include "components/autofill/core/browser/webdata/autofill_sync_metadata_table.h"
 #include "components/autofill/core/browser/webdata/mock_autofill_webdata_backend.h"
 #include "components/sync/base/features.h"
 #include "components/sync/model/data_batch.h"
@@ -147,7 +147,7 @@
   base::test::SingleThreadTaskEnvironment task_environment_;
   testing::NiceMock<MockAutofillWebDataBackend> backend_;
   AddressAutofillTable table_;
-  AutofillTable sync_metadata_table_;
+  AutofillSyncMetadataTable sync_metadata_table_;
   WebDatabase db_;
   testing::NiceMock<syncer::MockModelTypeChangeProcessor> mock_processor_;
   std::unique_ptr<ContactInfoSyncBridge> bridge_;
diff --git a/components/autofill/core/common/logging/log_buffer.cc b/components/autofill/core/common/logging/log_buffer.cc
index 43cb93cf6..b1edaf1 100644
--- a/components/autofill/core/common/logging/log_buffer.cc
+++ b/components/autofill/core/common/logging/log_buffer.cc
@@ -5,6 +5,7 @@
 #include "components/autofill/core/common/logging/log_buffer.h"
 
 #include <string>
+#include <string_view>
 
 #include "base/strings/strcat.h"
 #include "base/strings/utf_string_conversions.h"
@@ -243,7 +244,7 @@
 // Highlights the first |needle| in |haystack| by wrapping it in <b> tags.
 template <typename T, typename CharT = typename T::value_type>
 LogBuffer HighlightValueInternal(T haystack, T needle) {
-  using StringPieceT = base::BasicStringPiece<CharT>;
+  using StringPieceT = std::basic_string_view<CharT>;
   LogBuffer buffer(LogBuffer::IsActive(true));
   size_t pos = haystack.find(needle);
   if (pos == StringPieceT::npos || needle.empty()) {
diff --git a/components/eye_dropper/eye_dropper_view.cc b/components/eye_dropper/eye_dropper_view.cc
index 2c35b33..424bc9e 100644
--- a/components/eye_dropper/eye_dropper_view.cc
+++ b/components/eye_dropper/eye_dropper_view.cc
@@ -30,7 +30,6 @@
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "ui/aura/client/screen_position_client.h"
-#include "ui/display/screen.h"
 #endif
 
 namespace eye_dropper {
@@ -47,8 +46,6 @@
 
   // Timer used for updating the window location.
   base::RepeatingTimer timer_;
-  gfx::Point last_cursor_position_ =
-      display::Screen::GetScreen()->GetCursorScreenPoint();
   raw_ptr<EyeDropperView> owner_;
 };
 
@@ -65,14 +62,8 @@
 }
 
 void EyeDropperView::ViewPositionHandler::UpdateViewPosition() {
-  // The view can be moved by either mouse or touch. Only move it to the cursor
-  // position when cursor changes.
-  gfx::Point cursor_position =
-      display::Screen::GetScreen()->GetCursorScreenPoint();
-  if (std::exchange(last_cursor_position_, cursor_position) !=
-      cursor_position) {
-    owner_->UpdatePosition(cursor_position);
-  }
+  owner_->OnCursorPositionUpdate(
+      display::Screen::GetScreen()->GetCursorScreenPoint());
 }
 
 class EyeDropperView::ScreenCapturer
@@ -233,7 +224,7 @@
   pre_dispatch_handler_ =
       std::make_unique<PreEventDispatchHandler>(this, event_handler);
   widget->Show();
-  CaptureInputIfNeeded();
+  CaptureInput();
   auto* screen = display::Screen::GetScreen();
   gfx::Point initial_position = screen->GetCursorScreenPoint();
 #if BUILDFLAG(IS_CHROMEOS_ASH)
@@ -259,6 +250,15 @@
   }
 }
 
+void EyeDropperView::OnCursorPositionUpdate(gfx::Point cursor_position) {
+  // The view can be moved by either mouse or touch. Only move it to the cursor
+  // position when cursor changes.
+  if (std::exchange(last_cursor_position_, cursor_position) !=
+      cursor_position) {
+    UpdatePosition(std::move(cursor_position));
+  }
+}
+
 void EyeDropperView::OnPaint(gfx::Canvas* view_canvas) {
   if (screen_capturer_->GetBitmap().drawsNothing()) {
     return;
diff --git a/components/eye_dropper/eye_dropper_view.h b/components/eye_dropper/eye_dropper_view.h
index 4982dac..5d791689 100644
--- a/components/eye_dropper/eye_dropper_view.h
+++ b/components/eye_dropper/eye_dropper_view.h
@@ -15,6 +15,7 @@
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h"
 #include "ui/base/metadata/metadata_header_macros.h"
+#include "ui/display/screen.h"
 #include "ui/gfx/geometry/point.h"
 #include "ui/views/widget/widget_delegate.h"
 
@@ -40,6 +41,14 @@
   EyeDropperView& operator=(const EyeDropperView&) = delete;
   ~EyeDropperView() override;
 
+  // Called regularly to notify what the current cursor position is. Cursor
+  // position may not have changed between calls.
+  void OnCursorPositionUpdate(gfx::Point cursor_position);
+
+  ui::EventHandler* GetEventHandlerForTesting() {
+    return pre_dispatch_handler_.get();
+  }
+
  protected:
   // views::WidgetDelegateView:
   void OnPaint(gfx::Canvas* canvas) override;
@@ -84,7 +93,7 @@
   // Moves the view to the specified position.
   void UpdatePosition(gfx::Point position);
 
-  void CaptureInputIfNeeded();
+  void CaptureInput();
 
   void HideCursor();
   void ShowCursor();
@@ -104,6 +113,8 @@
   std::unique_ptr<ScreenCapturer> screen_capturer_;
   absl::optional<SkColor> selected_color_;
   base::TimeTicks ignore_selection_time_;
+  gfx::Point last_cursor_position_ =
+      display::Screen::GetScreen()->GetCursorScreenPoint();
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   // When the widget moves across displays we update the screenshot.
diff --git a/components/eye_dropper/eye_dropper_view_aura.cc b/components/eye_dropper/eye_dropper_view_aura.cc
index 67c25c8..39036ab 100644
--- a/components/eye_dropper/eye_dropper_view_aura.cc
+++ b/components/eye_dropper/eye_dropper_view_aura.cc
@@ -135,12 +135,10 @@
   }
 }
 
-void EyeDropperView::CaptureInputIfNeeded() {
-#if BUILDFLAG(IS_LINUX)
+void EyeDropperView::CaptureInput() {
   // The eye dropper needs to capture input since it is not activated
   // in order to avoid dismissing the color picker.
   GetWidget()->GetNativeWindow()->SetCapture();
-#endif
 }
 
 void EyeDropperView::HideCursor() {
diff --git a/components/favicon/android/large_icon_bridge.cc b/components/favicon/android/large_icon_bridge.cc
index f8346d7..c50e30b 100644
--- a/components/favicon/android/large_icon_bridge.cc
+++ b/components/favicon/android/large_icon_bridge.cc
@@ -55,14 +55,6 @@
       static_cast<int>(result.bitmap.icon_type));
 }
 
-void OnGoogleFaviconServerResponse(
-    const JavaRef<jobject>& j_callback,
-    favicon_base::GoogleFaviconServerRequestStatus status) {
-  JNIEnv* env = AttachCurrentThread();
-  Java_GoogleFaviconServerCallback_onRequestComplete(env, j_callback,
-                                                     static_cast<int>(status));
-}
-
 }  // namespace
 
 static jlong JNI_LargeIconBridge_Init(JNIEnv* env) {
@@ -131,7 +123,8 @@
       url::GURLAndroid::ToNativeGURL(env, j_page_url);
   CHECK(page_url);
   favicon_base::GoogleFaviconServerCallback callback =
-      base::BindOnce(&OnGoogleFaviconServerResponse,
+      base::BindOnce(&LargeIconBridge::OnGoogleFaviconServerResponse,
+                     weak_factory_.GetWeakPtr(),
                      ScopedJavaGlobalRef<jobject>(env, j_callback));
   large_icon_service
       ->GetLargeIconOrFallbackStyleFromGoogleServerSkippingLocalCache(
@@ -162,4 +155,12 @@
   large_icon_service->TouchIconFromGoogleServer(*icon_url);
 }
 
+void LargeIconBridge::OnGoogleFaviconServerResponse(
+    const JavaRef<jobject>& j_callback,
+    favicon_base::GoogleFaviconServerRequestStatus status) const {
+  JNIEnv* env = AttachCurrentThread();
+  Java_GoogleFaviconServerCallback_onRequestComplete(env, j_callback,
+                                                     static_cast<int>(status));
+}
+
 }  // namespace favicon
diff --git a/components/favicon/android/large_icon_bridge.h b/components/favicon/android/large_icon_bridge.h
index aff8b2d..8b5d184 100644
--- a/components/favicon/android/large_icon_bridge.h
+++ b/components/favicon/android/large_icon_bridge.h
@@ -8,7 +8,9 @@
 #include <jni.h>
 
 #include "base/android/scoped_java_ref.h"
+#include "base/memory/weak_ptr.h"
 #include "base/task/cancelable_task_tracker.h"
+#include "components/favicon_base/favicon_types.h"
 
 namespace favicon {
 
@@ -44,7 +46,15 @@
  private:
   virtual ~LargeIconBridge();
 
+  void OnGoogleFaviconServerResponse(
+      const base::android::JavaRef<jobject>& j_callback,
+      favicon_base::GoogleFaviconServerRequestStatus status) const;
+
+  // TODO(crbug.com/1513063): Remove this when LargeIconService no longer relies
+  //                          on CancelableTaskTracker.
   base::CancelableTaskTracker cancelable_task_tracker_;
+
+  base::WeakPtrFactory<LargeIconBridge> weak_factory_{this};
 };
 
 }  // namespace favicon
diff --git a/components/optimization_guide/internal b/components/optimization_guide/internal
index c5958b4..d2162208 160000
--- a/components/optimization_guide/internal
+++ b/components/optimization_guide/internal
@@ -1 +1 @@
-Subproject commit c5958b418ccfabbc5d4c216aada60902fd1c4784
+Subproject commit d2162208bcf500cdd93945ddc7ee633361f9dfa5
diff --git a/components/password_manager/core/browser/credential_cache.cc b/components/password_manager/core/browser/credential_cache.cc
index 5206bb5..ffe7211 100644
--- a/components/password_manager/core/browser/credential_cache.cc
+++ b/components/password_manager/core/browser/credential_cache.cc
@@ -41,8 +41,19 @@
                           return credential.origin() == origin;
                         });
   GetOrCreateCredentialStore(origin).SaveCredentials(std::move(credentials));
+
   GetOrCreateCredentialStore(origin).SetBlocklistedStatus(
       is_blocklisted.value());
+
+  std::vector<PasswordForm> unnotified_shared_credentials;
+  for (const PasswordForm* form : best_matches) {
+    if (form->type == PasswordForm::Type::kReceivedViaSharing &&
+        !form->sharing_notification_displayed) {
+      unnotified_shared_credentials.push_back(*form);
+    }
+  }
+  GetOrCreateCredentialStore(origin).SaveUnnotifiedSharedCredentials(
+      std::move(unnotified_shared_credentials));
 }
 
 const OriginCredentialStore& CredentialCache::GetCredentialStore(
diff --git a/components/password_manager/core/browser/credential_cache_unittest.cc b/components/password_manager/core/browser/credential_cache_unittest.cc
index b55b288..023a0a7 100644
--- a/components/password_manager/core/browser/credential_cache_unittest.cc
+++ b/components/password_manager/core/browser/credential_cache_unittest.cc
@@ -117,7 +117,36 @@
                            password_manager_util::GetLoginMatchType::kPSL)));
 }
 
-TEST_F(CredentialCacheTest, StoredCredentialsForIndependentOrigins) {
+TEST_F(CredentialCacheTest, StoresUnnotifiedSharedCredentialsCredentials) {
+  Origin origin = Origin::Create(GURL(kExampleSite));
+
+  std::unique_ptr<PasswordForm> non_shared_credentials =
+      CreateEntry("non_shared", "pass", GURL(kExampleSite),
+                  PasswordForm::MatchType::kExact);
+
+  std::unique_ptr<PasswordForm> shared_notified_credentials =
+      CreateEntry("shared_notified", "pass", GURL(kExampleSite),
+                  PasswordForm::MatchType::kExact);
+  shared_notified_credentials->type = PasswordForm::Type::kReceivedViaSharing;
+  shared_notified_credentials->sharing_notification_displayed = true;
+
+  std::unique_ptr<PasswordForm> shared_unnotified_credentials =
+      CreateEntry("shared_unnotified", "pass", GURL(kExampleSite),
+                  PasswordForm::MatchType::kExact);
+  shared_unnotified_credentials->type = PasswordForm::Type::kReceivedViaSharing;
+  shared_unnotified_credentials->sharing_notification_displayed = false;
+
+  cache()->SaveCredentialsAndBlocklistedForOrigin(
+      {non_shared_credentials.get(), shared_notified_credentials.get(),
+       shared_unnotified_credentials.get()},
+      IsOriginBlocklisted(false), origin);
+
+  EXPECT_THAT(
+      cache()->GetCredentialStore(origin).GetUnnotifiedSharedCredentials(),
+      testing::ElementsAre(*shared_unnotified_credentials));
+}
+
+TEST_F(CredentialCacheTest, StoresCredentialsForIndependentOrigins) {
   Origin origin = Origin::Create(GURL(kExampleSite));
   Origin origin2 = Origin::Create(GURL(kExampleSite2));
 
diff --git a/components/webcrypto/algorithms/aes.cc b/components/webcrypto/algorithms/aes.cc
index a4f9ecdd..12b37f98 100644
--- a/components/webcrypto/algorithms/aes.cc
+++ b/components/webcrypto/algorithms/aes.cc
@@ -7,7 +7,6 @@
 #include <stddef.h>
 
 #include "base/strings/strcat.h"
-#include "base/strings/string_piece.h"
 #include "components/webcrypto/algorithms/secret_key_util.h"
 #include "components/webcrypto/algorithms/util.h"
 #include "components/webcrypto/blink_key_handle.h"
@@ -22,7 +21,7 @@
 
 // Creates an AES algorithm name for the given key size (in bytes). For
 // instance "A128CBC" is the result of suffix="CBC", keylen_bytes=16.
-std::string MakeJwkAesAlgorithmName(base::StringPiece suffix,
+std::string MakeJwkAesAlgorithmName(std::string_view suffix,
                                     size_t keylen_bytes) {
   if (keylen_bytes == 16)
     return base::StrCat({"A128", suffix});
@@ -44,10 +43,10 @@
 }  // namespace
 
 AesAlgorithm::AesAlgorithm(blink::WebCryptoKeyUsageMask all_key_usages,
-                           base::StringPiece jwk_suffix)
+                           std::string_view jwk_suffix)
     : all_key_usages_(all_key_usages), jwk_suffix_(jwk_suffix) {}
 
-AesAlgorithm::AesAlgorithm(base::StringPiece jwk_suffix)
+AesAlgorithm::AesAlgorithm(std::string_view jwk_suffix)
     : all_key_usages_(blink::kWebCryptoKeyUsageEncrypt |
                       blink::kWebCryptoKeyUsageDecrypt |
                       blink::kWebCryptoKeyUsageWrapKey |
diff --git a/components/webcrypto/algorithms/aes.h b/components/webcrypto/algorithms/aes.h
index b02f500..3c2716a6 100644
--- a/components/webcrypto/algorithms/aes.h
+++ b/components/webcrypto/algorithms/aes.h
@@ -7,7 +7,8 @@
 
 #include <stdint.h>
 
-#include "base/strings/string_piece.h"
+#include <string_view>
+
 #include "components/webcrypto/algorithm_implementation.h"
 
 namespace webcrypto {
@@ -22,12 +23,12 @@
   // is the JWK name for 128-bit AES-CBC. The |jwk_suffix| in this case would
   // be "CBC".
   AesAlgorithm(blink::WebCryptoKeyUsageMask all_key_usages,
-               base::StringPiece jwk_suffix);
+               std::string_view jwk_suffix);
 
   // This is the same as the other AesAlgorithm constructor where
   // |all_key_usages| is pre-filled to values for encryption/decryption
   // algorithms (supports usages for: encrypt, decrypt, wrap, unwrap).
-  explicit AesAlgorithm(base::StringPiece jwk_suffix);
+  explicit AesAlgorithm(std::string_view jwk_suffix);
 
   Status GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
                      bool extractable,
diff --git a/components/webcrypto/algorithms/ec.cc b/components/webcrypto/algorithms/ec.cc
index eb3a072c..b4af6ab 100644
--- a/components/webcrypto/algorithms/ec.cc
+++ b/components/webcrypto/algorithms/ec.cc
@@ -6,6 +6,7 @@
 
 #include <stddef.h>
 
+#include <string_view>
 #include <utility>
 
 #include "base/containers/span.h"
@@ -156,7 +157,7 @@
 
 // Writes an unsigned BIGNUM into |jwk|, zero-padding it to a length of
 // |padded_length|.
-Status WritePaddedBIGNUM(base::StringPiece member_name,
+Status WritePaddedBIGNUM(std::string_view member_name,
                          const BIGNUM* value,
                          size_t padded_length,
                          JwkWriter* jwk) {
@@ -169,7 +170,7 @@
 
 // Reads a fixed length BIGNUM from a JWK.
 Status ReadPaddedBIGNUM(const JwkReader& jwk,
-                        base::StringPiece member_name,
+                        std::string_view member_name,
                         size_t expected_length,
                         bssl::UniquePtr<BIGNUM>* out) {
   std::vector<uint8_t> bytes;
diff --git a/components/webcrypto/algorithms/ed25519.cc b/components/webcrypto/algorithms/ed25519.cc
index adf8808..a5e0595 100644
--- a/components/webcrypto/algorithms/ed25519.cc
+++ b/components/webcrypto/algorithms/ed25519.cc
@@ -2,9 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "components/webcrypto/algorithms/ed25519.h"
+
 #include <string.h>
 
-#include "components/webcrypto/algorithms/ed25519.h"
+#include <string_view>
 
 #include "components/webcrypto/algorithms/asymmetric_key_util.h"
 #include "components/webcrypto/algorithms/util.h"
@@ -64,7 +66,7 @@
 
 // Reads a fixed length base64url-decoded bytes from a JWK.
 Status ReadBytes(const JwkReader& jwk,
-                 base::StringPiece member_name,
+                 std::string_view member_name,
                  size_t expected_length,
                  std::vector<uint8_t>* out) {
   std::vector<uint8_t> bytes;
diff --git a/components/webcrypto/algorithms/rsa.cc b/components/webcrypto/algorithms/rsa.cc
index ac7a5ec..e4b84fb8 100644
--- a/components/webcrypto/algorithms/rsa.cc
+++ b/components/webcrypto/algorithms/rsa.cc
@@ -6,9 +6,10 @@
 
 #include <utility>
 
+#include <string_view>
+
 #include "base/check_op.h"
 #include "base/containers/span.h"
-#include "base/strings/string_piece.h"
 #include "components/webcrypto/algorithms/asymmetric_key_util.h"
 #include "components/webcrypto/algorithms/util.h"
 #include "components/webcrypto/blink_key_handle.h"
@@ -50,7 +51,7 @@
 //     present.
 //   * expected_usages must be a subset of the JWK's "key_ops" if present.
 Status ReadRsaKeyJwk(base::span<const uint8_t> key_data,
-                     base::StringPiece expected_alg,
+                     std::string_view expected_alg,
                      bool expected_extractable,
                      blink::WebCryptoKeyUsageMask expected_usages,
                      JwkRsaInfo* result) {
diff --git a/components/webcrypto/algorithms/rsa_oaep_unittest.cc b/components/webcrypto/algorithms/rsa_oaep_unittest.cc
index 8081f97c..11a9de1 100644
--- a/components/webcrypto/algorithms/rsa_oaep_unittest.cc
+++ b/components/webcrypto/algorithms/rsa_oaep_unittest.cc
@@ -5,6 +5,8 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <string_view>
+
 #include "base/base64url.h"
 #include "base/containers/span.h"
 #include "components/webcrypto/algorithm_dispatch.h"
@@ -32,8 +34,8 @@
   // https://tools.ietf.org/html/draft-ietf-jose-json-web-signature-36#section-2
   std::string base64url_encoded;
   base::Base64UrlEncode(
-      base::StringPiece(reinterpret_cast<const char*>(input.data()),
-                        input.size()),
+      std::string_view(reinterpret_cast<const char*>(input.data()),
+                       input.size()),
       base::Base64UrlEncodePolicy::OMIT_PADDING, &base64url_encoded);
   return base64url_encoded;
 }
diff --git a/components/webcrypto/algorithms/rsa_ssa_unittest.cc b/components/webcrypto/algorithms/rsa_ssa_unittest.cc
index c2fbbec..229d204 100644
--- a/components/webcrypto/algorithms/rsa_ssa_unittest.cc
+++ b/components/webcrypto/algorithms/rsa_ssa_unittest.cc
@@ -5,9 +5,10 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <string_view>
+
 #include "base/check_op.h"
 #include "base/containers/span.h"
-#include "base/strings/string_piece.h"
 #include "base/strings/string_util.h"
 #include "base/values.h"
 #include "components/webcrypto/algorithm_dispatch.h"
@@ -66,7 +67,7 @@
   d.Set(b, std::move(*va));
 }
 
-std::string FlipHexByte(base::StringPiece hex, size_t index) {
+std::string FlipHexByte(std::string_view hex, size_t index) {
   auto bytes = HexStringToBytes(hex);
   bytes[index] ^= 0xff;
   return base::HexEncode(base::make_span(bytes));
@@ -78,7 +79,7 @@
       blink::kWebCryptoAlgorithmIdSha256);
 }
 
-blink::WebCryptoKey ImportJwkRS256OrDie(base::StringPiece jwk) {
+blink::WebCryptoKey ImportJwkRS256OrDie(std::string_view jwk) {
   std::vector<uint8_t> jwk_bytes(jwk.begin(), jwk.end());
   blink::WebCryptoKey key;
   Status status =
@@ -96,7 +97,7 @@
   return key;
 }
 
-Status ImportJwkRS256MustFail(base::StringPiece jwk) {
+Status ImportJwkRS256MustFail(std::string_view jwk) {
   std::vector<uint8_t> jwk_bytes(jwk.begin(), jwk.end());
   blink::WebCryptoKey key;
   Status status =
@@ -112,7 +113,7 @@
                               blink::kWebCryptoKeyUsageSign, &key);
 }
 
-Status ImportSpkiRS256MustFail(base::StringPiece spki) {
+Status ImportSpkiRS256MustFail(std::string_view spki) {
   auto spki_bytes = HexStringToBytes(spki);
   blink::WebCryptoKey key;
   // Note: SPKI keys can only be used for verification, not signing.
@@ -123,7 +124,7 @@
   return status;
 }
 
-Status ImportPkcs8RS256MustFail(base::StringPiece pkcs8) {
+Status ImportPkcs8RS256MustFail(std::string_view pkcs8) {
   auto pkcs8_bytes = HexStringToBytes(pkcs8);
   blink::WebCryptoKey key;
   Status status =
@@ -277,7 +278,7 @@
       "ECp9uhuF6RLlP6TGVhLjiL93h5aLjvYqluo2FhBlOshkKz4MrhH8To9JKefTQ\"}";
 
   EXPECT_BYTES_EQ(
-      base::as_bytes(base::make_span(base::StringPiece(expected_jwk))),
+      base::as_bytes(base::make_span(std::string_view(expected_jwk))),
       exported_key_jwk);
 
   ASSERT_EQ(Status::Success(),
diff --git a/components/webcrypto/algorithms/secret_key_util.cc b/components/webcrypto/algorithms/secret_key_util.cc
index c23098b..24afc5a 100644
--- a/components/webcrypto/algorithms/secret_key_util.cc
+++ b/components/webcrypto/algorithms/secret_key_util.cc
@@ -4,7 +4,6 @@
 
 #include "components/webcrypto/algorithms/secret_key_util.h"
 
-#include "base/strings/string_piece.h"
 #include "components/webcrypto/algorithms/util.h"
 #include "components/webcrypto/blink_key_handle.h"
 #include "components/webcrypto/generate_key_result.h"
@@ -50,7 +49,7 @@
 }
 
 void WriteSecretKeyJwk(base::span<const uint8_t> raw_key_data,
-                       base::StringPiece algorithm,
+                       std::string_view algorithm,
                        bool extractable,
                        blink::WebCryptoKeyUsageMask usages,
                        std::vector<uint8_t>* jwk_key_data) {
diff --git a/components/webcrypto/algorithms/secret_key_util.h b/components/webcrypto/algorithms/secret_key_util.h
index d4c29124..2349941 100644
--- a/components/webcrypto/algorithms/secret_key_util.h
+++ b/components/webcrypto/algorithms/secret_key_util.h
@@ -8,6 +8,7 @@
 #include <stdint.h>
 
 #include <string>
+#include <string_view>
 #include <vector>
 
 #include "base/containers/span.h"
@@ -48,7 +49,7 @@
 //  * extractable: The JWK extractability (i.e. "ext")
 //  * usages: The JWK usages (i.e. "key_ops")
 void WriteSecretKeyJwk(base::span<const uint8_t> raw_key_data,
-                       base::StringPiece algorithm,
+                       std::string_view algorithm,
                        bool extractable,
                        blink::WebCryptoKeyUsageMask usages,
                        std::vector<uint8_t>* jwk_key_data);
diff --git a/components/webcrypto/algorithms/test_helpers.cc b/components/webcrypto/algorithms/test_helpers.cc
index f44542b..a81cd8f 100644
--- a/components/webcrypto/algorithms/test_helpers.cc
+++ b/components/webcrypto/algorithms/test_helpers.cc
@@ -16,7 +16,6 @@
 #include "base/memory/raw_ptr.h"
 #include "base/path_service.h"
 #include "base/strings/string_number_conversions.h"
-#include "base/strings/string_piece.h"
 #include "base/strings/string_util.h"
 #include "base/values.h"
 #include "components/webcrypto/algorithm_dispatch.h"
@@ -31,7 +30,7 @@
 
 namespace {
 
-bool Base64DecodeUrlSafe(base::StringPiece input, std::string* output) {
+bool Base64DecodeUrlSafe(std::string_view input, std::string* output) {
   // The JSON web signature spec says that padding is omitted.
   // https://tools.ietf.org/html/draft-ietf-jose-json-web-signature-36#section-2
   return base::Base64UrlDecode(
@@ -128,7 +127,7 @@
   return corrupted_data;
 }
 
-std::vector<uint8_t> HexStringToBytes(base::StringPiece hex) {
+std::vector<uint8_t> HexStringToBytes(std::string_view hex) {
   std::vector<uint8_t> bytes;
 
   // HexStringToBytes() doesn't allow empty inputs, but this wrapper does.
@@ -156,7 +155,7 @@
 }
 
 std::vector<uint8_t> GetBytesFromHexString(const base::Value::Dict& dict,
-                                           base::StringPiece property_name) {
+                                           std::string_view property_name) {
   const std::string* hex_string = dict.FindStringByDottedPath(property_name);
   if (!hex_string) {
     ADD_FAILURE() << "Couldn't get string property: " << property_name;
@@ -316,8 +315,8 @@
 
 absl::optional<base::Value::Dict> GetJwkDictionary(
     const std::vector<uint8_t>& json) {
-  base::StringPiece json_string(reinterpret_cast<const char*>(json.data()),
-                                json.size());
+  std::string_view json_string(reinterpret_cast<const char*>(json.data()),
+                               json.size());
   absl::optional<base::Value> value = base::JSONReader::Read(json_string);
   EXPECT_TRUE(value.has_value());
   EXPECT_TRUE(value.value().is_dict());
@@ -328,8 +327,8 @@
 // required on the fields examined.
 ::testing::AssertionResult VerifyJwk(
     const base::Value::Dict& dict,
-    base::StringPiece kty_expected,
-    base::StringPiece alg_expected,
+    std::string_view kty_expected,
+    std::string_view alg_expected,
     blink::WebCryptoKeyUsageMask use_mask_expected) {
   // ---- kty
   const std::string* value_string = dict.FindString("kty");
@@ -377,8 +376,8 @@
 
 ::testing::AssertionResult VerifySecretJwk(
     const std::vector<uint8_t>& json,
-    base::StringPiece alg_expected,
-    base::StringPiece k_expected_hex,
+    std::string_view alg_expected,
+    std::string_view k_expected_hex,
     blink::WebCryptoKeyUsageMask use_mask_expected) {
   absl::optional<base::Value::Dict> dict = GetJwkDictionary(json);
   if (!dict.has_value() || dict.value().empty())
@@ -403,9 +402,9 @@
 
 ::testing::AssertionResult VerifyPublicJwk(
     const std::vector<uint8_t>& json,
-    base::StringPiece alg_expected,
-    base::StringPiece n_expected_hex,
-    base::StringPiece e_expected_hex,
+    std::string_view alg_expected,
+    std::string_view n_expected_hex,
+    std::string_view e_expected_hex,
     blink::WebCryptoKeyUsageMask use_mask_expected) {
   absl::optional<base::Value::Dict> dict = GetJwkDictionary(json);
   if (!dict.has_value() || dict.value().empty())
@@ -445,7 +444,7 @@
     int key_len_bits,
     const blink::WebCryptoAlgorithm& import_algorithm,
     blink::WebCryptoKeyUsageMask usages,
-    base::StringPiece jwk_alg) {
+    std::string_view jwk_alg) {
   std::vector<uint8_t> json;
   std::string key_hex;
 
@@ -571,7 +570,7 @@
   return CurveNameToCurve(*curve_str);
 }
 
-blink::WebCryptoNamedCurve CurveNameToCurve(base::StringPiece name) {
+blink::WebCryptoNamedCurve CurveNameToCurve(std::string_view name) {
   if (name == "P-256")
     return blink::kWebCryptoNamedCurveP256;
   if (name == "P-384")
diff --git a/components/webcrypto/algorithms/test_helpers.h b/components/webcrypto/algorithms/test_helpers.h
index 44ba0289..912522fa 100644
--- a/components/webcrypto/algorithms/test_helpers.h
+++ b/components/webcrypto/algorithms/test_helpers.h
@@ -10,10 +10,10 @@
 #include <memory>
 #include <ostream>
 #include <string>
+#include <string_view>
 #include <vector>
 
 #include "base/strings/string_number_conversions.h"
-#include "base/strings/string_piece.h"
 #include "base/values.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -66,7 +66,7 @@
 //  - For empty inputs, a byte is added.
 std::vector<uint8_t> Corrupted(const std::vector<uint8_t>& input);
 
-std::vector<uint8_t> HexStringToBytes(base::StringPiece hex);
+std::vector<uint8_t> HexStringToBytes(std::string_view hex);
 
 // Serialize |value| to json, then return that json as a byte vector.
 std::vector<uint8_t> MakeJsonVector(const base::ValueView& value);
@@ -85,7 +85,7 @@
 //
 // Returns empty vector on failure.
 std::vector<uint8_t> GetBytesFromHexString(const base::Value::Dict& dict,
-                                           base::StringPiece property_name);
+                                           std::string_view property_name);
 
 // Reads a string property with path "property_name" and converts it to a
 // WebCryptoAlgorithm. Returns null algorithm on failure.
@@ -139,23 +139,23 @@
 // required on the fields examined.
 ::testing::AssertionResult VerifyJwk(
     const base::Value::Dict& dict,
-    base::StringPiece kty_expected,
-    base::StringPiece alg_expected,
+    std::string_view kty_expected,
+    std::string_view alg_expected,
     blink::WebCryptoKeyUsageMask use_mask_expected);
 
 ::testing::AssertionResult VerifySecretJwk(
     const std::vector<uint8_t>& json,
-    base::StringPiece alg_expected,
-    base::StringPiece k_expected_hex,
+    std::string_view alg_expected,
+    std::string_view k_expected_hex,
     blink::WebCryptoKeyUsageMask use_mask_expected);
 
 // Verifies that the JSON in the input vector contains the provided
 // expected values. Exact matches are required on the fields examined.
 ::testing::AssertionResult VerifyPublicJwk(
     const std::vector<uint8_t>& json,
-    base::StringPiece alg_expected,
-    base::StringPiece n_expected_hex,
-    base::StringPiece e_expected_hex,
+    std::string_view alg_expected,
+    std::string_view n_expected_hex,
+    std::string_view e_expected_hex,
     blink::WebCryptoKeyUsageMask use_mask_expected);
 
 // Helper that tests importing ane exporting of symmetric keys as JWK.
@@ -163,7 +163,7 @@
     int key_len_bits,
     const blink::WebCryptoAlgorithm& import_algorithm,
     blink::WebCryptoKeyUsageMask usages,
-    base::StringPiece jwk_alg);
+    std::string_view jwk_alg);
 
 // Wrappers around GenerateKey() which expect the result to be either a secret
 // key or a public/private keypair. If the result does not match the
@@ -193,7 +193,7 @@
 blink::WebCryptoNamedCurve GetCurveNameFromDictionary(
     const base::Value::Dict& dict);
 
-blink::WebCryptoNamedCurve CurveNameToCurve(base::StringPiece name);
+blink::WebCryptoNamedCurve CurveNameToCurve(std::string_view name);
 
 // Creates an HMAC import algorithm whose inner hash algorithm is determined by
 // the specified algorithm ID. It is an error to call this method with a hash
diff --git a/components/webcrypto/algorithms/x25519.cc b/components/webcrypto/algorithms/x25519.cc
index 7a2aff83..b926c5f 100644
--- a/components/webcrypto/algorithms/x25519.cc
+++ b/components/webcrypto/algorithms/x25519.cc
@@ -4,6 +4,8 @@
 
 #include "components/webcrypto/algorithms/x25519.h"
 
+#include <string_view>
+
 #include "components/webcrypto/algorithms/asymmetric_key_util.h"
 #include "components/webcrypto/algorithms/util.h"
 #include "components/webcrypto/blink_key_handle.h"
@@ -64,7 +66,7 @@
 
 // Reads a fixed length base64url-decoded bytes from a JWK.
 Status ReadBytes(const JwkReader& jwk,
-                 base::StringPiece member_name,
+                 std::string_view member_name,
                  size_t expected_length,
                  std::vector<uint8_t>* out) {
   std::vector<uint8_t> bytes;
diff --git a/components/webcrypto/jwk.cc b/components/webcrypto/jwk.cc
index d99380b..b0240e8 100644
--- a/components/webcrypto/jwk.cc
+++ b/components/webcrypto/jwk.cc
@@ -13,7 +13,6 @@
 #include "base/base64url.h"
 #include "base/json/json_reader.h"
 #include "base/json/json_writer.h"
-#include "base/strings/string_piece.h"
 #include "base/strings/stringprintf.h"
 #include "base/values.h"
 #include "components/webcrypto/algorithms/util.h"
@@ -87,7 +86,7 @@
     {"wrapKey", blink::kWebCryptoKeyUsageWrapKey},
     {"unwrapKey", blink::kWebCryptoKeyUsageUnwrapKey}};
 
-bool JwkKeyOpToWebCryptoUsage(base::StringPiece key_op,
+bool JwkKeyOpToWebCryptoUsage(std::string_view key_op,
                               blink::WebCryptoKeyUsage* usage) {
   for (const auto& crypto_usage_entry : kJwkWebCryptoUsageMap) {
     if (crypto_usage_entry.jwk_key_op == key_op) {
@@ -200,11 +199,11 @@
 Status JwkReader::Init(base::span<const uint8_t> bytes,
                        bool expected_extractable,
                        blink::WebCryptoKeyUsageMask expected_usages,
-                       base::StringPiece expected_kty,
-                       base::StringPiece expected_alg) {
+                       std::string_view expected_kty,
+                       std::string_view expected_alg) {
   // Parse the incoming JWK JSON.
-  base::StringPiece json_string(reinterpret_cast<const char*>(bytes.data()),
-                                bytes.size());
+  std::string_view json_string(reinterpret_cast<const char*>(bytes.data()),
+                               bytes.size());
 
   {
     // Limit the visibility for |value| as it is moved to |dict_| (via
@@ -244,11 +243,11 @@
   return Status::Success();
 }
 
-bool JwkReader::HasMember(base::StringPiece member_name) const {
+bool JwkReader::HasMember(std::string_view member_name) const {
   return dict_.contains(member_name);
 }
 
-Status JwkReader::GetString(base::StringPiece member_name,
+Status JwkReader::GetString(std::string_view member_name,
                             std::string* result) const {
   const base::Value* value = dict_.Find(member_name);
   if (!value) {
@@ -261,7 +260,7 @@
   return Status::Success();
 }
 
-Status JwkReader::GetOptionalString(base::StringPiece member_name,
+Status JwkReader::GetOptionalString(std::string_view member_name,
                                     std::string* result,
                                     bool* member_exists) const {
   *member_exists = false;
@@ -279,7 +278,7 @@
   return Status::Success();
 }
 
-Status JwkReader::GetOptionalList(base::StringPiece member_name,
+Status JwkReader::GetOptionalList(std::string_view member_name,
                                   const base::Value::List** result,
                                   bool* member_exists) const {
   *member_exists = false;
@@ -297,7 +296,7 @@
   return Status::Success();
 }
 
-Status JwkReader::GetBytes(base::StringPiece member_name,
+Status JwkReader::GetBytes(std::string_view member_name,
                            std::vector<uint8_t>* result) const {
   std::string base64_string;
   Status status = GetString(member_name, &base64_string);
@@ -317,7 +316,7 @@
   return Status::Success();
 }
 
-Status JwkReader::GetBigInteger(base::StringPiece member_name,
+Status JwkReader::GetBigInteger(std::string_view member_name,
                                 std::vector<uint8_t>* result) const {
   Status status = GetBytes(member_name, result);
   if (status.IsError())
@@ -335,7 +334,7 @@
   return Status::Success();
 }
 
-Status JwkReader::GetOptionalBool(base::StringPiece member_name,
+Status JwkReader::GetOptionalBool(std::string_view member_name,
                                   bool* result,
                                   bool* member_exists) const {
   *member_exists = false;
@@ -357,7 +356,7 @@
   return GetOptionalString("alg", alg, has_alg);
 }
 
-Status JwkReader::VerifyAlg(base::StringPiece expected_alg) const {
+Status JwkReader::VerifyAlg(std::string_view expected_alg) const {
   bool has_jwk_alg;
   std::string jwk_alg_value;
   Status status = GetAlg(&jwk_alg_value, &has_jwk_alg);
@@ -370,10 +369,10 @@
   return Status::Success();
 }
 
-JwkWriter::JwkWriter(base::StringPiece algorithm,
+JwkWriter::JwkWriter(std::string_view algorithm,
                      bool extractable,
                      blink::WebCryptoKeyUsageMask usages,
-                     base::StringPiece kty) {
+                     std::string_view kty) {
   if (!algorithm.empty()) {
     dict_.Set("alg", algorithm);
   }
@@ -382,19 +381,19 @@
   dict_.Set("kty", kty);
 }
 
-void JwkWriter::SetString(base::StringPiece member_name,
-                          base::StringPiece value) {
+void JwkWriter::SetString(std::string_view member_name,
+                          std::string_view value) {
   dict_.Set(member_name, value);
 }
 
-void JwkWriter::SetBytes(base::StringPiece member_name,
+void JwkWriter::SetBytes(std::string_view member_name,
                          base::span<const uint8_t> value) {
   // The JSON web signature spec says that padding is omitted.
   // https://tools.ietf.org/html/draft-ietf-jose-json-web-signature-36#section-2
   std::string base64url_encoded;
   base::Base64UrlEncode(
-      base::StringPiece(reinterpret_cast<const char*>(value.data()),
-                        value.size()),
+      std::string_view(reinterpret_cast<const char*>(value.data()),
+                       value.size()),
       base::Base64UrlEncodePolicy::OMIT_PADDING, &base64url_encoded);
 
   dict_.Set(member_name, std::move(base64url_encoded));
diff --git a/components/webcrypto/jwk.h b/components/webcrypto/jwk.h
index 6f5c044e..1d2e920 100644
--- a/components/webcrypto/jwk.h
+++ b/components/webcrypto/jwk.h
@@ -8,10 +8,10 @@
 #include <stdint.h>
 
 #include <memory>
+#include <string_view>
 #include <vector>
 
 #include "base/containers/span.h"
-#include "base/strings/string_piece.h"
 #include "base/values.h"
 #include "third_party/blink/public/platform/web_crypto.h"
 
@@ -44,22 +44,22 @@
   Status Init(base::span<const uint8_t> bytes,
               bool expected_extractable,
               blink::WebCryptoKeyUsageMask expected_usages,
-              base::StringPiece expected_kty,
-              base::StringPiece expected_alg);
+              std::string_view expected_kty,
+              std::string_view expected_alg);
 
   // Returns true if the member |member_name| is present.
-  bool HasMember(base::StringPiece member_name) const;
+  bool HasMember(std::string_view member_name) const;
 
   // Extracts the required string member |member_name| and saves the result to
   // |*result|. If the member does not exist or is not a string, returns an
   // error.
-  Status GetString(base::StringPiece member_name, std::string* result) const;
+  Status GetString(std::string_view member_name, std::string* result) const;
 
   // Extracts the optional string member |member_name| and saves the result to
   // |*result| if it was found. If the member exists and is not a string,
   // returns an error. Otherwise returns success, and sets |*member_exists| if
   // it was found.
-  Status GetOptionalString(base::StringPiece member_name,
+  Status GetOptionalString(std::string_view member_name,
                            std::string* result,
                            bool* member_exists) const;
 
@@ -69,28 +69,28 @@
   // it was found.
   //
   // NOTE: |*result| is owned by the JwkReader.
-  Status GetOptionalList(base::StringPiece member_name,
+  Status GetOptionalList(std::string_view member_name,
                          const base::Value::List** result,
                          bool* member_exists) const;
 
   // Extracts the required string member |member_name| and saves the
   // base64url-decoded bytes to |*result|. If the member does not exist or is
   // not a string, or could not be base64url-decoded, returns an error.
-  Status GetBytes(base::StringPiece member_name,
+  Status GetBytes(std::string_view member_name,
                   std::vector<uint8_t>* result) const;
 
   // Extracts the required base64url member, which is interpreted as being a
   // big-endian unsigned integer.
   //
   // Sequences that contain leading zeros will be rejected.
-  Status GetBigInteger(base::StringPiece member_name,
+  Status GetBigInteger(std::string_view member_name,
                        std::vector<uint8_t>* result) const;
 
   // Extracts the optional boolean member |member_name| and saves the result to
   // |*result| if it was found. If the member exists and is not a boolean,
   // returns an error. Otherwise returns success, and sets |*member_exists| if
   // it was found.
-  Status GetOptionalBool(base::StringPiece member_name,
+  Status GetOptionalBool(std::string_view member_name,
                          bool* result,
                          bool* member_exists) const;
 
@@ -98,7 +98,7 @@
   Status GetAlg(std::string* alg, bool* has_alg) const;
 
   // Checks if the "alg" member matches |expected_alg|.
-  Status VerifyAlg(base::StringPiece expected_alg) const;
+  Status VerifyAlg(std::string_view expected_alg) const;
 
  private:
   base::Value::Dict dict_;
@@ -110,16 +110,16 @@
   // Initializes a writer, and sets the standard JWK members as indicated.
   // |algorithm| is optional, and is only written if the provided |algorithm| is
   // non-empty.
-  JwkWriter(base::StringPiece algorithm,
+  JwkWriter(std::string_view algorithm,
             bool extractable,
             blink::WebCryptoKeyUsageMask usages,
-            base::StringPiece kty);
+            std::string_view kty);
 
   // Sets a string member |member_name| to |value|.
-  void SetString(base::StringPiece member_name, base::StringPiece value);
+  void SetString(std::string_view member_name, std::string_view value);
 
   // Sets a bytes member |value| to |value| by base64 url-safe encoding it.
-  void SetBytes(base::StringPiece member_name, base::span<const uint8_t> value);
+  void SetBytes(std::string_view member_name, base::span<const uint8_t> value);
 
   // Flattens the JWK to JSON (UTF-8 encoded if necessary, however in practice
   // it will be ASCII).
diff --git a/components/webcrypto/status.cc b/components/webcrypto/status.cc
index 6032a85..77a795e 100644
--- a/components/webcrypto/status.cc
+++ b/components/webcrypto/status.cc
@@ -6,7 +6,6 @@
 
 #include "base/numerics/safe_conversions.h"
 #include "base/strings/strcat.h"
-#include "base/strings/string_piece.h"
 #include "base/strings/stringprintf.h"
 
 namespace webcrypto {
@@ -42,20 +41,20 @@
                 "JWK input could not be parsed to a JSON dictionary");
 }
 
-Status Status::ErrorJwkMemberMissing(base::StringPiece member_name) {
+Status Status::ErrorJwkMemberMissing(std::string_view member_name) {
   return Status(blink::kWebCryptoErrorTypeData,
                 base::StrCat({"The required JWK member \"", member_name,
                               "\" was missing"}));
 }
 
-Status Status::ErrorJwkMemberWrongType(base::StringPiece member_name,
-                                       base::StringPiece expected_type) {
+Status Status::ErrorJwkMemberWrongType(std::string_view member_name,
+                                       std::string_view expected_type) {
   return Status(blink::kWebCryptoErrorTypeData,
                 base::StrCat({"The JWK member \"", member_name, "\" must be a ",
                               expected_type}));
 }
 
-Status Status::ErrorJwkBase64Decode(base::StringPiece member_name) {
+Status Status::ErrorJwkBase64Decode(std::string_view member_name) {
   return Status(
       blink::kWebCryptoErrorTypeData,
       base::StrCat({"The JWK member \"", member_name,
@@ -105,7 +104,7 @@
                 "but are inconsistent with each other.");
 }
 
-Status Status::ErrorJwkUnexpectedKty(base::StringPiece expected) {
+Status Status::ErrorJwkUnexpectedKty(std::string_view expected) {
   return Status(
       blink::kWebCryptoErrorTypeData,
       base::StrCat({"The JWK \"kty\" member was not \"", expected, "\""}));
@@ -117,13 +116,13 @@
                 "of key data for the given algorithm.");
 }
 
-Status Status::ErrorJwkEmptyBigInteger(base::StringPiece member_name) {
+Status Status::ErrorJwkEmptyBigInteger(std::string_view member_name) {
   return Status(
       blink::kWebCryptoErrorTypeData,
       base::StrCat({"The JWK \"", member_name, "\" member was empty."}));
 }
 
-Status Status::ErrorJwkBigIntegerHasLeadingZero(base::StringPiece member_name) {
+Status Status::ErrorJwkBigIntegerHasLeadingZero(std::string_view member_name) {
   return Status(blink::kWebCryptoErrorTypeData,
                 base::StrCat({"The JWK \"", member_name,
                               "\" member contained a leading zero."}));
@@ -231,7 +230,7 @@
   return ErrorUnsupported("The requested operation is unsupported");
 }
 
-Status Status::ErrorUnsupported(base::StringPiece message) {
+Status Status::ErrorUnsupported(std::string_view message) {
   return Status(blink::kWebCryptoErrorTypeNotSupported, message);
 }
 
@@ -327,7 +326,7 @@
                 "The imported EC key is invalid");
 }
 
-Status Status::JwkOctetStringWrongLength(base::StringPiece member_name,
+Status Status::JwkOctetStringWrongLength(std::string_view member_name,
                                          size_t expected_length,
                                          size_t actual_length) {
   return Status(
@@ -416,7 +415,7 @@
 }
 
 Status::Status(blink::WebCryptoErrorType error_type,
-               base::StringPiece error_details_utf8)
+               std::string_view error_details_utf8)
     : type_(TYPE_ERROR),
       error_type_(error_type),
       error_details_(error_details_utf8) {}
diff --git a/components/webcrypto/status.h b/components/webcrypto/status.h
index 75db538..b51e312 100644
--- a/components/webcrypto/status.h
+++ b/components/webcrypto/status.h
@@ -8,8 +8,8 @@
 #include <stddef.h>
 
 #include <string>
+#include <string_view>
 
-#include "base/strings/string_piece.h"
 #include "third_party/blink/public/platform/web_crypto.h"
 
 namespace webcrypto {
@@ -62,15 +62,15 @@
   static Status ErrorJwkNotDictionary();
 
   // The required JWK member |member_name| was missing.
-  static Status ErrorJwkMemberMissing(base::StringPiece member_name);
+  static Status ErrorJwkMemberMissing(std::string_view member_name);
 
   // The JWK member |member_name| was not of type |expected_type|.
-  static Status ErrorJwkMemberWrongType(base::StringPiece member_name,
-                                        base::StringPiece expected_type);
+  static Status ErrorJwkMemberWrongType(std::string_view member_name,
+                                        std::string_view expected_type);
 
   // The JWK member |member_name| was a string, however could not be
   // successfully base64 decoded.
-  static Status ErrorJwkBase64Decode(base::StringPiece member_name);
+  static Status ErrorJwkBase64Decode(std::string_view member_name);
 
   // The "ext" parameter was specified but was
   // incompatible with the value requested by the Web Crypto call.
@@ -102,7 +102,7 @@
 
   // The "kty" parameter was given and was a string, however it was not the
   // expected value.
-  static Status ErrorJwkUnexpectedKty(base::StringPiece expected);
+  static Status ErrorJwkUnexpectedKty(std::string_view expected);
 
   // The amount of key data provided was incompatible with the selected
   // algorithm. For instance if the algorith name was A128CBC then EXACTLY
@@ -112,11 +112,11 @@
 
   // The JWK member |member_name| is supposed to represent a big-endian unsigned
   // integer, however was the empty string.
-  static Status ErrorJwkEmptyBigInteger(base::StringPiece member_name);
+  static Status ErrorJwkEmptyBigInteger(std::string_view member_name);
 
   // The big-endian unsigned integer |member_name| contained leading zeros. This
   // violates the JWA requirement that such octet strings be minimal.
-  static Status ErrorJwkBigIntegerHasLeadingZero(base::StringPiece member_name);
+  static Status ErrorJwkBigIntegerHasLeadingZero(std::string_view member_name);
 
   // The key_ops lists a usage more than once.
   static Status ErrorJwkDuplicateKeyOps();
@@ -181,7 +181,7 @@
   // question was unsupported, some parameter combination was unsupported, or
   // something has not yet been implemented.
   static Status ErrorUnsupported();
-  static Status ErrorUnsupported(base::StringPiece message);
+  static Status ErrorUnsupported(std::string_view message);
 
   // Something unexpected happened in the code, which implies there is a
   // source-level bug. These should not happen, but safer to fail than simply
@@ -245,7 +245,7 @@
 
   // The octet string |member_name| was expected to be |expected_length| bytes
   // long, but was instead |actual_length| bytes long.
-  static Status JwkOctetStringWrongLength(base::StringPiece member_name,
+  static Status JwkOctetStringWrongLength(std::string_view member_name,
                                           size_t expected_length,
                                           size_t actual_length);
 
@@ -312,7 +312,7 @@
 
   // Constructs an error with the specified error type and message.
   Status(blink::WebCryptoErrorType error_type,
-         base::StringPiece error_details_utf8);
+         std::string_view error_details_utf8);
 
   // Constructs a success or error without any details.
   explicit Status(Type type);
diff --git a/components/webdata/common/web_database_migration_unittest.cc b/components/webdata/common/web_database_migration_unittest.cc
index b2e77fa..126683e 100644
--- a/components/webdata/common/web_database_migration_unittest.cc
+++ b/components/webdata/common/web_database_migration_unittest.cc
@@ -20,6 +20,7 @@
 #include "components/autofill/core/browser/webdata/addresses/address_autofill_table.h"
 #include "components/autofill/core/browser/webdata/autocomplete_table.h"
 #include "components/autofill/core/browser/webdata/autofill_change.h"
+#include "components/autofill/core/browser/webdata/autofill_sync_metadata_table.h"
 #include "components/autofill/core/browser/webdata/autofill_table.h"
 #include "components/autofill/core/common/autofill_constants.h"
 #include "components/search_engines/keyword_table.h"
@@ -75,12 +76,14 @@
     autofill::AddressAutofillTable address_autofill_table;
     autofill::AutocompleteTable autocomplete_table;
     autofill::AutofillTable autofill_table;
+    autofill::AutofillSyncMetadataTable autofill_sync_metadata_table;
     KeywordTable keyword_table;
     TokenServiceTable token_service_table;
 
     WebDatabase db;
     db.AddTable(&address_autofill_table);
     db.AddTable(&autocomplete_table);
+    db.AddTable(&autofill_sync_metadata_table);
     db.AddTable(&autofill_table);
     db.AddTable(&keyword_table);
     db.AddTable(&token_service_table);
diff --git a/components/webdata_services/web_data_service_wrapper.cc b/components/webdata_services/web_data_service_wrapper.cc
index e9dcf1bd..484d8cfa 100644
--- a/components/webdata_services/web_data_service_wrapper.cc
+++ b/components/webdata_services/web_data_service_wrapper.cc
@@ -17,6 +17,7 @@
 #include "components/autofill/core/browser/webdata/autocomplete_sync_bridge.h"
 #include "components/autofill/core/browser/webdata/autocomplete_table.h"
 #include "components/autofill/core/browser/webdata/autofill_profile_sync_bridge.h"
+#include "components/autofill/core/browser/webdata/autofill_sync_metadata_table.h"
 #include "components/autofill/core/browser/webdata/autofill_table.h"
 #include "components/autofill/core/browser/webdata/autofill_wallet_credential_sync_bridge.h"
 #include "components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.h"
@@ -121,6 +122,8 @@
   profile_database_->AddTable(
       std::make_unique<autofill::AddressAutofillTable>());
   profile_database_->AddTable(std::make_unique<autofill::AutocompleteTable>());
+  profile_database_->AddTable(
+      std::make_unique<autofill::AutofillSyncMetadataTable>());
   profile_database_->AddTable(std::make_unique<autofill::AutofillTable>());
   profile_database_->AddTable(std::make_unique<KeywordTable>());
   profile_database_->AddTable(std::make_unique<TokenServiceTable>());
@@ -186,6 +189,8 @@
 #endif  // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS)
   account_database_ = base::MakeRefCounted<WebDatabaseService>(
       account_storage_path, ui_task_runner, db_task_runner);
+  account_database_->AddTable(
+      std::make_unique<autofill::AutofillSyncMetadataTable>());
   account_database_->AddTable(std::make_unique<autofill::AutofillTable>());
   account_database_->LoadDatabase();
 
diff --git a/content/browser/bad_message.h b/content/browser/bad_message.h
index bdb0b73..3c8792a 100644
--- a/content/browser/bad_message.h
+++ b/content/browser/bad_message.h
@@ -338,6 +338,8 @@
   MSDH_SEND_WHEEL_INVALID_ACTION = 311,
   MSDH_GET_ZOOM_LEVEL_BUT_CSC_FEATURE_DISABLED = 312,
   RFH_FENCED_DOCUMENT_DATA_NOT_FOUND = 313,
+  MSDH_SET_ZOOM_LEVEL_BUT_CSC_FEATURE_DISABLED = 314,
+  MSDH_SET_ZOOM_LEVEL_INVALID_LEVEL = 315,
 
   // Please add new elements here. The naming convention is abbreviated class
   // name (e.g. RenderFrameHost becomes RFH) plus a unique description of the
diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host.cc b/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
index 086c9a8..0c71f16 100644
--- a/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
+++ b/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
@@ -34,6 +34,7 @@
 #include "third_party/blink/public/common/features.h"
 #include "third_party/blink/public/common/features_generated.h"
 #include "third_party/blink/public/common/mediastream/media_stream_request.h"
+#include "third_party/blink/public/common/page/page_zoom.h"
 #include "third_party/blink/public/mojom/mediastream/media_devices.mojom.h"
 #include "third_party/blink/public/mojom/mediastream/media_stream.mojom.h"
 #include "url/origin.h"
@@ -737,6 +738,45 @@
                           CapturedSurfaceControlResult::kUnknownError);
 }
 
+void MediaStreamDispatcherHost::SetZoomLevel(
+    const base::UnguessableToken& device_id,
+    int32_t zoom_level,
+    SetZoomLevelCallback callback) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  if (!base::FeatureList::IsEnabled(blink::features::kCapturedSurfaceControl)) {
+    ReceivedBadMessage(
+        render_frame_host_id_.child_id,
+        bad_message::MSDH_GET_ZOOM_LEVEL_BUT_CSC_FEATURE_DISABLED);
+    std::move(callback).Run(CapturedSurfaceControlResult::kUnknownError);
+    return;
+  }
+
+  if (zoom_level <
+          static_cast<int>(std::ceil(100 * blink::kMinimumPageZoomFactor)) ||
+      static_cast<int>(std::floor(100 * blink::kMaximumPageZoomFactor)) <
+          zoom_level) {
+    ReceivedBadMessage(render_frame_host_id_.child_id,
+                       bad_message::MSDH_SET_ZOOM_LEVEL_INVALID_LEVEL);
+    std::move(callback).Run(CapturedSurfaceControlResult::kUnknownError);
+    return;
+  }
+
+  const GlobalRenderFrameHostId captured_id =
+      media_stream_manager_->video_capture_manager()
+          ->GetGlobalRenderFrameHostId(device_id);
+  if (!captured_id) {
+    // Either the capture session has ended, or the capture was not of a tab.
+    // Note that this is not a BadMessage, because the session might have
+    // ended asynchronously.
+    std::move(callback).Run(
+        CapturedSurfaceControlResult::kCapturedSurfaceNotFoundError);
+    return;
+  }
+
+  // TODO(crbug.com/1466247): Implement (with a permission prompt).
+  std::move(callback).Run(CapturedSurfaceControlResult::kUnknownError);
+}
+
 void MediaStreamDispatcherHost::OnSubCaptureTargetValidationComplete(
     const base::UnguessableToken& device_id,
     media::mojom::SubCaptureTargetType type,
diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host.h b/content/browser/renderer_host/media/media_stream_dispatcher_host.h
index a3446c44..153dbdce 100644
--- a/content/browser/renderer_host/media/media_stream_dispatcher_host.h
+++ b/content/browser/renderer_host/media/media_stream_dispatcher_host.h
@@ -139,6 +139,9 @@
                  SendWheelCallback callback) override;
   void GetZoomLevel(const base::UnguessableToken& device_id,
                     GetZoomLevelCallback callback) override;
+  void SetZoomLevel(const base::UnguessableToken& device_id,
+                    int32_t zoom_level,
+                    SetZoomLevelCallback callback) override;
   void OnSubCaptureTargetValidationComplete(
       const base::UnguessableToken& device_id,
       media::mojom::SubCaptureTargetType type,
diff --git a/content/browser/renderer_host/media/media_stream_manager_unittest.cc b/content/browser/renderer_host/media/media_stream_manager_unittest.cc
index 2d0241e..ee17c6c 100644
--- a/content/browser/renderer_host/media/media_stream_manager_unittest.cc
+++ b/content/browser/renderer_host/media/media_stream_manager_unittest.cc
@@ -291,6 +291,9 @@
                  SendWheelCallback callback) override {}
   void GetZoomLevel(const base::UnguessableToken& device_id,
                     GetZoomLevelCallback callback) override {}
+  void SetZoomLevel(const base::UnguessableToken& device_id,
+                    int32_t zoom_level,
+                    SetZoomLevelCallback callback) override {}
   void FocusCapturedSurface(const std::string& label, bool focus) override {}
   void ApplySubCaptureTarget(const base::UnguessableToken& device_id,
                              media::mojom::SubCaptureTargetType type,
diff --git a/content/test/data/accessibility/aria/input-text-aria-placeholder-expected-blink.txt b/content/test/data/accessibility/aria/input-text-aria-placeholder-expected-blink.txt
index 9892aa7..2a1881a 100644
--- a/content/test/data/accessibility/aria/input-text-aria-placeholder-expected-blink.txt
+++ b/content/test/data/accessibility/aria/input-text-aria-placeholder-expected-blink.txt
@@ -18,4 +18,4 @@
 ++++++++staticText name='aria-description5'
 ++++++++++inlineTextBox name='aria-description5'
 ++++++textField name='title6' placeholder='aria-placeholder6'
-++++++++genericContainer
+++++++++genericContainer
\ No newline at end of file
diff --git a/content/test/data/accessibility/html/input-button-expected-blink.txt b/content/test/data/accessibility/html/input-button-expected-blink.txt
index 23ed173..40e5817d 100644
--- a/content/test/data/accessibility/html/input-button-expected-blink.txt
+++ b/content/test/data/accessibility/html/input-button-expected-blink.txt
@@ -6,4 +6,4 @@
 ++++++++++inlineTextBox name='Button'
 ++++++button description='Description' inputType='button' name='Name' descriptionFrom=buttonLabel
 ++++++++staticText name='Description'
-++++++++++inlineTextBox name='Description'
+++++++++++inlineTextBox name='Description'
\ No newline at end of file
diff --git a/content/test/data/accessibility/html/input-date-disabled-expected-blink.txt b/content/test/data/accessibility/html/input-date-disabled-expected-blink.txt
index 17aa165..d9a6f1f2 100644
--- a/content/test/data/accessibility/html/input-date-disabled-expected-blink.txt
+++ b/content/test/data/accessibility/html/input-date-disabled-expected-blink.txt
@@ -2,20 +2,19 @@
 ++genericContainer ignored
 ++++genericContainer
 ++++++date inputType='date' restriction=disabled
-++++++++genericContainer ignored
+++++++++genericContainer
 ++++++++++genericContainer
-++++++++++++genericContainer
-++++++++++++++spinButton name='Month' placeholder='mm' restriction=disabled valueForRange=0.00 minValueForRange=1.00 maxValueForRange=12.00
-++++++++++++++++staticText name='mm'
-++++++++++++++++++inlineTextBox name='mm'
-++++++++++++++staticText name='/'
-++++++++++++++++inlineTextBox name='/'
-++++++++++++++spinButton name='Day' placeholder='dd' restriction=disabled valueForRange=0.00 minValueForRange=1.00 maxValueForRange=31.00
-++++++++++++++++staticText name='dd'
-++++++++++++++++++inlineTextBox name='dd'
-++++++++++++++staticText name='/'
-++++++++++++++++inlineTextBox name='/'
-++++++++++++++spinButton name='Year' placeholder='yyyy' restriction=disabled valueForRange=0.00 minValueForRange=1.00 maxValueForRange=275760.00
-++++++++++++++++staticText name='yyyy'
-++++++++++++++++++inlineTextBox name='yyyy'
-++++++++++popUpButton ignored invisible
+++++++++++++spinButton name='Month' placeholder='mm' restriction=disabled valueForRange=0.00 minValueForRange=1.00 maxValueForRange=12.00
+++++++++++++++staticText name='mm'
+++++++++++++++++inlineTextBox name='mm'
+++++++++++++staticText name='/'
+++++++++++++++inlineTextBox name='/'
+++++++++++++spinButton name='Day' placeholder='dd' restriction=disabled valueForRange=0.00 minValueForRange=1.00 maxValueForRange=31.00
+++++++++++++++staticText name='dd'
+++++++++++++++++inlineTextBox name='dd'
+++++++++++++staticText name='/'
+++++++++++++++inlineTextBox name='/'
+++++++++++++spinButton name='Year' placeholder='yyyy' restriction=disabled valueForRange=0.00 minValueForRange=1.00 maxValueForRange=275760.00
+++++++++++++++staticText name='yyyy'
+++++++++++++++++inlineTextBox name='yyyy'
+++++++++popUpButton ignored invisible
diff --git a/content/test/data/accessibility/html/input-date-expected-auralinux.txt b/content/test/data/accessibility/html/input-date-expected-auralinux.txt
index d516759..e3c97df 100644
--- a/content/test/data/accessibility/html/input-date-expected-auralinux.txt
+++ b/content/test/data/accessibility/html/input-date-expected-auralinux.txt
@@ -17,4 +17,4 @@
 ++++++++++[spin button] name='Day When' current=1.000000 minimum=1.000000 maximum=31.000000
 ++++++++++[static] name='/'
 ++++++++++[spin button] name='Year When' current=2008.000000 minimum=1.000000 maximum=275760.000000
-++++++[push button] name='Show date picker' description='Show date picker' description-from:tooltip
+++++++[push button] name='Show date picker' description='Show date picker' description-from:tooltip
\ No newline at end of file
diff --git a/content/test/data/accessibility/html/input-date-expected-blink.txt b/content/test/data/accessibility/html/input-date-expected-blink.txt
index fed79ef..adb74cc 100644
--- a/content/test/data/accessibility/html/input-date-expected-blink.txt
+++ b/content/test/data/accessibility/html/input-date-expected-blink.txt
@@ -2,38 +2,36 @@
 ++genericContainer ignored
 ++++genericContainer
 ++++++date inputType='date' value='2008-09-01'
-++++++++genericContainer ignored
+++++++++genericContainer
 ++++++++++genericContainer
-++++++++++++genericContainer
-++++++++++++++spinButton name='Month' placeholder='mm' value='09' valueForRange=9.00 minValueForRange=1.00 maxValueForRange=12.00
-++++++++++++++++staticText name='09'
-++++++++++++++++++inlineTextBox name='09'
-++++++++++++++staticText name='/'
-++++++++++++++++inlineTextBox name='/'
-++++++++++++++spinButton name='Day' placeholder='dd' value='01' valueForRange=1.00 minValueForRange=1.00 maxValueForRange=31.00
-++++++++++++++++staticText name='01'
-++++++++++++++++++inlineTextBox name='01'
-++++++++++++++staticText name='/'
-++++++++++++++++inlineTextBox name='/'
-++++++++++++++spinButton name='Year' placeholder='yyyy' value='2008' valueForRange=2008.00 minValueForRange=1.00 maxValueForRange=275760.00
-++++++++++++++++staticText name='2008'
-++++++++++++++++++inlineTextBox name='2008'
-++++++++++popUpButton description='Show date picker' name='Show date picker' descriptionFrom=title
+++++++++++++spinButton name='Month' placeholder='mm' value='09' valueForRange=9.00 minValueForRange=1.00 maxValueForRange=12.00
+++++++++++++++staticText name='09'
+++++++++++++++++inlineTextBox name='09'
+++++++++++++staticText name='/'
+++++++++++++++inlineTextBox name='/'
+++++++++++++spinButton name='Day' placeholder='dd' value='01' valueForRange=1.00 minValueForRange=1.00 maxValueForRange=31.00
+++++++++++++++staticText name='01'
+++++++++++++++++inlineTextBox name='01'
+++++++++++++staticText name='/'
+++++++++++++++inlineTextBox name='/'
+++++++++++++spinButton name='Year' placeholder='yyyy' value='2008' valueForRange=2008.00 minValueForRange=1.00 maxValueForRange=275760.00
+++++++++++++++staticText name='2008'
+++++++++++++++++inlineTextBox name='2008'
+++++++++popUpButton description='Show date picker' name='Show date picker' descriptionFrom=title
 ++++++date inputType='date' name='When' value='2008-09-01'
-++++++++genericContainer ignored
+++++++++genericContainer
 ++++++++++genericContainer
-++++++++++++genericContainer
-++++++++++++++spinButton name='Month When' placeholder='mm' value='09' valueForRange=9.00 minValueForRange=1.00 maxValueForRange=12.00
-++++++++++++++++staticText name='09'
-++++++++++++++++++inlineTextBox name='09'
-++++++++++++++staticText name='/'
-++++++++++++++++inlineTextBox name='/'
-++++++++++++++spinButton name='Day When' placeholder='dd' value='01' valueForRange=1.00 minValueForRange=1.00 maxValueForRange=31.00
-++++++++++++++++staticText name='01'
-++++++++++++++++++inlineTextBox name='01'
-++++++++++++++staticText name='/'
-++++++++++++++++inlineTextBox name='/'
-++++++++++++++spinButton name='Year When' placeholder='yyyy' value='2008' valueForRange=2008.00 minValueForRange=1.00 maxValueForRange=275760.00
-++++++++++++++++staticText name='2008'
-++++++++++++++++++inlineTextBox name='2008'
-++++++++++popUpButton description='Show date picker' name='Show date picker' descriptionFrom=title
+++++++++++++spinButton name='Month When' placeholder='mm' value='09' valueForRange=9.00 minValueForRange=1.00 maxValueForRange=12.00
+++++++++++++++staticText name='09'
+++++++++++++++++inlineTextBox name='09'
+++++++++++++staticText name='/'
+++++++++++++++inlineTextBox name='/'
+++++++++++++spinButton name='Day When' placeholder='dd' value='01' valueForRange=1.00 minValueForRange=1.00 maxValueForRange=31.00
+++++++++++++++staticText name='01'
+++++++++++++++++inlineTextBox name='01'
+++++++++++++staticText name='/'
+++++++++++++++inlineTextBox name='/'
+++++++++++++spinButton name='Year When' placeholder='yyyy' value='2008' valueForRange=2008.00 minValueForRange=1.00 maxValueForRange=275760.00
+++++++++++++++staticText name='2008'
+++++++++++++++++inlineTextBox name='2008'
+++++++++popUpButton description='Show date picker' name='Show date picker' descriptionFrom=title
diff --git a/content/test/data/accessibility/html/input-datetime-local-expected-auralinux.txt b/content/test/data/accessibility/html/input-datetime-local-expected-auralinux.txt
index 32a0cf02..72e046d 100644
--- a/content/test/data/accessibility/html/input-datetime-local-expected-auralinux.txt
+++ b/content/test/data/accessibility/html/input-datetime-local-expected-auralinux.txt
@@ -14,4 +14,4 @@
 ++++++++++[spin button] name='Minutes' current=0.000000 minimum=0.000000 maximum=59.000000
 ++++++++++[static] name=' '
 ++++++++++[spin button] name='AM/PM' current=0.000000 minimum=1.000000 maximum=2.000000
-++++++[push button] name='Show local date and time picker' description='Show local date and time picker' description-from:tooltip haspopup:menu
+++++++[push button] name='Show local date and time picker' description='Show local date and time picker' description-from:tooltip haspopup:menu
\ No newline at end of file
diff --git a/content/test/data/accessibility/html/input-month-expected-auralinux.txt b/content/test/data/accessibility/html/input-month-expected-auralinux.txt
index 0b75a92..8afaf109 100644
--- a/content/test/data/accessibility/html/input-month-expected-auralinux.txt
+++ b/content/test/data/accessibility/html/input-month-expected-auralinux.txt
@@ -6,4 +6,4 @@
 ++++++++++[spin button] name='Month' valuetext:0 current=0.000000 minimum=1.000000 maximum=12.000000
 ++++++++++[static] name=' '
 ++++++++++[spin button] name='Year' valuetext:0 current=0.000000 minimum=1.000000 maximum=275760.000000
-++++++[push button] name='Show month picker' description='Show month picker' description-from:tooltip haspopup:menu
+++++++[push button] name='Show month picker' description='Show month picker' description-from:tooltip haspopup:menu
\ No newline at end of file
diff --git a/content/test/data/accessibility/html/input-month-expected-blink.txt b/content/test/data/accessibility/html/input-month-expected-blink.txt
index 51403ae..1585ef52 100644
--- a/content/test/data/accessibility/html/input-month-expected-blink.txt
+++ b/content/test/data/accessibility/html/input-month-expected-blink.txt
@@ -2,15 +2,14 @@
 ++genericContainer ignored
 ++++genericContainer
 ++++++dateTime inputType='month'
-++++++++genericContainer ignored
+++++++++genericContainer
 ++++++++++genericContainer
-++++++++++++genericContainer
-++++++++++++++spinButton name='Month' placeholder='---------' valueForRange=0.00 minValueForRange=1.00 maxValueForRange=12.00
-++++++++++++++++staticText name='---------'
-++++++++++++++++++inlineTextBox name='---------'
-++++++++++++++staticText name=' '
-++++++++++++++++inlineTextBox name=' '
-++++++++++++++spinButton name='Year' placeholder='----' valueForRange=0.00 minValueForRange=1.00 maxValueForRange=275760.00
-++++++++++++++++staticText name='----'
-++++++++++++++++++inlineTextBox name='----'
-++++++++++popUpButton description='Show month picker' name='Show month picker' descriptionFrom=title haspopup=menu
+++++++++++++spinButton name='Month' placeholder='---------' valueForRange=0.00 minValueForRange=1.00 maxValueForRange=12.00
+++++++++++++++staticText name='---------'
+++++++++++++++++inlineTextBox name='---------'
+++++++++++++staticText name=' '
+++++++++++++++inlineTextBox name=' '
+++++++++++++spinButton name='Year' placeholder='----' valueForRange=0.00 minValueForRange=1.00 maxValueForRange=275760.00
+++++++++++++++staticText name='----'
+++++++++++++++++inlineTextBox name='----'
+++++++++popUpButton description='Show month picker' name='Show month picker' descriptionFrom=title haspopup=menu
\ No newline at end of file
diff --git a/content/test/data/accessibility/html/input-time-expected-auralinux.txt b/content/test/data/accessibility/html/input-time-expected-auralinux.txt
index 30e1137..9400f0a2 100644
--- a/content/test/data/accessibility/html/input-time-expected-auralinux.txt
+++ b/content/test/data/accessibility/html/input-time-expected-auralinux.txt
@@ -17,4 +17,4 @@
 ++++++++++[spin button] name='Minutes Breakfast' xml-roles:spinbutton current=0.000000 minimum=0.000000 maximum=59.000000
 ++++++++++[static] name=' '
 ++++++++++[spin button] name='AM/PM Breakfast' xml-roles:spinbutton current=1.000000 minimum=1.000000 maximum=2.000000
-++++++[push button] name='Show time picker' description='Show time picker' description-from:tooltip xml-roles:button
+++++++[push button] name='Show time picker' description='Show time picker' description-from:tooltip xml-roles:button
\ No newline at end of file
diff --git a/content/test/data/accessibility/html/input-time-expected-blink.txt b/content/test/data/accessibility/html/input-time-expected-blink.txt
index 8ecd2fc..1d612de 100644
--- a/content/test/data/accessibility/html/input-time-expected-blink.txt
+++ b/content/test/data/accessibility/html/input-time-expected-blink.txt
@@ -2,38 +2,36 @@
 ++genericContainer ignored
 ++++genericContainer
 ++++++inputTime inputType='time' value='00:00:00'
-++++++++genericContainer ignored
+++++++++genericContainer
 ++++++++++genericContainer
-++++++++++++genericContainer
-++++++++++++++spinButton name='Hours' placeholder='--' value='12' valueForRange=12.00 minValueForRange=1.00 maxValueForRange=12.00
-++++++++++++++++staticText name='12'
-++++++++++++++++++inlineTextBox name='12'
-++++++++++++++staticText name=':'
-++++++++++++++++inlineTextBox name=':'
-++++++++++++++spinButton name='Minutes' placeholder='--' value='00' valueForRange=0.00 minValueForRange=0.00 maxValueForRange=59.00
-++++++++++++++++staticText name='00'
-++++++++++++++++++inlineTextBox name='00'
-++++++++++++++staticText name=' '
-++++++++++++++++inlineTextBox name=' '
-++++++++++++++spinButton name='AM/PM' placeholder='--' value='AM' valueForRange=1.00 minValueForRange=1.00 maxValueForRange=2.00
-++++++++++++++++staticText name='AM'
-++++++++++++++++++inlineTextBox name='AM'
-++++++++++popUpButton description='Show time picker' name='Show time picker' descriptionFrom=title
+++++++++++++spinButton name='Hours' placeholder='--' value='12' valueForRange=12.00 minValueForRange=1.00 maxValueForRange=12.00
+++++++++++++++staticText name='12'
+++++++++++++++++inlineTextBox name='12'
+++++++++++++staticText name=':'
+++++++++++++++inlineTextBox name=':'
+++++++++++++spinButton name='Minutes' placeholder='--' value='00' valueForRange=0.00 minValueForRange=0.00 maxValueForRange=59.00
+++++++++++++++staticText name='00'
+++++++++++++++++inlineTextBox name='00'
+++++++++++++staticText name=' '
+++++++++++++++inlineTextBox name=' '
+++++++++++++spinButton name='AM/PM' placeholder='--' value='AM' valueForRange=1.00 minValueForRange=1.00 maxValueForRange=2.00
+++++++++++++++staticText name='AM'
+++++++++++++++++inlineTextBox name='AM'
+++++++++popUpButton description='Show time picker' name='Show time picker' descriptionFrom=title
 ++++++inputTime inputType='time' name='Breakfast' value='00:00:00'
-++++++++genericContainer ignored
+++++++++genericContainer
 ++++++++++genericContainer
-++++++++++++genericContainer
-++++++++++++++spinButton name='Hours Breakfast' placeholder='--' value='12' valueForRange=12.00 minValueForRange=1.00 maxValueForRange=12.00
-++++++++++++++++staticText name='12'
-++++++++++++++++++inlineTextBox name='12'
-++++++++++++++staticText name=':'
-++++++++++++++++inlineTextBox name=':'
-++++++++++++++spinButton name='Minutes Breakfast' placeholder='--' value='00' valueForRange=0.00 minValueForRange=0.00 maxValueForRange=59.00
-++++++++++++++++staticText name='00'
-++++++++++++++++++inlineTextBox name='00'
-++++++++++++++staticText name=' '
-++++++++++++++++inlineTextBox name=' '
-++++++++++++++spinButton name='AM/PM Breakfast' placeholder='--' value='AM' valueForRange=1.00 minValueForRange=1.00 maxValueForRange=2.00
-++++++++++++++++staticText name='AM'
-++++++++++++++++++inlineTextBox name='AM'
-++++++++++popUpButton description='Show time picker' name='Show time picker' descriptionFrom=title
+++++++++++++spinButton name='Hours Breakfast' placeholder='--' value='12' valueForRange=12.00 minValueForRange=1.00 maxValueForRange=12.00
+++++++++++++++staticText name='12'
+++++++++++++++++inlineTextBox name='12'
+++++++++++++staticText name=':'
+++++++++++++++inlineTextBox name=':'
+++++++++++++spinButton name='Minutes Breakfast' placeholder='--' value='00' valueForRange=0.00 minValueForRange=0.00 maxValueForRange=59.00
+++++++++++++++staticText name='00'
+++++++++++++++++inlineTextBox name='00'
+++++++++++++staticText name=' '
+++++++++++++++inlineTextBox name=' '
+++++++++++++spinButton name='AM/PM Breakfast' placeholder='--' value='AM' valueForRange=1.00 minValueForRange=1.00 maxValueForRange=2.00
+++++++++++++++staticText name='AM'
+++++++++++++++++inlineTextBox name='AM'
+++++++++popUpButton description='Show time picker' name='Show time picker' descriptionFrom=title
\ No newline at end of file
diff --git a/content/test/data/accessibility/html/input-time-with-popup-open-expected-blink.txt b/content/test/data/accessibility/html/input-time-with-popup-open-expected-blink.txt
index c5184681..ab85855 100644
--- a/content/test/data/accessibility/html/input-time-with-popup-open-expected-blink.txt
+++ b/content/test/data/accessibility/html/input-time-with-popup-open-expected-blink.txt
@@ -2,33 +2,32 @@
 ++genericContainer ignored
 ++++genericContainer
 ++++++inputTime inputType='time' value='13:50:02.922' controlsIds=group
-++++++++genericContainer ignored
+++++++++genericContainer
 ++++++++++genericContainer
-++++++++++++genericContainer
-++++++++++++++spinButton name='Hours' placeholder='--' value='01' valueForRange=1.00 minValueForRange=1.00 maxValueForRange=12.00
-++++++++++++++++staticText name='01'
-++++++++++++++++++inlineTextBox name='01'
-++++++++++++++staticText name=':'
-++++++++++++++++inlineTextBox name=':'
-++++++++++++++spinButton name='Minutes' placeholder='--' value='50' valueForRange=50.00 minValueForRange=0.00 maxValueForRange=59.00
-++++++++++++++++staticText name='50'
-++++++++++++++++++inlineTextBox name='50'
-++++++++++++++staticText name=':'
-++++++++++++++++inlineTextBox name=':'
-++++++++++++++spinButton name='Seconds' placeholder='--' value='02' restriction=disabled valueForRange=2.00 minValueForRange=0.00 maxValueForRange=59.00
-++++++++++++++++staticText name='02'
-++++++++++++++++++inlineTextBox name='02'
-++++++++++++++staticText name='.'
-++++++++++++++++inlineTextBox name='.'
-++++++++++++++spinButton name='Milliseconds' placeholder='---' value='922' restriction=disabled valueForRange=922.00 minValueForRange=0.00 maxValueForRange=999.00
-++++++++++++++++staticText name='922'
-++++++++++++++++++inlineTextBox name='922'
-++++++++++++++staticText name=' '
-++++++++++++++++inlineTextBox name=' '
-++++++++++++++spinButton name='AM/PM' placeholder='--' value='PM' valueForRange=2.00 minValueForRange=1.00 maxValueForRange=2.00
-++++++++++++++++staticText name='PM'
-++++++++++++++++++inlineTextBox name='PM'
-++++++++++popUpButton description='Show time picker' name='Show time picker' descriptionFrom=title
+++++++++++++spinButton name='Hours' placeholder='--' value='01' valueForRange=1.00 minValueForRange=1.00 maxValueForRange=12.00
+++++++++++++++staticText name='01'
+++++++++++++++++inlineTextBox name='01'
+++++++++++++staticText name=':'
+++++++++++++++inlineTextBox name=':'
+++++++++++++spinButton name='Minutes' placeholder='--' value='50' valueForRange=50.00 minValueForRange=0.00 maxValueForRange=59.00
+++++++++++++++staticText name='50'
+++++++++++++++++inlineTextBox name='50'
+++++++++++++staticText name=':'
+++++++++++++++inlineTextBox name=':'
+++++++++++++spinButton name='Seconds' placeholder='--' value='02' restriction=disabled valueForRange=2.00 minValueForRange=0.00 maxValueForRange=59.00
+++++++++++++++staticText name='02'
+++++++++++++++++inlineTextBox name='02'
+++++++++++++staticText name='.'
+++++++++++++++inlineTextBox name='.'
+++++++++++++spinButton name='Milliseconds' placeholder='---' value='922' restriction=disabled valueForRange=922.00 minValueForRange=0.00 maxValueForRange=999.00
+++++++++++++++staticText name='922'
+++++++++++++++++inlineTextBox name='922'
+++++++++++++staticText name=' '
+++++++++++++++inlineTextBox name=' '
+++++++++++++spinButton name='AM/PM' placeholder='--' value='PM' valueForRange=2.00 minValueForRange=1.00 maxValueForRange=2.00
+++++++++++++++staticText name='PM'
+++++++++++++++++inlineTextBox name='PM'
+++++++++popUpButton description='Show time picker' name='Show time picker' descriptionFrom=title
 ++++++++group
 ++++++++++genericContainer ignored
 ++++++++++++genericContainer ignored
@@ -471,4 +470,4 @@
 ++++++++++++++++++++++++++inlineTextBox name='PM'
 ++++++++++++++++++++++listBoxOption name='AM' selected=false
 ++++++++++++++++++++++++staticText name='AM'
-++++++++++++++++++++++++++inlineTextBox name='AM'
+++++++++++++++++++++++++++inlineTextBox name='AM'
\ No newline at end of file
diff --git a/content/test/data/accessibility/html/input-week-expected-auralinux.txt b/content/test/data/accessibility/html/input-week-expected-auralinux.txt
index 9f8f7f8..1ac1978 100644
--- a/content/test/data/accessibility/html/input-week-expected-auralinux.txt
+++ b/content/test/data/accessibility/html/input-week-expected-auralinux.txt
@@ -7,4 +7,4 @@
 ++++++++++[spin button] name='Week' current=0.000000 minimum=1.000000 maximum=53.000000
 ++++++++++[static] name=', '
 ++++++++++[spin button] name='Year' current=0.000000 minimum=1.000000 maximum=275760.000000
-++++++[push button] name='Show week picker' description='Show week picker' description-from:tooltip haspopup:menu
+++++++[push button] name='Show week picker' description='Show week picker' description-from:tooltip haspopup:menu
\ No newline at end of file
diff --git a/content/test/data/accessibility/html/input-week-expected-blink.txt b/content/test/data/accessibility/html/input-week-expected-blink.txt
index 70df92f..f4b2ca6 100644
--- a/content/test/data/accessibility/html/input-week-expected-blink.txt
+++ b/content/test/data/accessibility/html/input-week-expected-blink.txt
@@ -2,17 +2,16 @@
 ++genericContainer ignored
 ++++genericContainer
 ++++++dateTime inputType='week'
-++++++++genericContainer ignored
+++++++++genericContainer
 ++++++++++genericContainer
-++++++++++++genericContainer
-++++++++++++++staticText name='Week '
-++++++++++++++++inlineTextBox name='Week '
-++++++++++++++spinButton name='Week' placeholder='--' valueForRange=0.00 minValueForRange=1.00 maxValueForRange=53.00
-++++++++++++++++staticText name='--'
-++++++++++++++++++inlineTextBox name='--'
-++++++++++++++staticText name=', '
-++++++++++++++++inlineTextBox name=', '
-++++++++++++++spinButton name='Year' placeholder='----' valueForRange=0.00 minValueForRange=1.00 maxValueForRange=275760.00
-++++++++++++++++staticText name='----'
-++++++++++++++++++inlineTextBox name='----'
-++++++++++popUpButton description='Show week picker' name='Show week picker' descriptionFrom=title haspopup=menu
+++++++++++++staticText name='Week '
+++++++++++++++inlineTextBox name='Week '
+++++++++++++spinButton name='Week' placeholder='--' valueForRange=0.00 minValueForRange=1.00 maxValueForRange=53.00
+++++++++++++++staticText name='--'
+++++++++++++++++inlineTextBox name='--'
+++++++++++++staticText name=', '
+++++++++++++++inlineTextBox name=', '
+++++++++++++spinButton name='Year' placeholder='----' valueForRange=0.00 minValueForRange=1.00 maxValueForRange=275760.00
+++++++++++++++staticText name='----'
+++++++++++++++++inlineTextBox name='----'
+++++++++popUpButton description='Show week picker' name='Show week picker' descriptionFrom=title haspopup=menu
\ No newline at end of file
diff --git a/content/test/data/accessibility/html/interactive-controls-with-labels-expected-auralinux.txt b/content/test/data/accessibility/html/interactive-controls-with-labels-expected-auralinux.txt
index 2c8bfe5..e638b18 100644
--- a/content/test/data/accessibility/html/interactive-controls-with-labels-expected-auralinux.txt
+++ b/content/test/data/accessibility/html/interactive-controls-with-labels-expected-auralinux.txt
@@ -48,4 +48,4 @@
 ++++++++[spin button] name='AM/PM Test label' labelled-by=[label] current=2.000000 minimum=1.000000 maximum=2.000000
 ++++[push button] name='Show time picker' description='Show time picker' description-from:tooltip
 ++[push button] name='aria label'
-++[push button] name='Test label' labelled-by=[label]
+++[push button] name='Test label' labelled-by=[label]
\ No newline at end of file
diff --git a/content/test/data/accessibility/html/interactive-controls-with-labels-expected-blink.txt b/content/test/data/accessibility/html/interactive-controls-with-labels-expected-blink.txt
index ce2135f..d7854468 100644
--- a/content/test/data/accessibility/html/interactive-controls-with-labels-expected-blink.txt
+++ b/content/test/data/accessibility/html/interactive-controls-with-labels-expected-blink.txt
@@ -85,44 +85,42 @@
 ++++++++++staticText name='Option 8'
 ++++++++++++inlineTextBox name='Option 8'
 ++++++inputTime name='aria label' value='12:05'
-++++++++genericContainer ignored
+++++++++genericContainer
 ++++++++++genericContainer
-++++++++++++genericContainer
-++++++++++++++spinButton name='Hours aria label' placeholder='--' value='12' valueForRange=12.00 minValueForRange=1.00 maxValueForRange=12.00
-++++++++++++++++staticText name='12'
-++++++++++++++++++inlineTextBox name='12'
-++++++++++++++staticText name=':'
-++++++++++++++++inlineTextBox name=':'
-++++++++++++++spinButton name='Minutes aria label' placeholder='--' value='05' valueForRange=5.00 minValueForRange=0.00 maxValueForRange=59.00
-++++++++++++++++staticText name='05'
-++++++++++++++++++inlineTextBox name='05'
-++++++++++++++staticText name=' '
-++++++++++++++++inlineTextBox name=' '
-++++++++++++++spinButton name='AM/PM aria label' placeholder='--' value='PM' valueForRange=2.00 minValueForRange=1.00 maxValueForRange=2.00
-++++++++++++++++staticText name='PM'
-++++++++++++++++++inlineTextBox name='PM'
-++++++++++popUpButton description='Show time picker' name='Show time picker' descriptionFrom=title
+++++++++++++spinButton name='Hours aria label' placeholder='--' value='12' valueForRange=12.00 minValueForRange=1.00 maxValueForRange=12.00
+++++++++++++++staticText name='12'
+++++++++++++++++inlineTextBox name='12'
+++++++++++++staticText name=':'
+++++++++++++++inlineTextBox name=':'
+++++++++++++spinButton name='Minutes aria label' placeholder='--' value='05' valueForRange=5.00 minValueForRange=0.00 maxValueForRange=59.00
+++++++++++++++staticText name='05'
+++++++++++++++++inlineTextBox name='05'
+++++++++++++staticText name=' '
+++++++++++++++inlineTextBox name=' '
+++++++++++++spinButton name='AM/PM aria label' placeholder='--' value='PM' valueForRange=2.00 minValueForRange=1.00 maxValueForRange=2.00
+++++++++++++++staticText name='PM'
+++++++++++++++++inlineTextBox name='PM'
+++++++++popUpButton description='Show time picker' name='Show time picker' descriptionFrom=title
 ++++++inputTime name='Test label' value='12:05'
-++++++++genericContainer ignored
+++++++++genericContainer
 ++++++++++genericContainer
-++++++++++++genericContainer
-++++++++++++++spinButton name='Hours Test label' placeholder='--' value='12' valueForRange=12.00 minValueForRange=1.00 maxValueForRange=12.00
-++++++++++++++++staticText name='12'
-++++++++++++++++++inlineTextBox name='12'
-++++++++++++++staticText name=':'
-++++++++++++++++inlineTextBox name=':'
-++++++++++++++spinButton name='Minutes Test label' placeholder='--' value='05' valueForRange=5.00 minValueForRange=0.00 maxValueForRange=59.00
-++++++++++++++++staticText name='05'
-++++++++++++++++++inlineTextBox name='05'
-++++++++++++++staticText name=' '
-++++++++++++++++inlineTextBox name=' '
-++++++++++++++spinButton name='AM/PM Test label' placeholder='--' value='PM' valueForRange=2.00 minValueForRange=1.00 maxValueForRange=2.00
-++++++++++++++++staticText name='PM'
-++++++++++++++++++inlineTextBox name='PM'
-++++++++++popUpButton description='Show time picker' name='Show time picker' descriptionFrom=title
+++++++++++++spinButton name='Hours Test label' placeholder='--' value='12' valueForRange=12.00 minValueForRange=1.00 maxValueForRange=12.00
+++++++++++++++staticText name='12'
+++++++++++++++++inlineTextBox name='12'
+++++++++++++staticText name=':'
+++++++++++++++inlineTextBox name=':'
+++++++++++++spinButton name='Minutes Test label' placeholder='--' value='05' valueForRange=5.00 minValueForRange=0.00 maxValueForRange=59.00
+++++++++++++++staticText name='05'
+++++++++++++++++inlineTextBox name='05'
+++++++++++++staticText name=' '
+++++++++++++++inlineTextBox name=' '
+++++++++++++spinButton name='AM/PM Test label' placeholder='--' value='PM' valueForRange=2.00 minValueForRange=1.00 maxValueForRange=2.00
+++++++++++++++staticText name='PM'
+++++++++++++++++inlineTextBox name='PM'
+++++++++popUpButton description='Show time picker' name='Show time picker' descriptionFrom=title
 ++++++colorWell name='aria label' value='#e4e4e4'
 ++++++++genericContainer ignored
 ++++++++++genericContainer ignored
 ++++++colorWell name='Test label' value='#e4e4e4'
 ++++++++genericContainer ignored
-++++++++++genericContainer ignored
+++++++++++genericContainer ignored
\ No newline at end of file
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
index e74c09e..8020694 100644
--- a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
@@ -491,7 +491,7 @@
 
 ## win10 / angle-d3d11 / Passthrough command decoder failures ##
 
-crbug.com/1509927 [ win nvidia angle-d3d11 passthrough ] conformance/ogles/GL/atan/atan_009_to_012.html [ Failure ]
+crbug.com/1509927 [ angle-d3d11 no-clang-coverage nvidia passthrough release-x64 target-cpu-64 win ] conformance/ogles/GL/atan/atan_009_to_012.html [ Failure ]
 
 ## Vulkan / Win / NVIDIA / Passthrough command decoder ##
 
diff --git a/gpu/command_buffer/service/shared_image/gl_texture_passthrough_fallback_image_representation.cc b/gpu/command_buffer/service/shared_image/gl_texture_passthrough_fallback_image_representation.cc
index c47c6ff..c6dd703a 100644
--- a/gpu/command_buffer/service/shared_image/gl_texture_passthrough_fallback_image_representation.cc
+++ b/gpu/command_buffer/service/shared_image/gl_texture_passthrough_fallback_image_representation.cc
@@ -49,10 +49,18 @@
   api->glTexParameteriFn(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
   api->glTexParameteriFn(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 
-  const GLenum internal_format = format_desc.storage_internal_format;
   gl::ScopedProgressReporter scoped_progress_reporter(progress_reporter);
-  api->glTexStorage2DEXTFn(target, /*levels=*/1, internal_format, size.width(),
-                           size.height());
+
+  if (IsTexStorage2DAvailable()) {
+    const GLenum internal_format = format_desc.storage_internal_format;
+    api->glTexStorage2DEXTFn(target, /*levels=*/1, internal_format,
+                             size.width(), size.height());
+  } else {
+    const GLenum internal_format = format_desc.image_internal_format;
+    api->glTexImage2DFn(target, 0, internal_format, size.width(), size.height(),
+                        0, format_desc.data_format, format_desc.data_type,
+                        nullptr);
+  }
 
   return base::MakeRefCounted<gles2::TexturePassthrough>(service_id, target);
 }
diff --git a/infra/config/generated/testing/gn_isolate_map.pyl b/infra/config/generated/testing/gn_isolate_map.pyl
index 74468d5..b00754dc 100644
--- a/infra/config/generated/testing/gn_isolate_map.pyl
+++ b/infra/config/generated/testing/gn_isolate_map.pyl
@@ -419,10 +419,6 @@
     "label": "//:chrome_official_builder_no_unittests",
     "type": "additional_compile_target",
   },
-  "chrome_pkg": {
-    "label": "//chrome/app:chrome_pkg",
-    "type": "additional_compile_target",
-  },
   "chrome_private_code_test": {
     "label": "//chrome:chrome_private_code_test",
     "type": "generated_script",
diff --git a/infra/config/targets/compile_targets.star b/infra/config/targets/compile_targets.star
index f5c1affb4..dcc12663 100644
--- a/infra/config/targets/compile_targets.star
+++ b/infra/config/targets/compile_targets.star
@@ -80,11 +80,6 @@
 )
 
 targets.compile_target(
-    name = "chrome_pkg",
-    label = "//chrome/app:chrome_pkg",
-)
-
-targets.compile_target(
     name = "chrome_public_apk",
     label = "//chrome/android:chrome_public_apk",
 )
diff --git a/ios/chrome/browser/metrics/model/mobile_session_shutdown_metrics_provider.mm b/ios/chrome/browser/metrics/model/mobile_session_shutdown_metrics_provider.mm
index cba2111..0d4dded 100644
--- a/ios/chrome/browser/metrics/model/mobile_session_shutdown_metrics_provider.mm
+++ b/ios/chrome/browser/metrics/model/mobile_session_shutdown_metrics_provider.mm
@@ -210,11 +210,6 @@
                                      battery_charge);
 }
 
-// Logs the device's `available_storage` as a UTE stability metric.
-void LogAvailableStorage(NSInteger available_storage) {
-  UMA_STABILITY_HISTOGRAM_CUSTOM_COUNTS("Stability.iOS.UTE.AvailableStorage",
-                                        available_storage, 1, 200000, 100);
-}
 
 // Logs the OS version change between `os_version` and the current os version.
 // Records whether the version is the same, if a minor version change occurred,
@@ -313,9 +308,6 @@
     if (session_info.deviceBatteryState == DeviceBatteryState::kUnplugged) {
       LogBatteryCharge(session_info.deviceBatteryLevel);
     }
-    if (session_info.availableDeviceStorage >= 0) {
-      LogAvailableStorage(session_info.availableDeviceStorage);
-    }
     if (session_info.OSVersion) {
       LogOSVersionChange(base::SysNSStringToUTF8(session_info.OSVersion));
     }
diff --git a/ios/chrome/browser/ui/autofill/autofill_app_interface.h b/ios/chrome/browser/ui/autofill/autofill_app_interface.h
index 37df6e0..dada86f 100644
--- a/ios/chrome/browser/ui/autofill/autofill_app_interface.h
+++ b/ios/chrome/browser/ui/autofill/autofill_app_interface.h
@@ -27,11 +27,11 @@
 // the app binary and can be called from either app or test code.
 @interface AutofillAppInterface : NSObject
 
-// Removes all credentials stored.
-+ (void)clearPasswordStore;
+// Removes all credentials stored in the profile store.
++ (void)clearProfilePasswordStore;
 
-// Saves an example form in the store.
-+ (void)saveExamplePasswordForm;
+// Saves an example form in the profile store.
++ (void)saveExamplePasswordFormToProfileStore;
 
 // Saves an example form in the store for the passed URL spec.
 + (void)savePasswordFormForURLSpec:(NSString*)URLSpec;
diff --git a/ios/chrome/browser/ui/autofill/autofill_app_interface.mm b/ios/chrome/browser/ui/autofill/autofill_app_interface.mm
index 496bfbc..1b3e672 100644
--- a/ios/chrome/browser/ui/autofill/autofill_app_interface.mm
+++ b/ios/chrome/browser/ui/autofill/autofill_app_interface.mm
@@ -43,8 +43,9 @@
 const char16_t kExampleUsername[] = u"concrete username";
 const char16_t kExamplePassword[] = u"concrete password";
 
-// Gets the current password store.
-scoped_refptr<password_manager::PasswordStoreInterface> GetPasswordStore() {
+// Gets the current profile password store.
+scoped_refptr<password_manager::PasswordStoreInterface>
+GetPasswordProfileStore() {
   // ServiceAccessType governs behaviour in Incognito: only modifications with
   // EXPLICIT_ACCESS, which correspond to user's explicit gesture, succeed.
   // This test does not deal with Incognito, and should not run in Incognito
@@ -69,7 +70,7 @@
   const std::vector<password_manager::PasswordForm>& GetStoreResults() {
     results_.clear();
     ResetObtained();
-    GetPasswordStore()->GetAllLogins(weak_ptr_factory_.GetWeakPtr());
+    GetPasswordProfileStore()->GetAllLogins(weak_ptr_factory_.GetWeakPtr());
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wunused-result"
     base::test::ios::WaitUntilConditionOrTimeout(
@@ -108,10 +109,10 @@
   base::WeakPtrFactory<TestStoreConsumer> weak_ptr_factory_{this};
 };
 
-// Saves `form` to the password store and waits until the async processing is
-// done.
-void SaveToPasswordStore(const password_manager::PasswordForm& form) {
-  GetPasswordStore()->AddLogin(form);
+// Saves `form` to the profile password store and waits until the async
+// processing is done.
+void SaveToPasswordProfileStore(const password_manager::PasswordForm& form) {
+  GetPasswordProfileStore()->AddLogin(form);
   // When we retrieve the form from the store, `in_store` should be set.
   password_manager::PasswordForm expected_form = form;
   expected_form.in_store = password_manager::PasswordForm::Store::kProfileStore;
@@ -123,30 +124,30 @@
   }
 }
 
-// Saves an example form in the store.
-void SaveExamplePasswordForm() {
+// Saves an example form in the profile store.
+void SaveExamplePasswordFormInProfileStore() {
   password_manager::PasswordForm example;
   example.username_value = kExampleUsername;
   example.password_value = kExamplePassword;
   example.url = GURL("https://example.com/");
   example.signon_realm = password_manager_util::GetSignonRealm(example.url);
-  SaveToPasswordStore(example);
+  SaveToPasswordProfileStore(example);
 }
 
-// Saves an example form in the store for the passed URL.
+// Saves an example form in the profile store for the passed URL.
 void SaveLocalPasswordForm(const GURL& url) {
   password_manager::PasswordForm localForm;
   localForm.username_value = kExampleUsername;
   localForm.password_value = kExamplePassword;
   localForm.url = url;
   localForm.signon_realm = password_manager_util::GetSignonRealm(localForm.url);
-  SaveToPasswordStore(localForm);
+  SaveToPasswordProfileStore(localForm);
 }
 
-// Removes all credentials stored.
-void ClearPasswordStore() {
-  GetPasswordStore()->RemoveLoginsCreatedBetween(base::Time(), base::Time(),
-                                                 base::DoNothing());
+// Removes all credentials from the profile store.
+void ClearProfilePasswordStore() {
+  GetPasswordProfileStore()->RemoveLoginsCreatedBetween(
+      base::Time(), base::Time(), base::DoNothing());
   TestStoreConsumer consumer;
 }
 
@@ -350,12 +351,12 @@
 static std::unique_ptr<ScopedAutofillPaymentReauthModuleOverride>
     _scopedReauthModuleOverride;
 
-+ (void)clearPasswordStore {
-  ClearPasswordStore();
++ (void)clearProfilePasswordStore {
+  ClearProfilePasswordStore();
 }
 
-+ (void)saveExamplePasswordForm {
-  SaveExamplePasswordForm();
++ (void)saveExamplePasswordFormToProfileStore {
+  SaveExamplePasswordFormInProfileStore();
 }
 
 + (void)savePasswordFormForURLSpec:(NSString*)URLSpec {
diff --git a/ios/chrome/browser/ui/autofill/branding/branding_view_controller_egtest.mm b/ios/chrome/browser/ui/autofill/branding/branding_view_controller_egtest.mm
index d964863..afc0f4b 100644
--- a/ios/chrome/browser/ui/autofill/branding/branding_view_controller_egtest.mm
+++ b/ios/chrome/browser/ui/autofill/branding/branding_view_controller_egtest.mm
@@ -27,10 +27,10 @@
 // The "username" field in the test page.
 const char kFormElementUsername[] = "username";
 
-// Save a set of credentials so that the manual fill password button is visible
-// in keyboard accessories.
-void EnableManualFillButtonForPassword() {
-  [AutofillAppInterface saveExamplePasswordForm];
+// Save a set of credentials to the profile store so that the manual fill
+// password button is visible in keyboard accessories.
+void EnableManualFillButtonForPasswordInProfileStore() {
+  [AutofillAppInterface saveExamplePasswordFormToProfileStore];
 }
 
 // Save an address so that the manual fill address button is visible in keyboard
@@ -45,10 +45,10 @@
   [AutofillAppInterface saveLocalCreditCard];
 }
 
-// Remove all saved passwords, credit cards and addresses so that no manual fill
-// buttons will show in keyboard accessories.
-void DisableManualFillButtons() {
-  [AutofillAppInterface clearPasswordStore];
+// Remove all passwords in profile store, all credit cards and all addresses so
+// that no manual fill buttons will show in keyboard accessories.
+void DisableManualFillButtonsInProfileStore() {
+  [AutofillAppInterface clearProfilePasswordStore];
   [AutofillAppInterface clearProfilesStore];
   [AutofillAppInterface clearCreditCardStore];
 }
@@ -114,7 +114,7 @@
     [[AppLaunchManager sharedManager]
         ensureAppLaunchedWithConfiguration:[self appConfigurationForTestCase]];
   }
-  DisableManualFillButtons();
+  DisableManualFillButtonsInProfileStore();
   // Turn on test server and load test page.
   GREYAssertTrue(self.testServer->Start(), @"Test server failed to start.");
   GURL url = self.testServer->GetURL(kFormHTMLFile);
@@ -123,7 +123,7 @@
 }
 
 - (void)tearDown {
-  DisableManualFillButtons();
+  DisableManualFillButtonsInProfileStore();
   // Clear feature related local state prefs.
   [ChromeEarlGrey
       resetDataForLocalStatePref:prefs::kAutofillBrandingIconDisplayCount];
@@ -134,7 +134,7 @@
 
 // Tests that the autofill branding icon only shows twice.
 - (void)testBrandingTwoImpressions {
-  EnableManualFillButtonForPassword();
+  EnableManualFillButtonForPasswordInProfileStore();
   // First time.
   BringUpKeyboard();
   CheckBrandingHasVisiblity(YES);
@@ -153,7 +153,7 @@
 
 // Tests that the branding is visible when some manual fill button is visible.
 - (void)testSomeManualFillButtonsVisible {
-  EnableManualFillButtonForPassword();
+  EnableManualFillButtonForPasswordInProfileStore();
   BringUpKeyboard();
   CheckBrandingHasVisiblity(YES);
 }
@@ -167,8 +167,8 @@
 // Tests that the branding is not visible when some manual fill button is
 // enabled then disabled before the keyboard is presented.
 - (void)testEnableAndDisableManualFillButtonsBeforeKeyboardPresented {
-  EnableManualFillButtonForPassword();
-  DisableManualFillButtons();
+  EnableManualFillButtonForPasswordInProfileStore();
+  DisableManualFillButtonsInProfileStore();
   BringUpKeyboard();
   CheckBrandingHasVisiblity(NO);
 }
@@ -176,8 +176,8 @@
 // Tests that the branding is visible when some manual fill button is enabled,
 // disabled and re-enabled before the keyboard is presented.
 - (void)testEnableDisableAndReenableManualFillButtonsBeforeKeyboardPresented {
-  EnableManualFillButtonForPassword();
-  DisableManualFillButtons();
+  EnableManualFillButtonForPasswordInProfileStore();
+  DisableManualFillButtonsInProfileStore();
   EnableManualFillButtonForProfile();
   BringUpKeyboard();
   CheckBrandingHasVisiblity(YES);
@@ -186,10 +186,10 @@
 // Tests that the branding is visible when some manual fill button is enabled,
 // then disappears when the manual fill button is disabled.
 - (void)testDisableManualFillButtonsDuringKeyboardPresenting {
-  EnableManualFillButtonForPassword();
+  EnableManualFillButtonForPasswordInProfileStore();
   BringUpKeyboard();
   CheckBrandingHasVisiblity(YES);
-  DisableManualFillButtons();
+  DisableManualFillButtonsInProfileStore();
   DismissKeyboard();
   BringUpKeyboard();
   CheckBrandingHasVisiblity(NO);
@@ -200,11 +200,11 @@
 - (void)testEnableAndDisableManualFillButtonsDuringKeyboardPresenting {
   BringUpKeyboard();
   CheckBrandingHasVisiblity(NO);
-  EnableManualFillButtonForPassword();
+  EnableManualFillButtonForPasswordInProfileStore();
   DismissKeyboard();
   BringUpKeyboard();
   CheckBrandingHasVisiblity(YES);
-  DisableManualFillButtons();
+  DisableManualFillButtonsInProfileStore();
   DismissKeyboard();
   BringUpKeyboard();
   CheckBrandingHasVisiblity(NO);
@@ -213,12 +213,12 @@
 // Tests that the branding is visible even after one of the multiple manual fill
 // buttons is disabled.
 - (void)testEnableTwoManualFillButtonsAndDisableOneDuringKeyboardPresenting {
-  EnableManualFillButtonForPassword();
+  EnableManualFillButtonForPasswordInProfileStore();
   EnableManualFillButtonForCreditCard();
   BringUpKeyboard();
   CheckBrandingHasVisiblity(YES);
   // Hide manual fill button for password.
-  [AutofillAppInterface clearPasswordStore];
+  [AutofillAppInterface clearProfilePasswordStore];
   DismissKeyboard();
   BringUpKeyboard();
   CheckBrandingHasVisiblity(YES);
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller_egtest.mm b/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller_egtest.mm
index fe2f839..69cef32b 100644
--- a/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller_egtest.mm
+++ b/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller_egtest.mm
@@ -157,7 +157,9 @@
   GREYAssertTrue(self.testServer->Start(), @"Test server failed to start.");
   self.URL = self.testServer->GetURL(kFormHTMLFile);
   [self loadLoginPage];
-  [AutofillAppInterface saveExamplePasswordForm];
+  [AutofillAppInterface saveExamplePasswordFormToProfileStore];
+  [ChromeEarlGrey loadURL:self.URL];
+  [ChromeEarlGrey waitForWebStateContainingText:"hello!"];
 
   // Mock successful reauth for opening the Password Manager.
   [PasswordSettingsAppInterface setUpMockReauthenticationModule];
@@ -166,7 +168,7 @@
 }
 
 - (void)tearDown {
-  [AutofillAppInterface clearPasswordStore];
+  [AutofillAppInterface clearProfilePasswordStore];
   [PasswordSettingsAppInterface removeMockReauthenticationModule];
   [super tearDown];
 }
@@ -788,7 +790,7 @@
 
 // Tests that the password icon is not present when no passwords are available.
 - (void)testPasswordIconIsNotVisibleWhenPasswordStoreEmpty {
-  [AutofillAppInterface clearPasswordStore];
+  [AutofillAppInterface clearProfilePasswordStore];
 
   // Bring up the keyboard.
   [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
diff --git a/ios/chrome/browser/ui/content_suggestions/safety_check/safety_check_view_egtest.mm b/ios/chrome/browser/ui/content_suggestions/safety_check/safety_check_view_egtest.mm
index 2590ed6..79bb14c 100644
--- a/ios/chrome/browser/ui/content_suggestions/safety_check/safety_check_view_egtest.mm
+++ b/ios/chrome/browser/ui/content_suggestions/safety_check/safety_check_view_egtest.mm
@@ -113,7 +113,7 @@
 // Tests that the Password Checkup view is dismissed when there are no saved
 // passwords.
 - (void)testPasswordCheckupDismissedAfterAllPasswordsGone {
-  password_manager_test_utils::SavePasswordForm();
+  password_manager_test_utils::SavePasswordFormToProfileStore();
 
   [[[EarlGrey
       selectElementWithMatcher:grey_allOf(grey_accessibilityID(
@@ -149,7 +149,7 @@
           grey_accessibilityID(password_manager::kPasswordCheckupTableViewId)]
       assertWithMatcher:grey_notNil()];
 
-  [PasswordSettingsAppInterface clearPasswordStore];
+  [PasswordSettingsAppInterface clearProfilePasswordStore];
 
   // Verify that the Password Checkup Homepage is not displayed.
   [[EarlGrey
@@ -161,7 +161,7 @@
 // Tests that the Password Checkup view is dismissed when the user doesn't pass
 // Local Authentication.
 - (void)testPasswordCheckupDismissedAfterFailedAuthentication {
-  password_manager_test_utils::SavePasswordForm();
+  password_manager_test_utils::SavePasswordFormToProfileStore();
 
   [[[EarlGrey
       selectElementWithMatcher:grey_allOf(grey_accessibilityID(
diff --git a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_egtest.mm b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_egtest.mm
index 1e8ebe8..f77a0eff 100644
--- a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_egtest.mm
+++ b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_egtest.mm
@@ -768,10 +768,10 @@
 // contains the correct string for passwords.
 - (void)testBulkUploadDescriptionTextForPasswords {
   // Add local data.
-  password_manager_test_utils::SavePasswordForm(@"password1", @"user1",
-                                                @"https://example1.com");
-  password_manager_test_utils::SavePasswordForm(@"password2", @"user2",
-                                                @"https://example2.com");
+  password_manager_test_utils::SavePasswordFormToProfileStore(
+      @"password1", @"user1", @"https://example1.com");
+  password_manager_test_utils::SavePasswordFormToProfileStore(
+      @"password2", @"user2", @"https://example2.com");
 
   FakeSystemIdentity* fakeIdentity = [FakeSystemIdentity fakeIdentity1];
   [SigninEarlGrey addFakeIdentity:fakeIdentity];
@@ -838,8 +838,8 @@
 // contains the correct string for passwords and other data type.
 - (void)testBulkUploadDescriptionTextForPasswordsAndOthers {
   // Add local data.
-  password_manager_test_utils::SavePasswordForm(@"password", @"user",
-                                                @"https://example.com");
+  password_manager_test_utils::SavePasswordFormToProfileStore(
+      @"password", @"user", @"https://example.com");
   reading_list_test_utils::AddURLToReadingList(GURL("https://example.com"));
   SaveBookmark(@"foo", @"https://www.foo.com");
 
@@ -865,8 +865,8 @@
 // - Reading list
 - (void)testBulkUploadPageForAllDataTypes {
   // Add local data.
-  password_manager_test_utils::SavePasswordForm(@"password", @"user",
-                                                @"https://example.com");
+  password_manager_test_utils::SavePasswordFormToProfileStore(
+      @"password", @"user", @"https://example.com");
   reading_list_test_utils::AddURLToReadingList(GURL("https://example.com"));
   SaveBookmark(@"foo", @"https://www.foo.com");
 
@@ -911,8 +911,8 @@
 // - Passwords
 - (void)testBulkUploadPageForPasswordsOnly {
   // Add local data.
-  password_manager_test_utils::SavePasswordForm(@"password", @"user",
-                                                @"https://example.com");
+  password_manager_test_utils::SavePasswordFormToProfileStore(
+      @"password", @"user", @"https://example.com");
 
   FakeSystemIdentity* fakeIdentity = [FakeSystemIdentity fakeIdentity1];
   [SigninEarlGrey addFakeIdentity:fakeIdentity];
@@ -956,8 +956,8 @@
 // - Bookmarks
 - (void)testBulkUploadPageForPasswordsAndBookmarks {
   // Add local data.
-  password_manager_test_utils::SavePasswordForm(@"password", @"user",
-                                                @"https://example.com");
+  password_manager_test_utils::SavePasswordFormToProfileStore(
+      @"password", @"user", @"https://example.com");
   SaveBookmark(@"foo", @"https://www.foo.com");
 
   FakeSystemIdentity* fakeIdentity = [FakeSystemIdentity fakeIdentity1];
@@ -1001,8 +1001,8 @@
 // - Passwords
 - (void)testBulkUploadForPasswords {
   // Add local data.
-  password_manager_test_utils::SavePasswordForm(@"password", @"user",
-                                                @"https://example.com");
+  password_manager_test_utils::SavePasswordFormToProfileStore(
+      @"password", @"user", @"https://example.com");
   reading_list_test_utils::AddURLToReadingList(GURL("https://example.com"));
   SaveBookmark(@"foo", @"https://www.foo.com");
 
@@ -1093,8 +1093,8 @@
 // - Reading List
 - (void)testBulkUploadForBookmarksAndReadingList {
   // Add local data.
-  password_manager_test_utils::SavePasswordForm(@"password", @"user",
-                                                @"https://example.com");
+  password_manager_test_utils::SavePasswordFormToProfileStore(
+      @"password", @"user", @"https://example.com");
   reading_list_test_utils::AddURLToReadingList(GURL("https://example.com"));
   SaveBookmark(@"foo", @"https://www.foo.com");
 
@@ -1164,8 +1164,8 @@
 // - Reading List
 - (void)testBulkUploadForAllDataTypes {
   // Add local data.
-  password_manager_test_utils::SavePasswordForm(@"password", @"user",
-                                                @"https://example.com");
+  password_manager_test_utils::SavePasswordFormToProfileStore(
+      @"password", @"user", @"https://example.com");
   reading_list_test_utils::AddURLToReadingList(GURL("https://example.com"));
   SaveBookmark(@"foo", @"https://www.foo.com");
 
diff --git a/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_egtest.mm b/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_egtest.mm
index d2f99878..086d76c 100644
--- a/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_egtest.mm
+++ b/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_egtest.mm
@@ -31,9 +31,10 @@
 using password_manager_test_utils::PasswordCheckupCellForState;
 using password_manager_test_utils::PasswordIssuesTableView;
 using password_manager_test_utils::ReauthenticationController;
-using password_manager_test_utils::SaveCompromisedPasswordForm;
-using password_manager_test_utils::SaveMutedCompromisedPasswordForm;
-using password_manager_test_utils::SavePasswordForm;
+using password_manager_test_utils::SaveCompromisedPasswordFormToProfileStore;
+using password_manager_test_utils::
+    SaveMutedCompromisedPasswordFormToProfileStore;
+using password_manager_test_utils::SavePasswordFormToProfileStore;
 
 namespace {
 
@@ -177,14 +178,14 @@
 #pragma mark - Helpers
 
 // Saves two reused passwords.
-void SaveReusedPasswordForms() {
-  SavePasswordForm(kReusedPassword, kDefaultUsername, kSite1);
-  SavePasswordForm(kReusedPassword, kDefaultUsername, kSite2);
+void SaveReusedPasswordFormsToProfileStore() {
+  SavePasswordFormToProfileStore(kReusedPassword, kDefaultUsername, kSite1);
+  SavePasswordFormToProfileStore(kReusedPassword, kDefaultUsername, kSite2);
 }
 
 // Saves a weak password.
-void SaveWeakPasswordForm() {
-  SavePasswordForm(kWeakPassword, kDefaultUsername, kSite3);
+void SaveWeakPasswordFormToProfileStore() {
+  SavePasswordFormToProfileStore(kWeakPassword, kDefaultUsername, kSite3);
 }
 
 // Opens the Password Checkup Homepage.
@@ -314,7 +315,7 @@
 
 // Tests the safe state of the Password Checkup Homepage.
 - (void)testPasswordCheckupHomepageSafeState {
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   OpenPasswordCheckupHomepage(/*result_state=*/PasswordCheckStateSafe,
                               /*result_password_count=*/0);
@@ -335,7 +336,7 @@
 // Validates that the Password Manager UI is dismissed when local authentication
 // fails while in the Password Checkup UI.
 - (void)testPasswordCheckupHomepageWithFailedAuth {
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   OpenPasswordCheckupHomepage(/*result_state=*/PasswordCheckStateSafe,
                               /*result_password_count=*/0);
@@ -368,9 +369,9 @@
 
 // Tests the warning state of the Password Checkup Homepage.
 - (void)testPasswordCheckupHomepageWarningState {
-  SaveMutedCompromisedPasswordForm();
-  SaveReusedPasswordForms();
-  SaveWeakPasswordForm();
+  SaveMutedCompromisedPasswordFormToProfileStore();
+  SaveReusedPasswordFormsToProfileStore();
+  SaveWeakPasswordFormToProfileStore();
 
   OpenPasswordCheckupHomepage(
       /*result_state=*/PasswordCheckStateReusedPasswords,
@@ -404,7 +405,7 @@
 
 // Tests the severe warning state of the Password Checkup Homepage.
 - (void)testPasswordCheckupHomepageCompromisedState {
-  SaveCompromisedPasswordForm();
+  SaveCompromisedPasswordFormToProfileStore();
 
   OpenPasswordCheckupHomepage(
       /*result_state=*/PasswordCheckStateUnmutedCompromisedPasswords,
@@ -433,7 +434,7 @@
   if ([ChromeEarlGrey isIPadIdiom]) {
     EARL_GREY_TEST_DISABLED(@"Fails on iPad.");
   }
-  SaveCompromisedPasswordForm();
+  SaveCompromisedPasswordFormToProfileStore();
 
   NSInteger numberOfAffiliatedGroups = 1;
 
@@ -473,7 +474,7 @@
 
 // Tests the error state of the Password Checkup Homepage.
 - (void)testPasswordCheckupHomepageErrorState {
-  SaveCompromisedPasswordForm();
+  SaveCompromisedPasswordFormToProfileStore();
 
   OpenPasswordCheckupHomepage(
       /*result_state=*/PasswordCheckStateUnmutedCompromisedPasswords,
@@ -513,7 +514,7 @@
                            @"the Password Checkup Homepage.");
   }
 
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   // Rotate device to left landscape orientation before opening the Password
   // Checkup Homepage.
@@ -544,7 +545,7 @@
 
 // Tests dismissing a compromised password warning.
 - (void)testPasswordCheckupDismissCompromisedPasswordWarning {
-  SaveCompromisedPasswordForm();
+  SaveCompromisedPasswordFormToProfileStore();
 
   OpenPasswordCheckupHomepage(
       /*result_state=*/PasswordCheckStateUnmutedCompromisedPasswords,
@@ -603,7 +604,7 @@
 
 // Tests restoring a muted compromised password warning.
 - (void)testPasswordCheckupRestoreCompromisedPasswordWarning {
-  SaveMutedCompromisedPasswordForm();
+  SaveMutedCompromisedPasswordFormToProfileStore();
 
   OpenPasswordCheckupHomepage(
       /*result_state=*/PasswordCheckStateDismissedWarnings,
@@ -662,7 +663,7 @@
 
 // Tests deleting the last saved password through Password Checkup.
 - (void)testDeleteLastPassword {
-  SaveCompromisedPasswordForm();
+  SaveCompromisedPasswordFormToProfileStore();
 
   OpenPasswordCheckupHomepage(
       /*result_state=*/PasswordCheckStateUnmutedCompromisedPasswords,
@@ -693,7 +694,7 @@
 // Tests resolving the last reused passwords issue by editing a password through
 // Password Checkup.
 - (void)testResolveLastIssueByEditingPassword {
-  SaveReusedPasswordForms();
+  SaveReusedPasswordFormsToProfileStore();
 
   OpenPasswordCheckupHomepage(
       /*result_state=*/PasswordCheckStateReusedPasswords,
@@ -729,8 +730,8 @@
 // Tests resolving the last compromised passwords issue by deleting a password
 // through Password Checkup.
 - (void)testResolveLastIssueByDeletingPassword {
-  SavePasswordForm(kSafePassword, kDefaultUsername, kSite1);
-  SaveCompromisedPasswordForm();
+  SavePasswordFormToProfileStore(kSafePassword, kDefaultUsername, kSite1);
+  SaveCompromisedPasswordFormToProfileStore();
 
   OpenPasswordCheckupHomepage(
       /*result_state=*/PasswordCheckStateUnmutedCompromisedPasswords,
@@ -766,7 +767,7 @@
 // Tests resolving the last compromised passwords issue by deleting a password
 // through Password Checkup.
 - (void)testChangeCompromisedPasswordToSafePassword {
-  SaveCompromisedPasswordForm();
+  SaveCompromisedPasswordFormToProfileStore();
 
   OpenPasswordCheckupHomepage(
       /*result_state=*/PasswordCheckStateUnmutedCompromisedPasswords,
@@ -802,7 +803,7 @@
 // Tests changing the password of a muted compromised password to a weak
 // password.
 - (void)testChangeMutedPasswordToWeakPassword {
-  SaveMutedCompromisedPasswordForm();
+  SaveMutedCompromisedPasswordFormToProfileStore();
 
   OpenPasswordCheckupHomepage(
       /*result_state=*/PasswordCheckStateDismissedWarnings,
@@ -863,7 +864,7 @@
 // Tests the details page of a credential that is both weak and compromised when
 // opened from the weak issues page.
 - (void)testCompromisedAndWeakPasswordOpenedInWeakContext {
-  SaveCompromisedPasswordForm(kWeakPassword);
+  SaveCompromisedPasswordFormToProfileStore(kWeakPassword);
 
   OpenPasswordCheckupHomepage(
       /*result_state=*/PasswordCheckStateUnmutedCompromisedPasswords,
@@ -889,8 +890,8 @@
 // Tests the details page of a credential that is both reused and compromised
 // when opened from the reused issues page.
 - (void)testCompromisedAndReusedPasswordOpenedInReusedContext {
-  SaveCompromisedPasswordForm(kReusedPassword);
-  SaveReusedPasswordForms();
+  SaveCompromisedPasswordFormToProfileStore(kReusedPassword);
+  SaveReusedPasswordFormsToProfileStore();
 
   OpenPasswordCheckupHomepage(
       /*result_state=*/PasswordCheckStateUnmutedCompromisedPasswords,
@@ -916,13 +917,13 @@
 // Tests that Password Checkup Homepage is dismissed when there are no saved
 // passwords.
 - (void)testPasswordCheckupDismissedAfterAllPasswordsGone {
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   OpenPasswordCheckupHomepage(
       /*result_state=*/PasswordCheckStateSafe,
       /*result_password_count=*/0);
 
-  [PasswordSettingsAppInterface clearPasswordStore];
+  [PasswordSettingsAppInterface clearProfilePasswordStore];
 
   // Verify that the Password Checkup Homepage is dismissed.
   [[EarlGrey
@@ -934,7 +935,7 @@
 // Validates that the Password Manager UI is dismissed when local authentication
 // fails while in the Password Issues UI.
 - (void)testPasswordIssuesWithFailedAuth {
-  SaveWeakPasswordForm();
+  SaveWeakPasswordFormToProfileStore();
 
   OpenPasswordCheckupHomepage(
       /*result_state=*/PasswordCheckStateWeakPasswords,
diff --git a/ios/chrome/browser/ui/settings/password/password_manager_egtest.mm b/ios/chrome/browser/ui/settings/password/password_manager_egtest.mm
index 6e2f3400..d379040 100644
--- a/ios/chrome/browser/ui/settings/password/password_manager_egtest.mm
+++ b/ios/chrome/browser/ui/settings/password/password_manager_egtest.mm
@@ -87,7 +87,7 @@
 using password_manager_test_utils::PasswordSettingsTableView;
 using password_manager_test_utils::PasswordTextfieldForUsernameAndSites;
 using password_manager_test_utils::ReauthenticationController;
-using password_manager_test_utils::SavePasswordForm;
+using password_manager_test_utils::SavePasswordFormToProfileStore;
 using password_manager_test_utils::TapNavigationBarEditButton;
 using password_manager_test_utils::UsernameTextfieldForUsernameAndSites;
 using testing::ElementWithAccessibilityLabelSubstring;
@@ -353,32 +353,34 @@
 
 // Saves two example forms in the store.
 void SaveExamplePasswordForms() {
-  SavePasswordForm(/*password=*/@"password1",
-                   /*username=*/@"user1",
-                   /*origin=*/@"https://example11.com");
-  SavePasswordForm(/*password=*/@"password2",
-                   /*username=*/@"user2",
-                   /*origin=*/@"https://example12.com");
+  SavePasswordFormToProfileStore(/*password=*/@"password1",
+                                 /*username=*/@"user1",
+                                 /*origin=*/@"https://example11.com");
+  SavePasswordFormToProfileStore(/*password=*/@"password2",
+                                 /*username=*/@"user2",
+                                 /*origin=*/@"https://example12.com");
 }
 
 // Saves an example form with note in the store.
-void SaveExamplePasswordFormWithNote() {
-  GREYAssert(
-      [PasswordSettingsAppInterface saveExampleNote:@"concrete note"
-                                           password:kDefaultPassword
-                                           username:kDefaultUsername
-                                             origin:@"https://example.com"],
-      kPasswordStoreErrorMessage);
+void SaveExamplePasswordFormToProfileStoreWithNote() {
+  GREYAssert([PasswordSettingsAppInterface
+                 saveExampleNoteToProfileStore:@"concrete note"
+                                      password:kDefaultPassword
+                                      username:kDefaultUsername
+                                        origin:@"https://example.com"],
+             kPasswordStoreErrorMessage);
 }
 
 // Saves two example blocked forms in the store.
-void SaveExampleBlockedForms() {
-  GREYAssert([PasswordSettingsAppInterface
-                 saveExampleBlockedOrigin:@"https://exclude1.com"],
-             kPasswordStoreErrorMessage);
-  GREYAssert([PasswordSettingsAppInterface
-                 saveExampleBlockedOrigin:@"https://exclude2.com"],
-             kPasswordStoreErrorMessage);
+void SaveExampleBlockedFormsToProfileStore() {
+  GREYAssert(
+      [PasswordSettingsAppInterface
+          saveExampleBlockedOriginToProfileStore:@"https://exclude1.com"],
+      kPasswordStoreErrorMessage);
+  GREYAssert(
+      [PasswordSettingsAppInterface
+          saveExampleBlockedOriginToProfileStore:@"https://exclude2.com"],
+      kPasswordStoreErrorMessage);
 }
 
 // Taps on the "Settings" option to show the submenu.
@@ -661,7 +663,7 @@
   // settings get closed. Ensure that they are closed to avoid interference with
   // other tests.
   [PasswordSettingsAppInterface dismissSnackBar];
-  GREYAssert([PasswordSettingsAppInterface clearPasswordStore],
+  GREYAssert([PasswordSettingsAppInterface clearProfilePasswordStore],
              @"PasswordStore was not cleared.");
 
   GREYAssertNil([MetricsAppInterface releaseHistogramTester],
@@ -796,7 +798,7 @@
 // Verifies the UI elements are accessible on the Passwords page.
 - (void)testAccessibilityOnPasswords {
   // Saving a form is needed for using the "password details" view.
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   OpenPasswordManager();
   [ChromeEarlGrey verifyAccessibilityForCurrentScreen];
@@ -822,7 +824,7 @@
 // Checks that attempt to copy a password provides appropriate feedback.
 - (void)testCopyPasswordToast {
   // Saving a form is needed for using the "password details" view.
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   OpenPasswordManager();
 
@@ -848,7 +850,7 @@
 // Checks that an attempt to show a password provides an appropriate feedback.
 - (void)testShowPasswordSucceeded {
   // Saving a form is needed for using the "password details" view.
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   OpenPasswordManager();
 
@@ -873,7 +875,7 @@
 // Checks that attempts to copy a username provide appropriate feedback.
 - (void)testCopyUsernameToast {
   // Saving a form is needed for using the "password details" view.
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   OpenPasswordManager();
 
@@ -898,7 +900,7 @@
 // Checks that attempts to copy a site URL provide appropriate feedback.
 - (void)testCopySiteToast {
   // Saving a form is needed for using the "password details" view.
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   OpenPasswordManager();
 
@@ -926,7 +928,7 @@
 // to the list-of-passwords view which doesn't display that form anymore.
 - (void)testSavedFormDeletionInDetailView {
   // Save form to be deleted later.
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   OpenPasswordManager();
 
@@ -947,9 +949,10 @@
       selectElementWithMatcher:grey_accessibilityID(kPasswordsTableViewID)]
       assertWithMatcher:grey_notNil()];
 
-  // Verify that the deletion was propagated to the PasswordStore.
-  GREYAssertEqual(0, [PasswordSettingsAppInterface passwordStoreResultsCount],
-                  @"Stored password was not removed from PasswordStore.");
+  // Verify that the deletion was propagated to the ProfilePasswordStore.
+  GREYAssertEqual(
+      0, [PasswordSettingsAppInterface passwordProfileStoreResultsCount],
+      @"Stored password was not removed from ProfilePasswordStore.");
 
   // Also verify that the removed password is no longer in the list.
   [[self interactionForSinglePasswordEntryWithDomain:@"example.com"]
@@ -971,7 +974,7 @@
 // after the user had edited the password.
 - (void)testSavedFormDeletionInDetailViewAfterEditingFields {
   // Save form to be deleted later.
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   OpenPasswordManager();
 
@@ -999,9 +1002,10 @@
       selectElementWithMatcher:grey_accessibilityID(kPasswordsTableViewID)]
       assertWithMatcher:grey_notNil()];
 
-  // Verify that the deletion was propagated to the PasswordStore.
-  GREYAssertEqual(0, [PasswordSettingsAppInterface passwordStoreResultsCount],
-                  @"Stored password was not removed from PasswordStore.");
+  // Verify that the deletion was propagated to the ProfilePasswordStore.
+  GREYAssertEqual(
+      0, [PasswordSettingsAppInterface passwordProfileStoreResultsCount],
+      @"Stored password was not removed from ProfilePasswordStore.");
 
   // Also verify that the removed password is no longer in the list.
   [[self interactionForSinglePasswordEntryWithDomain:@"example.com"]
@@ -1023,10 +1027,10 @@
 // to the list-of-passwords showing only previously saved blocked sites.
 - (void)testSavedFormDeletionInDetailViewWithBlockedSites {
   // Save form to be deleted later.
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   // Saved blocked sites that should not be affected.
-  SaveExampleBlockedForms();
+  SaveExampleBlockedFormsToProfileStore();
 
   OpenPasswordManager();
 
@@ -1047,9 +1051,10 @@
       selectElementWithMatcher:grey_accessibilityID(kPasswordsTableViewID)]
       assertWithMatcher:grey_notNil()];
 
-  // Verify that the deletion was propagated to the PasswordStore.
-  GREYAssertEqual(2, [PasswordSettingsAppInterface passwordStoreResultsCount],
-                  @"Stored password was not removed from PasswordStore.");
+  // Verify that the deletion was propagated to the ProfilePasswordStore.
+  GREYAssertEqual(
+      2, [PasswordSettingsAppInterface passwordProfileStoreResultsCount],
+      @"Stored password was not removed from ProfilePasswordStore.");
 
   // Also verify that the removed password is no longer in the list.
   [[self interactionForSinglePasswordEntryWithDomain:@"example.com"]
@@ -1072,13 +1077,13 @@
 // anymore.
 - (void)testDuplicatedSavedFormDeletionInDetailView {
   // Save form to be deleted later.
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
   // Save duplicate of the previously saved form to be deleted at the same time.
   // This entry is considered duplicated because it maps to the same sort key
   // as the previous one.
-  SavePasswordForm(/*password=*/kDefaultPassword,
-                   /*username=*/kDefaultUsername,
-                   /*origin=*/@"https://example.com/example");
+  SavePasswordFormToProfileStore(/*password=*/kDefaultPassword,
+                                 /*username=*/kDefaultUsername,
+                                 /*origin=*/@"https://example.com/example");
 
   OpenPasswordManager();
 
@@ -1104,9 +1109,10 @@
       selectElementWithMatcher:grey_accessibilityID(kPasswordsTableViewID)]
       assertWithMatcher:grey_notNil()];
 
-  // Verify that the deletion was propagated to the PasswordStore.
-  GREYAssertEqual(0, [PasswordSettingsAppInterface passwordStoreResultsCount],
-                  @"Stored password was not removed from PasswordStore.");
+  // Verify that the deletion was propagated to the ProfilePasswordStore.
+  GREYAssertEqual(
+      0, [PasswordSettingsAppInterface passwordProfileStoreResultsCount],
+      @"Stored password was not removed from ProfilePasswordStore.");
 
   // Also verify that the removed password is no longer in the list.
   [[self interactionForSinglePasswordEntryWithDomain:@"example.com"]
@@ -1129,7 +1135,7 @@
 - (void)testBlockedFormDeletionInDetailView {
   // Save blocked form to be deleted later.
   GREYAssert([PasswordSettingsAppInterface
-                 saveExampleBlockedOrigin:@"https://blocked.com"],
+                 saveExampleBlockedOriginToProfileStore:@"https://blocked.com"],
              kPasswordStoreErrorMessage);
 
   OpenPasswordManager();
@@ -1154,9 +1160,10 @@
       selectElementWithMatcher:grey_accessibilityID(kPasswordsTableViewID)]
       assertWithMatcher:grey_notNil()];
 
-  // Verify that the deletion was propagated to the PasswordStore.
-  GREYAssertEqual(0, [PasswordSettingsAppInterface passwordStoreResultsCount],
-                  @"Stored password was not removed from PasswordStore.");
+  // Verify that the deletion was propagated to the ProfilePasswordStore.
+  GREYAssertEqual(
+      0, [PasswordSettingsAppInterface passwordProfileStoreResultsCount],
+      @"Stored password was not removed from ProfilePasswordStore.");
 
   // Also verify that the removed password is no longer in the list.
   [GetInteractionForPasswordEntry(@"secret.com")
@@ -1180,10 +1187,10 @@
 - (void)testBlockedFormDeletionInDetailViewWithSavedForm {
   // Save blocked form to be deleted later.
   GREYAssert([PasswordSettingsAppInterface
-                 saveExampleBlockedOrigin:@"https://blocked.com"],
+                 saveExampleBlockedOriginToProfileStore:@"https://blocked.com"],
              kPasswordStoreErrorMessage);
 
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   OpenPasswordManager();
 
@@ -1207,9 +1214,10 @@
       selectElementWithMatcher:grey_accessibilityID(kPasswordsTableViewID)]
       assertWithMatcher:grey_notNil()];
 
-  // Verify that the deletion was propagated to the PasswordStore.
-  GREYAssertEqual(1, [PasswordSettingsAppInterface passwordStoreResultsCount],
-                  @"Stored password was not removed from PasswordStore.");
+  // Verify that the deletion was propagated to the ProfilePasswordStore.
+  GREYAssertEqual(
+      1, [PasswordSettingsAppInterface passwordProfileStoreResultsCount],
+      @"Stored password was not removed from ProfilePasswordStore.");
 
   // Also verify that the removed blocked site is no longer in the list.
   [GetInteractionForPasswordEntry(@"secret.com")
@@ -1228,7 +1236,7 @@
 // Checks that deleting a password from password details can be cancelled.
 - (void)testCancelDeletionInDetailView {
   // Save form to be deleted later.
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   OpenPasswordManager();
 
@@ -1252,8 +1260,9 @@
       assertWithMatcher:grey_notNil()];
 
   // Verify that the deletion did not happen.
-  GREYAssertEqual(1u, [PasswordSettingsAppInterface passwordStoreResultsCount],
-                  @"Stored password was removed from PasswordStore.");
+  GREYAssertEqual(
+      1u, [PasswordSettingsAppInterface passwordProfileStoreResultsCount],
+      @"Stored password was removed from ProfilePasswordStore.");
 
   // Go back to the list view and verify that the password is still in the
   // list.
@@ -1274,7 +1283,7 @@
 // not accessible on tapping the entries.
 - (void)testEditMode {
   // Save a form to have something to tap on.
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   OpenPasswordManager();
 
@@ -1298,7 +1307,7 @@
 // an appropriate feedback.
 - (void)testCopyPasswordMenuItem {
   // Saving a form is needed for using the "password details" view.
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   OpenPasswordManager();
 
@@ -1332,11 +1341,13 @@
 
 // Checks that federated credentials have no password but show the federation.
 - (void)testFederated {
-  GREYAssert([PasswordSettingsAppInterface
-                 saveExampleFederatedOrigin:@"https://famous.provider.net"
-                                   username:@"federated username"
-                                     origin:@"https://example.com"],
-             kPasswordStoreErrorMessage);
+  GREYAssert(
+      [PasswordSettingsAppInterface
+          saveExampleFederatedOriginToProfileStore:
+              @"https://famous.provider.net"
+                                          username:@"federated username"
+                                            origin:@"https://example.com"],
+      kPasswordStoreErrorMessage);
 
   OpenPasswordManager();
 
@@ -1377,7 +1388,7 @@
 // Checks the order of the elements in the detail view layout for a
 // non-federated, non-blocked credential.
 - (void)testLayoutNormal {
-  SaveExamplePasswordFormWithNote();
+  SaveExamplePasswordFormToProfileStoreWithNote();
 
   OpenPasswordManager();
 
@@ -1415,7 +1426,7 @@
 // Checks that entering too long note while editing a password blocks the save
 // button and displays a footer explanation.
 - (void)testLayoutWithLongNotes {
-  SaveExamplePasswordFormWithNote();
+  SaveExamplePasswordFormToProfileStoreWithNote();
 
   OpenPasswordManager();
 
@@ -1465,7 +1476,7 @@
 // credential.
 - (void)testLayoutForBlockedCredential {
   GREYAssert([PasswordSettingsAppInterface
-                 saveExampleBlockedOrigin:@"https://example.com"],
+                 saveExampleBlockedOriginToProfileStore:@"https://example.com"],
              kPasswordStoreErrorMessage);
 
   OpenPasswordManager();
@@ -1493,11 +1504,13 @@
 // Checks the order of the elements in the detail view layout for a federated
 // credential.
 - (void)testLayoutFederated {
-  GREYAssert([PasswordSettingsAppInterface
-                 saveExampleFederatedOrigin:@"https://famous.provider.net"
-                                   username:@"federated username"
-                                     origin:@"https://example.com"],
-             kPasswordStoreErrorMessage);
+  GREYAssert(
+      [PasswordSettingsAppInterface
+          saveExampleFederatedOriginToProfileStore:
+              @"https://famous.provider.net"
+                                          username:@"federated username"
+                                            origin:@"https://example.com"],
+      kPasswordStoreErrorMessage);
 
   OpenPasswordManager();
 
@@ -1533,7 +1546,7 @@
 // Check that stored entries are shown no matter what the preference for saving
 // passwords is.
 - (void)testStoredEntriesAlwaysShown {
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   OpenPasswordManager();
 
@@ -1635,7 +1648,7 @@
 // Checks that deleting a password from the list view works.
 - (void)testDeletionInListView {
   // Save a password to be deleted later.
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   OpenPasswordManager();
 
@@ -1652,9 +1665,10 @@
   [[EarlGrey selectElementWithMatcher:BatchDeleteConfirmationButton()]
       performAction:grey_tap()];
 
-  // Verify that the deletion was propagated to the PasswordStore.
-  GREYAssertEqual(0, [PasswordSettingsAppInterface passwordStoreResultsCount],
-                  @"Stored password was not removed from PasswordStore.");
+  // Verify that the deletion was propagated to the ProfilePasswordStore.
+  GREYAssertEqual(
+      0, [PasswordSettingsAppInterface passwordProfileStoreResultsCount],
+      @"Stored password was not removed from ProfilePasswordStore.");
   // Verify that the removed password is no longer in the list.
   [GetInteractionForPasswordEntry(@"example.com, concrete username")
       assertWithMatcher:grey_not(grey_sufficientlyVisible())];
@@ -1685,14 +1699,16 @@
   // Enough just to ensure filling more than one page on all devices.
   constexpr int kPasswordsCount = 15;
 
-  // Send the passwords to the queue to be added to the PasswordStore.
-  [PasswordSettingsAppInterface saveExamplePasswordWithCount:kPasswordsCount];
+  // Send the passwords to the queue to be added to the ProfilePasswordStore.
+  [PasswordSettingsAppInterface
+      saveExamplePasswordToProfileWithCount:kPasswordsCount];
 
   // Use TestStoreConsumer::GetStoreResults to wait for the background storing
   // task to complete and to verify that the passwords have been stored.
-  GREYAssertEqual(kPasswordsCount,
-                  [PasswordSettingsAppInterface passwordStoreResultsCount],
-                  @"Unexpected PasswordStore results.");
+  GREYAssertEqual(
+      kPasswordsCount,
+      [PasswordSettingsAppInterface passwordProfileStoreResultsCount],
+      @"Unexpected ProfilePasswordStore results.");
 
   OpenPasswordManager();
 
@@ -1734,7 +1750,7 @@
 // button replaces the Done button.
 - (void)testEditButtonUpdateOnDeletion {
   // Save a password to be deleted later.
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   OpenPasswordManager();
 
@@ -1765,7 +1781,7 @@
 // Test export flow
 - (void)testExportFlow {
   // Saving a form is needed for exporting passwords.
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   OpenPasswordManager();
 
@@ -1829,7 +1845,7 @@
   }
 
   SaveExamplePasswordForms();
-  SaveExampleBlockedForms();
+  SaveExampleBlockedFormsToProfileStore();
 
   OpenPasswordManager();
 
@@ -1869,7 +1885,7 @@
 // TODO(crbug.com/1441783): Flaky.
 - (void)DISABLED_testSearchAndDeleteAllPasswords {
   SaveExamplePasswordForms();
-  SaveExampleBlockedForms();
+  SaveExampleBlockedFormsToProfileStore();
 
   OpenPasswordManager();
 
@@ -1984,7 +2000,7 @@
 
 // Edit a password with only incognito tab opened should work.
 - (void)testEditPasswordWithOnlyIncognitoTabOpen {
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   [ChromeEarlGrey openNewIncognitoTab];
   [ChromeEarlGrey closeAllNormalTabs];
@@ -2025,7 +2041,7 @@
 
 // Checks that attempts to edit a password provide appropriate feedback.
 - (void)testEditPassword {
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   OpenPasswordManager();
 
@@ -2071,7 +2087,7 @@
 
 // Checks that attempts to edit a username provide appropriate feedback.
 - (void)testEditUsername {
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   OpenPasswordManager();
 
@@ -2119,11 +2135,11 @@
 // Checks that attempts to edit a username to a value which is already used for
 // the same domain fails.
 - (void)testEditUsernameFails {
-  SavePasswordForm(/*password=*/kDefaultPassword,
-                   /*username=*/@"concrete username1");
+  SavePasswordFormToProfileStore(/*password=*/kDefaultPassword,
+                                 /*username=*/@"concrete username1");
 
-  SavePasswordForm(/*password=*/kDefaultPassword,
-                   /*username=*/@"concrete username2");
+  SavePasswordFormToProfileStore(/*password=*/kDefaultPassword,
+                                 /*username=*/@"concrete username2");
 
   OpenPasswordManager();
 
@@ -2163,7 +2179,7 @@
 
 // Checks that attempts to edit a username provide appropriate feedback.
 - (void)testCancelDuringEditing {
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   OpenPasswordManager();
 
@@ -2197,11 +2213,12 @@
 - (void)testRemovingMultiplePasswords {
   constexpr int kPasswordsCount = 4;
 
-  // Send the passwords to the queue to be added to the PasswordStore.
-  [PasswordSettingsAppInterface saveExamplePasswordWithCount:kPasswordsCount];
+  // Send the passwords to the queue to be added to the ProfilePasswordStore.
+  [PasswordSettingsAppInterface
+      saveExamplePasswordToProfileWithCount:kPasswordsCount];
 
-    // Also save passwords for example11.com and example12.com, since the rest
-    // will be grouped together.
+  // Also save passwords for example11.com and example12.com, since the rest
+  // will be grouped together.
   SaveExamplePasswordForms();
 
   OpenPasswordManager();
@@ -2229,9 +2246,10 @@
     [[EarlGrey selectElementWithMatcher:SavedPasswordsHeaderMatcher()]
         assertWithMatcher:grey_nil()];
 
-    // Verify that the deletion was propagated to the PasswordStore.
-    GREYAssertEqual(0, [PasswordSettingsAppInterface passwordStoreResultsCount],
-                    @"Stored password was not removed from PasswordStore.");
+    // Verify that the deletion was propagated to the ProfilePasswordStore.
+    GREYAssertEqual(
+        0, [PasswordSettingsAppInterface passwordProfileStoreResultsCount],
+        @"Stored password was not removed from ProfilePasswordStore.");
 
     // Finally, verify that the Add button is visible and enabled, because there
     // are no other password entries left for deletion via the "Edit" mode.
@@ -2247,7 +2265,7 @@
 
 // Checks that the "Add" button is not shown on Edit.
 - (void)testAddButtonDisabledInEditMode {
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
   OpenPasswordManager();
 
   TapNavigationBarEditButton();
@@ -2405,7 +2423,7 @@
     NSString* username = [NSString stringWithFormat:@"username %d", i];
     NSString* password = [NSString stringWithFormat:@"password %d", i];
     NSString* site = [NSString stringWithFormat:@"https://example%d.com", i];
-    SavePasswordForm(password, username, site);
+    SavePasswordFormToProfileStore(password, username, site);
   }
 
   OpenPasswordManager();
@@ -2439,7 +2457,7 @@
 // matches with an existing credential results in showing a section alert for
 // the existing credential.
 - (void)testAddNewDuplicatedPasswordCredential {
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   OpenPasswordManager();
 
@@ -2666,7 +2684,7 @@
 // enabled since the reauthentication happens before navigating to the details
 // view in this scenario.
 - (void)testShowHidePassword {
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   OpenPasswordManager();
 
@@ -2830,15 +2848,15 @@
 // but stays if there are still passwords on the page.
 - (void)testPasswordsDeletionNavigation {
   // Save forms with the same origin to be deleted later.
-  SavePasswordForm(/*password=*/@"password1",
-                   /*username=*/@"user1",
-                   /*origin=*/@"https://example1.com");
-  SavePasswordForm(/*password=*/@"password2",
-                   /*username=*/@"user2",
-                   /*origin=*/@"https://example1.com");
-  SavePasswordForm(/*password=*/@"password3",
-                   /*username=*/@"user3",
-                   /*origin=*/@"https://example3.com");
+  SavePasswordFormToProfileStore(/*password=*/@"password1",
+                                 /*username=*/@"user1",
+                                 /*origin=*/@"https://example1.com");
+  SavePasswordFormToProfileStore(/*password=*/@"password2",
+                                 /*username=*/@"user2",
+                                 /*origin=*/@"https://example1.com");
+  SavePasswordFormToProfileStore(/*password=*/@"password3",
+                                 /*username=*/@"user3",
+                                 /*origin=*/@"https://example3.com");
 
   OpenPasswordManager();
 
@@ -2983,9 +3001,9 @@
 }
 
 - (void)testMovePasswordToAccount {
-  SavePasswordForm(/*password=*/@"localPassword",
-                   /*username=*/@"username",
-                   /*origin=*/@"https://local.com");
+  SavePasswordFormToProfileStore(/*password=*/@"localPassword",
+                                 /*username=*/@"username",
+                                 /*origin=*/@"https://local.com");
   [SigninEarlGreyUI signinWithFakeIdentity:[FakeSystemIdentity fakeIdentity1]
                                 enableSync:NO];
   OpenPasswordManager();
@@ -3028,9 +3046,9 @@
 // Regression test for crbug.com/1431975. Similar to testMovePasswordToAccount
 // above but the only open tab is an incognito one.
 - (void)testMovePasswordToAccountWithOnlyIncognitoTabOpen {
-  SavePasswordForm(/*password=*/@"localPassword",
-                   /*username=*/@"username",
-                   /*origin=*/@"https://local.com");
+  SavePasswordFormToProfileStore(/*password=*/@"localPassword",
+                                 /*username=*/@"username",
+                                 /*origin=*/@"https://local.com");
   [SigninEarlGreyUI signinWithFakeIdentity:[FakeSystemIdentity fakeIdentity1]
                                 enableSync:NO];
 
@@ -3076,7 +3094,7 @@
 
 // Tests that the save passwords in account section is hidden when syncing.
 - (void)testSavePasswordsInAccountHiddenWhenSyncing {
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   [PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult:
                                     ReauthenticationResult::kSuccess];
@@ -3099,7 +3117,7 @@
 // Tests that the save passwords in account section is hidden when not
 // signed-in.
 - (void)testSavePasswordsInAccountHiddenWhenNotSignedIn {
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   [PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult:
                                     ReauthenticationResult::kSuccess];
@@ -3120,7 +3138,7 @@
 // Tests that the save passwords in account section is hidden when not opted-in
 // for account storage.
 - (void)testSavePasswordsInAccountHiddenWhenNotOptedInToAccountStorage {
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   [PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult:
                                     ReauthenticationResult::kSuccess];
@@ -3145,7 +3163,8 @@
 // Tests that the save passwords in account section is shown when the user is
 // eligible.
 - (void)testSavePasswordsInAccountShownWhenEligible {
-  SavePasswordForm(@"passwordtest1", @"user1", @"https://test1.com");
+  SavePasswordFormToProfileStore(@"passwordtest1", @"user1",
+                                 @"https://test1.com");
 
   [PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult:
                                     ReauthenticationResult::kSuccess];
@@ -3168,7 +3187,8 @@
 // Tests that the confirmation dialog contains the correct string for saving one
 // distinct domain to the account.
 - (void)testSavePasswordsInAccountOneDistinctDomain {
-  SavePasswordForm(@"password1", @"user1", @"https://example1.com");
+  SavePasswordFormToProfileStore(@"password1", @"user1",
+                                 @"https://example1.com");
 
   [PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult:
                                     ReauthenticationResult::kSuccess];
@@ -3197,8 +3217,10 @@
 // Tests that the confirmation dialog contains the correct string for saving two
 // distinct domains to the account.
 - (void)testSavePasswordsInAccountTwoDistinctDomains {
-  SavePasswordForm(@"password1", @"user1", @"https://example1.com");
-  SavePasswordForm(@"password1", @"user1", @"https://example2.com");
+  SavePasswordFormToProfileStore(@"password1", @"user1",
+                                 @"https://example1.com");
+  SavePasswordFormToProfileStore(@"password1", @"user1",
+                                 @"https://example2.com");
 
   [PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult:
                                     ReauthenticationResult::kSuccess];
@@ -3227,9 +3249,12 @@
 // Tests that the confirmation dialog contains the correct string for saving
 // three distinct domains to the account.
 - (void)testSavePasswordsInAccountThreeDistinctDomains {
-  SavePasswordForm(@"password1", @"user1", @"https://example1.com");
-  SavePasswordForm(@"password1", @"user1", @"https://example2.com");
-  SavePasswordForm(@"password1", @"user1", @"https://example3.com");
+  SavePasswordFormToProfileStore(@"password1", @"user1",
+                                 @"https://example1.com");
+  SavePasswordFormToProfileStore(@"password1", @"user1",
+                                 @"https://example2.com");
+  SavePasswordFormToProfileStore(@"password1", @"user1",
+                                 @"https://example3.com");
 
   [PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult:
                                     ReauthenticationResult::kSuccess];
@@ -3259,10 +3284,14 @@
 // Tests that the confirmation dialog contains the correct string for saving
 // four distinct domains to the account.
 - (void)testSavePasswordsInAccountFourDistinctDomains {
-  SavePasswordForm(@"password1", @"user1", @"https://example1.com");
-  SavePasswordForm(@"password1", @"user1", @"https://example2.com");
-  SavePasswordForm(@"password1", @"user1", @"https://example3.com");
-  SavePasswordForm(@"password1", @"user1", @"https://example4.com");
+  SavePasswordFormToProfileStore(@"password1", @"user1",
+                                 @"https://example1.com");
+  SavePasswordFormToProfileStore(@"password1", @"user1",
+                                 @"https://example2.com");
+  SavePasswordFormToProfileStore(@"password1", @"user1",
+                                 @"https://example3.com");
+  SavePasswordFormToProfileStore(@"password1", @"user1",
+                                 @"https://example4.com");
 
   [PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult:
                                     ReauthenticationResult::kSuccess];
@@ -3292,7 +3321,8 @@
 // Tests that the local password is moved when accepting the confirmation
 // dialog, and that the corresponding snackbar appears.
 - (void)testSavePasswordsInAccountFlowCompletes {
-  SavePasswordForm(@"password1", @"user1", @"https://example1.com");
+  SavePasswordFormToProfileStore(@"password1", @"user1",
+                                 @"https://example1.com");
 
   [PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult:
                                     ReauthenticationResult::kSuccess];
@@ -3328,7 +3358,8 @@
 // Tests that the local password is not moved when accepting the confirmation
 // dialog since authentication failed.
 - (void)testSavePasswordsInAccountFlowAuthFailed {
-  SavePasswordForm(@"password1", @"user1", @"https://example1.com");
+  SavePasswordFormToProfileStore(@"password1", @"user1",
+                                 @"https://example1.com");
 
   [PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult:
                                     ReauthenticationResult::kFailure];
@@ -3358,7 +3389,8 @@
 // Tests that the "set passcode" alert is shown if no authentication is set when
 // user tries to save passwords in their account.
 - (void)testSavePasswordsInAccountFlowNoAuthSetOnDevice {
-  SavePasswordForm(@"password1", @"user1", @"https://example1.com");
+  SavePasswordFormToProfileStore(@"password1", @"user1",
+                                 @"https://example1.com");
 
   [PasswordSettingsAppInterface mockReauthenticationModuleCanAttempt:NO];
   FakeSystemIdentity* fakeIdentity = [FakeSystemIdentity fakeIdentity1];
@@ -3390,15 +3422,19 @@
 // Tests that the local passwords are correctly handled in the save
 // passwords to account flow, and the correct snackbar appears.
 - (void)testSavePasswordsInAccountFlowCompletesMovingPasswords {
-  SavePasswordForm(@"password1", @"user1", @"https://example1.com");
-  SavePasswordForm(@"password2", @"user1", @"https://example1.com");
-  SavePasswordForm(@"password1", @"user1", @"https://example2.com");
+  SavePasswordFormToProfileStore(@"password1", @"user1",
+                                 @"https://example1.com");
+  SavePasswordFormToProfileStore(@"password2", @"user1",
+                                 @"https://example1.com");
+  SavePasswordFormToProfileStore(@"password1", @"user1",
+                                 @"https://example2.com");
 
   [PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult:
                                     ReauthenticationResult::kSuccess];
   FakeSystemIdentity* fakeIdentity = [FakeSystemIdentity fakeIdentity1];
   [SigninEarlGreyUI signinWithFakeIdentity:fakeIdentity enableSync:NO];
-  SavePasswordForm(@"password1", @"user1", @"https://example1.com");
+  SavePasswordFormToProfileStore(@"password1", @"user1",
+                                 @"https://example1.com");
 
   OpenPasswordManager();
   OpenSettingsSubmenu();
@@ -3545,7 +3581,7 @@
 // Search Passwords widget.
 - (void)testOpenSearchPasswordsWidget {
   // Add a saved password to not get the Password Manager's empty state.
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   [PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult:
                                     ReauthenticationResult::kSuccess];
@@ -3578,7 +3614,7 @@
 // Password Manager was initially opened with the Search Passwords widget.
 - (void)testGoingBackAfterOpeningInSearchMode {
   // Add a saved password to not get the Password Manager's empty state.
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   [PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult:
                                     ReauthenticationResult::kSuccess];
@@ -3613,7 +3649,7 @@
 // removes the promo from the table view.
 - (void)testClosingPasswordManagerWidgetPromo {
   // Add a saved password to not get the Password Manager's empty state.
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   OpenPasswordManager();
 
@@ -3633,7 +3669,7 @@
 // promo displays the instructions on how to install the widget.
 - (void)testOpeningPasswordManagerWidgetPromoInstructions {
   // Add a saved password to not get the Password Manager's empty state.
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   OpenPasswordManagerWidgetPromoInstructions();
 }
@@ -3642,7 +3678,7 @@
 // authentication while in the Widget Promo Instructions page.
 - (void)testOpeningPasswordManagerWidgetPromoInstructionsWithFailedAuth {
   // Add a saved password to not get the Password Manager's empty state.
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   OpenPasswordManagerWidgetPromoInstructions();
 
@@ -3668,7 +3704,7 @@
 // promo are disabled when the Password Manager is in edit mode.
 - (void)testPasswordManagerWidgetPromoInEditMode {
   // Add a saved password to not get the Password Manager's empty state.
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   OpenPasswordManager();
 
@@ -3698,7 +3734,7 @@
   }
 
   // Add a saved password to not get the Password Manager's empty state.
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   OpenPasswordManager();
 
@@ -3722,7 +3758,7 @@
 // dismissed by swipping it down and by tapping its close button.
 - (void)testDismissPasswordManagerWidgetPromoInstructionsScreen {
   // Add a saved password to not get the Password Manager's empty state.
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   OpenPasswordManager();
 
@@ -3769,7 +3805,7 @@
   }
 
   // Add a saved password to not get the Password Manager's empty state.
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   OpenPasswordManager();
 
@@ -3803,7 +3839,7 @@
 // saved in the local store.
 - (void)testMovePasswordToAccountStoreIfSignedIn_SyncToSigninEnabled {
   // Save form to be moved to account later.
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
 
   // Sign in.
   FakeSystemIdentity* fakeIdentity = [FakeSystemIdentity fakeIdentity1];
diff --git a/ios/chrome/browser/ui/settings/password/password_manager_egtest_utils.h b/ios/chrome/browser/ui/settings/password/password_manager_egtest_utils.h
index b63f12f..b5b7ca5 100644
--- a/ios/chrome/browser/ui/settings/password/password_manager_egtest_utils.h
+++ b/ios/chrome/browser/ui/settings/password/password_manager_egtest_utils.h
@@ -94,25 +94,27 @@
     NSString* username,
     NSString* compromised_description = nil);
 
-// Saves a password form in the store.
-void SavePasswordForm(NSString* password = kDefaultPassword,
-                      NSString* username = kDefaultUsername,
-                      NSString* origin = kDefaultSite);
+// Saves a password form in the profile store.
+void SavePasswordFormToProfileStore(NSString* password = kDefaultPassword,
+                                    NSString* username = kDefaultUsername,
+                                    NSString* origin = kDefaultSite);
 
 // Saves a password form in the account store.
 void SavePasswordFormToAccountStore(NSString* password = kDefaultPassword,
                                     NSString* username = kDefaultUsername,
                                     NSString* origin = kDefaultSite);
 
-// Saves a compromised password form in the store.
-void SaveCompromisedPasswordForm(NSString* password = kDefaultPassword,
-                                 NSString* username = kDefaultUsername,
-                                 NSString* origin = kDefaultSite);
+// Saves a compromised password form in the profile store.
+void SaveCompromisedPasswordFormToProfileStore(
+    NSString* password = kDefaultPassword,
+    NSString* username = kDefaultUsername,
+    NSString* origin = kDefaultSite);
 
-// Saves a muted compromised password form in the store.
-void SaveMutedCompromisedPasswordForm(NSString* origin = kDefaultSite,
-                                      NSString* username = kDefaultUsername,
-                                      NSString* password = kDefaultPassword);
+// Saves a muted compromised password form in the profile store.
+void SaveMutedCompromisedPasswordFormToProfileStore(
+    NSString* origin = kDefaultSite,
+    NSString* username = kDefaultUsername,
+    NSString* password = kDefaultPassword);
 
 // Opens the Password Manager page from the NTP.
 void OpenPasswordManager();
diff --git a/ios/chrome/browser/ui/settings/password/password_manager_egtest_utils.mm b/ios/chrome/browser/ui/settings/password/password_manager_egtest_utils.mm
index fec0710..bc7a6ae 100644
--- a/ios/chrome/browser/ui/settings/password/password_manager_egtest_utils.mm
+++ b/ios/chrome/browser/ui/settings/password/password_manager_egtest_utils.mm
@@ -182,13 +182,14 @@
 
 #pragma mark - Saving passwords
 
-void SavePasswordForm(NSString* password,
-                      NSString* username,
-                      NSString* origin) {
-  GREYAssert([PasswordSettingsAppInterface saveExamplePassword:password
-                                                      username:username
-                                                        origin:origin],
-             kPasswordStoreErrorMessage);
+void SavePasswordFormToProfileStore(NSString* password,
+                                    NSString* username,
+                                    NSString* origin) {
+  GREYAssert(
+      [PasswordSettingsAppInterface saveExamplePasswordToProfileStore:password
+                                                             username:username
+                                                               origin:origin],
+      kPasswordStoreErrorMessage);
 }
 
 void SavePasswordFormToAccountStore(NSString* password,
@@ -201,21 +202,23 @@
       kPasswordStoreErrorMessage);
 }
 
-void SaveCompromisedPasswordForm(NSString* password,
-                                 NSString* username,
-                                 NSString* origin) {
-  GREYAssert([PasswordSettingsAppInterface saveCompromisedPassword:password
-                                                          username:username
-                                                            origin:origin],
+void SaveCompromisedPasswordFormToProfileStore(NSString* password,
+                                               NSString* username,
+                                               NSString* origin) {
+  GREYAssert([PasswordSettingsAppInterface
+                 saveCompromisedPasswordToProfileStore:password
+                                              username:username
+                                                origin:origin],
              kPasswordStoreErrorMessage);
 }
 
-void SaveMutedCompromisedPasswordForm(NSString* origin,
-                                      NSString* username,
-                                      NSString* password) {
-  GREYAssert([PasswordSettingsAppInterface saveMutedCompromisedPassword:password
-                                                               username:username
-                                                                 origin:origin],
+void SaveMutedCompromisedPasswordFormToProfileStore(NSString* origin,
+                                                    NSString* username,
+                                                    NSString* password) {
+  GREYAssert([PasswordSettingsAppInterface
+                 saveMutedCompromisedPasswordToProfilePassword:password
+                                                      username:username
+                                                        origin:origin],
              kPasswordStoreErrorMessage);
 }
 
@@ -230,7 +233,7 @@
   // background task runner and wait until it is finished. Because the
   // background task runner is sequenced, this means that previously posted
   // tasks are also finished when this function exits.
-  [PasswordSettingsAppInterface passwordStoreResultsCount];
+  [PasswordSettingsAppInterface passwordProfileStoreResultsCount];
 }
 
 void TapNavigationBarEditButton() {
diff --git a/ios/chrome/browser/ui/settings/password/password_settings_app_interface.h b/ios/chrome/browser/ui/settings/password/password_settings_app_interface.h
index fc0e354..aa436b2 100644
--- a/ios/chrome/browser/ui/settings/password/password_settings_app_interface.h
+++ b/ios/chrome/browser/ui/settings/password/password_settings_app_interface.h
@@ -39,49 +39,50 @@
 // Dismisses snack bar.  Used before next test.
 + (void)dismissSnackBar;
 
-// Removes all credentials stored.
-+ (BOOL)clearPasswordStore;
+// Removes all credentials stored in the profile store.
++ (BOOL)clearProfilePasswordStore;
 
 // Creates multiple password form with index being part of the username,
-// password, origin and realm.
-+ (void)saveExamplePasswordWithCount:(NSInteger)count;
+// password, origin and realm in the profile store.
++ (void)saveExamplePasswordToProfileWithCount:(NSInteger)count;
 
-// Creates password form for given fields.
-+ (BOOL)saveExamplePassword:(NSString*)password
-                   username:(NSString*)username
-                     origin:(NSString*)origin;
+// Creates password form for given fields in the profile store.
++ (BOOL)saveExamplePasswordToProfileStore:(NSString*)password
+                                 username:(NSString*)username
+                                   origin:(NSString*)origin;
 
 // Creates password form for given fields and save it in the account store.
 + (BOOL)saveExamplePasswordToAccountStore:(NSString*)password
                                  username:(NSString*)username
                                    origin:(NSString*)origin;
 
-// Creates password form for given fields.
-+ (BOOL)saveExampleNote:(NSString*)note
-               password:(NSString*)password
-               username:(NSString*)username
-                 origin:(NSString*)origin;
+// Creates password form in profile store for given fields.
++ (BOOL)saveExampleNoteToProfileStore:(NSString*)note
+                             password:(NSString*)password
+                             username:(NSString*)username
+                               origin:(NSString*)origin;
 
-// Creates a compromised password form.
-+ (BOOL)saveCompromisedPassword:(NSString*)password
-                       username:(NSString*)username
-                         origin:(NSString*)origin;
+// Creates a compromised password form in profile store.
++ (BOOL)saveCompromisedPasswordToProfileStore:(NSString*)password
+                                     username:(NSString*)username
+                                       origin:(NSString*)origin;
 
-// Creates a muted compromised password form.
-+ (BOOL)saveMutedCompromisedPassword:(NSString*)password
-                            username:(NSString*)userName
-                              origin:(NSString*)origin;
+// Creates a muted compromised password form in profile password.
++ (BOOL)saveMutedCompromisedPasswordToProfilePassword:(NSString*)password
+                                             username:(NSString*)userName
+                                               origin:(NSString*)origin;
 
-// Creates a blocked password form for given origin.
-+ (BOOL)saveExampleBlockedOrigin:(NSString*)origin;
+// Creates a blocked password form for given origin in profile store.
++ (BOOL)saveExampleBlockedOriginToProfileStore:(NSString*)origin;
 
-// Creates a federated password form for given origins and user.
-+ (BOOL)saveExampleFederatedOrigin:(NSString*)federatedOrigin
-                          username:(NSString*)username
-                            origin:(NSString*)origin;
+// Creates a federated password form for given origins and user in the profile
+// store.
++ (BOOL)saveExampleFederatedOriginToProfileStore:(NSString*)federatedOrigin
+                                        username:(NSString*)username
+                                          origin:(NSString*)origin;
 
-// Gets number of password form stored.
-+ (NSInteger)passwordStoreResultsCount;
+// Gets number of password form stored in the profile store.
++ (NSInteger)passwordProfileStoreResultsCount;
 
 // Returns YES if credential service is enabled.
 + (BOOL)isCredentialsServiceEnabled;
diff --git a/ios/chrome/browser/ui/settings/password/password_settings_app_interface.mm b/ios/chrome/browser/ui/settings/password/password_settings_app_interface.mm
index 8cf65f0..32240ab 100644
--- a/ios/chrome/browser/ui/settings/password/password_settings_app_interface.mm
+++ b/ios/chrome/browser/ui/settings/password/password_settings_app_interface.mm
@@ -38,7 +38,8 @@
 
 namespace {
 
-scoped_refptr<password_manager::PasswordStoreInterface> GetPasswordStore() {
+scoped_refptr<password_manager::PasswordStoreInterface>
+GetPasswordProfileStore() {
   // Ensure that the fails in incognito mode by using IMPLICIT_ACCESS.
   return IOSChromeProfilePasswordStoreFactory::GetForBrowserState(
       chrome_test_util::GetOriginalBrowserState(),
@@ -67,10 +68,10 @@
 
   // Retrieves all logins from the profile password store and updates
   // `results_`. Returns true if the logins retrieved successfully.
-  bool FetchStoreResults() {
+  bool FetchProfileStoreResults() {
     results_.clear();
     ResetObtained();
-    GetPasswordStore()->GetAllLogins(weak_ptr_factory_.GetWeakPtr());
+    GetPasswordProfileStore()->GetAllLogins(weak_ptr_factory_.GetWeakPtr());
     bool responded =
         base::test::ios::WaitUntilConditionOrTimeout(base::Seconds(2), ^bool {
           return !AreObtainedReset();
@@ -130,15 +131,15 @@
 
 // Saves `form` to the password store and waits until the async processing is
 // done.
-bool SaveToPasswordStore(const PasswordForm& form) {
-  GetPasswordStore()->AddLogin(form);
+bool SaveToPasswordProfileStore(const PasswordForm& form) {
+  GetPasswordProfileStore()->AddLogin(form);
   // When we retrieve the form from the store, `in_store` should be set.
   password_manager::PasswordForm expected_form = form;
   expected_form.in_store = password_manager::PasswordForm::Store::kProfileStore;
 
   // Check the result and ensure PasswordStore processed this.
   FakeStoreConsumer consumer;
-  if (!consumer.FetchStoreResults()) {
+  if (!consumer.FetchProfileStoreResults()) {
     return false;
   }
   for (const auto& result : consumer.GetStoreResults()) {
@@ -183,11 +184,11 @@
   return form;
 }
 
-bool ClearPasswordStore() {
-  GetPasswordStore()->RemoveLoginsCreatedBetween(base::Time(), base::Time(),
-                                                 base::DoNothing());
+bool ClearProfilePasswordStore() {
+  GetPasswordProfileStore()->RemoveLoginsCreatedBetween(
+      base::Time(), base::Time(), base::DoNothing());
   FakeStoreConsumer consumer;
-  if (!consumer.FetchStoreResults()) {
+  if (!consumer.FetchProfileStoreResults()) {
     return false;
   }
   return consumer.GetStoreResults().empty();
@@ -241,21 +242,21 @@
       dismissAndCallCompletionBlocksWithCategory:@"PasswordsSnackbarCategory"];
 }
 
-+ (void)saveExamplePasswordWithCount:(NSInteger)count {
++ (void)saveExamplePasswordToProfileWithCount:(NSInteger)count {
   for (int i = 1; i <= count; ++i) {
-    GetPasswordStore()->AddLogin(CreateSampleFormWithIndex(i));
+    GetPasswordProfileStore()->AddLogin(CreateSampleFormWithIndex(i));
   }
 }
 
-+ (BOOL)saveExamplePassword:(NSString*)password
-                   username:(NSString*)username
-                     origin:(NSString*)origin {
++ (BOOL)saveExamplePasswordToProfileStore:(NSString*)password
+                                 username:(NSString*)username
+                                   origin:(NSString*)origin {
   PasswordForm example;
   example.username_value = base::SysNSStringToUTF16(username);
   example.password_value = base::SysNSStringToUTF16(password);
   example.url = GURL(base::SysNSStringToUTF16(origin));
   example.signon_realm = example.url.spec();
-  return SaveToPasswordStore(example);
+  return SaveToPasswordProfileStore(example);
 }
 
 + (BOOL)saveExamplePasswordToAccountStore:(NSString*)password
@@ -269,10 +270,10 @@
   return SaveToPasswordAccountStore(example);
 }
 
-+ (BOOL)saveExampleNote:(NSString*)note
-               password:(NSString*)password
-               username:(NSString*)username
-                 origin:(NSString*)origin {
++ (BOOL)saveExampleNoteToProfileStore:(NSString*)note
+                             password:(NSString*)password
+                             username:(NSString*)username
+                               origin:(NSString*)origin {
   PasswordForm example;
   example.username_value = base::SysNSStringToUTF16(username);
   example.password_value = base::SysNSStringToUTF16(password);
@@ -280,12 +281,12 @@
   example.signon_realm = example.url.spec();
   example.notes = {password_manager::PasswordNote(
       base::SysNSStringToUTF16(note), base::Time::Now())};
-  return SaveToPasswordStore(example);
+  return SaveToPasswordProfileStore(example);
 }
 
-+ (BOOL)saveCompromisedPassword:(NSString*)password
-                       username:(NSString*)username
-                         origin:(NSString*)origin {
++ (BOOL)saveCompromisedPasswordToProfileStore:(NSString*)password
+                                     username:(NSString*)username
+                                       origin:(NSString*)origin {
   PasswordForm example;
   example.username_value = base::SysNSStringToUTF16(username);
   example.password_value = base::SysNSStringToUTF16(password);
@@ -293,12 +294,12 @@
   example.signon_realm = example.url.spec();
   example.password_issues.insert({password_manager::InsecureType::kLeaked,
                                   password_manager::InsecurityMetadata()});
-  return SaveToPasswordStore(example);
+  return SaveToPasswordProfileStore(example);
 }
 
-+ (BOOL)saveMutedCompromisedPassword:(NSString*)password
-                            username:(NSString*)userName
-                              origin:(NSString*)origin {
++ (BOOL)saveMutedCompromisedPasswordToProfilePassword:(NSString*)password
+                                             username:(NSString*)userName
+                                               origin:(NSString*)origin {
   PasswordForm example;
   example.username_value = base::SysNSStringToUTF16(userName);
   example.password_value = base::SysNSStringToUTF16(password);
@@ -309,39 +310,39 @@
        password_manager::InsecurityMetadata(
            base::Time::Now(), password_manager::IsMuted(true),
            password_manager::TriggerBackendNotification(false))});
-  return SaveToPasswordStore(example);
+  return SaveToPasswordProfileStore(example);
 }
 
-+ (BOOL)saveExampleBlockedOrigin:(NSString*)origin {
++ (BOOL)saveExampleBlockedOriginToProfileStore:(NSString*)origin {
   PasswordForm example;
   example.url = GURL(base::SysNSStringToUTF16(origin));
   example.blocked_by_user = true;
   example.signon_realm = example.url.spec();
-  return SaveToPasswordStore(example);
+  return SaveToPasswordProfileStore(example);
 }
 
-+ (BOOL)saveExampleFederatedOrigin:(NSString*)federatedOrigin
-                          username:(NSString*)username
-                            origin:(NSString*)origin {
++ (BOOL)saveExampleFederatedOriginToProfileStore:(NSString*)federatedOrigin
+                                        username:(NSString*)username
+                                          origin:(NSString*)origin {
   PasswordForm federated;
   federated.username_value = base::SysNSStringToUTF16(username);
   federated.url = GURL(base::SysNSStringToUTF16(origin));
   federated.signon_realm = federated.url.spec();
   federated.federation_origin =
       url::Origin::Create(GURL(base::SysNSStringToUTF16(federatedOrigin)));
-  return SaveToPasswordStore(federated);
+  return SaveToPasswordProfileStore(federated);
 }
 
-+ (NSInteger)passwordStoreResultsCount {
++ (NSInteger)passwordProfileStoreResultsCount {
   FakeStoreConsumer consumer;
-  if (!consumer.FetchStoreResults()) {
+  if (!consumer.FetchProfileStoreResults()) {
     return -1;
   }
   return consumer.GetStoreResults().size();
 }
 
-+ (BOOL)clearPasswordStore {
-  return ClearPasswordStore();
++ (BOOL)clearProfilePasswordStore {
+  return ClearProfilePasswordStore();
 }
 
 + (BOOL)isCredentialsServiceEnabled {
diff --git a/ios/chrome/browser/ui/settings/password/password_sharing/password_sharing_egtest.mm b/ios/chrome/browser/ui/settings/password/password_sharing/password_sharing_egtest.mm
index 4edf1ac6..ebe560f8 100644
--- a/ios/chrome/browser/ui/settings/password/password_sharing/password_sharing_egtest.mm
+++ b/ios/chrome/browser/ui/settings/password/password_sharing/password_sharing_egtest.mm
@@ -32,7 +32,7 @@
 using base::test::ios::kWaitForActionTimeout;
 using password_manager_test_utils::kScrollAmount;
 using password_manager_test_utils::OpenPasswordManager;
-using password_manager_test_utils::SavePasswordForm;
+using password_manager_test_utils::SavePasswordFormToProfileStore;
 
 constexpr char kGoogleHelpCenterURL[] = "support.google.com";
 
@@ -52,21 +52,21 @@
 // Test case for the Password Sharing flow.
 @interface PasswordSharingTestCase : ChromeTestCase
 
-- (GREYElementInteraction*)saveExamplePasswordAndOpenDetails;
+- (GREYElementInteraction*)saveExamplePasswordToProfilestoreAndOpenDetails;
 
-- (GREYElementInteraction*)saveExamplePasswordsAndOpenDetails;
+- (GREYElementInteraction*)saveExamplePasswordsToProfileStoreAndOpenDetails;
 
 @end
 
 @implementation PasswordSharingTestCase
 
-- (GREYElementInteraction*)saveExamplePasswordAndOpenDetails {
+- (GREYElementInteraction*)saveExamplePasswordToProfilestoreAndOpenDetails {
   // Mock successful reauth for opening the Password Manager.
   [PasswordSettingsAppInterface setUpMockReauthenticationModule];
   [PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult:
                                     ReauthenticationResult::kSuccess];
 
-  SavePasswordForm();
+  SavePasswordFormToProfileStore();
   OpenPasswordManager();
 
   return [[[EarlGrey
@@ -80,16 +80,16 @@
       performAction:grey_tap()];
 }
 
-- (GREYElementInteraction*)saveExamplePasswordsAndOpenDetails {
+- (GREYElementInteraction*)saveExamplePasswordsToProfileStoreAndOpenDetails {
   // Mock successful reauth for opening the Password Manager.
   [PasswordSettingsAppInterface setUpMockReauthenticationModule];
   [PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult:
                                     ReauthenticationResult::kSuccess];
 
-  SavePasswordForm(/*password=*/@"password1",
-                   /*username=*/@"username1");
-  SavePasswordForm(/*password=*/@"password2",
-                   /*username=*/@"username2");
+  SavePasswordFormToProfileStore(/*password=*/@"password1",
+                                 /*username=*/@"username1");
+  SavePasswordFormToProfileStore(/*password=*/@"password2",
+                                 /*username=*/@"username2");
   OpenPasswordManager();
 
   return [[[EarlGrey
@@ -162,7 +162,7 @@
 
 - (void)testShareButtonVisibilityWithSharingDisabled {
   SignInAndEnableSync();
-  [self saveExamplePasswordAndOpenDetails];
+  [self saveExamplePasswordToProfilestoreAndOpenDetails];
 
   [[EarlGrey
       selectElementWithMatcher:grey_accessibilityID(kPasswordShareButtonID)]
@@ -171,7 +171,7 @@
 
 - (void)testShareButtonVisibilityWithSharingEnabled {
   SignInAndEnableSync();
-  [self saveExamplePasswordAndOpenDetails];
+  [self saveExamplePasswordToProfilestoreAndOpenDetails];
 
   [[EarlGrey
       selectElementWithMatcher:grey_accessibilityID(kPasswordShareButtonID)]
@@ -179,7 +179,7 @@
 }
 
 - (void)testShareButtonVisibilityForSignedOutUser {
-  [self saveExamplePasswordAndOpenDetails];
+  [self saveExamplePasswordToProfilestoreAndOpenDetails];
 
   [[EarlGrey
       selectElementWithMatcher:grey_accessibilityID(kPasswordShareButtonID)]
@@ -190,7 +190,7 @@
   FakeSystemIdentity* fake_identity = [FakeSystemIdentity fakeIdentity1];
   [SigninEarlGreyUI signinWithFakeIdentity:fake_identity enableSync:NO];
 
-  [self saveExamplePasswordAndOpenDetails];
+  [self saveExamplePasswordToProfilestoreAndOpenDetails];
 
   [[EarlGrey
       selectElementWithMatcher:grey_accessibilityID(kPasswordShareButtonID)]
@@ -203,7 +203,7 @@
        forUserPref:password_manager::prefs::kPasswordSharingEnabled];
 
   SignInAndEnableSync();
-  [self saveExamplePasswordAndOpenDetails];
+  [self saveExamplePasswordToProfilestoreAndOpenDetails];
 
   // Share button should be visible and display the policy info popup upon tap.
   [[EarlGrey
@@ -220,7 +220,7 @@
 
 - (void)testFamilyPickerCancelFlow {
   SignInAndEnableSync();
-  [self saveExamplePasswordAndOpenDetails];
+  [self saveExamplePasswordToProfilestoreAndOpenDetails];
 
   [[EarlGrey
       selectElementWithMatcher:grey_accessibilityID(kPasswordShareButtonID)]
@@ -242,7 +242,7 @@
 
 - (void)testPasswordPickerCancelFlow {
   SignInAndEnableSync();
-  [self saveExamplePasswordsAndOpenDetails];
+  [self saveExamplePasswordsToProfileStoreAndOpenDetails];
 
   [[EarlGrey
       selectElementWithMatcher:grey_accessibilityID(kPasswordShareButtonID)]
@@ -271,7 +271,7 @@
                    forUserPref:prefs::kPasswordSharingFlowHasBeenEntered];
 
   SignInAndEnableSync();
-  [self saveExamplePasswordAndOpenDetails];
+  [self saveExamplePasswordToProfilestoreAndOpenDetails];
 
   [[EarlGrey
       selectElementWithMatcher:grey_accessibilityID(kPasswordShareButtonID)]
@@ -308,7 +308,7 @@
                    forUserPref:prefs::kPasswordSharingFlowHasBeenEntered];
 
   SignInAndEnableSync();
-  [self saveExamplePasswordAndOpenDetails];
+  [self saveExamplePasswordToProfilestoreAndOpenDetails];
 
   [[EarlGrey
       selectElementWithMatcher:grey_accessibilityID(kPasswordShareButtonID)]
@@ -346,7 +346,7 @@
                    forUserPref:prefs::kPasswordSharingFlowHasBeenEntered];
 
   SignInAndEnableSync();
-  [self saveExamplePasswordAndOpenDetails];
+  [self saveExamplePasswordToProfilestoreAndOpenDetails];
 
   [[EarlGrey
       selectElementWithMatcher:grey_accessibilityID(kPasswordShareButtonID)]
@@ -368,7 +368,7 @@
 
 - (void)testPasswordSharingSuccess {
   SignInAndEnableSync();
-  [self saveExamplePasswordAndOpenDetails];
+  [self saveExamplePasswordToProfilestoreAndOpenDetails];
 
   [[EarlGrey
       selectElementWithMatcher:grey_accessibilityID(kPasswordShareButtonID)]
@@ -423,7 +423,7 @@
 
 - (void)testNavigationBetweenPasswordAndFamilyPicker {
   SignInAndEnableSync();
-  [self saveExamplePasswordsAndOpenDetails];
+  [self saveExamplePasswordsToProfileStoreAndOpenDetails];
 
   [[EarlGrey
       selectElementWithMatcher:grey_accessibilityID(kPasswordShareButtonID)]
@@ -457,7 +457,7 @@
 
 - (void)testTappingLearnMoreInFamilyPickerInfoPopup {
   SignInAndEnableSync();
-  [self saveExamplePasswordAndOpenDetails];
+  [self saveExamplePasswordToProfilestoreAndOpenDetails];
 
   [[EarlGrey
       selectElementWithMatcher:grey_accessibilityID(kPasswordShareButtonID)]
@@ -494,7 +494,7 @@
                    forUserPref:prefs::kPasswordSharingFlowHasBeenEntered];
 
   SignInAndEnableSync();
-  [self saveExamplePasswordAndOpenDetails];
+  [self saveExamplePasswordToProfilestoreAndOpenDetails];
 
   [[EarlGrey
       selectElementWithMatcher:grey_accessibilityID(kPasswordShareButtonID)]
@@ -525,7 +525,7 @@
                    forUserPref:prefs::kPasswordSharingFlowHasBeenEntered];
 
   SignInAndEnableSync();
-  [self saveExamplePasswordAndOpenDetails];
+  [self saveExamplePasswordToProfilestoreAndOpenDetails];
 
   [[EarlGrey
       selectElementWithMatcher:grey_accessibilityID(kPasswordShareButtonID)]
@@ -567,7 +567,7 @@
                    forUserPref:prefs::kPasswordSharingFlowHasBeenEntered];
 
   SignInAndEnableSync();
-  [self saveExamplePasswordAndOpenDetails];
+  [self saveExamplePasswordToProfilestoreAndOpenDetails];
 
   [[EarlGrey
       selectElementWithMatcher:grey_accessibilityID(kPasswordShareButtonID)]
@@ -591,7 +591,7 @@
                    forUserPref:prefs::kPasswordSharingFlowHasBeenEntered];
 
   SignInAndEnableSync();
-  [self saveExamplePasswordAndOpenDetails];
+  [self saveExamplePasswordToProfilestoreAndOpenDetails];
 
   [[EarlGrey
       selectElementWithMatcher:grey_accessibilityID(kPasswordShareButtonID)]
diff --git a/ios/chrome/browser/ui/settings/safety_check/safety_check_egtest.mm b/ios/chrome/browser/ui/settings/safety_check/safety_check_egtest.mm
index 5f8befac..65c9075 100644
--- a/ios/chrome/browser/ui/settings/safety_check/safety_check_egtest.mm
+++ b/ios/chrome/browser/ui/settings/safety_check/safety_check_egtest.mm
@@ -19,7 +19,7 @@
 #import "ios/testing/earl_grey/earl_grey_test.h"
 #import "ui/base/l10n/l10n_util.h"
 
-using password_manager_test_utils::SaveCompromisedPasswordForm;
+using password_manager_test_utils::SaveCompromisedPasswordFormToProfileStore;
 
 namespace {
 
@@ -155,7 +155,7 @@
 
 // Opens the Password Checkup UI from the Safety Check module.
 - (void)testOpenPasswordCheckup {
-  SaveCompromisedPasswordForm();
+  SaveCompromisedPasswordFormToProfileStore();
 
   OpenPasswordCheckup();
 
@@ -166,7 +166,7 @@
 // authentication. Validates that the Password Checkup content is not revealed
 // and it is dismissed after the failed authentication.
 - (void)testOpenPasswordCheckupWithFailedAuth {
-  SaveCompromisedPasswordForm();
+  SaveCompromisedPasswordFormToProfileStore();
 
   [PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult:
                                     ReauthenticationResult::kFailure];
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/regular/regular_grid_view_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/regular/regular_grid_view_controller.mm
index d263d4e..38f99ca 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/regular/regular_grid_view_controller.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/regular/regular_grid_view_controller.mm
@@ -378,6 +378,7 @@
     [weakSelf didTapInactiveTabsSettingsLink];
   };
   header.daysThreshold = _inactiveTabsDaysThreshold;
+  header.hidden = !IsInactiveTabsEnabled();
 }
 
 @end
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_preamble_header.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_preamble_header.mm
index c3b2f944..d7b03e1 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_preamble_header.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_preamble_header.mm
@@ -62,7 +62,6 @@
 }
 
 - (void)setDaysThreshold:(NSInteger)daysThreshold {
-  DCHECK_NE(daysThreshold, kInactiveTabsDisabledByUser);
   _daysThreshold = daysThreshold;
 
   // Update the text view's attributed text.
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/tab_strip_cell.mm b/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/tab_strip_cell.mm
index 76dbda0..4dbda60 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/tab_strip_cell.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/tab_strip_cell.mm
@@ -16,13 +16,20 @@
 // The size of the xmark symbol image.
 NSInteger kXmarkSymbolPointSize = 13;
 
+// Corner radius of the top left and right corner of the content view.
+const CGFloat kTopCornerRadius = 16;
+
+// Size of the decoration tails when the cell is selected.
+const CGFloat kTailSize = 16;
+
+// Content view constants.
 const CGFloat kFaviconLeadingMargin = 16;
 const CGFloat kCloseButtonMargin = 16;
 const CGFloat kTitleInset = 10.0;
 const CGFloat kFontSize = 14.0;
-
 const CGFloat kFaviconSize = 16.0;
 
+// Returns the default favicon image.
 UIImage* DefaultFavicon() {
   return DefaultSymbolWithPointSize(kGlobeAmericasSymbol, 14);
 }
@@ -30,24 +37,33 @@
 }  // namespace
 
 @implementation TabStripCell {
+  // Content view subviews.
   UIButton* _closeButton;
   UILabel* _titleLabel;
   UIImageView* _faviconView;
+
+  // Decoration tails, visible when the cell is selected.
+  UIView* _leftTailView;
+  UIView* _rightTailView;
+
+  // Width of the cell.
+  CGFloat _cellWidth;
+
+  // Wether the tail layers have been updated.
+  BOOL _tailLayersUpdated;
+
+  // Circular spinner that shows the loading state of the tab.
   MDCActivityIndicator* _activityIndicator;
 }
 
 - (instancetype)initWithFrame:(CGRect)frame {
   if ((self = [super initWithFrame:frame])) {
-    // TODO(crbug.com/1490555): Remove the border once we get closer to the
-    // design.
-    self.layer.borderColor = UIColor.blackColor.CGColor;
-    self.layer.borderWidth = 1;
+    self.layer.masksToBounds = NO;
+    _cellWidth = 0;
+    _tailLayersUpdated = NO;
 
     UIView* contentView = self.contentView;
 
-    UILayoutGuide* leadingImageGuide = [[UILayoutGuide alloc] init];
-    [self addLayoutGuide:leadingImageGuide];
-
     _faviconView = [self createFaviconView];
     [contentView addSubview:_faviconView];
 
@@ -60,38 +76,15 @@
     _titleLabel = [self createTitleLabel];
     [contentView addSubview:_titleLabel];
 
-    [NSLayoutConstraint activateConstraints:@[
-      [leadingImageGuide.leadingAnchor
-          constraintEqualToAnchor:contentView.leadingAnchor
-                         constant:kFaviconLeadingMargin],
-      [leadingImageGuide.centerYAnchor
-          constraintEqualToAnchor:contentView.centerYAnchor],
-      [leadingImageGuide.widthAnchor constraintEqualToConstant:kFaviconSize],
-      [leadingImageGuide.heightAnchor
-          constraintEqualToAnchor:leadingImageGuide.widthAnchor],
-    ]];
+    _leftTailView = [self createTailView];
+    [self addSubview:_leftTailView];
 
-    AddSameConstraints(leadingImageGuide, _faviconView);
-    AddSameConstraints(leadingImageGuide, _activityIndicator);
+    _rightTailView = [self createTailView];
+    [self addSubview:_rightTailView];
 
-    [NSLayoutConstraint activateConstraints:@[
-      [_closeButton.trailingAnchor
-          constraintEqualToAnchor:contentView.trailingAnchor
-                         constant:-kCloseButtonMargin],
-      [_closeButton.centerYAnchor
-          constraintEqualToAnchor:contentView.centerYAnchor],
-    ]];
+    [self setupConstraints];
 
-    [NSLayoutConstraint activateConstraints:@[
-      [_titleLabel.leadingAnchor
-          constraintEqualToAnchor:leadingImageGuide.trailingAnchor
-                         constant:kTitleInset],
-      [_titleLabel.trailingAnchor
-          constraintLessThanOrEqualToAnchor:_closeButton.leadingAnchor
-                                   constant:-kTitleInset],
-      [_titleLabel.centerYAnchor
-          constraintEqualToAnchor:contentView.centerYAnchor],
-    ]];
+    self.selected = NO;
   }
   return self;
 }
@@ -125,20 +118,43 @@
   }
 }
 
+- (void)layoutSubviews {
+  [super layoutSubviews];
+
+  CGFloat cellWidth = self.frame.size.width;
+  if (cellWidth != _cellWidth) {
+    [self updateContentViewLayer];
+    _cellWidth = cellWidth;
+  }
+
+  if (!_tailLayersUpdated) {
+    [self updateTailLayers];
+  }
+}
+
 #pragma mark - Accessor
 
 - (void)setSelected:(BOOL)selected {
   [super setSelected:selected];
-  self.backgroundColor = selected ? UIColor.blueColor : UIColor.whiteColor;
+
+  // Style the contentView background color.
+  self.contentView.backgroundColor =
+      selected ? [UIColor colorNamed:kPrimaryBackgroundColor]
+               : UIColor.clearColor;
+
   // Style the favicon tint color.
   _faviconView.tintColor = selected ? [UIColor colorNamed:kCloseButtonColor]
                                     : [UIColor colorNamed:kGrey500Color];
   // Style the close button tint color.
   _closeButton.tintColor = selected ? [UIColor colorNamed:kCloseButtonColor]
                                     : [UIColor colorNamed:kGrey500Color];
-  // Style the title tint color.
+  // Style the title text color.
   _titleLabel.textColor = selected ? [UIColor colorNamed:kTextPrimaryColor]
                                    : [UIColor colorNamed:kGrey600Color];
+
+  // Update decoration tails visibility.
+  _leftTailView.hidden = !selected;
+  _rightTailView.hidden = !selected;
 }
 
 #pragma mark - UICollectionViewCell
@@ -152,6 +168,126 @@
 
 #pragma mark - Private
 
+/// Updates the `contentView` layer for the `selected` state of the cell.
+- (void)updateContentViewLayer {
+  // Round the top corners of the content view.
+  UIBezierPath* path = [UIBezierPath
+      bezierPathWithRoundedRect:self.bounds
+              byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight
+                    cornerRadii:CGSizeMake(kTopCornerRadius, 0.0)];
+  CAShapeLayer* maskLayer = [CAShapeLayer layer];
+  maskLayer.path = path.CGPath;
+  self.contentView.layer.mask = maskLayer;
+}
+
+/// Updates the tail layers for the `selected` state of the cell.
+- (void)updateTailLayers {
+  CGRect leftTailRect = _leftTailView.bounds;
+  if (leftTailRect.size.width == 0) {
+    return;
+  }
+
+  CGFloat radius = kTailSize;
+
+  // Round the left tail.
+  UIBezierPath* leftTailPath = [UIBezierPath bezierPath];
+  [leftTailPath moveToPoint:CGPointMake(CGRectGetMaxX(leftTailRect),
+                                        CGRectGetMaxY(leftTailRect))];
+  [leftTailPath
+      addLineToPoint:CGPointMake(CGRectGetMaxX(leftTailRect),
+                                 CGRectGetMaxY(leftTailRect) - radius)];
+  [leftTailPath
+      addArcWithCenter:CGPointMake(CGRectGetMaxX(leftTailRect) - radius,
+                                   CGRectGetMaxY(leftTailRect) - radius)
+                radius:radius
+            startAngle:0
+              endAngle:M_PI_2
+             clockwise:YES];
+  [leftTailPath closePath];
+  CAShapeLayer* leftTailMaskLayer = [CAShapeLayer layer];
+  leftTailMaskLayer.path = leftTailPath.CGPath;
+  _leftTailView.layer.mask = leftTailMaskLayer;
+
+  // Round the right tail.
+  CGRect rightTailRect = _rightTailView.bounds;
+  UIBezierPath* rightTailpath = [UIBezierPath bezierPath];
+  [rightTailpath moveToPoint:CGPointMake(CGRectGetMinX(rightTailRect),
+                                         CGRectGetMaxY(rightTailRect))];
+  [rightTailpath
+      addLineToPoint:CGPointMake(CGRectGetMinX(rightTailRect),
+                                 CGRectGetMaxY(rightTailRect) - radius)];
+  [rightTailpath
+      addArcWithCenter:CGPointMake(CGRectGetMinX(rightTailRect) + radius,
+                                   CGRectGetMaxY(rightTailRect) - radius)
+                radius:radius
+            startAngle:M_PI
+              endAngle:M_PI_2
+             clockwise:NO];
+  [rightTailpath closePath];
+  CAShapeLayer* rightTailMaskLayer = [CAShapeLayer layer];
+  rightTailMaskLayer.path = rightTailpath.CGPath;
+  _rightTailView.layer.mask = rightTailMaskLayer;
+
+  _tailLayersUpdated = YES;
+}
+
+// Sets the cell constraints.
+- (void)setupConstraints {
+  UILayoutGuide* leadingImageGuide = [[UILayoutGuide alloc] init];
+  [self addLayoutGuide:leadingImageGuide];
+
+  UIView* contentView = self.contentView;
+
+  [NSLayoutConstraint activateConstraints:@[
+    [leadingImageGuide.leadingAnchor
+        constraintEqualToAnchor:contentView.leadingAnchor
+                       constant:kFaviconLeadingMargin],
+    [leadingImageGuide.centerYAnchor
+        constraintEqualToAnchor:contentView.centerYAnchor],
+    [leadingImageGuide.widthAnchor constraintEqualToConstant:kFaviconSize],
+    [leadingImageGuide.heightAnchor
+        constraintEqualToAnchor:leadingImageGuide.widthAnchor],
+  ]];
+
+  AddSameConstraints(leadingImageGuide, _faviconView);
+  AddSameConstraints(leadingImageGuide, _activityIndicator);
+
+  [NSLayoutConstraint activateConstraints:@[
+    [_closeButton.trailingAnchor
+        constraintEqualToAnchor:contentView.trailingAnchor
+                       constant:-kCloseButtonMargin],
+    [_closeButton.centerYAnchor
+        constraintEqualToAnchor:contentView.centerYAnchor],
+  ]];
+
+  [NSLayoutConstraint activateConstraints:@[
+    [_titleLabel.leadingAnchor
+        constraintEqualToAnchor:leadingImageGuide.trailingAnchor
+                       constant:kTitleInset],
+    [_titleLabel.trailingAnchor
+        constraintLessThanOrEqualToAnchor:_closeButton.leadingAnchor
+                                 constant:-kTitleInset],
+    [_titleLabel.centerYAnchor
+        constraintEqualToAnchor:contentView.centerYAnchor],
+  ]];
+
+  [NSLayoutConstraint activateConstraints:@[
+    [_leftTailView.trailingAnchor
+        constraintEqualToAnchor:contentView.leadingAnchor],
+    [_leftTailView.bottomAnchor
+        constraintEqualToAnchor:contentView.bottomAnchor],
+    [_leftTailView.widthAnchor constraintEqualToConstant:kTailSize],
+    [_leftTailView.heightAnchor constraintEqualToConstant:kTailSize],
+
+    [_rightTailView.leadingAnchor
+        constraintEqualToAnchor:contentView.trailingAnchor],
+    [_rightTailView.bottomAnchor
+        constraintEqualToAnchor:contentView.bottomAnchor],
+    [_rightTailView.widthAnchor constraintEqualToConstant:kTailSize],
+    [_rightTailView.heightAnchor constraintEqualToConstant:kTailSize],
+  ]];
+}
+
 // Selector registered to the close button.
 - (void)closeButtonTapped:(id)sender {
   [self.delegate closeButtonTappedForCell:self];
@@ -196,4 +332,13 @@
   return activityIndicator;
 }
 
+// Returns a new tail view.
+- (UIView*)createTailView {
+  UIView* tailView = [[UIView alloc] init];
+  tailView.backgroundColor = [UIColor colorNamed:kPrimaryBackgroundColor];
+  tailView.translatesAutoresizingMaskIntoConstraints = NO;
+  tailView.hidden = YES;
+  return tailView;
+}
+
 @end
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/tab_strip_view_controller.swift b/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/tab_strip_view_controller.swift
index efb48eef..9495e93 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/tab_strip_view_controller.swift
+++ b/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/tab_strip_view_controller.swift
@@ -34,6 +34,8 @@
     super.init(nibName: nil, bundle: nil)
 
     collectionView.delegate = self
+    collectionView.showsHorizontalScrollIndicator = false
+
     createRegistrations()
     diffableDataSource = UICollectionViewDiffableDataSource<Section, TabSwitcherItem>(
       collectionView: collectionView
@@ -55,6 +57,9 @@
     view.backgroundColor = UIColor(named: kGrey200Color)
 
     collectionView.translatesAutoresizingMaskIntoConstraints = false
+    collectionView.clipsToBounds = false
+    view.layer.masksToBounds = true
+
     collectionView.backgroundColor = .clear
     view.addSubview(collectionView)
 
@@ -95,7 +100,7 @@
   func selectItem(_ item: TabSwitcherItem?) {
     if let indexPaths = collectionView.indexPathsForSelectedItems {
       for indexPath in indexPaths {
-        collectionView.deselectItem(at: indexPath, animated: true)
+        collectionView.deselectItem(at: indexPath, animated: false)
       }
     }
     guard
@@ -108,7 +113,10 @@
     let scrollPosition: UICollectionView.ScrollPosition =
       collectionView.cellForItem(at: indexPath) != nil
       ? .centeredVertically : .centeredHorizontally
-    collectionView.selectItem(at: indexPath, animated: true, scrollPosition: scrollPosition)
+    collectionView.selectItem(at: indexPath, animated: false, scrollPosition: scrollPosition)
+
+    /// Invalidate the layout to correctly recalculate the frame of the `selected` cell.
+    collectionView.collectionViewLayout.invalidateLayout()
   }
 
   func reloadItem(_ item: TabSwitcherItem?) {
diff --git a/ios/chrome/browser/web/image_fetch/BUILD.gn b/ios/chrome/browser/web/image_fetch/BUILD.gn
index 47ac31d..6d36ffa 100644
--- a/ios/chrome/browser/web/image_fetch/BUILD.gn
+++ b/ios/chrome/browser/web/image_fetch/BUILD.gn
@@ -57,19 +57,3 @@
     "//services/network:test_support",
   ]
 }
-
-fuzzer_test("image_fetch_java_script_feature_fuzzer") {
-  additional_configs = [ "//testing/libfuzzer:build_for_ios_clusterfuzz_job" ]
-
-  sources = [ "image_fetch_java_script_feature_fuzzer.mm" ]
-  deps = [
-    ":image_fetch",
-    "//base",
-    "//ios/web/public/js_messaging",
-    "//ios/web/public/js_messaging/fuzzer_support",
-    "//ios/web/public/js_messaging/fuzzer_support:js_message_proto",
-    "//ios/web/public/test:fuzzer_support",
-    "//third_party/libprotobuf-mutator",
-  ]
-  seed_corpus = "fuzzer_corpus"
-}
diff --git a/ios/chrome/browser/web/model/BUILD.gn b/ios/chrome/browser/web/model/BUILD.gn
index 4853343..c0ee79142 100644
--- a/ios/chrome/browser/web/model/BUILD.gn
+++ b/ios/chrome/browser/web/model/BUILD.gn
@@ -61,3 +61,23 @@
   sources = [ "features.h" ]
   public_deps = [ "//ios/chrome/browser/web:feature_flags" ]
 }
+
+source_set("unit_tests") {
+  testonly = true
+  public_deps = [ "//ios/chrome/browser/web:unit_tests" ]
+}
+
+source_set("unit_tests_internal") {
+  testonly = true
+  public_deps = [ "//ios/chrome/browser/web:unit_tests_internal" ]
+}
+
+source_set("eg_app_support+eg2") {
+  testonly = true
+  public_deps = [ "//ios/chrome/browser/web:eg_app_support+eg2" ]
+}
+
+source_set("eg2_tests") {
+  testonly = true
+  public_deps = [ "//ios/chrome/browser/web:eg2_tests" ]
+}
diff --git a/ios/chrome/browser/web/model/choose_file/BUILD.gn b/ios/chrome/browser/web/model/choose_file/BUILD.gn
new file mode 100644
index 0000000..36c8241
--- /dev/null
+++ b/ios/chrome/browser/web/model/choose_file/BUILD.gn
@@ -0,0 +1,10 @@
+# Copyright 2023 The Chromium Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//ios/web/public/js_messaging/optimize_ts.gni")
+
+source_set("unit_tests") {
+  testonly = true
+  public_deps = [ "//ios/chrome/browser/web/choose_file:unit_tests" ]
+}
diff --git a/ios/chrome/browser/web/model/font_size/BUILD.gn b/ios/chrome/browser/web/model/font_size/BUILD.gn
index 847c6c3..205d1cb 100644
--- a/ios/chrome/browser/web/model/font_size/BUILD.gn
+++ b/ios/chrome/browser/web/model/font_size/BUILD.gn
@@ -11,3 +11,8 @@
   ]
   public_deps = [ "//ios/chrome/browser/web/font_size" ]
 }
+
+source_set("unit_tests") {
+  testonly = true
+  public_deps = [ "//ios/chrome/browser/web/font_size:unit_tests" ]
+}
diff --git a/ios/chrome/browser/web/model/image_fetch/BUILD.gn b/ios/chrome/browser/web/model/image_fetch/BUILD.gn
index 18bb8e2..b35598f 100644
--- a/ios/chrome/browser/web/model/image_fetch/BUILD.gn
+++ b/ios/chrome/browser/web/model/image_fetch/BUILD.gn
@@ -12,3 +12,25 @@
   ]
   public_deps = [ "//ios/chrome/browser/web/image_fetch" ]
 }
+
+fuzzer_test("image_fetch_java_script_feature_fuzzer") {
+  additional_configs = [ "//testing/libfuzzer:build_for_ios_clusterfuzz_job" ]
+
+  sources = [ "image_fetch_java_script_feature_fuzzer.mm" ]
+
+  deps = [
+    ":image_fetch",
+    "//base",
+    "//ios/web/public/js_messaging",
+    "//ios/web/public/js_messaging/fuzzer_support",
+    "//ios/web/public/js_messaging/fuzzer_support:js_message_proto",
+    "//ios/web/public/test:fuzzer_support",
+    "//third_party/libprotobuf-mutator",
+  ]
+  seed_corpus = "fuzzer_corpus"
+}
+
+source_set("unit_tests") {
+  testonly = true
+  public_deps = [ "//ios/chrome/browser/web/image_fetch:unit_tests" ]
+}
diff --git a/ios/chrome/browser/web/image_fetch/fuzzer_corpus/corpus1 b/ios/chrome/browser/web/model/image_fetch/fuzzer_corpus/corpus1
similarity index 100%
rename from ios/chrome/browser/web/image_fetch/fuzzer_corpus/corpus1
rename to ios/chrome/browser/web/model/image_fetch/fuzzer_corpus/corpus1
diff --git a/ios/chrome/browser/web/image_fetch/fuzzer_corpus/corpus2 b/ios/chrome/browser/web/model/image_fetch/fuzzer_corpus/corpus2
similarity index 100%
rename from ios/chrome/browser/web/image_fetch/fuzzer_corpus/corpus2
rename to ios/chrome/browser/web/model/image_fetch/fuzzer_corpus/corpus2
diff --git a/ios/chrome/browser/web/image_fetch/image_fetch_java_script_feature_fuzzer.mm b/ios/chrome/browser/web/model/image_fetch/image_fetch_java_script_feature_fuzzer.mm
similarity index 93%
rename from ios/chrome/browser/web/image_fetch/image_fetch_java_script_feature_fuzzer.mm
rename to ios/chrome/browser/web/model/image_fetch/image_fetch_java_script_feature_fuzzer.mm
index d355b4c..264c2cd 100644
--- a/ios/chrome/browser/web/image_fetch/image_fetch_java_script_feature_fuzzer.mm
+++ b/ios/chrome/browser/web/model/image_fetch/image_fetch_java_script_feature_fuzzer.mm
@@ -4,7 +4,7 @@
 
 #import "base/base64.h"
 #import "base/rand_util.h"
-#import "ios/chrome/browser/web/image_fetch/image_fetch_java_script_feature.h"
+#import "ios/chrome/browser/web/model/image_fetch/image_fetch_java_script_feature.h"
 #import "ios/web/public/js_messaging/fuzzer_support/fuzzer_env_with_java_script_feature.h"
 #import "ios/web/public/js_messaging/fuzzer_support/fuzzer_util.h"
 #import "ios/web/public/js_messaging/fuzzer_support/js_message.pb.h"
diff --git a/ios/chrome/browser/web/model/java_script_console/BUILD.gn b/ios/chrome/browser/web/model/java_script_console/BUILD.gn
index 4a4b84a..750566f 100644
--- a/ios/chrome/browser/web/model/java_script_console/BUILD.gn
+++ b/ios/chrome/browser/web/model/java_script_console/BUILD.gn
@@ -13,3 +13,8 @@
   ]
   public_deps = [ "//ios/chrome/browser/web/java_script_console" ]
 }
+
+source_set("unit_tests") {
+  testonly = true
+  public_deps = [ "//ios/chrome/browser/web/java_script_console:unit_tests" ]
+}
diff --git a/ios/chrome/browser/web/model/print/BUILD.gn b/ios/chrome/browser/web/model/print/BUILD.gn
index 0ed871c..2f2759a 100644
--- a/ios/chrome/browser/web/model/print/BUILD.gn
+++ b/ios/chrome/browser/web/model/print/BUILD.gn
@@ -12,3 +12,8 @@
   ]
   public_deps = [ "//ios/chrome/browser/web/print" ]
 }
+
+source_set("unit_tests") {
+  testonly = true
+  public_deps = [ "//ios/chrome/browser/web/print:unit_tests" ]
+}
diff --git a/ios/chrome/browser/web/model/session_state/BUILD.gn b/ios/chrome/browser/web/model/session_state/BUILD.gn
index 4ad8023..14105a2 100644
--- a/ios/chrome/browser/web/model/session_state/BUILD.gn
+++ b/ios/chrome/browser/web/model/session_state/BUILD.gn
@@ -12,3 +12,8 @@
 
   public_deps = [ "//ios/chrome/browser/web/session_state" ]
 }
+
+source_set("unit_tests") {
+  testonly = true
+  public_deps = [ "//ios/chrome/browser/web/session_state:unit_tests" ]
+}
diff --git a/ios/chrome/browser/web/model/web_performance_metrics/BUILD.gn b/ios/chrome/browser/web/model/web_performance_metrics/BUILD.gn
index de87f5f..660bf2d6 100644
--- a/ios/chrome/browser/web/model/web_performance_metrics/BUILD.gn
+++ b/ios/chrome/browser/web/model/web_performance_metrics/BUILD.gn
@@ -14,3 +14,10 @@
 
   public_deps = [ "//ios/chrome/browser/web/web_performance_metrics" ]
 }
+
+source_set("unit_tests") {
+  testonly = true
+
+  public_deps =
+      [ "//ios/chrome/browser/web/web_performance_metrics:unit_tests" ]
+}
diff --git a/ios/chrome/test/BUILD.gn b/ios/chrome/test/BUILD.gn
index cd69aae..be9f6a1e 100644
--- a/ios/chrome/test/BUILD.gn
+++ b/ios/chrome/test/BUILD.gn
@@ -38,7 +38,7 @@
   deps = [
     "//components/autofill/ios/form_util:form_activity_tab_helper_fuzzer",
     "//ios/chrome/browser/crash_report/model:crashpad_fuzzer_tests",
-    "//ios/chrome/browser/web/image_fetch:image_fetch_java_script_feature_fuzzer",
+    "//ios/chrome/browser/web/model/image_fetch:image_fetch_java_script_feature_fuzzer",
   ]
 }
 
@@ -138,7 +138,7 @@
     "//ios/chrome/browser/browser_state/model",
     "//ios/chrome/browser/shared/model/paths",
     "//ios/chrome/browser/shared/model/url:constants",
-    "//ios/chrome/browser/web/web_performance_metrics:unit_tests",
+    "//ios/chrome/browser/web/model/web_performance_metrics:unit_tests",
     "//ios/chrome/test:test_support",
     "//ios/components/webui:url_constants",
     "//ios/public/provider/chrome/browser/app_utils:app_utils_api",
@@ -453,14 +453,14 @@
     "//ios/chrome/browser/url_loading/model:unit_tests",
     "//ios/chrome/browser/variations/model:unit_tests",
     "//ios/chrome/browser/voice/model:unit_tests",
-    "//ios/chrome/browser/web:unit_tests",
-    "//ios/chrome/browser/web:unit_tests_internal",
-    "//ios/chrome/browser/web/choose_file:unit_tests",
-    "//ios/chrome/browser/web/font_size:unit_tests",
-    "//ios/chrome/browser/web/image_fetch:unit_tests",
-    "//ios/chrome/browser/web/java_script_console:unit_tests",
-    "//ios/chrome/browser/web/print:unit_tests",
-    "//ios/chrome/browser/web/session_state:unit_tests",
+    "//ios/chrome/browser/web/model:unit_tests",
+    "//ios/chrome/browser/web/model:unit_tests_internal",
+    "//ios/chrome/browser/web/model/choose_file:unit_tests",
+    "//ios/chrome/browser/web/model/font_size:unit_tests",
+    "//ios/chrome/browser/web/model/image_fetch:unit_tests",
+    "//ios/chrome/browser/web/model/java_script_console:unit_tests",
+    "//ios/chrome/browser/web/model/print:unit_tests",
+    "//ios/chrome/browser/web/model/session_state:unit_tests",
     "//ios/chrome/browser/web_selection/model:unit_tests",
     "//ios/chrome/browser/web_state_list/model:unit_tests",
     "//ios/chrome/browser/web_state_list/model/web_usage_enabler:unit_tests",
diff --git a/ios/chrome/test/earl_grey/BUILD.gn b/ios/chrome/test/earl_grey/BUILD.gn
index adbd92b..7f2d59ad 100644
--- a/ios/chrome/test/earl_grey/BUILD.gn
+++ b/ios/chrome/test/earl_grey/BUILD.gn
@@ -191,8 +191,8 @@
     "//ios/chrome/browser/ui/unit_conversion:eg_app_support+eg2",
     "//ios/chrome/browser/unified_consent/model",
     "//ios/chrome/browser/variations/model:eg_app_support+eg2",
-    "//ios/chrome/browser/web",
-    "//ios/chrome/browser/web:eg_app_support+eg2",
+    "//ios/chrome/browser/web/model",
+    "//ios/chrome/browser/web/model:eg_app_support+eg2",
     "//ios/chrome/common/ui/promo_style:constants",
     "//ios/chrome/test/app:test_support",
     "//ios/chrome/test/variations_smoke_test:eg_app_support+eg2",
@@ -290,7 +290,7 @@
     "//ios/chrome/browser/ui/tab_switcher/tab_grid:tab_grid_ui_constants",
     "//ios/chrome/browser/ui/tab_switcher/tab_grid/grid:grid_ui_constants",
     "//ios/chrome/browser/ui/toolbar:eg_test_support+eg2",
-    "//ios/chrome/browser/web:feature_flags",
+    "//ios/chrome/browser/web/model:feature_flags",
     "//ios/chrome/test:eg_test_support+eg2",
     "//ios/testing:http_server_bundle_data",
     "//ios/testing:nserror_support",
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm b/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm
index 402bc12..d7237864 100644
--- a/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm
+++ b/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm
@@ -59,7 +59,7 @@
 #import "ios/chrome/browser/ui/ntp/new_tab_page_feature.h"
 #import "ios/chrome/browser/ui/popup_menu/overflow_menu/feature_flags.h"
 #import "ios/chrome/browser/unified_consent/model/unified_consent_service_factory.h"
-#import "ios/chrome/browser/web/web_navigation_browser_agent.h"
+#import "ios/chrome/browser/web/model/web_navigation_browser_agent.h"
 #import "ios/chrome/test/app/browsing_data_test_util.h"
 #import "ios/chrome/test/app/chrome_test_util.h"
 #import "ios/chrome/test/app/navigation_test_util.h"
diff --git a/ios/chrome/test/earl_grey/chrome_test_case.mm b/ios/chrome/test/earl_grey/chrome_test_case.mm
index 8bd12ec1..cd24a44 100644
--- a/ios/chrome/test/earl_grey/chrome_test_case.mm
+++ b/ios/chrome/test/earl_grey/chrome_test_case.mm
@@ -18,7 +18,7 @@
 #import "base/test/ios/wait_util.h"
 #import "ios/chrome/browser/policy/model/policy_earl_grey_utils.h"
 #import "ios/chrome/browser/ui/ntp/new_tab_page_feature.h"
-#import "ios/chrome/browser/web/features.h"
+#import "ios/chrome/browser/web/model/features.h"
 #import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
 #import "ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h"
 #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h"
diff --git a/ios/chrome/test/earl_grey2/BUILD.gn b/ios/chrome/test/earl_grey2/BUILD.gn
index ec02c6b2..b7c1f41 100644
--- a/ios/chrome/test/earl_grey2/BUILD.gn
+++ b/ios/chrome/test/earl_grey2/BUILD.gn
@@ -265,7 +265,7 @@
 chrome_ios_eg2_test("ios_chrome_web_eg2tests_module") {
   xcode_test_application_name = "ios_chrome_eg2tests"
 
-  deps = [ "//ios/chrome/browser/web:eg2_tests" ]
+  deps = [ "//ios/chrome/browser/web/model:eg2_tests" ]
   data_deps = [ ":ios_chrome_eg2tests" ]
 }
 
diff --git a/ios/chrome/test/fakes/BUILD.gn b/ios/chrome/test/fakes/BUILD.gn
index f762de9..29e108d5 100644
--- a/ios/chrome/test/fakes/BUILD.gn
+++ b/ios/chrome/test/fakes/BUILD.gn
@@ -40,7 +40,7 @@
     "//ios/chrome/browser/ui/overscroll_actions",
     "//ios/chrome/browser/ui/presenters",
     "//ios/chrome/browser/ui/settings/utils",
-    "//ios/chrome/browser/web:web_internal",
+    "//ios/chrome/browser/web/model:web_internal",
     "//ios/web/public",
     "//ios/web/public/download",
   ]
diff --git a/ios/chrome/test/providers/text_zoom/BUILD.gn b/ios/chrome/test/providers/text_zoom/BUILD.gn
index 348947b5..f9f7d2e6 100644
--- a/ios/chrome/test/providers/text_zoom/BUILD.gn
+++ b/ios/chrome/test/providers/text_zoom/BUILD.gn
@@ -6,7 +6,7 @@
   testonly = true
   sources = [ "test_text_zoom.mm" ]
   deps = [
-    "//ios/chrome/browser/web/font_size",
+    "//ios/chrome/browser/web/model/font_size",
     "//ios/public/provider/chrome/browser/text_zoom:text_zoom_api",
   ]
 }
diff --git a/ios/chrome/test/providers/text_zoom/test_text_zoom.mm b/ios/chrome/test/providers/text_zoom/test_text_zoom.mm
index daa474d8..698ca847 100644
--- a/ios/chrome/test/providers/text_zoom/test_text_zoom.mm
+++ b/ios/chrome/test/providers/text_zoom/test_text_zoom.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/web/font_size/font_size_java_script_feature.h"
+#import "ios/chrome/browser/web/model/font_size/font_size_java_script_feature.h"
 #import "ios/public/provider/chrome/browser/text_zoom/text_zoom_api.h"
 
 namespace ios {
diff --git a/ios/components/security_interstitials/lookalikes/README.md b/ios/components/security_interstitials/lookalikes/README.md
index 7683f3fa..b550ce1 100644
--- a/ios/components/security_interstitials/lookalikes/README.md
+++ b/ios/components/security_interstitials/lookalikes/README.md
@@ -1,5 +1,6 @@
 This directory contains shared iOS lookalike code.
 
-End-to-end tests are located in ios/chrome/browser/web. The ShouldAllowResponse
-tab helper code needs to be unit tested here in components, since
-lookalike_url_egtest.mm uses a custom policy decider that overrides that method.
+End-to-end tests are located in ios/chrome/browser/web/model. The
+ShouldAllowResponse tab helper code needs to be unit tested here in components,
+since lookalike_url_egtest.mm uses a custom policy decider that overrides that
+method.
diff --git a/ipc/ipc_fuzzing_tests.cc b/ipc/ipc_fuzzing_tests.cc
index 39a1d9c..b9de0e6 100644
--- a/ipc/ipc_fuzzing_tests.cc
+++ b/ipc/ipc_fuzzing_tests.cc
@@ -143,11 +143,11 @@
 class SimpleListener : public IPC::Listener {
  public:
   SimpleListener() : other_(nullptr) {}
-  void Init(IPC::Sender* s) {
-    other_ = s;
-  }
+  void Init(IPC::Sender* s) { other_ = s; }
+  void Reset() { other_ = nullptr; }
+
  protected:
-  raw_ptr<IPC::Sender, DanglingUntriaged> other_;
+  raw_ptr<IPC::Sender> other_;
 };
 
 enum {
@@ -298,6 +298,7 @@
   sender()->Send(msg);
   EXPECT_TRUE(listener.ExpectMessage(value, MsgClassSI::ID));
 
+  listener.Reset();
   EXPECT_TRUE(WaitForClientShutdown());
   DestroyChannel();
 }
@@ -323,6 +324,7 @@
   sender()->Send(msg);
   EXPECT_TRUE(listener.ExpectMessage(1, MsgClassSI::ID));
 
+  listener.Reset();
   EXPECT_TRUE(WaitForClientShutdown());
   DestroyChannel();
 }
@@ -354,6 +356,7 @@
   sender()->Send(msg);
   EXPECT_TRUE(listener.ExpectMessage(3, MsgClassIS::ID));
 
+  listener.Reset();
   EXPECT_TRUE(WaitForClientShutdown());
   DestroyChannel();
 }
diff --git a/media/audio/audio_features.cc b/media/audio/audio_features.cc
index 0c134ca..ddbe04e 100644
--- a/media/audio/audio_features.cc
+++ b/media/audio/audio_features.cc
@@ -6,6 +6,7 @@
 
 #include "base/feature_list.h"
 #include "build/build_config.h"
+#include "media/media_buildflags.h"
 
 namespace features {
 
@@ -35,3 +36,17 @@
              base::FEATURE_ENABLED_BY_DEFAULT);
 #endif
 }  // namespace features
+
+namespace media {
+
+#if BUILDFLAG(IS_LINUX)
+bool IsPulseaudioLoopbackCaptureSupported() {
+#if defined(USE_PULSEAUDIO)
+  return true;
+#else
+  return false;
+#endif  // defined(USE_PULSEAUDIO)
+}
+#endif  // BUILDFLAG(IS_LINUX)
+
+}  // namespace media
diff --git a/media/audio/audio_features.h b/media/audio/audio_features.h
index 91cae7b..bf73302 100644
--- a/media/audio/audio_features.h
+++ b/media/audio/audio_features.h
@@ -25,4 +25,12 @@
 
 }  // namespace features
 
+namespace media {
+
+#if BUILDFLAG(IS_LINUX)
+MEDIA_EXPORT bool IsPulseaudioLoopbackCaptureSupported();
+#endif  // BUILDFLAG(IS_LINUX)
+
+}  // namespace media
+
 #endif  // MEDIA_AUDIO_AUDIO_FEATURES_H_
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc
index 5e1b938..f308c3fd 100644
--- a/media/base/media_switches.cc
+++ b/media/base/media_switches.cc
@@ -358,7 +358,19 @@
 BASE_FEATURE(kMacLoopbackAudioForScreenShare,
              "MacLoopbackAudioForScreenShare",
              base::FEATURE_DISABLED_BY_DEFAULT);
-#endif
+#endif  // BUILDFLAG(IS_MAC)
+
+#if BUILDFLAG(IS_LINUX)
+// Enables system audio mirroring using pulseaudio.
+BASE_FEATURE(kPulseaudioLoopbackForCast,
+             "PulseaudioLoopbackForCast",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
+// Enables system audio sharing using pulseaudio.
+BASE_FEATURE(kPulseaudioLoopbackForScreenShare,
+             "PulseaudioLoopbackForScreenShare",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+#endif  // BUILDFLAG(IS_LINUX)
 
 // When enabled, MediaCapabilities will check with GPU Video Accelerator
 // Factories to determine isPowerEfficient = true/false.
diff --git a/media/base/media_switches.h b/media/base/media_switches.h
index 056bc55..03c57977 100644
--- a/media/base/media_switches.h
+++ b/media/base/media_switches.h
@@ -303,6 +303,10 @@
 MEDIA_EXPORT BASE_DECLARE_FEATURE(kPlaybackSpeedButton);
 MEDIA_EXPORT BASE_DECLARE_FEATURE(kPreloadMediaEngagementData);
 MEDIA_EXPORT BASE_DECLARE_FEATURE(kPreloadMetadataSuspend);
+#if BUILDFLAG(IS_LINUX)
+MEDIA_EXPORT BASE_DECLARE_FEATURE(kPulseaudioLoopbackForCast);
+MEDIA_EXPORT BASE_DECLARE_FEATURE(kPulseaudioLoopbackForScreenShare);
+#endif  // BUILDFLAG(IS_LINUX)
 MEDIA_EXPORT BASE_DECLARE_FEATURE(kRecordMediaEngagementScores);
 MEDIA_EXPORT BASE_DECLARE_FEATURE(kRecordWebAudioEngagement);
 MEDIA_EXPORT BASE_DECLARE_FEATURE(kResumeBackgroundVideo);
diff --git a/media/gpu/BUILD.gn b/media/gpu/BUILD.gn
index 36aa809..fbd8ed7 100644
--- a/media/gpu/BUILD.gn
+++ b/media/gpu/BUILD.gn
@@ -11,6 +11,7 @@
 import("//media/gpu/args.gni")
 import("//media/media_options.gni")
 import("//testing/test.gni")
+import("//third_party/libgav1/options.gni")
 import("//tools/generate_stubs/rules.gni")
 
 buildflag_header("buildflags") {
@@ -395,7 +396,9 @@
       "//third_party/libvpx:libvpxrc",
     ]
   }
-  if (use_libgav1_parser) {
+
+  if (use_av1_hw_decoder) {
+    assert(use_libgav1_parser)
     sources += [
       "av1_decoder.cc",
       "av1_decoder.h",
@@ -633,7 +636,7 @@
     sources += [ "vp8_decoder_unittest.cc" ]
   }
 
-  if (use_libgav1_parser && media_use_ffmpeg) {
+  if (use_av1_hw_decoder && media_use_ffmpeg) {
     sources += [ "av1_decoder_unittest.cc" ]
     deps += [
       "//build:chromeos_buildflags",
@@ -677,7 +680,7 @@
   }
 }
 
-if (use_libgav1_parser) {
+if (use_av1_hw_decoder) {
   fuzzer_test("media_av1_decoder_fuzzer") {
     sources = [ "av1_decoder_fuzzertest.cc" ]
     deps = [
diff --git a/media/gpu/args.gni b/media/gpu/args.gni
index 6a3dcef..c16f135 100644
--- a/media/gpu/args.gni
+++ b/media/gpu/args.gni
@@ -42,6 +42,9 @@
   # H.264, VP9 and HEVC are enabled if protected media is enabled; AV1 is
   # optional.
   use_chromeos_protected_av1 = false
+
+  # A platform that is capable of hardware av1 decoding.
+  use_av1_hw_decoder = is_chromeos || is_linux || is_win || is_apple
 }
 
 if (use_arc_protected_media) {
diff --git a/media/gpu/mac/video_toolbox_frame_converter.cc b/media/gpu/mac/video_toolbox_frame_converter.cc
index ef3a3ef..c10ce6d 100644
--- a/media/gpu/mac/video_toolbox_frame_converter.cc
+++ b/media/gpu/mac/video_toolbox_frame_converter.cc
@@ -33,8 +33,7 @@
 constexpr uint32_t kSharedImageUsage =
     gpu::SHARED_IMAGE_USAGE_DISPLAY_READ | gpu::SHARED_IMAGE_USAGE_SCANOUT |
     gpu::SHARED_IMAGE_USAGE_MACOS_VIDEO_TOOLBOX |
-    gpu::SHARED_IMAGE_USAGE_RASTER | gpu::SHARED_IMAGE_USAGE_GLES2_READ |
-    gpu::SHARED_IMAGE_USAGE_GLES2_WRITE;
+    gpu::SHARED_IMAGE_USAGE_RASTER | gpu::SHARED_IMAGE_USAGE_GLES2_READ;
 
 constexpr char kSharedImageDebugLabel[] = "VideoToolboxVideoDecoder";
 
diff --git a/media/gpu/mac/vt_video_decode_accelerator_mac.cc b/media/gpu/mac/vt_video_decode_accelerator_mac.cc
index bb97942..1bc172f5 100644
--- a/media/gpu/mac/vt_video_decode_accelerator_mac.cc
+++ b/media/gpu/mac/vt_video_decode_accelerator_mac.cc
@@ -2329,8 +2329,7 @@
     const uint32_t shared_image_usage =
         gpu::SHARED_IMAGE_USAGE_DISPLAY_READ | gpu::SHARED_IMAGE_USAGE_SCANOUT |
         gpu::SHARED_IMAGE_USAGE_MACOS_VIDEO_TOOLBOX |
-        gpu::SHARED_IMAGE_USAGE_RASTER | gpu::SHARED_IMAGE_USAGE_GLES2_READ |
-        gpu::SHARED_IMAGE_USAGE_GLES2_WRITE;
+        gpu::SHARED_IMAGE_USAGE_RASTER | gpu::SHARED_IMAGE_USAGE_GLES2_READ;
     GLenum target = gl_client_.supports_arb_texture_rectangle
                         ? GL_TEXTURE_RECTANGLE_ARB
                         : GL_TEXTURE_2D;
diff --git a/media/gpu/test/BUILD.gn b/media/gpu/test/BUILD.gn
index 7fb5f70..d2fd2c0 100644
--- a/media/gpu/test/BUILD.gn
+++ b/media/gpu/test/BUILD.gn
@@ -229,31 +229,29 @@
   ]
 }
 
-if (use_libgav1_parser) {
-  static_library("video_encoder") {
-    testonly = true
-    sources = [
-      "bitstream_helpers.cc",
-      "bitstream_helpers.h",
-      "video_encoder/bitstream_file_writer.cc",
-      "video_encoder/bitstream_file_writer.h",
-      "video_encoder/bitstream_validator.cc",
-      "video_encoder/bitstream_validator.h",
-      "video_encoder/decoder_buffer_validator.cc",
-      "video_encoder/decoder_buffer_validator.h",
-      "video_encoder/video_encoder.cc",
-      "video_encoder/video_encoder.h",
-      "video_encoder/video_encoder_client.cc",
-      "video_encoder/video_encoder_client.h",
-    ]
-    deps = [
-      ":test_helpers",
-      "//media/gpu",
-      "//media/parsers",
-      "//testing/gtest:gtest",
-      "//third_party/libgav1:libgav1_parser",
-    ]
-  }
+static_library("video_encoder") {
+  testonly = true
+  sources = [
+    "bitstream_helpers.cc",
+    "bitstream_helpers.h",
+    "video_encoder/bitstream_file_writer.cc",
+    "video_encoder/bitstream_file_writer.h",
+    "video_encoder/bitstream_validator.cc",
+    "video_encoder/bitstream_validator.h",
+    "video_encoder/decoder_buffer_validator.cc",
+    "video_encoder/decoder_buffer_validator.h",
+    "video_encoder/video_encoder.cc",
+    "video_encoder/video_encoder.h",
+    "video_encoder/video_encoder_client.cc",
+    "video_encoder/video_encoder_client.h",
+  ]
+  deps = [
+    ":test_helpers",
+    "//media/gpu",
+    "//media/parsers",
+    "//testing/gtest:gtest",
+    "//third_party/libgav1:libgav1_parser",
+  ]
 }
 
 static_library("video_encoder_test_environment") {
diff --git a/media/gpu/test/video_encode_accelerator_tests.cc b/media/gpu/test/video_encode_accelerator_tests.cc
index bd4866df..af4e2885 100644
--- a/media/gpu/test/video_encode_accelerator_tests.cc
+++ b/media/gpu/test/video_encode_accelerator_tests.cc
@@ -349,6 +349,34 @@
   EXPECT_TRUE(encoder->WaitForBitstreamProcessors());
 }
 
+#if BUILDFLAG(USE_VAAPI)
+TEST_F(VideoEncoderTest, FlushAtEndOfStream_EnableDropFrame) {
+  const VideoCodec codec = VideoCodecProfileToVideoCodec(g_env->Profile());
+  if (codec != media::VideoCodec::kVP8) {
+    GTEST_SKIP() << "VideoEncodeAccelerator on this device doesn't support drop"
+                 << "frame with codec=" << GetCodecName(codec);
+  }
+  if (g_env->BitrateAllocation().GetMode() == Bitrate::Mode::kVariable) {
+    GTEST_SKIP() << "Drop frame doesn't support in VBR encoding";
+  }
+
+  auto config = GetDefaultConfig();
+  constexpr uint8_t kDropFrameThreshold = 10;
+  config.drop_frame_thresh = kDropFrameThreshold;
+  auto encoder = CreateVideoEncoder(g_env->Video(), config);
+  encoder->Encode();
+  EXPECT_TRUE(encoder->WaitForFlushDone());
+
+  EXPECT_EQ(encoder->GetFlushDoneCount(), 1u);
+  EXPECT_EQ(encoder->GetFrameReleasedCount(), g_env->Video()->NumFrames());
+  EXPECT_TRUE(encoder->WaitForBitstreamProcessors());
+
+  auto stats = encoder->GetStats();
+  VLOG(0) << "Dropped frames: " << stats.num_dropped_frames << " / "
+          << stats.total_num_encoded_frames;
+}
+#endif  // BUILDFLAG(USE_VAAPI)
+
 // Test initializing the video encoder. The test will be successful if the video
 // encoder is capable of setting up the encoder for the specified codec and
 // resolution. The test only verifies initialization and doesn't do any
diff --git a/media/gpu/test/video_encoder/bitstream_file_writer.cc b/media/gpu/test/video_encoder/bitstream_file_writer.cc
index 377a8c3a..6ae2d7c 100644
--- a/media/gpu/test/video_encoder/bitstream_file_writer.cc
+++ b/media/gpu/test/video_encoder/bitstream_file_writer.cc
@@ -108,6 +108,11 @@
 void BitstreamFileWriter::ProcessBitstream(
     scoped_refptr<BitstreamRef> bitstream,
     size_t frame_index) {
+  if (bitstream->metadata.payload_size_bytes == 0) {
+    // Drop frame. Do nothing for this.
+    return;
+  }
+
   if (spatial_layer_index_to_write_ && bitstream->metadata.vp9) {
     const Vp9Metadata& metadata = *bitstream->metadata.vp9;
     if (bitstream->metadata.key_frame) {
diff --git a/media/gpu/test/video_encoder/bitstream_validator.cc b/media/gpu/test/video_encoder/bitstream_validator.cc
index 9d65797..7d1c550b 100644
--- a/media/gpu/test/video_encoder/bitstream_validator.cc
+++ b/media/gpu/test/video_encoder/bitstream_validator.cc
@@ -186,6 +186,10 @@
   LOG_ASSERT(frame_index <= last_frame_index_)
       << "frame_index is larger than last frame index, frame_index="
       << frame_index << ", last_frame_index_=" << last_frame_index_;
+  if (bitstream->metadata.payload_size_bytes == 0) {
+    // Drop frame. Do nothing.
+    return;
+  }
   base::AutoLock lock(validator_lock_);
   // If many pending buffers are accumulated in this validator class and the
   // allocated memory size becomes large, the test process is killed by the
diff --git a/media/gpu/test/video_encoder/decoder_buffer_validator.cc b/media/gpu/test/video_encoder/decoder_buffer_validator.cc
index 1adec03d..5872bf20 100644
--- a/media/gpu/test/video_encoder/decoder_buffer_validator.cc
+++ b/media/gpu/test/video_encoder/decoder_buffer_validator.cc
@@ -83,6 +83,14 @@
 void DecoderBufferValidator::ProcessBitstream(
     scoped_refptr<BitstreamRef> bitstream,
     size_t frame_index) {
+  const BitstreamBufferMetadata& metadata = bitstream->metadata;
+  if (metadata.payload_size_bytes == 0) {
+    if (metadata.key_frame) {
+      LOG(ERROR) << "Don't drop key frame";
+      num_errors_++;
+    }
+    return;
+  }
   if (!Validate(*bitstream->buffer, bitstream->metadata))
     num_errors_++;
 }
diff --git a/media/gpu/test/video_encoder/video_encoder_client.cc b/media/gpu/test/video_encoder/video_encoder_client.cc
index adff52a55..c284669 100644
--- a/media/gpu/test/video_encoder/video_encoder_client.cc
+++ b/media/gpu/test/video_encoder/video_encoder_client.cc
@@ -358,11 +358,17 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(encoder_client_sequence_checker_);
   auto it = bitstream_buffers_.find(bitstream_buffer_id);
   LOG_ASSERT(it != bitstream_buffers_.end());
-  auto decoder_buffer = DecoderBuffer::FromSharedMemoryRegion(
-      it->second.Duplicate(), 0u /* offset */, metadata.payload_size_bytes);
-  if (!decoder_buffer)
-    return nullptr;
-  decoder_buffer->set_timestamp(base::Microseconds(frame_index_));
+
+  scoped_refptr<DecoderBuffer> decoder_buffer;
+  if (metadata.payload_size_bytes != 0) {
+    decoder_buffer = DecoderBuffer::FromSharedMemoryRegion(
+        it->second.Duplicate(), 0u /* offset */, metadata.payload_size_bytes);
+    if (!decoder_buffer) {
+      return nullptr;
+    }
+    decoder_buffer->set_timestamp(base::Microseconds(frame_index_));
+  }
+
   auto source_timestamp_it = source_timestamps_.find(metadata.timestamp);
   LOG_ASSERT(source_timestamp_it != source_timestamps_.end());
 
@@ -379,11 +385,17 @@
     const BitstreamBufferMetadata& metadata) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(encoder_client_sequence_checker_);
   DVLOGF(4) << "frame_index=" << frame_index_
-            << ", encoded image size=" << metadata.payload_size_bytes;
+            << ", encoded image size=" << metadata.payload_size_bytes
+            << (metadata.payload_size_bytes > 0 ? "" : " (Drop Frame)");
   {
+    // |metadata.payload_size_bytes| can be zero here, but counts the dropped
+    // frame to compute a bitrate from the network point of view.
     base::AutoLock auto_lock(stats_lock_);
     current_stats_.total_num_encoded_frames++;
     current_stats_.total_encoded_frames_size += metadata.payload_size_bytes;
+    if (metadata.payload_size_bytes == 0) {
+      current_stats_.num_dropped_frames++;
+    }
     if (metadata.vp9.has_value()) {
       uint8_t temporal_id = metadata.vp9->temporal_idx;
       uint8_t spatial_id = metadata.vp9->spatial_idx;
@@ -499,6 +511,8 @@
   config.initial_framerate = encoder_client_config_.framerate;
   config.storage_type = encoder_client_config_.input_storage_type;
   config.content_type = VideoEncodeAccelerator::Config::ContentType::kCamera;
+  config.drop_frame_thresh_percentage =
+      encoder_client_config_.drop_frame_thresh;
   config.spatial_layers = encoder_client_config_.spatial_layers;
   config.inter_layer_pred = encoder_client_config_.inter_layer_pred_mode;
 
diff --git a/media/gpu/test/video_encoder/video_encoder_client.h b/media/gpu/test/video_encoder/video_encoder_client.h
index 5b860c3..8d28239 100644
--- a/media/gpu/test/video_encoder/video_encoder_client.h
+++ b/media/gpu/test/video_encoder/video_encoder_client.h
@@ -59,6 +59,8 @@
   // The maximum number of bitstream buffer encodes that can be requested
   // without waiting for the result of the previous encodes requests.
   size_t max_outstanding_encode_requests = 1;
+  // The drop frame threshold. See VideoEncodeAccelerator::Config for detail.
+  uint8_t drop_frame_thresh = 0;
   // The desired bitrate in bits/second.
   media::VideoBitrateAllocation bitrate_allocation;
   // The desired framerate in frames/second.
@@ -94,6 +96,7 @@
   uint32_t framerate = 0;
   size_t total_num_encoded_frames = 0;
   size_t total_encoded_frames_size = 0;
+  size_t num_dropped_frames = 0;
   // Filled in spatial/temporal layer encoding and codec is vp9.
   std::vector<std::vector<size_t>> num_encoded_frames_per_layer;
   std::vector<std::vector<size_t>> encoded_frames_size_per_layer;
diff --git a/media/gpu/test/video_player/decoder_wrapper.cc b/media/gpu/test/video_player/decoder_wrapper.cc
index 58e8fea..8ca9c96 100644
--- a/media/gpu/test/video_player/decoder_wrapper.cc
+++ b/media/gpu/test/video_player/decoder_wrapper.cc
@@ -382,6 +382,14 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(worker_sequence_checker_);
   DCHECK(video_frame->metadata().power_efficient);
 
+  // Technically VideoDecoder clients shouldn't care about |video_frame|'s'
+  // timestamps but we do because we feed non-zeros in DecodeNextFragmentTask().
+  // Note that we cannot enforce non-strictly monotonically increasing time
+  // deltas because the feeding order might not be the same as the output order
+  // (e.g. in H.264 with B-frames the output order would be the "presentation"
+  // order and not the "decode" or "transmission" order).
+  DCHECK_NE(video_frame->timestamp(), base::TimeDelta());
+
   frame_renderer_->RenderFrame(video_frame);
 
   for (auto& frame_processor : frame_processors_)
diff --git a/media/gpu/v4l2/BUILD.gn b/media/gpu/v4l2/BUILD.gn
index e07f8c6f..b2149662 100644
--- a/media/gpu/v4l2/BUILD.gn
+++ b/media/gpu/v4l2/BUILD.gn
@@ -8,7 +8,6 @@
 import("//media/gpu/args.gni")
 import("//media/media_options.gni")
 import("//testing/test.gni")
-import("//third_party/libgav1/options.gni")
 import("//ui/gl/features.gni")
 
 assert(use_v4l2_codec)
@@ -122,6 +121,7 @@
     "//media/gpu:video_frame_mapper_common",
     "//media/gpu/chromeos:common",
     "//media/parsers",
+    "//third_party/libgav1:libgav1_parser",
     "//third_party/libyuv",
     "//ui/gfx/geometry",
     "//ui/ozone",
@@ -142,10 +142,6 @@
       "//media/gpu:video_frame_mapper_common",
     ]
   }
-
-  if (use_libgav1_parser) {
-    deps += [ "//third_party/libgav1:libgav1_parser" ]
-  }
 }
 
 # The v4l2 status functionality is in its own source set so that it can be
@@ -219,12 +215,9 @@
     "//media:test_support",
     "//media/gpu:common",
     "//media/parsers",
+    "//third_party/libgav1:libgav1_parser",
     "//third_party/libyuv",
   ]
-
-  if (use_libgav1_parser) {
-    deps += [ "//third_party/libgav1:libgav1_parser" ]
-  }
 }
 
 test("v4l2_unittest") {
diff --git a/media/gpu/v4l2/v4l2_stateful_video_decoder.cc b/media/gpu/v4l2/v4l2_stateful_video_decoder.cc
index c88a741f5..97a5881 100644
--- a/media/gpu/v4l2/v4l2_stateful_video_decoder.cc
+++ b/media/gpu/v4l2/v4l2_stateful_video_decoder.cc
@@ -454,7 +454,7 @@
                                       DecodeCB decode_cb) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(IsInitialized()) << "V4L2StatefulVideoDecoder must be Initialize()d";
-  DVLOGF(3) << buffer->AsHumanReadableString(/*verbose=*/false);
+  VLOGF(3) << buffer->AsHumanReadableString(/*verbose=*/false);
 
   if (buffer->end_of_stream()) {
     if (!event_task_runner_) {
@@ -1166,7 +1166,7 @@
         base::checked_cast<size_t>(nalu_info->nalu_size);
 
     if (nalu_info->is_start_of_new_frame && HasFragments()) {
-      VLOGF(3) << frame_fragments_.size()
+      VLOGF(4) << frame_fragments_.size()
                << " currently stored frame fragment(s) can be reassembled.";
       whole_frames.emplace_back(std::make_pair(
           ReassembleFragments(frame_fragments_), base::DoNothing()));
@@ -1184,9 +1184,10 @@
       continue;
     }
 
-    VLOGF(3) << "This was a frame fragment; storing it for later reassembly.";
+    VLOGF(4) << "This was a frame fragment; storing it for later reassembly.";
     frame_fragments_.emplace_back(
         DecoderBuffer::CopyFrom(buffer_pointer, found_nalu_size));
+    frame_fragments_.back()->set_timestamp(buffer->timestamp());
 
     buffer_pointer += found_nalu_size;
     remaining_buffer_size -= found_nalu_size;
diff --git a/media/gpu/v4l2/v4l2_video_encode_accelerator.cc b/media/gpu/v4l2/v4l2_video_encode_accelerator.cc
index 51dda6a7..cff9857 100644
--- a/media/gpu/v4l2/v4l2_video_encode_accelerator.cc
+++ b/media/gpu/v4l2/v4l2_video_encode_accelerator.cc
@@ -24,6 +24,7 @@
 #include "base/memory/shared_memory_mapping.h"
 #include "base/memory/unsafe_shared_memory_region.h"
 #include "base/numerics/safe_conversions.h"
+#include "base/strings/strcat.h"
 #include "base/task/sequenced_task_runner.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/task/task_traits.h"
@@ -317,8 +318,12 @@
                               device_input_layout_->coded_size(),
                               encoder_input_visible_rect_,
                               encoder_input_visible_rect_)) {
-      SetErrorState({EncoderStatus::Codes::kEncoderInitializationError,
-                     "Failed to create image processor"});
+      SetErrorState(
+          {EncoderStatus::Codes::kEncoderInitializationError,
+           base::StrCat(
+               {"Failed to create image processor ", "for format conversion",
+                VideoPixelFormatToString(input_layout->format()), " -> ",
+                VideoPixelFormatToString(device_input_layout_->format())})});
       return;
     }
 
@@ -327,10 +332,11 @@
         image_processor_->output_config().size.height());
     if (!NegotiateInputFormat(device_input_layout_->format(),
                               ip_output_buffer_size)) {
-      SetErrorState({EncoderStatus::Codes::kUnsupportedFrameFormat,
-                     "Failed to reconfigure v4l2 encoder driver with the "
-                     "ImageProcessor output buffer: " +
-                         ip_output_buffer_size.ToString()});
+      SetErrorState(
+          {EncoderStatus::Codes::kUnsupportedFrameFormat,
+           base::StrCat({"Failed to reconfigure v4l2 encoder driver with the ",
+                         "ImageProcessor output buffer: ",
+                         ip_output_buffer_size.ToString()})});
       return;
     }
   }
@@ -358,9 +364,9 @@
       break;
     default:
       SetErrorState({EncoderStatus::Codes::kEncoderUnsupportedConfig,
-                     "Invalid bitrate mode: " +
-                         base::NumberToString(
-                             base::strict_cast<int>(config.bitrate.mode()))});
+                     base::StrCat({"Invalid bitrate mode: ",
+                                   base::NumberToString(base::strict_cast<int>(
+                                       config.bitrate.mode()))})});
       return;
   }
 
@@ -368,9 +374,9 @@
           V4L2_CID_MPEG_CLASS,
           {V4L2ExtCtrl(V4L2_CID_MPEG_VIDEO_BITRATE_MODE, bitrate_mode)})) {
     SetErrorState({EncoderStatus::Codes::kEncoderHardwareDriverError,
-                   "Failed to configure bitrate mode: " +
-                       base::NumberToString(
-                           base::strict_cast<int>(config.bitrate.mode()))});
+                   base::StrCat({"Failed to configure bitrate mode: ",
+                                 base::NumberToString(base::strict_cast<int>(
+                                     config.bitrate.mode()))})});
     return;
   }
 
@@ -798,14 +804,16 @@
             : frame->IsMappable();
     if (!is_expected_storage_type) {
       SetErrorState({EncoderStatus::Codes::kInvalidInputFrame,
-                     "Unexpected storage: " + VideoFrame::StorageTypeToString(
-                                                  frame->storage_type())});
+                     base::StrCat({"Unexpected storage: ",
+                                   VideoFrame::StorageTypeToString(
+                                       frame->storage_type())})});
       return;
     }
 
     if (!ReconfigureFormatIfNeeded(*frame)) {
       SetErrorState({EncoderStatus::Codes::kUnsupportedFrameFormat,
-                     "Unsupported frame: " + frame->AsHumanReadableString()});
+                     base::StrCat({"Unsupported frame: ",
+                                   frame->AsHumanReadableString()})});
       return;
     }
 
@@ -1125,9 +1133,10 @@
       memset(&cmd, 0, sizeof(cmd));
       cmd.cmd = V4L2_ENC_CMD_STOP;
       if (device_->Ioctl(VIDIOC_ENCODER_CMD, &cmd) != 0) {
-        SetErrorState({EncoderStatus::Codes::kEncoderFailedFlush,
-                       "ioctl() failed: VIDIOC_ENCODER_CMD, errno=" +
-                           base::NumberToString(errno)});
+        SetErrorState(
+            {EncoderStatus::Codes::kEncoderFailedFlush,
+             base::StrCat({"ioctl() failed: VIDIOC_ENCODER_CMD, errno=",
+                           base::NumberToString(errno)})});
         child_task_runner_->PostTask(
             FROM_HERE, base::BindOnce(std::move(flush_callback_), false));
         return;
@@ -1221,9 +1230,10 @@
 
     auto ret = input_queue_->DequeueBuffer();
     if (!ret.first) {
-      SetErrorState({EncoderStatus::Codes::kEncoderHardwareDriverError,
-                     "Failed to dequeue buffer in OUTPUT queue, errno=" +
-                         base::NumberToString(errno)});
+      SetErrorState(
+          {EncoderStatus::Codes::kEncoderHardwareDriverError,
+           base::StrCat({"Failed to dequeue buffer in OUTPUT queue, errno=",
+                         base::NumberToString(errno)})});
       return;
     }
     if (!ret.second) {
@@ -1245,9 +1255,10 @@
 
     auto ret = output_queue_->DequeueBuffer();
     if (!ret.first) {
-      SetErrorState({EncoderStatus::Codes::kEncoderHardwareDriverError,
-                     "Failed to dequeue buffer in CAPTURE queue, errno=" +
-                         base::NumberToString(errno)});
+      SetErrorState(
+          {EncoderStatus::Codes::kEncoderHardwareDriverError,
+           base::StrCat({"Failed to dequeue buffer in CAPTURE queue, errno=",
+                         base::NumberToString(errno)})});
       return;
     }
     if (!ret.second) {
@@ -1324,9 +1335,10 @@
       memset(&cmd, 0, sizeof(cmd));
       cmd.cmd = V4L2_ENC_CMD_START;
       if (device_->Ioctl(VIDIOC_ENCODER_CMD, &cmd) != 0) {
-        SetErrorState({EncoderStatus::Codes::kEncoderFailedFlush,
-                       "ioctl() failed: VIDIOC_ENCODER_CMD, errno=" +
-                           base::NumberToString(errno)});
+        SetErrorState(
+            {EncoderStatus::Codes::kEncoderFailedFlush,
+             base::StrCat({"ioctl() failed: VIDIOC_ENCODER_CMD, errno=",
+                           base::NumberToString(errno)})});
         return;
       }
     }
@@ -1449,9 +1461,11 @@
         user_ptrs[i] = const_cast<uint8_t*>(frame->data(i));
       }
       if (!std::move(input_buf).QueueUserPtr(std::move(user_ptrs))) {
-        SetErrorState({EncoderStatus::Codes::kEncoderHardwareDriverError,
-                       "Failed queue a USRPTR buffer to input queue, errno=" +
-                           base::NumberToString(errno)});
+        SetErrorState(
+            {EncoderStatus::Codes::kEncoderHardwareDriverError,
+             base::StrCat(
+                 {"Failed queue a USRPTR buffer to input queue, errno=",
+                  base::NumberToString(errno)})});
         return false;
       }
       break;
@@ -1459,9 +1473,11 @@
     case V4L2_MEMORY_DMABUF: {
       if (!std::move(input_buf).QueueDMABuf(
               gmb_handle.native_pixmap_handle.planes)) {
-        SetErrorState({EncoderStatus::Codes::kEncoderHardwareDriverError,
-                       "Failed queue a DMABUF buffer to input queue, errno=" +
-                           base::NumberToString(errno)});
+        SetErrorState(
+            {EncoderStatus::Codes::kEncoderHardwareDriverError,
+             base::StrCat(
+                 {"Failed queue a DMABUF buffer to input queue, errno=",
+                  base::NumberToString(errno)})});
         return false;
       }
 
@@ -1477,10 +1493,10 @@
     }
     default:
       NOTREACHED();
-      SetErrorState(
-          {EncoderStatus::Codes::kEncoderIllegalState,
-           "Unknown input memory type: " +
-               base::NumberToString(static_cast<int>(input_buf.Memory()))});
+      SetErrorState({EncoderStatus::Codes::kEncoderIllegalState,
+                     base::StrCat({"Unknown input memory type: ",
+                                   base::NumberToString(static_cast<int>(
+                                       input_buf.Memory()))})});
       return false;
   }
 
@@ -1501,9 +1517,9 @@
 
   // Enqueue an output (VIDEO_CAPTURE) buffer.
   if (!std::move(output_buf).QueueMMap()) {
-    SetErrorState(
-        {EncoderStatus::Codes::kEncoderHardwareDriverError,
-         "Failed to QueueMMap, errno=" + base::NumberToString(errno)});
+    SetErrorState({EncoderStatus::Codes::kEncoderHardwareDriverError,
+                   base::StrCat({"Failed to QueueMMap, errno=",
+                                 base::NumberToString(errno)})});
     return false;
   }
   return true;
@@ -1670,8 +1686,8 @@
     parms.parm.output.timeperframe.denominator = framerate;
     if (device_->Ioctl(VIDIOC_S_PARM, &parms) != 0) {
       SetErrorState({EncoderStatus::Codes::kEncoderHardwareDriverError,
-                     "ioctl() failed: VIDIOC_S_PARM, errno=" +
-                         base::NumberToString(errno)});
+                     base::StrCat({"ioctl() failed: VIDIOC_S_PARM, errno=",
+                                   base::NumberToString(errno)})});
       return;
     }
   }
@@ -1792,14 +1808,14 @@
     crop.c = visible_rect;
     if (device_->Ioctl(VIDIOC_S_CROP, &crop) != 0) {
       SetErrorState({EncoderStatus::Codes::kEncoderHardwareDriverError,
-                     "ioctl() failed: VIDIOC_S_CROP, errno=" +
-                         base::NumberToString(errno)});
+                     base::StrCat({"ioctl() failed: VIDIOC_S_CROP, errno=",
+                                   base::NumberToString(errno)})});
       return false;
     }
     if (device_->Ioctl(VIDIOC_G_CROP, &crop) != 0) {
-      SetErrorState(
-          {EncoderStatus::Codes::kEncoderHardwareDriverError,
-           "ioctl() failed: VIDIOC_G_CROP" + base::NumberToString(errno)});
+      SetErrorState({EncoderStatus::Codes::kEncoderHardwareDriverError,
+                     base::StrCat({"ioctl() failed: VIDIOC_G_CROP",
+                                   base::NumberToString(errno)})});
       return false;
     }
 
@@ -1827,9 +1843,9 @@
   DCHECK(!output_queue_->IsStreaming());
 
   if (!SetOutputFormat(output_profile)) {
-    SetErrorState(
-        {EncoderStatus::Codes::kEncoderUnsupportedProfile,
-         "Unsupported codec profile: " + GetProfileName(output_profile)});
+    SetErrorState({EncoderStatus::Codes::kEncoderUnsupportedProfile,
+                   base::StrCat({"Unsupported codec profile: ",
+                                 GetProfileName(output_profile)})});
     return false;
   }
 
@@ -1848,8 +1864,8 @@
   auto v4l2_format = NegotiateInputFormat(input_format, input_size);
   if (!v4l2_format) {
     SetErrorState({EncoderStatus::Codes::kUnsupportedFrameFormat,
-                   "Unsupported input format: " +
-                       VideoPixelFormatToString(input_format)});
+                   base::StrCat({"Unsupported input format: ",
+                                 VideoPixelFormatToString(input_format)})});
     return false;
   }
 
@@ -1934,17 +1950,17 @@
   int32_t profile_value =
       V4L2Device::VideoCodecProfileToV4L2H264Profile(config.output_profile);
   if (profile_value < 0) {
-    SetErrorState(
-        {EncoderStatus::Codes::kEncoderUnsupportedProfile,
-         "unexpected h264 profile: " + GetProfileName(config.output_profile)});
+    SetErrorState({EncoderStatus::Codes::kEncoderUnsupportedProfile,
+                   base::StrCat({"Unexpected h264 profile: ",
+                                 GetProfileName(config.output_profile)})});
     return false;
   }
   if (!device_->SetExtCtrls(
           V4L2_CTRL_CLASS_MPEG,
           {V4L2ExtCtrl(V4L2_CID_MPEG_VIDEO_H264_PROFILE, profile_value)})) {
-    SetErrorState(
-        {EncoderStatus::Codes::kEncoderUnsupportedProfile,
-         "Unsupported h264 profile: " + GetProfileName(config.output_profile)});
+    SetErrorState({EncoderStatus::Codes::kEncoderUnsupportedProfile,
+                   base::StrCat({"Unsupported h264 profile: ",
+                                 GetProfileName(config.output_profile)})});
     return false;
   }
 
@@ -1971,12 +1987,14 @@
         FindValidH264Level(config.output_profile, config.bitrate.target_bps(),
                            framerate, framesize_in_mbs);
     if (!valid_level) {
-      SetErrorState({EncoderStatus::Codes::kEncoderInitializationError,
-                     "Could not find a valid h264 level for profile=" +
-                         GetProfileName(config.output_profile) + " bitrate=" +
-                         base::NumberToString(config.bitrate.target_bps()) +
-                         " framerate=" + base::NumberToString(framerate) +
-                         " size=" + config.input_visible_size.ToString()});
+      SetErrorState(
+          {EncoderStatus::Codes::kEncoderInitializationError,
+           base::StrCat({"Could not find a valid h264 level for"
+                         " profile=",
+                         GetProfileName(config.output_profile), " bitrate=",
+                         base::NumberToString(config.bitrate.target_bps()),
+                         " framerate=", base::NumberToString(framerate),
+                         " size=", config.input_visible_size.ToString()})});
       return false;
     }
 
@@ -2085,9 +2103,10 @@
   if (output_queue_->AllocateBuffers(kOutputBufferCount, V4L2_MEMORY_MMAP,
                                      /*incoherent=*/false) <
       kOutputBufferCount) {
-    SetErrorState({EncoderStatus::Codes::kEncoderInitializationError,
-                   "Failed to allocate V4L2 output buffers, errno=" +
-                       base::NumberToString(errno)});
+    SetErrorState(
+        {EncoderStatus::Codes::kEncoderInitializationError,
+         base::StrCat({"Failed to allocate V4L2 output buffers, errno=",
+                       base::NumberToString(errno)})});
     return false;
   }
   return true;
diff --git a/media/gpu/vaapi/BUILD.gn b/media/gpu/vaapi/BUILD.gn
index b9b78908..453a0d18 100644
--- a/media/gpu/vaapi/BUILD.gn
+++ b/media/gpu/vaapi/BUILD.gn
@@ -29,7 +29,6 @@
 }
 
 source_set("vaapi") {
-  assert(use_libgav1_parser)
   defines = [ "MEDIA_GPU_IMPLEMENTATION" ]
   sources = [
     "av1_vaapi_video_decoder_delegate.cc",
diff --git a/media/gpu/windows/d3d11_texture_wrapper.cc b/media/gpu/windows/d3d11_texture_wrapper.cc
index 71b6efd..1ec83a5d 100644
--- a/media/gpu/windows/d3d11_texture_wrapper.cc
+++ b/media/gpu/windows/d3d11_texture_wrapper.cc
@@ -235,12 +235,11 @@
   }
 
   // Usage flags to allow the display compositor to draw from it, video to
-  // decode, and allow webgl/canvas access.
+  // decode, and allow webgl/canvas access to read from it.
   uint32_t usage =
       gpu::SHARED_IMAGE_USAGE_VIDEO_DECODE |
-      gpu::SHARED_IMAGE_USAGE_GLES2_READ | gpu::SHARED_IMAGE_USAGE_GLES2_WRITE |
-      gpu::SHARED_IMAGE_USAGE_RASTER | gpu::SHARED_IMAGE_USAGE_DISPLAY_READ |
-      gpu::SHARED_IMAGE_USAGE_SCANOUT;
+      gpu::SHARED_IMAGE_USAGE_GLES2_READ | gpu::SHARED_IMAGE_USAGE_RASTER |
+      gpu::SHARED_IMAGE_USAGE_DISPLAY_READ | gpu::SHARED_IMAGE_USAGE_SCANOUT;
 
   scoped_refptr<gpu::DXGISharedHandleState> dxgi_shared_handle_state;
   D3D11_TEXTURE2D_DESC desc = {};
diff --git a/media/media_options.gni b/media/media_options.gni
index 2deb6fc..d35bce5 100644
--- a/media/media_options.gni
+++ b/media/media_options.gni
@@ -11,7 +11,6 @@
 import("//media/gpu/args.gni")
 import("//testing/libfuzzer/fuzzer_test.gni")
 import("//third_party/libaom/options.gni")
-import("//third_party/libgav1/options.gni")
 
 # This flag sets defaults for the current generation of cast devices.
 is_cast_media_device = is_castos || is_cast_android
diff --git a/media/renderers/shared_image_video_frame_test_utils.cc b/media/renderers/shared_image_video_frame_test_utils.cc
index 3634d163..b2cacd0 100644
--- a/media/renderers/shared_image_video_frame_test_utils.cc
+++ b/media/renderers/shared_image_video_frame_test_utils.cc
@@ -98,8 +98,7 @@
   auto shared_image = sii->CreateSharedImage(
       viz::SinglePlaneFormat::kRGBA_8888, coded_size, gfx::ColorSpace(),
       kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType,
-      gpu::SHARED_IMAGE_USAGE_GLES2_READ | gpu::SHARED_IMAGE_USAGE_GLES2_WRITE,
-      "RGBAVideoFrame", pixels);
+      gpu::SHARED_IMAGE_USAGE_GLES2_READ, "RGBAVideoFrame", pixels);
 
   return CreateSharedImageFrame(
       std::move(context_provider), VideoPixelFormat::PIXEL_FORMAT_ABGR,
diff --git a/media/video/gpu_memory_buffer_video_frame_pool.cc b/media/video/gpu_memory_buffer_video_frame_pool.cc
index f64ebf25..48bb8b94 100644
--- a/media/video/gpu_memory_buffer_video_frame_pool.cc
+++ b/media/video/gpu_memory_buffer_video_frame_pool.cc
@@ -1257,7 +1257,6 @@
     // Bind the texture and create or rebind the image.
     if (gpu_memory_buffer && !plane_resource.shared_image) {
       uint32_t usage = gpu::SHARED_IMAGE_USAGE_GLES2_READ |
-                       gpu::SHARED_IMAGE_USAGE_GLES2_WRITE |
                        gpu::SHARED_IMAGE_USAGE_RASTER |
                        gpu::SHARED_IMAGE_USAGE_DISPLAY_READ |
                        gpu::SHARED_IMAGE_USAGE_SCANOUT;
diff --git a/media/video/renderable_gpu_memory_buffer_video_frame_pool.cc b/media/video/renderable_gpu_memory_buffer_video_frame_pool.cc
index a044e504..4de5c3cf 100644
--- a/media/video/renderable_gpu_memory_buffer_video_frame_pool.cc
+++ b/media/video/renderable_gpu_memory_buffer_video_frame_pool.cc
@@ -198,9 +198,8 @@
 #if BUILDFLAG(IS_MAC)
       gpu::SHARED_IMAGE_USAGE_MACOS_VIDEO_TOOLBOX |
 #endif
-      gpu::SHARED_IMAGE_USAGE_GLES2_READ | gpu::SHARED_IMAGE_USAGE_GLES2_WRITE |
-      gpu::SHARED_IMAGE_USAGE_RASTER | gpu::SHARED_IMAGE_USAGE_DISPLAY_READ |
-      gpu::SHARED_IMAGE_USAGE_SCANOUT;
+      gpu::SHARED_IMAGE_USAGE_GLES2_READ | gpu::SHARED_IMAGE_USAGE_RASTER |
+      gpu::SHARED_IMAGE_USAGE_DISPLAY_READ | gpu::SHARED_IMAGE_USAGE_SCANOUT;
 
   uint32_t texture_target = GL_TEXTURE_2D;
 #if BUILDFLAG(IS_MAC)
diff --git a/media/video/vpx_video_encoder.cc b/media/video/vpx_video_encoder.cc
index e6b7750b..b93df69 100644
--- a/media/video/vpx_video_encoder.cc
+++ b/media/video/vpx_video_encoder.cc
@@ -523,7 +523,7 @@
             const_cast<uint8_t*>(frame->visible_data(VideoFrame::kYPlane));
         vpx_image_.planes[VPX_PLANE_U] =
             const_cast<uint8_t*>(frame->visible_data(VideoFrame::kUVPlane));
-        // In NV12 Y and U samples are combined in one plane (bytes go YUYUYU),
+        // In NV12 U and V samples are combined in one plane (bytes go UVUVUV),
         // but libvpx treats them as two planes with the same stride but shifted
         // by one byte.
         vpx_image_.planes[VPX_PLANE_V] = vpx_image_.planes[VPX_PLANE_U] + 1;
diff --git a/net/http/transport_security_state.cc b/net/http/transport_security_state.cc
index a2474cd..ecd9907 100644
--- a/net/http/transport_security_state.cc
+++ b/net/http/transport_security_state.cc
@@ -460,9 +460,6 @@
     bool is_issued_by_known_root,
     const HashValueVector& public_key_hashes,
     const X509Certificate* validated_certificate_chain,
-    const X509Certificate* served_certificate_chain,
-    const SignedCertificateTimestampAndStatusList&
-        signed_certificate_timestamps,
     ct::CTPolicyCompliance policy_compliance) {
   using CTRequirementLevel = RequireCTDelegate::CTRequirementLevel;
   std::string hostname = host_port_pair.host();
diff --git a/net/http/transport_security_state.h b/net/http/transport_security_state.h
index 5430a6af..8e3493426 100644
--- a/net/http/transport_security_state.h
+++ b/net/http/transport_security_state.h
@@ -351,9 +351,6 @@
       bool is_issued_by_known_root,
       const HashValueVector& public_key_hashes,
       const X509Certificate* validated_certificate_chain,
-      const X509Certificate* served_certificate_chain,
-      const SignedCertificateTimestampAndStatusList&
-          signed_certificate_timestamps,
       ct::CTPolicyCompliance policy_compliance);
 
   // Assign a |Delegate| for persisting the transport security state. If
diff --git a/net/http/transport_security_state_unittest.cc b/net/http/transport_security_state_unittest.cc
index 5ee5fdf..c8fb1b3ae 100644
--- a/net/http/transport_security_state_unittest.cc
+++ b/net/http/transport_security_state_unittest.cc
@@ -1126,7 +1126,6 @@
     const TransportSecurityState::CTRequirementsStatus original_status =
         state.CheckCTRequirements(
             HostPortPair("www.example.com", 443), true, hashes, cert.get(),
-            cert.get(), SignedCertificateTimestampAndStatusList(),
             ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS);
 
     MockRequireCTDelegate always_require_delegate;
@@ -1137,25 +1136,21 @@
         TransportSecurityState::CT_REQUIREMENTS_NOT_MET,
         state.CheckCTRequirements(
             HostPortPair("www.example.com", 443), true, hashes, cert.get(),
-            cert.get(), SignedCertificateTimestampAndStatusList(),
             ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
     EXPECT_EQ(
         TransportSecurityState::CT_REQUIREMENTS_NOT_MET,
         state.CheckCTRequirements(
             HostPortPair("www.example.com", 443), true, hashes, cert.get(),
-            cert.get(), SignedCertificateTimestampAndStatusList(),
             ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS));
     EXPECT_EQ(
         TransportSecurityState::CT_REQUIREMENTS_MET,
         state.CheckCTRequirements(
             HostPortPair("www.example.com", 443), true, hashes, cert.get(),
-            cert.get(), SignedCertificateTimestampAndStatusList(),
             ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS));
     EXPECT_EQ(
         TransportSecurityState::CT_REQUIREMENTS_MET,
         state.CheckCTRequirements(
             HostPortPair("www.example.com", 443), true, hashes, cert.get(),
-            cert.get(), SignedCertificateTimestampAndStatusList(),
             ct::CTPolicyCompliance::CT_POLICY_BUILD_NOT_TIMELY));
 
     state.SetRequireCTDelegate(nullptr);
@@ -1163,7 +1158,6 @@
         original_status,
         state.CheckCTRequirements(
             HostPortPair("www.example.com", 443), true, hashes, cert.get(),
-            cert.get(), SignedCertificateTimestampAndStatusList(),
             ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
   }
 
@@ -1174,7 +1168,6 @@
     const TransportSecurityState::CTRequirementsStatus original_status =
         state.CheckCTRequirements(
             HostPortPair("www.example.com", 443), true, hashes, cert.get(),
-            cert.get(), SignedCertificateTimestampAndStatusList(),
             ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS);
 
     MockRequireCTDelegate never_require_delegate;
@@ -1185,13 +1178,11 @@
         TransportSecurityState::CT_NOT_REQUIRED,
         state.CheckCTRequirements(
             HostPortPair("www.example.com", 443), true, hashes, cert.get(),
-            cert.get(), SignedCertificateTimestampAndStatusList(),
             ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
     EXPECT_EQ(
         TransportSecurityState::CT_NOT_REQUIRED,
         state.CheckCTRequirements(
             HostPortPair("www.example.com", 443), true, hashes, cert.get(),
-            cert.get(), SignedCertificateTimestampAndStatusList(),
             ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS));
 
     state.SetRequireCTDelegate(nullptr);
@@ -1199,7 +1190,6 @@
         original_status,
         state.CheckCTRequirements(
             HostPortPair("www.example.com", 443), true, hashes, cert.get(),
-            cert.get(), SignedCertificateTimestampAndStatusList(),
             ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
   }
 }
@@ -1260,29 +1250,24 @@
   EXPECT_EQ(TransportSecurityState::CT_NOT_REQUIRED,
             state_.CheckCTRequirements(
                 HostPortPair("www.example.com", 443), true, hashes, cert.get(),
-                cert.get(), SignedCertificateTimestampAndStatusList(),
                 ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
   EXPECT_EQ(TransportSecurityState::CT_NOT_REQUIRED,
             state_.CheckCTRequirements(
                 HostPortPair("www.example.com", 443), true, hashes, cert.get(),
-                cert.get(), SignedCertificateTimestampAndStatusList(),
                 ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS));
   EXPECT_EQ(TransportSecurityState::CT_NOT_REQUIRED,
             state_.CheckCTRequirements(
                 HostPortPair("www.example.com", 443), true, hashes, cert.get(),
-                cert.get(), SignedCertificateTimestampAndStatusList(),
                 ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS));
   EXPECT_EQ(TransportSecurityState::CT_NOT_REQUIRED,
             state_.CheckCTRequirements(
                 HostPortPair("www.example.com", 443), true, hashes, cert.get(),
-                cert.get(), SignedCertificateTimestampAndStatusList(),
                 ct::CTPolicyCompliance::CT_POLICY_BUILD_NOT_TIMELY));
 
   state_.SetRequireCTDelegate(nullptr);
   EXPECT_EQ(TransportSecurityState::CT_NOT_REQUIRED,
             state_.CheckCTRequirements(
                 HostPortPair("www.example.com", 443), true, hashes, cert.get(),
-                cert.get(), SignedCertificateTimestampAndStatusList(),
                 ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
 }
 
diff --git a/net/log/net_log_event_type_list.h b/net/log/net_log_event_type_list.h
index 36ef7aff..652995a 100644
--- a/net/log/net_log_event_type_list.h
+++ b/net/log/net_log_event_type_list.h
@@ -1782,7 +1782,8 @@
 // This event is emitted whenever a platform notification is received that
 // could possibly trigger connection migration.
 //   {
-//     "signal": <Type of the platform notification>
+//     "signal": <Type of the platform notification>,
+//     "network": <The network that triggered the notification>,
 //   }
 EVENT_TYPE(QUIC_STREAM_FACTORY_PLATFORM_NOTIFICATION)
 
diff --git a/net/quic/crypto/proof_verifier_chromium.cc b/net/quic/crypto/proof_verifier_chromium.cc
index 70508bf1..dd7a3f1 100644
--- a/net/quic/crypto/proof_verifier_chromium.cc
+++ b/net/quic/crypto/proof_verifier_chromium.cc
@@ -505,8 +505,8 @@
           HostPortPair(hostname_, port_),
           cert_verify_result.is_issued_by_known_root,
           cert_verify_result.public_key_hashes,
-          cert_verify_result.verified_cert.get(), cert_.get(),
-          cert_verify_result.scts, cert_verify_result.policy_compliance);
+          cert_verify_result.verified_cert.get(),
+          cert_verify_result.policy_compliance);
 
   if (sct_auditing_delegate_) {
     sct_auditing_delegate_->MaybeEnqueueReport(
diff --git a/net/quic/quic_stream_factory.cc b/net/quic/quic_stream_factory.cc
index 03f6febe..cbcddcd 100644
--- a/net/quic/quic_stream_factory.cc
+++ b/net/quic/quic_stream_factory.cc
@@ -1615,9 +1615,13 @@
 void QuicStreamFactory::OnNetworkConnected(handles::NetworkHandle network) {
   CollectDataOnPlatformNotification(NETWORK_CONNECTED, network);
   if (params_.migrate_sessions_on_network_change_v2) {
-    net_log_.AddEventWithStringParams(
-        NetLogEventType::QUIC_STREAM_FACTORY_PLATFORM_NOTIFICATION, "signal",
-        "OnNetworkConnected");
+    net_log_.AddEvent(
+        NetLogEventType::QUIC_STREAM_FACTORY_PLATFORM_NOTIFICATION, [&] {
+          base::Value::Dict dict;
+          dict.Set("signal", "OnNetworkConnected");
+          dict.Set("network", base::NumberToString(network));
+          return dict;
+        });
   }
   // Broadcast network connected to all sessions.
   // If migration is not turned on, session will not migrate but collect data.
@@ -1633,9 +1637,13 @@
 void QuicStreamFactory::OnNetworkDisconnected(handles::NetworkHandle network) {
   CollectDataOnPlatformNotification(NETWORK_DISCONNECTED, network);
   if (params_.migrate_sessions_on_network_change_v2) {
-    net_log_.AddEventWithStringParams(
-        NetLogEventType::QUIC_STREAM_FACTORY_PLATFORM_NOTIFICATION, "signal",
-        "OnNetworkDisconnected");
+    net_log_.AddEvent(
+        NetLogEventType::QUIC_STREAM_FACTORY_PLATFORM_NOTIFICATION, [&] {
+          base::Value::Dict dict;
+          dict.Set("signal", "OnNetworkDisconnected");
+          dict.Set("network", base::NumberToString(network));
+          return dict;
+        });
   }
   // Broadcast network disconnected to all sessions.
   // If migration is not turned on, session will not migrate but collect data.
@@ -1671,9 +1679,13 @@
   default_network_ = network;
 
   if (params_.migrate_sessions_on_network_change_v2) {
-    net_log_.AddEventWithStringParams(
-        NetLogEventType::QUIC_STREAM_FACTORY_PLATFORM_NOTIFICATION, "signal",
-        "OnNetworkMadeDefault");
+    net_log_.AddEvent(
+        NetLogEventType::QUIC_STREAM_FACTORY_PLATFORM_NOTIFICATION, [&] {
+          base::Value::Dict dict;
+          dict.Set("signal", "OnNetworkMadeDefault");
+          dict.Set("network", base::NumberToString(network));
+          return dict;
+        });
   }
 
   auto it = all_sessions_.begin();
diff --git a/net/socket/ssl_client_socket_impl.cc b/net/socket/ssl_client_socket_impl.cc
index 27a46ab3..62ec6d1 100644
--- a/net/socket/ssl_client_socket_impl.cc
+++ b/net/socket/ssl_client_socket_impl.cc
@@ -1303,8 +1303,7 @@
       context_->transport_security_state()->CheckCTRequirements(
           host_and_port_, server_cert_verify_result_.is_issued_by_known_root,
           server_cert_verify_result_.public_key_hashes,
-          server_cert_verify_result_.verified_cert.get(), server_cert_.get(),
-          server_cert_verify_result_.scts,
+          server_cert_verify_result_.verified_cert.get(),
           server_cert_verify_result_.policy_compliance);
 
   if (context_->sct_auditing_delegate()) {
diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc
index c9f9c4c5..ccfe8d8 100644
--- a/net/spdy/spdy_session.cc
+++ b/net/spdy/spdy_session.cc
@@ -766,7 +766,6 @@
   switch (transport_security_state->CheckCTRequirements(
       HostPortPair(new_hostname, 0), ssl_info.is_issued_by_known_root,
       ssl_info.public_key_hashes, ssl_info.cert.get(),
-      ssl_info.unverified_cert.get(), ssl_info.signed_certificate_timestamps,
       ssl_info.ct_policy_compliance)) {
     case TransportSecurityState::CT_REQUIREMENTS_NOT_MET:
       return false;
diff --git a/services/network/network_context.cc b/services/network/network_context.cc
index ae6fef7..122dcc7b 100644
--- a/services/network/network_context.cc
+++ b/services/network/network_context.cc
@@ -1455,15 +1455,14 @@
 
 int NetworkContext::CheckCTRequirementsForSignedExchange(
     net::CertVerifyResult& cert_verify_result,
-    const net::X509Certificate& certificate,
     const net::HostPortPair& host_port_pair) {
   net::X509Certificate* verified_cert = cert_verify_result.verified_cert.get();
 
   net::TransportSecurityState::CTRequirementsStatus ct_requirement_status =
       url_request_context_->transport_security_state()->CheckCTRequirements(
           host_port_pair, cert_verify_result.is_issued_by_known_root,
-          cert_verify_result.public_key_hashes, verified_cert, &certificate,
-          cert_verify_result.scts, cert_verify_result.policy_compliance);
+          cert_verify_result.public_key_hashes, verified_cert,
+          cert_verify_result.policy_compliance);
 
   if (url_request_context_->sct_auditing_delegate()) {
     url_request_context_->sct_auditing_delegate()->MaybeEnqueueReport(
@@ -2897,7 +2896,7 @@
   if (result == net::OK) {
 #if BUILDFLAG(IS_CT_SUPPORTED)
     int ct_result = CheckCTRequirementsForSignedExchange(
-        *pending_cert_verify->result, *pending_cert_verify->certificate,
+        *pending_cert_verify->result,
         net::HostPortPair::FromURL(pending_cert_verify->url));
 #endif  // BUILDFLAG(IS_CT_SUPPORTED)
     net::TransportSecurityState::PKPStatus pin_validity =
diff --git a/services/network/network_context.h b/services/network/network_context.h
index b6ed916..3ef62e2a 100644
--- a/services/network/network_context.h
+++ b/services/network/network_context.h
@@ -745,7 +745,6 @@
   // in //net.
   int CheckCTRequirementsForSignedExchange(
       net::CertVerifyResult& cert_verify_result,
-      const net::X509Certificate& certificate,
       const net::HostPortPair& host_port_pair);
 #endif  // BUILDFLAG(IS_CT_SUPPORTED)
 
diff --git a/services/preferences/tracked/pref_hash_filter_unittest.cc b/services/preferences/tracked/pref_hash_filter_unittest.cc
index c284a60..46412a0f 100644
--- a/services/preferences/tracked/pref_hash_filter_unittest.cc
+++ b/services/preferences/tracked/pref_hash_filter_unittest.cc
@@ -459,7 +459,7 @@
   if (out_value) {
     EXPECT_TRUE(out_value->is_dict());
 
-    out_value = dictionary_.Find(split_path);
+    out_value = out_value->GetDict().Find(split_path);
     if (out_value) {
       EXPECT_TRUE(out_value->is_string());
 
@@ -629,6 +629,10 @@
         base::BindOnce(&PrefHashFilterTest::GetPrefsBack,
                        base::Unretained(this), expect_prefs_modifications),
         std::move(pref_store_contents_));
+    // `mock_pref_hash_store_` is updated over an in-process mojo interface,
+    // flush pending tasks to make sure everything is up to date after this
+    // call.
+    task_environment_.RunUntilIdle();
   }
 
   raw_ptr<MockPrefHashStore, DanglingUntriaged> mock_pref_hash_store_;
@@ -839,8 +843,7 @@
   ASSERT_EQ(PrefTrackingStrategy::SPLIT, stored_value_split.second);
 }
 
-// TODO(https://crbug.com/1401148): Reenable.
-TEST_P(PrefHashFilterTest, DISABLED_UnknownNullValue) {
+TEST_P(PrefHashFilterTest, UnknownNullValue) {
   ASSERT_FALSE(pref_store_contents_.contains(kAtomicPref));
   ASSERT_FALSE(pref_store_contents_.contains(kSplitPref));
   // nullptr values are always trusted by the PrefHashStore.
@@ -883,8 +886,7 @@
   ASSERT_TRUE(validated_atomic_pref->is_personal);
 }
 
-// TODO(https://crbug.com/1401148): Reenable.
-TEST_P(PrefHashFilterTest, DISABLED_InitialValueUnknown) {
+TEST_P(PrefHashFilterTest, InitialValueUnknown) {
   base::Value* string_value =
       pref_store_contents_.Set(kAtomicPref, "string value");
 
@@ -955,8 +957,7 @@
   }
 }
 
-// TODO(https://crbug.com/1401148): Reenable.
-TEST_P(PrefHashFilterTest, DISABLED_InitialValueTrustedUnknown) {
+TEST_P(PrefHashFilterTest, InitialValueTrustedUnknown) {
   base::Value* string_value = pref_store_contents_.Set(kAtomicPref, "test");
 
   auto* value = pref_store_contents_.Set(kSplitPref, base::Value::Dict());
@@ -1087,8 +1088,7 @@
   }
 }
 
-// TODO(https://crbug.com/1401148): Reenable.
-TEST_P(PrefHashFilterTest, DISABLED_EmptyCleared) {
+TEST_P(PrefHashFilterTest, EmptyCleared) {
   ASSERT_FALSE(pref_store_contents_.contains(kAtomicPref));
   ASSERT_FALSE(pref_store_contents_.contains(kSplitPref));
   mock_pref_hash_store_->SetCheckResult(kAtomicPref, ValueState::CLEARED);
@@ -1123,8 +1123,7 @@
   ASSERT_EQ(PrefTrackingStrategy::SPLIT, stored_split_value.second);
 }
 
-// TODO(https://crbug.com/1401148): Reenable.
-TEST_P(PrefHashFilterTest, DISABLED_InitialValueUnchangedLegacyId) {
+TEST_P(PrefHashFilterTest, InitialValueUnchangedLegacyId) {
   base::Value* string_value =
       pref_store_contents_.Set(kAtomicPref, "string value");
 
@@ -1182,8 +1181,7 @@
   VerifyRecordedReset(false);
 }
 
-// TODO(https://crbug.com/1401148): Reenable.
-TEST_P(PrefHashFilterTest, DISABLED_DontResetReportOnly) {
+TEST_P(PrefHashFilterTest, DontResetReportOnly) {
   base::Value* int_value1 = pref_store_contents_.Set(kAtomicPref, 1);
   base::Value* int_value2 = pref_store_contents_.Set(kAtomicPref2, 2);
   base::Value* report_only_val = pref_store_contents_.Set(kReportOnlyPref, 3);
@@ -1254,8 +1252,7 @@
   }
 }
 
-// TODO(https://crbug.com/1401148): Reenable.
-TEST_P(PrefHashFilterTest, DISABLED_CallFilterSerializeDataCallbacks) {
+TEST_P(PrefHashFilterTest, CallFilterSerializeDataCallbacks) {
   base::Value::Dict root_dict;
   base::Value::Dict dict_value;
   dict_value.Set("a", true);
@@ -1328,8 +1325,7 @@
       0u, mock_external_validation_hash_store_contents_->stored_hashes_count());
 }
 
-// TODO(https://crbug.com/1401148): Reenable.
-TEST_P(PrefHashFilterTest, DISABLED_ExternalValidationValueChanged) {
+TEST_P(PrefHashFilterTest, ExternalValidationValueChanged) {
   pref_store_contents_.Set(kAtomicPref, 1234);
 
   base::Value::Dict dict_value;
diff --git a/testing/buildbot/chromium.coverage.json b/testing/buildbot/chromium.coverage.json
index 13afd28..d228e03 100644
--- a/testing/buildbot/chromium.coverage.json
+++ b/testing/buildbot/chromium.coverage.json
@@ -8366,9 +8366,6 @@
     ]
   },
   "fuchsia-code-coverage": {
-    "additional_compile_targets": [
-      "chrome_pkg"
-    ],
     "gtest_tests": [
       {
         "args": [
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl
index 74468d5..b00754dc 100644
--- a/testing/buildbot/gn_isolate_map.pyl
+++ b/testing/buildbot/gn_isolate_map.pyl
@@ -419,10 +419,6 @@
     "label": "//:chrome_official_builder_no_unittests",
     "type": "additional_compile_target",
   },
-  "chrome_pkg": {
-    "label": "//chrome/app:chrome_pkg",
-    "type": "additional_compile_target",
-  },
   "chrome_private_code_test": {
     "label": "//chrome:chrome_private_code_test",
     "type": "generated_script",
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl
index df3164a..e183243 100644
--- a/testing/buildbot/waterfalls.pyl
+++ b/testing/buildbot/waterfalls.pyl
@@ -2347,9 +2347,6 @@
         },
       },
       'fuchsia-code-coverage': {
-        'additional_compile_targets': [
-          'chrome_pkg',
-        ],
         'test_suites': {
           'gtest_tests': 'fuchsia_gtests',
           'isolated_scripts': 'gpu_angle_fuchsia_unittests_isolated_scripts',
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index f12ee29..f71fe172 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -5570,6 +5570,22 @@
             ]
         }
     ],
+    "DeskProfiles": [
+        {
+            "platforms": [
+                "chromeos",
+                "chromeos_lacros"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled_20240214",
+                    "enable_features": [
+                        "DeskProfiles"
+                    ]
+                }
+            ]
+        }
+    ],
     "DesktopLinkCapturingPWAExperiment": [
         {
             "platforms": [
@@ -10127,6 +10143,21 @@
             ]
         }
     ],
+    "LanguagePacksBasePack": [
+        {
+            "platforms": [
+                "chromeos"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "HandwritingLibraryDlc"
+                    ]
+                }
+            ]
+        }
+    ],
     "LauncherGameSearchStudy": [
         {
             "platforms": [
diff --git a/third_party/angle b/third_party/angle
index d704273..bd5dce9 160000
--- a/third_party/angle
+++ b/third_party/angle
@@ -1 +1 @@
-Subproject commit d704273d78967f286c300d445bdc0eb9f43b2389
+Subproject commit bd5dce9a8e8525527501da49d7807130bb9e39a1
diff --git a/third_party/blink/public/mojom/mediastream/media_stream.mojom b/third_party/blink/public/mojom/mediastream/media_stream.mojom
index c193611..87a172a0 100644
--- a/third_party/blink/public/mojom/mediastream/media_stream.mojom
+++ b/third_party/blink/public/mojom/mediastream/media_stream.mojom
@@ -307,6 +307,19 @@
   GetZoomLevel(mojo_base.mojom.UnguessableToken device_id)
            => (int32? zoom_level, CapturedSurfaceControlResult result);
 
+  // Sets the zoom level of the captured tab.
+  //
+  // |device_id| identifies the captured tab.
+  // |zoom_level| is the zoom level to be set.
+  // |result| reports if the call was successful or what type of error occurred.
+  //
+  // TODO(crbug.com/1512609): Create a new device mojo interface to replace the
+  // use of the device_id token.
+  [EnableIfNot=is_android]
+  SetZoomLevel(mojo_base.mojom.UnguessableToken device_id,
+               int32 zoom_level)
+           => (CapturedSurfaceControlResult result);
+
   // Get a MediaStreamDevice metadata object which refers to the same flow of
   // media backing an existing MediaStreamDevice.
   //
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn
index c1974a6..9ab85837 100644
--- a/third_party/blink/renderer/core/BUILD.gn
+++ b/third_party/blink/renderer/core/BUILD.gn
@@ -1519,6 +1519,7 @@
                          "",
                          "scheduler_integration_tests")
   sources += rebase_path(blink_core_tests_script, "", "script")
+  sources += rebase_path(blink_core_tests_scroll, "", "scroll")
   sources +=
       rebase_path(blink_core_tests_speculation_rules, "", "speculation_rules")
   sources += rebase_path(blink_core_tests_streams, "", "streams")
diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
index f14f734..126f021 100644
--- a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
@@ -2550,14 +2550,17 @@
 
   const auto& list = To<CSSValueList>(value);
   DCHECK_LE(list.length(), 3u);
-  double sx = To<CSSPrimitiveValue>(list.Item(0)).GetDoubleValue();
+  double sx = To<CSSPrimitiveValue>(list.Item(0))
+                  .ComputeNumber(state.CssToLengthConversionData());
   double sy = sx;
   double sz = 1;
   if (list.length() >= 2) {
-    sy = To<CSSPrimitiveValue>(list.Item(1)).GetDoubleValue();
+    sy = To<CSSPrimitiveValue>(list.Item(1))
+             .ComputeNumber(state.CssToLengthConversionData());
   }
   if (list.length() == 3) {
-    sz = To<CSSPrimitiveValue>(list.Item(2)).GetDoubleValue();
+    sz = To<CSSPrimitiveValue>(list.Item(2))
+             .ComputeNumber(state.CssToLengthConversionData());
   }
 
   return ScaleTransformOperation::Create(sx, sy, sz,
diff --git a/third_party/blink/renderer/core/editing/spellcheck/spell_checker.cc b/third_party/blink/renderer/core/editing/spellcheck/spell_checker.cc
index aa85ebff..db77dd9 100644
--- a/third_party/blink/renderer/core/editing/spellcheck/spell_checker.cc
+++ b/third_party/blink/renderer/core/editing/spellcheck/spell_checker.cc
@@ -59,6 +59,7 @@
 #include "third_party/blink/renderer/core/loader/empty_clients.h"
 #include "third_party/blink/renderer/core/page/page.h"
 #include "third_party/blink/renderer/platform/heap/garbage_collected.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
 #include "third_party/blink/renderer/platform/text/text_break_iterator.h"
 #include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
 
@@ -494,8 +495,14 @@
 
   if (cancel)
     return;
-  GetFrame().GetEditor().ReplaceSelectionWithText(
-      text, false, false, InputEvent::InputType::kInsertReplacementText);
+
+  if (RuntimeEnabledFeatures::SpellCheckerReplaceRangeUseInsertTextEnabled()) {
+    GetFrame().GetEditor().InsertTextWithoutSendingTextEvent(
+        text, false, nullptr, InputEvent::InputType::kInsertReplacementText);
+  } else {
+    GetFrame().GetEditor().ReplaceSelectionWithText(
+        text, false, false, InputEvent::InputType::kInsertReplacementText);
+  }
 }
 
 void SpellChecker::RespondToChangedSelection() {
diff --git a/third_party/blink/renderer/core/html/forms/html_input_element.cc b/third_party/blink/renderer/core/html/forms/html_input_element.cc
index 736b36df..ae248f3 100644
--- a/third_party/blink/renderer/core/html/forms/html_input_element.cc
+++ b/third_party/blink/renderer/core/html/forms/html_input_element.cc
@@ -420,12 +420,12 @@
   }
 }
 
-void HTMLInputElement::UpdateType(const AtomicString& typeAttributeValue) {
+void HTMLInputElement::UpdateType(const AtomicString& type_attribute_value) {
   DCHECK(input_type_);
   DCHECK(input_type_view_);
 
   const AtomicString& new_type_name =
-      InputType::NormalizeTypeName(typeAttributeValue);
+      InputType::NormalizeTypeName(type_attribute_value);
   if (input_type_->FormControlTypeAsString() == new_type_name) {
     return;
   }
diff --git a/third_party/blink/renderer/core/scroll/scroll_animator_test.cc b/third_party/blink/renderer/core/scroll/scroll_animator_test.cc
index 3cf4b7e..bbc3260 100644
--- a/third_party/blink/renderer/core/scroll/scroll_animator_test.cc
+++ b/third_party/blink/renderer/core/scroll/scroll_animator_test.cc
@@ -39,6 +39,7 @@
 #include "third_party/blink/renderer/platform/heap/thread_state.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
+#include "third_party/blink/renderer/platform/testing/task_environment.h"
 #include "third_party/blink/renderer/platform/wtf/functional.h"
 #include "ui/gfx/geometry/point_f.h"
 #include "ui/gfx/geometry/rect.h"
@@ -190,6 +191,7 @@
 // TODO(skobes): Add unit tests for composited scrolling paths.
 
 TEST(ScrollAnimatorTest, MainThreadStates) {
+  test::TaskEnvironment task_environment;
   auto* scrollable_area =
       MakeGarbageCollected<MockScrollableAreaForAnimatorTest>(
           true, ScrollOffset(), ScrollOffset(1000, 1000));
@@ -248,6 +250,7 @@
 }
 
 TEST(ScrollAnimatorTest, MainThreadEnabled) {
+  test::TaskEnvironment task_environment;
   auto* scrollable_area =
       MakeGarbageCollected<MockScrollableAreaForAnimatorTest>(
           true, ScrollOffset(), ScrollOffset(1000, 1000));
@@ -339,6 +342,7 @@
 // Test that a smooth scroll offset animation is aborted when followed by a
 // non-smooth scroll offset animation.
 TEST(ScrollAnimatorTest, AnimatedScrollAborted) {
+  test::TaskEnvironment task_environment;
   auto* scrollable_area =
       MakeGarbageCollected<MockScrollableAreaForAnimatorTest>(
           true, ScrollOffset(), ScrollOffset(1000, 1000));
@@ -391,6 +395,7 @@
 // Test that a smooth scroll offset animation running on the compositor is
 // completed on the main thread.
 TEST(ScrollAnimatorTest, AnimatedScrollTakeover) {
+  test::TaskEnvironment task_environment;
   auto* scrollable_area =
       MakeGarbageCollected<MockScrollableAreaForAnimatorTest>(
           true, ScrollOffset(), ScrollOffset(1000, 1000));
@@ -447,6 +452,7 @@
 }
 
 TEST(ScrollAnimatorTest, Disabled) {
+  test::TaskEnvironment task_environment;
   auto* scrollable_area =
       MakeGarbageCollected<MockScrollableAreaForAnimatorTest>(
           false, ScrollOffset(), ScrollOffset(1000, 1000));
@@ -490,6 +496,7 @@
 // Test that cancelling an animation resets the animation state.
 // See crbug.com/598548.
 TEST(ScrollAnimatorTest, CancellingAnimationResetsState) {
+  test::TaskEnvironment task_environment;
   auto* scrollable_area =
       MakeGarbageCollected<MockScrollableAreaForAnimatorTest>(
           true, ScrollOffset(), ScrollOffset(1000, 1000));
@@ -562,6 +569,7 @@
 // Test that the callback passed to UserScroll function will be run when the
 // animation is canceled or finished when the scroll is sent to main thread.
 TEST(ScrollAnimatorTest, UserScrollCallBackAtAnimationFinishOnMainThread) {
+  test::TaskEnvironment task_environment;
   auto* scrollable_area =
       MakeGarbageCollected<MockScrollableAreaForAnimatorTest>(
           true, ScrollOffset(), ScrollOffset(1000, 1000));
@@ -642,6 +650,7 @@
 // Test that the callback passed to UserScroll function will be run when the
 // animation is canceled or finished when the scroll is sent to compositor.
 TEST(ScrollAnimatorTest, UserScrollCallBackAtAnimationFinishOnCompositor) {
+  test::TaskEnvironment task_environment;
   auto* scrollable_area =
       MakeGarbageCollected<MockScrollableAreaForAnimatorTest>(
           true, ScrollOffset(), ScrollOffset(1000, 1000));
@@ -696,6 +705,7 @@
 // Test the behavior when in WaitingToCancelOnCompositor and a new user scroll
 // happens.
 TEST(ScrollAnimatorTest, CancellingCompositorAnimation) {
+  test::TaskEnvironment task_environment;
   auto* scrollable_area =
       MakeGarbageCollected<MockScrollableAreaForAnimatorTest>(
           true, ScrollOffset(), ScrollOffset(1000, 1000));
@@ -784,6 +794,7 @@
 // This test verifies that impl only animation updates get cleared once they
 // are pushed to compositor animation host.
 TEST(ScrollAnimatorTest, ImplOnlyAnimationUpdatesCleared) {
+  test::TaskEnvironment task_environment;
   auto* scrollable_area =
       MakeGarbageCollected<MockScrollableAreaForAnimatorTest>(
           true, ScrollOffset(), ScrollOffset(1000, 1000));
@@ -824,6 +835,7 @@
 }
 
 TEST(ScrollAnimatorTest, MainThreadAnimationTargetAdjustment) {
+  test::TaskEnvironment task_environment;
   auto* scrollable_area =
       MakeGarbageCollected<MockScrollableAreaForAnimatorTest>(
           true, ScrollOffset(-100, -100), ScrollOffset(1000, 1000));
diff --git a/third_party/blink/renderer/core/scroll/scrollable_area_test.cc b/third_party/blink/renderer/core/scroll/scrollable_area_test.cc
index 0eb2c0b..3820135 100644
--- a/third_party/blink/renderer/core/scroll/scrollable_area_test.cc
+++ b/third_party/blink/renderer/core/scroll/scrollable_area_test.cc
@@ -19,6 +19,7 @@
 #include "third_party/blink/renderer/platform/heap/thread_state.h"
 #include "third_party/blink/renderer/platform/testing/paint_test_configurations.h"
 #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
+#include "third_party/blink/renderer/platform/testing/task_environment.h"
 #include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h"
 #include "third_party/blink/renderer/platform/wtf/functional.h"
 
@@ -57,7 +58,10 @@
 }  // namespace
 
 class ScrollableAreaTest : public testing::Test,
-                           public PaintTestConfigurations {};
+                           public PaintTestConfigurations {
+ private:
+  test::TaskEnvironment task_environment_;
+};
 
 INSTANTIATE_PAINT_TEST_SUITE_P(ScrollableAreaTest);
 
diff --git a/third_party/blink/renderer/core/scroll/scrollbar_theme_fluent_unittest.cc b/third_party/blink/renderer/core/scroll/scrollbar_theme_fluent_unittest.cc
index 6258103..076fb07e 100644
--- a/third_party/blink/renderer/core/scroll/scrollbar_theme_fluent_unittest.cc
+++ b/third_party/blink/renderer/core/scroll/scrollbar_theme_fluent_unittest.cc
@@ -13,6 +13,7 @@
 #include "third_party/blink/renderer/core/scroll/scrollbar.h"
 #include "third_party/blink/renderer/core/scroll/scrollbar_test_suite.h"
 #include "third_party/blink/renderer/core/testing/scoped_mock_overlay_scrollbars.h"
+#include "third_party/blink/renderer/platform/testing/task_environment.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/native_theme/native_theme_features.h"
 
@@ -90,6 +91,7 @@
     return mock_scrollable_area_;
   }
 
+  test::TaskEnvironment task_environment_;
   std::unique_ptr<ScrollbarThemeFluentMock> theme_;
 
  private:
diff --git a/third_party/blink/renderer/core/scroll/scrollbar_theme_overlay_test.cc b/third_party/blink/renderer/core/scroll/scrollbar_theme_overlay_test.cc
index 8d66eff..7f0b4ca 100644
--- a/third_party/blink/renderer/core/scroll/scrollbar_theme_overlay_test.cc
+++ b/third_party/blink/renderer/core/scroll/scrollbar_theme_overlay_test.cc
@@ -7,6 +7,7 @@
 #include "third_party/blink/renderer/core/scroll/scroll_types.h"
 #include "third_party/blink/renderer/core/scroll/scrollbar_test_suite.h"
 #include "third_party/blink/renderer/platform/heap/thread_state.h"
+#include "third_party/blink/renderer/platform/testing/task_environment.h"
 #include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h"
 
 namespace blink {
@@ -14,7 +15,10 @@
 using testing::NiceMock;
 using testing::Return;
 
-class ScrollbarThemeOverlayTest : public testing::Test {};
+class ScrollbarThemeOverlayTest : public testing::Test {
+ private:
+  test::TaskEnvironment task_environment_;
+};
 
 TEST_F(ScrollbarThemeOverlayTest, PaintInvalidation) {
   ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source.cc b/third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source.cc
index 1a35b98..ec1e97d 100644
--- a/third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source.cc
@@ -46,14 +46,15 @@
   NOTREACHED_NORETURN();
 }
 
-void OnSendWheelResult(base::OnceCallback<void(bool, const String&)> callback,
-                       CapturedSurfaceControlResult result) {
+void OnCapturedSurfaceControlResult(
+    base::OnceCallback<void(bool, const String&)> callback,
+    CapturedSurfaceControlResult result) {
   const String error_string = CscResultToString(result);
   std::move(callback).Run(/*success=*/error_string.empty(),
                           /*error=*/error_string);
 }
 
-void OnZoomControlResult(
+void OnGetZoomLevelResult(
     base::OnceCallback<void(absl::optional<int>, const String&)> callback,
     absl::optional<int> zoom_level,
     CapturedSurfaceControlResult result) {
@@ -253,7 +254,7 @@
       blink::mojom::blink::CapturedWheelAction::New(action->x(), action->y(),
                                                     action->wheelDeltaX(),
                                                     action->wheelDeltaY()),
-      WTF::BindOnce(&OnSendWheelResult, std::move(callback)));
+      WTF::BindOnce(&OnCapturedSurfaceControlResult, std::move(callback)));
 }
 
 void MediaStreamVideoCapturerSource::GetZoomLevel(
@@ -269,14 +270,24 @@
 
   GetMediaStreamDispatcherHost()->GetZoomLevel(
       session_id.value(),
-      WTF::BindOnce(&OnZoomControlResult, std::move(callback)));
+      WTF::BindOnce(&OnGetZoomLevelResult, std::move(callback)));
 }
 
 void MediaStreamVideoCapturerSource::SetZoomLevel(
     int zoom_level,
     base::OnceCallback<void(bool, const String&)> callback) {
-  // TODO(crbug.com/1466247): Forward to GetMediaStreamDispatcherHost.
-  std::move(callback).Run(false, "Not implemented.");
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+  const absl::optional<base::UnguessableToken>& session_id =
+      device().serializable_session_id();
+  if (!session_id.has_value()) {
+    std::move(callback).Run(false, "Missing session ID.");
+    return;
+  }
+
+  GetMediaStreamDispatcherHost()->SetZoomLevel(
+      session_id.value(), zoom_level,
+      WTF::BindOnce(&OnCapturedSurfaceControlResult, std::move(callback)));
 }
 
 void MediaStreamVideoCapturerSource::ApplySubCaptureTarget(
diff --git a/third_party/blink/renderer/modules/mediastream/mock_mojo_media_stream_dispatcher_host.h b/third_party/blink/renderer/modules/mediastream/mock_mojo_media_stream_dispatcher_host.h
index 015276b..78ee7ae 100644
--- a/third_party/blink/renderer/modules/mediastream/mock_mojo_media_stream_dispatcher_host.h
+++ b/third_party/blink/renderer/modules/mediastream/mock_mojo_media_stream_dispatcher_host.h
@@ -63,6 +63,10 @@
                     SendWheelCallback));
   MOCK_METHOD2(GetZoomLevel,
                void(const base::UnguessableToken&, GetZoomLevelCallback));
+  MOCK_METHOD3(SetZoomLevel,
+               void(const base::UnguessableToken&,
+                    int32_t,
+                    SetZoomLevelCallback));
   MOCK_METHOD2(FocusCapturedSurface, void(const WTF::String&, bool));
   MOCK_METHOD5(ApplySubCaptureTarget,
                void(const base::UnguessableToken&,
diff --git a/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc b/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc
index 26c3a60..4d2c475 100644
--- a/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc
+++ b/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc
@@ -193,7 +193,10 @@
   if (drawing_buffer_) {
     return drawing_buffer_->antialias();
   }
-  return webgl_context_->GetDrawingBuffer()->Multisample();
+  if (!webgl_context_->isContextLost()) {
+    return webgl_context_->GetDrawingBuffer()->Multisample();
+  }
+  return false;
 }
 
 XRViewport* XRWebGLLayer::getViewport(XRView* view) {
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index e586c2b..c2c52a69 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1247,11 +1247,8 @@
       origin_trial_type: "deprecation",
     },
     {
-      // Makes the default display value of date type <input> elements
-      // inline-block for cross-browser compatibility. Enabled in M122, should
-      // be safe to remove in M126.
       name: "DateInputInlineBlock",
-      status: "stable",
+      status: "test",
     },
     {
       // TODO(crbug.com/1396384) This is being disabled, very slowly, via
@@ -3616,6 +3613,10 @@
       status: "stable",
     },
     {
+      name: "SpellCheckerReplaceRangeUseInsertText",
+      status: "stable",
+    },
+    {
       name: "SrcsetMaxDensity",
       base_feature: "none",
     },
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index dea24b6..2ca799d3 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -549,11 +549,6 @@
 crbug.com/1370460 [ Mac ] external/wpt/svg/text/reftests/lang-attribute.svg [ Failure ]
 crbug.com/1370460 [ Mac ] external/wpt/svg/text/reftests/xml-lang-attribute.svg [ Failure ]
 
-# Temporarily disabled to unblock https://crrev.com/c/5131015
-crbug.com/1512108 http/tests/devtools/console/console-functions.js [ Failure Pass ]
-crbug.com/1512108 http/tests/devtools/console/console-tainted-globals.js [ Failure Pass ]
-crbug.com/1512108 http/tests/devtools/sources/debugger/properties-special.js [ Failure Pass ]
-
 # WPT backgrounds and borders tests. Note that there are many more in NeverFixTests
 # that should be investigated (see crbug.com/780700)
 crbug.com/492187 external/wpt/css/CSS2/backgrounds/background-intrinsic-004.xht [ Failure ]
@@ -5147,6 +5142,10 @@
 # Incomplete support for mouse wheel in test_driver.
 crbug.com/1285411 external/wpt/css/css-scroll-snap/input/mouse-wheel.html [ Timeout ]
 
+# Temporarily disable tests to land https://crrev.com/c/5131512
+crbug.com/1509336 http/tests/devtools/har-importer.js [ Failure Pass ]
+crbug.com/1509336 http/tests/devtools/network/json-preview.js [ Failure Pass ]
+crbug.com/1509336 http/tests/devtools/network/network-choose-preview-view.js [ Failure Pass ]
 
 # Interop PE 2022-2023 investigation
 crbug.com/269917 external/wpt/uievents/mouse/cancel-mousedown-in-subframe.html [ Timeout ]
@@ -6867,6 +6866,9 @@
 fast/events/download-on-alt-click.html [ Pass Timeout ]
 fast/events/simulated-click-by-alt-enter.html [ Failure Pass ]
 
+# Need to support math functions with % resolution in ConsumeNumberOrPercent
+crbug.com/1505817 external/wpt/css/css-values/progress-computed.tentative.html [ Crash Failure ]
+
 # Failing on WebKit Linux MSAN
 crbug.com/1510005 [ Linux ] external/wpt/css/filter-effects/backdrop-filter-svg.html [ Crash Failure Pass Timeout ]
 crbug.com/1510005 [ Linux ] virtual/scalefactor200/external/wpt/css/filter-effects/backdrop-filter-svg.html [ Crash Failure Pass Timeout ]
@@ -6880,3 +6882,7 @@
 # TODO(crbug.com/1496375): Re-enable these tests.
 crbug.com/1496375 [ Linux ] http/tests/loading/image-picture-download-after-shrink.html [ Failure Pass ]
 crbug.com/1496375 [ Mac ] http/tests/loading/image-picture-download-after-shrink.html [ Failure Pass ]
+
+# Gardener 2023-12-19
+crbug.com/1512897 [ Linux ] external/wpt/webdriver/tests/bidi/network/combined/network_events.py [ Failure ]
+crbug.com/1512119 [ Linux ] external/wpt/webdriver/tests/classic/perform_actions/pointer_touch.py [ Failure ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites
index bf5e0f78..4db30ac 100644
--- a/third_party/blink/web_tests/VirtualTestSuites
+++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -800,21 +800,6 @@
     "expires": "Jul 1, 2023"
   },
   {
-    "prefix": "css-text-autospace",
-    "owners": [
-      "kojii@chromium.org",
-      "lingqi@chromium.org"
-    ],
-    "platforms": ["Linux", "Mac", "Win"],
-    "bases": [
-      "external/wpt/css/css-text/text-autospace/"
-    ],
-    "args": [
-      "--enable-blink-features=CSSTextAutoSpace",
-      "--disable-threaded-compositing", "--disable-threaded-animation"],
-    "expires": "June 1, 2024"
-  },
-  {
     "prefix": "css-sign-related-functions-disabled",
     "owners": ["seokho@chromium.org", "sakhapov@chromium.org"],
     "platforms": ["Linux", "Mac", "Win"],
diff --git a/third_party/blink/web_tests/external/wpt/css/css-values/progress-computed.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-values/progress-computed.tentative.html
index 2f564fa1..2ef0999 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-values/progress-computed.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-values/progress-computed.tentative.html
@@ -34,4 +34,5 @@
 test_math_used('calc(progress(sign(1001em - 10lh * progress(100px from 2rex to 10ex)) * 20em from 2rem to 12em) * 30)', '60', {prop:'flex-grow', type:'number'});
 test_math_used('calc(progress(sign(1001em - 10lh * progress(100px from 2rex to 10ex)) * 20em from 2rem to 12em) / 4)', '0.5', {prop:'flex-grow', type:'number'});
 test_math_used('calc(progress(sign(1001em - 10lh * progress(100px from 2rex to 10ex)) * 20em from 2rem to 12em) * 4)', '8', {prop:'column-count', type:'number'});
+test_math_used('calc(progress(sign(1001em - 10lh * progress(100px from 2rex to 10ex)) * 20em from 2rem to 12em) * 2)', '4', {prop:'scale'});
 </script>
diff --git a/third_party/blink/web_tests/fast/events/inputevents/inputevent-spellcheck.html b/third_party/blink/web_tests/fast/events/inputevents/inputevent-spellcheck.html
index fbc29156..145d7ad 100644
--- a/third_party/blink/web_tests/fast/events/inputevents/inputevent-spellcheck.html
+++ b/third_party/blink/web_tests/fast/events/inputevents/inputevent-spellcheck.html
@@ -16,13 +16,23 @@
       internals.setMarker(document, selection.getRangeAt(0), 'Spelling');
       const editable = document.getElementById('editable');
 
+      let beforeinputDispatched = false;
       editable.addEventListener('beforeinput', (event) => {
+        beforeinputDispatched = true;
         assert_equals(event.inputType, 'insertReplacementText');
         assert_equals(event.dataTransfer.getData('text/plain'), 'apple');
         assert_equals(event.getTargetRanges().length, 1);
       });
 
+      let inputDispatched = false;
+      editable.addEventListener('input', (event) => {
+        inputDispatched = true;
+      });
+
       internals.replaceMisspelled(document, 'apple');
+
+      assert_true(beforeinputDispatched);
+      assert_true(inputDispatched);
     },
     '<div contenteditable id="editable">apple| </div>');
 }, 'spellcheck-replace-in-contenteditable');
@@ -31,6 +41,96 @@
   assert_not_equals(window.internals,
                     undefined,
                     'This test requires internals.');
+  assert_selection(
+    [
+      '<div contenteditable>',
+        '<span style="color: rgb(255, 0, 0);">',
+          'this is a ^appla|.',
+        '</span>',
+      '</div>',
+    ],
+    selection => {
+      const document = selection.document;
+      internals.setMarker(document, selection.getRangeAt(0), 'Spelling');
+      const editable = document.querySelector('div');
+
+      let beforeinputDispatched = false;
+      editable.addEventListener('beforeinput', (event) => {
+        beforeinputDispatched = true;
+        assert_equals(event.inputType, 'insertReplacementText');
+        assert_equals(event.dataTransfer.getData('text/plain'), 'apple');
+        assert_equals(event.getTargetRanges().length, 1);
+      });
+
+      let inputDispatched = false;
+      editable.addEventListener('input', (event) => {
+        inputDispatched = true;
+      });
+
+      internals.replaceMisspelled(document, 'apple');
+
+      assert_true(beforeinputDispatched);
+      assert_true(inputDispatched);
+    },
+    [
+      '<div contenteditable>',
+        '<span style="color: rgb(255, 0, 0);">',
+          'this is a apple|.',
+        '</span>',
+      '</div>',
+    ],
+  );
+}, 'spellcheck-replace-contenteditable-with-rgb-color.');
+
+test(() => {
+  assert_not_equals(window.internals,
+                    undefined,
+                    'This test requires internals.');
+  assert_selection(
+    [
+      '<div contenteditable style="--darkColor__06400c: #a3da9b;">',
+        '<span style="color: var(--darkColor__06400c);">',
+          'this is a ^appla|.',
+        '</span>',
+      '</div>',
+    ],
+    selection => {
+      const document = selection.document;
+      internals.setMarker(document, selection.getRangeAt(0), 'Spelling');
+      const editable = document.querySelector('div');
+
+      let beforeinputDispatched = false;
+      editable.addEventListener('beforeinput', (event) => {
+        beforeinputDispatched = true;
+        assert_equals(event.inputType, 'insertReplacementText');
+        assert_equals(event.dataTransfer.getData('text/plain'), 'apple');
+        assert_equals(event.getTargetRanges().length, 1);
+      });
+
+      let inputDispatched = false;
+      editable.addEventListener('input', (event) => {
+        inputDispatched = true;
+      });
+
+      internals.replaceMisspelled(document, 'apple');
+
+      assert_true(beforeinputDispatched);
+      assert_true(inputDispatched);
+    },
+    [
+      '<div contenteditable style="--darkColor__06400c: #a3da9b;">',
+        '<span style="color: var(--darkColor__06400c);">',
+          'this is a apple|.',
+        '</span>',
+      '</div>',
+    ],
+  );
+}, 'spellcheck-replace-contenteditable-with-css-variables');
+
+test(() => {
+  assert_not_equals(window.internals,
+                    undefined,
+                    'This test requires internals.');
 
   assert_selection(
     '<textarea id="ta">^appla| </textarea>',
@@ -43,13 +143,23 @@
       const range = selection1.getRangeAt(0);
       internals.setMarker(document, range, 'Spelling');
 
+      let beforeinputDispatched = false;
       textarea.addEventListener('beforeinput', (event) => {
+        beforeinputDispatched = true;
         assert_equals(event.inputType, 'insertReplacementText');
         assert_equals(event.data, 'apple');
         assert_equals(event.getTargetRanges().length, 0);
       });
 
+      let inputDispatched = false;
+      textarea.addEventListener('input', (event) => {
+        inputDispatched = true;
+      });
+
       internals.replaceMisspelled(document, 'apple');
+
+      assert_true(beforeinputDispatched);
+      assert_true(inputDispatched);
     },
     '<textarea id="ta">apple| </textarea>');
 }, 'spellcheck-replace-in-textarea');
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/console-functions-expected.txt b/third_party/blink/web_tests/http/tests/devtools/console/console-functions-expected.txt
index a26b67e..255d079 100644
--- a/third_party/blink/web_tests/http/tests/devtools/console/console-functions-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/console/console-functions-expected.txt
@@ -6,7 +6,7 @@
     caller: null
     length: 0
     name: "simple"
-    prototype: {constructor: ƒ}
+    prototype: {}
     [[FunctionLocation]]: console-functions.js:15
     [[Prototype]]: ƒ ()
     [[Scopes]]: Scopes[1]
@@ -36,7 +36,7 @@
     caller: null
     length: 0
     name: ""
-    prototype: {constructor: ƒ}
+    prototype: {}
     [[FunctionLocation]]: console-functions.js:18
     [[Prototype]]: ƒ ()
     [[Scopes]]: Scopes[1]
@@ -46,7 +46,7 @@
     caller: null
     length: 2
     name: ""
-    prototype: {constructor: ƒ}
+    prototype: {}
     [[FunctionLocation]]: console-functions.js:19
     [[Prototype]]: ƒ ()
     [[Scopes]]: Scopes[1]
@@ -56,7 +56,7 @@
     caller: null
     length: 1
     name: "namedArgs"
-    prototype: {constructor: ƒ}
+    prototype: {}
     [[FunctionLocation]]: console-functions.js:20
     [[Prototype]]: ƒ ()
     [[Scopes]]: Scopes[1]
@@ -66,7 +66,7 @@
     caller: null
     length: 2
     name: "namedArgs2"
-    prototype: {constructor: ƒ}
+    prototype: {}
     [[FunctionLocation]]: console-functions.js:21
     [[Prototype]]: ƒ ()
     [[Scopes]]: Scopes[1]
@@ -76,7 +76,7 @@
     caller: null
     length: 1
     name: ""
-    prototype: {constructor: ƒ}
+    prototype: {}
     [[FunctionLocation]]: console-functions.js:22
     [[Prototype]]: ƒ ()
     [[Scopes]]: Scopes[1]
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/console-tainted-globals-expected.txt b/third_party/blink/web_tests/http/tests/devtools/console/console-tainted-globals-expected.txt
index adba69d..8d623cc 100644
--- a/third_party/blink/web_tests/http/tests/devtools/console/console-tainted-globals-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/console/console-tainted-globals-expected.txt
@@ -9,7 +9,7 @@
 testOverriddenArrayPushAndMathMax()
 (3) [1, 2, 3]
 testOverriddenConstructorName()
-{constructor: {…}}
+{}
 testThrowConstructorName()
 {}
 testOverriddenIsFinite()
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger/properties-special-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger/properties-special-expected.txt
index df3bf47..d76a06c2 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger/properties-special-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger/properties-special-expected.txt
@@ -7,7 +7,7 @@
     caller: null
     length: 2
     name: ""
-    prototype: {constructor: ƒ}
+    prototype: {}
     [[FunctionLocation]]: properties-special.js:14
     [[Prototype]]: ƒ ()
     [[Scopes]]: Scopes[1]
diff --git a/third_party/blink/web_tests/platform/linux/virtual/css-text-autospace/fast/dynamic/text-combine-expected.png b/third_party/blink/web_tests/platform/linux/virtual/css-text-autospace/fast/dynamic/text-combine-expected.png
deleted file mode 100644
index d695c7cb..0000000
--- a/third_party/blink/web_tests/platform/linux/virtual/css-text-autospace/fast/dynamic/text-combine-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/css-text-autospace/virtual/text-antialias/justify-ideograph-leading-expansion-expected.png b/third_party/blink/web_tests/platform/linux/virtual/css-text-autospace/virtual/text-antialias/justify-ideograph-leading-expansion-expected.png
deleted file mode 100644
index 5ebb15f..0000000
--- a/third_party/blink/web_tests/platform/linux/virtual/css-text-autospace/virtual/text-antialias/justify-ideograph-leading-expansion-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac13-arm64/virtual/css-text-autospace/virtual/text-antialias/justify-ideograph-leading-expansion-expected.png b/third_party/blink/web_tests/platform/mac-mac13-arm64/virtual/css-text-autospace/virtual/text-antialias/justify-ideograph-leading-expansion-expected.png
deleted file mode 100644
index 5ebb15f..0000000
--- a/third_party/blink/web_tests/platform/mac-mac13-arm64/virtual/css-text-autospace/virtual/text-antialias/justify-ideograph-leading-expansion-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/css-text-autospace/fast/dynamic/text-combine-expected.png b/third_party/blink/web_tests/platform/mac/virtual/css-text-autospace/fast/dynamic/text-combine-expected.png
deleted file mode 100644
index a5914181..0000000
--- a/third_party/blink/web_tests/platform/mac/virtual/css-text-autospace/fast/dynamic/text-combine-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/css-text-autospace/virtual/text-antialias/justify-ideograph-leading-expansion-expected.png b/third_party/blink/web_tests/platform/mac/virtual/css-text-autospace/virtual/text-antialias/justify-ideograph-leading-expansion-expected.png
deleted file mode 100644
index a614ed0..0000000
--- a/third_party/blink/web_tests/platform/mac/virtual/css-text-autospace/virtual/text-antialias/justify-ideograph-leading-expansion-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/css-text-autospace/fast/dynamic/text-combine-expected.png b/third_party/blink/web_tests/platform/win/virtual/css-text-autospace/fast/dynamic/text-combine-expected.png
deleted file mode 100644
index 64968f5..0000000
--- a/third_party/blink/web_tests/platform/win/virtual/css-text-autospace/fast/dynamic/text-combine-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/css-text-autospace/virtual/text-antialias/justify-ideograph-leading-expansion-expected.png b/third_party/blink/web_tests/platform/win/virtual/css-text-autospace/virtual/text-antialias/justify-ideograph-leading-expansion-expected.png
deleted file mode 100644
index 7456172..0000000
--- a/third_party/blink/web_tests/platform/win/virtual/css-text-autospace/virtual/text-antialias/justify-ideograph-leading-expansion-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/virtual/css-text-autospace/README.md b/third_party/blink/web_tests/virtual/css-text-autospace/README.md
deleted file mode 100644
index 14bca1a0..0000000
--- a/third_party/blink/web_tests/virtual/css-text-autospace/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-Tests for text-autospace property that requires --enable-blink-features=CSSTextAutoSpace.
-This property changes the default behavior, so it is disabled by default in web
-tests.
diff --git a/third_party/blink/web_tests/virtual/css-text-autospace/fast/css/getComputedStyle/computed-style-listing-expected.txt b/third_party/blink/web_tests/virtual/css-text-autospace/fast/css/getComputedStyle/computed-style-listing-expected.txt
deleted file mode 100644
index 29a011e..0000000
--- a/third_party/blink/web_tests/virtual/css-text-autospace/fast/css/getComputedStyle/computed-style-listing-expected.txt
+++ /dev/null
@@ -1,404 +0,0 @@
-This test documents all computed styles on a div element.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
--webkit-border-horizontal-spacing: 0px
--webkit-border-image: none
--webkit-border-vertical-spacing: 0px
--webkit-box-align: stretch
--webkit-box-decoration-break: slice
--webkit-box-direction: normal
--webkit-box-flex: 0
--webkit-box-ordinal-group: 1
--webkit-box-orient: horizontal
--webkit-box-pack: start
--webkit-box-reflect: none
--webkit-font-smoothing: auto
--webkit-line-break: auto
--webkit-line-clamp: none
--webkit-locale: auto
--webkit-mask-box-image: none
--webkit-mask-box-image-outset: 0
--webkit-mask-box-image-repeat: stretch
--webkit-mask-box-image-slice: 0 fill
--webkit-mask-box-image-source: none
--webkit-mask-box-image-width: auto
--webkit-mask-composite: source-over
--webkit-mask-position: 0% 0%
--webkit-mask-position-x: 0%
--webkit-mask-position-y: 0%
--webkit-mask-repeat: repeat
--webkit-print-color-adjust: economy
--webkit-rtl-ordering: logical
--webkit-text-combine: none
--webkit-text-decorations-in-effect: none
--webkit-text-fill-color: rgb(0, 0, 0)
--webkit-text-orientation: vertical-right
--webkit-text-security: none
--webkit-text-stroke-color: rgb(0, 0, 0)
--webkit-text-stroke-width: 0px
--webkit-user-drag: auto
--webkit-user-modify: read-only
--webkit-writing-mode: horizontal-tb
-accent-color: auto
-align-content: normal
-align-items: normal
-align-self: auto
-alignment-baseline: auto
-anchor-default: implicit
-anchor-name: none
-animation-composition: replace
-animation-delay: 0s
-animation-direction: normal
-animation-duration: 0s
-animation-fill-mode: none
-animation-iteration-count: 1
-animation-name: none
-animation-play-state: running
-animation-range-end: normal
-animation-range-start: normal
-animation-timeline: auto
-animation-timing-function: ease
-app-region: none
-appearance: none
-backdrop-filter: none
-backface-visibility: visible
-background-attachment: scroll
-background-blend-mode: normal
-background-clip: border-box
-background-color: rgba(0, 0, 0, 0)
-background-image: none
-background-origin: padding-box
-background-position: 0% 0%
-background-position-x: 0%
-background-position-y: 0%
-background-repeat: repeat
-background-size: auto
-baseline-shift: 0px
-baseline-source: auto
-block-size: 0px
-border-block-end-color: rgb(0, 0, 0)
-border-block-end-style: none
-border-block-end-width: 0px
-border-block-start-color: rgb(0, 0, 0)
-border-block-start-style: none
-border-block-start-width: 0px
-border-bottom-color: rgb(0, 0, 0)
-border-bottom-left-radius: 0px
-border-bottom-right-radius: 0px
-border-bottom-style: none
-border-bottom-width: 0px
-border-collapse: separate
-border-end-end-radius: 0px
-border-end-start-radius: 0px
-border-image-outset: 0
-border-image-repeat: stretch
-border-image-slice: 100%
-border-image-source: none
-border-image-width: 1
-border-inline-end-color: rgb(0, 0, 0)
-border-inline-end-style: none
-border-inline-end-width: 0px
-border-inline-start-color: rgb(0, 0, 0)
-border-inline-start-style: none
-border-inline-start-width: 0px
-border-left-color: rgb(0, 0, 0)
-border-left-style: none
-border-left-width: 0px
-border-right-color: rgb(0, 0, 0)
-border-right-style: none
-border-right-width: 0px
-border-spacing: 0px 0px
-border-start-end-radius: 0px
-border-start-start-radius: 0px
-border-top-color: rgb(0, 0, 0)
-border-top-left-radius: 0px
-border-top-right-radius: 0px
-border-top-style: none
-border-top-width: 0px
-bottom: auto
-box-shadow: none
-box-sizing: content-box
-break-after: auto
-break-before: auto
-break-inside: auto
-buffered-rendering: auto
-caption-side: top
-caret-color: rgb(0, 0, 0)
-clear: none
-clip: auto
-clip-path: none
-clip-rule: nonzero
-color: rgb(0, 0, 0)
-color-interpolation: srgb
-color-interpolation-filters: linearrgb
-color-rendering: auto
-column-count: auto
-column-gap: normal
-column-rule-color: rgb(0, 0, 0)
-column-rule-style: none
-column-rule-width: 0px
-column-span: none
-column-width: auto
-contain-intrinsic-block-size: none
-contain-intrinsic-height: none
-contain-intrinsic-inline-size: none
-contain-intrinsic-size: none
-contain-intrinsic-width: none
-container-name: none
-container-type: normal
-content: normal
-cursor: auto
-cx: 0px
-cy: 0px
-d: none
-direction: ltr
-display: block
-dominant-baseline: auto
-dynamic-range-limit: high
-empty-cells: show
-field-sizing: fixed
-fill: rgb(0, 0, 0)
-fill-opacity: 1
-fill-rule: nonzero
-filter: none
-flex-basis: auto
-flex-direction: row
-flex-grow: 0
-flex-shrink: 1
-flex-wrap: nowrap
-float: none
-flood-color: rgb(0, 0, 0)
-flood-opacity: 1
-font-kerning: auto
-font-optical-sizing: auto
-font-palette: normal
-font-size: 16px
-font-size-adjust: none
-font-stretch: 100%
-font-style: normal
-font-synthesis-small-caps: auto
-font-synthesis-style: auto
-font-synthesis-weight: auto
-font-variant: normal
-font-variant-alternates: normal
-font-variant-caps: normal
-font-variant-east-asian: normal
-font-variant-ligatures: normal
-font-variant-numeric: normal
-font-variant-position: normal
-font-weight: 400
-grid-auto-columns: auto
-grid-auto-flow: row
-grid-auto-rows: auto
-grid-column-end: auto
-grid-column-start: auto
-grid-row-end: auto
-grid-row-start: auto
-grid-template-areas: none
-grid-template-columns: none
-grid-template-rows: none
-height: 0px
-hyphenate-character: auto
-hyphenate-limit-chars: auto
-hyphens: manual
-image-orientation: from-image
-image-rendering: auto
-initial-letter: normal
-inline-size: 769px
-inset-block-end: auto
-inset-block-start: auto
-inset-inline-end: auto
-inset-inline-start: auto
-isolation: auto
-justify-content: normal
-justify-items: normal
-justify-self: auto
-left: auto
-letter-spacing: normal
-lighting-color: rgb(255, 255, 255)
-line-break: auto
-line-height: normal
-list-style-image: none
-list-style-position: outside
-list-style-type: disc
-margin-block-end: 0px
-margin-block-start: 0px
-margin-bottom: 0px
-margin-inline-end: 0px
-margin-inline-start: 0px
-margin-left: 0px
-margin-right: 0px
-margin-top: 0px
-marker-end: none
-marker-mid: none
-marker-start: none
-mask-clip: border-box
-mask-image: none
-mask-origin: border-box
-mask-size: auto
-mask-type: luminance
-math-depth: 0
-math-shift: normal
-math-style: normal
-max-block-size: none
-max-height: none
-max-inline-size: none
-max-width: none
-min-block-size: 0px
-min-height: 0px
-min-inline-size: 0px
-min-width: 0px
-mix-blend-mode: normal
-object-fit: fill
-object-position: 50% 50%
-object-view-box: none
-offset-anchor: auto
-offset-distance: 0px
-offset-path: none
-offset-position: normal
-offset-rotate: auto 0deg
-opacity: 1
-order: 0
-orphans: 2
-outline-color: rgb(0, 0, 0)
-outline-offset: 0px
-outline-style: none
-outline-width: 0px
-overflow: visible
-overflow-anchor: auto
-overflow-block: visible
-overflow-clip-margin: 0px
-overflow-inline: visible
-overflow-wrap: normal
-overflow-x: visible
-overflow-y: visible
-overlay: none
-overscroll-behavior-block: auto
-overscroll-behavior-inline: auto
-padding-block-end: 0px
-padding-block-start: 0px
-padding-bottom: 0px
-padding-inline-end: 0px
-padding-inline-start: 0px
-padding-left: 0px
-padding-right: 0px
-padding-top: 0px
-paint-order: normal
-perspective: none
-perspective-origin: 384.5px 0px
-pointer-events: auto
-popover-hide-delay: infinity * 1s
-popover-show-delay: 0.5s
-position: static
-position-fallback: none
-position-fallback-bounds: normal
-r: 0px
-resize: none
-right: auto
-rotate: none
-row-gap: normal
-ruby-position: over
-rx: auto
-ry: auto
-scale: none
-scroll-behavior: auto
-scroll-margin-block-end: 0px
-scroll-margin-block-start: 0px
-scroll-margin-inline-end: 0px
-scroll-margin-inline-start: 0px
-scroll-padding-block-end: auto
-scroll-padding-block-start: auto
-scroll-padding-inline-end: auto
-scroll-padding-inline-start: auto
-scroll-start-block: auto
-scroll-start-inline: auto
-scroll-start-target-block: none
-scroll-start-target-inline: none
-scroll-start-target-x: none
-scroll-start-target-y: none
-scroll-start-x: auto
-scroll-start-y: auto
-scroll-timeline-axis: block
-scroll-timeline-name: none
-scrollbar-color: auto
-scrollbar-gutter: auto
-scrollbar-width: auto
-shape-image-threshold: 0
-shape-margin: 0px
-shape-outside: none
-shape-rendering: auto
-speak: normal
-stop-color: rgb(0, 0, 0)
-stop-opacity: 1
-stroke: none
-stroke-dasharray: none
-stroke-dashoffset: 0px
-stroke-linecap: butt
-stroke-linejoin: miter
-stroke-miterlimit: 4
-stroke-opacity: 1
-stroke-width: 1px
-tab-size: 8
-table-layout: auto
-text-align: start
-text-align-last: auto
-text-anchor: start
-text-autospace: normal
-text-box-trim: none
-text-decoration: none solid rgb(0, 0, 0)
-text-decoration-color: rgb(0, 0, 0)
-text-decoration-line: none
-text-decoration-skip-ink: auto
-text-decoration-style: solid
-text-emphasis-color: rgb(0, 0, 0)
-text-emphasis-position: over
-text-emphasis-style: none
-text-indent: 0px
-text-overflow: clip
-text-rendering: auto
-text-shadow: none
-text-size-adjust: auto
-text-transform: none
-text-underline-position: auto
-text-wrap: wrap
-timeline-scope: none
-toggle-group: none
-toggle-root: none
-toggle-trigger: none
-toggle-visibility: normal
-top: auto
-touch-action: auto
-transform: none
-transform-origin: 384.5px 0px
-transform-style: flat
-transition-behavior: normal
-transition-delay: 0s
-transition-duration: 0s
-transition-property: all
-transition-timing-function: ease
-translate: none
-unicode-bidi: normal
-user-select: auto
-vector-effect: none
-vertical-align: baseline
-view-timeline-axis: block
-view-timeline-inset: auto
-view-timeline-name: none
-view-transition-name: none
-visibility: visible
-white-space-collapse: collapse
-widows: 2
-width: 769px
-will-change: auto
-word-break: normal
-word-spacing: 0px
-writing-mode: horizontal-tb
-x: 0px
-y: 0px
-z-index: auto
-zoom: 1
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/blink/web_tests/virtual/css-text-autospace/fast/css/getComputedStyle/computed-style-without-renderer-listing-expected.txt b/third_party/blink/web_tests/virtual/css-text-autospace/fast/css/getComputedStyle/computed-style-without-renderer-listing-expected.txt
deleted file mode 100644
index acbc2158df..0000000
--- a/third_party/blink/web_tests/virtual/css-text-autospace/fast/css/getComputedStyle/computed-style-without-renderer-listing-expected.txt
+++ /dev/null
@@ -1,404 +0,0 @@
-This test documents all computed styles on a display: none element.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
--webkit-border-horizontal-spacing: 0px
--webkit-border-image: none
--webkit-border-vertical-spacing: 0px
--webkit-box-align: stretch
--webkit-box-decoration-break: slice
--webkit-box-direction: normal
--webkit-box-flex: 0
--webkit-box-ordinal-group: 1
--webkit-box-orient: horizontal
--webkit-box-pack: start
--webkit-box-reflect: none
--webkit-font-smoothing: auto
--webkit-line-break: auto
--webkit-line-clamp: none
--webkit-locale: auto
--webkit-mask-box-image: none
--webkit-mask-box-image-outset: 0
--webkit-mask-box-image-repeat: stretch
--webkit-mask-box-image-slice: 0 fill
--webkit-mask-box-image-source: none
--webkit-mask-box-image-width: auto
--webkit-mask-composite: source-over
--webkit-mask-position: 0% 0%
--webkit-mask-position-x: 0%
--webkit-mask-position-y: 0%
--webkit-mask-repeat: repeat
--webkit-print-color-adjust: economy
--webkit-rtl-ordering: logical
--webkit-text-combine: none
--webkit-text-decorations-in-effect: none
--webkit-text-fill-color: rgb(0, 0, 0)
--webkit-text-orientation: vertical-right
--webkit-text-security: none
--webkit-text-stroke-color: rgb(0, 0, 0)
--webkit-text-stroke-width: 0px
--webkit-user-drag: auto
--webkit-user-modify: read-only
--webkit-writing-mode: horizontal-tb
-accent-color: auto
-align-content: normal
-align-items: normal
-align-self: auto
-alignment-baseline: auto
-anchor-default: implicit
-anchor-name: none
-animation-composition: replace
-animation-delay: 0s
-animation-direction: normal
-animation-duration: 0s
-animation-fill-mode: none
-animation-iteration-count: 1
-animation-name: none
-animation-play-state: running
-animation-range-end: normal
-animation-range-start: normal
-animation-timeline: auto
-animation-timing-function: ease
-app-region: none
-appearance: none
-backdrop-filter: none
-backface-visibility: visible
-background-attachment: scroll
-background-blend-mode: normal
-background-clip: border-box
-background-color: rgba(0, 0, 0, 0)
-background-image: none
-background-origin: padding-box
-background-position: 0% 0%
-background-position-x: 0%
-background-position-y: 0%
-background-repeat: repeat
-background-size: auto
-baseline-shift: 0px
-baseline-source: auto
-block-size: auto
-border-block-end-color: rgb(0, 0, 0)
-border-block-end-style: none
-border-block-end-width: 0px
-border-block-start-color: rgb(0, 0, 0)
-border-block-start-style: none
-border-block-start-width: 0px
-border-bottom-color: rgb(0, 0, 0)
-border-bottom-left-radius: 0px
-border-bottom-right-radius: 0px
-border-bottom-style: none
-border-bottom-width: 0px
-border-collapse: separate
-border-end-end-radius: 0px
-border-end-start-radius: 0px
-border-image-outset: 0
-border-image-repeat: stretch
-border-image-slice: 100%
-border-image-source: none
-border-image-width: 1
-border-inline-end-color: rgb(0, 0, 0)
-border-inline-end-style: none
-border-inline-end-width: 0px
-border-inline-start-color: rgb(0, 0, 0)
-border-inline-start-style: none
-border-inline-start-width: 0px
-border-left-color: rgb(0, 0, 0)
-border-left-style: none
-border-left-width: 0px
-border-right-color: rgb(0, 0, 0)
-border-right-style: none
-border-right-width: 0px
-border-spacing: 0px 0px
-border-start-end-radius: 0px
-border-start-start-radius: 0px
-border-top-color: rgb(0, 0, 0)
-border-top-left-radius: 0px
-border-top-right-radius: 0px
-border-top-style: none
-border-top-width: 0px
-bottom: auto
-box-shadow: none
-box-sizing: content-box
-break-after: auto
-break-before: auto
-break-inside: auto
-buffered-rendering: auto
-caption-side: top
-caret-color: rgb(0, 0, 0)
-clear: none
-clip: auto
-clip-path: none
-clip-rule: nonzero
-color: rgb(0, 0, 0)
-color-interpolation: srgb
-color-interpolation-filters: linearrgb
-color-rendering: auto
-column-count: auto
-column-gap: normal
-column-rule-color: rgb(0, 0, 0)
-column-rule-style: none
-column-rule-width: 0px
-column-span: none
-column-width: auto
-contain-intrinsic-block-size: none
-contain-intrinsic-height: none
-contain-intrinsic-inline-size: none
-contain-intrinsic-size: none
-contain-intrinsic-width: none
-container-name: none
-container-type: normal
-content: normal
-cursor: auto
-cx: 0px
-cy: 0px
-d: none
-direction: ltr
-display: none
-dominant-baseline: auto
-dynamic-range-limit: high
-empty-cells: show
-field-sizing: fixed
-fill: rgb(0, 0, 0)
-fill-opacity: 1
-fill-rule: nonzero
-filter: none
-flex-basis: auto
-flex-direction: row
-flex-grow: 0
-flex-shrink: 1
-flex-wrap: nowrap
-float: none
-flood-color: rgb(0, 0, 0)
-flood-opacity: 1
-font-kerning: auto
-font-optical-sizing: auto
-font-palette: normal
-font-size: 16px
-font-size-adjust: none
-font-stretch: 100%
-font-style: normal
-font-synthesis-small-caps: auto
-font-synthesis-style: auto
-font-synthesis-weight: auto
-font-variant: normal
-font-variant-alternates: normal
-font-variant-caps: normal
-font-variant-east-asian: normal
-font-variant-ligatures: normal
-font-variant-numeric: normal
-font-variant-position: normal
-font-weight: 400
-grid-auto-columns: auto
-grid-auto-flow: row
-grid-auto-rows: auto
-grid-column-end: auto
-grid-column-start: auto
-grid-row-end: auto
-grid-row-start: auto
-grid-template-areas: none
-grid-template-columns: none
-grid-template-rows: none
-height: auto
-hyphenate-character: auto
-hyphenate-limit-chars: auto
-hyphens: manual
-image-orientation: from-image
-image-rendering: auto
-initial-letter: normal
-inline-size: auto
-inset-block-end: auto
-inset-block-start: auto
-inset-inline-end: auto
-inset-inline-start: auto
-isolation: auto
-justify-content: normal
-justify-items: normal
-justify-self: auto
-left: auto
-letter-spacing: normal
-lighting-color: rgb(255, 255, 255)
-line-break: auto
-line-height: normal
-list-style-image: none
-list-style-position: outside
-list-style-type: disc
-margin-block-end: 0px
-margin-block-start: 0px
-margin-bottom: 0px
-margin-inline-end: 0px
-margin-inline-start: 0px
-margin-left: 0px
-margin-right: 0px
-margin-top: 0px
-marker-end: none
-marker-mid: none
-marker-start: none
-mask-clip: border-box
-mask-image: none
-mask-origin: border-box
-mask-size: auto
-mask-type: luminance
-math-depth: 0
-math-shift: normal
-math-style: normal
-max-block-size: none
-max-height: none
-max-inline-size: none
-max-width: none
-min-block-size: 0px
-min-height: 0px
-min-inline-size: 0px
-min-width: 0px
-mix-blend-mode: normal
-object-fit: fill
-object-position: 50% 50%
-object-view-box: none
-offset-anchor: auto
-offset-distance: 0px
-offset-path: none
-offset-position: normal
-offset-rotate: auto 0deg
-opacity: 1
-order: 0
-orphans: 2
-outline-color: rgb(0, 0, 0)
-outline-offset: 0px
-outline-style: none
-outline-width: 0px
-overflow: visible
-overflow-anchor: auto
-overflow-block: visible
-overflow-clip-margin: 0px
-overflow-inline: visible
-overflow-wrap: normal
-overflow-x: visible
-overflow-y: visible
-overlay: none
-overscroll-behavior-block: auto
-overscroll-behavior-inline: auto
-padding-block-end: 0px
-padding-block-start: 0px
-padding-bottom: 0px
-padding-inline-end: 0px
-padding-inline-start: 0px
-padding-left: 0px
-padding-right: 0px
-padding-top: 0px
-paint-order: normal
-perspective: none
-perspective-origin: 50% 50%
-pointer-events: auto
-popover-hide-delay: infinity * 1s
-popover-show-delay: 0.5s
-position: static
-position-fallback: none
-position-fallback-bounds: normal
-r: 0px
-resize: none
-right: auto
-rotate: none
-row-gap: normal
-ruby-position: over
-rx: auto
-ry: auto
-scale: none
-scroll-behavior: auto
-scroll-margin-block-end: 0px
-scroll-margin-block-start: 0px
-scroll-margin-inline-end: 0px
-scroll-margin-inline-start: 0px
-scroll-padding-block-end: auto
-scroll-padding-block-start: auto
-scroll-padding-inline-end: auto
-scroll-padding-inline-start: auto
-scroll-start-block: auto
-scroll-start-inline: auto
-scroll-start-target-block: none
-scroll-start-target-inline: none
-scroll-start-target-x: none
-scroll-start-target-y: none
-scroll-start-x: auto
-scroll-start-y: auto
-scroll-timeline-axis: block
-scroll-timeline-name: none
-scrollbar-color: auto
-scrollbar-gutter: auto
-scrollbar-width: auto
-shape-image-threshold: 0
-shape-margin: 0px
-shape-outside: none
-shape-rendering: auto
-speak: normal
-stop-color: rgb(0, 0, 0)
-stop-opacity: 1
-stroke: none
-stroke-dasharray: none
-stroke-dashoffset: 0px
-stroke-linecap: butt
-stroke-linejoin: miter
-stroke-miterlimit: 4
-stroke-opacity: 1
-stroke-width: 1px
-tab-size: 8
-table-layout: auto
-text-align: start
-text-align-last: auto
-text-anchor: start
-text-autospace: normal
-text-box-trim: none
-text-decoration: none solid rgb(0, 0, 0)
-text-decoration-color: rgb(0, 0, 0)
-text-decoration-line: none
-text-decoration-skip-ink: auto
-text-decoration-style: solid
-text-emphasis-color: rgb(0, 0, 0)
-text-emphasis-position: over
-text-emphasis-style: none
-text-indent: 0px
-text-overflow: clip
-text-rendering: auto
-text-shadow: none
-text-size-adjust: auto
-text-transform: none
-text-underline-position: auto
-text-wrap: wrap
-timeline-scope: none
-toggle-group: none
-toggle-root: none
-toggle-trigger: none
-toggle-visibility: normal
-top: auto
-touch-action: auto
-transform: none
-transform-origin: 50% 50%
-transform-style: flat
-transition-behavior: normal
-transition-delay: 0s
-transition-duration: 0s
-transition-property: all
-transition-timing-function: ease
-translate: none
-unicode-bidi: normal
-user-select: auto
-vector-effect: none
-vertical-align: baseline
-view-timeline-axis: block
-view-timeline-inset: auto
-view-timeline-name: none
-view-transition-name: none
-visibility: visible
-white-space-collapse: collapse
-widows: 2
-width: auto
-will-change: auto
-word-break: normal
-word-spacing: 0px
-writing-mode: horizontal-tb
-x: 0px
-y: 0px
-z-index: auto
-zoom: 1
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/blink/web_tests/virtual/css-text-autospace/svg/css/getComputedStyle-listing-expected.txt b/third_party/blink/web_tests/virtual/css-text-autospace/svg/css/getComputedStyle-listing-expected.txt
deleted file mode 100644
index d77adbe..0000000
--- a/third_party/blink/web_tests/virtual/css-text-autospace/svg/css/getComputedStyle-listing-expected.txt
+++ /dev/null
@@ -1,404 +0,0 @@
-This test documents all computed styles on an SVG rect element.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
--webkit-border-horizontal-spacing: 0px
--webkit-border-image: none
--webkit-border-vertical-spacing: 0px
--webkit-box-align: stretch
--webkit-box-decoration-break: slice
--webkit-box-direction: normal
--webkit-box-flex: 0
--webkit-box-ordinal-group: 1
--webkit-box-orient: horizontal
--webkit-box-pack: start
--webkit-box-reflect: none
--webkit-font-smoothing: auto
--webkit-line-break: auto
--webkit-line-clamp: none
--webkit-locale: auto
--webkit-mask-box-image: none
--webkit-mask-box-image-outset: 0
--webkit-mask-box-image-repeat: stretch
--webkit-mask-box-image-slice: 0 fill
--webkit-mask-box-image-source: none
--webkit-mask-box-image-width: auto
--webkit-mask-composite: source-over
--webkit-mask-position: 0% 0%
--webkit-mask-position-x: 0%
--webkit-mask-position-y: 0%
--webkit-mask-repeat: repeat
--webkit-print-color-adjust: economy
--webkit-rtl-ordering: logical
--webkit-text-combine: none
--webkit-text-decorations-in-effect: none
--webkit-text-fill-color: rgb(0, 0, 0)
--webkit-text-orientation: vertical-right
--webkit-text-security: none
--webkit-text-stroke-color: rgb(0, 0, 0)
--webkit-text-stroke-width: 0px
--webkit-user-drag: auto
--webkit-user-modify: read-only
--webkit-writing-mode: horizontal-tb
-accent-color: auto
-align-content: normal
-align-items: normal
-align-self: auto
-alignment-baseline: auto
-anchor-default: implicit
-anchor-name: none
-animation-composition: replace
-animation-delay: 0s
-animation-direction: normal
-animation-duration: 0s
-animation-fill-mode: none
-animation-iteration-count: 1
-animation-name: none
-animation-play-state: running
-animation-range-end: normal
-animation-range-start: normal
-animation-timeline: auto
-animation-timing-function: ease
-app-region: none
-appearance: none
-backdrop-filter: none
-backface-visibility: visible
-background-attachment: scroll
-background-blend-mode: normal
-background-clip: border-box
-background-color: rgba(0, 0, 0, 0)
-background-image: none
-background-origin: padding-box
-background-position: 0% 0%
-background-position-x: 0%
-background-position-y: 0%
-background-repeat: repeat
-background-size: auto
-baseline-shift: 0px
-baseline-source: auto
-block-size: 100px
-border-block-end-color: rgb(0, 0, 0)
-border-block-end-style: none
-border-block-end-width: 0px
-border-block-start-color: rgb(0, 0, 0)
-border-block-start-style: none
-border-block-start-width: 0px
-border-bottom-color: rgb(0, 0, 0)
-border-bottom-left-radius: 0px
-border-bottom-right-radius: 0px
-border-bottom-style: none
-border-bottom-width: 0px
-border-collapse: separate
-border-end-end-radius: 0px
-border-end-start-radius: 0px
-border-image-outset: 0
-border-image-repeat: stretch
-border-image-slice: 100%
-border-image-source: none
-border-image-width: 1
-border-inline-end-color: rgb(0, 0, 0)
-border-inline-end-style: none
-border-inline-end-width: 0px
-border-inline-start-color: rgb(0, 0, 0)
-border-inline-start-style: none
-border-inline-start-width: 0px
-border-left-color: rgb(0, 0, 0)
-border-left-style: none
-border-left-width: 0px
-border-right-color: rgb(0, 0, 0)
-border-right-style: none
-border-right-width: 0px
-border-spacing: 0px 0px
-border-start-end-radius: 0px
-border-start-start-radius: 0px
-border-top-color: rgb(0, 0, 0)
-border-top-left-radius: 0px
-border-top-right-radius: 0px
-border-top-style: none
-border-top-width: 0px
-bottom: auto
-box-shadow: none
-box-sizing: content-box
-break-after: auto
-break-before: auto
-break-inside: auto
-buffered-rendering: auto
-caption-side: top
-caret-color: rgb(0, 0, 0)
-clear: none
-clip: auto
-clip-path: none
-clip-rule: nonzero
-color: rgb(0, 0, 0)
-color-interpolation: srgb
-color-interpolation-filters: linearrgb
-color-rendering: auto
-column-count: auto
-column-gap: normal
-column-rule-color: rgb(0, 0, 0)
-column-rule-style: none
-column-rule-width: 0px
-column-span: none
-column-width: auto
-contain-intrinsic-block-size: none
-contain-intrinsic-height: none
-contain-intrinsic-inline-size: none
-contain-intrinsic-size: none
-contain-intrinsic-width: none
-container-name: none
-container-type: normal
-content: normal
-cursor: auto
-cx: 0px
-cy: 0px
-d: none
-direction: ltr
-display: inline
-dominant-baseline: auto
-dynamic-range-limit: high
-empty-cells: show
-field-sizing: fixed
-fill: rgb(0, 128, 0)
-fill-opacity: 1
-fill-rule: nonzero
-filter: none
-flex-basis: auto
-flex-direction: row
-flex-grow: 0
-flex-shrink: 1
-flex-wrap: nowrap
-float: none
-flood-color: rgb(0, 0, 0)
-flood-opacity: 1
-font-kerning: auto
-font-optical-sizing: auto
-font-palette: normal
-font-size: 16px
-font-size-adjust: none
-font-stretch: 100%
-font-style: normal
-font-synthesis-small-caps: auto
-font-synthesis-style: auto
-font-synthesis-weight: auto
-font-variant: normal
-font-variant-alternates: normal
-font-variant-caps: normal
-font-variant-east-asian: normal
-font-variant-ligatures: normal
-font-variant-numeric: normal
-font-variant-position: normal
-font-weight: 400
-grid-auto-columns: auto
-grid-auto-flow: row
-grid-auto-rows: auto
-grid-column-end: auto
-grid-column-start: auto
-grid-row-end: auto
-grid-row-start: auto
-grid-template-areas: none
-grid-template-columns: none
-grid-template-rows: none
-height: 100px
-hyphenate-character: auto
-hyphenate-limit-chars: auto
-hyphens: manual
-image-orientation: from-image
-image-rendering: auto
-initial-letter: normal
-inline-size: 100px
-inset-block-end: auto
-inset-block-start: auto
-inset-inline-end: auto
-inset-inline-start: auto
-isolation: auto
-justify-content: normal
-justify-items: normal
-justify-self: auto
-left: auto
-letter-spacing: normal
-lighting-color: rgb(255, 255, 255)
-line-break: auto
-line-height: normal
-list-style-image: none
-list-style-position: outside
-list-style-type: disc
-margin-block-end: 0px
-margin-block-start: 0px
-margin-bottom: 0px
-margin-inline-end: 0px
-margin-inline-start: 0px
-margin-left: 0px
-margin-right: 0px
-margin-top: 0px
-marker-end: none
-marker-mid: none
-marker-start: none
-mask-clip: border-box
-mask-image: none
-mask-origin: border-box
-mask-size: auto
-mask-type: luminance
-math-depth: 0
-math-shift: normal
-math-style: normal
-max-block-size: none
-max-height: none
-max-inline-size: none
-max-width: none
-min-block-size: 0px
-min-height: 0px
-min-inline-size: 0px
-min-width: 0px
-mix-blend-mode: normal
-object-fit: fill
-object-position: 50% 50%
-object-view-box: none
-offset-anchor: auto
-offset-distance: 0px
-offset-path: none
-offset-position: normal
-offset-rotate: auto 0deg
-opacity: 1
-order: 0
-orphans: 2
-outline-color: rgb(0, 0, 0)
-outline-offset: 0px
-outline-style: none
-outline-width: 0px
-overflow: visible
-overflow-anchor: auto
-overflow-block: visible
-overflow-clip-margin: 0px
-overflow-inline: visible
-overflow-wrap: normal
-overflow-x: visible
-overflow-y: visible
-overlay: none
-overscroll-behavior-block: auto
-overscroll-behavior-inline: auto
-padding-block-end: 0px
-padding-block-start: 0px
-padding-bottom: 0px
-padding-inline-end: 0px
-padding-inline-start: 0px
-padding-left: 0px
-padding-right: 0px
-padding-top: 0px
-paint-order: normal
-perspective: none
-perspective-origin: 0px 0px
-pointer-events: auto
-popover-hide-delay: infinity * 1s
-popover-show-delay: 0.5s
-position: static
-position-fallback: none
-position-fallback-bounds: normal
-r: 0px
-resize: none
-right: auto
-rotate: none
-row-gap: normal
-ruby-position: over
-rx: auto
-ry: auto
-scale: none
-scroll-behavior: auto
-scroll-margin-block-end: 0px
-scroll-margin-block-start: 0px
-scroll-margin-inline-end: 0px
-scroll-margin-inline-start: 0px
-scroll-padding-block-end: auto
-scroll-padding-block-start: auto
-scroll-padding-inline-end: auto
-scroll-padding-inline-start: auto
-scroll-start-block: auto
-scroll-start-inline: auto
-scroll-start-target-block: none
-scroll-start-target-inline: none
-scroll-start-target-x: none
-scroll-start-target-y: none
-scroll-start-x: auto
-scroll-start-y: auto
-scroll-timeline-axis: block
-scroll-timeline-name: none
-scrollbar-color: auto
-scrollbar-gutter: auto
-scrollbar-width: auto
-shape-image-threshold: 0
-shape-margin: 0px
-shape-outside: none
-shape-rendering: auto
-speak: normal
-stop-color: rgb(0, 0, 0)
-stop-opacity: 1
-stroke: none
-stroke-dasharray: none
-stroke-dashoffset: 0px
-stroke-linecap: butt
-stroke-linejoin: miter
-stroke-miterlimit: 4
-stroke-opacity: 1
-stroke-width: 1px
-tab-size: 8
-table-layout: auto
-text-align: start
-text-align-last: auto
-text-anchor: start
-text-autospace: normal
-text-box-trim: none
-text-decoration: none solid rgb(0, 0, 0)
-text-decoration-color: rgb(0, 0, 0)
-text-decoration-line: none
-text-decoration-skip-ink: auto
-text-decoration-style: solid
-text-emphasis-color: rgb(0, 0, 0)
-text-emphasis-position: over
-text-emphasis-style: none
-text-indent: 0px
-text-overflow: clip
-text-rendering: auto
-text-shadow: none
-text-size-adjust: auto
-text-transform: none
-text-underline-position: auto
-text-wrap: wrap
-timeline-scope: none
-toggle-group: none
-toggle-root: none
-toggle-trigger: none
-toggle-visibility: normal
-top: auto
-touch-action: auto
-transform: none
-transform-origin: 0px 0px
-transform-style: flat
-transition-behavior: normal
-transition-delay: 0s
-transition-duration: 0s
-transition-property: all
-transition-timing-function: ease
-translate: none
-unicode-bidi: normal
-user-select: auto
-vector-effect: none
-vertical-align: baseline
-view-timeline-axis: block
-view-timeline-inset: auto
-view-timeline-name: none
-view-transition-name: none
-visibility: visible
-white-space-collapse: collapse
-widows: 2
-width: 100px
-will-change: auto
-word-break: normal
-word-spacing: 0px
-writing-mode: horizontal-tb
-x: 0px
-y: 0px
-z-index: auto
-zoom: 1
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/blink/web_tests/virtual/css-text-autospace/webexposed/css-properties-as-js-properties-expected.txt b/third_party/blink/web_tests/virtual/css-text-autospace/webexposed/css-properties-as-js-properties-expected.txt
deleted file mode 100644
index 0e42c4c7f..0000000
--- a/third_party/blink/web_tests/virtual/css-text-autospace/webexposed/css-properties-as-js-properties-expected.txt
+++ /dev/null
@@ -1,663 +0,0 @@
-This test (crudely) documents Blink's web-exposed CSS properties.  All changes to this list should go through Blink's feature review process: http://www.chromium.org/blink#new-features
-
-
-accentColor
-additiveSymbols
-alignContent
-alignItems
-alignSelf
-alignmentBaseline
-all
-anchorDefault
-anchorName
-animation
-animationComposition
-animationDelay
-animationDirection
-animationDuration
-animationFillMode
-animationIterationCount
-animationName
-animationPlayState
-animationRange
-animationRangeEnd
-animationRangeStart
-animationTimeline
-animationTimingFunction
-appRegion
-appearance
-ascentOverride
-aspectRatio
-backdropFilter
-backfaceVisibility
-background
-backgroundAttachment
-backgroundBlendMode
-backgroundClip
-backgroundColor
-backgroundImage
-backgroundOrigin
-backgroundPosition
-backgroundPositionX
-backgroundPositionY
-backgroundRepeat
-backgroundRepeatX
-backgroundRepeatY
-backgroundSize
-basePalette
-baselineShift
-baselineSource
-blockSize
-border
-borderBlock
-borderBlockColor
-borderBlockEnd
-borderBlockEndColor
-borderBlockEndStyle
-borderBlockEndWidth
-borderBlockStart
-borderBlockStartColor
-borderBlockStartStyle
-borderBlockStartWidth
-borderBlockStyle
-borderBlockWidth
-borderBottom
-borderBottomColor
-borderBottomLeftRadius
-borderBottomRightRadius
-borderBottomStyle
-borderBottomWidth
-borderCollapse
-borderColor
-borderEndEndRadius
-borderEndStartRadius
-borderImage
-borderImageOutset
-borderImageRepeat
-borderImageSlice
-borderImageSource
-borderImageWidth
-borderInline
-borderInlineColor
-borderInlineEnd
-borderInlineEndColor
-borderInlineEndStyle
-borderInlineEndWidth
-borderInlineStart
-borderInlineStartColor
-borderInlineStartStyle
-borderInlineStartWidth
-borderInlineStyle
-borderInlineWidth
-borderLeft
-borderLeftColor
-borderLeftStyle
-borderLeftWidth
-borderRadius
-borderRight
-borderRightColor
-borderRightStyle
-borderRightWidth
-borderSpacing
-borderStartEndRadius
-borderStartStartRadius
-borderStyle
-borderTop
-borderTopColor
-borderTopLeftRadius
-borderTopRightRadius
-borderTopStyle
-borderTopWidth
-borderWidth
-bottom
-boxShadow
-boxSizing
-breakAfter
-breakBefore
-breakInside
-bufferedRendering
-captionSide
-caretColor
-clear
-clip
-clipPath
-clipRule
-color
-colorInterpolation
-colorInterpolationFilters
-colorRendering
-colorScheme
-columnCount
-columnFill
-columnGap
-columnRule
-columnRuleColor
-columnRuleStyle
-columnRuleWidth
-columnSpan
-columnWidth
-columns
-contain
-containIntrinsicBlockSize
-containIntrinsicHeight
-containIntrinsicInlineSize
-containIntrinsicSize
-containIntrinsicWidth
-container
-containerName
-containerType
-content
-contentVisibility
-counterIncrement
-counterReset
-counterSet
-cssFloat
-cssText
-cursor
-cx
-cy
-d
-descentOverride
-direction
-display
-dominantBaseline
-dynamicRangeLimit
-emptyCells
-fallback
-fieldSizing
-fill
-fillOpacity
-fillRule
-filter
-flex
-flexBasis
-flexDirection
-flexFlow
-flexGrow
-flexShrink
-flexWrap
-float
-floodColor
-floodOpacity
-font
-fontDisplay
-fontFamily
-fontFeatureSettings
-fontKerning
-fontOpticalSizing
-fontPalette
-fontSize
-fontSizeAdjust
-fontStretch
-fontStyle
-fontSynthesis
-fontSynthesisSmallCaps
-fontSynthesisStyle
-fontSynthesisWeight
-fontVariant
-fontVariantAlternates
-fontVariantCaps
-fontVariantEastAsian
-fontVariantLigatures
-fontVariantNumeric
-fontVariantPosition
-fontVariationSettings
-fontWeight
-forcedColorAdjust
-gap
-getPropertyPriority
-getPropertyValue
-grid
-gridArea
-gridAutoColumns
-gridAutoFlow
-gridAutoRows
-gridColumn
-gridColumnEnd
-gridColumnGap
-gridColumnStart
-gridGap
-gridRow
-gridRowEnd
-gridRowGap
-gridRowStart
-gridTemplate
-gridTemplateAreas
-gridTemplateColumns
-gridTemplateRows
-height
-hyphenateCharacter
-hyphenateLimitChars
-hyphens
-imageOrientation
-imageRendering
-inherits
-initialLetter
-initialValue
-inlineSize
-inset
-insetBlock
-insetBlockEnd
-insetBlockStart
-insetInline
-insetInlineEnd
-insetInlineStart
-isolation
-item
-justifyContent
-justifyItems
-justifySelf
-left
-length
-letterSpacing
-lightingColor
-lineBreak
-lineGapOverride
-lineHeight
-listStyle
-listStyleImage
-listStylePosition
-listStyleType
-margin
-marginBlock
-marginBlockEnd
-marginBlockStart
-marginBottom
-marginInline
-marginInlineEnd
-marginInlineStart
-marginLeft
-marginRight
-marginTop
-marker
-markerEnd
-markerMid
-markerStart
-mask
-maskClip
-maskImage
-maskOrigin
-maskSize
-maskType
-mathDepth
-mathShift
-mathStyle
-maxBlockSize
-maxHeight
-maxInlineSize
-maxWidth
-minBlockSize
-minHeight
-minInlineSize
-minWidth
-mixBlendMode
-negative
-objectFit
-objectPosition
-objectViewBox
-offset
-offsetAnchor
-offsetDistance
-offsetPath
-offsetPosition
-offsetRotate
-opacity
-order
-orphans
-outline
-outlineColor
-outlineOffset
-outlineStyle
-outlineWidth
-overflow
-overflowAnchor
-overflowBlock
-overflowClipMargin
-overflowInline
-overflowWrap
-overflowX
-overflowY
-overlay
-overrideColors
-overscrollBehavior
-overscrollBehaviorBlock
-overscrollBehaviorInline
-overscrollBehaviorX
-overscrollBehaviorY
-pad
-padding
-paddingBlock
-paddingBlockEnd
-paddingBlockStart
-paddingBottom
-paddingInline
-paddingInlineEnd
-paddingInlineStart
-paddingLeft
-paddingRight
-paddingTop
-page
-pageBreakAfter
-pageBreakBefore
-pageBreakInside
-pageOrientation
-paintOrder
-parentRule
-perspective
-perspectiveOrigin
-placeContent
-placeItems
-placeSelf
-pointerEvents
-popoverHideDelay
-popoverShowDelay
-position
-positionFallback
-positionFallbackBounds
-prefix
-quotes
-r
-range
-removeProperty
-resize
-right
-rotate
-rowGap
-rubyPosition
-rx
-ry
-scale
-scrollBehavior
-scrollMargin
-scrollMarginBlock
-scrollMarginBlockEnd
-scrollMarginBlockStart
-scrollMarginBottom
-scrollMarginInline
-scrollMarginInlineEnd
-scrollMarginInlineStart
-scrollMarginLeft
-scrollMarginRight
-scrollMarginTop
-scrollPadding
-scrollPaddingBlock
-scrollPaddingBlockEnd
-scrollPaddingBlockStart
-scrollPaddingBottom
-scrollPaddingInline
-scrollPaddingInlineEnd
-scrollPaddingInlineStart
-scrollPaddingLeft
-scrollPaddingRight
-scrollPaddingTop
-scrollSnapAlign
-scrollSnapStop
-scrollSnapType
-scrollStart
-scrollStartBlock
-scrollStartInline
-scrollStartTarget
-scrollStartTargetBlock
-scrollStartTargetInline
-scrollStartTargetX
-scrollStartTargetY
-scrollStartX
-scrollStartY
-scrollTimeline
-scrollTimelineAxis
-scrollTimelineName
-scrollbarColor
-scrollbarGutter
-scrollbarWidth
-setProperty
-shapeImageThreshold
-shapeMargin
-shapeOutside
-shapeRendering
-size
-sizeAdjust
-speak
-speakAs
-src
-stopColor
-stopOpacity
-stroke
-strokeDasharray
-strokeDashoffset
-strokeLinecap
-strokeLinejoin
-strokeMiterlimit
-strokeOpacity
-strokeWidth
-suffix
-symbols
-syntax
-system
-tabSize
-tableLayout
-textAlign
-textAlignLast
-textAnchor
-textAutospace
-textBoxTrim
-textCombineUpright
-textDecoration
-textDecorationColor
-textDecorationLine
-textDecorationSkipInk
-textDecorationStyle
-textDecorationThickness
-textEmphasis
-textEmphasisColor
-textEmphasisPosition
-textEmphasisStyle
-textIndent
-textOrientation
-textOverflow
-textRendering
-textShadow
-textSizeAdjust
-textTransform
-textUnderlineOffset
-textUnderlinePosition
-textWrap
-timelineScope
-toggle
-toggleGroup
-toggleRoot
-toggleTrigger
-toggleVisibility
-top
-touchAction
-transform
-transformBox
-transformOrigin
-transformStyle
-transition
-transitionBehavior
-transitionDelay
-transitionDuration
-transitionProperty
-transitionTimingFunction
-translate
-unicodeBidi
-unicodeRange
-userSelect
-vectorEffect
-verticalAlign
-viewTimeline
-viewTimelineAxis
-viewTimelineInset
-viewTimelineName
-viewTransitionName
-visibility
-webkitAlignContent
-webkitAlignItems
-webkitAlignSelf
-webkitAnimation
-webkitAnimationDelay
-webkitAnimationDirection
-webkitAnimationDuration
-webkitAnimationFillMode
-webkitAnimationIterationCount
-webkitAnimationName
-webkitAnimationPlayState
-webkitAnimationTimingFunction
-webkitAppRegion
-webkitAppearance
-webkitBackfaceVisibility
-webkitBackgroundClip
-webkitBackgroundOrigin
-webkitBackgroundSize
-webkitBorderAfter
-webkitBorderAfterColor
-webkitBorderAfterStyle
-webkitBorderAfterWidth
-webkitBorderBefore
-webkitBorderBeforeColor
-webkitBorderBeforeStyle
-webkitBorderBeforeWidth
-webkitBorderBottomLeftRadius
-webkitBorderBottomRightRadius
-webkitBorderEnd
-webkitBorderEndColor
-webkitBorderEndStyle
-webkitBorderEndWidth
-webkitBorderHorizontalSpacing
-webkitBorderImage
-webkitBorderRadius
-webkitBorderStart
-webkitBorderStartColor
-webkitBorderStartStyle
-webkitBorderStartWidth
-webkitBorderTopLeftRadius
-webkitBorderTopRightRadius
-webkitBorderVerticalSpacing
-webkitBoxAlign
-webkitBoxDecorationBreak
-webkitBoxDirection
-webkitBoxFlex
-webkitBoxOrdinalGroup
-webkitBoxOrient
-webkitBoxPack
-webkitBoxReflect
-webkitBoxShadow
-webkitBoxSizing
-webkitClipPath
-webkitColumnBreakAfter
-webkitColumnBreakBefore
-webkitColumnBreakInside
-webkitColumnCount
-webkitColumnGap
-webkitColumnRule
-webkitColumnRuleColor
-webkitColumnRuleStyle
-webkitColumnRuleWidth
-webkitColumnSpan
-webkitColumnWidth
-webkitColumns
-webkitFilter
-webkitFlex
-webkitFlexBasis
-webkitFlexDirection
-webkitFlexFlow
-webkitFlexGrow
-webkitFlexShrink
-webkitFlexWrap
-webkitFontFeatureSettings
-webkitFontSmoothing
-webkitHyphenateCharacter
-webkitJustifyContent
-webkitLineBreak
-webkitLineClamp
-webkitLocale
-webkitLogicalHeight
-webkitLogicalWidth
-webkitMarginAfter
-webkitMarginBefore
-webkitMarginEnd
-webkitMarginStart
-webkitMask
-webkitMaskBoxImage
-webkitMaskBoxImageOutset
-webkitMaskBoxImageRepeat
-webkitMaskBoxImageSlice
-webkitMaskBoxImageSource
-webkitMaskBoxImageWidth
-webkitMaskClip
-webkitMaskComposite
-webkitMaskImage
-webkitMaskOrigin
-webkitMaskPosition
-webkitMaskPositionX
-webkitMaskPositionY
-webkitMaskRepeat
-webkitMaskRepeatX
-webkitMaskRepeatY
-webkitMaskSize
-webkitMaxLogicalHeight
-webkitMaxLogicalWidth
-webkitMinLogicalHeight
-webkitMinLogicalWidth
-webkitOpacity
-webkitOrder
-webkitPaddingAfter
-webkitPaddingBefore
-webkitPaddingEnd
-webkitPaddingStart
-webkitPerspective
-webkitPerspectiveOrigin
-webkitPerspectiveOriginX
-webkitPerspectiveOriginY
-webkitPrintColorAdjust
-webkitRtlOrdering
-webkitRubyPosition
-webkitShapeImageThreshold
-webkitShapeMargin
-webkitShapeOutside
-webkitTapHighlightColor
-webkitTextCombine
-webkitTextDecorationsInEffect
-webkitTextEmphasis
-webkitTextEmphasisColor
-webkitTextEmphasisPosition
-webkitTextEmphasisStyle
-webkitTextFillColor
-webkitTextOrientation
-webkitTextSecurity
-webkitTextSizeAdjust
-webkitTextStroke
-webkitTextStrokeColor
-webkitTextStrokeWidth
-webkitTransform
-webkitTransformOrigin
-webkitTransformOriginX
-webkitTransformOriginY
-webkitTransformOriginZ
-webkitTransformStyle
-webkitTransition
-webkitTransitionDelay
-webkitTransitionDuration
-webkitTransitionProperty
-webkitTransitionTimingFunction
-webkitUserDrag
-webkitUserModify
-webkitUserSelect
-webkitWritingMode
-whiteSpace
-whiteSpaceCollapse
-widows
-width
-willChange
-wordBreak
-wordSpacing
-wordWrap
-writingMode
-x
-y
-zIndex
-zoom
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/blink/web_tests/virtual/css-text-autospace/webexposed/css-property-listing-expected.txt b/third_party/blink/web_tests/virtual/css-text-autospace/webexposed/css-property-listing-expected.txt
deleted file mode 100644
index 0c45662..0000000
--- a/third_party/blink/web_tests/virtual/css-text-autospace/webexposed/css-property-listing-expected.txt
+++ /dev/null
@@ -1,1045 +0,0 @@
-This test documents Blink's web-exposed CSS properties.
-All changes to this list should go through Blink's feature review process: http://www.chromium.org/blink#new-features
-
-[LONGHANDS]
-    -webkit-border-horizontal-spacing
-    -webkit-border-image
-    -webkit-border-vertical-spacing
-    -webkit-box-align
-    -webkit-box-decoration-break
-    -webkit-box-direction
-    -webkit-box-flex
-    -webkit-box-ordinal-group
-    -webkit-box-orient
-    -webkit-box-pack
-    -webkit-box-reflect
-    -webkit-font-smoothing
-    -webkit-line-break
-    -webkit-line-clamp
-    -webkit-locale
-    -webkit-mask-box-image-outset
-    -webkit-mask-box-image-repeat
-    -webkit-mask-box-image-slice
-    -webkit-mask-box-image-source
-    -webkit-mask-box-image-width
-    -webkit-mask-composite
-    -webkit-mask-position-x
-    -webkit-mask-position-y
-    -webkit-mask-repeat-x
-    -webkit-mask-repeat-y
-    -webkit-perspective-origin-x
-    -webkit-perspective-origin-y
-    -webkit-print-color-adjust
-    -webkit-rtl-ordering
-    -webkit-ruby-position
-    -webkit-tap-highlight-color
-    -webkit-text-combine
-    -webkit-text-decorations-in-effect
-    -webkit-text-fill-color
-    -webkit-text-orientation
-    -webkit-text-security
-    -webkit-text-stroke-color
-    -webkit-text-stroke-width
-    -webkit-transform-origin-x
-    -webkit-transform-origin-y
-    -webkit-transform-origin-z
-    -webkit-user-drag
-    -webkit-user-modify
-    -webkit-writing-mode
-    accent-color
-    align-content
-    align-items
-    align-self
-    alignment-baseline
-    all
-    anchor-default
-    anchor-name
-    animation-composition
-    animation-delay
-    animation-direction
-    animation-duration
-    animation-fill-mode
-    animation-iteration-count
-    animation-name
-    animation-play-state
-    animation-range-end
-    animation-range-start
-    animation-timeline
-    animation-timing-function
-    app-region
-    appearance
-    aspect-ratio
-    backdrop-filter
-    backface-visibility
-    background-attachment
-    background-blend-mode
-    background-clip
-    background-color
-    background-image
-    background-origin
-    background-position-x
-    background-position-y
-    background-repeat-x
-    background-repeat-y
-    background-size
-    baseline-shift
-    baseline-source
-    block-size
-    border-block-end-color
-    border-block-end-style
-    border-block-end-width
-    border-block-start-color
-    border-block-start-style
-    border-block-start-width
-    border-bottom-color
-    border-bottom-left-radius
-    border-bottom-right-radius
-    border-bottom-style
-    border-bottom-width
-    border-collapse
-    border-end-end-radius
-    border-end-start-radius
-    border-image-outset
-    border-image-repeat
-    border-image-slice
-    border-image-source
-    border-image-width
-    border-inline-end-color
-    border-inline-end-style
-    border-inline-end-width
-    border-inline-start-color
-    border-inline-start-style
-    border-inline-start-width
-    border-left-color
-    border-left-style
-    border-left-width
-    border-right-color
-    border-right-style
-    border-right-width
-    border-start-end-radius
-    border-start-start-radius
-    border-top-color
-    border-top-left-radius
-    border-top-right-radius
-    border-top-style
-    border-top-width
-    bottom
-    box-shadow
-    box-sizing
-    break-after
-    break-before
-    break-inside
-    buffered-rendering
-    caption-side
-    caret-color
-    clear
-    clip
-    clip-path
-    clip-rule
-    color
-    color-interpolation
-    color-interpolation-filters
-    color-rendering
-    color-scheme
-    column-count
-    column-fill
-    column-gap
-    column-rule-color
-    column-rule-style
-    column-rule-width
-    column-span
-    column-width
-    contain
-    contain-intrinsic-block-size
-    contain-intrinsic-height
-    contain-intrinsic-inline-size
-    contain-intrinsic-width
-    container-name
-    container-type
-    content
-    content-visibility
-    counter-increment
-    counter-reset
-    counter-set
-    cursor
-    cx
-    cy
-    d
-    direction
-    display
-    dominant-baseline
-    dynamic-range-limit
-    empty-cells
-    field-sizing
-    fill
-    fill-opacity
-    fill-rule
-    filter
-    flex-basis
-    flex-direction
-    flex-grow
-    flex-shrink
-    flex-wrap
-    float
-    flood-color
-    flood-opacity
-    font-family
-    font-feature-settings
-    font-kerning
-    font-optical-sizing
-    font-palette
-    font-size
-    font-size-adjust
-    font-stretch
-    font-style
-    font-synthesis-small-caps
-    font-synthesis-style
-    font-synthesis-weight
-    font-variant-alternates
-    font-variant-caps
-    font-variant-east-asian
-    font-variant-ligatures
-    font-variant-numeric
-    font-variant-position
-    font-variation-settings
-    font-weight
-    forced-color-adjust
-    grid-auto-columns
-    grid-auto-flow
-    grid-auto-rows
-    grid-column-end
-    grid-column-start
-    grid-row-end
-    grid-row-start
-    grid-template-areas
-    grid-template-columns
-    grid-template-rows
-    height
-    hyphenate-character
-    hyphenate-limit-chars
-    hyphens
-    image-orientation
-    image-rendering
-    initial-letter
-    inline-size
-    inset-block-end
-    inset-block-start
-    inset-inline-end
-    inset-inline-start
-    isolation
-    justify-content
-    justify-items
-    justify-self
-    left
-    letter-spacing
-    lighting-color
-    line-break
-    line-height
-    list-style-image
-    list-style-position
-    list-style-type
-    margin-block-end
-    margin-block-start
-    margin-bottom
-    margin-inline-end
-    margin-inline-start
-    margin-left
-    margin-right
-    margin-top
-    marker-end
-    marker-mid
-    marker-start
-    mask
-    mask-clip
-    mask-image
-    mask-origin
-    mask-size
-    mask-type
-    math-depth
-    math-shift
-    math-style
-    max-block-size
-    max-height
-    max-inline-size
-    max-width
-    min-block-size
-    min-height
-    min-inline-size
-    min-width
-    mix-blend-mode
-    object-fit
-    object-position
-    object-view-box
-    offset-anchor
-    offset-distance
-    offset-path
-    offset-position
-    offset-rotate
-    opacity
-    order
-    orphans
-    outline-color
-    outline-offset
-    outline-style
-    outline-width
-    overflow-anchor
-    overflow-block
-    overflow-clip-margin
-    overflow-inline
-    overflow-wrap
-    overflow-x
-    overflow-y
-    overlay
-    overscroll-behavior-block
-    overscroll-behavior-inline
-    overscroll-behavior-x
-    overscroll-behavior-y
-    padding-block-end
-    padding-block-start
-    padding-bottom
-    padding-inline-end
-    padding-inline-start
-    padding-left
-    padding-right
-    padding-top
-    page
-    page-orientation
-    paint-order
-    perspective
-    perspective-origin
-    pointer-events
-    popover-hide-delay
-    popover-show-delay
-    position
-    position-fallback
-    position-fallback-bounds
-    quotes
-    r
-    resize
-    right
-    rotate
-    row-gap
-    ruby-position
-    rx
-    ry
-    scale
-    scroll-behavior
-    scroll-margin-block-end
-    scroll-margin-block-start
-    scroll-margin-bottom
-    scroll-margin-inline-end
-    scroll-margin-inline-start
-    scroll-margin-left
-    scroll-margin-right
-    scroll-margin-top
-    scroll-padding-block-end
-    scroll-padding-block-start
-    scroll-padding-bottom
-    scroll-padding-inline-end
-    scroll-padding-inline-start
-    scroll-padding-left
-    scroll-padding-right
-    scroll-padding-top
-    scroll-snap-align
-    scroll-snap-stop
-    scroll-snap-type
-    scroll-start-block
-    scroll-start-inline
-    scroll-start-target-block
-    scroll-start-target-inline
-    scroll-start-target-x
-    scroll-start-target-y
-    scroll-start-x
-    scroll-start-y
-    scroll-timeline-axis
-    scroll-timeline-name
-    scrollbar-color
-    scrollbar-gutter
-    scrollbar-width
-    shape-image-threshold
-    shape-margin
-    shape-outside
-    shape-rendering
-    size
-    speak
-    stop-color
-    stop-opacity
-    stroke
-    stroke-dasharray
-    stroke-dashoffset
-    stroke-linecap
-    stroke-linejoin
-    stroke-miterlimit
-    stroke-opacity
-    stroke-width
-    tab-size
-    table-layout
-    text-align
-    text-align-last
-    text-anchor
-    text-autospace
-    text-box-trim
-    text-combine-upright
-    text-decoration-color
-    text-decoration-line
-    text-decoration-skip-ink
-    text-decoration-style
-    text-decoration-thickness
-    text-emphasis-color
-    text-emphasis-position
-    text-emphasis-style
-    text-indent
-    text-orientation
-    text-overflow
-    text-rendering
-    text-shadow
-    text-size-adjust
-    text-transform
-    text-underline-offset
-    text-underline-position
-    text-wrap
-    timeline-scope
-    toggle-group
-    toggle-root
-    toggle-trigger
-    toggle-visibility
-    top
-    touch-action
-    transform
-    transform-box
-    transform-origin
-    transform-style
-    transition-behavior
-    transition-delay
-    transition-duration
-    transition-property
-    transition-timing-function
-    translate
-    unicode-bidi
-    user-select
-    vector-effect
-    vertical-align
-    view-timeline-axis
-    view-timeline-inset
-    view-timeline-name
-    view-transition-name
-    visibility
-    white-space-collapse
-    widows
-    width
-    will-change
-    word-break
-    word-spacing
-    writing-mode
-    x
-    y
-    z-index
-    zoom
-
-[SHORTHANDS]
-    -webkit-column-break-after
-        break-after
-    -webkit-column-break-before
-        break-before
-    -webkit-column-break-inside
-        break-inside
-    -webkit-mask
-        -webkit-mask-position-x
-        -webkit-mask-position-y
-        -webkit-mask-repeat-x
-        -webkit-mask-repeat-y
-        mask-clip
-        mask-image
-        mask-origin
-        mask-size
-    -webkit-mask-box-image
-        -webkit-mask-box-image-outset
-        -webkit-mask-box-image-repeat
-        -webkit-mask-box-image-slice
-        -webkit-mask-box-image-source
-        -webkit-mask-box-image-width
-    -webkit-mask-position
-        -webkit-mask-position-x
-        -webkit-mask-position-y
-    -webkit-mask-repeat
-        -webkit-mask-repeat-x
-        -webkit-mask-repeat-y
-    -webkit-text-stroke
-        -webkit-text-stroke-color
-        -webkit-text-stroke-width
-    animation
-        animation-delay
-        animation-direction
-        animation-duration
-        animation-fill-mode
-        animation-iteration-count
-        animation-name
-        animation-play-state
-        animation-range-end
-        animation-range-start
-        animation-timeline
-        animation-timing-function
-    animation-range
-        animation-range-end
-        animation-range-start
-    background
-        background-attachment
-        background-clip
-        background-color
-        background-image
-        background-origin
-        background-position-x
-        background-position-y
-        background-repeat-x
-        background-repeat-y
-        background-size
-    background-position
-        background-position-x
-        background-position-y
-    background-repeat
-        background-repeat-x
-        background-repeat-y
-    border
-        border-bottom-color
-        border-bottom-style
-        border-bottom-width
-        border-image-outset
-        border-image-repeat
-        border-image-slice
-        border-image-source
-        border-image-width
-        border-left-color
-        border-left-style
-        border-left-width
-        border-right-color
-        border-right-style
-        border-right-width
-        border-top-color
-        border-top-style
-        border-top-width
-    border-block
-        border-block-end-color
-        border-block-end-style
-        border-block-end-width
-        border-block-start-color
-        border-block-start-style
-        border-block-start-width
-    border-block-color
-        border-block-end-color
-        border-block-start-color
-    border-block-end
-        border-block-end-color
-        border-block-end-style
-        border-block-end-width
-    border-block-start
-        border-block-start-color
-        border-block-start-style
-        border-block-start-width
-    border-block-style
-        border-block-end-style
-        border-block-start-style
-    border-block-width
-        border-block-end-width
-        border-block-start-width
-    border-bottom
-        border-bottom-color
-        border-bottom-style
-        border-bottom-width
-    border-color
-        border-bottom-color
-        border-left-color
-        border-right-color
-        border-top-color
-    border-image
-        border-image-outset
-        border-image-repeat
-        border-image-slice
-        border-image-source
-        border-image-width
-    border-inline
-        border-inline-end-color
-        border-inline-end-style
-        border-inline-end-width
-        border-inline-start-color
-        border-inline-start-style
-        border-inline-start-width
-    border-inline-color
-        border-inline-end-color
-        border-inline-start-color
-    border-inline-end
-        border-inline-end-color
-        border-inline-end-style
-        border-inline-end-width
-    border-inline-start
-        border-inline-start-color
-        border-inline-start-style
-        border-inline-start-width
-    border-inline-style
-        border-inline-end-style
-        border-inline-start-style
-    border-inline-width
-        border-inline-end-width
-        border-inline-start-width
-    border-left
-        border-left-color
-        border-left-style
-        border-left-width
-    border-radius
-        border-bottom-left-radius
-        border-bottom-right-radius
-        border-top-left-radius
-        border-top-right-radius
-    border-right
-        border-right-color
-        border-right-style
-        border-right-width
-    border-spacing
-        -webkit-border-horizontal-spacing
-        -webkit-border-vertical-spacing
-    border-style
-        border-bottom-style
-        border-left-style
-        border-right-style
-        border-top-style
-    border-top
-        border-top-color
-        border-top-style
-        border-top-width
-    border-width
-        border-bottom-width
-        border-left-width
-        border-right-width
-        border-top-width
-    column-rule
-        column-rule-color
-        column-rule-style
-        column-rule-width
-    columns
-        column-count
-        column-width
-    contain-intrinsic-size
-        contain-intrinsic-height
-        contain-intrinsic-width
-    container
-        container-name
-        container-type
-    flex
-        flex-basis
-        flex-grow
-        flex-shrink
-    flex-flow
-        flex-direction
-        flex-wrap
-    font
-        font-family
-        font-feature-settings
-        font-kerning
-        font-optical-sizing
-        font-size
-        font-size-adjust
-        font-stretch
-        font-style
-        font-variant-alternates
-        font-variant-caps
-        font-variant-east-asian
-        font-variant-ligatures
-        font-variant-numeric
-        font-variant-position
-        font-variation-settings
-        font-weight
-        line-height
-    font-synthesis
-        font-synthesis-small-caps
-        font-synthesis-style
-        font-synthesis-weight
-    font-variant
-        font-variant-alternates
-        font-variant-caps
-        font-variant-east-asian
-        font-variant-ligatures
-        font-variant-numeric
-        font-variant-position
-    gap
-        column-gap
-        row-gap
-    grid
-        grid-auto-columns
-        grid-auto-flow
-        grid-auto-rows
-        grid-template-areas
-        grid-template-columns
-        grid-template-rows
-    grid-area
-        grid-column-end
-        grid-column-start
-        grid-row-end
-        grid-row-start
-    grid-column
-        grid-column-end
-        grid-column-start
-    grid-column-gap
-        column-gap
-    grid-gap
-        column-gap
-        row-gap
-    grid-row
-        grid-row-end
-        grid-row-start
-    grid-row-gap
-        row-gap
-    grid-template
-        grid-template-areas
-        grid-template-columns
-        grid-template-rows
-    inset
-        bottom
-        left
-        right
-        top
-    inset-block
-        inset-block-end
-        inset-block-start
-    inset-inline
-        inset-inline-end
-        inset-inline-start
-    list-style
-        list-style-image
-        list-style-position
-        list-style-type
-    margin
-        margin-bottom
-        margin-left
-        margin-right
-        margin-top
-    margin-block
-        margin-block-end
-        margin-block-start
-    margin-inline
-        margin-inline-end
-        margin-inline-start
-    marker
-        marker-end
-        marker-mid
-        marker-start
-    offset
-        offset-anchor
-        offset-distance
-        offset-path
-        offset-position
-        offset-rotate
-    outline
-        outline-color
-        outline-style
-        outline-width
-    overflow
-        overflow-x
-        overflow-y
-    overscroll-behavior
-        overscroll-behavior-x
-        overscroll-behavior-y
-    padding
-        padding-bottom
-        padding-left
-        padding-right
-        padding-top
-    padding-block
-        padding-block-end
-        padding-block-start
-    padding-inline
-        padding-inline-end
-        padding-inline-start
-    page-break-after
-        break-after
-    page-break-before
-        break-before
-    page-break-inside
-        break-inside
-    place-content
-        align-content
-        justify-content
-    place-items
-        align-items
-        justify-items
-    place-self
-        align-self
-        justify-self
-    scroll-margin
-        scroll-margin-bottom
-        scroll-margin-left
-        scroll-margin-right
-        scroll-margin-top
-    scroll-margin-block
-        scroll-margin-block-end
-        scroll-margin-block-start
-    scroll-margin-inline
-        scroll-margin-inline-end
-        scroll-margin-inline-start
-    scroll-padding
-        scroll-padding-bottom
-        scroll-padding-left
-        scroll-padding-right
-        scroll-padding-top
-    scroll-padding-block
-        scroll-padding-block-end
-        scroll-padding-block-start
-    scroll-padding-inline
-        scroll-padding-inline-end
-        scroll-padding-inline-start
-    scroll-start
-        scroll-start-block
-        scroll-start-inline
-    scroll-start-target
-        scroll-start-target-block
-        scroll-start-target-inline
-    scroll-timeline
-        scroll-timeline-axis
-        scroll-timeline-name
-    text-decoration
-        text-decoration-color
-        text-decoration-line
-        text-decoration-style
-        text-decoration-thickness
-    text-emphasis
-        text-emphasis-color
-        text-emphasis-style
-    toggle
-        toggle-root
-        toggle-trigger
-    transition
-        transition-behavior
-        transition-delay
-        transition-duration
-        transition-property
-        transition-timing-function
-    view-timeline
-        view-timeline-axis
-        view-timeline-inset
-        view-timeline-name
-    white-space
-        text-wrap
-        white-space-collapse
-
-[ALIASES]
-    -epub-caption-side
-        caption-side
-    -epub-text-combine
-        -webkit-text-combine
-    -epub-text-emphasis
-        text-emphasis
-    -epub-text-emphasis-color
-        text-emphasis-color
-    -epub-text-emphasis-style
-        text-emphasis-style
-    -epub-text-orientation
-        -webkit-text-orientation
-    -epub-text-transform
-        text-transform
-    -epub-word-break
-        word-break
-    -epub-writing-mode
-        -webkit-writing-mode
-    -webkit-align-content
-        align-content
-    -webkit-align-items
-        align-items
-    -webkit-align-self
-        align-self
-    -webkit-animation
-        animation
-    -webkit-animation-delay
-        animation-delay
-    -webkit-animation-direction
-        animation-direction
-    -webkit-animation-duration
-        animation-duration
-    -webkit-animation-fill-mode
-        animation-fill-mode
-    -webkit-animation-iteration-count
-        animation-iteration-count
-    -webkit-animation-name
-        animation-name
-    -webkit-animation-play-state
-        animation-play-state
-    -webkit-animation-timing-function
-        animation-timing-function
-    -webkit-app-region
-        app-region
-    -webkit-appearance
-        appearance
-    -webkit-backface-visibility
-        backface-visibility
-    -webkit-background-clip
-        background-clip
-    -webkit-background-origin
-        background-origin
-    -webkit-background-size
-        background-size
-    -webkit-border-after
-        border-block-end
-    -webkit-border-after-color
-        border-block-end-color
-    -webkit-border-after-style
-        border-block-end-style
-    -webkit-border-after-width
-        border-block-end-width
-    -webkit-border-before
-        border-block-start
-    -webkit-border-before-color
-        border-block-start-color
-    -webkit-border-before-style
-        border-block-start-style
-    -webkit-border-before-width
-        border-block-start-width
-    -webkit-border-bottom-left-radius
-        border-bottom-left-radius
-    -webkit-border-bottom-right-radius
-        border-bottom-right-radius
-    -webkit-border-end
-        border-inline-end
-    -webkit-border-end-color
-        border-inline-end-color
-    -webkit-border-end-style
-        border-inline-end-style
-    -webkit-border-end-width
-        border-inline-end-width
-    -webkit-border-radius
-        border-radius
-    -webkit-border-start
-        border-inline-start
-    -webkit-border-start-color
-        border-inline-start-color
-    -webkit-border-start-style
-        border-inline-start-style
-    -webkit-border-start-width
-        border-inline-start-width
-    -webkit-border-top-left-radius
-        border-top-left-radius
-    -webkit-border-top-right-radius
-        border-top-right-radius
-    -webkit-box-shadow
-        box-shadow
-    -webkit-box-sizing
-        box-sizing
-    -webkit-clip-path
-        clip-path
-    -webkit-column-count
-        column-count
-    -webkit-column-gap
-        column-gap
-    -webkit-column-rule
-        column-rule
-    -webkit-column-rule-color
-        column-rule-color
-    -webkit-column-rule-style
-        column-rule-style
-    -webkit-column-rule-width
-        column-rule-width
-    -webkit-column-span
-        column-span
-    -webkit-column-width
-        column-width
-    -webkit-columns
-        columns
-    -webkit-filter
-        filter
-    -webkit-flex
-        flex
-    -webkit-flex-basis
-        flex-basis
-    -webkit-flex-direction
-        flex-direction
-    -webkit-flex-flow
-        flex-flow
-    -webkit-flex-grow
-        flex-grow
-    -webkit-flex-shrink
-        flex-shrink
-    -webkit-flex-wrap
-        flex-wrap
-    -webkit-font-feature-settings
-        font-feature-settings
-    -webkit-hyphenate-character
-        hyphenate-character
-    -webkit-justify-content
-        justify-content
-    -webkit-logical-height
-        block-size
-    -webkit-logical-width
-        inline-size
-    -webkit-margin-after
-        margin-block-end
-    -webkit-margin-before
-        margin-block-start
-    -webkit-margin-end
-        margin-inline-end
-    -webkit-margin-start
-        margin-inline-start
-    -webkit-mask-clip
-        mask-clip
-    -webkit-mask-image
-        mask-image
-    -webkit-mask-origin
-        mask-origin
-    -webkit-mask-size
-        mask-size
-    -webkit-max-logical-height
-        max-block-size
-    -webkit-max-logical-width
-        max-inline-size
-    -webkit-min-logical-height
-        min-block-size
-    -webkit-min-logical-width
-        min-inline-size
-    -webkit-opacity
-        opacity
-    -webkit-order
-        order
-    -webkit-padding-after
-        padding-block-end
-    -webkit-padding-before
-        padding-block-start
-    -webkit-padding-end
-        padding-inline-end
-    -webkit-padding-start
-        padding-inline-start
-    -webkit-perspective
-        perspective
-    -webkit-perspective-origin
-        perspective-origin
-    -webkit-shape-image-threshold
-        shape-image-threshold
-    -webkit-shape-margin
-        shape-margin
-    -webkit-shape-outside
-        shape-outside
-    -webkit-text-emphasis
-        text-emphasis
-    -webkit-text-emphasis-color
-        text-emphasis-color
-    -webkit-text-emphasis-position
-        text-emphasis-position
-    -webkit-text-emphasis-style
-        text-emphasis-style
-    -webkit-text-size-adjust
-        text-size-adjust
-    -webkit-transform
-        transform
-    -webkit-transform-origin
-        transform-origin
-    -webkit-transform-style
-        transform-style
-    -webkit-transition
-        transition
-    -webkit-transition-delay
-        transition-delay
-    -webkit-transition-duration
-        transition-duration
-    -webkit-transition-property
-        transition-property
-    -webkit-transition-timing-function
-        transition-timing-function
-    -webkit-user-select
-        user-select
-    word-wrap
-        overflow-wrap
-
diff --git a/third_party/chromium-variations b/third_party/chromium-variations
index 6a94fae..118eb36 160000
--- a/third_party/chromium-variations
+++ b/third_party/chromium-variations
@@ -1 +1 @@
-Subproject commit 6a94fae344833b2e4c170955c9b10fa3a40c5550
+Subproject commit 118eb368c73b8895223c9614b11b48ec5d3ec851
diff --git a/third_party/cros-components/src b/third_party/cros-components/src
index f448b44..e8ae400 160000
--- a/third_party/cros-components/src
+++ b/third_party/cros-components/src
@@ -1 +1 @@
-Subproject commit f448b44c03202bdb5fb1305216d4723724d5288b
+Subproject commit e8ae400644fdede4c5bbaa6e8157e6411c6b0b7e
diff --git a/third_party/devtools-frontend-internal b/third_party/devtools-frontend-internal
index 6b248f3..1b8b0c8 160000
--- a/third_party/devtools-frontend-internal
+++ b/third_party/devtools-frontend-internal
@@ -1 +1 @@
-Subproject commit 6b248f365bc8723b398e68704df495ecfbf3f8ee
+Subproject commit 1b8b0c8770a2e7a17e0b9297b464364d5a363839
diff --git a/third_party/devtools-frontend/src b/third_party/devtools-frontend/src
index 891806c..abd45dd 160000
--- a/third_party/devtools-frontend/src
+++ b/third_party/devtools-frontend/src
@@ -1 +1 @@
-Subproject commit 891806c2cf2bfe370e5e865269042afafbf9a569
+Subproject commit abd45dd7ffc41e93c8c3d7bf82ca7bcb420d94a1
diff --git a/third_party/libgav1/options.gni b/third_party/libgav1/options.gni
index 68abc77..3b35a5d 100644
--- a/third_party/libgav1/options.gni
+++ b/third_party/libgav1/options.gni
@@ -6,8 +6,5 @@
 import("//build/config/gclient_args.gni")
 
 declare_args() {
-  use_libgav1_parser =
-      (is_chromeos || is_linux || is_win || is_apple) &&
-      (target_cpu == "x86" || target_cpu == "x64" || target_cpu == "arm" ||
-       target_cpu == "arm64" || target_cpu == "ppc64")
+  use_libgav1_parser = true
 }
diff --git a/third_party/nearby/README.chromium b/third_party/nearby/README.chromium
index 88311ff0..84bbe9f 100644
--- a/third_party/nearby/README.chromium
+++ b/third_party/nearby/README.chromium
@@ -1,7 +1,7 @@
 Name: Nearby Connections Library
 Short Name: Nearby
 URL: https://github.com/google/nearby
-Version: 85091845a8471a776df9461d476f733304b13c8e
+Version: 32740f8591a568a2e3a6f54b018cd0874e5af2ff
 License: Apache 2.0
 License File: LICENSE
 Security Critical: yes
diff --git a/third_party/nearby/src b/third_party/nearby/src
index 8509184..32740f8 160000
--- a/third_party/nearby/src
+++ b/third_party/nearby/src
@@ -1 +1 @@
-Subproject commit 85091845a8471a776df9461d476f733304b13c8e
+Subproject commit 32740f8591a568a2e3a6f54b018cd0874e5af2ff
diff --git a/third_party/skia b/third_party/skia
index 63bed82..6dc3b52 160000
--- a/third_party/skia
+++ b/third_party/skia
@@ -1 +1 @@
-Subproject commit 63bed826008ee7e0170ce9224c6aaab1b2f720f7
+Subproject commit 6dc3b52777daccbaf1f3a28b2e2bd39c7a4d38e1
diff --git a/third_party/tflite/README.chromium b/third_party/tflite/README.chromium
index 26bb419c..de52bb9a 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: 40fde191ba7aedececf64b73854a74b344bccdb7
-Date: 2023-12-11
+Version: 6ecc7e35b190face7769a9eb29f21aed7ea077cc
+Date: 2023-12-18
 License: Apache 2.0
 License File: LICENSE
 Security Critical: Yes
diff --git a/third_party/tflite/src b/third_party/tflite/src
index 40fde19..6ecc7e3 160000
--- a/third_party/tflite/src
+++ b/third_party/tflite/src
@@ -1 +1 @@
-Subproject commit 40fde191ba7aedececf64b73854a74b344bccdb7
+Subproject commit 6ecc7e35b190face7769a9eb29f21aed7ea077cc
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 8413e82..996eed22 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -4878,6 +4878,11 @@
   <int value="3" label="PREDICTION_SOURCE_OVERALL"/>
 </enum>
 
+<enum name="AutofillPreFilledFields">
+  <int value="0" label="Pre-filled on page load"/>
+  <int value="1" label="Empty on page load"/>
+</enum>
+
 <enum name="AutofillProfileAction">
   <int value="0" label="Existing profile used"/>
   <int value="1" label="Existing profile updated"/>
@@ -10852,6 +10857,7 @@
 <enum name="CvcFillingFlowType">
   <int value="0" label="CVC filled without any interactive authentication"/>
   <int value="1" label="CVC filled by FIDO authentication"/>
+  <int value="2" label="CVC filed by mandatory re-auth"/>
 </enum>
 
 <enum name="DaemonError">
@@ -33940,6 +33946,7 @@
   <int value="373275338" label="AndroidPartnerCustomizationPhenotype:disabled"/>
   <int value="373531060" label="MacCoreLocationBackend:enabled"/>
   <int value="373578344" label="SafeBrowsingSecuritySectionUIAndroid:enabled"/>
+  <int value="373617942" label="PulseaudioLoopbackForCast:disabled"/>
   <int value="373805498" label="OmniboxExpandedStateShape:enabled"/>
   <int value="375032683" label="CellularAllowPerNetworkRoaming:enabled"/>
   <int value="375485858" label="EnableZeroStateMixedTypesRanker:disabled"/>
@@ -34495,6 +34502,7 @@
   <int value="649384106" label="FailFastQuietChip:disabled"/>
   <int value="649508040" label="AutofillEnableCompanyName:enabled"/>
   <int value="650013099" label="PrivacySandboxSettings2:disabled"/>
+  <int value="650168383" label="PulseaudioLoopbackForScreenShare:enabled"/>
   <int value="651421878" label="VideoRotateToFullscreen:enabled"/>
   <int value="651471603" label="MediaFoundationD3D11VideoCapture:enabled"/>
   <int value="651562604" label="RawClipboard:enabled"/>
@@ -36204,6 +36212,7 @@
   <int value="1458583431" label="arc-use-auth-endpoint"/>
   <int value="1459529277" label="disable-text-input-focus-manager"/>
   <int value="1459803015" label="WebRtcEnableCaptureMultiChannelApm:enabled"/>
+  <int value="1460266536" label="PulseaudioLoopbackForScreenShare:disabled"/>
   <int value="1460747747" label="GdiTextPrinting:enabled"/>
   <int value="1460958818" label="NTPForeignSessionsSuggestions:enabled"/>
   <int value="1461581256" label="MovablePartialScreenshot:enabled"/>
@@ -36383,6 +36392,7 @@
   <int value="1547049944" label="ScalableIph:enabled"/>
   <int value="1548776701" label="AllBookmarks:disabled"/>
   <int value="1548942246" label="PassiveDocumentEventListeners:disabled"/>
+  <int value="1550193978" label="PulseaudioLoopbackForCast:enabled"/>
   <int value="1550865563" label="AnimatedImageDragShadow:enabled"/>
   <int value="1551743170"
       label="WebAuthenticationNewDiscoverableCredentialsUi:disabled"/>
diff --git a/tools/metrics/histograms/metadata/autofill/histograms.xml b/tools/metrics/histograms/metadata/autofill/histograms.xml
index 84b2edb8..8027654 100644
--- a/tools/metrics/histograms/metadata/autofill/histograms.xml
+++ b/tools/metrics/histograms/metadata/autofill/histograms.xml
@@ -2344,6 +2344,23 @@
   </summary>
 </histogram>
 
+<histogram name="Autofill.Iban.UnmaskIbanDuration{UnmaskIbanResult}" units="ms"
+    expires_after="2024-07-01">
+  <owner>qihuizhao@google.com</owner>
+  <owner>jsaul@google.com</owner>
+  <owner>payments-autofill-team@google.com</owner>
+  <summary>
+    Recorded at a successful return of an unmask server IBAN call. This metric
+    tracks the duration from the user's click on a server IBAN suggestion to the
+    successful reception of a response of unmasking a server IBAN.
+  </summary>
+  <token key="UnmaskIbanResult">
+    <variant name="" summary="UnmaskIban request overall"/>
+    <variant name=".Failure" summary="UnmaskIban request failed"/>
+    <variant name=".Success" summary="UnmaskIban request succeeded"/>
+  </token>
+</histogram>
+
 <histogram name="Autofill.IbanUploadEnabled" enum="IbanUploadEnabledStatus"
     expires_after="2024-07-01">
   <owner>qihuizhao@google.com</owner>
@@ -3481,6 +3498,17 @@
   </summary>
 </histogram>
 
+<histogram name="Autofill.PreFilledFields.{FormType}"
+    enum="AutofillPreFilledFields" expires_after="2024-05-10">
+  <owner>bwolfgang@google.com</owner>
+  <owner>chrome-autofill-team@google.com</owner>
+  <summary>
+    Records the number of fields that are pre-filled or empty on page load. The
+    metric is emitted on form submission.
+  </summary>
+  <token key="FormType" variants="Autofill.Ablation.FormType"/>
+</histogram>
+
 <histogram name="Autofill.PreviouslyHiddenSuggestionNumber" units="suggestions"
     expires_after="2024-12-12">
   <owner>jihadghanna@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/memory/histograms.xml b/tools/metrics/histograms/metadata/memory/histograms.xml
index 1d659c7..00e10ee 100644
--- a/tools/metrics/histograms/metadata/memory/histograms.xml
+++ b/tools/metrics/histograms/metadata/memory/histograms.xml
@@ -2392,7 +2392,7 @@
 </histogram>
 
 <histogram name="Memory.VmmSwap.{VmName}.DisableReason"
-    enum="VmmSwapDisableReason" expires_after="2024-04-28">
+    enum="VmmSwapDisableReason" expires_after="2024-06-02">
   <owner>kawasin@google.com</owner>
   <owner>sstan@google.com</owner>
   <summary>
@@ -2406,7 +2406,7 @@
 </histogram>
 
 <histogram name="Memory.VmmSwap.{VmName}.InactiveBeforeEnableDuration"
-    units="Hours" expires_after="2024-01-31">
+    units="Hours" expires_after="2024-06-02">
   <owner>kawasin@google.com</owner>
   <owner>sstan@google.com</owner>
   <summary>
@@ -2458,7 +2458,7 @@
 </histogram>
 
 <histogram name="Memory.VmmSwap.{VmName}.PolicyResult"
-    enum="VmmSwapPolicyResult" expires_after="2024-04-28">
+    enum="VmmSwapPolicyResult" expires_after="2024-06-02">
   <owner>kawasin@google.com</owner>
   <owner>sstan@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/stability/enums.xml b/tools/metrics/histograms/metadata/stability/enums.xml
index b79600c6..28374b2 100644
--- a/tools/metrics/histograms/metadata/stability/enums.xml
+++ b/tools/metrics/histograms/metadata/stability/enums.xml
@@ -476,6 +476,8 @@
   <int value="311" label="MSDH_SEND_WHEEL_INVALID_ACTION"/>
   <int value="312" label="MSDH_GET_ZOOM_LEVEL_BUT_CSC_FEATURE_DISABLED"/>
   <int value="313" label="RFH_FENCED_DOCUMENT_DATA_NOT_FOUND"/>
+  <int value="314" label="MSDH_SET_ZOOM_LEVEL_BUT_CSC_FEATURE_DISABLED"/>
+  <int value="315" label="MSDH_SET_ZOOM_LEVEL_INVALID_LEVEL"/>
 </enum>
 
 <enum name="BadMessageReasonExtensions">
diff --git a/tools/metrics/histograms/metadata/stability/histograms.xml b/tools/metrics/histograms/metadata/stability/histograms.xml
index 78e31538..80eb0149 100644
--- a/tools/metrics/histograms/metadata/stability/histograms.xml
+++ b/tools/metrics/histograms/metadata/stability/histograms.xml
@@ -398,19 +398,6 @@
   </summary>
 </histogram>
 
-<histogram name="Stability.iOS.UTE.AvailableStorage" units="KB"
-    expires_after="2021-10-10">
-  <owner>michaeldo@chromium.org</owner>
-  <owner>olivierrobin@chromium.org</owner>
-  <summary>
-    Number of kilobytes available for &quot;important&quot; data. When an iOS
-    device is critically low on space, actions generally assumed to succeed can
-    fail. In extreme cases, this could potentially include writing the
-    &quot;unclean shutdown&quot; bit to signal a clean shutdown. Logged on
-    application launch if the last session terminated in an unclean state.
-  </summary>
-</histogram>
-
 <histogram name="Stability.iOS.UTE.BatteryCharge" units="%"
     expires_after="2024-05-01">
   <owner>michaeldo@chromium.org</owner>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index e8ae477..1e787e0 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -13,8 +13,8 @@
             "full_remote_path": "perfetto-luci-artifacts/3e53e144bee271ec558363df2e561a77d7e0b789/linux-arm/trace_processor_shell"
         },
         "mac": {
-            "hash": "d4b484d9567370f690c6af2cf4e26fc973c673ec",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/819068d7e83a09200ee0b3a43fe44d90465cca5e/trace_processor_shell"
+            "hash": "c584fa0ead673b142de66fb9fed98c95679f9cb9",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/84bb6bced2420d2e7bd880cbf30b348448fa95d4/trace_processor_shell"
         },
         "mac_arm64": {
             "hash": "28d38c5eef93cf965ad3b3c656d4419f8e55f864",
diff --git a/ui/events/event.cc b/ui/events/event.cc
index 3347c45..83f097e 100644
--- a/ui/events/event.cc
+++ b/ui/events/event.cc
@@ -301,8 +301,9 @@
 
 std::string Event::ToString() const {
   return base::StrCat(
-      {GetName(), " time_stamp ",
-       base::NumberToString(time_stamp_.since_origin().InSecondsF())});
+      {GetName(), " time_stamp=",
+       base::NumberToString(time_stamp_.since_origin().InSecondsF()),
+       " source_device_id=", base::NumberToString(source_device_id_)});
 }
 
 Event::Event(EventType type, base::TimeTicks time_stamp, int flags)
@@ -422,8 +423,8 @@
 }
 
 std::string LocatedEvent::ToString() const {
-  return base::StrCat({Event::ToString(), " location ", location_.ToString(),
-                       " root_location ", root_location_.ToString()});
+  return base::StrCat({Event::ToString(), " location=", location_.ToString(),
+                       " root_location=", root_location_.ToString()});
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -592,10 +593,12 @@
 }
 
 std::string MouseEvent::ToString() const {
-  return base::StrCat(
-      {LocatedEvent::ToString(), " flags ",
-       base::JoinString(base::make_span(MouseEventFlagsNames(flags())),
-                        " | ")});
+  return base::StrCat({
+      LocatedEvent::ToString(),
+      " flags=",
+      base::JoinString(base::make_span(MouseEventFlagsNames(flags())), "|"),
+      base::StringPrintf("(0x%04x)", flags()),
+  });
 }
 
 std::unique_ptr<Event> MouseEvent::Clone() const {
@@ -1157,10 +1160,25 @@
 }
 
 std::string KeyEvent::ToString() const {
-  return base::StrCat(
-      {Event::ToString(), " key ", base::StringPrintf("(0x%.4x)", key_code_),
-       " flags ",
-       base::JoinString(base::make_span(KeyEventFlagsNames(flags())), " | ")});
+  auto dom_key = GetDomKey();
+  return base::StrCat({
+      Event::ToString(),
+      " code=",
+      KeycodeConverter::DomCodeToCodeString(code()),
+      base::StringPrintf("(0x%04x)", static_cast<uint32_t>(code_)),
+      " key=",
+      KeycodeConverter::DomKeyToKeyString(dom_key),
+      base::StringPrintf("(0x%04x)", static_cast<uint32_t>(dom_key)),
+      " keycode=",
+      base::StringPrintf("(0x%04x)", key_code_),
+#if BUILDFLAG(IS_OZONE)
+      " scan_code=",
+      base::StringPrintf("(0x%04x)", scan_code_),
+#endif  // BUILDFLAG(IS_OZONE)
+      " flags=",
+      base::JoinString(base::make_span(KeyEventFlagsNames(flags())), "|"),
+      base::StringPrintf("(0x%04x)", flags()),
+  });
 }
 
 std::unique_ptr<Event> KeyEvent::Clone() const {
@@ -1272,11 +1290,16 @@
 }
 
 std::string ScrollEvent::ToString() const {
-  return base::StringPrintf(
-      "%s offset %g,%g offset_ordinal %g,%g momentum_phase %s event_phase %s",
-      MouseEvent::ToString().c_str(), x_offset_, y_offset_, x_offset_ordinal_,
-      y_offset_ordinal_, MomentumPhaseToString(momentum_phase_).c_str(),
-      ScrollEventPhaseToString(scroll_event_phase_).c_str());
+  return base::StrCat({
+      MouseEvent::ToString(),
+      base::StringPrintf(" offset=%g,%g", x_offset_, y_offset_),
+      base::StringPrintf(" offset_ordinal=%g,%g", x_offset_ordinal_,
+                         y_offset_ordinal_),
+      " momentum_phase=",
+      MomentumPhaseToString(momentum_phase_),
+      " event_phase=",
+      ScrollEventPhaseToString(scroll_event_phase_),
+  });
 }
 
 std::unique_ptr<Event> ScrollEvent::Clone() const {
@@ -1312,9 +1335,11 @@
 GestureEvent::~GestureEvent() = default;
 
 std::string GestureEvent::ToString() const {
-  return base::StringPrintf("%s touch_event_id %d",
-                            LocatedEvent::ToString().c_str(),
-                            unique_touch_event_id_);
+  return base::StrCat({
+      LocatedEvent::ToString(),
+      " touch_event_id=",
+      base::NumberToString(unique_touch_event_id_),
+  });
 }
 
 std::unique_ptr<Event> GestureEvent::Clone() const {
diff --git a/ui/file_manager/file_manager/common/js/files_app_entry_types.ts b/ui/file_manager/file_manager/common/js/files_app_entry_types.ts
index 789fc48..1525a774 100644
--- a/ui/file_manager/file_manager/common/js/files_app_entry_types.ts
+++ b/ui/file_manager/file_manager/common/js/files_app_entry_types.ts
@@ -25,6 +25,7 @@
 import {ErrorCallback, FakeEntry, FileEntryCallback, FileErrorCallback, FilesAppDirEntry, FilesAppEntry, MetadataCallback} from '../../externs/files_app_entry_interfaces.js';
 import type {VolumeInfo} from '../../externs/volume_info.js';
 
+import {isSameEntry} from './entry_utils.js';
 import {vmTypeToIconName} from './icon_util.js';
 import {getVolumeTypeFromRootType, RootType, VolumeType} from './volume_manager_types.js';
 
@@ -285,7 +286,7 @@
    */
   removeChildEntry(entry: Entry|FilesAppEntry): boolean {
     const childIndex =
-        this.children_.findIndex(childEntry => childEntry === entry);
+        this.children_.findIndex(childEntry => isSameEntry(childEntry, entry));
     if (childIndex !== -1) {
       this.children_.splice(childIndex, 1);
       return true;
@@ -568,7 +569,7 @@
    */
   removeChildEntry(entry: Entry|FilesAppEntry): boolean {
     const childIndex =
-        this.children_.findIndex(childEntry => childEntry === entry);
+        this.children_.findIndex(childEntry => isSameEntry(childEntry, entry));
     if (childIndex !== -1) {
       this.children_.splice(childIndex, 1);
       return true;
diff --git a/ui/file_manager/file_manager/externs/drag_target.js b/ui/file_manager/file_manager/externs/drag_target.js
deleted file mode 100644
index 3ceb289..0000000
--- a/ui/file_manager/file_manager/externs/drag_target.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2017 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @interface
- */
-class DragTarget {
-  /**
-   * This definition is required to satisfy
-   *
-   * @param {number} x
-   * @param {number} y
-   * @param {number=} opt_width
-   * @param {number=} opt_height
-   * @return {Array<number>}
-   */
-  getHitElements(x, y, opt_width, opt_height) {}
-}
diff --git a/ui/file_manager/file_manager/foreground/js/crostini_controller.ts b/ui/file_manager/file_manager/foreground/js/crostini_controller.ts
index cb5f568..a3d2134 100644
--- a/ui/file_manager/file_manager/foreground/js/crostini_controller.ts
+++ b/ui/file_manager/file_manager/foreground/js/crostini_controller.ts
@@ -36,6 +36,7 @@
    * changes.
    */
   async redraw() {
+    const store = getStore();
     // Setup Linux files fake root.
     let crostiniNavigationModelItem;
     if (this.crostini_.isEnabled(DEFAULT_CROSTINI_VM)) {
@@ -45,10 +46,10 @@
           str('LINUX_FILES_ROOT_LABEL'), NavigationModelItemType.CROSTINI,
           crostiniEntry);
       crostiniNavigationModelItem.disabled = this.disabled_;
-      getStore().dispatch(addUiEntry({entry: crostiniEntry}));
+      store.dispatch(addUiEntry(crostiniEntry));
     } else {
       crostiniNavigationModelItem = null;
-      getStore().dispatch(removeUiEntry({key: crostiniPlaceHolderKey}));
+      store.dispatch(removeUiEntry(crostiniPlaceHolderKey));
     }
     if (!isNewDirectoryTreeEnabled()) {
       this.directoryTree_.dataModel.linuxFilesItem =
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager.ts b/ui/file_manager/file_manager/foreground/js/file_manager.ts
index 9014294..e7d2897 100644
--- a/ui/file_manager/file_manager/foreground/js/file_manager.ts
+++ b/ui/file_manager/file_manager/foreground/js/file_manager.ts
@@ -997,7 +997,7 @@
     this.recentEntry_ = new FakeEntryImpl(
         str('RECENT_ROOT_LABEL'), RootType.RECENT, this.getSourceRestriction_(),
         chrome.fileManagerPrivate.FileCategory.ALL);
-    this.store_.dispatch(addUiEntry({entry: this.recentEntry_}));
+    this.store_.dispatch(addUiEntry(this.recentEntry_));
     assert(this.launchParams_);
     this.selectionHandler_ = new FileSelectionHandler(
         this.directoryModel_, this.ui_.listContainer, this.metadataModel_,
@@ -1698,8 +1698,7 @@
             str('TRASH_ROOT_LABEL'), NavigationModelItemType.TRASH,
             new TrashRootEntry());
       }
-      this.store_.dispatch(
-          addUiEntry({entry: this.fakeTrashItem_.entry as FakeEntry}));
+      this.store_.dispatch(addUiEntry(this.fakeTrashItem_.entry as FakeEntry));
       assert(this.ui_.directoryTree);
       if (!isXfTree(this.ui_.directoryTree)) {
         this.ui_.directoryTree!.dataModel.fakeTrashItem = this.fakeTrashItem_;
@@ -1707,7 +1706,7 @@
       return;
     }
 
-    this.store_.dispatch(removeUiEntry({key: trashRootKey}));
+    this.store_.dispatch(removeUiEntry(trashRootKey));
     assert(this.ui_.directoryTree);
     if (!isXfTree(this.ui_.directoryTree)) {
       this.ui_.directoryTree!.dataModel.fakeTrashItem = null;
@@ -1726,7 +1725,7 @@
       if (!driveFakeRoot) {
         driveFakeRoot = new EntryList(
             str('DRIVE_DIRECTORY_LABEL'), RootType.DRIVE_FAKE_ROOT);
-        this.store_.dispatch(addUiEntry({entry: driveFakeRoot}));
+        this.store_.dispatch(addUiEntry(driveFakeRoot));
       }
       assert(this.ui.directoryTree);
       if (!isXfTree(this.ui.directoryTree)) {
@@ -1744,7 +1743,7 @@
       }
       return;
     }
-    this.store_.dispatch(removeUiEntry({key: driveRootEntryListKey}));
+    this.store_.dispatch(removeUiEntry(driveRootEntryListKey));
     assert(this.ui.directoryTree);
     if (!isXfTree(this.ui.directoryTree)) {
       this.ui.directoryTree!.dataModel.fakeDriveItem = null;
diff --git a/ui/file_manager/file_manager/foreground/js/guest_os_controller.ts b/ui/file_manager/file_manager/foreground/js/guest_os_controller.ts
index 81f7182..f4fd0f1f 100644
--- a/ui/file_manager/file_manager/foreground/js/guest_os_controller.ts
+++ b/ui/file_manager/file_manager/foreground/js/guest_os_controller.ts
@@ -18,8 +18,8 @@
  */
 export class GuestOsController {
   constructor(
-    private readonly directoryTree_: DirectoryTree,
-    private readonly volumeManager_: VolumeManager) {
+      private readonly directoryTree_: DirectoryTree,
+      private readonly volumeManager_: VolumeManager) {
     if (!isGuestOsEnabled()) {
       console.warn('Created a guest os controller when it\'s not enabled');
     }
@@ -52,7 +52,7 @@
       const uiEntry = getEntry(state, uiEntryKey);
       if (uiEntry && 'guest_id' in uiEntry &&
           !newGuestIdSet.has((uiEntry as GuestOsPlaceholder).guest_id)) {
-        store.dispatch(removeUiEntry({key: uiEntryKey}));
+        store.dispatch(removeUiEntry(uiEntryKey));
       }
     }
 
@@ -67,7 +67,7 @@
           VolumeType.GUEST_OS;
 
       navigationModelItem.disabled = this.volumeManager_.isDisabled(volumeType);
-      store.dispatch(addUiEntry({entry: guestOsEntry}));
+      store.dispatch(addUiEntry(guestOsEntry));
       return navigationModelItem;
     });
 
diff --git a/ui/file_manager/file_manager/foreground/js/ui/drag_selector.js b/ui/file_manager/file_manager/foreground/js/ui/drag_selector.js
deleted file mode 100644
index 31b1d3da..0000000
--- a/ui/file_manager/file_manager/foreground/js/ui/drag_selector.js
+++ /dev/null
@@ -1,310 +0,0 @@
-// Copyright 2013 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import {List} from './list.js';
-
-export class DragSelector {
-  /**
-   * Drag selector used on the file list or the grid table.
-   */
-  constructor() {
-    /**
-     * Target list of drag selection.
-     * @type {List}
-     * @private
-     */
-    // @ts-ignore: error TS2322: Type 'null' is not assignable to type 'List'.
-    this.target_ = null;
-
-    /**
-     * Border element of drag handle.
-     * @type {Element}
-     * @private
-     */
-    // @ts-ignore: error TS2322: Type 'null' is not assignable to type
-    // 'Element'.
-    this.border_ = null;
-
-    /**
-     * Start point of dragging.
-     * @type {number?}
-     * @private
-     */
-    this.startX_ = null;
-
-    /**
-     * Start point of dragging.
-     * @type {number?}
-     * @private
-     */
-    this.startY_ = null;
-
-    /**
-     * Indexes of selected items by dragging at the last update.
-     * @type {Array<number>!}
-     * @private
-     */
-    this.lastSelection_ = [];
-
-    /**
-     * Indexes of selected items at the start of dragging.
-     * @type {Array<number>!}
-     * @private
-     */
-    this.originalSelection_ = [];
-
-    // Bind handlers to make them removable.
-    this.onMouseMoveBound_ = this.onMouseMove_.bind(this);
-    this.onMouseUpBound_ = this.onMouseUp_.bind(this);
-  }
-
-  /**
-   * Obtains the scrolled position in the element of mouse pointer from the
-   * mouse event.
-   *
-   * @param {HTMLElement} element Element that has the scroll bars.
-   * @param {MouseEvent} event The mouse event.
-   * @return {?{x:number, y:number}} Scrolled position.
-   */
-  static getScrolledPosition(element, event) {
-    // @ts-ignore: error TS2339: Property 'cachedBounds' does not exist on type
-    // 'HTMLElement'.
-    if (!element.cachedBounds) {
-      // @ts-ignore: error TS2339: Property 'cachedBounds' does not exist on
-      // type 'HTMLElement'.
-      element.cachedBounds = element.getBoundingClientRect();
-      // @ts-ignore: error TS2339: Property 'cachedBounds' does not exist on
-      // type 'HTMLElement'.
-      if (!element.cachedBounds) {
-        return null;
-      }
-    }
-    // @ts-ignore: error TS2339: Property 'cachedBounds' does not exist on type
-    // 'HTMLElement'.
-    const rect = element.cachedBounds;
-    return {
-      x: event.clientX - rect.left + element.scrollLeft,
-      y: event.clientY - rect.top + element.scrollTop,
-    };
-  }
-
-  /**
-   * Starts drag selection by reacting dragstart event.
-   * This function must be called from handlers of dragstart event.
-   *
-   * @this {DragSelector}
-   * @param {List} list List where the drag selection starts.
-   * @param {MouseEvent} event The dragstart event.
-   */
-  startDragSelection(list, event) {
-    // Precondition check
-    // @ts-ignore: error TS2551: Property 'selectionModel_' does not exist on
-    // type 'List'. Did you mean 'selectionModel'?
-    if (!list.selectionModel_.multiple || this.target_) {
-      return;
-    }
-
-    // Set the target of the drag selection
-    this.target_ = list;
-
-    // Save the start state.
-    const startPos = DragSelector.getScrolledPosition(list, event);
-    if (!startPos) {
-      return;
-    }
-    // @ts-ignore: error TS2339: Property 'x' does not exist on type 'Object'.
-    this.startX_ = startPos.x;
-    // @ts-ignore: error TS2339: Property 'y' does not exist on type 'Object'.
-    this.startY_ = startPos.y;
-    this.lastSelection_ = [];
-    // @ts-ignore: error TS2551: Property 'selectionModel_' does not exist on
-    // type 'List'. Did you mean 'selectionModel'?
-    this.originalSelection_ = this.target_.selectionModel_.selectedIndexes;
-
-    // Create and add the border element
-    if (!this.border_) {
-      this.border_ = this.target_.ownerDocument.createElement('div');
-      this.border_.className = 'drag-selection-border';
-    }
-    // @ts-ignore: error TS2339: Property 'style' does not exist on type
-    // 'Element'.
-    this.border_.style.left = this.startX_ + 'px';
-    // @ts-ignore: error TS2339: Property 'style' does not exist on type
-    // 'Element'.
-    this.border_.style.top = this.startY_ + 'px';
-    // @ts-ignore: error TS2339: Property 'style' does not exist on type
-    // 'Element'.
-    this.border_.style.width = '0';
-    // @ts-ignore: error TS2339: Property 'style' does not exist on type
-    // 'Element'.
-    this.border_.style.height = '0';
-    list.appendChild(this.border_);
-
-    // Register event handlers.
-    // The handlers are bounded at the constructor.
-    this.target_.ownerDocument.addEventListener(
-        'mousemove', this.onMouseMoveBound_, true);
-    this.target_.ownerDocument.addEventListener(
-        'mouseup', this.onMouseUpBound_, true);
-  }
-
-  /**
-   * Handles the mousemove event.
-   * @private
-   * @param {MouseEvent} event The mousemove event.
-   */
-  onMouseMove_(event) {
-    event = /** @type {MouseEvent} */ (event);
-    // Get the selection bounds.
-    const pos = DragSelector.getScrolledPosition(this.target_, event);
-    const borderBounds = {
-      // @ts-ignore: error TS2339: Property 'x' does not exist on type 'Object'.
-      left: Math.max(Math.min(this.startX_, pos.x), 0),
-      // @ts-ignore: error TS2339: Property 'y' does not exist on type 'Object'.
-      top: Math.max(Math.min(this.startY_, pos.y), 0),
-      // @ts-ignore: error TS2339: Property 'x' does not exist on type 'Object'.
-      right: Math.min(Math.max(this.startX_, pos.x), this.target_.scrollWidth),
-      bottom: Math.min(
-          // @ts-ignore: error TS2339: Property 'y' does not exist on type
-          // 'Object'.
-          Math.max(this.startY_, pos.y), this.target_.scrollHeight),
-    };
-    // @ts-ignore: error TS2339: Property 'width' does not exist on type '{
-    // left: number; top: number; right: number; bottom: number; }'.
-    borderBounds.width = borderBounds.right - borderBounds.left;
-    // @ts-ignore: error TS2339: Property 'height' does not exist on type '{
-    // left: number; top: number; right: number; bottom: number; }'.
-    borderBounds.height = borderBounds.bottom - borderBounds.top;
-
-    // Collect items within the selection rect.
-    const currentSelection =
-        // @ts-ignore: error TS2304: Cannot find name 'DragTarget'.
-        (/** @type {DragTarget} */ (this.target_))
-            .getHitElements(
-                borderBounds.left, borderBounds.top,
-                // @ts-ignore: error TS2339: Property 'height' does not exist on
-                // type '{ left: number; top: number; right: number; bottom:
-                // number; }'.
-                borderBounds.width, borderBounds.height);
-    const pointedElements =
-        // @ts-ignore: error TS2339: Property 'y' does not exist on type
-        // 'Object'.
-        (/** @type {DragTarget} */ (this.target_)).getHitElements(pos.x, pos.y);
-    const leadIndex = pointedElements.length ? pointedElements[0] : -1;
-
-    // Diff the selection between currentSelection and this.lastSelection_.
-    // @ts-ignore: error TS7034: Variable 'selectionFlag' implicitly has type
-    // 'any[]' in some locations where its type cannot be determined.
-    const selectionFlag = [];
-    for (let i = 0; i < this.lastSelection_.length; i++) {
-      const index = this.lastSelection_[i];
-      // Bit operator can be used for undefined value.
-      // @ts-ignore: error TS2538: Type 'undefined' cannot be used as an index
-      // type.
-      selectionFlag[index] =
-          // @ts-ignore: error TS2538: Type 'undefined' cannot be used as an
-          // index type.
-          selectionFlag[index] | SelectionFlag_.IN_LAST_SELECTION;
-    }
-    for (let i = 0; i < currentSelection.length; i++) {
-      const index = currentSelection[i];
-      // Bit operator can be used for undefined value.
-      selectionFlag[index] =
-          // @ts-ignore: error TS2532: Object is possibly 'undefined'.
-          selectionFlag[index] | SelectionFlag_.IN_CURRENT_SELECTION;
-    }
-
-    // Update the selection
-    // @ts-ignore: error TS2551: Property 'selectionModel_' does not exist on
-    // type 'List'. Did you mean 'selectionModel'?
-    this.target_.selectionModel_.beginChange();
-    for (const name in selectionFlag) {
-      const index = parseInt(name, 10);
-      const flag = selectionFlag[index];
-      // The flag may be one of following:
-      // - IN_LAST_SELECTION | IN_CURRENT_SELECTION
-      // - IN_LAST_SELECTION
-      // - IN_CURRENT_SELECTION
-      // - undefined
-
-      // If the flag equals to (IN_LAST_SELECTION | IN_CURRENT_SELECTION),
-      // this is included in both the last selection and the current selection.
-      // We have nothing to do for this item.
-
-      if (flag == SelectionFlag_.IN_LAST_SELECTION) {
-        // If the flag equals to IN_LAST_SELECTION,
-        // then the item is included in lastSelection but not in
-        // currentSelection. Revert the selection state to
-        // this.originalSelection_.
-        // @ts-ignore: error TS2551: Property 'selectionModel_' does not exist
-        // on type 'List'. Did you mean 'selectionModel'?
-        this.target_.selectionModel_.setIndexSelected(
-            index, this.originalSelection_.indexOf(index) != -1);
-      } else if (flag == SelectionFlag_.IN_CURRENT_SELECTION) {
-        // If the flag equals to IN_CURRENT_SELECTION,
-        // this is included in currentSelection but not in lastSelection.
-        // @ts-ignore: error TS2551: Property 'selectionModel_' does not exist
-        // on type 'List'. Did you mean 'selectionModel'?
-        this.target_.selectionModel_.setIndexSelected(index, true);
-      }
-    }
-    if (leadIndex != -1) {
-      // @ts-ignore: error TS2551: Property 'selectionModel_' does not exist on
-      // type 'List'. Did you mean 'selectionModel'?
-      this.target_.selectionModel_.leadIndex = leadIndex;
-      // @ts-ignore: error TS2551: Property 'selectionModel_' does not exist on
-      // type 'List'. Did you mean 'selectionModel'?
-      this.target_.selectionModel_.anchorIndex = leadIndex;
-    }
-    // @ts-ignore: error TS2551: Property 'selectionModel_' does not exist on
-    // type 'List'. Did you mean 'selectionModel'?
-    this.target_.selectionModel_.endChange();
-    this.lastSelection_ = currentSelection;
-
-    // Update the size of border
-    // @ts-ignore: error TS2339: Property 'style' does not exist on type
-    // 'Element'.
-    this.border_.style.left = borderBounds.left + 'px';
-    // @ts-ignore: error TS2339: Property 'style' does not exist on type
-    // 'Element'.
-    this.border_.style.top = borderBounds.top + 'px';
-    // @ts-ignore: error TS2339: Property 'width' does not exist on type '{
-    // left: number; top: number; right: number; bottom: number; }'.
-    this.border_.style.width = borderBounds.width + 'px';
-    // @ts-ignore: error TS2339: Property 'height' does not exist on type '{
-    // left: number; top: number; right: number; bottom: number; }'.
-    this.border_.style.height = borderBounds.height + 'px';
-  }
-
-  /**
-   * Handle the mouseup event.
-   * @private
-   * @param {MouseEvent} event The mouseup event.
-   */
-  onMouseUp_(event) {
-    this.onMouseMove_(event);
-    this.target_.removeChild(this.border_);
-    this.target_.ownerDocument.removeEventListener(
-        'mousemove', this.onMouseMoveBound_, true);
-    this.target_.ownerDocument.removeEventListener(
-        'mouseup', this.onMouseUpBound_, true);
-    // @ts-ignore: error TS2339: Property 'cachedBounds' does not exist on type
-    // 'List'.
-    this.target_.cachedBounds = null;
-    // @ts-ignore: error TS2322: Type 'null' is not assignable to type 'List'.
-    this.target_ = null;
-    // The target may select an item by reacting to the mouseup event.
-    // This suppress to the selecting behavior.
-    event.stopPropagation();
-  }
-}
-
-/**
- * Flag that shows whether the item is included in the selection or not.
- * @enum {number}
- */
-const SelectionFlag_ = {
-  IN_LAST_SELECTION: 1 << 0,
-  IN_CURRENT_SELECTION: 1 << 1,
-};
diff --git a/ui/file_manager/file_manager/foreground/js/ui/drag_selector.ts b/ui/file_manager/file_manager/foreground/js/ui/drag_selector.ts
new file mode 100644
index 0000000..330b1a5
--- /dev/null
+++ b/ui/file_manager/file_manager/foreground/js/ui/drag_selector.ts
@@ -0,0 +1,234 @@
+// Copyright 2013 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import {assert} from 'chrome://resources/js/assert.js';
+
+import {List} from './list.js';
+
+interface DragState {
+  /**
+   * Target list of drag selection.
+   */
+  target: List;
+
+  /**
+   * Start point of dragging.
+   */
+  startX: number;
+
+  /**
+   * Start point of dragging.
+   */
+  startY: number;
+}
+
+/**
+ * Drag selector used on the file list or the grid table.
+ */
+export class DragSelector {
+  /**
+   * Stores the current state of the drag selection. Only has a value while the
+   * mouse button is down.
+   */
+  private state_: DragState|null = null;
+
+  /**
+   * Border element of drag handle.
+   */
+  private border_: HTMLDivElement|null = null;
+
+  /**
+   * Indexes of selected items by dragging at the last update.
+   */
+  private lastSelection_: number[] = [];
+
+  /**
+   * Indexes of selected items at the start of dragging.
+   */
+  private originalSelection_: number[] = [];
+
+  // Bind handlers to make them removable.
+  private onMouseMoveBound_ = this.onMouseMove_.bind(this);
+  private onMouseUpBound_ = this.onMouseUp_.bind(this);
+
+  /**
+   * Obtains the scrolled position in the element of mouse pointer from the
+   * mouse event.
+   *
+   * @param element Element that has the scroll bars.
+   * @param event The mouse event.
+   * @return Scrolled position.
+   */
+  static getScrolledPosition(element: List, event: MouseEvent):
+      {x: number, y: number} {
+    if (!element.cachedBounds) {
+      element.cachedBounds = element.getBoundingClientRect();
+    }
+    const rect = element.cachedBounds;
+    return {
+      x: event.clientX - rect.left + element.scrollLeft,
+      y: event.clientY - rect.top + element.scrollTop,
+    };
+  }
+
+  /**
+   * Starts drag selection by reacting dragstart event.
+   * This function must be called from handlers of dragstart event.
+   *
+   * @param list List where the drag selection starts.
+   * @param event The dragstart event.
+   */
+  startDragSelection(list: List, event: MouseEvent) {
+    // Precondition check
+    if (!list.selectionModel || !list.selectionModel.multiple || this.state_) {
+      return;
+    }
+
+    // Save the start state.
+    const startPos = DragSelector.getScrolledPosition(list, event);
+    if (!startPos) {
+      return;
+    }
+
+    const state = this.state_ = {
+      // Set the target of the drag selection
+      target: list,
+      startX: startPos.x,
+      startY: startPos.y,
+    };
+    this.lastSelection_ = [];
+    this.originalSelection_ = list.selectionModel.selectedIndexes;
+
+    // Create and add the border element
+    if (!this.border_) {
+      this.border_ = state.target.ownerDocument.createElement('div');
+      this.border_.className = 'drag-selection-border';
+    }
+    this.border_.style.left = state.startX + 'px';
+    this.border_.style.top = state.startY + 'px';
+    this.border_.style.width = '0';
+    this.border_.style.height = '0';
+    list.appendChild(this.border_);
+
+    // Register event handlers.
+    // The handlers are bounded at the constructor.
+    state.target.ownerDocument.addEventListener(
+        'mousemove', this.onMouseMoveBound_, true);
+    state.target.ownerDocument.addEventListener(
+        'mouseup', this.onMouseUpBound_, true);
+  }
+
+  /**
+   * Handles the mousemove event.
+   * @param event The mousemove event.
+   */
+  private onMouseMove_(event: MouseEvent) {
+    assert(this.state_);
+    const state = this.state_;
+    // Get the selection bounds.
+    const pos = DragSelector.getScrolledPosition(state.target, event);
+    const borderBounds = {
+      left: Math.max(Math.min(state.startX, pos.x), 0),
+      top: Math.max(Math.min(state.startY, pos.y), 0),
+      right: Math.min(Math.max(state.startX, pos.x), state.target.scrollWidth),
+      bottom:
+          Math.min(Math.max(state.startY, pos.y), state.target.scrollHeight),
+      width: 0,
+      height: 0,
+    };
+    borderBounds.width = borderBounds.right - borderBounds.left;
+    borderBounds.height = borderBounds.bottom - borderBounds.top;
+
+    // Collect items within the selection rect.
+    const currentSelection = state.target.getHitElements(
+        borderBounds.left, borderBounds.top, borderBounds.width,
+        borderBounds.height);
+    const pointedElements = state.target.getHitElements(pos.x, pos.y);
+    const leadIndex = pointedElements[0] != undefined ? pointedElements[0] : -1;
+
+    // Diff the selection between currentSelection and this.lastSelection_.
+    const selectionFlag: number[] = [];
+    for (const index of this.lastSelection_) {
+      // Bit operator can be used for undefined value.
+      selectionFlag[index] =
+          (selectionFlag[index] || 0) | SelectionFlag.IN_LAST_SELECTION;
+    }
+    for (const index of currentSelection) {
+      // Bit operator can be used for undefined value.
+      selectionFlag[index] =
+          (selectionFlag[index] || 0) | SelectionFlag.IN_CURRENT_SELECTION;
+    }
+
+    // Update the selection
+    const selectionModel = state.target.selectionModel!;
+    selectionModel.beginChange();
+    for (const name in selectionFlag) {
+      const index = parseInt(name, 10);
+      const flag = selectionFlag[index];
+      // The flag may be one of following:
+      // - IN_LAST_SELECTION | IN_CURRENT_SELECTION
+      // - IN_LAST_SELECTION
+      // - IN_CURRENT_SELECTION
+      // - undefined
+
+      // If the flag equals to (IN_LAST_SELECTION | IN_CURRENT_SELECTION),
+      // this is included in both the last selection and the current selection.
+      // We have nothing to do for this item.
+
+      if (flag == SelectionFlag.IN_LAST_SELECTION) {
+        // If the flag equals to IN_LAST_SELECTION,
+        // then the item is included in lastSelection but not in
+        // currentSelection. Revert the selection state to
+        // this.originalSelection_.
+        selectionModel.setIndexSelected(
+            index, this.originalSelection_.indexOf(index) != -1);
+      } else if (flag == SelectionFlag.IN_CURRENT_SELECTION) {
+        // If the flag equals to IN_CURRENT_SELECTION,
+        // this is included in currentSelection but not in lastSelection.
+        selectionModel.setIndexSelected(index, true);
+      }
+    }
+    if (leadIndex != -1) {
+      selectionModel.leadIndex = leadIndex;
+      selectionModel.anchorIndex = leadIndex;
+    }
+    selectionModel.endChange();
+    this.lastSelection_ = currentSelection;
+
+    // Update the size of border
+    assert(this.border_);
+    this.border_.style.left = borderBounds.left + 'px';
+    this.border_.style.top = borderBounds.top + 'px';
+    this.border_.style.width = borderBounds.width + 'px';
+    this.border_.style.height = borderBounds.height + 'px';
+  }
+
+  /**
+   * Handle the mouseup event.
+   * @param event The mouseup event.
+   */
+  private onMouseUp_(event: MouseEvent) {
+    assert(this.border_);
+    assert(this.state_);
+    this.onMouseMove_(event);
+    this.state_.target.removeChild(this.border_);
+    this.state_.target.ownerDocument.removeEventListener(
+        'mousemove', this.onMouseMoveBound_, true);
+    this.state_.target.ownerDocument.removeEventListener(
+        'mouseup', this.onMouseUpBound_, true);
+    this.state_.target.cachedBounds = null;
+    this.state_ = null;
+    // The target may select an item by reacting to the mouseup event.
+    // This suppress to the selecting behavior.
+    event.stopPropagation();
+  }
+}
+
+/**
+ * Flag that shows whether the item is included in the selection or not.
+ */
+enum SelectionFlag {
+  IN_LAST_SELECTION = 1 << 0,
+  IN_CURRENT_SELECTION = 1 << 1,
+}
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_grid.ts b/ui/file_manager/file_manager/foreground/js/ui/file_grid.ts
index 406dbb8..020da1e0 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/file_grid.ts
+++ b/ui/file_manager/file_manager/foreground/js/ui/file_grid.ts
@@ -1036,8 +1036,8 @@
    * @param height Height of the coordinate.
    * @return Indexes of the hit elements.
    */
-  getHitElements(x: number, y: number, width?: number, height?: number):
-      number[] {
+  override getHitElements(
+      x: number, y: number, width?: number, height?: number): number[] {
     const currentSelection = [];
     const startXWithPadding =
         isRTL() ? this.clientWidth - (x + (width ?? 0)) : x;
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_table_list.ts b/ui/file_manager/file_manager/foreground/js/ui/file_table_list.ts
index ec6bb11..80c39fdb 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/file_table_list.ts
+++ b/ui/file_manager/file_manager/foreground/js/ui/file_table_list.ts
@@ -258,11 +258,11 @@
    * @param _x X coordinate value.
    * @param y Y coordinate value.
    * @param _width Width of the coordinate.
-   * @param _height Height of the coordinate.
+   * @param height Height of the coordinate.
    * @return Index list of hit elements.
    */
-  getHitElements(_x: number, y: number, _width?: number, _height?: number):
-      number[] {
+  override getHitElements(
+      _x: number, y: number, _width?: number, height?: number): number[] {
     const fileListModel = this.dataModel;
     const groupBySnapshot =
         fileListModel ? fileListModel.getGroupBySnapshot() : [];
@@ -272,7 +272,7 @@
 
     const currentSelection = [];
     const startHeight = y;
-    const endHeight = y + (_height || 0);
+    const endHeight = y + (height || 0);
     const length = this.selectionModel?.length ?? 0;
     for (let i = 0; i < length; i++) {
       const itemMetrics = this.getHeightsForIndex(i);
diff --git a/ui/file_manager/file_manager/foreground/js/ui/grid.ts b/ui/file_manager/file_manager/foreground/js/ui/grid.ts
index 1c2de78..90010c8 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/grid.ts
+++ b/ui/file_manager/file_manager/foreground/js/ui/grid.ts
@@ -40,7 +40,7 @@
 /**
  * Creates a new grid element.
  */
-export class Grid extends List {
+export abstract class Grid extends List {
   /**
    * The number of columns in the grid. Either set by the user, or lazy
    * calculated as the maximum number of items fitting in the grid width.
diff --git a/ui/file_manager/file_manager/foreground/js/ui/list.ts b/ui/file_manager/file_manager/foreground/js/ui/list.ts
index de6db0c..5f50c538b 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/list.ts
+++ b/ui/file_manager/file_manager/foreground/js/ui/list.ts
@@ -59,7 +59,7 @@
 /**
  * Creates a new list element.
  */
-export class List extends HTMLUListElement {
+export abstract class List extends HTMLUListElement {
   /**
    * Measured size of list items. This is lazily calculated the first time it
    * is needed. Note that lead item is allowed to have a different height, to
@@ -1437,6 +1437,18 @@
   set hasElementFocus(value: boolean) {
     boolAttrSetter(this, 'hasElementFocus', value);
   }
+
+  /**
+   * Obtains the index list of elements that are hit by a point or rectangle.
+   *
+   * @param x X coordinate value.
+   * @param y Y coordinate value.
+   * @param width Width of the coordinate.
+   * @param height Height of the coordinate.
+   * @return Indexes of the hit elements.
+   */
+  abstract getHitElements(
+      x: number, y: number, width?: number, height?: number): number[];
 }
 
 
diff --git a/ui/file_manager/file_manager/foreground/js/ui/table/table_list.ts b/ui/file_manager/file_manager/foreground/js/ui/table/table_list.ts
index efe26ff1..bf8738c 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/table/table_list.ts
+++ b/ui/file_manager/file_manager/foreground/js/ui/table/table_list.ts
@@ -16,7 +16,7 @@
 /**
  * Creates a new table list element.
  */
-export class TableList extends List {
+export abstract class TableList extends List {
   private table_: Table|null = null;
 
   override initialize() {
diff --git a/ui/file_manager/file_manager/lib/base_store.ts b/ui/file_manager/file_manager/lib/base_store.ts
index 2ddefcc..ca6683c 100644
--- a/ui/file_manager/file_manager/lib/base_store.ts
+++ b/ui/file_manager/file_manager/lib/base_store.ts
@@ -141,7 +141,7 @@
   private initialized_: boolean = false;
 
   /** Queues actions while the Store un-initialized. */
-  private queuedActions_: Action[];
+  private queuedActions_: Array<Action|ActionsProducerGen>;
 
   /**
    * Observers that are notified when the State is updated by Action/Reducer.
@@ -216,7 +216,11 @@
     this.state_ = initialState;
 
     this.queuedActions_.forEach((action) => {
-      this.dispatchInternal_(action);
+      if (isActionsProducer(action)) {
+        this.consumeProducedActions_(action);
+      } else {
+        this.dispatchInternal_(action);
+      }
     });
 
     this.initialized_ = true;
@@ -280,15 +284,15 @@
    * reducers during the initialization.
    */
   dispatch(action: Action|ActionsProducerGen) {
-    if (isActionsProducer(action)) {
-      this.consumeProducedActions_(action);
-      return;
-    }
     if (!this.initialized_) {
       this.queuedActions_.push(action);
       return;
     }
-    this.dispatchInternal_(action);
+    if (isActionsProducer(action)) {
+      this.consumeProducedActions_(action);
+    } else {
+      this.dispatchInternal_(action);
+    }
   }
 
   /** Synchronously call apply the `action` by calling the reducer.  */
diff --git a/ui/file_manager/file_manager/state/ducks/ui_entries.ts b/ui/file_manager/file_manager/state/ducks/ui_entries.ts
index dbf5250..88af8c5 100644
--- a/ui/file_manager/file_manager/state/ducks/ui_entries.ts
+++ b/ui/file_manager/file_manager/state/ducks/ui_entries.ts
@@ -2,14 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {isSameEntry, isVolumeEntry, sortEntries} from '../../common/js/entry_utils.js';
+import {isSameEntry, isVolumeEntry} from '../../common/js/entry_utils.js';
 import {EntryList} from '../../common/js/files_app_entry_types.js';
 import {RootType} from '../../common/js/volume_manager_types.js';
 import {FakeEntry} from '../../externs/files_app_entry_interfaces.js';
 import {FileKey, State} from '../../externs/ts/state.js';
+import {ActionsProducerGen} from '../../lib/actions_producer.js';
 import {Slice} from '../../lib/base_store.js';
-import {cacheEntries, getMyFiles} from '../ducks/all_entries.js';
-import {getEntry, getFileData} from '../store.js';
+import {cacheEntries, getMyFiles, readSubDirectories} from '../ducks/all_entries.js';
+import {getEntry, getStore} from '../store.js';
 
 /**
  * @fileoverview UI entries slice of the store.
@@ -31,9 +32,9 @@
 
 
 /** Create action to add an UI entry to the store. */
-export const addUiEntry = slice.addReducer('add', addUiEntryReducer);
+export const addUiEntryInternal = slice.addReducer('add', addUiEntryReducer);
 
-export function addUiEntryReducer(currentState: State, payload: {
+function addUiEntryReducer(currentState: State, payload: {
   entry: FakeEntry|EntryList,
 }): State {
   // Cache entries, so the reducers can use any entry from `allEntries`.
@@ -41,87 +42,110 @@
 
   const {entry} = payload;
   const key = entry.toURL();
-
-  let isVolumeEntryExistedInMyFiles = false;
-  if (entry.rootType && uiEntryRootTypesInMyFiles.has(entry.rootType)) {
-    const {myFilesEntry} = getMyFiles(currentState);
-    const children = myFilesEntry.getUiChildren();
-    // Check if the the ui entry already has a corresponding volume entry.
-    isVolumeEntryExistedInMyFiles = !!children.find(
-        childEntry =>
-            isVolumeEntry(childEntry) && childEntry.name === entry.name);
-    const isUiEntryExistedInMyFiles =
-        !!children.find(childEntry => isSameEntry(childEntry, entry));
-    // We only add the UI entry here if:
-    // 1. it is not existed in MyFiles entry
-    // 2. its corresponding volume (which ui entry is a placeholder for) is not
-    // existed in MyFiles entry
-    const shouldAddUiEntry =
-        !isUiEntryExistedInMyFiles && !isVolumeEntryExistedInMyFiles;
-    if (shouldAddUiEntry) {
-      myFilesEntry.addEntry(entry);
-      // Push the new entry to the children of FileData and sort them.
-      const fileData = getFileData(currentState, myFilesEntry.toURL());
-      if (fileData) {
-        const newChildren = fileData.children.concat(entry.toURL());
-        const childEntries =
-            newChildren.map(childKey => getEntry(currentState, childKey)!);
-        const sortedChildren =
-            sortEntries(myFilesEntry, childEntries).map(entry => entry.toURL());
-        currentState.allEntries[myFilesEntry.toURL()] = {
-          ...fileData,
-          children: sortedChildren,
-        };
-      }
-    }
-  }
-
-  // If the corresponding volume entry exists, we don't add the ui entry here.
-  if (!currentState.uiEntries.find(k => k === key) &&
-      !isVolumeEntryExistedInMyFiles) {
-    // Shallow copy.
-    currentState.uiEntries = currentState.uiEntries.slice();
-    currentState.uiEntries.push(key);
-  }
+  const uiEntries = [...currentState.uiEntries, key];
 
   return {
     ...currentState,
+    uiEntries,
   };
 }
 
-/** Create action to remove an UI entry from the store. */
-export const removeUiEntry = slice.addReducer('remove', removeUiEntryReducer);
+/**
+ * Add UI entry to the store and re-scan MyFiles if the newly added UI entry is
+ * under MyFiles.
+ */
+export async function*
+    addUiEntry(entry: FakeEntry|EntryList): ActionsProducerGen {
+  const state = getStore().getState();
+  const exists = state.uiEntries.find(key => key === entry.toURL());
+  if (exists) {
+    return;
+  }
 
-export function removeUiEntryReducer(currentState: State, payload: {
+  // If the UI entry to be added is under MyFiles, we also need to update
+  // MyFiles's UI children.
+  let isVolumeEntryInMyFiles = false;
+  if (entry.rootType && uiEntryRootTypesInMyFiles.has(entry.rootType)) {
+    const {myFilesEntry} = getMyFiles(state);
+    const children = myFilesEntry.getUiChildren();
+    // Check if the the ui entry already has a corresponding volume entry.
+    isVolumeEntryInMyFiles = !!children.find(
+        childEntry =>
+            isVolumeEntry(childEntry) && childEntry.name === entry.name);
+    const isUiEntryInMyFiles =
+        !!children.find(childEntry => isSameEntry(childEntry, entry));
+    // We only add the UI entry here if:
+    // 1. it does not exist in MyFiles entry's UI children.
+    // 2. its corresponding volume (which ui entry is a placeholder for) does
+    // not exist in MyFiles entry's UI children.
+    const shouldAddUiEntry = !isUiEntryInMyFiles && !isVolumeEntryInMyFiles;
+    if (shouldAddUiEntry) {
+      myFilesEntry.addEntry(entry);
+      yield addUiEntryInternal({entry});
+      // Get MyFiles again from the latest state after yield because yield pause
+      // the execution of this function and between the pause MyFiles might
+      // change from EntryList to Volume (e.g. MyFiles volume mounts during the
+      // pause).
+      const {myFilesEntry: updatedMyFiles} = getMyFiles(getStore().getState());
+      // Trigger a re-scan for MyFiles to make FileData.children in the store
+      // has this newly added children.
+      for await (const action of readSubDirectories(updatedMyFiles)) {
+        yield action;
+      }
+      return;
+    }
+  }
+  if (!isVolumeEntryInMyFiles) {
+    yield addUiEntryInternal({entry});
+  }
+}
+
+/** Create action to remove an UI entry from the store. */
+const removeUiEntryInternal = slice.addReducer('remove', removeUiEntryReducer);
+
+function removeUiEntryReducer(currentState: State, payload: {
   key: FileKey,
 }): State {
   const {key} = payload;
-  const entry = getEntry(currentState, key) as FakeEntry | null;
-  if (currentState.uiEntries.find(k => k === key)) {
-    // Shallow copy.
-    currentState.uiEntries = currentState.uiEntries.filter(k => k !== key);
-  }
-
-  // We also need to remove it from the children of MyFiles if it's existed
-  // there.
-  if (entry?.rootType && uiEntryRootTypesInMyFiles.has(entry.rootType)) {
-    const {myFilesEntry} = getMyFiles(currentState);
-    const children = myFilesEntry.getUiChildren();
-    const isUiEntryExistedInMyFiles =
-        !!children.find(childEntry => isSameEntry(childEntry, entry));
-    if (isUiEntryExistedInMyFiles) {
-      myFilesEntry.removeChildEntry(entry);
-      const fileData = getFileData(currentState, myFilesEntry.toURL());
-      if (fileData) {
-        currentState.allEntries[myFilesEntry.toURL()] = {
-          ...fileData,
-          children: fileData.children.filter(child => child !== key),
-        };
-      }
-    }
-  }
+  const uiEntries = currentState.uiEntries.filter(k => k !== key);
 
   return {
     ...currentState,
+    uiEntries,
   };
 }
+
+/**
+ * Remove UI entry from the store and re-scan MyFiles if the removed UI entry is
+ * under MyFiles.
+ */
+export async function* removeUiEntry(key: FileKey): ActionsProducerGen {
+  const state = getStore().getState();
+  const exists = state.uiEntries.find(uiEntryKey => uiEntryKey === key);
+  if (!exists) {
+    return;
+  }
+
+  yield removeUiEntryInternal({key});
+
+  const entry = getEntry(state, key) as FakeEntry | EntryList | null;
+  // We also need to remove it from the children of MyFiles if it's existed
+  // there.
+  if (entry?.rootType && uiEntryRootTypesInMyFiles.has(entry.rootType)) {
+    // Get MyFiles from the latest state after yield because yield pause
+    // the execution of this function and between the pause MyFiles might
+    // change.
+    const {myFilesEntry} = getMyFiles(getStore().getState());
+    const children = myFilesEntry.getUiChildren();
+    const isUiEntryInMyFiles =
+        !!children.find(childEntry => isSameEntry(childEntry, entry));
+    if (isUiEntryInMyFiles) {
+      myFilesEntry.removeChildEntry(entry);
+      // Trigger a re-scan for MyFiles to make FileData.children in the store
+      // removes this children.
+      for await (const action of readSubDirectories(myFilesEntry)) {
+        yield action;
+      }
+    }
+  }
+}
diff --git a/ui/file_manager/file_manager/state/ducks/ui_entries_unittest.ts b/ui/file_manager/file_manager/state/ducks/ui_entries_unittest.ts
index 8edaa83..7c712d9e 100644
--- a/ui/file_manager/file_manager/state/ducks/ui_entries_unittest.ts
+++ b/ui/file_manager/file_manager/state/ducks/ui_entries_unittest.ts
@@ -40,7 +40,7 @@
 
   // Dispatch an action to add a UI entry.
   const uiEntry = new FakeEntryImpl('Ui entry', RootType.RECENT);
-  store.dispatch(addUiEntry({entry: uiEntry}));
+  store.dispatch(addUiEntry(uiEntry));
 
   // Expect the newly added entry is in the store.
   const want: Partial<State> = {
@@ -67,7 +67,7 @@
   const store = setupStore(initialState);
 
   // Dispatch an action to add an already existed UI entry.
-  store.dispatch(addUiEntry({entry: uiEntry}));
+  store.dispatch(addUiEntry(uiEntry));
 
   // Expect nothing changes in the store.
   const want: State['uiEntries'] = [uiEntry.toURL()];
@@ -102,7 +102,7 @@
 
   // Dispatch an action to add a new UI entry which belongs to MyFiles.
   const uiEntry = new FakeEntryImpl('Linux files', RootType.CROSTINI);
-  store.dispatch(addUiEntry({entry: uiEntry}));
+  store.dispatch(addUiEntry(uiEntry));
 
   // Expect 2 ui entries in the store.
   const want: Partial<State> = {
@@ -154,7 +154,7 @@
   const store = setupStore(initialState);
 
   // Dispatch an action to add an already existed UI entry.
-  store.dispatch(addUiEntry({entry: uiEntry}));
+  store.dispatch(addUiEntry(uiEntry));
 
   // Expect no changes in the store.
   await waitDeepEquals(store, initialState, (state) => state);
@@ -194,7 +194,7 @@
   // Dispatch an action to add UI entry.
   const uiEntry =
       new GuestOsPlaceholder(label, 0, chrome.fileManagerPrivate.VmType.ARCVM);
-  store.dispatch(addUiEntry({entry: uiEntry}));
+  store.dispatch(addUiEntry(uiEntry));
 
   // Expect the UI entry is not being added to the store.
   await waitDeepEquals(store, [], (state) => state.uiEntries);
@@ -222,7 +222,7 @@
   };
   const uiEntry = new GuestOsPlaceholder(
       'Play files', 0, chrome.fileManagerPrivate.VmType.ARCVM);
-  store.dispatch(addUiEntry({entry: uiEntry}));
+  store.dispatch(addUiEntry(uiEntry));
 
   // Expect the UI entry is being disabled.
   await waitUntil(() => uiEntry.disabled === true);
@@ -241,7 +241,7 @@
   const store = setupStore(initialState);
 
   // Dispatch an action to remove the UI entry.
-  store.dispatch(removeUiEntry({key: uiEntry.toURL()}));
+  store.dispatch(removeUiEntry(uiEntry.toURL()));
 
   // Expect the UI entry has been removed.
   await waitDeepEquals(store, [], (state) => state.uiEntries);
@@ -256,7 +256,7 @@
 
   // Dispatch an action to remove a non-existed UI entry.
   const uiEntry = new FakeEntryImpl('Ui entry', RootType.TRASH);
-  store.dispatch(removeUiEntry({key: uiEntry.toURL()}));
+  store.dispatch(removeUiEntry(uiEntry.toURL()));
 
   // Expect nothing changes in the store.
   await waitDeepEquals(store, initialState, (state) => state);
@@ -285,7 +285,7 @@
   const store = setupStore(initialState);
 
   // Dispatch an action to remove ui entry.
-  store.dispatch(removeUiEntry({key: uiEntry.toURL()}));
+  store.dispatch(removeUiEntry(uiEntry.toURL()));
 
   // Expect the entry has been removed from MyFiles.
   const want: Partial<State> = {
diff --git a/ui/file_manager/file_names.gni b/ui/file_manager/file_names.gni
index 488b5a7c5..4334f4b 100644
--- a/ui/file_manager/file_names.gni
+++ b/ui/file_manager/file_names.gni
@@ -34,7 +34,6 @@
   "file_manager/foreground/js/ui/default_task_dialog.js",
   "file_manager/foreground/js/ui/dialog_footer.js",
   "file_manager/foreground/js/ui/directory_tree.js",
-  "file_manager/foreground/js/ui/drag_selector.js",
   "file_manager/foreground/js/ui/install_linux_package_dialog.js",
   "file_manager/foreground/js/ui/tree.js",
 ]
@@ -165,6 +164,7 @@
   "file_manager/foreground/js/ui/combobutton.ts",
   "file_manager/foreground/js/ui/command.ts",
   "file_manager/foreground/js/ui/context_menu_handler.ts",
+  "file_manager/foreground/js/ui/drag_selector.ts",
   "file_manager/foreground/js/ui/file_grid.ts",
   "file_manager/foreground/js/ui/file_list_selection_model.ts",
   "file_manager/foreground/js/ui/file_manager_dialog_base.ts",
diff --git a/ui/gl/swap_chain_presenter.cc b/ui/gl/swap_chain_presenter.cc
index d0fe762..24c64b26 100644
--- a/ui/gl/swap_chain_presenter.cc
+++ b/ui/gl/swap_chain_presenter.cc
@@ -41,6 +41,14 @@
              "FallbackBT709VideoToBT601",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
+BASE_FEATURE(kDisableVPBLTUpscale,
+             "DisableVPBLTUpscale",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
+BASE_FEATURE(kApplyTransformToLetterboxing,
+             "ApplyTransformToLetterBoxing",
+             base::FEATURE_ENABLED_BY_DEFAULT);
+
 gfx::ColorSpace GetOutputColorSpace(const gfx::ColorSpace& input_color_space,
                                     bool is_yuv_swapchain) {
   gfx::ColorSpace output_color_space =
@@ -690,17 +698,29 @@
 }
 
 void SwapChainPresenter::SetTargetToFullScreen(gfx::Transform* visual_transform,
-                                               gfx::Rect* visual_clip_rect) {
-  // Reset the horizontal/vertical shift according to the visual clip and
-  // original transform, since DWM will do the positioning in case of overlay.
-  visual_transform->set_rc(
-      0, 3,
-      visual_clip_rect->x() -
-          visual_transform->rc(0, 3) * visual_transform->rc(0, 0));
-  visual_transform->set_rc(
-      1, 3,
-      visual_clip_rect->y() -
-          visual_transform->rc(1, 3) * visual_transform->rc(1, 1));
+                                               gfx::Rect* visual_clip_rect,
+                                               const gfx::Rect& target_rect) {
+  if (base::FeatureList::IsEnabled(kApplyTransformToLetterboxing)) {
+    // Reset the horizontal/vertical shift according to the target_rect and
+    // original transform, since DWM will do the positioning in case of overlay.
+    visual_transform->set_rc(0, 3,
+                             visual_transform->rc(0, 3) -
+                                 target_rect.x() * visual_transform->rc(0, 0));
+    visual_transform->set_rc(1, 3,
+                             visual_transform->rc(1, 3) -
+                                 target_rect.y() * visual_transform->rc(1, 1));
+  } else {
+    // Reset the horizontal/vertical shift according to the visual clip and
+    // original transform, since DWM will do the positioning in case of overlay.
+    visual_transform->set_rc(
+        0, 3,
+        visual_clip_rect->x() -
+            visual_transform->rc(0, 3) * visual_transform->rc(0, 0));
+    visual_transform->set_rc(
+        1, 3,
+        visual_clip_rect->y() -
+            visual_transform->rc(1, 3) * visual_transform->rc(1, 1));
+  }
 
   // Expand the clip rect for swap chain to the whole screen.
   *visual_clip_rect = gfx::Rect(GetMonitorSize());
@@ -1034,8 +1054,19 @@
   // Here the destination surface size is set to the whole monitor, while the
   // target region is set to the visual clip rectangle on the screen.
   if (params.z_order > 0) {
-    *dest_size = monitor_size;
-    *target_rect = *visual_clip_rect;
+    if (base::FeatureList::IsEnabled(kApplyTransformToLetterboxing)) {
+      // The transform scaling ratio should be applied in the process of
+      // calculating dest_size and target_rect.
+      float inverse_scale_x = 1.0f / std::abs(visual_transform->rc(0, 0));
+      float inverse_scale_y = 1.0f / std::abs(visual_transform->rc(1, 1));
+      *dest_size = gfx::ScaleToRoundedSize(monitor_size, inverse_scale_x,
+                                           inverse_scale_y);
+      *target_rect = gfx::ScaleToRoundedRect(*visual_clip_rect, inverse_scale_x,
+                                             inverse_scale_y);
+    } else {
+      *dest_size = monitor_size;
+      *target_rect = *visual_clip_rect;
+    }
   } else {
     // For underlay scenario, keep the destination surface size and target
     // region according to swap chain size.
@@ -1114,7 +1145,19 @@
   // overlays especially for protected video. Use the onscreen size (scale==1)
   // for overlay can avoid this problem.
   // TODO(sunnyps): Support 90/180/270 deg rotations using video context.
-  if (params.transform.IsScaleOrTranslation()) {
+
+  // On battery_power mode, set swap_chain_size to the source content size when
+  // the swap chain presents upscaled overlay, multi-plane overlay hardware will
+  // perform an upscaling operation instead of video processor(VP). Disabling VP
+  // upscaled BLT is more power saving as the video processor can do the minimal
+  // amount of work and the overlay has to read the minimal amount of data.
+  bool can_disable_vp_upscaling_blt =
+      base::FeatureList::IsEnabled(kDisableVPBLTUpscale) &&
+      is_on_battery_power_ && std::abs(params.transform.rc(0, 0)) > 1.0f &&
+      std::abs(params.transform.rc(1, 1)) > 1.0f;
+
+  if (params.transform.IsScaleOrTranslation() &&
+      !can_disable_vp_upscaling_blt) {
     swap_chain_size = overlay_onscreen_rect.size();
   }
 
@@ -1451,7 +1494,7 @@
     // But the visual transform and clip rectangle for DCLayerTree update need
     // to keep the same as the last presentation when desktop plane was removed.
     if (last_desktop_plane_removed_) {
-      SetTargetToFullScreen(visual_transform, visual_clip_rect);
+      SetTargetToFullScreen(visual_transform, visual_clip_rect, *target_rect);
     }
 
     return true;
@@ -1469,7 +1512,7 @@
     // Only NV12 format is supported in zero copy presentation path.
     if (dest_size.has_value() && target_rect.has_value() &&
         params.z_order > 0) {
-      SetTargetToFullScreen(visual_transform, visual_clip_rect);
+      SetTargetToFullScreen(visual_transform, visual_clip_rect, *target_rect);
     } else {
       last_desktop_plane_removed_ = false;
     }
@@ -1614,7 +1657,7 @@
   // Update |visual_transform| and |visual_clip_rect| for the full screen
   // letterboxing overlay presentation.
   if (is_letterboxing_overlay_ready) {
-    SetTargetToFullScreen(visual_transform, visual_clip_rect);
+    SetTargetToFullScreen(visual_transform, visual_clip_rect, *target_rect);
   } else {
     last_desktop_plane_removed_ = false;
   }
diff --git a/ui/gl/swap_chain_presenter.h b/ui/gl/swap_chain_presenter.h
index ba53e18..1d40f10 100644
--- a/ui/gl/swap_chain_presenter.h
+++ b/ui/gl/swap_chain_presenter.h
@@ -131,7 +131,8 @@
   // make sure the video full screen letterboxing take the whole monitor area,
   // and DWM will take care of the letterboxing info setup automatically.
   void SetTargetToFullScreen(gfx::Transform* visual_transform,
-                             gfx::Rect* visual_clip_rect);
+                             gfx::Rect* visual_clip_rect,
+                             const gfx::Rect& target_rect);
 
   // Takes in input DC layer params and the video overlay quad. The swap chain
   // backbuffer size will be rounded to the monitor size if it is within a close
diff --git a/ui/webui/resources/cr_elements/chromeos/cros_color_overrides.css b/ui/webui/resources/cr_elements/chromeos/cros_color_overrides.css
index 3ea327a1..936973eb 100644
--- a/ui/webui/resources/cr_elements/chromeos/cros_color_overrides.css
+++ b/ui/webui/resources/cr_elements/chromeos/cros_color_overrides.css
@@ -225,6 +225,7 @@
 /* Input and Textarea */
 :host-context(body.jelly-enabled) cr-input,
 :host-context(body.jelly-enabled) cr-search-field::part(searchInput),
+:host-context(body.jelly-enabled) cr-searchable-drop-down::part(input),
 :host-context(body.jelly-enabled) cr-textarea {
   --cr-input-background-color: var(--cros-sys-input_field_on_base);
   --cr-input-error-color: var(--cros-sys-error);
@@ -376,6 +377,16 @@
   --cr-input-padding-top: 10px;
 }
 
+/* Searchable Dropdown */
+:host-context(body.jelly-enabled) cr-searchable-drop-down {
+  --cr-searchable-drop-down-bg-color: var(--cros-sys-base_elevated);
+  --cr-searchable-drop-down-icon-color-focus: var(--cros-sys-primary);
+  --cr-searchable-drop-down-list-bg-color-selected:
+      var(--cros-sys-base_highlight);
+  --cr-searchable-drop-down-list-item-color: var(--cros-sys-on_surface);
+  --cr-searchable-drop-down-shadow: var(--cros-elevation-3-shadow);
+}
+
 /* Slider */
 :host-context(body.jelly-enabled) cr-slider {
   --cr-slider-active-color: var(--cros-sys-primary);
diff --git a/v8 b/v8
index 457c0cb..a6128e4 160000
--- a/v8
+++ b/v8
@@ -1 +1 @@
-Subproject commit 457c0cbb2f97c9a56941eb48b95e0234d0739cd3
+Subproject commit a6128e4e5e13d5352e267b2824f0835b2cbe4a70