diff --git a/DEPS b/DEPS
index 875ba2d..ace2183 100644
--- a/DEPS
+++ b/DEPS
@@ -280,15 +280,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': '59cba4b1bd401b58f8ad1263ea291066af8afa38',
+  'skia_revision': '81d55ce3f7bf9c05a46b5ea83e56d0e5970e6d8f',
   # 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': 'b5975d323033f797af622da8fe46ed1cbbe54baf',
+  'v8_revision': '40b12f74022a16b3efdc06e6662a2a9aafb79f9c',
   # 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': '5975eb03450509bee07aa8d9b8e33f422c07dcb6',
+  'angle_revision': '0bc70e96e465bd194163a15ca2f52e2cacb91e4a',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -331,7 +331,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling freetype
   # and whatever else without interference from each other.
-  'freetype_revision': '9c706dcca71607c9b88fd241eab89320914c78b0',
+  'freetype_revision': 'd9b8a69e9a8ba5ac999e721d50c231fe2e01d0bd',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling freetype
   # and whatever else without interference from each other.
@@ -359,7 +359,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling devtools-frontend
   # and whatever else without interference from each other.
-  'devtools_frontend_revision': 'd61644e9909f713883b1dc9438918b139986a810',
+  'devtools_frontend_revision': '4d70c841496347cd83032d51d01739d30f413493',
   # 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.
@@ -399,7 +399,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.
-  'quiche_revision': 'd29a68fc287d148722cfd9d9312df0dba05e6902',
+  'quiche_revision': '8dcfd0550284b92904ecccd1dfdcf31e297fc117',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ios_webkit
   # and whatever else without interference from each other.
@@ -1122,7 +1122,7 @@
   # Tools used when building Chrome for Chrome OS. This affects both the Simple
   # Chrome workflow, as well as the chromeos-chrome ebuild.
   'src/third_party/chromite': {
-      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '41d2e02e8d1438445eee7463ae4536fe6280e0fc',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'b355aaf148ed217b8a5038fafa5ef42601efa4df',
       'condition': 'checkout_chromeos',
   },
 
@@ -1542,7 +1542,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + '678b18cbe3b1730876323237279bd80b135c2046',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + 'b9f4805cadbde30a1bc094e6c55a4084a0dc4f44',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
@@ -1785,7 +1785,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@85d7985df9722d9b87bf99b1a6801fe4cca3b42a',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@279fd5b9cbdec5cee79c3da9ca75d98a2a1a1614',
     'condition': 'checkout_src_internal',
   },
 
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index 36e66f0..99c0f518 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -6026,7 +6026,8 @@
     test_class_declaration = input_api.re.compile(r'^\s*public\sclass.*Test')
     uiautomator_test = input_api.re.compile(r'[uU]i[aA]utomator')
 
-    errors = []
+    missing_annotation_errors = []
+    extra_annotation_errors = []
 
     def _FilterFile(affected_file):
         return input_api.FilterSourceFile(
@@ -6054,16 +6055,26 @@
         if (is_instrumentation_test and
             not batch_matched and
             not do_not_batch_matched):
-          errors.append(str(f.LocalPath()))
+          missing_annotation_errors.append(str(f.LocalPath()))
+        if (not is_instrumentation_test and
+            (batch_matched or
+             do_not_batch_matched)):
+          extra_annotation_errors.append(str(f.LocalPath()))
 
     results = []
 
-    if errors:
+    if missing_annotation_errors:
         results.append(
             output_api.PresubmitPromptWarning(
                 """
 Instrumentation tests should use either @Batch or @DoNotBatch. If tests are not
 safe to run in batch, please use @DoNotBatch with reasons.
-""", errors))
+""", missing_annotation_errors))
+    if extra_annotation_errors:
+        results.append(
+            output_api.PresubmitPromptWarning(
+                """
+Robolectric tests do not need a @Batch or @DoNotBatch annotations.
+""", extra_annotation_errors))
 
     return results
diff --git a/PRESUBMIT_test.py b/PRESUBMIT_test.py
index 12a7f3b..27a2261 100755
--- a/PRESUBMIT_test.py
+++ b/PRESUBMIT_test.py
@@ -4556,12 +4556,24 @@
     mock_input.files = [
         MockFile('path/OneTest.java', ['public class OneTest']),
         MockFile('path/TwoTest.java', ['public class TwoTest']),
+        MockFile('path/ThreeTest.java',
+                 ['@Batch(Batch.PER_CLASS)',
+                  'import org.chromium.base.test.BaseRobolectricTestRunner;',
+                  'public class Three {']),
+        MockFile('path/FourTest.java',
+                 ['@DoNotBatch(reason = "dummy reason 1")',
+                  'import org.chromium.base.test.BaseRobolectricTestRunner;',
+                  'public class Four {']),
     ]
     errors = PRESUBMIT.CheckBatchAnnotation(mock_input, MockOutputApi())
-    self.assertEqual(1, len(errors))
+    self.assertEqual(2, len(errors))
     self.assertEqual(2, len(errors[0].items))
     self.assertIn('OneTest.java', errors[0].items[0])
     self.assertIn('TwoTest.java', errors[0].items[1])
+    self.assertEqual(2, len(errors[1].items))
+    self.assertIn('ThreeTest.java', errors[1].items[0])
+    self.assertIn('FourTest.java', errors[1].items[1])
+
 
   def testAnnotationsPresent(self):
     """Examples of when there is @Batch or @DoNotBatch is correctly flagged."""
diff --git a/WATCHLISTS b/WATCHLISTS
index 18680dadc..6672d7ed7 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -836,6 +836,9 @@
                   'chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/|' \
                   'components/contextual_search/',
     },
+    'core_timing': {
+      'filepath': 'third_party/blink/renderer/core/timing/' \
+    },
     'core_web_vitals_plm': {
       'filepath': 'chrome/browser/page_load_metrics/observers/core/|' \
                   'components/page_load_metrics/browser/observers/core/',
@@ -2481,6 +2484,7 @@
     'contextual_search': ['donnd+watch@chromium.org',
                           'twellington+watch@chromium.org',
                           'gangwu+watch@chromium.org'],
+    'core_timing': ['core-timing-reviews@chromium.org'],
     'core_web_vitals_plm': ['core-web-vitals-plm-reviews@chromium.org'],
     'core_web_vitals_wpt': ['chrome-speed-metrics-core+watchlist@google.com',
                             'lighthouse-eng-external+watch-speed-metrics@google.com'],
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/PopupWindowTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/PopupWindowTest.java
index e5a9e16..82c32330 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/PopupWindowTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/PopupWindowTest.java
@@ -28,7 +28,6 @@
 import org.chromium.android_webview.test.util.CommonResources;
 import org.chromium.android_webview.test.util.JSUtils;
 import org.chromium.base.ThreadUtils;
-import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Criteria;
 import org.chromium.base.test.util.CriteriaHelper;
@@ -495,7 +494,6 @@
     @Test
     @SmallTest
     @Feature({"AndroidWebView"})
-    @DisabledTest(message = "https://crbug.com/1336342")
     public void testSingleWindowModeJsInjection() throws Throwable {
         // Choose a free port which is different from |mWebServer| so they have different origins.
         TestWebServer crossOriginWebServer = TestWebServer.startAdditional();
@@ -579,6 +577,13 @@
         Assert.assertNotNull("mainFrameReplyProxy should not be null.", mainFrameReplyProxy);
         Assert.assertNotNull("iframeReplyProxy should not be null.", iframeReplyProxy);
 
+        // Wait for the page to finish rendering entirely before
+        // attempting to click the iframe_link
+        // We need this because we're using the DOMUtils
+        // Long term we plan to switch to JSUtils to avoid this
+        // https://crbug.com/1334843
+        mParentContentsClient.getOnPageCommitVisibleHelper().waitForFirst();
+
         // Step 4. Click iframe_link to give user gesture.
         DOMUtils.clickRect(mParentContents.getWebContents(), rect);
 
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc
index 54a8ed5..b7366fd 100644
--- a/ash/constants/ash_features.cc
+++ b/ash/constants/ash_features.cc
@@ -1199,7 +1199,7 @@
 // from the apps grid. This feature was previously named "AppListBubble".
 // https://crbug.com/1204551
 const base::Feature kProductivityLauncher{"ProductivityLauncher",
-                                          base::FEATURE_DISABLED_BY_DEFAULT};
+                                          base::FEATURE_ENABLED_BY_DEFAULT};
 
 // Controls whether to enable Projector.
 const base::Feature kProjector{"Projector", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/base/allocator/partition_allocator/partition_alloc_base/threading/platform_thread_posix_for_testing.cc b/base/allocator/partition_allocator/partition_alloc_base/threading/platform_thread_posix_for_testing.cc
index 8e8280a..044c7c9a 100644
--- a/base/allocator/partition_allocator/partition_alloc_base/threading/platform_thread_posix_for_testing.cc
+++ b/base/allocator/partition_allocator/partition_alloc_base/threading/platform_thread_posix_for_testing.cc
@@ -12,6 +12,7 @@
 #include <sys/time.h>
 #include <sys/types.h>
 #include <unistd.h>
+#include <memory>
 
 #include "base/allocator/partition_allocator/partition_alloc_base/logging.h"
 #include "base/allocator/partition_allocator/partition_alloc_base/threading/platform_thread_internal_posix.h"
diff --git a/base/lazy_instance.h b/base/lazy_instance.h
index c2bf3f7..85fc23a1 100644
--- a/base/lazy_instance.h
+++ b/base/lazy_instance.h
@@ -45,9 +45,9 @@
 #ifndef BASE_LAZY_INSTANCE_H_
 #define BASE_LAZY_INSTANCE_H_
 
+#include <atomic>
 #include <new>  // For placement new.
 
-#include "base/atomicops.h"
 #include "base/check_op.h"
 #include "base/dcheck_is_on.h"
 #include "base/debug/leak_annotations.h"
@@ -157,7 +157,7 @@
 #endif
 
     return subtle::GetOrCreateLazyPointer(
-        &private_instance_, &Traits::New, private_buf_,
+        private_instance_, &Traits::New, private_buf_,
         Traits::kRegisterOnExit ? OnExit : nullptr, this);
   }
 
@@ -168,7 +168,7 @@
     // created right now (i.e. |private_instance_| has value of
     // internal::kLazyInstanceStateCreating) or was already created (i.e.
     // |private_instance_| has any other non-zero value).
-    return 0 != subtle::NoBarrier_Load(&private_instance_);
+    return 0 != private_instance_.load(std::memory_order_relaxed);
   }
 
   // MSVC gives a warning that the alignment expands the size of the
@@ -176,13 +176,13 @@
   // is expected in this case.
 #if BUILDFLAG(IS_WIN)
 #pragma warning(push)
-#pragma warning(disable: 4324)
+#pragma warning(disable : 4324)
 #endif
 
   // Effectively private: member data is only public to allow the linker to
   // statically initialize it and to maintain a POD class. DO NOT USE FROM
   // OUTSIDE THIS CLASS.
-  subtle::AtomicWord private_instance_;
+  std::atomic<uintptr_t> private_instance_;
 
   // Preallocated space for the Type instance.
   alignas(Type) char private_buf_[sizeof(Type)];
@@ -193,7 +193,8 @@
 
  private:
   Type* instance() {
-    return reinterpret_cast<Type*>(subtle::NoBarrier_Load(&private_instance_));
+    return reinterpret_cast<Type*>(
+        private_instance_.load(std::memory_order_relaxed));
   }
 
   // Adapter function for use with AtExit.  This should be called single
@@ -203,7 +204,7 @@
     LazyInstance<Type, Traits>* me =
         reinterpret_cast<LazyInstance<Type, Traits>*>(lazy_instance);
     Traits::Delete(me->instance());
-    subtle::NoBarrier_Store(&me->private_instance_, 0);
+    me->private_instance_.store(0, std::memory_order_relaxed);
   }
 };
 
diff --git a/base/lazy_instance_helpers.cc b/base/lazy_instance_helpers.cc
index b458c7a..fcb00fd3 100644
--- a/base/lazy_instance_helpers.cc
+++ b/base/lazy_instance_helpers.cc
@@ -4,21 +4,24 @@
 
 #include "base/lazy_instance_helpers.h"
 
+#include <atomic>
+
 #include "base/at_exit.h"
-#include "base/atomicops.h"
 #include "base/threading/platform_thread.h"
 
 namespace base {
 namespace internal {
 
-bool NeedsLazyInstance(subtle::AtomicWord* state) {
+bool NeedsLazyInstance(std::atomic<uintptr_t>& state) {
   // Try to create the instance, if we're the first, will go from 0 to
   // kLazyInstanceStateCreating, otherwise we've already been beaten here.
   // The memory access has no memory ordering as state 0 and
   // kLazyInstanceStateCreating have no associated data (memory barriers are
   // all about ordering of memory accesses to *associated* data).
-  if (subtle::NoBarrier_CompareAndSwap(state, 0, kLazyInstanceStateCreating) ==
-      0) {
+  uintptr_t expected = 0;
+  if (state.compare_exchange_strong(expected, kLazyInstanceStateCreating,
+                                    std::memory_order_relaxed,
+                                    std::memory_order_relaxed)) {
     // Caller must create instance
     return true;
   }
@@ -28,32 +31,33 @@
   // state_ == STATE_CREATED needs to acquire visibility over
   // the associated data (buf_). Pairing Release_Store is in
   // CompleteLazyInstance().
-  if (subtle::Acquire_Load(state) == kLazyInstanceStateCreating) {
+  if (state.load(std::memory_order_acquire) == kLazyInstanceStateCreating) {
     const base::TimeTicks start = base::TimeTicks::Now();
     do {
       const base::TimeDelta elapsed = base::TimeTicks::Now() - start;
-      // Spin with YieldCurrentThread for at most one ms - this ensures maximum
-      // responsiveness. After that spin with Sleep(1ms) so that we don't burn
-      // excessive CPU time - this also avoids infinite loops due to priority
-      // inversions (https://crbug.com/797129).
+      // Spin with YieldCurrentThread for at most one ms - this ensures
+      // maximum responsiveness. After that spin with Sleep(1ms) so that we
+      // don't burn excessive CPU time - this also avoids infinite loops due
+      // to priority inversions (https://crbug.com/797129).
       if (elapsed < Milliseconds(1))
         PlatformThread::YieldCurrentThread();
       else
         PlatformThread::Sleep(Milliseconds(1));
-    } while (subtle::Acquire_Load(state) == kLazyInstanceStateCreating);
+    } while (state.load(std::memory_order_acquire) ==
+             kLazyInstanceStateCreating);
   }
   // Someone else created the instance.
   return false;
 }
 
-void CompleteLazyInstance(subtle::AtomicWord* state,
-                          subtle::AtomicWord new_instance,
+void CompleteLazyInstance(std::atomic<uintptr_t>& state,
+                          uintptr_t new_instance,
                           void (*destructor)(void*),
                           void* destructor_arg) {
   // Instance is created, go from CREATING to CREATED (or reset it if
   // |new_instance| is null). Releases visibility over |private_buf_| to
   // readers. Pairing Acquire_Load is in NeedsLazyInstance().
-  subtle::Release_Store(state, new_instance);
+  state.store(new_instance, std::memory_order_release);
 
   // Make sure that the lazily instantiated object will get destroyed at exit.
   if (new_instance && destructor)
diff --git a/base/lazy_instance_helpers.h b/base/lazy_instance_helpers.h
index 8834919e..489aee0 100644
--- a/base/lazy_instance_helpers.h
+++ b/base/lazy_instance_helpers.h
@@ -5,7 +5,8 @@
 #ifndef BASE_LAZY_INSTANCE_HELPERS_H_
 #define BASE_LAZY_INSTANCE_HELPERS_H_
 
-#include "base/atomicops.h"
+#include <atomic>
+#include <cstdint>
 #include "base/base_export.h"
 #include "base/check.h"
 
@@ -17,18 +18,18 @@
 
 // Our AtomicWord doubles as a spinlock, where a value of
 // kLazyInstanceStateCreating means the spinlock is being held for creation.
-constexpr subtle::AtomicWord kLazyInstanceStateCreating = 1;
+constexpr uintptr_t kLazyInstanceStateCreating = 1;
 
 // Helper for GetOrCreateLazyPointer(). Checks if instance needs to be created.
 // If so returns true otherwise if another thread has beat us, waits for
 // instance to be created and returns false.
-BASE_EXPORT bool NeedsLazyInstance(subtle::AtomicWord* state);
+BASE_EXPORT bool NeedsLazyInstance(std::atomic<uintptr_t>& state);
 
 // Helper for GetOrCreateLazyPointer(). After creating an instance, this is
 // called to register the dtor to be called at program exit and to update the
 // atomic state to hold the |new_instance|
-BASE_EXPORT void CompleteLazyInstance(subtle::AtomicWord* state,
-                                      subtle::AtomicWord new_instance,
+BASE_EXPORT void CompleteLazyInstance(std::atomic<uintptr_t>& state,
+                                      uintptr_t new_instance,
                                       void (*destructor)(void*),
                                       void* destructor_arg);
 
@@ -55,17 +56,16 @@
 // worsened by https://chromium-review.googlesource.com/c/chromium/src/+/868013
 // and caught then as https://crbug.com/804034.
 template <typename Type>
-Type* GetOrCreateLazyPointer(subtle::AtomicWord* state,
+Type* GetOrCreateLazyPointer(std::atomic<uintptr_t>& state,
                              Type* (*creator_func)(void*),
                              void* creator_arg,
                              void (*destructor)(void*),
                              void* destructor_arg) {
-  DCHECK(state);
   DCHECK(creator_func);
 
   // If any bit in the created mask is true, the instance has already been
   // fully constructed.
-  constexpr subtle::AtomicWord kLazyInstanceCreatedMask =
+  constexpr uintptr_t kLazyInstanceCreatedMask =
       ~internal::kLazyInstanceStateCreating;
 
   // We will hopefully have fast access when the instance is already created.
@@ -74,20 +74,19 @@
   // has acquire memory ordering as a thread which sees |state| > creating needs
   // to acquire visibility over the associated data. Pairing Release_Store is in
   // CompleteLazyInstance().
-  subtle::AtomicWord instance = subtle::Acquire_Load(state);
+  uintptr_t instance = state.load(std::memory_order_acquire);
   if (!(instance & kLazyInstanceCreatedMask)) {
     if (internal::NeedsLazyInstance(state)) {
       // This thread won the race and is now responsible for creating the
       // instance and storing it back into |state|.
-      instance =
-          reinterpret_cast<subtle::AtomicWord>((*creator_func)(creator_arg));
+      instance = reinterpret_cast<uintptr_t>((*creator_func)(creator_arg));
       internal::CompleteLazyInstance(state, instance, destructor,
                                      destructor_arg);
     } else {
       // This thread lost the race but now has visibility over the constructed
       // instance (NeedsLazyInstance() doesn't return until the constructing
       // thread releases the instance via CompleteLazyInstance()).
-      instance = subtle::Acquire_Load(state);
+      instance = state.load(std::memory_order_acquire);
       DCHECK(instance & kLazyInstanceCreatedMask);
     }
   }
diff --git a/base/memory/singleton.h b/base/memory/singleton.h
index 58e6ab95..31ed7af 100644
--- a/base/memory/singleton.h
+++ b/base/memory/singleton.h
@@ -27,7 +27,8 @@
 #ifndef BASE_MEMORY_SINGLETON_H_
 #define BASE_MEMORY_SINGLETON_H_
 
-#include "base/atomicops.h"
+#include <atomic>
+
 #include "base/dcheck_is_on.h"
 #include "base/lazy_instance_helpers.h"
 #include "base/threading/thread_restrictions.h"
@@ -101,7 +102,7 @@
   // WARNING: User has to support a New() which returns null.
   static Type* New() {
     // Only constructs once and returns pointer; otherwise returns null.
-    if (subtle::NoBarrier_AtomicExchange(&dead_, 1))
+    if (dead_.exchange(true, std::memory_order_relaxed))
       return nullptr;
 
     return new (buffer_) Type();
@@ -118,18 +119,20 @@
   static const bool kAllowedToAccessOnNonjoinableThread = true;
 #endif
 
-  static void ResurrectForTesting() { subtle::NoBarrier_Store(&dead_, 0); }
+  static void ResurrectForTesting() {
+    dead_.store(false, std::memory_order_relaxed);
+  }
 
  private:
   alignas(Type) static char buffer_[sizeof(Type)];
   // Signal the object was already deleted, so it is not revived.
-  static subtle::Atomic32 dead_;
+  static std::atomic<bool> dead_;
 };
 
 template <typename Type>
 alignas(Type) char StaticMemorySingletonTraits<Type>::buffer_[sizeof(Type)];
 template <typename Type>
-subtle::Atomic32 StaticMemorySingletonTraits<Type>::dead_ = 0;
+std::atomic<bool> StaticMemorySingletonTraits<Type>::dead_ = false;
 
 // The Singleton<Type, Traits, DifferentiatingType> class manages a single
 // instance of Type which will be created on first use and will be destroyed at
@@ -235,7 +238,7 @@
 #endif
 
     return subtle::GetOrCreateLazyPointer(
-        &instance_, &CreatorFunc, nullptr,
+        instance_, &CreatorFunc, nullptr,
         Traits::kRegisterAtExit ? OnExit : nullptr, nullptr);
   }
 
@@ -247,7 +250,7 @@
       internal::AssertSingletonAllowed();
 #endif
 
-    if (!subtle::NoBarrier_Load(&instance_))
+    if (!instance_.load(std::memory_order_relaxed))
       return nullptr;
 
     // Need to invoke get() nonetheless as some Traits return null after
@@ -265,14 +268,16 @@
   static void OnExit(void* /*unused*/) {
     // AtExit should only ever be register after the singleton instance was
     // created.  We should only ever get here with a valid instance_ pointer.
-    Traits::Delete(reinterpret_cast<Type*>(subtle::NoBarrier_Load(&instance_)));
-    instance_ = 0;
+    Traits::Delete(
+        reinterpret_cast<Type*>(instance_.load(std::memory_order_relaxed)));
+    instance_.store(0, std::memory_order_relaxed);
   }
-  static subtle::AtomicWord instance_;
+  static std::atomic<uintptr_t> instance_;
 };
 
 template <typename Type, typename Traits, typename DifferentiatingType>
-subtle::AtomicWord Singleton<Type, Traits, DifferentiatingType>::instance_ = 0;
+std::atomic<uintptr_t> Singleton<Type, Traits, DifferentiatingType>::instance_ =
+    0;
 
 }  // namespace base
 
diff --git a/base/message_loop/message_pump_libevent.cc b/base/message_loop/message_pump_libevent.cc
index b58e5231..93c2aef 100644
--- a/base/message_loop/message_pump_libevent.cc
+++ b/base/message_loop/message_pump_libevent.cc
@@ -198,11 +198,23 @@
     if (run_state.should_quit)
       break;
 
-    // Process native events if any are ready. Do not block waiting for more.
-    {
-      auto scoped_do_work_item = delegate->BeginWorkItem();
-      event_base_loop(event_base_, EVLOOP_NONBLOCK);
-    }
+    // Process native events if any are ready. Do not block waiting for more. Do
+    // not instantiate a ScopedDoWorkItem for this call as:
+    //  - This most often ends up calling OnLibeventNotification() below which
+    //    already instantiates a ScopedDoWorkItem (and doing so twice would
+    //    incorrectly appear as nested work).
+    //  - "ThreadController active" is already up per the above DoWork() so this
+    //    would only be about detecting #task-in-task-implies-nested
+    //    (ref. thread_controller.h).
+    //  - This can result in the same work as the
+    //    event_base_loop(event_base_, EVLOOP_ONCE) call at the end of this
+    //    method and that call definitely can't be in a ScopedDoWorkItem as
+    //    it includes sleep.
+    //  - The only downside is that, if a native task other than
+    //    OnLibeventNotification() did enter a nested loop from here, it
+    //    wouldn't be labeled as such in tracing by "ThreadController active".
+    //    Contact gab@/scheduler-dev@ if a problematic trace emerges.
+    event_base_loop(event_base_, EVLOOP_NONBLOCK);
 
     bool attempt_more_work = immediate_work_available || processed_io_events_;
     processed_io_events_ = false;
@@ -303,10 +315,6 @@
                                                  void* context) {
   FdWatchController* controller = static_cast<FdWatchController*>(context);
   DCHECK(controller);
-  TRACE_EVENT("toplevel", "OnLibevent", "fd", fd);
-
-  TRACE_HEAP_PROFILER_API_SCOPED_TASK_EXECUTION heap_profiler_scope(
-      controller->created_from_location().file_name());
 
   MessagePumpLibevent* pump = controller->pump();
   pump->processed_io_events_ = true;
@@ -317,6 +325,12 @@
   if (pump->run_state_)
     scoped_do_work_item = pump->run_state_->delegate->BeginWorkItem();
 
+  // Trace events must begin after the above BeginWorkItem() so that the
+  // ensuing "ThreadController active" outscopes all the events under it.
+  TRACE_EVENT("toplevel", "OnLibevent", "fd", fd);
+  TRACE_HEAP_PROFILER_API_SCOPED_TASK_EXECUTION heap_profiler_scope(
+      controller->created_from_location().file_name());
+
   if ((flags & (EV_READ | EV_WRITE)) == (EV_READ | EV_WRITE)) {
     // Both callbacks will be called. It is necessary to check that |controller|
     // is not destroyed.
diff --git a/base/message_loop/message_pump_unittest.cc b/base/message_loop/message_pump_unittest.cc
index dc2fc09..cf31c2d 100644
--- a/base/message_loop/message_pump_unittest.cc
+++ b/base/message_loop/message_pump_unittest.cc
@@ -155,17 +155,10 @@
 
   void AddPostDoWorkExpectations(
       testing::StrictMock<MockMessagePumpDelegate>& delegate) {
-#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_NACL)
-    if ((GetParam() == MessagePumpType::UI &&
-         std::is_same<MessagePumpForUI, MessagePumpLibevent>::value) ||
-        (GetParam() == MessagePumpType::IO &&
-         std::is_same<MessagePumpForIO, MessagePumpLibevent>::value)) {
-      // MessagePumpLibEvent checks for native notifications once after
-      // processing a DoWork().
-      EXPECT_CALL(delegate, MockOnBeginWorkItem);
-      EXPECT_CALL(delegate, MockOnEndWorkItem);
-    }
-#endif  // BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_NACL)
+    // MessagePumpLibEvent checks for native notifications once after processing
+    // a DoWork() but only instantiates a ScopedDoWorkItem that triggers
+    // MessagePumpLibevent::OnLibeventNotification() which this test does not
+    // so there are no post-work expectations at the moment.
   }
 
   std::unique_ptr<MessagePump> message_pump_;
diff --git a/base/task/lazy_thread_pool_task_runner.cc b/base/task/lazy_thread_pool_task_runner.cc
index efa886f..3822be12 100644
--- a/base/task/lazy_thread_pool_task_runner.cc
+++ b/base/task/lazy_thread_pool_task_runner.cc
@@ -4,6 +4,7 @@
 
 #include "base/task/lazy_thread_pool_task_runner.h"
 
+#include <atomic>
 #include <utility>
 
 #include "base/check_op.h"
@@ -21,7 +22,7 @@
 
 template <typename TaskRunnerType, bool com_sta>
 void LazyThreadPoolTaskRunner<TaskRunnerType, com_sta>::Reset() {
-  subtle::AtomicWord state = subtle::Acquire_Load(&state_);
+  uintptr_t state = state_.load(std::memory_order_acquire);
 
   DCHECK_NE(state, kLazyInstanceStateCreating) << "Race: all threads should be "
                                                   "unwound in unittests before "
@@ -36,7 +37,7 @@
   task_runner->Release();
 
   // Clear the state.
-  subtle::NoBarrier_Store(&state_, 0);
+  state_.store(0, std::memory_order_relaxed);
 }
 
 template <>
@@ -94,7 +95,7 @@
 scoped_refptr<TaskRunnerType>
 LazyThreadPoolTaskRunner<TaskRunnerType, com_sta>::Get() {
   return WrapRefCounted(subtle::GetOrCreateLazyPointer(
-      &state_, &LazyThreadPoolTaskRunner<TaskRunnerType, com_sta>::CreateRaw,
+      state_, &LazyThreadPoolTaskRunner<TaskRunnerType, com_sta>::CreateRaw,
       reinterpret_cast<void*>(this), nullptr, nullptr));
 }
 
diff --git a/base/task/lazy_thread_pool_task_runner.h b/base/task/lazy_thread_pool_task_runner.h
index 2dcb68242..1a2e661 100644
--- a/base/task/lazy_thread_pool_task_runner.h
+++ b/base/task/lazy_thread_pool_task_runner.h
@@ -5,9 +5,9 @@
 #ifndef BASE_TASK_LAZY_THREAD_POOL_TASK_RUNNER_H_
 #define BASE_TASK_LAZY_THREAD_POOL_TASK_RUNNER_H_
 
+#include <atomic>
 #include <vector>
 
-#include "base/atomicops.h"
 #include "base/base_export.h"
 #include "base/callback.h"
 #include "base/task/common/checked_lock.h"
@@ -178,7 +178,7 @@
   // - This instance is creating a TaskRunner: kLazyInstanceStateCreating
   // - This instance holds a TaskRunner: Pointer to the TaskRunner.
   // LazyInstance's internals are reused to handle transition between states.
-  subtle::AtomicWord state_ = 0;
+  std::atomic<uintptr_t> state_ = 0;
 
   // No DISALLOW_COPY_AND_ASSIGN since that prevents static initialization with
   // Visual Studio (warning C4592: 'symbol will be dynamically initialized
diff --git a/base/task/sequence_manager/thread_controller_with_message_pump_impl.cc b/base/task/sequence_manager/thread_controller_with_message_pump_impl.cc
index 44a8db4e..fe5a528 100644
--- a/base/task/sequence_manager/thread_controller_with_message_pump_impl.cc
+++ b/base/task/sequence_manager/thread_controller_with_message_pump_impl.cc
@@ -17,6 +17,7 @@
 #include "base/time/tick_clock.h"
 #include "base/trace_event/base_tracing.h"
 #include "build/build_config.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(IS_IOS)
 #include "base/message_loop/message_pump_mac.h"
@@ -449,6 +450,22 @@
 }
 
 bool ThreadControllerWithMessagePumpImpl::DoIdleWork() {
+  struct OnIdle {
+    explicit OnIdle(ThreadControllerWithMessagePumpImpl& outer)
+        : outer_(outer) {}
+
+    // Very last step before going idle, must be fast as this is hidden from the
+    // DoIdleWork trace event below.
+    ~OnIdle() { outer_.run_level_tracker_.OnIdle(); }
+
+   private:
+    ThreadControllerWithMessagePumpImpl& outer_;
+  };
+  absl::optional<OnIdle> on_idle;
+
+  // Must be after `on_idle` as this trace event's scope must end before the END
+  // of the "ThreadController active" trace event emitted from
+  // `run_level_tracker_.OnIdle()`.
   TRACE_EVENT0("sequence_manager", "SequenceManager::DoIdleWork");
 
   // A hang watch scope should already be in place in most cases but some
@@ -486,12 +503,14 @@
     return false;
   }
 
-  run_level_tracker_.OnIdle();
   // This is mostly redundant with the identical call in BeforeWait (upcoming)
   // but some uninstrumented MessagePump impls don't call BeforeWait so it must
   // also be done here.
   hang_watch_scope_.reset();
 
+  // All return paths below are truly idle.
+  on_idle.emplace(*this);
+
   // Check if any runloop timeout has expired.
   if (main_thread_only().quit_runloop_after != TimeTicks::Max() &&
       main_thread_only().quit_runloop_after <= time_source_->NowTicks()) {
diff --git a/base/task/sequenced_task_runner.h b/base/task/sequenced_task_runner.h
index f9c245496..61b2288 100644
--- a/base/task/sequenced_task_runner.h
+++ b/base/task/sequenced_task_runner.h
@@ -24,6 +24,10 @@
 namespace webrtc {
 class ThreadWrapper;
 }  // namespace webrtc
+namespace media {
+class AlsaPcmOutputStream;
+class FakeAudioWorker;
+}  // namespace media
 
 namespace base {
 
@@ -55,6 +59,8 @@
   friend class blink::WebRtcTaskQueue;
   friend class PostDelayedTaskPassKeyForTesting;
   friend class webrtc::ThreadWrapper;
+  friend class media::AlsaPcmOutputStream;
+  friend class media::FakeAudioWorker;
 };
 
 class PostDelayedTaskPassKeyForTesting : public PostDelayedTaskPassKey {};
diff --git a/build/fuchsia/linux_internal.sdk.sha1 b/build/fuchsia/linux_internal.sdk.sha1
index cfa1891..6f64c7b 100644
--- a/build/fuchsia/linux_internal.sdk.sha1
+++ b/build/fuchsia/linux_internal.sdk.sha1
@@ -1 +1 @@
-8.20220617.0.1
+8.20220617.1.1
diff --git a/cc/input/touch_action.h b/cc/input/touch_action.h
index 2165530..d5a29507 100644
--- a/cc/input/touch_action.h
+++ b/cc/input/touch_action.h
@@ -39,8 +39,15 @@
   // and it doesn't have a horizontal scrollable ancestor (including
   // itself), we don't set this bit.
   kInternalPanXScrolls = 0x40,
-  kAuto = kManipulation | kDoubleTapZoom | kInternalPanXScrolls,
-  kMax = (1 << 7) - 1
+
+  // This is used internally by stylus handwriting feature. Stylus writing would
+  // not be started when this bit is set. When the element is non-password edit
+  // field and has kPan, we don't set this bit.
+  kInternalNotWritable = 0x80,
+
+  kAuto = kManipulation | kDoubleTapZoom | kInternalPanXScrolls |
+          kInternalNotWritable,
+  kMax = (1 << 8) - 1
 };
 
 inline TouchAction operator|(TouchAction a, TouchAction b) {
@@ -67,6 +74,11 @@
   //  we skip printing internal panx scrolls since it's not a web exposed touch
   //  action field.
   touch_action &= ~TouchAction::kInternalPanXScrolls;
+
+  // we skip printing kInternalNotWritable since it's not a web exposed
+  // touch action field.
+  touch_action &= ~TouchAction::kInternalNotWritable;
+
   switch (static_cast<int>(touch_action)) {
     case 0:
       return "NONE";
diff --git a/chrome/VERSION b/chrome/VERSION
index 32adb574..59a9c95 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=105
 MINOR=0
-BUILD=5126
+BUILD=5127
 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index 22f787f..2ca10db 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -1081,6 +1081,7 @@
     "//chrome/browser/ui/messages/android:java",
     "//chrome/browser/ui/messages/android:junit",
     "//chrome/browser/uid/android:java",
+    "//chrome/browser/uid/android:junit",
     "//chrome/browser/usb/android:junit",
     "//chrome/browser/user_education:java",
     "//chrome/browser/util:java",
@@ -1557,7 +1558,6 @@
     "//chrome/browser/ui/android/toolbar:javatests",
     "//chrome/browser/ui/messages/android:java",
     "//chrome/browser/uid/android:java",
-    "//chrome/browser/uid/android:javatests",
     "//chrome/browser/util:java",
     "//chrome/browser/video_tutorials:test_support_java",
     "//chrome/browser/webapps/android:java",
@@ -1646,7 +1646,6 @@
     "//components/paint_preview/player/android:javatests",
     "//components/password_manager/core/browser:password_manager_java_enums",
     "//components/payments/content/android:java",
-    "//components/payments/content/android:javatests",
     "//components/payments/content/android:service_java",
     "//components/payments/mojom:mojom_java",
     "//components/permissions/android:java",
@@ -3188,6 +3187,7 @@
     "//components/external_intents/android:unit_device_javatests",
     "//components/infobars/android:unit_device_javatests",
     "//components/messages/android/internal:unit_device_javatests",
+    "//components/payments/content/android:unit_device_javatests",
     "//components/signin/public/android:unit_device_javatests",
     "//components/strictmode/android:unit_device_javatests",
     "//components/url_formatter/android:unit_device_javatests",
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt
index f6a7ada..23c8b81 100644
--- a/chrome/android/profiles/newest.txt
+++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-104.0.5112.9_rc-r1-merged.afdo.bz2
+chromeos-chrome-amd64-104.0.5112.12_rc-r1-merged.afdo.bz2
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 49e9fa12..94b2dc2 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -5307,6 +5307,8 @@
       "chromeos/policy/dlp/dlp_rules_manager_factory.h",
       "chromeos/policy/dlp/dlp_rules_manager_impl.cc",
       "chromeos/policy/dlp/dlp_rules_manager_impl.h",
+      "chromeos/policy/dlp/dlp_scoped_file_access_delegate.cc",
+      "chromeos/policy/dlp/dlp_scoped_file_access_delegate.h",
       "chromeos/policy/dlp/dlp_warn_dialog.cc",
       "chromeos/policy/dlp/dlp_warn_dialog.h",
       "chromeos/policy/dlp/dlp_warn_notifier.cc",
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS
index 686f663..f054d91 100644
--- a/chrome/browser/DEPS
+++ b/chrome/browser/DEPS
@@ -152,6 +152,7 @@
   "+components/feature_engagement",
   "+components/feed",
   "+components/feedback",
+  "+components/file_access",
   "+components/find_in_page",
   "+components/flags_ui",
   "+components/app_restore",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index c09a1f15..ac05633 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -5168,6 +5168,16 @@
      FEATURE_VALUE_TYPE(omnibox::kBlurWithEscape)},
 #endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC) ||
         // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_FUCHSIA)
+#if BUILDFLAG(IS_WIN)
+    {"omnibox-on-device-head-suggestions",
+     flag_descriptions::kOmniboxOnDeviceHeadSuggestionsName,
+     flag_descriptions::kOmniboxOnDeviceHeadSuggestionsDescription, kOsWin,
+     FEATURE_VALUE_TYPE(omnibox::kOnDeviceHeadProviderNonIncognito)},
+    {"omnibox-on-device-head-suggestions-incognito",
+     flag_descriptions::kOmniboxOnDeviceHeadSuggestionsIncognitoName,
+     flag_descriptions::kOmniboxOnDeviceHeadSuggestionsIncognitoDescription,
+     kOsWin, FEATURE_VALUE_TYPE(omnibox::kOnDeviceHeadProviderIncognito)},
+#endif  // BUILDFLAG(IS_WIN)
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
     {"scheduler-configuration", flag_descriptions::kSchedulerConfigurationName,
@@ -6207,6 +6217,11 @@
      flag_descriptions::kChromeOSDirectVideoDecoderDescription,
      kOsCrOS | kOsLacros,
      FEATURE_VALUE_TYPE(media::kUseChromeOSDirectVideoDecoder)},
+
+    {"enable-vbr-encode-acceleration",
+     flag_descriptions::kChromeOSHWVBREncodingName,
+     flag_descriptions::kChromeOSHWVBREncodingDescription, kOsCrOS | kOsLacros,
+     FEATURE_VALUE_TYPE(media::kChromeOSHWVBREncoding)},
 #if defined(ARCH_CPU_ARM_FAMILY)
     {"prefer-libyuv-image-processor",
      flag_descriptions::kPreferLibYuvImageProcessorName,
@@ -7500,7 +7515,8 @@
          switches::kEnableFeatures,
          "PrivacySandboxSettings3:"
          "disable-dialog-for-testing/true/show-sample-data/true,"
-         "EnableFetchingAccountCapabilities")},
+         "EnableFetchingAccountCapabilities,InterestGroupStorage,"
+         "AdInterestGroupAPI,Fledge,FencedFrames")},
 
     {"privacy-sandbox-ads-apis",
      flag_descriptions::kPrivacySandboxAdsAPIsOverrideName,
diff --git a/chrome/browser/apps/app_service/launch_utils.cc b/chrome/browser/apps/app_service/launch_utils.cc
index f361991..fb9a73e5 100644
--- a/chrome/browser/apps/app_service/launch_utils.cc
+++ b/chrome/browser/apps/app_service/launch_utils.cc
@@ -413,6 +413,7 @@
       ConvertAppServiceToCrosapiLaunchContainer(params.container);
   crosapi_params->disposition =
       ConvertWindowOpenDispositionToCrosapi(params.disposition);
+  crosapi_params->display_id = params.display_id;
   return crosapi_params;
 }
 
@@ -423,7 +424,7 @@
       crosapi_params->app_id,
       ConvertCrosapiToAppServiceLaunchContainer(crosapi_params->container),
       ConvertWindowOpenDispositionFromCrosapi(crosapi_params->disposition),
-      crosapi_params->launch_source);
+      crosapi_params->launch_source, crosapi_params->display_id);
   if (!crosapi_params->intent) {
     return params;
   }
diff --git a/chrome/browser/apps/app_service/launch_utils_unittest.cc b/chrome/browser/apps/app_service/launch_utils_unittest.cc
index 57c52b2..16d5b37b 100644
--- a/chrome/browser/apps/app_service/launch_utils_unittest.cc
+++ b/chrome/browser/apps/app_service/launch_utils_unittest.cc
@@ -23,13 +23,14 @@
       apps::mojom::LaunchContainer container,
       WindowOpenDisposition disposition,
       bool preferred_container,
+      int64_t display_id = display::kInvalidDisplayId,
       apps::mojom::LaunchContainer fallback_container =
           apps::mojom::LaunchContainer::kLaunchContainerNone) {
     return apps::CreateAppIdLaunchParamsWithEventFlags(
         app_id,
         apps::GetEventFlags(container, disposition, preferred_container),
-        apps::mojom::LaunchSource::kFromChromeInternal,
-        display::kInvalidDisplayId, fallback_container);
+        apps::mojom::LaunchSource::kFromChromeInternal, display_id,
+        fallback_container);
   }
 
   std::string app_id = "aaa";
@@ -70,7 +71,8 @@
   auto preferred_container =
       apps::mojom::LaunchContainer::kLaunchContainerWindow;
   auto params =
-      CreateLaunchParams(container, disposition, true, preferred_container);
+      CreateLaunchParams(container, disposition, true,
+                         display::kInvalidDisplayId, preferred_container);
 
   EXPECT_EQ(preferred_container, params.container);
   EXPECT_EQ(disposition, params.disposition);
@@ -82,7 +84,8 @@
   auto preferred_container =
       apps::mojom::LaunchContainer::kLaunchContainerWindow;
   auto params =
-      CreateLaunchParams(container, disposition, true, preferred_container);
+      CreateLaunchParams(container, disposition, true,
+                         display::kInvalidDisplayId, preferred_container);
 
   EXPECT_EQ(preferred_container, params.container);
   EXPECT_EQ(WindowOpenDisposition::NEW_FOREGROUND_TAB, params.disposition);
@@ -208,7 +211,8 @@
 TEST_F(LaunchUtilsTest, ConvertToCrosapi) {
   auto container = apps::mojom::LaunchContainer::kLaunchContainerWindow;
   auto disposition = WindowOpenDisposition::NEW_WINDOW;
-  auto params = CreateLaunchParams(container, disposition, false);
+  const int64_t kDisplayId = 1;
+  auto params = CreateLaunchParams(container, disposition, false, kDisplayId);
 
   auto crosapi_params = apps::ConvertLaunchParamsToCrosapi(params, &profile_);
   auto converted_params =
@@ -217,13 +221,15 @@
   EXPECT_EQ(params.container, converted_params.container);
   EXPECT_EQ(params.disposition, converted_params.disposition);
   EXPECT_EQ(params.launch_source, converted_params.launch_source);
+  EXPECT_EQ(params.display_id, converted_params.display_id);
 }
 
 // Verifies that convert params with override url to crosapi and back works.
 TEST_F(LaunchUtilsTest, ConvertToCrosapiUrl) {
   auto container = apps::mojom::LaunchContainer::kLaunchContainerWindow;
   auto disposition = WindowOpenDisposition::NEW_WINDOW;
-  auto params = CreateLaunchParams(container, disposition, false);
+  const int64_t kDisplayId = 2;
+  auto params = CreateLaunchParams(container, disposition, false, kDisplayId);
   params.override_url = GURL("abc.example.com");
 
   auto crosapi_params = apps::ConvertLaunchParamsToCrosapi(params, &profile_);
@@ -234,13 +240,15 @@
   EXPECT_EQ(params.disposition, converted_params.disposition);
   EXPECT_EQ(params.launch_source, converted_params.launch_source);
   EXPECT_EQ(params.override_url, converted_params.override_url);
+  EXPECT_EQ(params.display_id, converted_params.display_id);
 }
 
 // Verifies that convert params with files to crosapi and back works.
 TEST_F(LaunchUtilsTest, ConvertToCrosapiFiles) {
   auto container = apps::mojom::LaunchContainer::kLaunchContainerWindow;
   auto disposition = WindowOpenDisposition::NEW_WINDOW;
-  auto params = CreateLaunchParams(container, disposition, false);
+  const int64_t kDisplayId = 3;
+  auto params = CreateLaunchParams(container, disposition, false, kDisplayId);
   params.launch_files.emplace_back("root");
 
   auto crosapi_params = apps::ConvertLaunchParamsToCrosapi(params, &profile_);
@@ -250,6 +258,7 @@
   EXPECT_EQ(params.container, converted_params.container);
   EXPECT_EQ(params.disposition, converted_params.disposition);
   EXPECT_EQ(params.launch_source, converted_params.launch_source);
+  EXPECT_EQ(params.display_id, converted_params.display_id);
   EXPECT_EQ(params.launch_files, converted_params.launch_files);
 }
 
@@ -257,7 +266,8 @@
 TEST_F(LaunchUtilsTest, ConvertToCrosapiIntent) {
   auto container = apps::mojom::LaunchContainer::kLaunchContainerWindow;
   auto disposition = WindowOpenDisposition::NEW_WINDOW;
-  auto params = CreateLaunchParams(container, disposition, false);
+  const int64_t kDisplayId = 4;
+  auto params = CreateLaunchParams(container, disposition, false, kDisplayId);
   params.intent = apps_util::CreateIntentFromUrl(GURL("abc.example.com"));
 
   auto crosapi_params = apps::ConvertLaunchParamsToCrosapi(params, &profile_);
@@ -267,6 +277,7 @@
   EXPECT_EQ(params.container, converted_params.container);
   EXPECT_EQ(params.disposition, converted_params.disposition);
   EXPECT_EQ(params.launch_source, converted_params.launch_source);
+  EXPECT_EQ(params.display_id, converted_params.display_id);
   EXPECT_EQ(params.intent, converted_params.intent);
 }
 
@@ -301,6 +312,8 @@
   crosapi_params->disposition =
       crosapi::mojom::WindowOpenDisposition::kNewForegroundTab;
   crosapi_params->launch_source = apps::mojom::LaunchSource::kFromSharesheet;
+  const int64_t kDisplayId = 5;
+  crosapi_params->display_id = kDisplayId;
   crosapi_params->intent = crosapi::mojom::Intent::New();
   crosapi_params->intent->action = apps_util::kIntentActionSend;
   crosapi_params->intent->mime_type = kIntentMimeType;
@@ -323,6 +336,7 @@
             WindowOpenDisposition::NEW_FOREGROUND_TAB);
   EXPECT_EQ(converted_params.launch_source,
             apps::mojom::LaunchSource::kFromSharesheet);
+  EXPECT_EQ(converted_params.display_id, kDisplayId);
 
   EXPECT_EQ(converted_params.launch_files.size(), 1U);
   EXPECT_EQ(converted_params.launch_files[0], base::FilePath(kFilePath));
diff --git a/chrome/browser/chrome_back_forward_cache_browsertest.cc b/chrome/browser/chrome_back_forward_cache_browsertest.cc
index 598c0662..96b82acb 100644
--- a/chrome/browser/chrome_back_forward_cache_browsertest.cc
+++ b/chrome/browser/chrome_back_forward_cache_browsertest.cc
@@ -234,8 +234,9 @@
             content::RenderFrameHost::LifecycleState::kInBackForwardCache);
 }
 
+// TODO(crbug.com/1324437): Disabled for being flaky.
 IN_PROC_BROWSER_TEST_F(ChromeBackForwardCacheBrowserTest,
-                       PermissionContextBase) {
+                       DISABLED_PermissionContextBase) {
   // HTTPS needed for GEOLOCATION permission
   net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
   https_server.AddDefaultHandlers(GetChromeTestDataDir());
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index df05d6d..a4fb70f 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -426,6 +426,7 @@
 #endif  // !BUILDFLAG(IS_CHROMEOS_ASH)
 
 #if BUILDFLAG(IS_CHROMEOS)
+#include "chrome/browser/chromeos/policy/dlp/dlp_scoped_file_access_delegate.h"
 #include "chrome/browser/chromeos/tablet_mode/chrome_content_browser_client_tablet_mode_part.h"
 #include "chrome/browser/policy/networking/policy_cert_service.h"
 #include "chrome/browser/policy/networking/policy_cert_service_factory.h"
@@ -2722,6 +2723,27 @@
   return profile->GetPrefs()->GetBoolean(prefs::kSignedHTTPExchangeEnabled);
 }
 
+void ChromeContentBrowserClient::RequestFilesAccess(
+    const std::vector<base::FilePath>& files,
+    const GURL& destination_url,
+    base::OnceCallback<void(file_access::ScopedFileAccess)>
+        continuation_callback) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+#if BUILDFLAG(IS_CHROMEOS)
+  auto* delegate = policy::DlpScopedFileAccessDelegate::Get();
+  if (delegate) {
+    delegate->RequestFilesAccess(files, destination_url,
+                                 std::move(continuation_callback));
+  } else {
+    std::move(continuation_callback)
+        .Run(file_access::ScopedFileAccess::Allowed());
+  }
+#else
+  std::move(continuation_callback)
+      .Run(file_access::ScopedFileAccess::Allowed());
+#endif
+}
+
 void ChromeContentBrowserClient::AllowWorkerFileSystem(
     const GURL& url,
     content::BrowserContext* browser_context,
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h
index 3a877063..d84961a 100644
--- a/chrome/browser/chrome_content_browser_client.h
+++ b/chrome/browser/chrome_content_browser_client.h
@@ -23,6 +23,7 @@
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/startup_data.h"
 #include "components/embedder_support/user_agent_utils.h"
+#include "components/file_access/scoped_file_access.h"
 #include "components/safe_browsing/content/browser/web_api_handshake_checker.h"
 #include "content/public/browser/child_process_security_policy.h"
 #include "content/public/browser/content_browser_client.h"
@@ -269,6 +270,11 @@
   bool DoesSchemeAllowCrossOriginSharedWorker(
       const std::string& scheme) override;
   bool AllowSignedExchange(content::BrowserContext* browser_context) override;
+  void RequestFilesAccess(
+      const std::vector<base::FilePath>& files,
+      const GURL& destination_url,
+      base::OnceCallback<void(file_access::ScopedFileAccess)>
+          continuation_callback) override;
   void AllowWorkerFileSystem(
       const GURL& url,
       content::BrowserContext* browser_context,
diff --git a/chrome/browser/chrome_preloading.cc b/chrome/browser/chrome_preloading.cc
index cc4c01ce..788aa8d8 100644
--- a/chrome/browser/chrome_preloading.cc
+++ b/chrome/browser/chrome_preloading.cc
@@ -8,3 +8,8 @@
     ChromePreloadingPredictor predictor) {
   return static_cast<content::PreloadingPredictor>(predictor);
 }
+
+content::PreloadingEligibility ToPreloadingEligibility(
+    ChromePreloadingEligibility eligibility) {
+  return static_cast<content::PreloadingEligibility>(eligibility);
+}
diff --git a/chrome/browser/chrome_preloading.h b/chrome/browser/chrome_preloading.h
index 1c94662..0e8bce1c 100644
--- a/chrome/browser/chrome_preloading.h
+++ b/chrome/browser/chrome_preloading.h
@@ -14,14 +14,19 @@
 // numeric values should never be reused.
 enum class ChromePreloadingPredictor {
   // Numbering starts from `kPreloadingPredictorContentEnd` defined in
-  // //content/public/preloading.h . Advance numbering by +1 after adding a new
-  // element.
+  // //content/browser/public/preloading.h . Advance numbering by +1 when adding
+  // a new element.
 
   // When the preloading URL is predicted from the Omnibox Direct URL Input
   // (DUI). This is used to perform various preloading operations like prefetch
   // and prerender to load Omnibox predicted URLs faster.
   kOmniboxDirectURLInput = content::kPreloadingPredictorContentEnd,
 
+  // When a pointerdown (e.g. mousedown or touchstart) event happens on an
+  // anchor element with an href value pointing to an HTTP(S) origin, we may
+  // attempt to preload the link.
+  kPointerDownOnAnchor = content::kPreloadingPredictorContentEnd + 1,
+
   // TODO(crbug.com/1309934): Integrate more Preloading predictors with
   // Preloading logging APIs.
 };
@@ -31,4 +36,20 @@
 content::PreloadingPredictor ToPreloadingPredictor(
     ChromePreloadingPredictor predictor);
 
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused.
+enum class ChromePreloadingEligibility {
+  // Numbering starts from `kPreloadingEligibilityContentEnd` defined in
+  // //content/public/preloading.h . Advance numbering by +1 when adding a new
+  // element.
+
+  // Chrome was unable to get a LoadingPredictor object for the user profile.
+  kUnableToGetLoadingPredictor = content::kPreloadingEligibilityContentEnd,
+};
+
+// Helper method to convert ChromePreloadingEligibility to
+// content::PreloadingEligibility to avoid casting.
+content::PreloadingEligibility ToPreloadingEligibility(
+    ChromePreloadingEligibility eligibility);
+
 #endif  // CHROME_BROWSER_CHROME_PRELOADING_H_
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index d328862..8a93651 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -1733,6 +1733,8 @@
     "policy/dlp/dlp_rules_manager_factory.h",
     "policy/dlp/dlp_rules_manager_impl.cc",
     "policy/dlp/dlp_rules_manager_impl.h",
+    "policy/dlp/dlp_scoped_file_access_delegate.cc",
+    "policy/dlp/dlp_scoped_file_access_delegate.h",
     "policy/dlp/dlp_warn_dialog.cc",
     "policy/dlp/dlp_warn_dialog.h",
     "policy/dlp/dlp_warn_notifier.cc",
@@ -3038,6 +3040,7 @@
     "policy/dlp/dlp_rules_manager_impl_unittest.cc",
     "policy/dlp/dlp_rules_manager_test_utils.cc",
     "policy/dlp/dlp_rules_manager_test_utils.h",
+    "policy/dlp/dlp_scoped_file_access_delegate_unittest.cc",
     "policy/dlp/mock_dlp_content_observer.cc",
     "policy/dlp/mock_dlp_content_observer.h",
     "policy/dlp/mock_dlp_rules_manager.cc",
@@ -3159,6 +3162,7 @@
     "//chromeos/dbus/cryptohome",
     "//chromeos/dbus/cryptohome:attestation_proto",
     "//chromeos/dbus/dlcservice",
+    "//chromeos/dbus/dlp",
     "//chromeos/dbus/gnubby",
     "//chromeos/dbus/lorgnette_manager:lorgnette_proto",
     "//chromeos/dbus/missive",
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.cc b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.cc
index 643e65a..3289615 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.cc
@@ -15,12 +15,12 @@
 #include "base/containers/fixed_flat_map.h"
 #include "base/feature_list.h"
 #include "base/values.h"
-#include "build/chromeos_buildflags.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller.h"
 #include "chrome/browser/chromeos/policy/dlp/dlp_histogram_helper.h"
 #include "chrome/browser/chromeos/policy/dlp/dlp_policy_constants.h"
 #include "chrome/browser/chromeos/policy/dlp/dlp_reporting_manager.h"
+#include "chrome/browser/chromeos/policy/dlp/dlp_scoped_file_access_delegate.h"
 #include "chrome/common/chrome_features.h"
 #include "chromeos/dbus/dlp/dlp_client.h"
 #include "chromeos/dbus/dlp/dlp_service.pb.h"
@@ -178,14 +178,16 @@
   return max_level;
 }
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
 void OnSetDlpFilesPolicy(const ::dlp::SetDlpFilesPolicyResponse response) {
   if (response.has_error_message()) {
+    DlpScopedFileAccessDelegate::DeleteInstance();
     LOG(ERROR) << "Failed to set DLP Files policy and start DLP daemon, error: "
                << response.error_message();
+    return;
   }
+  DCHECK(chromeos::DlpClient::Get()->IsAlive());
+  DlpScopedFileAccessDelegate::Initialize(chromeos::DlpClient::Get());
 }
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 ::dlp::DlpRuleLevel GetLevelProtoEnum(const DlpRulesManager::Level level) {
   static constexpr auto kLevelsMap =
@@ -202,6 +204,7 @@
 
 DlpRulesManagerImpl::~DlpRulesManagerImpl() {
   DataTransferDlpController::DeleteInstance();
+  DlpScopedFileAccessDelegate::DeleteInstance();
 }
 
 // static
@@ -519,7 +522,6 @@
     DataTransferDlpController::DeleteInstance();
   }
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
   // TODO(crbug.com/1174501) Shutdown the daemon when restrictions are empty.
   if (request_to_daemon.rules_size() > 0 &&
       base::FeatureList::IsEnabled(
@@ -527,8 +529,9 @@
     DlpBooleanHistogram(dlp::kFilesDaemonStartedUMA, true);
     chromeos::DlpClient::Get()->SetDlpFilesPolicy(
         request_to_daemon, base::BindOnce(&OnSetDlpFilesPolicy));
+  } else {
+    DlpScopedFileAccessDelegate::DeleteInstance();
   }
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 }
 
 }  // namespace policy
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.h b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.h
index 3ed1257..414f05f 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.h
+++ b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.h
@@ -98,6 +98,7 @@
   // string patterns.
   std::map<UrlConditionId, std::string> dst_pattterns_mapping_;
 
+  // System-wide singleton instantiated when required by rules configuration.
   std::unique_ptr<DlpReportingManager> reporting_manager_;
 };
 
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl_unittest.cc b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl_unittest.cc
index 8938a23..bcc31e6 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl_unittest.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl_unittest.cc
@@ -667,6 +667,7 @@
   EXPECT_EQ(1, chromeos::DlpClient::Get()
                    ->GetTestInterface()
                    ->GetSetDlpFilesPolicyCount());
+  base::RunLoop().RunUntilIdle();
   chromeos::DlpClient::Shutdown();
 }
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_scoped_file_access_delegate.cc b/chrome/browser/chromeos/policy/dlp/dlp_scoped_file_access_delegate.cc
new file mode 100644
index 0000000..363ff619
--- /dev/null
+++ b/chrome/browser/chromeos/policy/dlp/dlp_scoped_file_access_delegate.cc
@@ -0,0 +1,82 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/policy/dlp/dlp_scoped_file_access_delegate.h"
+
+#include <sys/stat.h>
+
+#include "base/process/process_handle.h"
+#include "chromeos/dbus/dlp/dlp_client.h"
+
+namespace policy {
+
+namespace {
+
+static DlpScopedFileAccessDelegate* g_delegate = nullptr;
+
+ino_t GetInodeValue(const base::FilePath& path) {
+  struct stat file_stats;
+  if (stat(path.value().c_str(), &file_stats) != 0)
+    return 0;
+  return file_stats.st_ino;
+}
+
+}  // namespace
+
+// static
+DlpScopedFileAccessDelegate* DlpScopedFileAccessDelegate::Get() {
+  return g_delegate;
+}
+
+// static
+void DlpScopedFileAccessDelegate::Initialize(chromeos::DlpClient* client) {
+  g_delegate = new DlpScopedFileAccessDelegate(client);
+}
+
+// static
+void DlpScopedFileAccessDelegate::DeleteInstance() {
+  delete g_delegate;
+  g_delegate = nullptr;
+}
+
+DlpScopedFileAccessDelegate::DlpScopedFileAccessDelegate(
+    chromeos::DlpClient* client)
+    : client_(client) {}
+
+void DlpScopedFileAccessDelegate::RequestFilesAccess(
+    const std::vector<base::FilePath>& files,
+    const GURL& destination_url,
+    base::OnceCallback<void(file_access::ScopedFileAccess)> callback) {
+  if (!client_->IsAlive()) {
+    std::move(callback).Run(file_access::ScopedFileAccess::Allowed());
+    return;
+  }
+
+  dlp::RequestFileAccessRequest request;
+  for (const auto& file : files) {
+    auto inode_n = GetInodeValue(file);
+    if (inode_n > 0) {
+      request.add_inodes(inode_n);
+    }
+  }
+  request.set_destination_url(destination_url.spec());
+  request.set_process_id(base::GetCurrentProcId());
+  client_->RequestFileAccess(
+      request, base::BindOnce(&DlpScopedFileAccessDelegate::OnResponse,
+                              base::Unretained(this), std::move(callback)));
+}
+
+void DlpScopedFileAccessDelegate::OnResponse(
+    base::OnceCallback<void(file_access::ScopedFileAccess)> callback,
+    const dlp::RequestFileAccessResponse response,
+    base::ScopedFD fd) {
+  if (response.has_error_message()) {
+    std::move(callback).Run(file_access::ScopedFileAccess::Allowed());
+    return;
+  }
+  std::move(callback).Run(
+      file_access::ScopedFileAccess(response.allowed(), std::move(fd)));
+}
+
+}  // namespace policy
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_scoped_file_access_delegate.h b/chrome/browser/chromeos/policy/dlp/dlp_scoped_file_access_delegate.h
new file mode 100644
index 0000000..b5f6edc
--- /dev/null
+++ b/chrome/browser/chromeos/policy/dlp/dlp_scoped_file_access_delegate.h
@@ -0,0 +1,63 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_POLICY_DLP_DLP_SCOPED_FILE_ACCESS_DELEGATE_H_
+#define CHROME_BROWSER_CHROMEOS_POLICY_DLP_DLP_SCOPED_FILE_ACCESS_DELEGATE_H_
+
+#include <string>
+#include <vector>
+
+#include "base/callback.h"
+#include "base/files/file_path.h"
+#include "base/files/scoped_file.h"
+#include "chromeos/dbus/dlp/dlp_service.pb.h"
+#include "components/file_access/scoped_file_access.h"
+#include "url/gurl.h"
+
+namespace chromeos {
+class DlpClient;
+}  // namespace chromeos
+
+namespace policy {
+
+// Delegate class to proxy file access requests to DLP daemon over D-Bus when
+// DLP Files restrictions should apply.
+class DlpScopedFileAccessDelegate {
+ public:
+  ~DlpScopedFileAccessDelegate() = default;
+
+  // Returns the singleton instance if was initialized.
+  // Otherwise it means that no files DLP restrictions should be applied.
+  static DlpScopedFileAccessDelegate* Get();
+
+  // Initializes the singleton instance.
+  static void Initialize(chromeos::DlpClient* client);
+
+  // Deletes the singleton instance.
+  static void DeleteInstance();
+
+  // Requests access to |files| in order to be sent to |destination_url|.
+  // |continuation_callback| is called with a token that should be hold until
+  // `open()` operation on the files finished.
+  void RequestFilesAccess(
+      const std::vector<base::FilePath>& files,
+      const GURL& destination_url,
+      base::OnceCallback<void(file_access::ScopedFileAccess)> callback);
+
+ private:
+  friend class DlpScopedFileAccessDelegateTest;
+  explicit DlpScopedFileAccessDelegate(chromeos::DlpClient* client);
+
+  // Handles D-Bus response to access files.
+  void OnResponse(
+      base::OnceCallback<void(file_access::ScopedFileAccess)> callback,
+      const ::dlp::RequestFileAccessResponse response,
+      base::ScopedFD fd);
+
+  chromeos::DlpClient* client_;
+};
+
+}  // namespace policy
+
+#endif  // CHROME_BROWSER_CHROMEOS_POLICY_DLP_DLP_SCOPED_FILE_ACCESS_DELEGATE_H_
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_scoped_file_access_delegate_unittest.cc b/chrome/browser/chromeos/policy/dlp/dlp_scoped_file_access_delegate_unittest.cc
new file mode 100644
index 0000000..b724a5a7
--- /dev/null
+++ b/chrome/browser/chromeos/policy/dlp/dlp_scoped_file_access_delegate_unittest.cc
@@ -0,0 +1,48 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/policy/dlp/dlp_scoped_file_access_delegate.h"
+
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/test/task_environment.h"
+#include "base/test/test_future.h"
+#include "chromeos/dbus/dlp/fake_dlp_client.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace policy {
+
+class DlpScopedFileAccessDelegateTest : public testing::Test {
+ public:
+  DlpScopedFileAccessDelegateTest() = default;
+  ~DlpScopedFileAccessDelegateTest() override = default;
+
+  DlpScopedFileAccessDelegateTest(const DlpScopedFileAccessDelegateTest&) =
+      delete;
+  DlpScopedFileAccessDelegateTest& operator=(
+      const DlpScopedFileAccessDelegateTest&) = delete;
+
+ protected:
+  base::test::SingleThreadTaskEnvironment task_environment_;
+  chromeos::FakeDlpClient fake_dlp_client_;
+  DlpScopedFileAccessDelegate delegate_{&fake_dlp_client_};
+};
+
+TEST_F(DlpScopedFileAccessDelegateTest, Test) {
+  base::FilePath file_path;
+  base::CreateTemporaryFile(&file_path);
+
+  base::test::TestFuture<file_access::ScopedFileAccess> future1;
+  delegate_.RequestFilesAccess({file_path}, GURL("example.com"),
+                               future1.GetCallback());
+  EXPECT_TRUE(future1.Get<0>().is_allowed());
+
+  fake_dlp_client_.SetFileAccessAllowed(false);
+  base::test::TestFuture<file_access::ScopedFileAccess> future2;
+  delegate_.RequestFilesAccess({file_path}, GURL("example.com"),
+                               future2.GetCallback());
+  EXPECT_FALSE(future2.Get<0>().is_allowed());
+}
+
+}  // namespace policy
diff --git a/chrome/browser/extensions/updater/extension_updater_unittest.cc b/chrome/browser/extensions/updater/extension_updater_unittest.cc
index a48d9b71..9ef93f56 100644
--- a/chrome/browser/extensions/updater/extension_updater_unittest.cc
+++ b/chrome/browser/extensions/updater/extension_updater_unittest.cc
@@ -1505,13 +1505,12 @@
     CRXFileInfo crx_file_info;
     base::Version version("0.0.1");
     std::set<int> requests({0});
+    ExtensionDownloaderTask task = CreateDownloaderTask(id);
+    task.fetch_priority = fetch_priority;
     std::unique_ptr<ExtensionDownloader::ExtensionFetch> fetch =
         std::make_unique<ExtensionDownloader::ExtensionFetch>(
-            ExtensionDownloaderTask(id, GURL() /*update_url*/,
-                                    ManifestLocation::kInternal,
-                                    false /*is_corrupt_reinstall*/,
-                                    0 /*request_id*/, fetch_priority),
-            test_url, hash, version.GetString(), requests, fetch_priority);
+            std::move(task), test_url, hash, version.GetString(), requests,
+            fetch_priority);
 
     updater.downloader_->FetchUpdatedExtension(std::move(fetch), absl::nullopt);
 
@@ -1554,12 +1553,8 @@
     requests.insert(0);
     std::unique_ptr<ExtensionDownloader::ExtensionFetch> fetch =
         std::make_unique<ExtensionDownloader::ExtensionFetch>(
-            ExtensionDownloaderTask(
-                id, GURL() /*update_url*/, ManifestLocation::kInternal,
-                false /*is_corrupt_reinstall*/, 0 /*request_id*/,
-                DownloadFetchPriority::kBackground),
-            test_url, hash, version.GetString(), requests,
-            DownloadFetchPriority::kBackground);
+            CreateDownloaderTask(id), test_url, hash, version.GetString(),
+            requests, DownloadFetchPriority::kBackground);
     updater.downloader_->FetchUpdatedExtension(std::move(fetch), absl::nullopt);
 
     if (pending) {
@@ -1832,12 +1827,8 @@
     requests.insert(0);
     std::unique_ptr<ExtensionDownloader::ExtensionFetch> extension_fetch =
         std::make_unique<ExtensionDownloader::ExtensionFetch>(
-            ExtensionDownloaderTask(
-                id, GURL() /*update_url*/, ManifestLocation::kInternal,
-                false /*is_corrupt_reinstall*/, 0 /*request_id*/,
-                DownloadFetchPriority::kBackground),
-            test_url, hash, version.GetString(), requests,
-            DownloadFetchPriority::kBackground);
+            CreateDownloaderTask(id), test_url, hash, version.GetString(),
+            requests, DownloadFetchPriority::kBackground);
     updater.downloader_->FetchUpdatedExtension(std::move(extension_fetch),
                                                absl::nullopt);
 
@@ -2058,19 +2049,11 @@
     // Start two fetches
     std::unique_ptr<ExtensionDownloader::ExtensionFetch> fetch1 =
         std::make_unique<ExtensionDownloader::ExtensionFetch>(
-            ExtensionDownloaderTask(
-                id1, GURL() /*update_url*/, ManifestLocation::kInternal,
-                false /*is_corrupt_reinstall*/, 0 /*request_id*/,
-                DownloadFetchPriority::kBackground),
-            url1, hash1, version1, requests,
+            CreateDownloaderTask(id1), url1, hash1, version1, requests,
             DownloadFetchPriority::kBackground);
     std::unique_ptr<ExtensionDownloader::ExtensionFetch> fetch2 =
         std::make_unique<ExtensionDownloader::ExtensionFetch>(
-            ExtensionDownloaderTask(
-                id2, GURL() /*update_url*/, ManifestLocation::kInternal,
-                false /*is_corrupt_reinstall*/, 0 /*request_id*/,
-                DownloadFetchPriority::kBackground),
-            url2, hash2, version2, requests,
+            CreateDownloaderTask(id2), url2, hash2, version2, requests,
             DownloadFetchPriority::kBackground);
     updater.downloader_->FetchUpdatedExtension(std::move(fetch1),
                                                absl::optional<std::string>());
@@ -2696,25 +2679,22 @@
   std::string id = crx_file::id_util::GenerateId("foo");
   EXPECT_CALL(helper->delegate(), GetPingDataForExtension(id, _))
       .WillOnce(Return(false));
-  EXPECT_TRUE(helper->downloader().AddPendingExtension(ExtensionDownloaderTask(
-      id, GURL("http://example.com/update"), ManifestLocation::kInternal, false,
-      0, DownloadFetchPriority::kBackground)));
+  EXPECT_TRUE(helper->downloader().AddPendingExtension(
+      CreateDownloaderTask(id, GURL("http://example.com/update"))));
   helper->downloader().StartAllPending(nullptr);
   Mock::VerifyAndClearExpectations(&helper->delegate());
   EXPECT_EQ(1u, ManifestFetchersCount(&helper->downloader()));
 
   // Extensions with invalid update URLs should be rejected.
   id = crx_file::id_util::GenerateId("foo2");
-  EXPECT_FALSE(helper->downloader().AddPendingExtension(ExtensionDownloaderTask(
-      id, GURL("http:google.com:foo"), ManifestLocation::kInternal, false, 0,
-      DownloadFetchPriority::kBackground)));
+  EXPECT_FALSE(helper->downloader().AddPendingExtension(
+      CreateDownloaderTask(id, GURL("http:google.com:foo"))));
   helper->downloader().StartAllPending(nullptr);
   EXPECT_EQ(1u, ManifestFetchersCount(&helper->downloader()));
 
   // Extensions with empty IDs should be rejected.
-  EXPECT_FALSE(helper->downloader().AddPendingExtension(ExtensionDownloaderTask(
-      std::string(), GURL(), ManifestLocation::kInternal, false, 0,
-      DownloadFetchPriority::kBackground)));
+  EXPECT_FALSE(helper->downloader().AddPendingExtension(
+      CreateDownloaderTask(std::string(), GURL())));
   helper->downloader().StartAllPending(nullptr);
   EXPECT_EQ(1u, ManifestFetchersCount(&helper->downloader()));
 
@@ -2731,8 +2711,7 @@
   EXPECT_CALL(helper->delegate(), GetPingDataForExtension(id, _))
       .WillOnce(Return(false));
   EXPECT_TRUE(helper->downloader().AddPendingExtension(
-      ExtensionDownloaderTask(id, GURL(), ManifestLocation::kInternal, false, 0,
-                              DownloadFetchPriority::kBackground)));
+      CreateDownloaderTask(id, GURL())));
   helper->downloader().StartAllPending(nullptr);
   EXPECT_EQ(1u, ManifestFetchersCount(&helper->downloader()));
 
@@ -2747,51 +2726,57 @@
   auto helper = std::make_unique<ExtensionDownloaderTestHelper>();
   EXPECT_EQ(0u, ManifestFetchersCount(&helper->downloader()));
 
-  // First, verify that adding valid extensions does invoke the callbacks on
-  // the delegate.
-  std::string id = crx_file::id_util::GenerateId("foo");
-  EXPECT_CALL(helper->delegate(), GetPingDataForExtension(id, _))
-      .WillOnce(Return(false));
-  EXPECT_TRUE(helper->downloader().AddPendingExtension(ExtensionDownloaderTask(
-      id, GURL("http://example.com/update"), ManifestLocation::kInternal, false,
-      0, DownloadFetchPriority::kBackground, base::Version(kVersion),
-      Manifest::TYPE_UNKNOWN, std::string())));
-  helper->downloader().StartAllPending(nullptr);
-  Mock::VerifyAndClearExpectations(&helper->delegate());
-  EXPECT_EQ(1u, ManifestFetchersCount(&helper->downloader()));
+  {
+    // First, verify that adding valid extensions does invoke the callbacks on
+    // the delegate.
+    ExtensionId id = crx_file::id_util::GenerateId("foo");
+    EXPECT_CALL(helper->delegate(), GetPingDataForExtension(id, _))
+        .WillOnce(Return(false));
+    ExtensionDownloaderTask task =
+        CreateDownloaderTask(id, GURL("http://example.com/update"));
+    task.version = base::Version(kVersion);
+    EXPECT_TRUE(helper->downloader().AddPendingExtension(std::move(task)));
+    helper->downloader().StartAllPending(nullptr);
+    Mock::VerifyAndClearExpectations(&helper->delegate());
+    EXPECT_EQ(1u, ManifestFetchersCount(&helper->downloader()));
+  }
 
-  // Extensions with invalid update URLs should be rejected.
-  id = crx_file::id_util::GenerateId("foo2");
-  EXPECT_FALSE(helper->downloader().AddPendingExtension(ExtensionDownloaderTask(
-      id, GURL("http:google.com:foo"), ManifestLocation::kInternal, false, 0,
-      DownloadFetchPriority::kBackground, base::Version(kVersion),
-      Manifest::TYPE_UNKNOWN, std::string())));
-  helper->downloader().StartAllPending(nullptr);
-  EXPECT_EQ(1u, ManifestFetchersCount(&helper->downloader()));
+  {
+    // Extensions with invalid update URLs should be rejected.
+    ExtensionId id = crx_file::id_util::GenerateId("foo2");
+    ExtensionDownloaderTask task =
+        CreateDownloaderTask(id, GURL("http:google.com:foo"));
+    task.version = base::Version(kVersion);
+    EXPECT_FALSE(helper->downloader().AddPendingExtension(std::move(task)));
+    helper->downloader().StartAllPending(nullptr);
+    EXPECT_EQ(1u, ManifestFetchersCount(&helper->downloader()));
+  }
 
-  // Extensions with empty IDs should be rejected.
-  EXPECT_FALSE(helper->downloader().AddPendingExtension(ExtensionDownloaderTask(
-      std::string(), GURL(), ManifestLocation::kInternal, false, 0,
-      DownloadFetchPriority::kBackground, base::Version(kVersion),
-      Manifest::TYPE_UNKNOWN, std::string())));
-  helper->downloader().StartAllPending(nullptr);
-  EXPECT_EQ(1u, ManifestFetchersCount(&helper->downloader()));
+  {
+    // Extensions with empty IDs should be rejected.
+    ExtensionDownloaderTask task = CreateDownloaderTask(std::string(), GURL());
+    task.version = base::Version(kVersion);
+    EXPECT_FALSE(helper->downloader().AddPendingExtension(std::move(task)));
+    helper->downloader().StartAllPending(nullptr);
+    EXPECT_EQ(1u, ManifestFetchersCount(&helper->downloader()));
+  }
 
   // Reset the ExtensionDownloader so that it drops the current fetcher.
   helper = std::make_unique<ExtensionDownloaderTestHelper>();
   EXPECT_EQ(0u, ManifestFetchersCount(&helper->downloader()));
 
-  // Extensions with empty update URLs should have a default one
-  // filled in.
-  id = crx_file::id_util::GenerateId("foo3");
-  EXPECT_CALL(helper->delegate(), GetPingDataForExtension(id, _))
-      .WillOnce(Return(false));
-  EXPECT_TRUE(helper->downloader().AddPendingExtension(ExtensionDownloaderTask(
-      id, GURL(), ManifestLocation::kInternal, false, 0,
-      DownloadFetchPriority::kBackground, base::Version(kVersion),
-      Manifest::TYPE_UNKNOWN, std::string())));
-  helper->downloader().StartAllPending(nullptr);
-  EXPECT_EQ(1u, ManifestFetchersCount(&helper->downloader()));
+  {
+    // Extensions with empty update URLs should have a default one
+    // filled in.
+    ExtensionId id = crx_file::id_util::GenerateId("foo3");
+    EXPECT_CALL(helper->delegate(), GetPingDataForExtension(id, _))
+        .WillOnce(Return(false));
+    ExtensionDownloaderTask task = CreateDownloaderTask(id, GURL());
+    task.version = base::Version(kVersion);
+    EXPECT_TRUE(helper->downloader().AddPendingExtension(std::move(task)));
+    helper->downloader().StartAllPending(nullptr);
+    EXPECT_EQ(1u, ManifestFetchersCount(&helper->downloader()));
+  }
 
   RunUntilIdle();
   auto* request = &(*helper->test_url_loader_factory().pending_requests())[0];
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index f0224f15..3ddcc707 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -2906,6 +2906,11 @@
     "expiry_milestone": 110
   },
   {
+    "name": "enable-vbr-encode-acceleration",
+    "owners": [ "chromeos-gfx-video@google.com" ],
+    "expiry_milestone": 120
+  },
+  {
     "name": "enable-virtual-keyboard",
     "owners": [ "//ash/keyboard/OWNERS" ],
     // Useful for debugging the virtual keyboard on non-tablet devices.
@@ -4613,14 +4618,14 @@
       "expiry_milestone": 105
   },
   {
-    "name": "omnibox-on-device-head-suggestions-incognito",
+    "name": "omnibox-on-device-head-suggestions",
     "owners": [ "cechen@google.com", "suggest-2g@google.com" ],
-    "expiry_milestone": 93
+    "expiry_milestone": 120
   },
   {
-    "name": "omnibox-on-device-head-suggestions-non-incognito",
+    "name": "omnibox-on-device-head-suggestions-incognito",
     "owners": [ "cechen@google.com", "suggest-2g@google.com" ],
-    "expiry_milestone": 93
+    "expiry_milestone": 120
   },
   {
     "name": "omnibox-on-focus-suggestions-contextual-web",
@@ -5061,7 +5066,7 @@
       "dullweber",
       "sauski",
       "chrome-friendly-settings@google.com"],
-    "expiry_milestone": 103
+    "expiry_milestone": 108
   },
   {
     "name": "privacy-sandbox-v3-desktop",
@@ -5069,7 +5074,7 @@
       "dullweber",
       "sauski",
       "chrome-friendly-settings@google.com"],
-    "expiry_milestone": 103
+    "expiry_milestone": 108
   },
   {
     "name": "private-network-access-respect-preflight-results",
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index ec1f697..96ac4e5 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -1844,6 +1844,21 @@
     "in the HTTP cache. If no or zero duration is provided, the existing "
     "in-memory cache will used instead of HTTP cache.";
 
+const char kOmniboxOnDeviceHeadSuggestionsName[] =
+    "Omnibox on device head suggestions (non-incognito only)";
+const char kOmniboxOnDeviceHeadSuggestionsDescription[] =
+    "Google head non personalized search suggestions provided by a compact on "
+    "device model for non-incognito. Turn off this feature if you have other "
+    "apps running which affects local file access (e.g. anti-virus software) "
+    "and are experiencing searchbox typing lags.";
+const char kOmniboxOnDeviceHeadSuggestionsIncognitoName[] =
+    "Omnibox on device head suggestions (incognito only)";
+const char kOmniboxOnDeviceHeadSuggestionsIncognitoDescription[] =
+    "Google head non personalized search suggestions provided by a compact on "
+    "device model for incognito. Turn off this feature if you have other "
+    "apps running which affects local file access (e.g. anti-virus software) "
+    "and are experiencing searchbox typing lags.";
+
 const char kOmniboxRichAutocompletionName[] = "Omnibox Rich Autocompletion";
 const char kOmniboxRichAutocompletionDescription[] =
     "Allow autocompletion for titles and non-prefixes. I.e. suggestions whose "
@@ -5814,6 +5829,13 @@
     "which is added for platforms where said direct VideoDecoder does not work "
     "or is not well tested (see the disable_cros_video_decoder USE flag in "
     "ChromeOS)";
+const char kChromeOSHWVBREncodingName[] =
+    "ChromeOS Hardware Variable Bitrate Encoding";
+const char kChromeOSHWVBREncodingDescription[] =
+    "Enables the hardware-accelerated variable bitrate (VBR) encoding on "
+    "ChromeOS. If the hardware encoder supports VBR for a specified codec, a "
+    "video is recorded in VBR encoding in MediaRecoder API automatically and "
+    "WebCodecs API if configured so.";
 #if defined(ARCH_CPU_ARM_FAMILY)
 const char kPreferLibYuvImageProcessorName[] = "Prefer libYUV image processor";
 const char kPreferLibYuvImageProcessorDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 384f582a..66e2a445 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -1038,6 +1038,12 @@
 extern const char kOmniboxMostVisitedTilesName[];
 extern const char kOmniboxMostVisitedTilesDescription[];
 
+extern const char kOmniboxOnDeviceHeadSuggestionsName[];
+extern const char kOmniboxOnDeviceHeadSuggestionsDescription[];
+
+extern const char kOmniboxOnDeviceHeadSuggestionsIncognitoName[];
+extern const char kOmniboxOnDeviceHeadSuggestionsIncognitoDescription[];
+
 extern const char kOmniboxRichAutocompletionName[];
 extern const char kOmniboxRichAutocompletionDescription[];
 extern const char kOmniboxRichAutocompletionMinCharName[];
@@ -3335,6 +3341,8 @@
 #if BUILDFLAG(IS_CHROMEOS) && BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION)
 extern const char kChromeOSDirectVideoDecoderName[];
 extern const char kChromeOSDirectVideoDecoderDescription[];
+extern const char kChromeOSHWVBREncodingName[];
+extern const char kChromeOSHWVBREncodingDescription[];
 #if defined(ARCH_CPU_ARM_FAMILY)
 extern const char kPreferLibYuvImageProcessorName[];
 extern const char kPreferLibYuvImageProcessorDescription[];
diff --git a/chrome/browser/navigation_predictor/anchor_element_preloader.cc b/chrome/browser/navigation_predictor/anchor_element_preloader.cc
index 1e56ec5..37c87627 100644
--- a/chrome/browser/navigation_predictor/anchor_element_preloader.cc
+++ b/chrome/browser/navigation_predictor/anchor_element_preloader.cc
@@ -3,17 +3,28 @@
 // found in the LICENSE file.
 
 #include "chrome/browser/navigation_predictor/anchor_element_preloader.h"
+#include "base/callback.h"
 #include "base/metrics/histogram_functions.h"
+#include "chrome/browser/chrome_preloading.h"
 #include "chrome/browser/predictors/loading_predictor.h"
 #include "chrome/browser/predictors/loading_predictor_factory.h"
 #include "chrome/browser/prefetch/prefetch_prefs.h"
 #include "content/public/browser/browser_context.h"
+#include "content/public/browser/preloading.h"
+#include "content/public/browser/preloading_data.h"
 #include "content/public/browser/web_contents.h"
 #include "services/metrics/public/cpp/ukm_builders.h"
 #include "services/metrics/public/cpp/ukm_recorder.h"
 #include "third_party/blink/public/common/features.h"
 #include "url/scheme_host_port.h"
 
+namespace {
+bool is_match_for_preconnect(const url::SchemeHostPort& preconnected_origin,
+                             const GURL& visited_url) {
+  return preconnected_origin == url::SchemeHostPort(visited_url);
+}
+}  // anonymous namespace
+
 const char kPreloadingAnchorElementPreloaderPreloadingTriggered[] =
     "Preloading.AnchorElementPreloader.PreloadingTriggered";
 
@@ -36,36 +47,61 @@
 }
 
 void AnchorElementPreloader::OnPointerDown(const GURL& target) {
+  content::PreloadingData* preloading_data =
+      content::PreloadingData::GetOrCreateForWebContents(
+          content::WebContents::FromRenderFrameHost(render_frame_host()));
+  url::SchemeHostPort scheme_host_port(target);
+  content::PreloadingURLMatchCallback match_callback =
+      base::BindRepeating(is_match_for_preconnect, scheme_host_port);
+
+  // For now we add a prediction with a confidence of 100. In the future we will
+  // likely compute the confidence by looking at different factors (e.g. anchor
+  // element dimensions, last time since scroll, etc.).
+  preloading_data->AddPreloadingPrediction(
+      ToPreloadingPredictor(ChromePreloadingPredictor::kPointerDownOnAnchor),
+      /*confidence=*/100, match_callback);
+  content::PreloadingAttempt* attempt = preloading_data->AddPreloadingAttempt(
+      ToPreloadingPredictor(ChromePreloadingPredictor::kPointerDownOnAnchor),
+      content::PreloadingType::kPreconnect, match_callback);
+
   if (!prefetch::IsSomePreloadingEnabled(
           *Profile::FromBrowserContext(render_frame_host()->GetBrowserContext())
                ->GetPrefs())) {
-    return;
-  }
-  url::SchemeHostPort scheme_host_port(target);
-  if (preconnected_targets_.find(scheme_host_port) !=
-      preconnected_targets_.end()) {
-    // We've already preconnected to that origin.
-    return;
-  }
-  preconnected_targets_.insert(scheme_host_port);
-
-  RecordUmaPreloadedTriggered(AnchorElementPreloaderType::kPreconnect);
-
-  RecordUkmPreloadType(AnchorElementPreloaderType::kPreconnect);
-
-  if (base::GetFieldTrialParamByFeatureAsBool(
-          blink::features::kAnchorElementInteraction, "preconnect_holdback",
-          false)) {
+    attempt->SetEligibility(
+        content::PreloadingEligibility::kPreloadingDisabled);
     return;
   }
 
   auto* loading_predictor = predictors::LoadingPredictorFactory::GetForProfile(
       Profile::FromBrowserContext(render_frame_host()->GetBrowserContext()));
-
   if (!loading_predictor) {
+    attempt->SetEligibility(ToPreloadingEligibility(
+        ChromePreloadingEligibility::kUnableToGetLoadingPredictor));
     return;
   }
 
+  attempt->SetEligibility(content::PreloadingEligibility::kEligible);
+  RecordUmaPreloadedTriggered(AnchorElementPreloaderType::kPreconnect);
+
+  if (base::GetFieldTrialParamByFeatureAsBool(
+          blink::features::kAnchorElementInteraction, "preconnect_holdback",
+          false)) {
+    attempt->SetHoldbackStatus(content::PreloadingHoldbackStatus::kHoldback);
+    return;
+  }
+  attempt->SetHoldbackStatus(content::PreloadingHoldbackStatus::kAllowed);
+
+  if (preconnected_targets_.find(scheme_host_port) !=
+      preconnected_targets_.end()) {
+    // We've already preconnected to that origin.
+    attempt->SetTriggeringOutcome(
+        content::PreloadingTriggeringOutcome::kDuplicate);
+    return;
+  }
+  preconnected_targets_.insert(scheme_host_port);
+  attempt->SetTriggeringOutcome(
+      content::PreloadingTriggeringOutcome::kTriggeredButOutcomeUnknown);
+
   net::SchemefulSite schemeful_site(target);
   net::NetworkIsolationKey network_isolation_key(schemeful_site,
                                                  schemeful_site);
@@ -78,13 +114,3 @@
   base::UmaHistogramEnumeration(
       kPreloadingAnchorElementPreloaderPreloadingTriggered, preload);
 }
-
-void AnchorElementPreloader::RecordUkmPreloadType(
-    AnchorElementPreloaderType type) {
-  ukm::SourceId source_id = render_frame_host()->GetPageUkmSourceId();
-
-  ukm::UkmRecorder* ukm_recorder = ukm::UkmRecorder::Get();
-  ukm::builders::Preloading_AnchorInteraction(source_id)
-      .SetAnchorElementPreloaderType(static_cast<int64_t>(type))
-      .Record(ukm_recorder);
-}
diff --git a/chrome/browser/navigation_predictor/anchor_element_preloader_browsertest.cc b/chrome/browser/navigation_predictor/anchor_element_preloader_browsertest.cc
index c2000ff..35464f0 100644
--- a/chrome/browser/navigation_predictor/anchor_element_preloader_browsertest.cc
+++ b/chrome/browser/navigation_predictor/anchor_element_preloader_browsertest.cc
@@ -5,6 +5,7 @@
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
+#include "chrome/browser/chrome_preloading.h"
 #include "chrome/browser/navigation_predictor/anchor_element_preloader.h"
 #include "chrome/browser/predictors/loading_predictor.h"
 #include "chrome/browser/predictors/loading_predictor_factory.h"
@@ -15,8 +16,10 @@
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/ukm/test_ukm_recorder.h"
+#include "content/public/browser/preloading.h"
 #include "content/public/test/browser_test.h"
 #include "content/public/test/browser_test_utils.h"
+#include "content/public/test/preloading_test_util.h"
 #include "net/base/features.h"
 #include "net/dns/mock_host_resolver.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
@@ -26,6 +29,10 @@
 #include "ui/gfx/geometry/point_conversions.h"
 
 namespace {
+
+using UkmEntry = ukm::TestUkmRecorder::HumanReadableUkmEntry;
+using Preloading_Attempt = ukm::builders::Preloading_Attempt;
+
 class AnchorElementPreloaderBrowserTest
     : public subresource_filter::SubresourceFilterBrowserTest,
       public predictors::PreconnectManager::Observer {
@@ -61,6 +68,11 @@
             browser()->profile());
     histogram_tester_ = std::make_unique<base::HistogramTester>();
     test_ukm_recorder_ = std::make_unique<ukm::TestAutoSetUkmRecorder>();
+    ukm_entry_builder_ =
+        std::make_unique<content::test::PreloadingAttemptUkmEntryBuilder>(
+            content::PreloadingType::kPreconnect,
+            ToPreloadingPredictor(
+                ChromePreloadingPredictor::kPointerDownOnAnchor));
     ASSERT_TRUE(loading_predictor);
     loading_predictor->preconnect_manager()->SetObserverForTesting(this);
   }
@@ -109,6 +121,17 @@
     return test_ukm_recorder_.get();
   }
 
+  content::RenderFrameHost* GetPrimaryMainFrame() {
+    return browser()
+        ->tab_strip_model()
+        ->GetActiveWebContents()
+        ->GetPrimaryMainFrame();
+  }
+
+  const content::test::PreloadingAttemptUkmEntryBuilder& ukm_entry_builder() {
+    return *ukm_entry_builder_;
+  }
+
   base::HistogramTester* histogram_tester() { return histogram_tester_.get(); }
 
  protected:
@@ -120,6 +143,8 @@
   std::unique_ptr<base::RunLoop> run_loop_;
   std::unique_ptr<ukm::TestAutoSetUkmRecorder> test_ukm_recorder_;
   std::unique_ptr<base::HistogramTester> histogram_tester_;
+  std::unique_ptr<content::test::PreloadingAttemptUkmEntryBuilder>
+      ukm_entry_builder_;
 };
 
 IN_PROC_BROWSER_TEST_F(AnchorElementPreloaderBrowserTest, OneAnchor) {
@@ -129,12 +154,6 @@
 
   WaitForPreresolveCountForURL(1);
   EXPECT_EQ(1, preresolve_count_);
-  ukm::SourceId ukm_source_id = browser()
-                                    ->tab_strip_model()
-                                    ->GetActiveWebContents()
-                                    ->GetPrimaryMainFrame()
-                                    ->GetPageUkmSourceId();
-
   histogram_tester()->ExpectTotalCount(
       kPreloadingAnchorElementPreloaderPreloadingTriggered, 1);
 
@@ -142,67 +161,106 @@
       kPreloadingAnchorElementPreloaderPreloadingTriggered,
       AnchorElementPreloaderType::kPreconnect, 1);
 
+  // Navigate away to the same origin that was preconnected. This should flush
+  // the Preloading UKM logs.
+  EXPECT_TRUE(ui_test_utils::NavigateToURL(
+      browser(), GURL(std::string(kOrigin1) + "foo")));
+  ukm::SourceId ukm_source_id = GetPrimaryMainFrame()->GetPageUkmSourceId();
   auto ukm_entries = test_ukm_recorder()->GetEntries(
-      ukm::builders::Preloading_AnchorInteraction::kEntryName,
-      {ukm::builders::Preloading_AnchorInteraction::
-           kAnchorElementPreloaderTypeName});
-
+      Preloading_Attempt::kEntryName,
+      content::test::kPreloadingAttemptUkmMetrics);
   EXPECT_EQ(ukm_entries.size(), 1u);
-
-  EXPECT_EQ(ukm_entries[0].source_id, ukm_source_id);
+  UkmEntry expected_entry = ukm_entry_builder().BuildEntry(
+      ukm_source_id, content::PreloadingEligibility::kEligible,
+      content::PreloadingHoldbackStatus::kAllowed,
+      content::PreloadingTriggeringOutcome::kTriggeredButOutcomeUnknown,
+      /*accurate=*/true);
+  EXPECT_EQ(ukm_entries[0], expected_entry)
+      << content::test::ActualVsExpectedUkmEntryToString(ukm_entries[0],
+                                                         expected_entry);
 }
 
-IN_PROC_BROWSER_TEST_F(AnchorElementPreloaderBrowserTest, Duplicates) {
-  const GURL& url = GetTestURL("/many_anchors.html");
+IN_PROC_BROWSER_TEST_F(AnchorElementPreloaderBrowserTest, OneAnchorInaccurate) {
+  const GURL& url = GetTestURL("/one_anchor.html");
   EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
-  ukm::SourceId ukm_source_id = browser()
-                                    ->tab_strip_model()
-                                    ->GetActiveWebContents()
-                                    ->GetPrimaryMainFrame()
-                                    ->GetPageUkmSourceId();
+  SimulateMouseDownElementWithId("anchor1");
 
-  // First link with mousedown event should get preconnected.
-  SimulateMouseDownElementWithId("anchor1_origin1");
   WaitForPreresolveCountForURL(1);
   EXPECT_EQ(1, preresolve_count_);
   histogram_tester()->ExpectTotalCount(
       kPreloadingAnchorElementPreloaderPreloadingTriggered, 1);
+
   histogram_tester()->ExpectUniqueSample(
       kPreloadingAnchorElementPreloaderPreloadingTriggered,
       AnchorElementPreloaderType::kPreconnect, 1);
+
+  // Navigate away to an origin that was not preconnected. This should flush
+  // the Preloading UKM logs.
+  EXPECT_TRUE(ui_test_utils::NavigateToURL(
+      browser(), GURL(std::string(kOrigin2) + "foo")));
+  ukm::SourceId ukm_source_id = GetPrimaryMainFrame()->GetPageUkmSourceId();
   auto ukm_entries = test_ukm_recorder()->GetEntries(
-      ukm::builders::Preloading_AnchorInteraction::kEntryName,
-      {ukm::builders::Preloading_AnchorInteraction::
-           kAnchorElementPreloaderTypeName});
+      Preloading_Attempt::kEntryName,
+      content::test::kPreloadingAttemptUkmMetrics);
   EXPECT_EQ(ukm_entries.size(), 1u);
-  EXPECT_EQ(ukm_entries[0].source_id, ukm_source_id);
+  UkmEntry expected_entry = ukm_entry_builder().BuildEntry(
+      ukm_source_id, content::PreloadingEligibility::kEligible,
+      content::PreloadingHoldbackStatus::kAllowed,
+      content::PreloadingTriggeringOutcome::kTriggeredButOutcomeUnknown,
+      /*accurate=*/false);
+  EXPECT_EQ(ukm_entries[0], expected_entry)
+      << content::test::ActualVsExpectedUkmEntryToString(ukm_entries[0],
+                                                         expected_entry);
+}
+
+IN_PROC_BROWSER_TEST_F(AnchorElementPreloaderBrowserTest, Duplicates) {
+  const GURL& url = GetTestURL("/many_anchors.html");
+
+  EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
+
+  // First link with mousedown event should get preconnected.
+  SimulateMouseDownElementWithId("anchor1_origin1");
+  WaitForPreresolveCountForURL(1);
 
   // Second mousedown event to same origin: should not trigger a preconnect.
   SimulateMouseDownElementWithId("anchor2_origin1");
-  EXPECT_EQ(1, preresolve_count_);
-  histogram_tester()->ExpectTotalCount(
-      kPreloadingAnchorElementPreloaderPreloadingTriggered, 1);
-  ukm_entries = test_ukm_recorder()->GetEntries(
-      ukm::builders::Preloading_AnchorInteraction::kEntryName,
-      {ukm::builders::Preloading_AnchorInteraction::
-           kAnchorElementPreloaderTypeName});
-  EXPECT_EQ(ukm_entries.size(), 1u);
 
   // Third mousedown event to a different origin: should trigger a preconnect.
   SimulateMouseDownElementWithId("anchor1_origin2");
   WaitForPreresolveCountForURL(2);
-  EXPECT_EQ(2, preresolve_count_);
-  histogram_tester()->ExpectTotalCount(
-      kPreloadingAnchorElementPreloaderPreloadingTriggered, 2);
-  histogram_tester()->ExpectUniqueSample(
-      kPreloadingAnchorElementPreloaderPreloadingTriggered,
-      AnchorElementPreloaderType::kPreconnect, 2);
-  ukm_entries = test_ukm_recorder()->GetEntries(
-      ukm::builders::Preloading_AnchorInteraction::kEntryName,
-      {ukm::builders::Preloading_AnchorInteraction::
-           kAnchorElementPreloaderTypeName});
-  EXPECT_EQ(ukm_entries.size(), 2u);
-  EXPECT_EQ(ukm_entries[1].source_id, ukm_source_id);
+
+  // Navigate away to the first origin that was preconnected. This should flush
+  // the Preloading UKM logs.
+  EXPECT_TRUE(ui_test_utils::NavigateToURL(
+      browser(), GURL(std::string(kOrigin1) + "foo")));
+  ukm::SourceId ukm_source_id = GetPrimaryMainFrame()->GetPageUkmSourceId();
+  auto ukm_entries = test_ukm_recorder()->GetEntries(
+      Preloading_Attempt::kEntryName,
+      content::test::kPreloadingAttemptUkmMetrics);
+  EXPECT_EQ(ukm_entries.size(), 3u);
+  std::vector<UkmEntry> expected_entries = {
+      // Successful preconnect to first origin.
+      ukm_entry_builder().BuildEntry(
+          ukm_source_id, content::PreloadingEligibility::kEligible,
+          content::PreloadingHoldbackStatus::kAllowed,
+          content::PreloadingTriggeringOutcome::kTriggeredButOutcomeUnknown,
+          /*accurate=*/true),
+      // Duplicate preconnect to first origin.
+      ukm_entry_builder().BuildEntry(
+          ukm_source_id, content::PreloadingEligibility::kEligible,
+          content::PreloadingHoldbackStatus::kAllowed,
+          content::PreloadingTriggeringOutcome::kDuplicate,
+          /*accurate=*/true),
+      // Preconnect to first second origin.
+      ukm_entry_builder().BuildEntry(
+          ukm_source_id, content::PreloadingEligibility::kEligible,
+          content::PreloadingHoldbackStatus::kAllowed,
+          content::PreloadingTriggeringOutcome::kTriggeredButOutcomeUnknown,
+          /*accurate=*/false),
+  };
+  EXPECT_THAT(ukm_entries, testing::UnorderedElementsAreArray(expected_entries))
+      << content::test::ActualVsExpectedUkmEntriesToString(ukm_entries,
+                                                           expected_entries);
 }
 
 IN_PROC_BROWSER_TEST_F(AnchorElementPreloaderBrowserTest, InvalidHref) {
@@ -218,11 +276,11 @@
       kPreloadingAnchorElementPreloaderPreloadingTriggered,
       AnchorElementPreloaderType::kPreconnect, 0);
 
+  // Navigate away. This should flush the Preloading UKM logs.
+  EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
   auto ukm_entries = test_ukm_recorder()->GetEntries(
-      ukm::builders::Preloading_AnchorInteraction::kEntryName,
-      {ukm::builders::Preloading_AnchorInteraction::
-           kAnchorElementPreloaderTypeName});
-
+      Preloading_Attempt::kEntryName,
+      content::test::kPreloadingAttemptUkmMetrics);
   EXPECT_EQ(ukm_entries.size(), 0u);
 }
 
@@ -243,21 +301,6 @@
   histogram_tester()->ExpectUniqueSample(
       kPreloadingAnchorElementPreloaderPreloadingTriggered,
       AnchorElementPreloaderType::kPreconnect, 1);
-
-  ukm::SourceId ukm_source_id = browser()
-                                    ->tab_strip_model()
-                                    ->GetActiveWebContents()
-                                    ->GetPrimaryMainFrame()
-                                    ->GetPageUkmSourceId();
-
-  auto ukm_entries = test_ukm_recorder()->GetEntries(
-      ukm::builders::Preloading_AnchorInteraction::kEntryName,
-      {ukm::builders::Preloading_AnchorInteraction::
-           kAnchorElementPreloaderTypeName});
-
-  EXPECT_EQ(ukm_entries.size(), 1u);
-
-  EXPECT_EQ(ukm_entries[0].source_id, ukm_source_id);
 }
 
 IN_PROC_BROWSER_TEST_F(AnchorElementPreloaderBrowserTest,
@@ -276,12 +319,23 @@
       kPreloadingAnchorElementPreloaderPreloadingTriggered,
       AnchorElementPreloaderType::kPreconnect, 0);
 
+  // Navigate away to the same origin that was preconnected. This should flush
+  // the Preloading UKM logs.
+  EXPECT_TRUE(ui_test_utils::NavigateToURL(
+      browser(), GURL(std::string(kOrigin1) + "foo")));
+  ukm::SourceId ukm_source_id = GetPrimaryMainFrame()->GetPageUkmSourceId();
   auto ukm_entries = test_ukm_recorder()->GetEntries(
-      ukm::builders::Preloading_AnchorInteraction::kEntryName,
-      {ukm::builders::Preloading_AnchorInteraction::
-           kAnchorElementPreloaderTypeName});
-
-  EXPECT_EQ(ukm_entries.size(), 0u);
+      Preloading_Attempt::kEntryName,
+      content::test::kPreloadingAttemptUkmMetrics);
+  EXPECT_EQ(ukm_entries.size(), 1u);
+  UkmEntry expected_entry = ukm_entry_builder().BuildEntry(
+      ukm_source_id, content::PreloadingEligibility::kPreloadingDisabled,
+      content::PreloadingHoldbackStatus::kUnspecified,
+      content::PreloadingTriggeringOutcome::kUnspecified,
+      /*accurate=*/true);
+  EXPECT_EQ(ukm_entries[0], expected_entry)
+      << content::test::ActualVsExpectedUkmEntryToString(ukm_entries[0],
+                                                         expected_entry);
 }
 
 class AnchorElementPreloaderHoldbackBrowserTest
@@ -315,19 +369,22 @@
       kPreloadingAnchorElementPreloaderPreloadingTriggered,
       AnchorElementPreloaderType::kPreconnect, 1);
 
-  ukm::SourceId ukm_source_id = browser()
-                                    ->tab_strip_model()
-                                    ->GetActiveWebContents()
-                                    ->GetPrimaryMainFrame()
-                                    ->GetPageUkmSourceId();
-
+  // Navigate away to the same origin that was preconnected. This should flush
+  // the Preloading UKM logs.
+  EXPECT_TRUE(ui_test_utils::NavigateToURL(
+      browser(), GURL(std::string(kOrigin1) + "foo")));
+  ukm::SourceId ukm_source_id = GetPrimaryMainFrame()->GetPageUkmSourceId();
   auto ukm_entries = test_ukm_recorder()->GetEntries(
-      ukm::builders::Preloading_AnchorInteraction::kEntryName,
-      {ukm::builders::Preloading_AnchorInteraction::
-           kAnchorElementPreloaderTypeName});
-
+      Preloading_Attempt::kEntryName,
+      content::test::kPreloadingAttemptUkmMetrics);
   EXPECT_EQ(ukm_entries.size(), 1u);
-
-  EXPECT_EQ(ukm_entries[0].source_id, ukm_source_id);
+  UkmEntry expected_entry = ukm_entry_builder().BuildEntry(
+      ukm_source_id, content::PreloadingEligibility::kEligible,
+      content::PreloadingHoldbackStatus::kHoldback,
+      content::PreloadingTriggeringOutcome::kUnspecified,
+      /*accurate=*/true);
+  EXPECT_EQ(ukm_entries[0], expected_entry)
+      << content::test::ActualVsExpectedUkmEntryToString(ukm_entries[0],
+                                                         expected_entry);
 }
 }  // namespace
diff --git a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/PasswordCheckupClientHelper.java b/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/PasswordCheckupClientHelper.java
index f71c0e53..1bc9651 100644
--- a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/PasswordCheckupClientHelper.java
+++ b/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/PasswordCheckupClientHelper.java
@@ -35,53 +35,6 @@
      *         account will be used.
      * @param successCallback callback called with the intent if the retrieving was successful
      * @param failureCallback callback called if the retrieving failed with the encountered error.
-     *      The error should be a value from {@link CredentialManagerError}.
-     */
-    @Deprecated
-    default void getPasswordCheckupPendingIntent(@PasswordCheckReferrer int referrer,
-            Optional<String> accountName, Callback<PendingIntent> successCallback,
-            Callback<Integer> failureCallback) {}
-
-    /**
-     * Asynchronously runs Password Checkup and stores the result in PasswordSpecifics then saves it
-     * to the ChromeSync module.
-     *
-     * @param referrer the place that requested to start a check.
-     * @param accountName the account name that is syncing passwords. If no value was provided local
-     *         account will be used.
-     * @param successCallback callback called with Password Check started successful
-     * @param failureCallback callback called if encountered an error.
-     *      The error should be a value from {@link CredentialManagerError}.
-     */
-    @Deprecated
-    default void runPasswordCheckup(@PasswordCheckReferrer int referrer,
-            Optional<String> accountName, Callback<Void> successCallback,
-            Callback<Integer> failureCallback) {}
-
-    /**
-     * Asynchronously returns the number of breached credentials for the provided account.
-     *
-     * @param referrer the place that requested number of breached credentials.
-     * @param accountName the account name that is syncing passwords. If no value was provided local
-     *         account will be used.
-     * @param successCallback callback called with the number of breached passwords.
-     * @param failureCallback callback called if encountered an error.
-     *      The error should be a value from {@link CredentialManagerError}.
-     */
-    @Deprecated
-    default void getNumberOfBreachedCredentials(@PasswordCheckReferrer int referrer,
-            Optional<String> accountName, Callback<Integer> successCallback,
-            Callback<Integer> failureCallback) {}
-
-    /**
-     * Retrieves a pending intent that can be used to launch the Password Checkup UI in the
-     * credential manager. The intent is to either be used immediately or discarded.
-     *
-     * @param referrer the place that will launch the password checkup UI
-     * @param accountName the account name that is syncing passwords. If no value was provided local
-     *         account will be used.
-     * @param successCallback callback called with the intent if the retrieving was successful
-     * @param failureCallback callback called if the retrieving failed with the encountered error.
      */
     default void getPasswordCheckupIntent(@PasswordCheckReferrer int referrer,
             Optional<String> accountName, Callback<PendingIntent> successCallback,
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
index da7202e..8fef3101 100644
--- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc
+++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -775,7 +775,7 @@
     base::Value::Type::LIST },
   { key::kDefaultClipboardSetting,
     prefs::kManagedDefaultClipboardSetting,
-    base::Value::Type::LIST },
+    base::Value::Type::INTEGER },
   { key::kClipboardAllowedForUrls,
     prefs::kManagedClipboardAllowedForUrls,
     base::Value::Type::LIST },
diff --git a/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_network_context_client.cc b/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_network_context_client.cc
index 4db97f9..2441aafc 100644
--- a/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_network_context_client.cc
+++ b/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_network_context_client.cc
@@ -20,6 +20,7 @@
     int32_t process_id,
     bool async,
     const std::vector<base::FilePath>& file_paths,
+    const GURL& destination_url,
     OnFileUploadRequestedCallback callback) {
   std::move(callback).Run(net::ERR_ACCESS_DENIED, std::vector<base::File>());
 }
diff --git a/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_network_context_client.h b/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_network_context_client.h
index c6807e1..0e8aa9e 100644
--- a/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_network_context_client.h
+++ b/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_network_context_client.h
@@ -23,6 +23,7 @@
   void OnFileUploadRequested(int32_t process_id,
                              bool async,
                              const std::vector<base::FilePath>& file_paths,
+                             const GURL& destination_url,
                              OnFileUploadRequestedCallback callback) override;
   void OnCanSendReportingReports(
       const std::vector<url::Origin>& origins,
diff --git a/chrome/browser/resources/chromeos/arc_support/recommend_app_old_list_view.js b/chrome/browser/resources/chromeos/arc_support/recommend_app_old_list_view.js
index 1ac1463..3fbd0aaf 100644
--- a/chrome/browser/resources/chromeos/arc_support/recommend_app_old_list_view.js
+++ b/chrome/browser/resources/chromeos/arc_support/recommend_app_old_list_view.js
@@ -147,12 +147,4 @@
   sendNumberOfSelectedApps();
 }
 
-/**
- * Calculate height of the recommend-apps-container.
- * @return {number}
- */
-function getHeight() {
-  return document.querySelector('#recommend-apps-container').clientHeight;
-}
-
 window.addEventListener('message', onMessage_);
diff --git a/chrome/browser/resources/chromeos/login/screens/common/recommend_apps.html b/chrome/browser/resources/chromeos/login/screens/common/recommend_apps.html
index 3d377cb8..5c8a2c1 100644
--- a/chrome/browser/resources/chromeos/login/screens/common/recommend_apps.html
+++ b/chrome/browser/resources/chromeos/login/screens/common/recommend_apps.html
@@ -28,14 +28,23 @@
       }
 
       #app-list-view-container {
-        display: flex;
-        flex-direction: column;
+        display: grid;
+        gap: 16px 0;
+        grid-template-areas:
+            'select'
+            'list';
+        grid-template-rows: 20px 1fr;
+        height: 95%;
       }
 
       #selectAllButton {
         display: flex;
+        grid-area: select;
         justify-content: flex-end;
-        margin-bottom: 16px;
+      }
+
+      #appView {
+        grid-area: list;
       }
 
       #app-list-view-container-new {
@@ -60,8 +69,8 @@
       <template is="dom-if" if="[[!isOobeNewRecommendAppsEnabled_]]">
         <div id="app-list-view-container" slot="content">
           <div id="selectAllButton">
-            <a class="oobe-local-link focus-on-show" is="action-link"
-                on-click="onSelectAll_">
+            <a id="selectAllLink" class="oobe-local-link focus-on-show"
+                is="action-link" on-click="onSelectAll_">
               [[i18nDynamic(locale, 'recommendAppsSelectAll')]]
             </a>
           </div>
diff --git a/chrome/browser/resources/chromeos/login/screens/common/recommend_apps.js b/chrome/browser/resources/chromeos/login/screens/common/recommend_apps.js
index d6ea0dd..e2618ed 100644
--- a/chrome/browser/resources/chromeos/login/screens/common/recommend_apps.js
+++ b/chrome/browser/resources/chromeos/login/screens/common/recommend_apps.js
@@ -204,17 +204,12 @@
    * Handles event when contents in the webview is generated.
    */
   onFullyLoaded_() {
+    this.setUIStep(RecommendAppsUiState.LIST);
     if (this.isOobeNewRecommendAppsEnabled_) {
-      this.setUIStep(RecommendAppsUiState.LIST);
+      this.shadowRoot.querySelector('#appsList').focus();
       return;
     }
-    // Can't use this.$.appView here as the element is in a <dom-if>.
-    const appListView = this.shadowRoot.querySelector('#appView');
-    appListView.executeScript({code: 'getHeight();'}, function(result) {
-      appListView.setAttribute('style', 'height: ' + result + 'px');
-    });
-    this.setUIStep(RecommendAppsUiState.LIST);
-    this.$.installButton.focus();
+    this.shadowRoot.querySelector('#selectAllLink').focus();
   }
 
   /**
diff --git a/chrome/browser/resources/settings/autofill_page/password_view.html b/chrome/browser/resources/settings/autofill_page/password_view.html
index f8f1e22d..f7f9632 100644
--- a/chrome/browser/resources/settings/autofill_page/password_view.html
+++ b/chrome/browser/resources/settings/autofill_page/password_view.html
@@ -55,7 +55,8 @@
       $i18n{editPasswordUsernameLabel}
     </div>
     <div class="row-container">
-      <input id="usernameInput" value="[[credential.username]]" readonly>
+      <input id="usernameInput" value="[[credential.username]]" readonly
+          aria-label="$i18n{editPasswordUsernameLabel}">
       <cr-icon-button id="copyUsernameButton" class="icon-copy-content"
           slot="suffix" title="$i18n{copyUsername}"
           on-click="onCopyUsernameButtonClick_">
@@ -66,7 +67,8 @@
     </div>
     <div class="row-container">
       <input id="passwordInput" readonly value="[[getPassword_(password_)]]"
-          type="[[getPasswordInputType_(credential, isPasswordVisible_)]]">
+          type="[[getPasswordInputType_(credential, isPasswordVisible_)]]"
+          aria-label="$i18n{editPasswordPasswordLabel}">
       <template is="dom-if" if="[[!isFederated_(credential)]]" restamp>
         <cr-icon-button id="showPasswordButton" slot="suffix"
             class$="[[getIconClass_(isPasswordVisible_)]]"
diff --git a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_browser_proxy.js b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_browser_proxy.js
index 475ec9e..35489dc8 100644
--- a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_browser_proxy.js
+++ b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_browser_proxy.js
@@ -17,9 +17,9 @@
  * @typedef {{vm_name: string,
  *            container_name: string}}
  */
-export let ContainerId;
+export let GuestId;
 
-/** @type {!ContainerId} */ export const DEFAULT_CONTAINER_ID = {
+/** @type {!GuestId} */ export const DEFAULT_CONTAINER_ID = {
   vm_name: DEFAULT_CROSTINI_VM,
   container_name: DEFAULT_CROSTINI_CONTAINER,
 };
@@ -35,10 +35,12 @@
 };
 
 /**
+ * Note: key names are kept to match c++ style keys in prefs, they must stay in
+ * sync.
  * @typedef {{label: string,
  *            port_number: number,
  *            protocol_type: !CrostiniPortProtocol,
- *            container_id: !ContainerId}}
+ *            container_id: !GuestId}}
  */
 export let CrostiniPortSetting;
 
@@ -53,9 +55,11 @@
 export let CrostiniDiskInfo;
 
 /**
+ * Note: key names are kept to match c++ style keys in prefs, they must stay in
+ * sync.
  * @typedef {{port_number: number,
  *            protocol_type: !CrostiniPortProtocol,
- *            container_id: !ContainerId}}
+ *            container_id: !GuestId}}
  */
 export let CrostiniPortActiveSetting;
 
@@ -73,7 +77,7 @@
 
 /**
  * |ipv4| below is null if the container is not currently running.
- * @typedef {{id: !ContainerId,
+ * @typedef {{id: !GuestId,
  *            ipv4: ?string}}
  */
 export let ContainerInfo;
@@ -105,13 +109,13 @@
 
   /**
    * Export crostini container.
-   * @param {!ContainerId} containerId container id of container to export.
+   * @param {!GuestId} containerId container id of container to export.
    */
   exportCrostiniContainer(containerId) {}
 
   /**
    * Import crostini container.
-   * @param {!ContainerId} containerId container id of container to import.
+   * @param {!GuestId} containerId container id of container to import.
    */
   importCrostiniContainer(containerId) {}
 
@@ -170,7 +174,7 @@
   checkCrostiniMicSharingStatus(proposedValue) {}
 
   /**
-   * @param {!ContainerId} containerId id of container to add port forwarding.
+   * @param {!GuestId} containerId id of container to add port forwarding.
    * @param {number} portNumber Port number to start forwarding.
    * @param {!CrostiniPortProtocol} protocol Networking protocol to use.
    * @param {string} label Label for this port.
@@ -180,7 +184,7 @@
   addCrostiniPortForward(containerId, portNumber, protocol, label) {}
 
   /**
-   * @param {!ContainerId} containerId id from which to remove port forwarding.
+   * @param {!GuestId} containerId id from which to remove port forwarding.
    * @param {number} portNumber Port number to stop forwarding and remove.
    * @param {!CrostiniPortProtocol} protocol Networking protocol to use.
    * @return {!Promise<boolean>} Whether requested port was deallocated and
@@ -189,13 +193,13 @@
   removeCrostiniPortForward(containerId, portNumber, protocol) {}
 
   /**
-   * @param {!ContainerId} containerId id from which to remove all port
+   * @param {!GuestId} containerId id from which to remove all port
    *     forwarding.
    */
   removeAllCrostiniPortForwards(containerId) {}
 
   /**
-   * @param {!ContainerId} containerId id for which to activate port forward.
+   * @param {!GuestId} containerId id for which to activate port forward.
    * @param {number} portNumber Existing port number to activate.
    * @param {!CrostiniPortProtocol} protocol Networking protocol for existing
    * port rule to activate.
@@ -205,7 +209,7 @@
   activateCrostiniPortForward(containerId, portNumber, protocol) {}
 
   /**
-   * @param {!ContainerId} containerId id for which to deactivate port forward.
+   * @param {!GuestId} containerId id for which to deactivate port forward.
    * @param {number} portNumber Existing port number to activate.
    * @param {!CrostiniPortProtocol} protocol Networking protocol for existing
    * port rule to deactivate.
@@ -240,7 +244,7 @@
   getCrostiniMicSharingEnabled() {}
 
   /**
-   * @param {!ContainerId} containerId id of container to create.
+   * @param {!GuestId} containerId id of container to create.
    * @param {?URL} imageServer url of lxd container server from which to fetch
    * @param {?string} imageAlias name of image to fetch e.g. 'debian/bullseye'
    * @param {?string} ansiblePlaybook file location of an Ansible playbook to
@@ -249,7 +253,7 @@
   createContainer(containerId, imageServer, imageAlias, ansiblePlaybook) {}
 
   /**
-   * @param {!ContainerId} containerId id of container to delete.
+   * @param {!GuestId} containerId id of container to delete.
    */
   deleteContainer(containerId) {}
 
@@ -260,13 +264,13 @@
   requestContainerInfo() {}
 
   /**
-   * @param {!ContainerId} containerId container id to update.
+   * @param {!GuestId} containerId container id to update.
    * @param {!skia.mojom.SkColor} badge_color new badge color for the container.
    */
   setContainerBadgeColor(containerId, badge_color) {}
 
   /**
-   * @param {!ContainerId} containerId id of container to stop, recovering
+   * @param {!GuestId} containerId id of container to stop, recovering
    * CPU and other resources.
    */
   stopContainer(containerId) {}
diff --git a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_container_select.js b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_container_select.js
index aa36663..f498bb1 100644
--- a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_container_select.js
+++ b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_container_select.js
@@ -11,11 +11,11 @@
 
 import {html, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-import {ContainerId, ContainerInfo, DEFAULT_CONTAINER_ID, DEFAULT_CROSTINI_VM} from './crostini_browser_proxy.js';
+import {ContainerInfo, DEFAULT_CONTAINER_ID, DEFAULT_CROSTINI_VM, GuestId} from './crostini_browser_proxy.js';
 
 /**
- * @param {!ContainerId} first
- * @param {!ContainerId} second
+ * @param {!GuestId} first
+ * @param {!GuestId} second
  * @return boolean
  */
 export function equalContainerId(first, second) {
@@ -24,7 +24,7 @@
 }
 
 /**
- * @param {!ContainerId} id
+ * @param {!GuestId} id
  * @return string
  */
 export function containerLabel(id) {
@@ -48,7 +48,7 @@
   static get properties() {
     return {
       /**
-       * @type {!ContainerId}
+       * @type {!GuestId}
        */
       selectedContainerId: {
         type: Object,
@@ -81,7 +81,7 @@
   }
 
   /**
-   * @param {!ContainerId} id
+   * @param {!GuestId} id
    * @return string
    * @private
    */
diff --git a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_extra_containers.js b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_extra_containers.js
index d62f3bb..2b0e22c 100644
--- a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_extra_containers.js
+++ b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_extra_containers.js
@@ -21,8 +21,7 @@
 import {WebUIListenerBehavior, WebUIListenerBehaviorInterface} from '//resources/js/web_ui_listener_behavior.m.js';
 import {html, mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-
-import {ContainerId, ContainerInfo, CrostiniBrowserProxy, CrostiniBrowserProxyImpl, DEFAULT_CROSTINI_CONTAINER, DEFAULT_CROSTINI_VM} from './crostini_browser_proxy.js';
+import {ContainerInfo, CrostiniBrowserProxy, CrostiniBrowserProxyImpl, DEFAULT_CROSTINI_CONTAINER, DEFAULT_CROSTINI_VM, GuestId} from './crostini_browser_proxy.js';
 
 /**
  * @constructor
@@ -149,7 +148,7 @@
    */
   onContainerMenuClick_(event) {
     const id =
-        /** @type {ContainerId} */ (event.currentTarget['dataContainerId']);
+        /** @type {GuestId} */ (event.currentTarget['dataContainerId']);
     this.lastMenuContainerInfo_ = this.allContainers_.find(
         e => e.id.vm_name === id.vm_name &&
             e.id.container_name === id.container_name);
@@ -210,7 +209,7 @@
    */
   onContainerColorChange_(event) {
     const containerId =
-        /** @type {ContainerId} */ (event.currentTarget['dataContainerId']);
+        /** @type {GuestId} */ (event.currentTarget['dataContainerId']);
 
     CrostiniBrowserProxyImpl.getInstance().setContainerBadgeColor(
         containerId, hexColorToSkColor(event.target.value));
diff --git a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_extra_containers_create_dialog.js b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_extra_containers_create_dialog.js
index 0d8fbfb..e50d43b 100644
--- a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_extra_containers_create_dialog.js
+++ b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_extra_containers_create_dialog.js
@@ -17,7 +17,7 @@
 import {loadTimeData} from '//resources/js/load_time_data.m.js';
 import {html, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-import {ContainerId, ContainerInfo, CrostiniBrowserProxy, CrostiniBrowserProxyImpl, DEFAULT_CROSTINI_CONTAINER, DEFAULT_CROSTINI_VM} from './crostini_browser_proxy.js';
+import {ContainerInfo, CrostiniBrowserProxy, CrostiniBrowserProxyImpl, DEFAULT_CROSTINI_CONTAINER, DEFAULT_CROSTINI_VM, GuestId} from './crostini_browser_proxy.js';
 
 /** @polymer */
 class ExtraContainersCreateDialog extends PolymerElement {
diff --git a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_port_forwarding.js b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_port_forwarding.js
index 092743ea..183bd21e 100644
--- a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_port_forwarding.js
+++ b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_port_forwarding.js
@@ -28,7 +28,7 @@
 import {recordSettingChange} from '../metrics_recorder.js';
 import {PrefsBehavior, PrefsBehaviorInterface} from '../prefs_behavior.js';
 
-import {ContainerId, ContainerInfo, CrostiniBrowserProxy, CrostiniBrowserProxyImpl, CrostiniDiskInfo, CrostiniPortActiveSetting, CrostiniPortProtocol, CrostiniPortSetting, DEFAULT_CONTAINER_ID, DEFAULT_CROSTINI_CONTAINER, DEFAULT_CROSTINI_VM, MAX_VALID_PORT_NUMBER, MIN_VALID_PORT_NUMBER, PortState} from './crostini_browser_proxy.js';
+import {ContainerInfo, CrostiniBrowserProxy, CrostiniBrowserProxyImpl, CrostiniDiskInfo, CrostiniPortActiveSetting, CrostiniPortProtocol, CrostiniPortSetting, DEFAULT_CONTAINER_ID, DEFAULT_CROSTINI_CONTAINER, DEFAULT_CROSTINI_VM, GuestId, MAX_VALID_PORT_NUMBER, MIN_VALID_PORT_NUMBER, PortState} from './crostini_browser_proxy.js';
 import {containerLabel, equalContainerId} from './crostini_container_select.js';
 
 
@@ -212,7 +212,7 @@
   onShowRemoveSinglePortMenuClick_(event) {
     const dataSet = /** @type {{portNumber: string, protocolType: string}} */
         (event.currentTarget.dataset);
-    const id = /** @type {ContainerId} */
+    const id = /** @type {GuestId} */
         (event.currentTarget['dataContainerId']);
     this.lastMenuOpenedPort_ = {
       port_number: Number(dataSet.portNumber),
@@ -271,7 +271,7 @@
   onPortActivationChange_(event) {
     const dataSet = /** @type {{portNumber: string, protocolType: string}} */
         (event.currentTarget.dataset);
-    const id = /** @type {ContainerId} */
+    const id = /** @type {GuestId} */
         (event.currentTarget['dataContainerId']);
     const portNumber = Number(dataSet.portNumber);
     const protocolType = /** @type {!CrostiniPortProtocol} */
@@ -298,7 +298,7 @@
 
   /**
    * @param {!Array<!CrostiniPortSetting>} allPorts
-   * @param {!ContainerId} id
+   * @param {!GuestId} id
    * @return boolean
    * @private
    */
@@ -309,7 +309,7 @@
   }
 
   /**
-   * @param {!ContainerId} id
+   * @param {!GuestId} id
    * @return string
    * @private
    */
@@ -319,7 +319,7 @@
 
   /**
    * @param {!Array<!CrostiniPortSetting>} allPorts
-   * @param {!ContainerId} id
+   * @param {!GuestId} id
    * @return boolean
    * @private
    */
@@ -328,7 +328,7 @@
   }
 
   /**
-   * @param {!ContainerId} id
+   * @param {!GuestId} id
    * @return function
    * @private
    */
diff --git a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_port_forwarding_add_port_dialog.js b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_port_forwarding_add_port_dialog.js
index 316297f..7a3e377 100644
--- a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_port_forwarding_add_port_dialog.js
+++ b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_port_forwarding_add_port_dialog.js
@@ -18,7 +18,7 @@
 import {I18nBehavior} from '//resources/js/i18n_behavior.m.js';
 import {html, microTask, PolymerElement, TemplateInstanceBase, Templatizer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-import {ContainerId, ContainerInfo, CrostiniBrowserProxy, CrostiniBrowserProxyImpl, CrostiniPortActiveSetting, CrostiniPortProtocol, CrostiniPortSetting, DEFAULT_CONTAINER_ID, MAX_VALID_PORT_NUMBER, MIN_VALID_PORT_NUMBER, PortState} from './crostini_browser_proxy.js';
+import {ContainerInfo, CrostiniBrowserProxy, CrostiniBrowserProxyImpl, CrostiniPortActiveSetting, CrostiniPortProtocol, CrostiniPortSetting, DEFAULT_CONTAINER_ID, GuestId, MAX_VALID_PORT_NUMBER, MIN_VALID_PORT_NUMBER, PortState} from './crostini_browser_proxy.js';
 
 /** @polymer */
 class CrostiniPortForwardingAddPortDialog extends PolymerElement {
@@ -66,7 +66,7 @@
       },
 
       /**
-       * @type {!ContainerId}
+       * @type {!GuestId}
        */
       containerId_: {
         type: Object,
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index d588e46..b5a2aab 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -776,6 +776,8 @@
       "android/device_dialog/usb_chooser_dialog_android.cc",
       "android/device_dialog/usb_chooser_dialog_android.h",
       "android/external_protocol_dialog_android.cc",
+      "android/fast_checkout/fast_checkout_view_impl.cc",
+      "android/fast_checkout/fast_checkout_view_impl.h",
       "android/infobars/autofill_credit_card_filling_infobar.cc",
       "android/infobars/autofill_credit_card_filling_infobar.h",
       "android/infobars/autofill_offer_notification_infobar.cc",
@@ -874,6 +876,7 @@
       "fast_checkout/fast_checkout_controller.h",
       "fast_checkout/fast_checkout_controller_impl.cc",
       "fast_checkout/fast_checkout_controller_impl.h",
+      "fast_checkout/fast_checkout_view.h",
       "javascript_dialogs/javascript_tab_modal_dialog_manager_delegate_android.cc",
       "javascript_dialogs/javascript_tab_modal_dialog_manager_delegate_android.h",
       "page_info/about_this_site_message_delegate_android.cc",
diff --git a/chrome/browser/ui/android/fast_checkout/fast_checkout_view_impl.cc b/chrome/browser/ui/android/fast_checkout/fast_checkout_view_impl.cc
new file mode 100644
index 0000000..9e3b59c
--- /dev/null
+++ b/chrome/browser/ui/android/fast_checkout/fast_checkout_view_impl.cc
@@ -0,0 +1,40 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/android/fast_checkout/fast_checkout_view_impl.h"
+
+#include <memory>
+
+#include "base/android/jni_array.h"
+#include "base/android/jni_string.h"
+#include "chrome/browser/ui/fast_checkout/fast_checkout_controller.h"
+#include "components/autofill/core/browser/data_model/autofill_profile.h"
+#include "components/autofill/core/browser/data_model/credit_card.h"
+
+FastCheckoutViewImpl::FastCheckoutViewImpl(
+    base::WeakPtr<FastCheckoutController> controller)
+    : controller_(controller) {}
+
+FastCheckoutViewImpl::~FastCheckoutViewImpl() = default;
+
+void FastCheckoutViewImpl::OnOptionsSelected(
+    JNIEnv* env,
+    const base::android::JavaParamRef<jobject>& autofill_profile_java,
+    const base::android::JavaParamRef<jobject>& credit_card_java) {}
+
+void FastCheckoutViewImpl::OnDismiss(JNIEnv* env) {}
+
+void FastCheckoutViewImpl::Show(
+    base::span<const autofill::AutofillProfile> autofill_profiles,
+    base::span<const autofill::CreditCard> credit_cards) {}
+
+bool FastCheckoutViewImpl::RecreateJavaObject() {
+  return false;
+}
+
+// static
+std::unique_ptr<FastCheckoutView> FastCheckoutView::Create(
+    base::WeakPtr<FastCheckoutController> controller) {
+  return std::make_unique<FastCheckoutViewImpl>(controller);
+}
diff --git a/chrome/browser/ui/android/fast_checkout/fast_checkout_view_impl.h b/chrome/browser/ui/android/fast_checkout/fast_checkout_view_impl.h
new file mode 100644
index 0000000..455bd55
--- /dev/null
+++ b/chrome/browser/ui/android/fast_checkout/fast_checkout_view_impl.h
@@ -0,0 +1,47 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_ANDROID_FAST_CHECKOUT_FAST_CHECKOUT_VIEW_IMPL_H_
+#define CHROME_BROWSER_UI_ANDROID_FAST_CHECKOUT_FAST_CHECKOUT_VIEW_IMPL_H_
+
+#include "base/android/jni_android.h"
+#include "base/android/scoped_java_ref.h"
+#include "base/callback.h"
+#include "base/memory/raw_ptr.h"
+#include "chrome/browser/ui/fast_checkout/fast_checkout_view.h"
+
+class FastCheckoutController;
+
+// This class provides an Android implementation of the `FastCheckoutView`
+// interface. It communicates with its `FastCheckoutBridge` Java counterpart via
+// JNI.
+class FastCheckoutViewImpl : public FastCheckoutView {
+ public:
+  explicit FastCheckoutViewImpl(
+      base::WeakPtr<FastCheckoutController> controller);
+  ~FastCheckoutViewImpl() override;
+
+  void OnOptionsSelected(
+      JNIEnv* env,
+      const base::android::JavaParamRef<jobject>& autofill_profile_java,
+      const base::android::JavaParamRef<jobject>& credit_card_java);
+  void OnDismiss(JNIEnv* env);
+
+  // FastCheckoutView:
+  void Show(base::span<const autofill::AutofillProfile> autofill_profiles,
+            base::span<const autofill::CreditCard> credit_cards) override;
+
+ private:
+  // Returns either true if the java counterpart of this bridge is initialized
+  // successfully or false if the creation failed. This method  will recreate
+  // the java object whenever Show() is called.
+  bool RecreateJavaObject();
+
+  const base::WeakPtr<FastCheckoutController> controller_;
+
+  // The corresponding java object.
+  base::android::ScopedJavaGlobalRef<jobject> java_object_internal_;
+};
+
+#endif  // CHROME_BROWSER_UI_ANDROID_FAST_CHECKOUT_FAST_CHECKOUT_VIEW_IMPL_H_
diff --git a/chrome/browser/ui/fast_checkout/fast_checkout_controller_impl.h b/chrome/browser/ui/fast_checkout/fast_checkout_controller_impl.h
index b23aeb7..d3d8a07 100644
--- a/chrome/browser/ui/fast_checkout/fast_checkout_controller_impl.h
+++ b/chrome/browser/ui/fast_checkout/fast_checkout_controller_impl.h
@@ -8,14 +8,13 @@
 #include "chrome/browser/ui/fast_checkout/fast_checkout_controller.h"
 
 #include "base/memory/raw_ptr.h"
-#include "base/observer_list.h"
 #include "ui/gfx/native_widget_types.h"
 
 namespace content {
 class WebContents;
 }  // namespace content
 
-// The controller acts as C++ entry point to the fast checkout UI. It provides
+// The controller acts as C++ entry point to Fast Checkout UI. It provides
 // clients all necessary directives to communicate back and forth with the
 // bottom sheet.
 class FastCheckoutControllerImpl : public FastCheckoutController {
diff --git a/chrome/browser/ui/fast_checkout/fast_checkout_view.h b/chrome/browser/ui/fast_checkout/fast_checkout_view.h
new file mode 100644
index 0000000..de39f7a0
--- /dev/null
+++ b/chrome/browser/ui/fast_checkout/fast_checkout_view.h
@@ -0,0 +1,34 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_FAST_CHECKOUT_FAST_CHECKOUT_VIEW_H_
+#define CHROME_BROWSER_UI_FAST_CHECKOUT_FAST_CHECKOUT_VIEW_H_
+
+#include "base/containers/span.h"
+#include "chrome/browser/ui/fast_checkout/fast_checkout_controller.h"
+
+namespace autofill {
+class AutofillProfile;
+class CreditCard;
+}  // namespace autofill
+
+class FastCheckoutView {
+ public:
+  FastCheckoutView() = default;
+  FastCheckoutView(const FastCheckoutView&) = delete;
+  FastCheckoutView& operator=(const FastCheckoutView&) = delete;
+  virtual ~FastCheckoutView() = default;
+
+  // Show the sheet with provided options to the user. After user interaction,
+  // either `OnCredentialSelected` or `OnDismiss` gets invoked.
+  virtual void Show(
+      base::span<const autofill::AutofillProfile> autofill_profiles,
+      base::span<const autofill::CreditCard> credit_cards) = 0;
+
+  // Factory function for creating the view.
+  static std::unique_ptr<FastCheckoutView> Create(
+      base::WeakPtr<FastCheckoutController> controller);
+};
+
+#endif  // CHROME_BROWSER_UI_FAST_CHECKOUT_FAST_CHECKOUT_VIEW_H_
diff --git a/chrome/browser/ui/passwords/settings/password_manager_porter.cc b/chrome/browser/ui/passwords/settings/password_manager_porter.cc
index c2150a6..c475be7 100644
--- a/chrome/browser/ui/passwords/settings/password_manager_porter.cc
+++ b/chrome/browser/ui/passwords/settings/password_manager_porter.cc
@@ -126,11 +126,11 @@
     return false;
   }
 
-  // Set a new exporter for this request.
-  exporter_ = exporter_for_testing_
-                  ? std::move(exporter_for_testing_)
-                  : std::make_unique<password_manager::PasswordManagerExporter>(
-                        presenter_, on_export_progress_callback_);
+  if (!exporter_) {
+    // Set a new exporter for this request.
+    exporter_ = std::make_unique<password_manager::PasswordManagerExporter>(
+        presenter_, on_export_progress_callback_);
+  }
 
   // Start serialising while the user selects a file.
   exporter_->PreparePasswordsForExport();
@@ -153,7 +153,7 @@
 
 void PasswordManagerPorter::SetExporterForTesting(
     std::unique_ptr<password_manager::PasswordManagerExporter> exporter) {
-  exporter_for_testing_ = std::move(exporter);
+  exporter_ = std::move(exporter);
 }
 
 void PasswordManagerPorter::Import(content::WebContents* web_contents) {
diff --git a/chrome/browser/ui/passwords/settings/password_manager_porter.h b/chrome/browser/ui/passwords/settings/password_manager_porter.h
index 8519d8c..65366ed72 100644
--- a/chrome/browser/ui/passwords/settings/password_manager_porter.h
+++ b/chrome/browser/ui/passwords/settings/password_manager_porter.h
@@ -93,10 +93,6 @@
   // PasswordManagerExporter instance for each export.
   raw_ptr<password_manager::SavedPasswordsPresenter> presenter_;
   ProgressCallback on_export_progress_callback_;
-  // If |exporter_for_testing_| is set, the next export will make it the current
-  // exporter, instead of creating a new instance.
-  std::unique_ptr<password_manager::PasswordManagerExporter>
-      exporter_for_testing_;
 };
 
 #endif  // CHROME_BROWSER_UI_PASSWORDS_SETTINGS_PASSWORD_MANAGER_PORTER_H_
diff --git a/chrome/browser/ui/views/webid/account_selection_bubble_view.cc b/chrome/browser/ui/views/webid/account_selection_bubble_view.cc
index acc63a5..200459f 100644
--- a/chrome/browser/ui/views/webid/account_selection_bubble_view.cc
+++ b/chrome/browser/ui/views/webid/account_selection_bubble_view.cc
@@ -61,6 +61,12 @@
 constexpr int kVerticalSpacing = 8;
 // The height of the progress bar shown when showing "Verifying...".
 constexpr int kProgressBarHeight = 2;
+// The size of the space between the right boundary of the WebContents and the
+// right boundary of the bubble.
+constexpr int kRightMargin = 40;
+// The size of the space between the top boundary of the WebContents and the top
+// boundary of the bubble.
+constexpr int kTopMargin = 16;
 
 constexpr char kImageFetcherUmaClient[] = "FedCMAccountChooser";
 
@@ -254,8 +260,12 @@
     TabStripModel* tab_strip_model,
     base::OnceCallback<void(const content::IdentityRequestAccount&)>
         on_account_selected_callback)
-    : views::BubbleDialogDelegateView(anchor_view,
-                                      views::BubbleBorder::Arrow::TOP_RIGHT),
+    : views::BubbleDialogDelegateView(
+          anchor_view,
+          // Note that BOTTOM_RIGHT means the bubble's bottom and right are
+          // anchored to the `anchor_view`, which effectively means the bubble
+          // will be on top of the `anchor_view`, aligned on its right side.
+          views::BubbleBorder::Arrow::BOTTOM_RIGHT),
       idp_for_display_(base::UTF8ToUTF16(idp_for_display)),
       brand_text_color_(idp_metadata.brand_text_color),
       brand_background_color_(idp_metadata.brand_background_color),
@@ -299,6 +309,35 @@
 
 AccountSelectionBubbleView::~AccountSelectionBubbleView() = default;
 
+gfx::Rect AccountSelectionBubbleView::GetBubbleBounds() {
+  // The bubble initially looks like this relative to the contents_web_view:
+  //                        |--------|
+  //                        |        |
+  //                        | bubble |
+  //                        |        |
+  //       |-------------------------|
+  //       |                         |
+  //       | contents_web_view       |
+  //       |          ...            |
+  //       |-------------------------|
+  // Thus, we need to move the bubble to the left by kRightMargin and down by
+  // the size of the bubble plus kTopMargin in order to achieve what we want:
+  //       |-------------------------|
+  //       |               kTopMargin|
+  //       |         |--------|      |
+  //       |         |        |kRight|
+  //       |         | bubble |Margin|
+  //       |         |--------|      |
+  //       |                         |
+  //       | contents_web_view       |
+  //       |          ...            |
+  //       |-------------------------|
+  return views::BubbleDialogDelegateView::GetBubbleBounds() +
+         gfx::Vector2d(-kRightMargin,
+                       GetWidget()->client_view()->GetPreferredSize().height() +
+                           kTopMargin);
+}
+
 std::unique_ptr<views::View> AccountSelectionBubbleView::CreateHeaderView(
     const std::u16string& title,
     bool has_icon) {
diff --git a/chrome/browser/ui/views/webid/account_selection_bubble_view.h b/chrome/browser/ui/views/webid/account_selection_bubble_view.h
index 7b575fee..53707a6 100644
--- a/chrome/browser/ui/views/webid/account_selection_bubble_view.h
+++ b/chrome/browser/ui/views/webid/account_selection_bubble_view.h
@@ -42,6 +42,8 @@
   ~AccountSelectionBubbleView() override;
 
  private:
+  gfx::Rect GetBubbleBounds() override;
+
   // Returns a View containing the logo of the identity provider and the title
   // of the bubble, properly formatted.
   std::unique_ptr<views::View> CreateHeaderView(const std::u16string& title,
diff --git a/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop.cc b/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop.cc
index 0231d87..8e8ebc2 100644
--- a/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop.cc
+++ b/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop.cc
@@ -54,7 +54,7 @@
   Browser* browser =
       chrome::FindBrowserWithWebContents(delegate_->GetWebContents());
   BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser);
-  views::View* anchor_view = browser_view->top_container();
+  views::View* anchor_view = browser_view->contents_web_view();
   TabStripModel* tab_strip_model = browser_view->browser()->tab_strip_model();
   tab_strip_model->AddObserver(this);
   bubble_widget_ =
diff --git a/chrome/browser/ui/webui/settings/search_engines_handler.cc b/chrome/browser/ui/webui/settings/search_engines_handler.cc
index 7fc77aae..5e32859 100644
--- a/chrome/browser/ui/webui/settings/search_engines_handler.cc
+++ b/chrome/browser/ui/webui/settings/search_engines_handler.cc
@@ -103,8 +103,7 @@
   pref_change_registrar_.RemoveAll();
 }
 
-std::unique_ptr<base::DictionaryValue>
-SearchEnginesHandler::GetSearchEnginesList() {
+base::Value::Dict SearchEnginesHandler::GetSearchEnginesList() {
   // Find the default engine.
   const TemplateURL* default_engine =
       list_controller_.GetDefaultSearchProvider();
@@ -112,7 +111,7 @@
       list_controller_.table_model()->IndexOfTemplateURL(default_engine);
 
   // Build the first list (default search engines).
-  base::ListValue defaults;
+  base::Value::List defaults;
   int last_default_engine_index =
       list_controller_.table_model()->last_search_engine_index();
 
@@ -121,13 +120,12 @@
 
   for (int i = 0; i < last_default_engine_index; ++i) {
     // Third argument is false, as the engine is not from an extension.
-    defaults.Append(
-        base::Value(CreateDictionaryForEngine(i, i == default_index)));
+    defaults.Append(CreateDictionaryForEngine(i, i == default_index));
   }
 
   // Build the second list (active search engines). This will not have any
   // entries if the new Search Engines page is not enabled.
-  base::ListValue actives;
+  base::Value::List actives;
   int last_active_engine_index =
       list_controller_.table_model()->last_active_engine_index();
 
@@ -135,12 +133,11 @@
   for (int i = std::max(last_default_engine_index, 0);
        i < last_active_engine_index; ++i) {
     // Third argument is false, as the engine is not from an extension.
-    actives.Append(
-        base::Value(CreateDictionaryForEngine(i, i == default_index)));
+    actives.Append(CreateDictionaryForEngine(i, i == default_index));
   }
 
   // Build the second list (other search engines).
-  base::ListValue others;
+  base::Value::List others;
   int last_other_engine_index =
       list_controller_.table_model()->last_other_engine_index();
 
@@ -149,33 +146,32 @@
 
   for (int i = std::max(last_active_engine_index, 0);
        i < last_other_engine_index; ++i) {
-    others.Append(
-        base::Value(CreateDictionaryForEngine(i, i == default_index)));
+    others.Append(CreateDictionaryForEngine(i, i == default_index));
   }
 
   // Build the third list (omnibox extensions).
-  base::ListValue extensions;
+  base::Value::List extensions;
   int engine_count = list_controller_.table_model()->RowCount();
 
   // Sanity check for https://crbug.com/781703.
   CHECK_LE(last_other_engine_index, engine_count);
 
   for (int i = std::max(last_other_engine_index, 0); i < engine_count; ++i) {
-    extensions.Append(
-        base::Value(CreateDictionaryForEngine(i, i == default_index)));
+    extensions.Append(CreateDictionaryForEngine(i, i == default_index));
   }
 
-  auto search_engines_info = std::make_unique<base::DictionaryValue>();
-  search_engines_info->SetKey("defaults", std::move(defaults));
-  search_engines_info->SetKey("actives", std::move(actives));
-  search_engines_info->SetKey("others", std::move(others));
-  search_engines_info->SetKey("extensions", std::move(extensions));
+  base::Value::Dict search_engines_info;
+  search_engines_info.Set("defaults", std::move(defaults));
+  search_engines_info.Set("actives", std::move(actives));
+  search_engines_info.Set("others", std::move(others));
+  search_engines_info.Set("extensions", std::move(extensions));
   return search_engines_info;
 }
 
 void SearchEnginesHandler::OnModelChanged() {
   AllowJavascript();
-  FireWebUIListener("search-engines-changed", *GetSearchEnginesList());
+  FireWebUIListener("search-engines-changed",
+                    base::Value(GetSearchEnginesList()));
 }
 
 void SearchEnginesHandler::OnItemsChanged(int start, int length) {
@@ -257,7 +253,7 @@
   CHECK_EQ(1U, args.size());
   const base::Value& callback_id = args[0];
   AllowJavascript();
-  ResolveJavascriptCallback(callback_id, *GetSearchEnginesList());
+  ResolveJavascriptCallback(callback_id, base::Value(GetSearchEnginesList()));
 }
 
 void SearchEnginesHandler::HandleSetDefaultSearchEngine(
diff --git a/chrome/browser/ui/webui/settings/search_engines_handler.h b/chrome/browser/ui/webui/settings/search_engines_handler.h
index 8a061fc..10fe6c3 100644
--- a/chrome/browser/ui/webui/settings/search_engines_handler.h
+++ b/chrome/browser/ui/webui/settings/search_engines_handler.h
@@ -56,7 +56,7 @@
   // Retrieves all search engines and returns them to WebUI.
   void HandleGetSearchEnginesList(const base::Value::List& args);
 
-  std::unique_ptr<base::DictionaryValue> GetSearchEnginesList();
+  base::Value::Dict GetSearchEnginesList();
 
   // Removes the search engine at the given index. Called from WebUI.
   void HandleRemoveSearchEngine(const base::Value::List& args);
diff --git a/chrome/browser/uid/android/BUILD.gn b/chrome/browser/uid/android/BUILD.gn
index 04ce935..8e605f8 100644
--- a/chrome/browser/uid/android/BUILD.gn
+++ b/chrome/browser/uid/android/BUILD.gn
@@ -18,23 +18,27 @@
   ]
 }
 
-android_library("javatests") {
+robolectric_library("junit") {
   testonly = true
   sources = [
-    "javatests/src/org/chromium/chrome/browser/uid/SettingsSecureBasedIdentificationGeneratorTest.java",
-    "javatests/src/org/chromium/chrome/browser/uid/UniqueIdentificationGeneratorFactoryTest.java",
-    "javatests/src/org/chromium/chrome/browser/uid/UuidBasedUniqueIdentificationGeneratorTest.java",
+    "junit/src/org/chromium/chrome/browser/uid/SettingsSecureBasedIdentificationGeneratorTest.java",
+    "junit/src/org/chromium/chrome/browser/uid/UniqueIdentificationGeneratorFactoryTest.java",
+    "junit/src/org/chromium/chrome/browser/uid/UuidBasedUniqueIdentificationGeneratorTest.java",
   ]
   deps = [
     ":java",
     "//base:base_java_test_support",
+    "//base:base_junit_test_support",
     "//base/test:test_support_java",
     "//chrome/browser/preferences:java",
     "//chrome/browser/util:java",
     "//chrome/test/android:chrome_java_unit_test_support",
+    "//third_party/android_deps:robolectric_all_java",
     "//third_party/android_support_test_runner:runner_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
+    "//third_party/androidx:androidx_test_core_java",
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/junit:junit",
+    "//third_party/mockito:mockito_java",
   ]
 }
diff --git a/chrome/browser/uid/android/javatests/src/org/chromium/chrome/browser/uid/UuidBasedUniqueIdentificationGeneratorTest.java b/chrome/browser/uid/android/javatests/src/org/chromium/chrome/browser/uid/UuidBasedUniqueIdentificationGeneratorTest.java
deleted file mode 100644
index c4a4aa0..0000000
--- a/chrome/browser/uid/android/javatests/src/org/chromium/chrome/browser/uid/UuidBasedUniqueIdentificationGeneratorTest.java
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.uid;
-
-import android.support.test.InstrumentationRegistry;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import org.chromium.base.test.util.AdvancedMockContext;
-import org.chromium.base.test.util.Batch;
-import org.chromium.base.test.util.Feature;
-import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
-import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
-
-/** Unit tests for {@link UuidBasedUniqueIdentificationGenerator}. */
-@RunWith(ChromeJUnit4ClassRunner.class)
-@Batch(UniqueIdentificationGeneratorFactoryTest.IDENTITY_GENERATOR_BATCH_NAME)
-public class UuidBasedUniqueIdentificationGeneratorTest {
-    private static final String FLAG_UUID = "uuid";
-
-    private AdvancedMockContext mContext;
-
-    @Before
-    public void setUp() {
-        mContext = new AdvancedMockContext(InstrumentationRegistry.getTargetContext());
-        SharedPreferencesManager.getInstance().disableKeyCheckerForTesting();
-    }
-
-    @Test
-    @SmallTest
-    @Feature({"Sync"})
-    public void testGenerationAndRestorationOfUuid() {
-        String preferenceKey = "some_preference_key";
-        String expectedUniqueId = "myUuid";
-        TestGenerator generator = new TestGenerator(mContext, preferenceKey, expectedUniqueId);
-
-        // Get a unique ID and ensure it is as expected.
-        Assert.assertEquals(expectedUniqueId, generator.getUniqueId(null));
-
-        // Asking for a unique ID again, should not try to regenerate it.
-        mContext.clearFlag(FLAG_UUID);
-        Assert.assertEquals(expectedUniqueId, generator.getUniqueId(null));
-        Assert.assertFalse(mContext.isFlagSet(FLAG_UUID));
-
-        // After a restart, the TestGenerator should read the UUID from a preference, instead of
-        // asking for it.
-        mContext.clearFlag(FLAG_UUID);
-        generator = new TestGenerator(mContext, preferenceKey, null);
-        Assert.assertEquals(expectedUniqueId, generator.getUniqueId(null));
-        Assert.assertFalse(mContext.isFlagSet(FLAG_UUID));
-    }
-
-    @Test
-    @SmallTest
-    @Feature({"Sync"})
-    public void testTwoDifferentGeneratorsShouldUseDifferentPreferences() {
-        String preferenceKey1 = "some_preference_key";
-        String preferenceKey2 = "some_other_preference_key";
-        String expectedUniqueId1 = "myUuid";
-        String expectedUniqueId2 = "myOtherUuid";
-        TestGenerator generator1 = new TestGenerator(mContext, preferenceKey1, expectedUniqueId1);
-        TestGenerator generator2 = new TestGenerator(mContext, preferenceKey2, expectedUniqueId2);
-
-        // Get a unique ID and ensure it is as expected.
-        Assert.assertEquals(expectedUniqueId1, generator1.getUniqueId(null));
-        Assert.assertEquals(expectedUniqueId2, generator2.getUniqueId(null));
-
-        // Asking for a unique ID again, should not try to regenerate it.
-        mContext.clearFlag(FLAG_UUID);
-        Assert.assertEquals(expectedUniqueId1, generator1.getUniqueId(null));
-        Assert.assertFalse(mContext.isFlagSet(FLAG_UUID));
-        mContext.clearFlag(FLAG_UUID);
-        Assert.assertEquals(expectedUniqueId2, generator2.getUniqueId(null));
-        Assert.assertFalse(mContext.isFlagSet(FLAG_UUID));
-    }
-
-    private static class TestGenerator extends UuidBasedUniqueIdentificationGenerator {
-        private final AdvancedMockContext mContext;
-        private final String mUuid;
-
-        TestGenerator(AdvancedMockContext context, String preferenceKey, String uuid) {
-            super(context, preferenceKey);
-            mContext = context;
-            mUuid = uuid;
-        }
-
-        @Override
-        String getUUID() {
-            mContext.setFlag(FLAG_UUID);
-            return mUuid;
-        }
-    }
-}
diff --git a/chrome/browser/uid/android/javatests/src/org/chromium/chrome/browser/uid/SettingsSecureBasedIdentificationGeneratorTest.java b/chrome/browser/uid/android/junit/src/org/chromium/chrome/browser/uid/SettingsSecureBasedIdentificationGeneratorTest.java
similarity index 69%
rename from chrome/browser/uid/android/javatests/src/org/chromium/chrome/browser/uid/SettingsSecureBasedIdentificationGeneratorTest.java
rename to chrome/browser/uid/android/junit/src/org/chromium/chrome/browser/uid/SettingsSecureBasedIdentificationGeneratorTest.java
index ef2ca1a..81b605f 100644
--- a/chrome/browser/uid/android/javatests/src/org/chromium/chrome/browser/uid/SettingsSecureBasedIdentificationGeneratorTest.java
+++ b/chrome/browser/uid/android/junit/src/org/chromium/chrome/browser/uid/SettingsSecureBasedIdentificationGeneratorTest.java
@@ -4,23 +4,36 @@
 
 package org.chromium.chrome.browser.uid;
 
+import static org.mockito.Mockito.doReturn;
+
+import androidx.test.core.app.ApplicationProvider;
 import androidx.test.filters.SmallTest;
 
 import org.junit.Assert;
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.mockito.Spy;
 
-import org.chromium.base.test.util.AdvancedMockContext;
+import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.base.test.util.Batch;
 import org.chromium.base.test.util.Feature;
 import org.chromium.chrome.browser.util.HashUtil;
-import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 
 /** Unit tests for {@link SettingsSecureBasedIdentificationGenerator}. */
-@RunWith(ChromeJUnit4ClassRunner.class)
+@RunWith(BaseRobolectricTestRunner.class)
 @Batch(UniqueIdentificationGeneratorFactoryTest.IDENTITY_GENERATOR_BATCH_NAME)
 public class SettingsSecureBasedIdentificationGeneratorTest {
-    private static final String FLAG_ANDROID_ID = "android_id";
+    // Tell R8 this class is spied on and shouldn't be made final.
+    @Spy
+    SettingsSecureBasedIdentificationGenerator mGenerator;
+
+    @Before
+    public void setUp() {
+        mGenerator = Mockito.spy(new SettingsSecureBasedIdentificationGenerator(
+                ApplicationProvider.getApplicationContext()));
+    }
 
     @Test
     @SmallTest
@@ -62,28 +75,10 @@
     }
 
     private void runTest(String androidId, String salt, String expectedUniqueId) {
-        AdvancedMockContext context = new AdvancedMockContext();
-        TestGenerator generator = new TestGenerator(context, androidId);
+        doReturn(androidId).when(mGenerator).getAndroidId();
 
         // Get a unique ID and ensure it is as expected.
-        String result = generator.getUniqueId(salt);
+        String result = mGenerator.getUniqueId(salt);
         Assert.assertEquals(expectedUniqueId, result);
     }
-
-    private static class TestGenerator extends SettingsSecureBasedIdentificationGenerator {
-        private final AdvancedMockContext mContext;
-        private final String mAndroidId;
-
-        TestGenerator(AdvancedMockContext context, String androidId) {
-            super(context);
-            mContext = context;
-            mAndroidId = androidId;
-        }
-
-        @Override
-        String getAndroidId() {
-            mContext.setFlag(FLAG_ANDROID_ID);
-            return mAndroidId;
-        }
-    }
 }
diff --git a/chrome/browser/uid/android/javatests/src/org/chromium/chrome/browser/uid/UniqueIdentificationGeneratorFactoryTest.java b/chrome/browser/uid/android/junit/src/org/chromium/chrome/browser/uid/UniqueIdentificationGeneratorFactoryTest.java
similarity index 96%
rename from chrome/browser/uid/android/javatests/src/org/chromium/chrome/browser/uid/UniqueIdentificationGeneratorFactoryTest.java
rename to chrome/browser/uid/android/junit/src/org/chromium/chrome/browser/uid/UniqueIdentificationGeneratorFactoryTest.java
index b9c47bbb..84e5267 100644
--- a/chrome/browser/uid/android/javatests/src/org/chromium/chrome/browser/uid/UniqueIdentificationGeneratorFactoryTest.java
+++ b/chrome/browser/uid/android/junit/src/org/chromium/chrome/browser/uid/UniqueIdentificationGeneratorFactoryTest.java
@@ -11,12 +11,12 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.base.test.util.Batch;
 import org.chromium.base.test.util.Feature;
-import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 
 /** Unit tests for {@link UniqueIdentificationGeneratorFactory}. */
-@RunWith(ChromeJUnit4ClassRunner.class)
+@RunWith(BaseRobolectricTestRunner.class)
 @Batch(UniqueIdentificationGeneratorFactoryTest.IDENTITY_GENERATOR_BATCH_NAME)
 public class UniqueIdentificationGeneratorFactoryTest {
     public static final String IDENTITY_GENERATOR_BATCH_NAME = "identity_generator";
diff --git a/chrome/browser/uid/android/junit/src/org/chromium/chrome/browser/uid/UuidBasedUniqueIdentificationGeneratorTest.java b/chrome/browser/uid/android/junit/src/org/chromium/chrome/browser/uid/UuidBasedUniqueIdentificationGeneratorTest.java
new file mode 100644
index 0000000..d8b02ab1
--- /dev/null
+++ b/chrome/browser/uid/android/junit/src/org/chromium/chrome/browser/uid/UuidBasedUniqueIdentificationGeneratorTest.java
@@ -0,0 +1,100 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.uid;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.mockito.Spy;
+
+import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.base.test.util.Batch;
+import org.chromium.base.test.util.Feature;
+import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
+
+/** Unit tests for {@link UuidBasedUniqueIdentificationGenerator}. */
+@RunWith(BaseRobolectricTestRunner.class)
+@Batch(UniqueIdentificationGeneratorFactoryTest.IDENTITY_GENERATOR_BATCH_NAME)
+public class UuidBasedUniqueIdentificationGeneratorTest {
+    // Tell R8 this class is spied on and shouldn't be made final.
+    @Spy
+    UuidBasedUniqueIdentificationGenerator mGenerator;
+
+    @Before
+    public void setUp() {
+        SharedPreferencesManager.getInstance().disableKeyCheckerForTesting();
+    }
+
+    @Test
+    @SmallTest
+    @Feature({"Sync"})
+    public void testGenerationAndRestorationOfUuid() {
+        String preferenceKey = "some_preference_key";
+        String expectedUniqueId = "myUuid";
+        UuidBasedUniqueIdentificationGenerator generator =
+                createSpiedGenerator(preferenceKey, expectedUniqueId);
+
+        // Get a unique ID and ensure it is as expected.
+        Assert.assertEquals(expectedUniqueId, generator.getUniqueId(null));
+        verify(generator, times(1)).getUUID();
+
+        // Asking for a unique ID again, should not try to regenerate it.
+        Assert.assertEquals(expectedUniqueId, generator.getUniqueId(null));
+        verify(generator, times(1)).getUUID();
+
+        // After a restart, the TestGenerator should read the UUID from a preference, instead of
+        // asking for it.
+        generator = createSpiedGenerator(preferenceKey, null);
+        Assert.assertEquals(expectedUniqueId, generator.getUniqueId(null));
+        verify(generator, never()).getUUID();
+    }
+
+    @Test
+    @SmallTest
+    @Feature({"Sync"})
+    public void testTwoDifferentGeneratorsShouldUseDifferentPreferences() {
+        String preferenceKey1 = "some_preference_key";
+        String preferenceKey2 = "some_other_preference_key";
+        String expectedUniqueId1 = "myUuid";
+        String expectedUniqueId2 = "myOtherUuid";
+        UuidBasedUniqueIdentificationGenerator generator1 =
+                createSpiedGenerator(preferenceKey1, expectedUniqueId1);
+        UuidBasedUniqueIdentificationGenerator generator2 =
+                createSpiedGenerator(preferenceKey2, expectedUniqueId2);
+
+        // Get a unique ID and ensure it is as expected.
+        Assert.assertEquals(expectedUniqueId1, generator1.getUniqueId(null));
+        Assert.assertEquals(expectedUniqueId2, generator2.getUniqueId(null));
+        verify(generator1, times(1)).getUUID();
+        verify(generator2, times(1)).getUUID();
+
+        // Asking for a unique ID again, should not try to regenerate it.
+        Assert.assertEquals(expectedUniqueId1, generator1.getUniqueId(null));
+        Assert.assertEquals(expectedUniqueId2, generator2.getUniqueId(null));
+        verify(generator1, times(1)).getUUID();
+        verify(generator2, times(1)).getUUID();
+    }
+
+    private UuidBasedUniqueIdentificationGenerator createSpiedGenerator(
+            String preferenceKey, String uuidToReturn) {
+        Context context = ApplicationProvider.getApplicationContext();
+        UuidBasedUniqueIdentificationGenerator spiedGenerator =
+                Mockito.spy(new UuidBasedUniqueIdentificationGenerator(context, preferenceKey));
+        doReturn(uuidToReturn).when(spiedGenerator).getUUID();
+        return spiedGenerator;
+    }
+}
diff --git a/chrome/browser/web_applications/extensions/BUILD.gn b/chrome/browser/web_applications/extensions/BUILD.gn
index 47f26f1..059f606 100644
--- a/chrome/browser/web_applications/extensions/BUILD.gn
+++ b/chrome/browser/web_applications/extensions/BUILD.gn
@@ -52,7 +52,6 @@
     "bookmark_app_util_unittest.cc",
     "externally_managed_app_install_task_unittest.cc",
     "web_app_policy_manager_unittest.cc",
-    "web_app_provider_unittest.cc",
   ]
 
   deps = [
diff --git a/chrome/browser/web_applications/extensions/web_app_provider_unittest.cc b/chrome/browser/web_applications/extensions/web_app_provider_unittest.cc
deleted file mode 100644
index 39dfb50..0000000
--- a/chrome/browser/web_applications/extensions/web_app_provider_unittest.cc
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/web_applications/web_app_provider.h"
-
-#include "base/memory/raw_ptr.h"
-#include "build/chromeos_buildflags.h"
-#include "chrome/browser/web_applications/web_app_registrar.h"
-#include "chrome/browser/web_applications/web_app_utils.h"
-#include "chrome/test/base/chrome_render_view_host_test_harness.h"
-#include "chrome/test/base/testing_profile.h"
-
-namespace web_app {
-
-class WebAppProviderUnitTest : public ChromeRenderViewHostTestHarness {
- public:
-  WebAppProviderUnitTest() = default;
-  WebAppProviderUnitTest(const WebAppProviderUnitTest&) = delete;
-  WebAppProviderUnitTest& operator=(const WebAppProviderUnitTest&) = delete;
-  ~WebAppProviderUnitTest() override = default;
-
-  void SetUp() override {
-    ChromeRenderViewHostTestHarness::SetUp();
-
-#if BUILDFLAG(IS_CHROMEOS_LACROS)
-    SkipMainProfileCheckForTesting();
-#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
-
-    provider_ = WebAppProvider::GetForLocalAppsUnchecked(profile());
-  }
-
-  WebAppProvider* provider() { return provider_; }
-
- private:
-  raw_ptr<WebAppProvider> provider_;
-};
-
-TEST_F(WebAppProviderUnitTest, Registrar) {
-  WebAppRegistrar& registrar = provider()->registrar();
-  EXPECT_FALSE(registrar.IsInstalled("unknown"));
-}
-
-}  // namespace web_app
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index 318872c..06566e0 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-main-1655423930-5f8c09f38f66207c53cf29b21ff71829ddba9095.profdata
+chrome-linux-main-1655466571-3c36953a1de324b0904d8f22857f74dda49d16c4.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt
index 7341b0d4..305ddbc 100644
--- a/chrome/build/mac-arm.pgo.txt
+++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@
-chrome-mac-arm-main-1655423930-2a8afe46877fd4cd7e11686f4c2df813f51e2b56.profdata
+chrome-mac-arm-main-1655445530-0f845484c9b2b14413a1d924e20fdc4fc7a4ea3c.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index bfbbe3a..caac24a6 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-main-1655423930-d16f73044832132c981be18f4e873e2248299826.profdata
+chrome-mac-main-1655466571-7d65938c5b97e550699896fed8a00e761848f383.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index ece5041..cc15437 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1655434727-268c22535f8e13d194691e2bd3f449bcd80da004.profdata
+chrome-win32-main-1655466571-9ee46619307dfb2a7a5220b5cda12d613db51bbb.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 36b0f15..414956f 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1655434727-fba457c15c825ed11b6a16513d4cb89363b256e8.profdata
+chrome-win64-main-1655466571-e25340d25f6143180c76ee686afd081746c67b6f.profdata
diff --git a/chrome/renderer/autofill/form_autofill_browsertest.cc b/chrome/renderer/autofill/form_autofill_browsertest.cc
index 8d678a96..582f853 100644
--- a/chrome/renderer/autofill/form_autofill_browsertest.cc
+++ b/chrome/renderer/autofill/form_autofill_browsertest.cc
@@ -50,7 +50,8 @@
 using blink::WebString;
 using blink::WebVector;
 
-namespace autofill::form_util {
+namespace autofill {
+namespace form_util {
 
 namespace {
 
@@ -2526,7 +2527,6 @@
   expected.autocomplete_attribute = "off";
   expected.should_autocomplete = false;
   expected.is_focusable = true;
-  expected.is_visible = true;
   expected.text_direction = base::i18n::LEFT_TO_RIGHT;
 
   expected.value = u"CA";
@@ -5658,4 +5658,5 @@
   EXPECT_EQ(u"aria description", fields[2].aria_description);
 }
 
-}  // namespace autofill::form_util
+}  // namespace form_util
+}  // namespace autofill
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index dd28cb2..db95539a 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -7308,6 +7308,7 @@
       "../browser/chromeos/policy/dlp/dlp_rules_manager_impl_unittest.cc",
       "../browser/chromeos/policy/dlp/dlp_rules_manager_test_utils.cc",
       "../browser/chromeos/policy/dlp/dlp_rules_manager_test_utils.h",
+      "../browser/chromeos/policy/dlp/dlp_scoped_file_access_delegate_unittest.cc",
       "../browser/chromeos/policy/dlp/mock_dlp_content_manager.cc",
       "../browser/chromeos/policy/dlp/mock_dlp_content_manager.h",
       "../browser/chromeos/policy/dlp/mock_dlp_content_observer.cc",
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json
index 33f823c..76a1f5f 100644
--- a/chrome/test/data/policy/policy_test_cases.json
+++ b/chrome/test/data/policy/policy_test_cases.json
@@ -5345,6 +5345,13 @@
     ],
     "policy_pref_mapping_tests": [
       {
+        "prefs": {
+          "profile.managed_default_content_settings.clipboard": {
+            "default_value": 0
+          }
+        }
+      },
+      {
         "policies": {
           "DefaultClipboardSetting": 2
         },
@@ -11686,7 +11693,7 @@
         "policies": {},
         "prefs": {
           "power.adaptive_charging_enabled": {
-            "default_value": false
+            "default_value": true
           }
         }
       },
diff --git a/chrome/test/data/webrtc/peerconnection_getstats.js b/chrome/test/data/webrtc/peerconnection_getstats.js
index b47962d6..996ae39b 100644
--- a/chrome/test/data/webrtc/peerconnection_getstats.js
+++ b/chrome/test/data/webrtc/peerconnection_getstats.js
@@ -97,13 +97,14 @@
   });
 
 /*
- * RTCInboundRTPStreamStats
+ * RTCInboundRtpStreamStats
  * https://w3c.github.io/webrtc-stats/#inboundrtpstats-dict*
  * @private
  */
 let kRTCInboundRtpStreamStats = new RTCStats(kRTCReceivedRtpStreamStats, {
   trackId: 'string',
-  receiverId: 'string',
+  trackIdentifier: 'string',
+  mid: 'string',
   remoteId: 'string',
   framesDecoded: 'number',
   keyFramesDecoded: 'number',
@@ -183,8 +184,8 @@
 let kRTCOutboundRtpStreamStats = new RTCStats(kRTCSentRtpStreamStats, {
   trackId: 'string',
   mediaSourceId: 'string',
-  senderId: 'string',
   remoteId: 'string',
+  mid: 'string',
   retransmittedPacketsSent: 'number',
   retransmittedBytesSent: 'number',
   headerBytesSent: 'number',
@@ -312,134 +313,45 @@
 
 /*
  * RTCMediaStreamStats
- * https://w3c.github.io/webrtc-stats/#msstats-dict*
+ * https://w3c.github.io/webrtc-stats/#obsolete-rtcmediastreamstats-members
  * @private
  */
 let kRTCMediaStreamStats = new RTCStats(null, {
   streamIdentifier: 'string',
   trackIds: 'sequence_string',
 });
-addRTCStatsToAllowlist(Presence.MANDATORY, 'stream', kRTCMediaStreamStats);
+// It's OPTIONAL because this dictionary has become obsolete.
+addRTCStatsToAllowlist(Presence.OPTIONAL, 'stream', kRTCMediaStreamStats);
 
 /**
- * RTCMediaHandlerStats
- * https://w3c.github.io/webrtc-stats/#mststats-dict*
+ * RTCMediaStreamTrackStats
+ * https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamtrackstats
  * @private
  */
-let kRTCMediaHandlerStats = new RTCStats(null, {
+let kRTCMediaStreamTrackStats = new RTCStats('track', {
   trackIdentifier: 'string',
   remoteSource: 'boolean',
   ended: 'boolean',
   kind: 'string',
   priority: 'string',
   detached: 'boolean',  // Obsolete, detached stats should fire "onstatsended".
-});
-
-/*
- * RTCVideoHandlerStats
- * https://w3c.github.io/webrtc-stats/#dom-rtcvideohandlerstats
- * @private
- */
-let kRTCVideoHandlerStats = new RTCStats(kRTCMediaHandlerStats, {
   frameWidth: 'number',
   frameHeight: 'number',
-});
-
-/*
- * RTCVideoSenderStats
- * https://w3c.github.io/webrtc-stats/#dom-rtcvideosenderstats
- * @private
- */
-let kRTCVideoSenderStats = new RTCStats(kRTCVideoHandlerStats, {
   mediaSourceId: 'string',
   framesCaptured: 'number',
   framesSent: 'number',
   hugeFramesSent: 'number',
-});
-// TODO(hbos): When sender is implemented, make presence MANDATORY.
-addRTCStatsToAllowlist(Presence.OPTIONAL, 'sender', kRTCVideoSenderStats);
-
-/*
- * RTCSenderVideoTrackAttachmentStats
- * https://w3c.github.io/webrtc-stats/#dom-rtcsendervideotrackattachmentstats
- * @private
- */
-let kRTCSenderVideoTrackAttachmentStats = new RTCStats(kRTCVideoSenderStats, {
-});
-addRTCStatsToAllowlist(
-    Presence.MANDATORY, 'track', kRTCSenderVideoTrackAttachmentStats);
-
-/*
- * RTCVideoReceiverStats
- * https://w3c.github.io/webrtc-stats/#dom-rtcvideoreceiverstats
- * @private
- */
-let kRTCVideoReceiverStats = new RTCStats(kRTCVideoHandlerStats, {
   estimatedPlayoutTimestamp: 'number',
   jitterBufferDelay: 'number',
   jitterBufferEmittedCount: 'number',
   framesReceived: 'number',
   framesDecoded: 'number',
   framesDropped: 'number',
-});
-// TODO(hbos): When receiver is implemented, make presence MANDATORY.
-addRTCStatsToAllowlist(
-    Presence.OPTIONAL, 'receiver', kRTCVideoReceiverStats);
-
-/*
- * RTCReceiverVideoTrackAttachmentStats
- * https://github.com/w3c/webrtc-stats/issues/424
- * @private
- */
-let kRTCReceiverVideoTrackAttachmentStats =
-    new RTCStats(kRTCVideoReceiverStats, {
-});
-addRTCStatsToAllowlist(
-    Presence.MANDATORY, 'track', kRTCReceiverVideoTrackAttachmentStats);
-
-/*
- * RTCAudioHandlerStats
- * https://w3c.github.io/webrtc-stats/#dom-rtcaudiohandlerstats
- * @private
- */
-let kRTCAudioHandlerStats = new RTCStats(kRTCMediaHandlerStats, {
   audioLevel: 'number',
   totalAudioEnergy: 'number',
   totalSamplesDuration: 'number',
-});
-
-/*
- * RTCAudioSenderStats
- * https://w3c.github.io/webrtc-stats/#dom-rtcaudiosenderstats
- * @private
- */
-let kRTCAudioSenderStats = new RTCStats(kRTCAudioHandlerStats, {
-  mediaSourceId: 'string',
   echoReturnLoss: 'number',
   echoReturnLossEnhancement: 'number',
-});
-// TODO(hbos): When sender is implemented, make presence MANDATORY.
-addRTCStatsToAllowlist(Presence.OPTIONAL, 'sender', kRTCAudioSenderStats);
-
-/*
- * RTCSenderAudioTrackAttachmentStats
- * https://w3c.github.io/webrtc-stats/#dom-rtcsenderaudiotrackattachmentstats
- * @private
- */
-let kRTCSenderAudioTrackAttachmentStats = new RTCStats(kRTCAudioSenderStats, {
-});
-addRTCStatsToAllowlist(
-    Presence.MANDATORY, 'track', kRTCSenderAudioTrackAttachmentStats);
-
-/*
- * RTCAudioReceiverStats
- * https://w3c.github.io/webrtc-stats/#dom-rtcaudioreceiverstats
- * @private
- */
-let kRTCAudioReceiverStats = new RTCStats(kRTCAudioHandlerStats, {
-  estimatedPlayoutTimestamp: 'number',
-  jitterBufferDelay: 'number',
-  jitterBufferEmittedCount: 'number',
   totalSamplesReceived: 'number',
   concealedSamples: 'number',
   silentConcealedSamples: 'number',
@@ -447,20 +359,8 @@
   insertedSamplesForDeceleration: 'number',
   removedSamplesForAcceleration: 'number',
 });
-// TODO(hbos): When receiver is implemented, make presence MANDATORY.
-addRTCStatsToAllowlist(
-    Presence.OPTIONAL, 'receiver', kRTCAudioReceiverStats);
-
-/*
- * RTCReceiverAudioTrackAttachmentStats
- * https://github.com/w3c/webrtc-stats/issues/424
- * @private
- */
-let kRTCReceiverAudioTrackAttachmentStats =
-    new RTCStats(kRTCAudioReceiverStats, {
-});
-addRTCStatsToAllowlist(
-    Presence.MANDATORY, 'track', kRTCReceiverAudioTrackAttachmentStats);
+// It's OPTIONAL because this dictionary has become obsolete.
+addRTCStatsToAllowlist(Presence.OPTIONAL, 'track', kRTCMediaStreamTrackStats);
 
 /*
  * RTCDataChannelStats
diff --git a/chromeos/crosapi/mojom/app_service_types.mojom b/chromeos/crosapi/mojom/app_service_types.mojom
index 8f9924e..9020f91 100644
--- a/chromeos/crosapi/mojom/app_service_types.mojom
+++ b/chromeos/crosapi/mojom/app_service_types.mojom
@@ -425,6 +425,8 @@
   [MinVersion=14]LaunchContainer container@3;
   // How the tab opened in a window if app is opened in tab.
   [MinVersion=14]WindowOpenDisposition disposition@4;
+  // An id that indicates which display the app should be launched in.
+  [MinVersion=15]int64 display_id@5;
 };
 
 [Stable]
diff --git a/chromeos/dbus/dlp/dlp_client.cc b/chromeos/dbus/dlp/dlp_client.cc
index a8c32fe0..774f8df 100644
--- a/chromeos/dbus/dlp/dlp_client.cc
+++ b/chromeos/dbus/dlp/dlp_client.cc
@@ -138,6 +138,28 @@
                        weak_factory_.GetWeakPtr(), std::move(callback)));
   }
 
+  void RequestFileAccess(const dlp::RequestFileAccessRequest request,
+                         RequestFileAccessCallback callback) override {
+    dbus::MethodCall method_call(dlp::kDlpInterface,
+                                 dlp::kRequestFileAccessMethod);
+    dbus::MessageWriter writer(&method_call);
+
+    if (!writer.AppendProtoAsArrayOfBytes(request)) {
+      dlp::RequestFileAccessResponse response;
+      response.set_error_message(base::StrCat(
+          {"Failure to call d-bus method: ", dlp::kRequestFileAccessMethod}));
+      base::ThreadTaskRunnerHandle::Get()->PostTask(
+          FROM_HERE,
+          base::BindOnce(std::move(callback), response, base::ScopedFD()));
+      return;
+    }
+
+    proxy_->CallMethod(
+        &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
+        base::BindOnce(&DlpClientImpl::HandleRequestFileAccessResponse,
+                       weak_factory_.GetWeakPtr(), std::move(callback)));
+  }
+
   bool IsAlive() const override { return is_alive_; }
 
  private:
@@ -186,6 +208,30 @@
     std::move(callback).Run(response_proto);
   }
 
+  void HandleRequestFileAccessResponse(RequestFileAccessCallback callback,
+                                       dbus::Response* response) {
+    dlp::RequestFileAccessResponse response_proto;
+    base::ScopedFD fd;
+    if (!response) {
+      response_proto.set_error_message(kDbusCallFailure);
+      std::move(callback).Run(response_proto, std::move(fd));
+      return;
+    }
+
+    dbus::MessageReader reader(response);
+    if (!reader.PopArrayOfBytesAsProto(&response_proto)) {
+      response_proto.set_error_message(kProtoMessageParsingFailure);
+      std::move(callback).Run(response_proto, std::move(fd));
+      return;
+    }
+    if (!reader.PopFileDescriptor(&fd)) {
+      response_proto.set_error_message(kProtoMessageParsingFailure);
+      std::move(callback).Run(response_proto, std::move(fd));
+      return;
+    }
+    std::move(callback).Run(response_proto, std::move(fd));
+  }
+
   // D-Bus proxy for the Dlp daemon, not owned.
   dbus::ObjectProxy* proxy_ = nullptr;
 
diff --git a/chromeos/dbus/dlp/dlp_client.h b/chromeos/dbus/dlp/dlp_client.h
index 83672b34..995c0961 100644
--- a/chromeos/dbus/dlp/dlp_client.h
+++ b/chromeos/dbus/dlp/dlp_client.h
@@ -9,6 +9,7 @@
 
 #include "base/callback.h"
 #include "base/component_export.h"
+#include "base/files/scoped_file.h"
 #include "chromeos/dbus/dlp/dlp_service.pb.h"
 #include "dbus/object_proxy.h"
 
@@ -31,6 +32,9 @@
       base::OnceCallback<void(const dlp::GetFilesSourcesResponse response)>;
   using CheckFilesTransferCallback =
       base::OnceCallback<void(const dlp::CheckFilesTransferResponse response)>;
+  using RequestFileAccessCallback =
+      base::OnceCallback<void(const dlp::RequestFileAccessResponse response,
+                              base::ScopedFD fd)>;
 
   // Interface with testing functionality. Accessed through GetTestInterface(),
   // only implemented in the fake implementation.
@@ -46,6 +50,9 @@
     virtual void SetCheckFilesTransferResponse(
         dlp::CheckFilesTransferResponse response) = 0;
 
+    // Sets response for RequestFileAccess call.
+    virtual void SetFileAccessAllowed(bool allowed) = 0;
+
    protected:
     virtual ~TestInterface() {}
   };
@@ -77,6 +84,8 @@
   virtual void CheckFilesTransfer(
       const dlp::CheckFilesTransferRequest request,
       CheckFilesTransferCallback callback) const = 0;
+  virtual void RequestFileAccess(const dlp::RequestFileAccessRequest request,
+                                 RequestFileAccessCallback callback) = 0;
 
   virtual bool IsAlive() const = 0;
 
diff --git a/chromeos/dbus/dlp/fake_dlp_client.cc b/chromeos/dbus/dlp/fake_dlp_client.cc
index 4441427..28beb43 100644
--- a/chromeos/dbus/dlp/fake_dlp_client.cc
+++ b/chromeos/dbus/dlp/fake_dlp_client.cc
@@ -72,6 +72,14 @@
   std::move(callback).Run(response);
 }
 
+void FakeDlpClient::RequestFileAccess(
+    const dlp::RequestFileAccessRequest request,
+    RequestFileAccessCallback callback) {
+  dlp::RequestFileAccessResponse response;
+  response.set_allowed(file_access_allowed_);
+  std::move(callback).Run(response, base::ScopedFD());
+}
+
 bool FakeDlpClient::IsAlive() const {
   return true;
 }
@@ -93,4 +101,8 @@
   check_files_transfer_response_ = response;
 }
 
+void FakeDlpClient::SetFileAccessAllowed(bool allowed) {
+  file_access_allowed_ = allowed;
+}
+
 }  // namespace chromeos
diff --git a/chromeos/dbus/dlp/fake_dlp_client.h b/chromeos/dbus/dlp/fake_dlp_client.h
index a620e37..c34ce24 100644
--- a/chromeos/dbus/dlp/fake_dlp_client.h
+++ b/chromeos/dbus/dlp/fake_dlp_client.h
@@ -15,9 +15,8 @@
 
 namespace chromeos {
 
-class COMPONENT_EXPORT(CHROMEOS_DBUS) FakeDlpClient
-    : public DlpClient,
-      public DlpClient::TestInterface {
+class COMPONENT_EXPORT(DLP) FakeDlpClient : public DlpClient,
+                                            public DlpClient::TestInterface {
  public:
   FakeDlpClient();
   FakeDlpClient(const FakeDlpClient&) = delete;
@@ -33,6 +32,8 @@
                        GetFilesSourcesCallback callback) const override;
   void CheckFilesTransfer(const dlp::CheckFilesTransferRequest request,
                           CheckFilesTransferCallback callback) const override;
+  void RequestFileAccess(const dlp::RequestFileAccessRequest request,
+                         RequestFileAccessCallback callback) override;
   bool IsAlive() const override;
   DlpClient::TestInterface* GetTestInterface() override;
 
@@ -41,9 +42,11 @@
   void SetFakeSource(const std::string& fake_source) override;
   void SetCheckFilesTransferResponse(
       dlp::CheckFilesTransferResponse response) override;
+  void SetFileAccessAllowed(bool allowed) override;
 
  private:
   int set_dlp_files_policy_count_ = 0;
+  bool file_access_allowed_ = true;
   base::flat_map<ino_t, std::string> files_database_;
   absl::optional<std::string> fake_source_;
   absl::optional<dlp::CheckFilesTransferResponse>
diff --git a/chromeos/profiles/atom.afdo.newest.txt b/chromeos/profiles/atom.afdo.newest.txt
index 9c91c358..eb6d602 100644
--- a/chromeos/profiles/atom.afdo.newest.txt
+++ b/chromeos/profiles/atom.afdo.newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-atom-104-5060.22-1654508750-benchmark-104.0.5112.9-r1-redacted.afdo.xz
+chromeos-chrome-amd64-atom-104-5060.22-1654508750-benchmark-104.0.5112.12-r1-redacted.afdo.xz
diff --git a/chromeos/profiles/bigcore.afdo.newest.txt b/chromeos/profiles/bigcore.afdo.newest.txt
index a8fcda5..407e4d004 100644
--- a/chromeos/profiles/bigcore.afdo.newest.txt
+++ b/chromeos/profiles/bigcore.afdo.newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-bigcore-104-5060.37-1655113479-benchmark-104.0.5112.9-r1-redacted.afdo.xz
+chromeos-chrome-amd64-bigcore-104-5060.37-1655113479-benchmark-104.0.5112.12-r1-redacted.afdo.xz
diff --git a/chromeos/tast_control.gni b/chromeos/tast_control.gni
index f8d86d6..8dc82ec 100644
--- a/chromeos/tast_control.gni
+++ b/chromeos/tast_control.gni
@@ -302,6 +302,7 @@
 
   # http://crbug.com/1336853
   "arc.StandardizedKeyboardTyping",
+  "arc.StandardizedKeyboardTyping.tablet_mode",
   "arc.StandardizedKeyboardKeys.tablet_mode",
 
   # http://b/236312054
diff --git a/components/autofill/content/renderer/autofill_agent.cc b/components/autofill/content/renderer/autofill_agent.cc
index 84898f80..3db2768 100644
--- a/components/autofill/content/renderer/autofill_agent.cc
+++ b/components/autofill/content/renderer/autofill_agent.cc
@@ -288,14 +288,17 @@
 
 void AutofillAgent::DidChangeScrollOffsetImpl(
     const WebFormControlElement& element) {
-  if (element != element_ || element_.IsNull() || focus_requires_scroll_ ||
-      !is_popup_possibly_visible_ || !element_.Focused())
+  if (element != element_ || element.IsNull() || focus_requires_scroll_ ||
+      !is_popup_possibly_visible_ || !element.Focused()) {
     return;
+  }
+
+  DCHECK(IsOwnedByFrame(element, render_frame()));
 
   FormData form;
   FormFieldData field;
   if (FindFormAndFieldForFormControlElement(
-          element_, field_data_manager_.get(),
+          element, field_data_manager_.get(),
           static_cast<ExtractMask>(form_util::EXTRACT_BOUNDS |
                                    GetExtractDatalistMask()),
           &form, &field)) {
diff --git a/components/autofill/content/renderer/form_autofill_util.cc b/components/autofill/content/renderer/form_autofill_util.cc
index ffb53d4..1b5cbac 100644
--- a/components/autofill/content/renderer/form_autofill_util.cc
+++ b/components/autofill/content/renderer/form_autofill_util.cc
@@ -1643,10 +1643,6 @@
 
 }  // namespace
 
-// TODO(crbug.com/1335257): This check is very similar to IsWebElementVisible()
-// (see the documentation there for the subtle differences: zoom factor and
-// scroll size). We can probably merge them but should do a Finch experiment
-// about it.
 bool IsVisibleIframe(const WebElement& element) {
   DCHECK(element.HasHTMLTagName("iframe"));
   // It is common for not-humanly-visible elements to have very small yet
@@ -1827,10 +1823,6 @@
   return element.IsCheckbox() || element.IsRadioButton();
 }
 
-bool IsCheckableElement(const WebElement& element) {
-  return IsCheckableElement(element.DynamicTo<WebInputElement>());
-}
-
 bool IsAutofillableInputElement(const WebInputElement& element) {
   return IsTextInput(element) || IsMonthInput(element) ||
          IsCheckableElement(element);
@@ -1846,16 +1838,6 @@
   return element.IsFocusable();
 }
 
-bool IsWebElementVisible(blink::WebElement element) {
-  auto HasMinSize = [](auto size) {
-    constexpr int kMinPixelSize = 10;
-    return size.width() >= kMinPixelSize && size.height() >= kMinPixelSize;
-  };
-  return !element.IsNull() && IsWebElementFocusable(element) &&
-         (IsCheckableElement(element) || HasMinSize(element.GetClientSize()) ||
-          HasMinSize(element.GetScrollSize()));
-}
-
 std::u16string GetFormIdentifier(const WebFormElement& form) {
   std::u16string identifier = form.GetName().Utf16();
   if (identifier.empty())
@@ -1991,7 +1973,6 @@
     // The browser doesn't need to differentiate between preview and autofill.
     field->is_autofilled = element.IsAutofilled();
     field->is_focusable = IsWebElementFocusable(element);
-    field->is_visible = IsWebElementVisible(element);
     field->should_autocomplete = element.AutoComplete();
 
     field->text_direction = GetTextDirectionForElement(element);
diff --git a/components/autofill/content/renderer/form_autofill_util.h b/components/autofill/content/renderer/form_autofill_util.h
index c9ae9cee..6dc4996 100644
--- a/components/autofill/content/renderer/form_autofill_util.h
+++ b/components/autofill/content/renderer/form_autofill_util.h
@@ -85,7 +85,7 @@
 //
 // Future potential improvements include:
 // * Detect potential visibility of elements with "overflow: visible".
-//   (See WebElement::GetScrollSize().)
+//   (See Element::scrollWidth().)
 // * Detect invisibility of elements with
 //   - "position: absolute; {left,top,right,bottol}: -100px"
 //   - "opacity: 0.0"
@@ -173,29 +173,6 @@
 // descendant has a non-empty bounding client rect.
 bool IsWebElementFocusable(const blink::WebElement& element);
 
-// A heuristic visibility detection. See crbug.com/1335257 for an overview of
-// relevant aspects.
-//
-// Note that WebElement::BoundsInViewport(), WebElement::GetClientSize(), and
-// WebElement::GetScrollSize() include the padding but do not include the border
-// and margin. BoundsInViewport() additionally scales the dimensions according
-// to the zoom factor.
-//
-// It seems that invisible fields on websites typically have dimensions between
-// 0 and 10 pixels, before the zoom factor. Therefore choosing `kMinPixelSize`
-// is easier without including the zoom factor. For that reason, this function
-// prefers GetClientSize() over BoundsInViewport().
-//
-// This function does not check the position in the viewport because fields in
-// iframes commonly are visible despite the body having height zero. Therefore,
-// `e.GetDocument().Body().BoundsInViewport().Intersects(e.BoundsInViewport())`
-// yields false negatives.
-//
-// Exposed for testing purposes.
-//
-// TODO(crbug.com/1335257): Can input fields or iframes actually overflow?
-bool IsWebElementVisible(blink::WebElement element);
-
 // Returns the form's |name| attribute if non-empty; otherwise the form's |id|
 // attribute.
 std::u16string GetFormIdentifier(const blink::WebFormElement& form);
diff --git a/components/autofill/content/renderer/form_autofill_util_browsertest.cc b/components/autofill/content/renderer/form_autofill_util_browsertest.cc
index 12d8478..62445ea 100644
--- a/components/autofill/content/renderer/form_autofill_util_browsertest.cc
+++ b/components/autofill/content/renderer/form_autofill_util_browsertest.cc
@@ -946,9 +946,6 @@
 }
 
 // Tests the visibility detection of iframes.
-// This test checks many scenarios. It's intentionally not a parameterized test
-// for performance reasons.
-// This test is very similar to the IsWebElementVisibleTest test.
 TEST_F(FormAutofillUtilsTest, IsVisibleIframeTest) {
   // Test cases of <iframe> elements with different styles.
   //
@@ -962,10 +959,10 @@
   // IsVisibleIframe() but invisible to the human).
   //
   // The `data-false="{POSITIVE,NEGATIVE}"` attribute indicates whether the test
-  // case is a false positive/negative compared to human visibility perception.
-  // In such a case, not meeting the expectation actually indicates an
-  // improvement of IsVisibleIframe(), as it means a false positive/negative has
-  // been fixed.
+  // case to be a false positive/negative compared to human visibility
+  // perception. In such a case, not meeting the expectation actually indicates
+  // an improvement of IsVisibleIframe(), as it means a false positive/negative
+  // has been fixed.
   //
   // The sole purpose of the `data-false` attribute is to document this and to
   // print a message when such a test fails.
@@ -999,7 +996,7 @@
         <iframe srcdoc="<input>" data-visible   style="width: 100px; height: 100px; position: absolute; right:  -200px;" data-false="POSITIVE"></iframe>
         <iframe srcdoc="<input>" data-visible   style="width: 100px; height: 100px; position: absolute; bottom: -200px;" data-false="POSITIVE"></iframe>
 
-        <iframe srcdoc="<input>" data-visible   style=""></iframe> <!-- Finish with a visible frame to make sure all <iframe> tags have been closed -->
+        <iframe srcdoc="<input>" data-visible   style=""></iframe> <!-- Finish with a visible frame to make sure all <iframe>s have been closed -->
 
         <div style="width: 10000; height: 10000"></div>
       </body>)");
@@ -1017,7 +1014,7 @@
     }
     return result;
   }();
-  ASSERT_GE(iframes.size(), 23u);
+  ASSERT_GE(iframes.size(), 16u);
 
   auto RunTestCases = [](const std::vector<WebElement>& iframes) {
     for (WebElement iframe : iframes) {
@@ -1050,125 +1047,6 @@
   }
 }
 
-// Tests the visibility detection of iframes.
-// This test checks many scenarios. It's intentionally not a parameterized test
-// for performance reasons.
-// This test is very similar to the IsVisibleIframeTest test.
-TEST_F(FormAutofillUtilsTest, IsWebElementVisibleTest) {
-  // Test cases of <input> elements with different types and styles.
-  //
-  // The `data-[in]visible` attribute represents whether IsWebElementVisible()
-  // is expected to classify the input as [in]visible.
-  //
-  // Since IsWebElementVisible() falls short of what the human user will
-  // consider visible or invisible, there are false positives and false
-  // negatives. For example, IsWebElementVisible() does not check opacity, so
-  // <input style="opacity: 0.0"> is a false positive (it's visible to
-  // IsWebElementVisible() but invisible to the human).
-  //
-  // The `data-false="{POSITIVE,NEGATIVE}"` attribute indicates whether the test
-  // case is a false positive/negative compared to human visibility perception.
-  // In such a case, not meeting the expectation actually indicates an
-  // improvement of IsWebElementVisible(), as it means a false positive/negative
-  // has been fixed.
-  //
-  // The sole purpose of the `data-false` attribute is to document this and to
-  // print a message when such a test fails.
-  LoadHTML(R"(
-      <body>
-        <input type="text" data-visible   style="">
-        <input type="text" data-visible   style="display: block;">
-        <input type="text" data-visible   style="visibility: visible;">
-
-        <input type="text" data-invisible style="display: none;">
-        <input type="text" data-invisible style="visibility: hidden;">
-        <div style="display: none;">     <input type="text" data-invisible></div>
-        <div style="visibility: hidden;"><input type="text" data-invisible></div>
-
-        <input type="text" data-visible   style="width: 15px; height: 15px;">
-        <input type="text" data-invisible style="width: 15px; height:  5px;">
-        <input type="text" data-invisible style="width:  5px; height: 15px;">
-        <input type="text" data-invisible style="width:  5px; height:  5px;">
-
-        <input type="text" data-invisible style="width: 1px; height: 1px;">
-        <input type="text" data-invisible style="width: 1px; height: 1px; overflow: visible;" data-false="NEGATIVE">
-
-        <input type="text" data-visible   style="opacity: 0.0;" data-false="POSITIVE">
-        <input type="text" data-visible   style="opacity: 0.0;" data-false="POSITIVE">
-        <input type="text" data-visible   style="position: absolute; clip: rect(0,0,0,0);" data-false="POSITIVE">
-
-        <input type="text" data-visible   style="width: 100px; position: absolute; left:    -75px;">
-        <input type="text" data-visible   style="width: 100px; position: absolute; top:     -75px;">
-        <input type="text" data-visible   style="width: 100px; position: absolute; left:   -200px;" data-false="POSITIVE">
-        <input type="text" data-visible   style="width: 100px; position: absolute; top:    -200px;" data-false="POSITIVE">
-        <input type="text" data-visible   style="width: 100px; position: absolute; right:  -200px;" data-false="POSITIVE">
-        <input type="text" data-visible   style="width: 100px; position: absolute; bottom: -200px;" data-false="POSITIVE">
-
-        <input type="checkbox" data-visible   style="">
-        <input type="checkbox" data-invisible style="display: none;">
-        <input type="checkbox" data-invisible style="visibility: hidden;">
-        <input type="checkbox" data-visible   style="width: 15px; height: 15px;">
-        <input type="checkbox" data-visible   style="width: 15px; height:  5px;">
-        <input type="checkbox" data-visible   style="width:  5px; height: 15px;">
-        <input type="checkbox" data-visible   style="width:  5px; height:  5px;">
-
-        <input type="radio" data-visible   style="">
-        <input type="radio" data-invisible style="display: none;">
-        <input type="radio" data-invisible style="visibility: hidden;">
-        <input type="radio" data-visible   style="width: 15px; height: 15px;">
-        <input type="radio" data-visible   style="width: 15px; height:  5px;">
-        <input type="radio" data-visible   style="width:  5px; height: 15px;">
-        <input type="radio" data-visible   style="width:  5px; height:  5px;">
-
-        <div style="width: 10000; height: 10000"></div>
-      </body>)");
-
-  // Ensure that Android runs at default page scale.
-  web_view_->SetPageScaleFactor(1.0);
-
-  std::vector<WebElement> inputs = [this] {
-    WebDocument doc = GetMainFrame()->GetDocument();
-    std::vector<WebElement> result;
-    WebElementCollection inputs = doc.GetElementsByHTMLTagName("input");
-    for (WebElement input = inputs.FirstItem(); !input.IsNull();
-         input = inputs.NextItem()) {
-      result.push_back(input);
-    }
-    return result;
-  }();
-  ASSERT_GE(inputs.size(), 36u);
-
-  auto RunTestCases = [](const std::vector<WebElement>& inputs) {
-    for (WebElement input : inputs) {
-      gfx::Rect bounds = input.BoundsInViewport();
-      bool expectation = input.HasAttribute("data-visible");
-      SCOPED_TRACE(
-          testing::Message()
-          << "Iframe with style \n  " << input.GetAttribute("style").Ascii()
-          << "\nwith dimensions w=" << bounds.width()
-          << ",h=" << bounds.height() << " and position x=" << bounds.x()
-          << ",y=" << bounds.y()
-          << (input.HasAttribute("data-false") ? "\nwhich used to be a FALSE "
-                                               : "")
-          << input.GetAttribute("data-false").Ascii());
-      ASSERT_TRUE(input.HasAttribute("data-visible") !=
-                  input.HasAttribute("data-invisible"));
-      EXPECT_EQ(IsWebElementVisible(input), expectation);
-    }
-  };
-
-  RunTestCases(inputs);
-
-  {
-    ExecuteJavaScriptForTests(
-        "window.scrollTo(document.body.scrollWidth,document.body.scrollHeight)"
-        ";");
-    content::RunAllTasksUntilIdle();
-    SCOPED_TRACE(testing::Message() << "Scrolled to bottom right");
-    RunTestCases(inputs);
-  }
-}
-
 // Tests `GetClosestAncestorFormElement(element)`.
 TEST_F(FormAutofillUtilsTest, GetClosestAncestorFormElement) {
   LoadHTML(R"(
diff --git a/components/autofill/content/renderer/form_tracker.cc b/components/autofill/content/renderer/form_tracker.cc
index 1cd65a4..1d7bbb3 100644
--- a/components/autofill/content/renderer/form_tracker.cc
+++ b/components/autofill/content/renderer/form_tracker.cc
@@ -130,8 +130,11 @@
     const WebFormControlElement& element,
     Observer::ElementChangeSource change_source) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(form_tracker_sequence_checker_);
-  // Render frame could be gone as this is the post task.
-  if (!render_frame()) return;
+  // The frame or document could be null because this function is called
+  // asynchronously.
+  const blink::WebDocument& doc = element.GetDocument();
+  if (!render_frame() || doc.IsNull() || !doc.GetFrame())
+    return;
 
   if (element.Form().IsNull()) {
     last_interacted_formless_element_ = element;
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc
index d7d3c5a..2ff856a 100644
--- a/components/autofill/core/browser/form_structure.cc
+++ b/components/autofill/core/browser/form_structure.cc
@@ -231,15 +231,30 @@
              : absl::nullopt;
 }
 
-// Tries mapping a non-standardized html autocomplete `value` to an
-// HtmlFieldType.
-absl::optional<HtmlFieldType> ParseAutocompleteAttributeExtensions(
+// Maps `value`s that Autofill has proposed for the HTML autocomplete standard,
+// but which are not standardized, to their HtmlFieldType.
+absl::optional<HtmlFieldType> ParseProposedAutocompleteAttribute(
     base::StringPiece value) {
-  static constexpr auto extensions =
+  static constexpr auto proposed_attributes =
       base::MakeFixedFlatMap<base::StringPiece, HtmlFieldType>({
           {"address", HTML_TYPE_STREET_ADDRESS},
-          {"company", HTML_TYPE_ORGANIZATION},
           {"coupon-code", HTML_TYPE_MERCHANT_PROMO_CODE},
+          {"username", HTML_TYPE_EMAIL},
+      });
+
+  auto* it = proposed_attributes.find(value);
+  return it != proposed_attributes.end()
+             ? absl::optional<HtmlFieldType>(it->second)
+             : absl::nullopt;
+}
+
+// Maps non standardized `value`s for the HTML autocomplete attribute to an
+// HtmlFieldType. This is primarily a list of "reasonable guesses".
+absl::optional<HtmlFieldType> ParseNonStandarizedAutocompleteAttribute(
+    base::StringPiece value) {
+  static constexpr auto non_standardized_attributes =
+      base::MakeFixedFlatMap<base::StringPiece, HtmlFieldType>({
+          {"company", HTML_TYPE_ORGANIZATION},
           {"first-name", HTML_TYPE_GIVEN_NAME},
           {"gift-code", HTML_TYPE_MERCHANT_PROMO_CODE},
           {"locality", HTML_TYPE_ADDRESS_LEVEL2},
@@ -250,12 +265,24 @@
           {"tel-ext", HTML_TYPE_TEL_EXTENSION},
           {"upi", HTML_TYPE_UPI_VPA},
           {"upi-vpa", HTML_TYPE_UPI_VPA},
-          {"username", HTML_TYPE_EMAIL},
       });
 
-  auto* it = extensions.find(value);
-  return it != extensions.end() ? absl::optional<HtmlFieldType>(it->second)
-                                : absl::nullopt;
+  auto* it = non_standardized_attributes.find(value);
+  return it != non_standardized_attributes.end()
+             ? absl::optional<HtmlFieldType>(it->second)
+             : absl::nullopt;
+}
+
+// If the autocomplete `value` doesn't match any of Autofill's supported values,
+// Autofill should remain enabled for good intended values. This function checks
+// if there is reason to believe so, by matching `value` against patterns like
+// "address".
+// Ignoring autocomplete="off" and alike is treated separately in
+// `ParseFieldTypesFromAutocompleteAttributes()`.
+bool ShouldIgnoreAutocompleteValue(const std::string& value) {
+  // For now, only ignore unrecognizable autocomplete attributes containing
+  // "address".
+  return MatchesPattern(base::UTF8ToUTF16(value), u"address");
 }
 
 // Returns the Chrome Autofill-supported field type corresponding to a given
@@ -276,11 +303,24 @@
 
   absl::optional<HtmlFieldType> type =
       ParseStandardizedAutocompleteAttribute(value);
-  if (!type.has_value())
-    type = ParseAutocompleteAttributeExtensions(value);
+  if (!type.has_value()) {
+    type = ParseProposedAutocompleteAttribute(value);
+    if (!type.has_value())
+      type = ParseNonStandarizedAutocompleteAttribute(value);
+  }
 
-  return type.has_value() ? RationalizeAutocompleteType(type.value(), field)
-                          : HTML_TYPE_UNRECOGNIZED;
+  if (type.has_value())
+    return RationalizeAutocompleteType(type.value(), field);
+
+  // `value` cannot be mapped to any HtmlFieldType. By classifying the field
+  // as HTML_TYPE_UNRECOGNIZED Autofill is effectively disabled. Instead, check
+  // if we have reason to ignore the value and treat the field as
+  // HTML_TYPE_UNSPECIFIED. This makes us ignore the autocomplete value.
+  return ShouldIgnoreAutocompleteValue(value) &&
+                 base::FeatureList::IsEnabled(
+                     features::kAutofillIgnoreUnmappableAutocompleteValues)
+             ? HTML_TYPE_UNSPECIFIED
+             : HTML_TYPE_UNRECOGNIZED;
 }
 
 std::ostream& operator<<(std::ostream& out,
@@ -2830,10 +2870,6 @@
     buffer << Tr{} << "Label:" << truncated_label;
 
     buffer << Tr{} << "Is empty:" << (field->IsEmpty() ? "Yes" : "No");
-    buffer << Tr{} << "Is focusable:"
-           << (field->IsFocusable() ? "Yes (focusable)" : "No (unfocusable)");
-    buffer << Tr{} << "Is visible:"
-           << (field->is_visible ? "Yes (visible)" : "No (invisible)");
     buffer << CTag{"table"};
     buffer << CTag{"td"};
     buffer << CTag{"tr"};
diff --git a/components/autofill/core/browser/form_structure_unittest.cc b/components/autofill/core/browser/form_structure_unittest.cc
index 8bfe6ca..8db5b470 100644
--- a/components/autofill/core/browser/form_structure_unittest.cc
+++ b/components/autofill/core/browser/form_structure_unittest.cc
@@ -573,6 +573,20 @@
   EXPECT_TRUE(form_structure->ShouldBeParsed());
 }
 
+// Tests that unmappable autocomplete values containing "address" are treated
+// as HTML_TYPE_UNSPECIFIED instead of HTML_TYPE_UNRECOGNIZED.
+TEST_F(FormStructureTestImpl, IgnoreUnmappableAutocompleteValues) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitAndEnableFeature(
+      features::kAutofillIgnoreUnmappableAutocompleteValues);
+
+  CheckFormStructureTestData(
+      {{{.description_for_logging = "IgnoreUnmappableAutocompleteValues",
+         .fields = {{.autocomplete_attribute = "address-info"}}},
+        {.determine_heuristic_type = true},
+        {.expected_html_type = {HTML_TYPE_UNSPECIFIED}}}});
+}
+
 // Tests that ShouldBeParsed returns true for a form containing less than three
 // fields if at least one has an autocomplete attribute.
 TEST_F(FormStructureTestImpl, DetermineHeuristicTypes_AutocompleteFalse) {
diff --git a/components/autofill/core/common/autofill_features.cc b/components/autofill/core/common/autofill_features.cc
index f7fb7e74..aa0ae53d 100644
--- a/components/autofill/core/common/autofill_features.cc
+++ b/components/autofill/core/common/autofill_features.cc
@@ -358,6 +358,13 @@
         &kAutofillIgnoreEarlyClicksOnPopup, "duration",
         base::Milliseconds(250)};
 
+// When enabled, HTML autocomplete values that do not map to any known type, but
+// look reasonable (e.g. contain "address") are simply ignored. Without the
+// feature, Autofill is disabled on such fields.
+const base::Feature kAutofillIgnoreUnmappableAutocompleteValues{
+    "AutofillIgnoreUnmappableAutocompleteValues",
+    base::FEATURE_DISABLED_BY_DEFAULT};
+
 // When enabled, only changed values are highlighted in preview mode.
 // TODO(crbug/1248585): Remove when launched.
 const base::Feature kAutofillHighlightOnlyChangedValuesInPreviewMode{
diff --git a/components/autofill/core/common/autofill_features.h b/components/autofill/core/common/autofill_features.h
index d8b3036..af50ad5 100644
--- a/components/autofill/core/common/autofill_features.h
+++ b/components/autofill/core/common/autofill_features.h
@@ -133,6 +133,8 @@
 extern const base::FeatureParam<base::TimeDelta>
     kAutofillIgnoreEarlyClicksOnPopupDuration;
 COMPONENT_EXPORT(AUTOFILL)
+extern const base::Feature kAutofillIgnoreUnmappableAutocompleteValues;
+COMPONENT_EXPORT(AUTOFILL)
 extern const base::Feature kAutofillHighlightOnlyChangedValuesInPreviewMode;
 COMPONENT_EXPORT(AUTOFILL)
 extern const base::Feature kAutofillServerTypeTakesPrecedence;
diff --git a/components/autofill/core/common/form_field_data.h b/components/autofill/core/common/form_field_data.h
index de784bca..381b0528 100644
--- a/components/autofill/core/common/form_field_data.h
+++ b/components/autofill/core/common/form_field_data.h
@@ -207,7 +207,6 @@
   bool is_autofilled = false;
   CheckStatus check_status = CheckStatus::kNotCheckable;
   bool is_focusable = true;
-  bool is_visible = true;
   bool should_autocomplete = true;
   RoleAttribute role = RoleAttribute::kOther;
   base::i18n::TextDirection text_direction = base::i18n::UNKNOWN_DIRECTION;
@@ -259,7 +258,6 @@
 
 // Prefer to use this macro in place of |EXPECT_EQ()| for comparing
 // |FormFieldData|s in test code.
-// TODO(crbug.com/1208354): Replace this with FormData::DeepEqual().
 #define EXPECT_FORM_FIELD_DATA_EQUALS(expected, actual)                        \
   do {                                                                         \
     EXPECT_EQ_UNIQUE_ID(expected, actual);                                     \
diff --git a/components/autofill/core/common/mojom/autofill_types.mojom b/components/autofill/core/common/mojom/autofill_types.mojom
index 609485f..249aaa6e 100644
--- a/components/autofill/core/common/mojom/autofill_types.mojom
+++ b/components/autofill/core/common/mojom/autofill_types.mojom
@@ -189,7 +189,6 @@
   string section;
   CheckStatus check_status;
   bool is_focusable;
-  bool is_visible;
   bool should_autocomplete;
   RoleAttribute role;
   mojo_base.mojom.TextDirection text_direction;
diff --git a/components/autofill/core/common/mojom/autofill_types_mojom_traits.cc b/components/autofill/core/common/mojom/autofill_types_mojom_traits.cc
index 88fe33bc..3944958 100644
--- a/components/autofill/core/common/mojom/autofill_types_mojom_traits.cc
+++ b/components/autofill/core/common/mojom/autofill_types_mojom_traits.cc
@@ -120,7 +120,6 @@
     return false;
 
   out->is_focusable = data.is_focusable();
-  out->is_visible = data.is_visible();
   out->should_autocomplete = data.should_autocomplete();
 
   if (!data.ReadRole(&out->role))
diff --git a/components/autofill/core/common/mojom/autofill_types_mojom_traits.h b/components/autofill/core/common/mojom/autofill_types_mojom_traits.h
index 9060cf6..0d882e6 100644
--- a/components/autofill/core/common/mojom/autofill_types_mojom_traits.h
+++ b/components/autofill/core/common/mojom/autofill_types_mojom_traits.h
@@ -181,10 +181,6 @@
     return r.is_focusable;
   }
 
-  static bool is_visible(const autofill::FormFieldData& r) {
-    return r.is_visible;
-  }
-
   static bool should_autocomplete(const autofill::FormFieldData& r) {
     return r.should_autocomplete;
   }
diff --git a/components/autofill_assistant/browser/BUILD.gn b/components/autofill_assistant/browser/BUILD.gn
index 281ad616..0233c5e 100644
--- a/components/autofill_assistant/browser/BUILD.gn
+++ b/components/autofill_assistant/browser/BUILD.gn
@@ -28,10 +28,9 @@
 
 proto_library("test_proto") {
   sources = [
-    "external_action_extension_test.proto",
+    "external_action_test.proto",
     "parse_jspb_test.proto",
   ]
-  link_deps = [ "//components/autofill_assistant/browser/public:proto" ]
 }
 
 static_library("browser") {
diff --git a/components/autofill_assistant/browser/actions/external_action_unittest.cc b/components/autofill_assistant/browser/actions/external_action_unittest.cc
index ac8be3fd..ffcacb1 100644
--- a/components/autofill_assistant/browser/actions/external_action_unittest.cc
+++ b/components/autofill_assistant/browser/actions/external_action_unittest.cc
@@ -10,7 +10,7 @@
 #include "base/test/test_simple_task_runner.h"
 #include "components/autofill_assistant/browser/actions/mock_action_delegate.h"
 #include "components/autofill_assistant/browser/actions/wait_for_dom_test_base.h"
-#include "components/autofill_assistant/browser/external_action_extension_test.pb.h"
+#include "components/autofill_assistant/browser/external_action_test.pb.h"
 #include "components/autofill_assistant/browser/service.pb.h"
 #include "components/autofill_assistant/browser/web/mock_web_controller.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -52,11 +52,11 @@
 external::Result MakeResult(bool success) {
   external::Result result;
   result.set_success(success);
-  testing::TestResultExtension test_extension_proto;
-  test_extension_proto.set_text("test text");
+  testing::TestExternalResultProto test_external_result_proto;
+  test_external_result_proto.set_text("test text");
 
-  *result.mutable_result_info()->MutableExtension(
-      testing::test_result_extension) = std::move(test_extension_proto);
+  test_external_result_proto.SerializeToString(
+      result.mutable_result_info()->mutable_result_payload());
   return result;
 }
 
@@ -75,12 +75,17 @@
           });
   Run();
   EXPECT_THAT(returned_processed_action_proto->status(), Eq(ACTION_APPLIED));
-  EXPECT_TRUE(returned_processed_action_proto->has_external_action_result());
-  EXPECT_THAT(returned_processed_action_proto->external_action_result()
+  ASSERT_TRUE(returned_processed_action_proto->external_action_result()
                   .result_info()
-                  .GetExtension(testing::test_result_extension)
-                  .text(),
-              Eq("test text"));
+                  .has_result_payload());
+  testing::TestExternalResultProto test_external_result_proto;
+  bool parse_success = test_external_result_proto.ParseFromString(
+      returned_processed_action_proto->external_action_result()
+          .result_info()
+          .result_payload());
+  EXPECT_TRUE(parse_success);
+
+  EXPECT_THAT(test_external_result_proto.text(), Eq("test text"));
 }
 
 TEST_F(ExternalActionTest, ExternalFailure) {
@@ -99,11 +104,17 @@
   EXPECT_THAT(returned_processed_action_proto->status(),
               Eq(UNKNOWN_ACTION_STATUS));
   EXPECT_TRUE(returned_processed_action_proto->has_external_action_result());
-  EXPECT_THAT(returned_processed_action_proto->external_action_result()
+  ASSERT_TRUE(returned_processed_action_proto->external_action_result()
                   .result_info()
-                  .GetExtension(testing::test_result_extension)
-                  .text(),
-              Eq("test text"));
+                  .has_result_payload());
+  testing::TestExternalResultProto test_external_result_proto;
+  bool parse_success = test_external_result_proto.ParseFromString(
+      returned_processed_action_proto->external_action_result()
+          .result_info()
+          .result_payload());
+  EXPECT_TRUE(parse_success);
+
+  EXPECT_THAT(test_external_result_proto.text(), Eq("test text"));
 }
 
 TEST_F(ExternalActionTest, FailsIfProtoExtensionInfoNotSet) {
diff --git a/components/autofill_assistant/browser/external_action_extension_test.proto b/components/autofill_assistant/browser/external_action_test.proto
similarity index 64%
rename from components/autofill_assistant/browser/external_action_extension_test.proto
rename to components/autofill_assistant/browser/external_action_test.proto
index 18efa16..40da58f 100644
--- a/components/autofill_assistant/browser/external_action_extension_test.proto
+++ b/components/autofill_assistant/browser/external_action_test.proto
@@ -8,12 +8,6 @@
 
 option optimize_for = LITE_RUNTIME;
 
-import "public/external_action.proto";
-
-extend external.ResultInfo {
-  optional TestResultExtension test_result_extension = 100;
-}
-
-message TestResultExtension {
+message TestExternalResultProto {
   optional string text = 1;
 }
diff --git a/components/autofill_assistant/browser/public/external_action.proto b/components/autofill_assistant/browser/public/external_action.proto
index 595f218..8499bf58 100644
--- a/components/autofill_assistant/browser/public/external_action.proto
+++ b/components/autofill_assistant/browser/public/external_action.proto
@@ -18,7 +18,9 @@
 
 // Extended by the integrator.
 message ActionInfo {
-  extensions 100 to max;
+  optional bytes action_payload = 1;
+
+  reserved 100 to max;
 }
 
 // The result of the execution of |Action|
@@ -33,7 +35,9 @@
 
 // Extended by the integrator.
 message ResultInfo {
-  extensions 100 to max;
+  optional bytes result_payload = 1;
+
+  reserved 100 to max;
 }
 
 // An update on the status of the DOM conditions for the current action.
diff --git a/components/file_access/BUILD.gn b/components/file_access/BUILD.gn
new file mode 100644
index 0000000..0bc60bb
--- /dev/null
+++ b/components/file_access/BUILD.gn
@@ -0,0 +1,16 @@
+# Copyright 2022 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+component("file_access") {
+  output_name = "file_access_lib"
+
+  sources = [
+    "scoped_file_access.cc",
+    "scoped_file_access.h",
+  ]
+
+  defines = [ "IS_FILE_ACCESS_IMPL" ]
+
+  deps = [ "//base" ]
+}
diff --git a/components/file_access/OWNERS b/components/file_access/OWNERS
new file mode 100644
index 0000000..bb766c68
--- /dev/null
+++ b/components/file_access/OWNERS
@@ -0,0 +1,2 @@
+ayaelattar@chromium.org
+poromov@chromium.org
diff --git a/components/file_access/scoped_file_access.cc b/components/file_access/scoped_file_access.cc
new file mode 100644
index 0000000..c4b96444
--- /dev/null
+++ b/components/file_access/scoped_file_access.cc
@@ -0,0 +1,29 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/file_access/scoped_file_access.h"
+
+namespace file_access {
+
+#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
+ScopedFileAccess::ScopedFileAccess(bool allowed, base::ScopedFD fd)
+    : allowed_(allowed), lifeline_fd_(std::move(fd)) {}
+#else
+ScopedFileAccess::ScopedFileAccess(bool allowed) : allowed_(allowed) {}
+#endif
+ScopedFileAccess::ScopedFileAccess(ScopedFileAccess&& other) = default;
+ScopedFileAccess& ScopedFileAccess::operator=(ScopedFileAccess&& other) =
+    default;
+ScopedFileAccess::~ScopedFileAccess() = default;
+
+// static
+ScopedFileAccess ScopedFileAccess::Allowed() {
+#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
+  return ScopedFileAccess(/*allowed=*/true, base::ScopedFD());
+#else
+  return ScopedFileAccess(/*allowed=*/true);
+#endif
+}
+
+}  // namespace file_access
diff --git a/components/file_access/scoped_file_access.h b/components/file_access/scoped_file_access.h
new file mode 100644
index 0000000..1e80ce4c
--- /dev/null
+++ b/components/file_access/scoped_file_access.h
@@ -0,0 +1,50 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_FILE_ACCESS_SCOPED_FILE_ACCESS_H_
+#define COMPONENTS_FILE_ACCESS_SCOPED_FILE_ACCESS_H_
+
+#include "base/component_export.h"
+#include "build/build_config.h"
+
+#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
+#include "base/files/scoped_file.h"
+#endif
+
+namespace file_access {
+
+// Move-only object to handle access token to open files.
+// After the object destruction, the caller may lose access to open some of the
+// requested files.
+// Platform-dependant as holds ScopedFD as a token, when supported.
+class COMPONENT_EXPORT(FILE_ACCESS) ScopedFileAccess {
+ public:
+  ScopedFileAccess(ScopedFileAccess&& other);
+  ScopedFileAccess& operator=(ScopedFileAccess&& other);
+  ScopedFileAccess(const ScopedFileAccess&) = delete;
+  ScopedFileAccess& operator=(const ScopedFileAccess&) = delete;
+  ~ScopedFileAccess();
+
+  bool is_allowed() const { return allowed_; }
+
+#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
+  ScopedFileAccess(bool allowed, base::ScopedFD fd);
+#else
+  ScopedFileAccess(bool allowed);
+#endif
+
+  // Object identifying allowed access.
+  static ScopedFileAccess Allowed();
+
+ private:
+  bool allowed_;
+#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
+  // Holds access token. When closed, access may be revoked.
+  base::ScopedFD lifeline_fd_;
+#endif
+};
+
+}  // namespace file_access
+
+#endif  // COMPONENTS_FILE_ACCESS_SCOPED_FILE_ACCESS_H_
diff --git a/components/payments/content/android/BUILD.gn b/components/payments/content/android/BUILD.gn
index 05144417..c34b470 100644
--- a/components/payments/content/android/BUILD.gn
+++ b/components/payments/content/android/BUILD.gn
@@ -360,7 +360,7 @@
   ]
 }
 
-android_library("javatests") {
+android_library("unit_device_javatests") {
   testonly = true
   sources = [ "javatests/src/org/chromium/components/payments/AndroidPaymentAppUnitTest.java" ]
   deps = [
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json
index 369756c..147bde1 100644
--- a/components/policy/resources/policy_templates.json
+++ b/components/policy/resources/policy_templates.json
@@ -30989,7 +30989,7 @@
           'caption': 'Disable adaptive charging model on <ph name="PRODUCT_OS_NAME">$2<ex>Google ChromeOS</ex></ph>',
         },
       ],
-      'default': False,
+      'default': True,
       'example_value': False,
       'id': 971,
       'caption': '''Enable adaptive charging model to hold charging process to extend battery life''',
diff --git a/components/viz/service/display/direct_renderer.cc b/components/viz/service/display/direct_renderer.cc
index ce0b2474..cd932deb 100644
--- a/components/viz/service/display/direct_renderer.cc
+++ b/components/viz/service/display/direct_renderer.cc
@@ -908,6 +908,12 @@
   if (requested_viewport_size != device_viewport_size_)
     last_viewport_resize_time_ = base::TimeTicks::Now();
 
+  // Width & height mustn't be more than max texture size.
+  if (surface_width > output_surface_->capabilities().max_texture_size)
+    surface_width = output_surface_->capabilities().max_texture_size;
+  if (surface_height > output_surface_->capabilities().max_texture_size)
+    surface_height = output_surface_->capabilities().max_texture_size;
+
   device_viewport_size_ = requested_viewport_size;
   return gfx::Size(surface_width, surface_height);
 }
diff --git a/components/viz/service/display/output_surface.h b/components/viz/service/display/output_surface.h
index 40a1cc2..5655794 100644
--- a/components/viz/service/display/output_surface.h
+++ b/components/viz/service/display/output_surface.h
@@ -136,6 +136,9 @@
     // SkColorType for all supported buffer formats.
     SkColorType sk_color_types[static_cast<int>(gfx::BufferFormat::LAST) + 1] =
         {};
+
+    // Max size for textures.
+    int max_texture_size = 0;
   };
 
   // Constructor for skia-based compositing.
diff --git a/components/viz/service/display_embedder/compositor_gpu_thread.cc b/components/viz/service/display_embedder/compositor_gpu_thread.cc
index e3a72cb..cb93d533 100644
--- a/components/viz/service/display_embedder/compositor_gpu_thread.cc
+++ b/components/viz/service/display_embedder/compositor_gpu_thread.cc
@@ -129,6 +129,15 @@
   // GL resources with the contexts created on gpu main thread.
   auto context =
       gl::init::CreateGLContext(share_group.get(), surface.get(), attribs);
+
+  if (!context && !features::UseGles2ForOopR()) {
+    LOG(ERROR) << "Failed to create GLES3 context, fallback to GLES2.";
+    attribs.client_major_es_version = 2;
+    attribs.client_minor_es_version = 0;
+    context =
+        gl::init::CreateGLContext(share_group.get(), surface.get(), attribs);
+  }
+
   if (!context) {
     LOG(ERROR) << "Failed to create shared context";
     return nullptr;
diff --git a/components/viz/service/display_embedder/skia_output_device.cc b/components/viz/service/display_embedder/skia_output_device.cc
index bbc98d2..c9c31e7 100644
--- a/components/viz/service/display_embedder/skia_output_device.cc
+++ b/components/viz/service/display_embedder/skia_output_device.cc
@@ -113,6 +113,7 @@
       latency_tracker_runner_(CreateLatencyTracerRunner()) {
   DCHECK(gr_context);
   capabilities_.max_render_target_size = gr_context->maxRenderTargetSize();
+  capabilities_.max_texture_size = gr_context->maxTextureSize();
 }
 
 SkiaOutputDevice::~SkiaOutputDevice() {
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 6917b71..c257212 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -70,6 +70,7 @@
     "//components/discardable_memory/service",
     "//components/download/database",
     "//components/download/public/common:public",
+    "//components/file_access",
     "//components/filename_generation",
     "//components/link_header_util",
     "//components/metrics",
diff --git a/content/browser/DEPS b/content/browser/DEPS
index 686dbfdc..e576a1f 100644
--- a/content/browser/DEPS
+++ b/content/browser/DEPS
@@ -10,6 +10,7 @@
   "+components/discardable_memory/service",
   "+components/download/database",
   "+components/download/public/common",
+  "+components/file_access",
   "+components/filename_generation",
   "+components/permissions/features.h",
   "+components/services/font",
diff --git a/content/browser/android/ime_adapter_android.cc b/content/browser/android/ime_adapter_android.cc
index faa2b8f..3cf5372e 100644
--- a/content/browser/android/ime_adapter_android.cc
+++ b/content/browser/android/ime_adapter_android.cc
@@ -343,14 +343,28 @@
     Java_ImeAdapterImpl_cancelComposition(env, obj);
 }
 
-void ImeAdapterAndroid::FocusedNodeChanged(bool is_editable_node) {
+void ImeAdapterAndroid::FocusedNodeChanged(
+    bool is_editable_node,
+    const gfx::Rect& node_bounds_in_screen) {
   JNIEnv* env = AttachCurrentThread();
   ScopedJavaLocalRef<jobject> obj = java_ime_adapter_.get(env);
   if (!obj.is_null()) {
-    Java_ImeAdapterImpl_focusedNodeChanged(env, obj, is_editable_node);
+    Java_ImeAdapterImpl_focusedNodeChanged(
+        env, obj, is_editable_node, node_bounds_in_screen.x(),
+        node_bounds_in_screen.y(), node_bounds_in_screen.right(),
+        node_bounds_in_screen.bottom());
   }
 }
 
+bool ImeAdapterAndroid::RequestStartStylusWriting() {
+  JNIEnv* env = AttachCurrentThread();
+  ScopedJavaLocalRef<jobject> obj = java_ime_adapter_.get(env);
+  if (!obj.is_null()) {
+    return Java_ImeAdapterImpl_requestStartStylusWriting(env, obj);
+  }
+  return false;
+}
+
 void ImeAdapterAndroid::AdvanceFocusForIME(JNIEnv* env,
                                            const JavaParamRef<jobject>& obj,
                                            jint focus_type) {
diff --git a/content/browser/android/ime_adapter_android.h b/content/browser/android/ime_adapter_android.h
index a6135bb..72bd5499 100644
--- a/content/browser/android/ime_adapter_android.h
+++ b/content/browser/android/ime_adapter_android.h
@@ -110,8 +110,11 @@
 
   // Called from native -> java
   void CancelComposition();
-  void FocusedNodeChanged(bool is_editable_node);
+  void FocusedNodeChanged(bool is_editable_node,
+                          const gfx::Rect& node_bounds_in_screen);
   void SetCharacterBounds(const std::vector<gfx::RectF>& rects);
+  // Requests to start stylus writing and returns true if successful.
+  bool RequestStartStylusWriting();
 
   base::android::ScopedJavaLocalRef<jobject> java_ime_adapter_for_testing(
       JNIEnv* env) {
diff --git a/content/browser/network_context_client_base_impl.cc b/content/browser/network_context_client_base_impl.cc
index bbb23a5..b59031c 100644
--- a/content/browser/network_context_client_base_impl.cc
+++ b/content/browser/network_context_client_base_impl.cc
@@ -10,8 +10,11 @@
 #include "base/task/thread_pool.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
+#include "components/file_access/scoped_file_access.h"
 #include "content/browser/child_process_security_policy_impl.h"
+#include "content/public/browser/content_browser_client.h"
 #include "content/public/browser/network_context_client_base.h"
+#include "content/public/common/content_client.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "services/network/public/mojom/trust_tokens.mojom.h"
 
@@ -29,7 +32,8 @@
     const std::vector<base::FilePath>& file_paths,
     network::mojom::NetworkContextClient::OnFileUploadRequestedCallback
         callback,
-    scoped_refptr<base::TaskRunner> task_runner) {
+    scoped_refptr<base::TaskRunner> task_runner,
+    file_access::ScopedFileAccess scoped_file_access) {
   std::vector<base::File> files;
   uint32_t file_flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
                         (async ? base::File::FLAG_ASYNC : 0);
@@ -66,17 +70,32 @@
 
 }  // namespace
 
-void NetworkContextOnFileUploadRequested(
+void OnScopedFilesAccessAcquired(
     int32_t process_id,
     bool async,
     const std::vector<base::FilePath>& file_paths,
     network::mojom::NetworkContextClient::OnFileUploadRequestedCallback
-        callback) {
+        callback,
+    file_access::ScopedFileAccess scoped_file_access) {
   base::ThreadPool::PostTask(
       FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_BLOCKING},
       base::BindOnce(&HandleFileUploadRequest, process_id, async, file_paths,
                      std::move(callback),
-                     base::SequencedTaskRunnerHandle::Get()));
+                     base::SequencedTaskRunnerHandle::Get(),
+                     std::move(scoped_file_access)));
+}
+
+void NetworkContextOnFileUploadRequested(
+    int32_t process_id,
+    bool async,
+    const std::vector<base::FilePath>& file_paths,
+    const GURL& destination_url,
+    network::mojom::NetworkContextClient::OnFileUploadRequestedCallback
+        callback) {
+  GetContentClient()->browser()->RequestFilesAccess(
+      file_paths, destination_url,
+      base::BindOnce(&OnScopedFilesAccessAcquired, process_id, async,
+                     file_paths, std::move(callback)));
 }
 
 NetworkContextClientBase::NetworkContextClientBase() = default;
@@ -86,9 +105,10 @@
     int32_t process_id,
     bool async,
     const std::vector<base::FilePath>& file_paths,
+    const GURL& destination_url,
     OnFileUploadRequestedCallback callback) {
   NetworkContextOnFileUploadRequested(process_id, async, file_paths,
-                                      std::move(callback));
+                                      destination_url, std::move(callback));
 }
 
 void NetworkContextClientBase::OnCanSendReportingReports(
diff --git a/content/browser/network_context_client_base_impl.h b/content/browser/network_context_client_base_impl.h
index ab7e264..4ad9726 100644
--- a/content/browser/network_context_client_base_impl.h
+++ b/content/browser/network_context_client_base_impl.h
@@ -15,6 +15,7 @@
     int32_t process_id,
     bool async,
     const std::vector<base::FilePath>& file_paths,
+    const GURL& destination_url,
     network::mojom::NetworkContextClient::OnFileUploadRequestedCallback
         callback);
 
diff --git a/content/browser/network_context_client_base_impl_unittest.cc b/content/browser/network_context_client_base_impl_unittest.cc
index 5f2bdd5..fa7e3b0 100644
--- a/content/browser/network_context_client_base_impl_unittest.cc
+++ b/content/browser/network_context_client_base_impl_unittest.cc
@@ -89,6 +89,7 @@
 TEST_F(NetworkContextClientBaseTest, UploadNoFiles) {
   UploadResponse response;
   client_.OnFileUploadRequested(kRendererProcessId, true, {},
+                                /*destination_url=*/GURL(),
                                 std::move(response.callback));
   task_environment_.RunUntilIdle();
   EXPECT_EQ(net::OK, response.error_code);
@@ -102,6 +103,7 @@
 
   UploadResponse response;
   client_.OnFileUploadRequested(kRendererProcessId, true, {path},
+                                /*destination_url=*/GURL(),
                                 std::move(response.callback));
   task_environment_.RunUntilIdle();
   EXPECT_EQ(net::OK, response.error_code);
@@ -116,6 +118,7 @@
 
   UploadResponse response;
   client_.OnFileUploadRequested(kRendererProcessId, false, {path},
+                                /*destination_url=*/GURL(),
                                 std::move(response.callback));
   task_environment_.RunUntilIdle();
   EXPECT_EQ(net::OK, response.error_code);
@@ -142,6 +145,7 @@
 
   UploadResponse response;
   client_.OnFileUploadRequested(kRendererProcessId, false, {content_path},
+                                /*destination_url=*/GURL(),
                                 std::move(response.callback));
   task_environment_.RunUntilIdle();
   EXPECT_EQ(net::OK, response.error_code);
@@ -163,6 +167,7 @@
 
   UploadResponse response;
   client_.OnFileUploadRequested(kRendererProcessId, false, {path1, path2},
+                                /*destination_url=*/GURL(),
                                 std::move(response.callback));
   task_environment_.RunUntilIdle();
   EXPECT_EQ(net::OK, response.error_code);
@@ -177,6 +182,7 @@
 
   UploadResponse response;
   client_.OnFileUploadRequested(kRendererProcessId, false, {path},
+                                /*destination_url=*/GURL(),
                                 std::move(response.callback));
   task_environment_.RunUntilIdle();
   EXPECT_EQ(net::ERR_ACCESS_DENIED, response.error_code);
@@ -192,6 +198,7 @@
 
   UploadResponse response;
   client_.OnFileUploadRequested(kRendererProcessId, false, {path1, path2},
+                                /*destination_url=*/GURL(),
                                 std::move(response.callback));
   task_environment_.RunUntilIdle();
   EXPECT_EQ(net::ERR_ACCESS_DENIED, response.error_code);
@@ -207,6 +214,7 @@
 
   UploadResponse response;
   client_.OnFileUploadRequested(kRendererProcessId, false, {path1, path2},
+                                /*destination_url=*/GURL(),
                                 std::move(response.callback));
   task_environment_.RunUntilIdle();
   EXPECT_EQ(net::ERR_FILE_NOT_FOUND, response.error_code);
@@ -220,6 +228,7 @@
 
   UploadResponse response;
   client_.OnFileUploadRequested(kBrowserProcessId, false, {path},
+                                /*destination_url=*/GURL(),
                                 std::move(response.callback));
   task_environment_.RunUntilIdle();
   EXPECT_EQ(net::OK, response.error_code);
diff --git a/content/browser/preloading_attempt_impl.cc b/content/browser/preloading_attempt_impl.cc
index f91e6a34d..4e25f47 100644
--- a/content/browser/preloading_attempt_impl.cc
+++ b/content/browser/preloading_attempt_impl.cc
@@ -5,6 +5,7 @@
 #include "content/browser/preloading_attempt_impl.h"
 
 #include "content/common/state_transitions.h"
+#include "content/public/browser/preloading.h"
 #include "services/metrics/public/cpp/ukm_builders.h"
 #include "services/metrics/public/cpp/ukm_recorder.h"
 
@@ -18,14 +19,12 @@
   static const base::NoDestructor<StateTransitions<PreloadingTriggeringOutcome>>
       allowed_transitions(StateTransitions<PreloadingTriggeringOutcome>({
           {PreloadingTriggeringOutcome::kUnspecified,
-           {PreloadingTriggeringOutcome::kNotTriggered,
-            PreloadingTriggeringOutcome::kDuplicate,
+           {PreloadingTriggeringOutcome::kDuplicate,
             PreloadingTriggeringOutcome::kRunning,
             PreloadingTriggeringOutcome::kReady,
             PreloadingTriggeringOutcome::kSuccess,
-            PreloadingTriggeringOutcome::kFailure}},
-
-          {PreloadingTriggeringOutcome::kNotTriggered, {}},
+            PreloadingTriggeringOutcome::kFailure,
+            PreloadingTriggeringOutcome::kTriggeredButOutcomeUnknown}},
 
           {PreloadingTriggeringOutcome::kDuplicate, {}},
 
@@ -43,6 +42,8 @@
           {PreloadingTriggeringOutcome::kSuccess, {}},
 
           {PreloadingTriggeringOutcome::kFailure, {}},
+
+          {PreloadingTriggeringOutcome::kTriggeredButOutcomeUnknown, {}},
       }));
   DCHECK_STATE_TRANSITION(allowed_transitions,
                           /*old_state=*/old_state,
@@ -53,11 +54,32 @@
 }  // namespace
 
 void PreloadingAttemptImpl::SetEligibility(PreloadingEligibility eligibility) {
+  // Ensure that eligiblity is only set once and that it's set before the
+  // holdback status and the triggering outcome.
+  DCHECK_EQ(eligibility_, PreloadingEligibility::kUnspecified);
+  DCHECK_EQ(holdback_status_, PreloadingHoldbackStatus::kUnspecified);
+  DCHECK_EQ(triggering_outcome_, PreloadingTriggeringOutcome::kUnspecified);
+  DCHECK_NE(eligibility, PreloadingEligibility::kUnspecified);
   eligibility_ = eligibility;
 }
 
+void PreloadingAttemptImpl::SetHoldbackStatus(
+    PreloadingHoldbackStatus holdback_status) {
+  // Ensure that the holdback status is only set once and that it's set for
+  // eligible attempts and before the triggering outcome.
+  DCHECK_EQ(eligibility_, PreloadingEligibility::kEligible);
+  DCHECK_EQ(holdback_status_, PreloadingHoldbackStatus::kUnspecified);
+  DCHECK_EQ(triggering_outcome_, PreloadingTriggeringOutcome::kUnspecified);
+  DCHECK_NE(holdback_status, PreloadingHoldbackStatus::kUnspecified);
+  holdback_status_ = holdback_status;
+}
+
 void PreloadingAttemptImpl::SetTriggeringOutcome(
     PreloadingTriggeringOutcome triggering_outcome) {
+  // Ensure that the triggering outcome is only set for eligible and
+  // non-holdback attempts.
+  DCHECK_EQ(eligibility_, PreloadingEligibility::kEligible);
+  DCHECK_EQ(holdback_status_, PreloadingHoldbackStatus::kAllowed);
   // Check that we do the correct transition before setting
   // `triggering_outcome_`.
   DCHECKTriggeringOutcomeTransitions(/*old_state=*/triggering_outcome_,
@@ -65,10 +87,14 @@
   triggering_outcome_ = triggering_outcome;
 }
 
-void PreloadingAttemptImpl::SetFailureReason(int64_t reason) {
-  // Value of failure reason should be greater than zero, as zero in
-  // FailureReason represents success.
-  DCHECK_GT(reason, 0);
+void PreloadingAttemptImpl::SetFailureReason(PreloadingFailureReason reason) {
+  // Ensure that the failure reason is only set once and is only set for
+  // eligible and non-holdback attempts.
+  DCHECK_EQ(eligibility_, PreloadingEligibility::kEligible);
+  DCHECK_EQ(holdback_status_, PreloadingHoldbackStatus::kAllowed);
+  DCHECK_EQ(failure_reason_, PreloadingFailureReason::kUnspecified);
+  DCHECK_NE(reason, PreloadingFailureReason::kUnspecified);
+  SetTriggeringOutcome(PreloadingTriggeringOutcome::kFailure);
   failure_reason_ = reason;
 }
 
@@ -107,8 +133,9 @@
         .SetPreloadingType(static_cast<int64_t>(preloading_type_))
         .SetPreloadingPredictor(static_cast<int64_t>(predictor_type_))
         .SetEligibility(static_cast<int64_t>(eligibility_))
+        .SetHoldbackStatus(static_cast<int64_t>(holdback_status_))
         .SetTriggeringOutcome(static_cast<int64_t>(triggering_outcome_))
-        .SetFailureReason(failure_reason_)
+        .SetFailureReason(static_cast<int64_t>(failure_reason_))
         .SetAccurateTriggering(accurate_triggering)
         .Record(ukm_recorder);
   }
@@ -119,8 +146,9 @@
         .SetPreloadingType(static_cast<int64_t>(preloading_type_))
         .SetPreloadingPredictor(static_cast<int64_t>(predictor_type_))
         .SetEligibility(static_cast<int64_t>(eligibility_))
+        .SetHoldbackStatus(static_cast<int64_t>(holdback_status_))
         .SetTriggeringOutcome(static_cast<int64_t>(triggering_outcome_))
-        .SetFailureReason(failure_reason_)
+        .SetFailureReason(static_cast<int64_t>(failure_reason_))
         .SetAccurateTriggering(accurate_triggering)
         .Record(ukm_recorder);
   }
@@ -133,9 +161,6 @@
     case PreloadingTriggeringOutcome::kUnspecified:
       os << "Unspecified";
       break;
-    case PreloadingTriggeringOutcome::kNotTriggered:
-      os << "NotTriggered";
-      break;
     case PreloadingTriggeringOutcome::kDuplicate:
       os << "Duplicate";
       break;
@@ -151,6 +176,9 @@
     case PreloadingTriggeringOutcome::kFailure:
       os << "Failure";
       break;
+    case PreloadingTriggeringOutcome::kTriggeredButOutcomeUnknown:
+      os << "TriggeredButOutcomeUnknown";
+      break;
   }
   return os;
 }
diff --git a/content/browser/preloading_attempt_impl.h b/content/browser/preloading_attempt_impl.h
index 0d854ddd..d02417a 100644
--- a/content/browser/preloading_attempt_impl.h
+++ b/content/browser/preloading_attempt_impl.h
@@ -5,6 +5,7 @@
 #ifndef CONTENT_BROWSER_PRELOADING_ATTEMPT_IMPL_H_
 #define CONTENT_BROWSER_PRELOADING_ATTEMPT_IMPL_H_
 
+#include "content/public/browser/preloading.h"
 #include "content/public/browser/preloading_data.h"
 
 #include "services/metrics/public/cpp/ukm_source_id.h"
@@ -18,6 +19,7 @@
 
   // PreloadingAttempt implementation:
   void SetEligibility(PreloadingEligibility eligibility) override;
+  void SetHoldbackStatus(PreloadingHoldbackStatus holdback_status) override;
   void SetTriggeringOutcome(
       PreloadingTriggeringOutcome triggering_outcome) override;
 
@@ -32,9 +34,9 @@
   void RecordPreloadingAttemptUKMs(ukm::SourceId navigated_page,
                                    const GURL& navigated_url);
 
-  // Sets the specific failure reason specific to the PreloadingType once the
-  // PreloadingTriggeringOutcome is set to kFailure.
-  void SetFailureReason(int64_t reason);
+  // Sets the specific failure reason specific to the PreloadingType. This also
+  // sets the PreloadingTriggeringOutcome to kFailure.
+  void SetFailureReason(PreloadingFailureReason reason);
 
   explicit PreloadingAttemptImpl(
       PreloadingPredictor predictor,
@@ -47,11 +49,15 @@
   // preloading logging reason. Zero as a failure reason signifies no reason is
   // specified. This value is casted from preloading specific enum to int64_t
   // instead of having an enum declaration for each case.
-  int64_t failure_reason_ = 0;
+  PreloadingFailureReason failure_reason_ =
+      PreloadingFailureReason::kUnspecified;
 
   // Specifies the eligibility status for this PreloadingAttempt.
   PreloadingEligibility eligibility_ = PreloadingEligibility::kUnspecified;
 
+  PreloadingHoldbackStatus holdback_status_ =
+      PreloadingHoldbackStatus::kUnspecified;
+
   // Specifies the triggering outcome for this PreloadingAttempt.
   PreloadingTriggeringOutcome triggering_outcome_ =
       PreloadingTriggeringOutcome::kUnspecified;
diff --git a/content/browser/renderer_host/input/input_router_impl.cc b/content/browser/renderer_host/input/input_router_impl.cc
index 3c280031..2ab5afb 100644
--- a/content/browser/renderer_host/input/input_router_impl.cc
+++ b/content/browser/renderer_host/input/input_router_impl.cc
@@ -176,6 +176,15 @@
     return;
   }
 
+  // Handle scroll gesture events for stylus writing. If we could not start
+  // writing for any reason, we should not filter the scroll events.
+  if (HandleGestureScrollForStylusWriting(gesture_event.event)) {
+    disposition_handler_->OnGestureEventAck(
+        gesture_event, blink::mojom::InputEventResultSource::kBrowser,
+        blink::mojom::InputEventResultState::kConsumed);
+    return;
+  }
+
   wheel_event_queue_.OnGestureScrollEvent(gesture_event);
 
   if (gesture_event.event.SourceDevice() ==
@@ -210,6 +219,60 @@
   }
 }
 
+bool InputRouterImpl::HandleGestureScrollForStylusWriting(
+    const blink::WebGestureEvent& event) {
+  switch (event.GetType()) {
+    case WebInputEvent::Type::kGestureScrollBegin: {
+      if (event.data.scroll_begin.pointer_count != 1)
+        break;
+
+      const float& deltaXHint = event.data.scroll_begin.delta_x_hint;
+      const float& deltaYHint = event.data.scroll_begin.delta_y_hint;
+      if (deltaXHint == 0.0 && deltaYHint == 0.0)
+        break;
+
+      if (!client_->GetRenderWidgetHostViewBase())
+        break;
+
+      absl::optional<cc::TouchAction> allowed_touch_action =
+          AllowedTouchAction();
+      // Don't handle for non-writable areas as kInternalNotWritable bit is set.
+      if (!allowed_touch_action.has_value() ||
+          (allowed_touch_action.value() &
+           cc::TouchAction::kInternalNotWritable) ==
+              cc::TouchAction::kInternalNotWritable)
+        break;
+
+      // Request to start stylus writing as we have detected stylus writing
+      // movement, and treat scroll gesture as stylus input if started.
+      if (client_->GetRenderWidgetHostViewBase()->RequestStartStylusWriting()) {
+        stylus_writing_started_ = true;
+        // The below call is done to Focus the stylus writable input element.
+        client_->OnStartStylusWriting();
+        return true;
+      }
+      break;
+    }
+    case WebInputEvent::Type::kGestureScrollUpdate:
+      // TODO(crbug.com/1330817): Pass the queued scroll delta to stylus
+      // writing recognition system.
+      return stylus_writing_started_;
+    case WebInputEvent::Type::kGestureScrollEnd: {
+      // When stylus writing starts, Touch Move events would be forwarded to
+      // stylus recognition system and gesture detection would be reset. We
+      // would receive the GestureScrollEnd here after that.
+      if (stylus_writing_started_) {
+        stylus_writing_started_ = false;
+        return true;
+      }
+      break;
+    }
+    default:
+      break;
+  }
+  return false;
+}
+
 void InputRouterImpl::SendTouchEvent(
     const TouchEventWithLatencyInfo& touch_event) {
   TouchEventWithLatencyInfo updated_touch_event = touch_event;
diff --git a/content/browser/renderer_host/input/input_router_impl.h b/content/browser/renderer_host/input/input_router_impl.h
index 3ecc630c..f7c7e77e 100644
--- a/content/browser/renderer_host/input/input_router_impl.h
+++ b/content/browser/renderer_host/input/input_router_impl.h
@@ -22,6 +22,7 @@
 #include "content/browser/renderer_host/input/passthrough_touch_event_queue.h"
 #include "content/browser/renderer_host/input/touch_action_filter.h"
 #include "content/browser/renderer_host/input/touchpad_pinch_event_queue.h"
+#include "content/browser/renderer_host/render_widget_host_view_base.h"
 #include "content/common/content_export.h"
 #include "content/common/input/input_event_stream_validator.h"
 #include "content/public/browser/native_web_keyboard_event.h"
@@ -47,6 +48,8 @@
   virtual void OnImeCompositionRangeChanged(
       const gfx::Range& range,
       const std::vector<gfx::Rect>& bounds) = 0;
+  virtual RenderWidgetHostViewBase* GetRenderWidgetHostViewBase() = 0;
+  virtual void OnStartStylusWriting() = 0;
 };
 
 // A default implementation for browser input event routing.
@@ -182,6 +185,8 @@
       blink::mojom::InputEventResultSource ack_source,
       blink::mojom::InputEventResultState ack_result) override;
 
+  bool HandleGestureScrollForStylusWriting(const blink::WebGestureEvent& event);
+
   void FilterAndSendWebInputEvent(
       const blink::WebInputEvent& input_event,
       const ui::LatencyInfo& latency_info,
@@ -242,6 +247,9 @@
   // gesture scroll yet.
   bool touch_scroll_started_sent_;
 
+  // Whether stylus writing has started.
+  bool stylus_writing_started_ = false;
+
   MouseWheelEventQueue wheel_event_queue_;
   PassthroughTouchEventQueue touch_event_queue_;
   TouchpadPinchEventQueue touchpad_pinch_event_queue_;
diff --git a/content/browser/renderer_host/input/input_router_impl_unittest.cc b/content/browser/renderer_host/input/input_router_impl_unittest.cc
index 3e4d7c6..1c942237 100644
--- a/content/browser/renderer_host/input/input_router_impl_unittest.cc
+++ b/content/browser/renderer_host/input/input_router_impl_unittest.cc
@@ -26,14 +26,19 @@
 #include "content/browser/renderer_host/input/input_router_client.h"
 #include "content/browser/renderer_host/input/mock_input_disposition_handler.h"
 #include "content/browser/renderer_host/input/mock_input_router_client.h"
+#include "content/browser/renderer_host/mock_render_widget_host.h"
+#include "content/browser/site_instance_group.h"
 #include "content/common/content_constants_internal.h"
 #include "content/public/common/content_features.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/test/browser_task_environment.h"
 #include "content/public/test/mock_render_process_host.h"
 #include "content/public/test/test_browser_context.h"
+#include "content/test/mock_render_widget_host_delegate.h"
 #include "content/test/mock_widget_input_handler.h"
+#include "content/test/test_render_view_host.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/features.h"
 #include "third_party/blink/public/common/input/synthetic_web_input_event_builders.h"
 #include "third_party/blink/public/mojom/input/touch_event.mojom.h"
 #include "ui/events/base_event_utils.h"
@@ -94,6 +99,23 @@
 
 }  // namespace
 
+class MockRenderWidgetHostViewForStylusWriting
+    : public TestRenderWidgetHostView {
+ public:
+  MockRenderWidgetHostViewForStylusWriting(RenderWidgetHost* host)
+      : TestRenderWidgetHostView(host) {}
+  ~MockRenderWidgetHostViewForStylusWriting() override = default;
+
+  bool RequestStartStylusWriting() override { return supports_stylus_writing_; }
+
+  void set_supports_stylus_writing(bool supports) {
+    supports_stylus_writing_ = supports;
+  }
+
+ private:
+  bool supports_stylus_writing_ = false;
+};
+
 // TODO(dtapuska): Remove this class when we don't have multiple implementations
 // of InputRouters.
 class MockInputRouterImplClient : public InputRouterImplClient {
@@ -108,6 +130,14 @@
 
   void OnImeCancelComposition() override {}
 
+  RenderWidgetHostViewBase* GetRenderWidgetHostViewBase() override {
+    return render_widget_host_view_;
+  }
+
+  void OnStartStylusWriting() override {
+    on_start_stylus_writing_called_ = true;
+  }
+
   void SetMouseCapture(bool capture) override {}
 
   void RequestMouseLock(
@@ -207,9 +237,18 @@
   const blink::WebInputEvent* last_filter_event() const {
     return input_router_client_.last_filter_event();
   }
+  bool on_start_stylus_writing_called() {
+    return on_start_stylus_writing_called_;
+  }
+  void set_render_widget_host_view(
+      MockRenderWidgetHostViewForStylusWriting* view) {
+    render_widget_host_view_ = view;
+  }
 
   MockInputRouterClient input_router_client_;
   MockWidgetInputHandler widget_input_handler_;
+  MockRenderWidgetHostViewForStylusWriting* render_widget_host_view_;
+  bool on_start_stylus_writing_called_ = false;
 };
 
 class InputRouterImplTestBase : public testing::Test {
@@ -234,6 +273,23 @@
 
     client_->set_input_router(input_router());
     disposition_handler_->set_input_router(input_router());
+
+    browser_context_ = std::make_unique<TestBrowserContext>();
+    process_host_ =
+        std::make_unique<MockRenderProcessHost>(browser_context_.get());
+    site_instance_group_ = base::WrapRefCounted(new SiteInstanceGroup(
+        SiteInstanceImpl::NextBrowsingInstanceId(), process_host_.get()));
+    widget_host_ = MakeNewWidgetHost();
+    mock_view_ =
+        new MockRenderWidgetHostViewForStylusWriting(widget_host_.get());
+    client_->set_render_widget_host_view(mock_view_.get());
+  }
+
+  std::unique_ptr<RenderWidgetHostImpl> MakeNewWidgetHost() {
+    int32_t routing_id = process_host_->GetNextRoutingID();
+    return MockRenderWidgetHost::Create(
+        /*frame_tree=*/nullptr, &delegate_, site_instance_group_->GetSafeRef(),
+        routing_id);
   }
 
   void TearDown() override {
@@ -242,6 +298,12 @@
 
     input_router_.reset();
     client_.reset();
+    if (mock_view_)
+      delete mock_view_;
+    widget_host_ = nullptr;
+    process_host_->Cleanup();
+    site_instance_group_.reset();
+    process_host_ = nullptr;
   }
 
   void SetUpForTouchAckTimeoutTest(int desktop_timeout_ms,
@@ -442,6 +504,15 @@
     disposition_handler_->GetAndResetAckCount();
   }
 
+  void PressAndSetTouchActionWritable() {
+    PressTouchPoint(1, 1);
+    SendTouchEvent();
+    input_router_->SetTouchActionFromMain(
+        cc::TouchAction::kAuto & ~cc::TouchAction::kInternalNotWritable);
+    GetAndResetDispatchedMessages();
+    disposition_handler_->GetAndResetAckCount();
+  }
+
   void TouchActionSetFromMainNotOverridden() {
     input_router_->SetTouchActionFromMain(cc::TouchAction::kAuto);
     ASSERT_TRUE(input_router_->AllowedTouchAction().has_value());
@@ -514,10 +585,16 @@
   std::unique_ptr<MockInputRouterImplClient> client_;
   std::unique_ptr<InputRouterImpl> input_router_;
   std::unique_ptr<MockInputDispositionHandler> disposition_handler_;
+  raw_ptr<MockRenderWidgetHostViewForStylusWriting> mock_view_;
 
  private:
   content::BrowserTaskEnvironment task_environment_;
   SyntheticWebTouchEvent touch_event_;
+  std::unique_ptr<BrowserContext> browser_context_;
+  std::unique_ptr<MockRenderProcessHost> process_host_;
+  scoped_refptr<SiteInstanceGroup> site_instance_group_;
+  std::unique_ptr<RenderWidgetHostImpl> widget_host_;
+  MockRenderWidgetHostDelegate delegate_;
 };
 
 class InputRouterImplTest : public InputRouterImplTestBase {
@@ -2215,6 +2292,185 @@
 
 namespace {
 
+class InputRouterImplStylusWritingTest : public InputRouterImplTest {
+ public:
+  InputRouterImplStylusWritingTest() {
+    feature_list_.InitWithFeatures({blink::features::kStylusWritingToInput},
+                                   {});
+  }
+
+ private:
+  base::test::ScopedFeatureList feature_list_;
+};
+
+}  // namespace
+
+// Tests that stylus writing is not started when touch action is not writable.
+TEST_F(InputRouterImplStylusWritingTest,
+       StylusWritingNotStartedForNotWritableTouchAction) {
+  PressAndSetTouchActionAuto();
+
+  // Set RequestStartStylusWriting() to return true, to ensure scroll events are
+  // not filtered when touch action is not writable.
+  mock_view_->set_supports_stylus_writing(true);
+  ASSERT_TRUE(
+      client_->GetRenderWidgetHostViewBase()->RequestStartStylusWriting());
+  SimulateGestureEvent(SyntheticWebGestureEventBuilder::BuildScrollBegin(
+      2.f, 2.f, blink::WebGestureDevice::kTouchscreen, /* pointer_count */ 1));
+  // scroll begin is not filtered when kInternalNotWritable is set.
+  DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
+  ASSERT_EQ(1U, dispatched_messages.size());
+  EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
+  ASSERT_FALSE(client_->on_start_stylus_writing_called());
+}
+
+// Tests that stylus writing is not started when touch action is writable, but
+// request to start stylus writing returned false.
+TEST_F(InputRouterImplStylusWritingTest,
+       StylusWritingNotStartedForTouchActionWritable) {
+  PressAndSetTouchActionWritable();
+
+  // RequestStartStylusWriting() returns false by default.
+  ASSERT_FALSE(
+      client_->GetRenderWidgetHostViewBase()->RequestStartStylusWriting());
+  SimulateGestureEvent(SyntheticWebGestureEventBuilder::BuildScrollBegin(
+      2.f, 2.f, blink::WebGestureDevice::kTouchscreen, /* pointer_count */ 1));
+  DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
+  ASSERT_EQ(1U, dispatched_messages.size());
+  ASSERT_TRUE(dispatched_messages[0]->ToEvent());
+  dispatched_messages[0]->ToEvent()->CallCallback(
+      blink::mojom::InputEventResultState::kConsumed);
+  EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
+  EXPECT_EQ(WebInputEvent::Type::kGestureScrollBegin,
+            disposition_handler_->ack_event_type());
+  ASSERT_FALSE(client_->on_start_stylus_writing_called());
+
+  SimulateGestureEvent(WebInputEvent::Type::kGestureScrollUpdate,
+                       blink::WebGestureDevice::kTouchscreen);
+  dispatched_messages = GetAndResetDispatchedMessages();
+  // This dispatches TouchScrollStarted and GestureScrollUpdate.
+  ASSERT_EQ(2U, dispatched_messages.size());
+  EXPECT_EQ(WebInputEvent::Type::kTouchScrollStarted,
+            dispatched_messages[0]->ToEvent()->Event()->Event().GetType());
+  EXPECT_EQ(WebInputEvent::Type::kGestureScrollUpdate,
+            dispatched_messages[1]->ToEvent()->Event()->Event().GetType());
+  dispatched_messages[1]->ToEvent()->CallCallback(
+      blink::mojom::InputEventResultState::kConsumed);
+  EXPECT_EQ(WebInputEvent::Type::kGestureScrollUpdate,
+            disposition_handler_->ack_event_type());
+  EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
+
+  SimulateGestureEvent(WebInputEvent::Type::kGestureScrollEnd,
+                       blink::WebGestureDevice::kTouchscreen);
+  dispatched_messages = GetAndResetDispatchedMessages();
+  ASSERT_EQ(1U, dispatched_messages.size());
+  ASSERT_TRUE(dispatched_messages[0]->ToEvent());
+  dispatched_messages[0]->ToEvent()->CallCallback(
+      blink::mojom::InputEventResultState::kConsumed);
+  EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
+  EXPECT_EQ(WebInputEvent::Type::kGestureScrollEnd,
+            disposition_handler_->ack_event_type());
+}
+
+// Tests that stylus writing is not started when touch action is writable,
+// request to start stylus writing returns true but pointer count is more
+// than 1.
+TEST_F(InputRouterImplStylusWritingTest, StylusWritingNotStartedForMultiTouch) {
+  PressAndSetTouchActionWritable();
+
+  // Set RequestStartStylusWriting() to return true.
+  mock_view_->set_supports_stylus_writing(true);
+  ASSERT_TRUE(
+      client_->GetRenderWidgetHostViewBase()->RequestStartStylusWriting());
+  SimulateGestureEvent(SyntheticWebGestureEventBuilder::BuildScrollBegin(
+      2.f, 2.f, blink::WebGestureDevice::kTouchscreen, /* pointer_count */ 2));
+  DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
+  // Scroll begin is not filtered when pointer count is 2.
+  ASSERT_EQ(1U, dispatched_messages.size());
+  EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
+  // Message not sent to client that stylus writing has been started.
+  ASSERT_FALSE(client_->on_start_stylus_writing_called());
+}
+
+// Tests that stylus writing is started when touch action is writable, and
+// request to start stylus writing returns true, and pointer count is 1.
+TEST_F(InputRouterImplStylusWritingTest,
+       StylusWritingStartedForTouchActionWritable) {
+  PressAndSetTouchActionWritable();
+
+  // Set RequestStartStylusWriting() to return true.
+  mock_view_->set_supports_stylus_writing(true);
+  ASSERT_TRUE(
+      client_->GetRenderWidgetHostViewBase()->RequestStartStylusWriting());
+  // GestureScrollBegin is filtered.
+  SimulateGestureEvent(SyntheticWebGestureEventBuilder::BuildScrollBegin(
+      2.f, 2.f, blink::WebGestureDevice::kTouchscreen, /* pointer_count */ 1));
+  DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
+  ASSERT_EQ(0U, dispatched_messages.size());
+  EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
+  EXPECT_EQ(WebInputEvent::Type::kGestureScrollBegin,
+            disposition_handler_->ack_event_type());
+  // Message sent to client that stylus writing has been started.
+  ASSERT_TRUE(client_->on_start_stylus_writing_called());
+
+  // GestureScrollUpdate and GestureScrollEnd are also filtered.
+  SimulateGestureEvent(WebInputEvent::Type::kGestureScrollUpdate,
+                       blink::WebGestureDevice::kTouchscreen);
+  dispatched_messages = GetAndResetDispatchedMessages();
+  ASSERT_EQ(0U, dispatched_messages.size());
+  EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
+  EXPECT_EQ(WebInputEvent::Type::kGestureScrollUpdate,
+            disposition_handler_->ack_event_type());
+
+  SimulateGestureEvent(WebInputEvent::Type::kGestureScrollEnd,
+                       blink::WebGestureDevice::kTouchscreen);
+  dispatched_messages = GetAndResetDispatchedMessages();
+  ASSERT_EQ(0U, dispatched_messages.size());
+  EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
+  EXPECT_EQ(WebInputEvent::Type::kGestureScrollEnd,
+            disposition_handler_->ack_event_type());
+}
+
+// Tests that GestureScrollBegin is filtered even if compositor touch action
+// allows scroll.
+TEST_F(InputRouterImplStylusWritingTest,
+       StylusWritingFiltersGSBEvenWhenCompositorTouchActionAllows) {
+  auto touch_event_consumers = blink::mojom::TouchEventConsumers::New(
+      HasTouchEventHandlers(true), HasHitTestableScrollbar(false));
+  OnHasTouchEventConsumers(std::move(touch_event_consumers));
+  // Send a touchstart
+  PressTouchPoint(1, 1);
+  SendTouchEvent();
+  DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
+  ASSERT_EQ(1U, dispatched_messages.size());
+  ASSERT_TRUE(dispatched_messages[0]->ToEvent());
+  absl::optional<cc::TouchAction> expected_touch_action = cc::TouchAction::kPan;
+  dispatched_messages[0]->ToEvent()->CallCallback(
+      blink::mojom::InputEventResultSource::kCompositorThread,
+      ui::LatencyInfo(), blink::mojom::InputEventResultState::kNotConsumed,
+      nullptr, blink::mojom::TouchActionOptional::New(cc::TouchAction::kPan));
+  ASSERT_EQ(1U, disposition_handler_->GetAndResetAckCount());
+  absl::optional<cc::TouchAction> allowed_touch_action = AllowedTouchAction();
+  cc::TouchAction compositor_allowed_touch_action =
+      CompositorAllowedTouchAction();
+  EXPECT_FALSE(allowed_touch_action.has_value());
+  EXPECT_EQ(expected_touch_action.value(), compositor_allowed_touch_action);
+
+  // GestureScrollBegin is filtered until we get touch action from Main.
+  SimulateGestureEvent(SyntheticWebGestureEventBuilder::BuildScrollBegin(
+      2.f, 2.f, blink::WebGestureDevice::kTouchscreen, /* pointer_count */ 1));
+  dispatched_messages = GetAndResetDispatchedMessages();
+  ASSERT_EQ(0U, dispatched_messages.size());
+
+  input_router_->SetTouchActionFromMain(cc::TouchAction::kAuto);
+  allowed_touch_action = AllowedTouchAction();
+  EXPECT_TRUE(allowed_touch_action.has_value());
+  dispatched_messages = GetAndResetDispatchedMessages();
+  ASSERT_EQ(1U, dispatched_messages.size());
+}
+
+namespace {
+
 class InputRouterImplScaleEventTest : public InputRouterImplTestBase {
  public:
   InputRouterImplScaleEventTest() {}
diff --git a/content/browser/renderer_host/input/touch_action_filter.cc b/content/browser/renderer_host/input/touch_action_filter.cc
index 0468ab64..6e3bc94 100644
--- a/content/browser/renderer_host/input/touch_action_filter.cc
+++ b/content/browser/renderer_host/input/touch_action_filter.cc
@@ -12,6 +12,7 @@
 #include "base/notreached.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/trace_event/trace_event.h"
+#include "third_party/blink/public/common/features.h"
 #include "third_party/blink/public/common/input/web_gesture_event.h"
 #include "ui/events/blink/blink_features.h"
 
@@ -429,6 +430,16 @@
   const float absDeltaXHint = fabs(deltaXHint);
   const float absDeltaYHint = fabs(deltaYHint);
 
+  // We need to wait for main-thread touch action to see if touch region is
+  // writable for stylus handwriting, and accumulate scroll events until then.
+  // TODO(mahesh.ma): Wait for main-thread action only if stylus writing service
+  // is enabled. Replace Feature flag with a configurable setting.
+  if (base::FeatureList::IsEnabled(blink::features::kStylusWritingToInput) &&
+      !is_active_touch_action &&
+      (touch_action & cc::TouchAction::kInternalNotWritable) !=
+          cc::TouchAction::kInternalNotWritable)
+    return true;
+
   cc::TouchAction minimal_conforming_touch_action = cc::TouchAction::kNone;
   if (absDeltaXHint > absDeltaYHint) {
     // If we're performing a horizontal gesture over a region that could
diff --git a/content/browser/renderer_host/input/touch_action_filter_unittest.cc b/content/browser/renderer_host/input/touch_action_filter_unittest.cc
index 8c0aa4cc..84217ecc 100644
--- a/content/browser/renderer_host/input/touch_action_filter_unittest.cc
+++ b/content/browser/renderer_host/input/touch_action_filter_unittest.cc
@@ -541,12 +541,14 @@
             cc::TouchAction::kAuto & cc::TouchAction::kPan);
   EXPECT_EQ(cc::TouchAction::kManipulation,
             cc::TouchAction::kAuto & ~(cc::TouchAction::kDoubleTapZoom |
-                                       cc::TouchAction::kInternalPanXScrolls));
+                                       cc::TouchAction::kInternalPanXScrolls |
+                                       cc::TouchAction::kInternalNotWritable));
   EXPECT_EQ(cc::TouchAction::kPanX,
             cc::TouchAction::kPanLeft | cc::TouchAction::kPanRight);
   EXPECT_EQ(cc::TouchAction::kAuto, cc::TouchAction::kManipulation |
                                         cc::TouchAction::kDoubleTapZoom |
-                                        cc::TouchAction::kInternalPanXScrolls);
+                                        cc::TouchAction::kInternalPanXScrolls |
+                                        cc::TouchAction::kInternalNotWritable);
 }
 
 TEST_F(TouchActionFilterTest, MultiTouch) {
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index 18133ca..e3a14e47a 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -2888,6 +2888,15 @@
     view_->ImeCancelComposition();
 }
 
+RenderWidgetHostViewBase* RenderWidgetHostImpl::GetRenderWidgetHostViewBase() {
+  return GetView();
+}
+
+void RenderWidgetHostImpl::OnStartStylusWriting() {
+  if (blink_frame_widget_)
+    blink_frame_widget_->OnStartStylusWriting();
+}
+
 bool RenderWidgetHostImpl::IsWheelScrollInProgress() {
   return is_in_gesture_scroll_[static_cast<int>(
       blink::WebGestureDevice::kTouchpad)];
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h
index a46a7aa..e617a44 100644
--- a/content/browser/renderer_host/render_widget_host_impl.h
+++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -760,6 +760,8 @@
       const gfx::Range& range,
       const std::vector<gfx::Rect>& character_bounds) override;
   void OnImeCancelComposition() override;
+  RenderWidgetHostViewBase* GetRenderWidgetHostViewBase() override;
+  void OnStartStylusWriting() override;
   bool IsWheelScrollInProgress() override;
   bool IsAutoscrollInProgress() override;
   void SetMouseCapture(bool capture) override;
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc
index 17c320b2..e805aaede3 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -1090,7 +1090,13 @@
     bool is_editable_node,
     const gfx::Rect& node_bounds_in_screen) {
   if (ime_adapter_android_)
-    ime_adapter_android_->FocusedNodeChanged(is_editable_node);
+    ime_adapter_android_->FocusedNodeChanged(is_editable_node,
+                                             node_bounds_in_screen);
+}
+
+bool RenderWidgetHostViewAndroid::RequestStartStylusWriting() {
+  return ime_adapter_android_ &&
+         ime_adapter_android_->RequestStartStylusWriting();
 }
 
 void RenderWidgetHostViewAndroid::RenderProcessGone() {
diff --git a/content/browser/renderer_host/render_widget_host_view_android.h b/content/browser/renderer_host/render_widget_host_view_android.h
index ab53db2a..08768d4 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.h
+++ b/content/browser/renderer_host/render_widget_host_view_android.h
@@ -142,6 +142,7 @@
   void SetIsLoading(bool is_loading) override;
   void FocusedNodeChanged(bool is_editable_node,
                           const gfx::Rect& node_bounds_in_screen) override;
+  bool RequestStartStylusWriting() override;
   void RenderProcessGone() override;
   void ShowWithVisibility(PageVisibilityState page_visibility) final;
   void Destroy() override;
diff --git a/content/browser/renderer_host/render_widget_host_view_base.cc b/content/browser/renderer_host/render_widget_host_view_base.cc
index edcca00..1bb9760 100644
--- a/content/browser/renderer_host/render_widget_host_view_base.cc
+++ b/content/browser/renderer_host/render_widget_host_view_base.cc
@@ -499,6 +499,10 @@
   return nullptr;
 }
 
+bool RenderWidgetHostViewBase::RequestStartStylusWriting() {
+  return false;
+}
+
 bool RenderWidgetHostViewBase::RequestRepaintForTesting() {
   return false;
 }
diff --git a/content/browser/renderer_host/render_widget_host_view_base.h b/content/browser/renderer_host/render_widget_host_view_base.h
index 912e238..2f7dabc3 100644
--- a/content/browser/renderer_host/render_widget_host_view_base.h
+++ b/content/browser/renderer_host/render_widget_host_view_base.h
@@ -245,6 +245,9 @@
   virtual void FocusedNodeChanged(bool is_editable_node,
                                   const gfx::Rect& node_bounds_in_screen) {}
 
+  // Requests to start stylus writing and returns true if successful.
+  virtual bool RequestStartStylusWriting();
+
   // This method will clear any cached fallback surface. For use in response to
   // a CommitPending where there is no content for TakeFallbackContentFrom.
   virtual void ClearFallbackSurfaceForCommitPending() {}
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc
index 35d6438..7c8d40d 100644
--- a/content/browser/site_per_process_browsertest.cc
+++ b/content/browser/site_per_process_browsertest.cc
@@ -12006,7 +12006,8 @@
   absl::optional<cc::TouchAction> effective_touch_action;
   absl::optional<cc::TouchAction> allowed_touch_action;
   cc::TouchAction expected_touch_action =
-      cc::TouchAction::kPan | cc::TouchAction::kInternalPanXScrolls;
+      cc::TouchAction::kPan | cc::TouchAction::kInternalPanXScrolls |
+      cc::TouchAction::kInternalNotWritable;
   GetTouchActionsForChild(router, rwhv_root, rwhv_child, point_inside_child,
                           effective_touch_action, allowed_touch_action);
   if (allowed_touch_action.has_value())
diff --git a/content/browser/speculation_rules/prefetch/prefetch_network_context_client.cc b/content/browser/speculation_rules/prefetch/prefetch_network_context_client.cc
index 8433319..6b21bc8 100644
--- a/content/browser/speculation_rules/prefetch/prefetch_network_context_client.cc
+++ b/content/browser/speculation_rules/prefetch/prefetch_network_context_client.cc
@@ -20,6 +20,7 @@
     int32_t process_id,
     bool async,
     const std::vector<base::FilePath>& file_paths,
+    const GURL& destination_url,
     OnFileUploadRequestedCallback callback) {
   std::move(callback).Run(net::ERR_ACCESS_DENIED, std::vector<base::File>());
 }
diff --git a/content/browser/speculation_rules/prefetch/prefetch_network_context_client.h b/content/browser/speculation_rules/prefetch/prefetch_network_context_client.h
index 4b636d4..9a927b5 100644
--- a/content/browser/speculation_rules/prefetch/prefetch_network_context_client.h
+++ b/content/browser/speculation_rules/prefetch/prefetch_network_context_client.h
@@ -25,6 +25,7 @@
   void OnFileUploadRequested(int32_t process_id,
                              bool async,
                              const std::vector<base::FilePath>& file_paths,
+                             const GURL& destination_url,
                              OnFileUploadRequestedCallback callback) override;
   void OnCanSendReportingReports(
       const std::vector<url::Origin>& origins,
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc
index 287f44b..63e6075 100644
--- a/content/browser/storage_partition_impl.cc
+++ b/content/browser/storage_partition_impl.cc
@@ -2006,9 +2006,10 @@
     int32_t process_id,
     bool async,
     const std::vector<base::FilePath>& file_paths,
+    const GURL& destination_url,
     OnFileUploadRequestedCallback callback) {
   NetworkContextOnFileUploadRequested(process_id, async, file_paths,
-                                      std::move(callback));
+                                      destination_url, std::move(callback));
 }
 
 void StoragePartitionImpl::OnCanSendReportingReports(
diff --git a/content/browser/storage_partition_impl.h b/content/browser/storage_partition_impl.h
index bcb666a6..1b836b6 100644
--- a/content/browser/storage_partition_impl.h
+++ b/content/browser/storage_partition_impl.h
@@ -283,6 +283,7 @@
   void OnFileUploadRequested(int32_t process_id,
                              bool async,
                              const std::vector<base::FilePath>& file_paths,
+                             const GURL& destination_url,
                              OnFileUploadRequestedCallback callback) override;
   void OnCanSendReportingReports(
       const std::vector<url::Origin>& origins,
diff --git a/content/browser/webrtc/webrtc_getusermedia_browsertest.cc b/content/browser/webrtc/webrtc_getusermedia_browsertest.cc
index 4cca073..4827e07f 100644
--- a/content/browser/webrtc/webrtc_getusermedia_browsertest.cc
+++ b/content/browser/webrtc/webrtc_getusermedia_browsertest.cc
@@ -517,8 +517,16 @@
 }
 
 // This test calls getUserMedia and checks for aspect ratio behavior.
+// TODO(1337302): Flaky for tsan, mac, lacros.
+#if defined(THREAD_SANITIZER) || BUILDFLAG(IS_MAC) || \
+    BUILDFLAG(IS_CHROMEOS_LACROS)
+#define MAYBE_TestGetUserMediaAspectRatio4To3 \
+  DISABLED_TestGetUserMediaAspectRatio4To3
+#else
+#define MAYBE_TestGetUserMediaAspectRatio4To3 TestGetUserMediaAspectRatio4To3
+#endif
 IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
-                       TestGetUserMediaAspectRatio4To3) {
+                       MAYBE_TestGetUserMediaAspectRatio4To3) {
   ASSERT_TRUE(embedded_test_server()->Start());
 
   GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
@@ -548,8 +556,16 @@
 }
 
 // This test calls getUserMedia and checks for aspect ratio behavior.
+// TODO(1337302): Flaky for tsan, mac, lacros.
+#if defined(THREAD_SANITIZER) || BUILDFLAG(IS_MAC) || \
+    BUILDFLAG(IS_CHROMEOS_LACROS)
+#define MAYBE_TestGetUserMediaAspectRatio1To1 \
+  DISABLED_TestGetUserMediaAspectRatio1To1
+#else
+#define MAYBE_TestGetUserMediaAspectRatio1To1 TestGetUserMediaAspectRatio1To1
+#endif
 IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
-                       TestGetUserMediaAspectRatio1To1) {
+                       MAYBE_TestGetUserMediaAspectRatio1To1) {
   ASSERT_TRUE(embedded_test_server()->Start());
 
   GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapterImpl.java b/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapterImpl.java
index 27bc5b96..ca57c354 100644
--- a/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapterImpl.java
+++ b/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapterImpl.java
@@ -971,7 +971,7 @@
     }
 
     @CalledByNative
-    private void focusedNodeChanged(boolean isEditable) {
+    private void focusedNodeChanged(boolean isEditable, int left, int top, int right, int bottom) {
         if (DEBUG_LOGS) Log.i(TAG, "focusedNodeChanged: isEditable [%b]", isEditable);
 
         // Update controller before the connection is restarted.
@@ -982,6 +982,14 @@
         if (mTextInputType != TextInputType.NONE && mInputConnection != null && isEditable) {
             mRestartInputOnNextStateUpdate = true;
         }
+
+        // TODO(mahesh.ma): Add Android stylus writing logic.
+    }
+
+    @CalledByNative
+    private boolean requestStartStylusWriting() {
+        // TODO(mahesh.ma): Add Android stylus writing logic.
+        return false;
     }
 
     /**
diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn
index c4d26406..abd02c0 100644
--- a/content/public/browser/BUILD.gn
+++ b/content/public/browser/BUILD.gn
@@ -455,6 +455,7 @@
     "//build:chromecast_buildflags",
     "//components/browsing_topics/common:common",
     "//components/download/public/common:public",
+    "//components/file_access",
     "//components/services/storage/privileged/mojom",
     "//components/services/storage/public/mojom",
     "//content/public/common:common_sources",
diff --git a/content/public/browser/DEPS b/content/public/browser/DEPS
index 7d232dd..47c2eee 100644
--- a/content/public/browser/DEPS
+++ b/content/public/browser/DEPS
@@ -3,6 +3,7 @@
   # components/download are needed for providing the download feature.
   # TODO(qinmin): move it to services/download when download becomes a service.
   "+components/download/public/common",
+  "+components/file_access",
   "+components/services/storage/privileged",
   "+components/services/storage/public",
   "+components/viz/common",
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
index c1beba6..9a593698 100644
--- a/content/public/browser/content_browser_client.cc
+++ b/content/public/browser/content_browser_client.cc
@@ -429,6 +429,15 @@
   // |browser_context| may be null (e.g. during shutdown of a service worker).
 }
 
+void ContentBrowserClient::RequestFilesAccess(
+    const std::vector<base::FilePath>& files,
+    const GURL& destination_url,
+    base::OnceCallback<void(file_access::ScopedFileAccess)>
+        continuation_callback) {
+  std::move(continuation_callback)
+      .Run(file_access::ScopedFileAccess::Allowed());
+}
+
 void ContentBrowserClient::AllowWorkerFileSystem(
     const GURL& url,
     BrowserContext* browser_context,
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index a497941..58755b9 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -24,6 +24,7 @@
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "components/download/public/common/quarantine_connection.h"
+#include "components/file_access/scoped_file_access.h"
 #include "content/common/content_export.h"
 #include "content/public/browser/allow_service_worker_result.h"
 #include "content/public/browser/certificate_request_result_type.h"
@@ -748,6 +749,15 @@
       BrowserContext* browser_context,
       blink::RendererPreferences* out_prefs);
 
+  // Requests access to |files| in order to be sent to |destination_url|.
+  // |continuation_callback| is called with a token that should be held until
+  // `open()` operation on the files is finished.
+  virtual void RequestFilesAccess(
+      const std::vector<base::FilePath>& files,
+      const GURL& destination_url,
+      base::OnceCallback<void(file_access::ScopedFileAccess)>
+          continuation_callback);
+
   // Allow the embedder to control if access to file system by a shared worker
   // is allowed.
   virtual void AllowWorkerFileSystem(
diff --git a/content/public/browser/network_context_client_base.h b/content/public/browser/network_context_client_base.h
index d43635b..93000f7 100644
--- a/content/public/browser/network_context_client_base.h
+++ b/content/public/browser/network_context_client_base.h
@@ -26,6 +26,7 @@
   void OnFileUploadRequested(int32_t process_id,
                              bool async,
                              const std::vector<base::FilePath>& file_paths,
+                             const GURL& destination_url,
                              OnFileUploadRequestedCallback callback) override;
   void OnCanSendReportingReports(
       const std::vector<url::Origin>& origins,
diff --git a/content/public/browser/preloading.h b/content/public/browser/preloading.h
index f220d102..1996fb6 100644
--- a/content/public/browser/preloading.h
+++ b/content/public/browser/preloading.h
@@ -20,8 +20,12 @@
   // which will be added later to PreloadingType as we expand.
   kUnspecified = 0,
 
-  // TODO(crbug.com/1309934): Add more preloading types from 1 - 3 as we
-  // integrate Preloading logging with various preloading types.
+  // TODO(crbug.com/1309934): Add preloading types 1 and 3 as we integrate
+  // Preloading logging with various preloading types.
+
+  // Establishes a connection (including potential TLS handshake) with an
+  // origin.
+  kPreconnect = 2,
 
   // This speedup technique comes with the most impact and overhead. We preload
   // and render a page before the user navigates to it. This will make the next
@@ -50,7 +54,8 @@
 
 // This constant is used to define the value from which embedders can add more
 // enums beyond this value. We mask it by 100 to avoid usage of the same numbers
-// for logging.
+// for logging. This constant determines the value of enumerations persisted
+// into logs so should not be changed.
 static constexpr int64_t kPreloadingPredictorContentEnd = 100;
 
 // Defines if a preloading operation is eligible for a given preloading
@@ -67,8 +72,34 @@
   // predictor.
   kEligible = 1,
 
-  // TODO(crbug.com/1309934): Add more specific ineligibility reasons subject to
-  // each preloading operation.
+  // Preloading operation was ineligible because preloading was disabled.
+  kPreloadingDisabled = 2,
+};
+
+// This constant is used to define the value from which embedders can add more
+// enums beyond this value.
+static constexpr int64_t kPreloadingEligibilityContentEnd = 100;
+
+// The outcome of the holdback check. This is not part of eligibility status to
+// clarify that this check needs to happen after we are done verifying the
+// eligibility of a preloading attempt. In general, eligibility checks can be
+// reordered, but the holdback check always needs to come after verifying that
+// the preloading attempt was eligible.
+
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused.
+enum class PreloadingHoldbackStatus {
+  // The preloading holdback status has not been set yet. This should only
+  // happen when the preloading attempt was not eligible.
+  kUnspecified = 0,
+
+  // The preload was eligible to be triggered and was not disabled via a field
+  // trial holdback. Given enough time, the preload will trigger.
+  kAllowed = 1,
+
+  // The preload was eligible to be triggered but was disabled via a field
+  // trial holdback. This is useful for measuring the impact of preloading.
+  kHoldback = 2,
 };
 
 // Defines the post-triggering outcome once the preloading operation is
@@ -77,13 +108,10 @@
 // These values are persisted to logs. Entries should not be renumbered and
 // numeric values should never be reused.
 enum class PreloadingTriggeringOutcome {
-  // No TriggeringOutcome is present.
+  // The outcome is kUnspecified for attempts that were not triggered due to
+  // various ineligibility reasons or due to a field trial holdback.
   kUnspecified = 0,
 
-  // Status is NotTriggered for attempts that were not triggered due to various
-  // ineligibility reasons.
-  kNotTriggered = 1,
-
   // For attempts that we wanted to trigger, but for which we already had an
   // equivalent attempt (same preloading operation and same URL/target) in
   // progress.
@@ -103,6 +131,18 @@
 
   // Preloading was triggered but encountered an error and failed.
   kFailure = 6,
+
+  // Some preloading features don't provide a way to keep track of the
+  // progression of the preloading attempt. In those cases, we just log
+  // kTriggeredButOutcomeUnknown, meaning that preloading was triggered but we
+  // don't know if it was successful.
+  kTriggeredButOutcomeUnknown = 7,
+};
+
+enum class PreloadingFailureReason {
+  // The failure reason is unspecified if the triggering outcome is not
+  // kFailure.
+  kUnspecified = 0,
 };
 
 }  // namespace content
diff --git a/content/public/browser/preloading_data.h b/content/public/browser/preloading_data.h
index 6be46cd5..8c3942da 100644
--- a/content/public/browser/preloading_data.h
+++ b/content/public/browser/preloading_data.h
@@ -39,8 +39,18 @@
   // called once per preloading attempt.
   virtual void SetEligibility(PreloadingEligibility eligibility) = 0;
 
-  // Updates the preload outcome after it was triggered.
-  // - Initially set to kNotTriggered.
+  // Sets the outcome of the holdback check used to implement counterfactual
+  // experiments. This is not part of eligibility status to clarify that this
+  // check needs to happen after we are done verifying the eligibility of a
+  // preloading attempt. In general, eligibility checks can be reordered, but
+  // the holdback check always needs to come after verifying that the preloading
+  // attempt was eligible. This must only be called after calling
+  // SetEligibility(kEligible) and should not be called more than once.
+  virtual void SetHoldbackStatus(PreloadingHoldbackStatus holdback_status) = 0;
+
+  // Updates the preload outcome after it was triggered. This should only be
+  // called for eligible attempts with a kAllowed holdback status.
+  // - Initially set to kUnspecified.
   // - After triggering this if there is already a preloading attempt available
   // for the same URL we set to kDuplicate, or
   // - kRunning (for preloading methods with given enough time, we expect to
diff --git a/content/public/test/DEPS b/content/public/test/DEPS
index d91839f..166beac 100644
--- a/content/public/test/DEPS
+++ b/content/public/test/DEPS
@@ -24,6 +24,7 @@
   "+components/services/storage/privileged",
   "+components/services/storage/public",
   "+components/startup_metric_utils/browser",
+  "+components/ukm/test_ukm_recorder.h",
   "+components/viz/client",
   "+components/viz/common",
   "+components/viz/host",
diff --git a/content/public/test/fake_frame_widget.h b/content/public/test/fake_frame_widget.h
index 50c2e9a..f6d43207 100644
--- a/content/public/test/fake_frame_widget.h
+++ b/content/public/test/fake_frame_widget.h
@@ -60,6 +60,7 @@
                          ui::mojom::DragOperation operation,
                          base::OnceClosure callback) override {}
   void DragSourceSystemDragEnded() override {}
+  void OnStartStylusWriting() override {}
   void SetBackgroundOpaque(bool value) override {}
   void SetTextDirection(base::i18n::TextDirection direction) override;
   void SetActive(bool active) override;
diff --git a/content/public/test/preloading_test_util.cc b/content/public/test/preloading_test_util.cc
new file mode 100644
index 0000000..6a134486
--- /dev/null
+++ b/content/public/test/preloading_test_util.cc
@@ -0,0 +1,87 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/public/test/preloading_test_util.h"
+
+#include "base/strings/stringprintf.h"
+#include "services/metrics/public/cpp/ukm_builders.h"
+
+namespace content::test {
+
+using UkmEntry = ukm::TestUkmRecorder::HumanReadableUkmEntry;
+using Preloading_Attempt = ukm::builders::Preloading_Attempt;
+
+const std::vector<std::string> kPreloadingAttemptUkmMetrics{
+    Preloading_Attempt::kPreloadingTypeName,
+    Preloading_Attempt::kPreloadingPredictorName,
+    Preloading_Attempt::kEligibilityName,
+    Preloading_Attempt::kHoldbackStatusName,
+    Preloading_Attempt::kTriggeringOutcomeName,
+    Preloading_Attempt::kAccurateTriggeringName,
+};
+
+PreloadingAttemptUkmEntryBuilder::PreloadingAttemptUkmEntryBuilder(
+    PreloadingType preloading_type,
+    PreloadingPredictor predictor)
+    : preloading_type_(preloading_type), predictor_(predictor) {}
+
+UkmEntry PreloadingAttemptUkmEntryBuilder::BuildEntry(
+    ukm::SourceId source_id,
+    PreloadingEligibility eligibility,
+    PreloadingHoldbackStatus holdback_status,
+    PreloadingTriggeringOutcome triggering_outcome,
+    bool accurate) const {
+  return UkmEntry{
+      source_id,
+      {
+          {Preloading_Attempt::kPreloadingTypeName,
+           static_cast<int64_t>(preloading_type_)},
+          {Preloading_Attempt::kPreloadingPredictorName,
+           static_cast<int64_t>(predictor_)},
+          {Preloading_Attempt::kEligibilityName,
+           static_cast<int64_t>(eligibility)},
+          {Preloading_Attempt::kHoldbackStatusName,
+           static_cast<int64_t>(holdback_status)},
+          {Preloading_Attempt::kTriggeringOutcomeName,
+           static_cast<int64_t>(triggering_outcome)},
+          {Preloading_Attempt::kAccurateTriggeringName, accurate ? 1 : 0},
+      }};
+}
+
+std::string UkmEntryToString(const UkmEntry& entry) {
+  std::string result;
+  result +=
+      base::StringPrintf("Source ID: %d\n", static_cast<int>(entry.source_id));
+  for (const auto& metric : entry.metrics) {
+    result += base::StringPrintf("Metric '%s' = %d\n", metric.first.c_str(),
+                                 static_cast<int>(metric.second));
+  }
+  result += "\n";
+  return result;
+}
+
+std::string ActualVsExpectedUkmEntryToString(const UkmEntry& actual,
+                                             const UkmEntry& expected) {
+  std::string result = "Actual UKM entry:\n";
+  result += UkmEntryToString(actual);
+  result += "Expected UKM entry:\n";
+  result += UkmEntryToString(expected);
+  return result;
+}
+
+std::string ActualVsExpectedUkmEntriesToString(
+    const std::vector<UkmEntry>& actual,
+    const std::vector<UkmEntry>& expected) {
+  std::string result = "Actual UKM entries:\n";
+  for (auto entry : actual) {
+    result += UkmEntryToString(entry);
+  }
+  result += "Expected UKM entries:\n";
+  for (auto entry : expected) {
+    result += UkmEntryToString(entry);
+  }
+  return result;
+}
+
+}  // namespace content::test
diff --git a/content/public/test/preloading_test_util.h b/content/public/test/preloading_test_util.h
new file mode 100644
index 0000000..ae3b8bb
--- /dev/null
+++ b/content/public/test/preloading_test_util.h
@@ -0,0 +1,55 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_PUBLIC_TEST_PRELOADING_TEST_UTIL_H_
+#define CONTENT_PUBLIC_TEST_PRELOADING_TEST_UTIL_H_
+
+#include <vector>
+
+#include "components/ukm/test_ukm_recorder.h"
+#include "content/public/browser/preloading.h"
+#include "services/metrics/public/cpp/ukm_source_id.h"
+
+namespace content::test {
+
+// The set of UKM metric names in the PreloadingAttempt UKM logs. This is
+// useful for calling TestUkmRecorder::GetEntries.
+extern const std::vector<std::string> kPreloadingAttemptUkmMetrics;
+
+// Utility class to make building expected
+// TestUkmRecorder::HumanReadableUkmEntry for EXPECT_EQ.
+class PreloadingAttemptUkmEntryBuilder {
+ public:
+  PreloadingAttemptUkmEntryBuilder(PreloadingType preloading_type,
+                                   PreloadingPredictor predictor);
+
+  ukm::TestUkmRecorder::HumanReadableUkmEntry BuildEntry(
+      ukm::SourceId source_id,
+      PreloadingEligibility eligibility,
+      PreloadingHoldbackStatus holdback_status,
+      PreloadingTriggeringOutcome triggering_outcome,
+      bool accurate) const;
+
+ private:
+  PreloadingType preloading_type_;
+  PreloadingPredictor predictor_;
+};
+
+// Turns a UKM entry into a human-readable string.
+std::string UkmEntryToString(
+    const ukm::TestUkmRecorder::HumanReadableUkmEntry& entry);
+
+// Turns two UKM entries into a human-readable string.
+std::string ActualVsExpectedUkmEntryToString(
+    const ukm::TestUkmRecorder::HumanReadableUkmEntry& actual,
+    const ukm::TestUkmRecorder::HumanReadableUkmEntry& expected);
+
+// Turns two collections of UKM entries into human-readable strings.
+std::string ActualVsExpectedUkmEntriesToString(
+    const std::vector<ukm::TestUkmRecorder::HumanReadableUkmEntry>& actual,
+    const std::vector<ukm::TestUkmRecorder::HumanReadableUkmEntry>& expected);
+
+}  // namespace content::test
+
+#endif  // CONTENT_PUBLIC_TEST_PRELOADING_TEST_UTIL_H_
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index 63ccc4f..cccba399 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -251,6 +251,8 @@
     "../public/test/permissions_test_utils.h",
     "../public/test/policy_container_utils.cc",
     "../public/test/policy_container_utils.h",
+    "../public/test/preloading_test_util.cc",
+    "../public/test/preloading_test_util.h",
     "../public/test/prerender_test_util.cc",
     "../public/test/prerender_test_util.h",
     "../public/test/private_network_access_util.cc",
@@ -499,6 +501,7 @@
     "//components/network_session_configurator/common:common",
     "//components/services/storage",
     "//components/startup_metric_utils/browser",
+    "//components/ukm:test_support",
     "//components/variations",
     "//components/viz/client",
     "//components/viz/host",
diff --git a/content/test/data/gpu/vc/video_utils.js b/content/test/data/gpu/vc/video_utils.js
index 59837c3..d526ae1d 100644
--- a/content/test/data/gpu/vc/video_utils.js
+++ b/content/test/data/gpu/vc/video_utils.js
@@ -254,9 +254,8 @@
 // If rAF is running at 60 fps, skip every other frame so the demo is
 // running at 30 fps.
 // 30 fps is 33 milliseconds/frame. To prevent skipping frames accidentally
-// when rAF is running near 30fps with small delta, use 32 ms instead of 33 ms
-// for comparison.
-const kFrameTime30Fps = 32;
+// when rAF is running near 30fps, we use 5ms delta for jittering.
+const kFrameTime30Fps = 33 - 5;
 
 // The time of last FPS update.
 let fpsPrevTime = performance.now();
diff --git a/content/test/data/gpu/vc/webgpu_video.js b/content/test/data/gpu/vc/webgpu_video.js
index 1e34ff0..0a7b35c9 100644
--- a/content/test/data/gpu/vc/webgpu_video.js
+++ b/content/test/data/gpu/vc/webgpu_video.js
@@ -165,12 +165,13 @@
   const vertexBufferForVideos = createVertexBufferForVideos(device, videos,
     videoRows, videoColumns);
 
-  const swapChainFormat = context.getPreferredFormat(adapter);
+  const swapChainFormat = navigator.gpu.getPreferredCanvasFormat();
 
   const swapChain = context.configure({
     device,
     format: swapChainFormat,
     usage: GPUTextureUsage.RENDER_ATTACHMENT,
+    alphaMode: "opaque"
   });
 
   let fragmentShaderModule;
@@ -186,6 +187,7 @@
 
 
   const pipelineForVideos = device.createRenderPipeline({
+    layout: "auto",
     vertex: {
       module: device.createShaderModule({
         code: wgslShaders.vertex,
@@ -225,7 +227,8 @@
     colorAttachments: [
       {
         view: undefined, // Assigned later
-        loadValue: { r: 1.0, g: 1.0, b: 1.0, a: 1.0 },
+        clearValue: { r: 1.0, g: 1.0, b: 1.0, a: 1.0 },
+        loadOp: 'clear',
         storeOp: 'store',
       },
     ],
@@ -278,6 +281,7 @@
     createVertexBufferForIcons(device, videos, videoRows, videoColumns);
 
   const renderPipelineDescriptorForIcon = {
+    layout: "auto",
     vertex: {
       module: device.createShaderModule({
         code: wgslShaders.vertex_icons,
@@ -331,6 +335,7 @@
 
   const vertexBufferForFPS = createVertexBufferForFPS(device);
   const pipelineForFPS = device.createRenderPipeline({
+    layout: "auto",
     vertex: {
       module: device.createShaderModule({
         code: wgslShaders.vertex,
diff --git a/extensions/browser/updater/extension_downloader_test_helper.cc b/extensions/browser/updater/extension_downloader_test_helper.cc
index 68c0d3b..e3daf59 100644
--- a/extensions/browser/updater/extension_downloader_test_helper.cc
+++ b/extensions/browser/updater/extension_downloader_test_helper.cc
@@ -121,6 +121,14 @@
       &delegate_, test_shared_url_loader_factory_, GetTestVerifierFormat());
 }
 
+ExtensionDownloaderTask CreateDownloaderTask(const ExtensionId& id,
+                                             const GURL& update_url) {
+  return ExtensionDownloaderTask(
+      id, update_url, mojom::ManifestLocation::kInternal,
+      false /* is_corrupt_reinstall */, 0 /* request_id */,
+      DownloadFetchPriority::kBackground);
+}
+
 void AddExtensionToFetchDataForTesting(ManifestFetchData* fetch_data,
                                        const ExtensionId& id,
                                        const std::string& version,
@@ -130,10 +138,7 @@
                            ExtensionDownloaderTestHelper::kEmptyUpdateUrlData,
                            std::string(), mojom::ManifestLocation::kInternal,
                            DownloadFetchPriority::kBackground);
-  fetch_data->AddAssociatedTask(ExtensionDownloaderTask(
-      id, update_url, mojom::ManifestLocation::kInternal,
-      false /* is_corrupt_reinstall */, 0 /* request_id */,
-      DownloadFetchPriority::kBackground));
+  fetch_data->AddAssociatedTask(CreateDownloaderTask(id, update_url));
 }
 
 void AddExtensionToFetchDataForTesting(ManifestFetchData* fetch_data,
diff --git a/extensions/browser/updater/extension_downloader_test_helper.h b/extensions/browser/updater/extension_downloader_test_helper.h
index 8cf0f9e..769394d0 100644
--- a/extensions/browser/updater/extension_downloader_test_helper.h
+++ b/extensions/browser/updater/extension_downloader_test_helper.h
@@ -127,6 +127,12 @@
   ExtensionDownloader downloader_;
 };
 
+// Creates a downloader task with most arguments set to default values.
+// Note that as ExtensionDownloaderTask is just a simple struct, callers can
+// configure additional properties if needed.
+ExtensionDownloaderTask CreateDownloaderTask(const ExtensionId& id,
+                                             const GURL& update_url = {});
+
 // Creates extension info and associated task, adds both to `fetch_data`.
 void AddExtensionToFetchDataForTesting(ManifestFetchData* fetch_data,
                                        const ExtensionId& id,
diff --git a/extensions/browser/updater/extension_downloader_unittest.cc b/extensions/browser/updater/extension_downloader_unittest.cc
index f6d22d0..3cb145c 100644
--- a/extensions/browser/updater/extension_downloader_unittest.cc
+++ b/extensions/browser/updater/extension_downloader_unittest.cc
@@ -55,10 +55,8 @@
     fetch->AddExtension(kTestExtensionId, "1.0", &zero_days, "", "",
                         mojom::ManifestLocation::kInternal,
                         DownloadFetchPriority::kBackground);
-    fetch->AddAssociatedTask(ExtensionDownloaderTask(
-        kTestExtensionId, kUpdateUrl, mojom::ManifestLocation::kInternal,
-        false /* is_corrupt_reinstall */, 0 /* request_id */,
-        DownloadFetchPriority::kBackground));
+    fetch->AddAssociatedTask(
+        CreateDownloaderTask(kTestExtensionId, kUpdateUrl));
     return fetch;
   }
 
@@ -430,22 +428,16 @@
   GURL kUpdateUrl("http://localhost/manifest1");
   const URLStats& stats = GetDownloaderURLStats(&helper);
 
-  helper.downloader().AddPendingExtension(ExtensionDownloaderTask(
-      kTestExtensionId, extension_urls::GetWebstoreUpdateUrl(),
-      mojom::ManifestLocation::kInternal, false /* is_corrupt_reinstall */,
-      0 /* request_id */, DownloadFetchPriority::kBackground));
+  helper.downloader().AddPendingExtension(CreateDownloaderTask(
+      kTestExtensionId, extension_urls::GetWebstoreUpdateUrl()));
   EXPECT_EQ(1, stats.google_url_count);
 
-  helper.downloader().AddPendingExtension(ExtensionDownloaderTask(
-      kTestExtensionId2, GURL() /* update_url */,
-      mojom::ManifestLocation::kInternal, false /* is_corrupt_reinstall */,
-      0 /* request_id */, DownloadFetchPriority::kBackground));
+  helper.downloader().AddPendingExtension(
+      CreateDownloaderTask(kTestExtensionId2, GURL()));
   EXPECT_EQ(1, stats.no_url_count);
 
-  helper.downloader().AddPendingExtension(ExtensionDownloaderTask(
-      kTestExtensionId3, kUpdateUrl, mojom::ManifestLocation::kInternal,
-      false /* is_corrupt_reinstall */, 0 /* request_id */,
-      DownloadFetchPriority::kBackground));
+  helper.downloader().AddPendingExtension(
+      CreateDownloaderTask(kTestExtensionId3, kUpdateUrl));
   EXPECT_EQ(1, stats.other_url_count);
 }
 
@@ -458,19 +450,16 @@
   // Clear pending queue to check it.
   helper.downloader().StartAllPending(nullptr);
   // Invalid update URL, shouldn't be added at all.
-  helper.downloader().AddPendingExtension(ExtensionDownloaderTask(
-      kTestExtensionId, GURL("http://?invalid=url"),
-      mojom::ManifestLocation::kInternal, false /* is_corrupt_reinstall */,
-      0 /* request_id */, DownloadFetchPriority::kBackground));
+  helper.downloader().AddPendingExtension(
+      CreateDownloaderTask(kTestExtensionId, GURL("http://?invalid=url")));
   EXPECT_EQ(0u, tasks.size());
 
   // Clear pending queue to check it.
   helper.downloader().StartAllPending(nullptr);
   // HTTP Webstore URL, should be replaced with HTTPS.
-  helper.downloader().AddPendingExtension(ExtensionDownloaderTask(
-      kTestExtensionId, GURL("http://clients2.google.com/service/update2/crx"),
-      mojom::ManifestLocation::kInternal, false /* is_corrupt_reinstall */,
-      0 /* request_id */, DownloadFetchPriority::kBackground));
+  helper.downloader().AddPendingExtension(CreateDownloaderTask(
+      kTestExtensionId,
+      GURL("http://clients2.google.com/service/update2/crx")));
   ASSERT_EQ(1u, tasks.size());
   EXPECT_EQ(GURL("https://clients2.google.com/service/update2/crx"),
             tasks.rbegin()->update_url);
@@ -478,20 +467,16 @@
   // Clear pending queue to check it.
   helper.downloader().StartAllPending(nullptr);
   // Just a custom URL, should be kept as is.
-  helper.downloader().AddPendingExtension(ExtensionDownloaderTask(
-      kTestExtensionId, GURL("https://example.com"),
-      mojom::ManifestLocation::kInternal, false /* is_corrupt_reinstall */,
-      0 /* request_id */, DownloadFetchPriority::kBackground));
+  helper.downloader().AddPendingExtension(
+      CreateDownloaderTask(kTestExtensionId, GURL("https://example.com")));
   ASSERT_EQ(1u, tasks.size());
   EXPECT_EQ(GURL("https://example.com"), tasks.rbegin()->update_url);
 
   // Clear pending queue to check it.
   helper.downloader().StartAllPending(nullptr);
   // Empty URL, should be replaced with Webstore one.
-  helper.downloader().AddPendingExtension(ExtensionDownloaderTask(
-      kTestExtensionId, GURL(""), mojom::ManifestLocation::kInternal,
-      false /* is_corrupt_reinstall */, 0 /* request_id */,
-      DownloadFetchPriority::kBackground));
+  helper.downloader().AddPendingExtension(
+      CreateDownloaderTask(kTestExtensionId, GURL("")));
   ASSERT_EQ(1u, tasks.size());
   EXPECT_EQ(GURL("https://clients2.google.com/service/update2/crx"),
             tasks.rbegin()->update_url);
@@ -503,26 +488,18 @@
 
   // Add two extensions with different update URLs (to have at least two items
   // in manifest requests queue).
-  helper.downloader().AddPendingExtension(ExtensionDownloaderTask(
-      kTestExtensionId, GURL("http://example1.com/"),
-      mojom::ManifestLocation::kInternal, false /* is_corrupt_reinstall */,
-      0 /* request_id */, DownloadFetchPriority::kBackground));
-  helper.downloader().AddPendingExtension(ExtensionDownloaderTask(
-      kTestExtensionId2, GURL("http://example2.com/"),
-      mojom::ManifestLocation::kInternal, false /* is_corrupt_reinstall */,
-      0 /* request_id */, DownloadFetchPriority::kBackground));
+  helper.downloader().AddPendingExtension(
+      CreateDownloaderTask(kTestExtensionId, GURL("http://example1.com/")));
+  helper.downloader().AddPendingExtension(
+      CreateDownloaderTask(kTestExtensionId2, GURL("http://example2.com/")));
 
   helper.downloader().StartAllPending(nullptr);
 
   // Add the same two extensions again.
-  helper.downloader().AddPendingExtension(ExtensionDownloaderTask(
-      kTestExtensionId, GURL("http://example1.com/"),
-      mojom::ManifestLocation::kInternal, false /* is_corrupt_reinstall */,
-      0 /* request_id */, DownloadFetchPriority::kBackground));
-  helper.downloader().AddPendingExtension(ExtensionDownloaderTask(
-      kTestExtensionId2, GURL("http://example2.com/"),
-      mojom::ManifestLocation::kInternal, false /* is_corrupt_reinstall */,
-      0 /* request_id */, DownloadFetchPriority::kBackground));
+  helper.downloader().AddPendingExtension(
+      CreateDownloaderTask(kTestExtensionId, GURL("http://example1.com/")));
+  helper.downloader().AddPendingExtension(
+      CreateDownloaderTask(kTestExtensionId2, GURL("http://example2.com/")));
 
   helper.downloader().StartAllPending(nullptr);
 
@@ -546,11 +523,10 @@
 
   helper.downloader().SetBackoffPolicyForTesting(&kZeroBackoffPolicy);
 
-  helper.downloader().AddPendingExtension(ExtensionDownloaderTask(
-      kTestExtensionId, extension_urls::GetWebstoreUpdateUrl(),
-      mojom::ManifestLocation::kExternalPolicyDownload,
-      false /* is_corrupt_reinstall */, 0 /* request_id */,
-      DownloadFetchPriority::kBackground));
+  ExtensionDownloaderTask task = CreateDownloaderTask(
+      kTestExtensionId, extension_urls::GetWebstoreUpdateUrl());
+  task.install_location = mojom::ManifestLocation::kExternalPolicyDownload,
+  helper.downloader().AddPendingExtension(std::move(task));
   auto test_extension_cache = std::make_unique<ExtensionCacheFake>();
   helper.downloader().StartAllPending(test_extension_cache.get());
 
@@ -574,11 +550,10 @@
 
   helper.downloader().SetBackoffPolicyForTesting(&kZeroBackoffPolicy);
 
-  helper.downloader().AddPendingExtension(ExtensionDownloaderTask(
-      kTestExtensionId, extension_urls::GetWebstoreUpdateUrl(),
-      mojom::ManifestLocation::kExternalPolicyDownload,
-      false /* is_corrupt_reinstall */, 0 /* request_id */,
-      DownloadFetchPriority::kBackground));
+  ExtensionDownloaderTask task = CreateDownloaderTask(
+      kTestExtensionId, extension_urls::GetWebstoreUpdateUrl());
+  task.install_location = mojom::ManifestLocation::kExternalPolicyDownload;
+  helper.downloader().AddPendingExtension(std::move(task));
 
   EXPECT_CALL(
       helper.delegate(),
diff --git a/gpu/ipc/service/gpu_channel_manager.cc b/gpu/ipc/service/gpu_channel_manager.cc
index a08f0f7..4587d857c 100644
--- a/gpu/ipc/service/gpu_channel_manager.cc
+++ b/gpu/ipc/service/gpu_channel_manager.cc
@@ -823,6 +823,15 @@
 
     context =
         gl::init::CreateGLContext(share_group.get(), surface.get(), attribs);
+
+    if (!context && !features::UseGles2ForOopR()) {
+      LOG(ERROR) << "Failed to create GLES3 context, fallback to GLES2.";
+      attribs.client_major_es_version = 2;
+      attribs.client_minor_es_version = 0;
+      context =
+          gl::init::CreateGLContext(share_group.get(), surface.get(), attribs);
+    }
+
     if (!context) {
       // TODO(piman): This might not be fatal, we could recurse into
       // CreateGLContext to get more info, tho it should be exceedingly
diff --git a/gpu/skia_bindings/gl_bindings_skia_cmd_buffer.cc b/gpu/skia_bindings/gl_bindings_skia_cmd_buffer.cc
index d2fc9fb..7798572 100644
--- a/gpu/skia_bindings/gl_bindings_skia_cmd_buffer.cc
+++ b/gpu/skia_bindings/gl_bindings_skia_cmd_buffer.cc
@@ -112,6 +112,8 @@
       gles_bind(&GLES2Interface::CompressedTexImage2D, impl, context_support);
   functions->fCompressedTexSubImage2D = gles_bind(
       &GLES2Interface::CompressedTexSubImage2D, impl, context_support);
+  functions->fCopyBufferSubData =
+        gles_bind(&GLES2Interface::CopyBufferSubData, impl, context_support);
   functions->fCopyTexSubImage2D =
       gles_bind(&GLES2Interface::CopyTexSubImage2D, impl, context_support);
   functions->fCreateProgram =
diff --git a/infra/config/generated/builders/reclient/ios-simulator reclient staging/properties.json b/infra/config/generated/builders/reclient/ios-simulator reclient staging/properties.json
index ac685d2..4e570ca 100644
--- a/infra/config/generated/builders/reclient/ios-simulator reclient staging/properties.json
+++ b/infra/config/generated/builders/reclient/ios-simulator reclient staging/properties.json
@@ -56,5 +56,6 @@
     ]
   },
   "builder_group": "chromium.reclient.fyi",
-  "recipe": "chromium"
+  "recipe": "chromium",
+  "xcode_build_version": "13c100"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/reclient/ios-simulator reclient test/properties.json b/infra/config/generated/builders/reclient/ios-simulator reclient test/properties.json
index a3c58c5f..177dd52 100644
--- a/infra/config/generated/builders/reclient/ios-simulator reclient test/properties.json
+++ b/infra/config/generated/builders/reclient/ios-simulator reclient test/properties.json
@@ -56,5 +56,6 @@
     ]
   },
   "builder_group": "chromium.reclient.fyi",
-  "recipe": "chromium"
+  "recipe": "chromium",
+  "xcode_build_version": "13c100"
 }
\ No newline at end of file
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg
index 55a59452..f4200a1 100644
--- a/infra/config/generated/luci/cr-buildbucket.cfg
+++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -109,6 +109,7 @@
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Mac-11|Mac-12"
       dimensions: "pool:luci.chromium.ci"
       exe {
@@ -178,6 +179,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -257,6 +259,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -336,6 +339,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -415,6 +419,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -494,6 +499,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -573,6 +579,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -652,6 +659,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -723,6 +731,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -805,6 +814,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -884,6 +894,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -966,6 +977,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -1048,6 +1060,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -1130,6 +1143,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -1212,6 +1226,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -1294,6 +1309,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -1376,6 +1392,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -1458,6 +1475,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -1540,6 +1558,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -1622,6 +1641,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -1704,6 +1724,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -1786,6 +1807,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -1868,6 +1890,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -2110,6 +2133,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -2192,6 +2216,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -2274,6 +2299,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -2356,6 +2382,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -2438,6 +2465,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:1"
@@ -2520,6 +2548,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -2602,6 +2631,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -2684,6 +2714,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -2766,6 +2797,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -2848,6 +2880,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -2930,6 +2963,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -3009,6 +3043,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -3088,6 +3123,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -3167,6 +3203,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -3246,6 +3283,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows-10"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -3325,6 +3363,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows-10"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -3404,6 +3443,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -3486,6 +3526,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -3568,6 +3609,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -3647,6 +3689,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -3726,6 +3769,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -3805,6 +3849,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -3884,6 +3929,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -3963,6 +4009,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -4041,6 +4088,7 @@
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Mac"
       dimensions: "pool:luci.chromium.gpu.ci"
       exe {
@@ -4118,6 +4166,7 @@
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Mac"
       dimensions: "pool:luci.chromium.gpu.ci"
       exe {
@@ -4196,6 +4245,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -4275,6 +4325,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -4354,6 +4405,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -4433,6 +4485,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -4512,6 +4565,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -4591,6 +4645,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -4670,6 +4725,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -4749,6 +4805,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -4828,6 +4885,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -4907,6 +4965,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -4986,6 +5045,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -5065,6 +5125,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -5144,6 +5205,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -5223,6 +5285,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -5302,6 +5365,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -5381,6 +5445,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -5460,6 +5525,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -5539,6 +5605,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -5618,6 +5685,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -5697,6 +5765,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -5771,6 +5840,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:16"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:1"
@@ -5845,6 +5915,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -5920,6 +5991,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -5994,6 +6066,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -6068,6 +6141,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -6150,6 +6224,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -6232,6 +6307,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -6314,6 +6390,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -6396,6 +6473,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -6478,6 +6556,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -6560,6 +6639,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -6641,6 +6721,7 @@
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Mac"
       dimensions: "pool:luci.chromium.gpu.ci"
       exe {
@@ -6721,6 +6802,7 @@
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Mac"
       dimensions: "pool:luci.chromium.gpu.ci"
       exe {
@@ -6801,6 +6883,7 @@
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Mac"
       dimensions: "pool:luci.chromium.gpu.ci"
       exe {
@@ -6881,6 +6964,7 @@
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Mac"
       dimensions: "pool:luci.chromium.gpu.ci"
       exe {
@@ -6962,6 +7046,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -7044,6 +7129,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -7126,6 +7212,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -7208,6 +7295,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -7290,6 +7378,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -7372,6 +7461,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -7454,6 +7544,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -7536,6 +7627,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -7614,6 +7706,7 @@
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Mac"
       dimensions: "pool:luci.chromium.gpu.ci"
       exe {
@@ -7694,6 +7787,7 @@
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Mac"
       dimensions: "pool:luci.chromium.gpu.ci"
       exe {
@@ -7772,6 +7866,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -7854,6 +7949,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -7933,6 +8029,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -8015,6 +8112,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -8097,6 +8195,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -8176,6 +8275,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -8247,6 +8347,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -8318,6 +8419,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -8389,6 +8491,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -8530,6 +8633,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -8601,6 +8705,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -8672,6 +8777,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -8743,6 +8849,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -8814,6 +8921,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -8885,6 +8993,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -9171,6 +9280,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:1"
@@ -9253,6 +9363,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -9335,6 +9446,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -9417,6 +9529,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -9499,6 +9612,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -9581,6 +9695,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -9663,6 +9778,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -9742,6 +9858,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -9821,6 +9938,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -9903,6 +10021,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -9982,6 +10101,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:16"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:1"
@@ -10064,6 +10184,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -10146,6 +10267,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -10228,6 +10350,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:16"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:1"
@@ -10310,6 +10433,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-20.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -10389,6 +10513,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -10471,6 +10596,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -10550,6 +10676,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -10632,6 +10759,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -10714,6 +10842,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -10796,6 +10925,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -10878,6 +11008,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -10960,6 +11091,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -11042,6 +11174,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -11124,6 +11257,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -11206,6 +11340,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:1"
@@ -11288,6 +11423,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-20.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -11367,6 +11503,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -11449,6 +11586,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -11531,6 +11669,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -11613,6 +11752,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -11695,6 +11835,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -11787,6 +11928,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -11869,6 +12011,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -11951,6 +12094,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -12030,6 +12174,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -12109,6 +12254,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -12747,6 +12893,7 @@
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Mac-11|Mac-12"
       dimensions: "pool:luci.chromium.ci"
       exe {
@@ -12825,6 +12972,7 @@
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Mac-11|Mac-12"
       dimensions: "pool:luci.chromium.ci"
       exe {
@@ -12980,6 +13128,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -13059,6 +13208,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -13141,6 +13291,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -13223,6 +13374,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -13305,6 +13457,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -13387,6 +13540,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -13469,6 +13623,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -13551,6 +13706,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -13633,6 +13789,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -13715,6 +13872,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -13797,6 +13955,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -13879,6 +14038,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -13961,6 +14121,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -14043,6 +14204,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -14125,6 +14287,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -14207,6 +14370,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -14289,6 +14453,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -14371,6 +14536,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -14591,6 +14757,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -14673,6 +14840,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -14755,6 +14923,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -14837,6 +15006,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -14919,6 +15089,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -14998,6 +15169,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -15080,6 +15252,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -15162,6 +15335,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -15244,6 +15418,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -15326,6 +15501,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -15405,6 +15581,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -15484,6 +15661,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -15563,6 +15741,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -15642,6 +15821,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -15724,6 +15904,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -15806,6 +15987,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -15888,6 +16070,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -15970,6 +16153,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -16052,6 +16236,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -16134,6 +16319,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -16216,6 +16402,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -16298,6 +16485,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -16380,6 +16568,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -16462,6 +16651,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -16544,6 +16734,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -16626,6 +16817,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -16708,6 +16900,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -16790,6 +16983,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -16953,6 +17147,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -17023,6 +17218,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -17105,6 +17301,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -17187,6 +17384,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -17269,6 +17467,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -17350,6 +17549,7 @@
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Mac-11|Mac-12"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:1"
@@ -17431,6 +17631,7 @@
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Mac-11|Mac-12"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:1"
@@ -17512,6 +17713,7 @@
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Mac-11|Mac-12"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:1"
@@ -17593,6 +17795,7 @@
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Mac-11|Mac-12"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:1"
@@ -17664,6 +17867,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -17827,6 +18031,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -17909,6 +18114,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -17991,6 +18197,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -18073,6 +18280,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -18155,6 +18363,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -18318,6 +18527,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -18558,6 +18768,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -18637,6 +18848,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -18716,6 +18928,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -18795,6 +19008,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -18877,6 +19091,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -18959,6 +19174,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -19200,6 +19416,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows-10"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -19681,6 +19898,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -19763,6 +19981,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows-10"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -19847,6 +20066,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows-10"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -19927,6 +20147,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows-10"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -20006,6 +20227,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows-10"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -20085,6 +20307,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -20167,6 +20390,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -20249,6 +20473,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -20331,6 +20556,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -20413,6 +20639,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -20495,6 +20722,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -20577,6 +20805,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -20659,6 +20888,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -20741,6 +20971,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -20823,6 +21054,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -21064,6 +21296,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -21146,6 +21379,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -21228,6 +21462,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -21307,6 +21542,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -21389,6 +21625,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows-10"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -21544,6 +21781,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -21626,6 +21864,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -21705,6 +21944,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -21784,6 +22024,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -21863,6 +22104,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -21942,6 +22184,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -22021,6 +22264,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -22090,6 +22334,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -22162,6 +22407,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -22229,6 +22475,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -22301,6 +22548,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -22368,6 +22616,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -22447,6 +22696,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -22529,6 +22779,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -22611,6 +22862,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -22693,6 +22945,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -22772,6 +23025,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -22858,6 +23112,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -22937,6 +23192,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -23016,6 +23272,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -23172,6 +23429,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -23251,6 +23509,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:1"
@@ -23330,6 +23589,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:1"
@@ -23409,6 +23669,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -23488,6 +23749,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -23567,6 +23829,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -23646,6 +23909,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -23725,6 +23989,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -23804,6 +24069,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -23951,6 +24217,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -24030,6 +24297,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -24109,6 +24377,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -24188,6 +24457,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -24267,6 +24537,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -24346,6 +24617,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -24425,6 +24697,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -24504,6 +24777,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -24583,6 +24857,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -24740,6 +25015,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -24822,6 +25098,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -24901,6 +25178,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -24983,6 +25261,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -25065,6 +25344,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -25222,6 +25502,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -25301,6 +25582,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -25383,6 +25665,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -25465,6 +25748,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -25544,6 +25828,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -25623,6 +25908,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -25861,6 +26147,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -26061,6 +26348,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -26143,6 +26431,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -26222,6 +26511,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -26304,6 +26594,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -26386,6 +26677,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -26468,6 +26760,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -26547,6 +26840,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -26626,6 +26920,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -26705,6 +27000,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -26787,6 +27083,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -26869,6 +27166,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -26951,6 +27249,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -27030,6 +27329,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -27109,6 +27409,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -27191,6 +27492,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -27273,6 +27575,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -27355,6 +27658,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -27437,6 +27741,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -27519,6 +27824,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -27601,6 +27907,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -27680,6 +27987,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -27760,6 +28068,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -27839,6 +28148,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -27921,6 +28231,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -28003,6 +28314,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -28085,6 +28397,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -28167,6 +28480,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -28240,6 +28554,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -28322,6 +28637,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:1"
@@ -28401,6 +28717,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -28483,6 +28800,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -28562,6 +28880,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -28641,6 +28960,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -28720,6 +29040,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -28802,6 +29123,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -28884,6 +29206,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -28963,6 +29286,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -29042,6 +29366,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -29199,6 +29524,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -29281,6 +29607,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -29363,6 +29690,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -29445,6 +29773,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -29527,6 +29856,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -29608,6 +29938,7 @@
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Mac"
       dimensions: "pool:luci.chromium.gpu.ci"
       exe {
@@ -29684,6 +30015,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -31310,6 +31642,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -31392,6 +31725,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -31474,6 +31808,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -31553,6 +31888,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -31632,6 +31968,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -31711,6 +32048,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -31790,6 +32128,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -31872,6 +32211,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -31954,6 +32294,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -32036,6 +32377,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -32108,6 +32450,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -32180,6 +32523,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -32247,6 +32591,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -32314,6 +32659,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -32381,6 +32727,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -32448,6 +32795,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -32527,6 +32875,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -32609,6 +32958,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -32691,6 +33041,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -32770,6 +33121,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -32858,6 +33210,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -32937,6 +33290,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -33019,6 +33373,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -33098,6 +33453,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -33177,6 +33533,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -33256,6 +33613,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -33335,6 +33693,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -33417,6 +33776,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -33496,6 +33856,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:1"
@@ -33575,6 +33936,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -33657,6 +34019,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:1"
@@ -33736,6 +34099,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -33818,6 +34182,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:1"
@@ -33897,6 +34262,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -33976,6 +34342,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -34058,6 +34425,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -34137,6 +34505,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -34219,6 +34588,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -34298,6 +34668,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -34377,6 +34748,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -34456,6 +34828,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -34538,6 +34911,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -34617,6 +34991,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -34696,6 +35071,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:1"
@@ -34775,6 +35151,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -34857,6 +35234,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -34936,6 +35314,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -35015,6 +35394,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -35094,6 +35474,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -35176,6 +35557,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -35333,6 +35715,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -35568,6 +35951,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -35650,6 +36034,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -35724,6 +36109,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -35806,6 +36192,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -35888,6 +36275,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -35967,6 +36355,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -36049,6 +36438,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -36129,6 +36519,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -36209,6 +36600,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -36289,6 +36681,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -36355,6 +36748,7 @@
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Mac"
       dimensions: "pool:luci.chromium.gpu.ci"
       exe {
@@ -36426,6 +36820,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -37055,6 +37450,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -37134,6 +37530,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -37213,6 +37610,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:24"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Mac"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:1"
@@ -37527,6 +37925,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -37605,6 +38004,7 @@
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Mac"
       dimensions: "pool:luci.chromium.ci"
       exe {
@@ -37682,6 +38082,7 @@
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Mac"
       dimensions: "pool:luci.chromium.ci"
       exe {
@@ -37759,6 +38160,7 @@
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Mac"
       dimensions: "pool:luci.chromium.gpu.ci"
       exe {
@@ -37839,6 +38241,7 @@
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
       dimensions: "cpu:arm64"
+      dimensions: "free_space:standard"
       dimensions: "os:Mac"
       dimensions: "pool:luci.chromium.ci"
       exe {
@@ -37916,6 +38319,7 @@
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
       dimensions: "cpu:arm64"
+      dimensions: "free_space:standard"
       dimensions: "os:Mac"
       dimensions: "pool:luci.chromium.ci"
       exe {
@@ -37993,6 +38397,7 @@
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Mac"
       dimensions: "pool:luci.chromium.ci"
       exe {
@@ -38070,6 +38475,7 @@
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Mac"
       dimensions: "pool:luci.chromium.ci"
       exe {
@@ -38147,6 +38553,7 @@
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Mac-11|Mac-12"
       dimensions: "pool:luci.chromium.ci"
       exe {
@@ -38225,6 +38632,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -38304,6 +38712,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -38383,6 +38792,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -38462,6 +38872,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -38541,6 +38952,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -38620,6 +39032,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -38699,6 +39112,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -38781,6 +39195,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -38860,6 +39275,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -38939,6 +39355,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -39018,6 +39435,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -39148,6 +39566,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -39220,6 +39639,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -39292,6 +39712,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -39364,6 +39785,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows-10"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -39602,6 +40024,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows-10"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -39684,6 +40107,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -39763,6 +40187,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -40150,6 +40575,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -40232,6 +40658,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -40306,6 +40733,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -40380,6 +40808,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -40462,6 +40891,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -40544,6 +40974,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows-10"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -40623,6 +41054,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows-10"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -40702,6 +41134,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows-10"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -40781,6 +41214,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -40848,6 +41282,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -40915,6 +41350,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -40982,6 +41418,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:2"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.gpu.ci"
       dimensions: "ssd:0"
@@ -41049,6 +41486,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows-10"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:1"
@@ -41128,6 +41566,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -41207,6 +41646,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -41286,6 +41726,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -41683,6 +42124,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows-10"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -41762,6 +42204,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows-10"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -41841,6 +42284,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -41920,6 +42364,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -42644,6 +43089,7 @@
       name: "flakiness-data-packager"
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -43709,6 +44155,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -43759,6 +44206,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -44396,6 +44844,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -44446,6 +44895,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -44496,6 +44946,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -44546,6 +44997,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -44596,6 +45048,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -44646,6 +45099,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -44898,6 +45352,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -44948,6 +45403,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -44998,6 +45454,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -45048,6 +45505,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -45274,6 +45732,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -45353,6 +45812,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -45432,6 +45892,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -45511,6 +45972,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -45590,6 +46052,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -45669,6 +46132,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:32"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Windows"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
@@ -45747,6 +46211,7 @@
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Mac-11|Mac-12"
       dimensions: "pool:luci.chromium.ci"
       exe {
@@ -45780,6 +46245,10 @@
         '  "recipe": "chromium"'
         '}'
       execution_timeout_secs: 10800
+      caches {
+        name: "xcode_ios_13c100"
+        path: "xcode_ios_13c100.app"
+      }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
@@ -45824,6 +46293,7 @@
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
       dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
       dimensions: "os:Mac-11|Mac-12"
       dimensions: "pool:luci.chromium.ci"
       exe {
@@ -45857,6 +46327,10 @@
         '  "recipe": "chromium"'
         '}'
       execution_timeout_secs: 10800
+      caches {
+        name: "xcode_ios_13c100"
+        path: "xcode_ios_13c100.app"
+      }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
diff --git a/infra/config/lib/builders.star b/infra/config/lib/builders.star
index f0707f7..5eb43cf 100644
--- a/infra/config/lib/builders.star
+++ b/infra/config/lib/builders.star
@@ -175,6 +175,15 @@
     x13wk = xcode_enum("13a1030dwk"),
 )
 
+# Free disk space in a machine reserved for build tasks.
+# The values in this enum will be used to populate bot dimension "free_space",
+# and each bot will allocate a corresponding amount of free disk space based on
+# the value of the dimension through "bot_config.py".
+free_space = struct(
+    standard = "standard",
+    high = "high",
+)
+
 ################################################################################
 # Implementation details                                                       #
 ################################################################################
@@ -301,6 +310,7 @@
     auto_builder_dimension = args.COMPUTE,
     builder_group = None,
     builderless = args.COMPUTE,
+    free_space = None,
     cores = None,
     cpu = None,
     fully_qualified_builder_dimension = False,
@@ -349,6 +359,7 @@
         triggered_by = args.DEFAULT,
         os = args.DEFAULT,
         builderless = args.DEFAULT,
+        free_space = args.DEFAULT,
         builder_cache_name = None,
         override_builder_dimension = None,
         auto_builder_dimension = args.DEFAULT,
@@ -429,6 +440,10 @@
         builderless: a boolean indicating whether the builder runs on
             builderless machines. If True, emits a 'builderless:1' dimension. By
             default, considered True iff `os` refers to a linux OS.
+        free_space: an enum that indicates the amount of free disk space reserved
+            in a machine for incoming build tasks. This value is used to create
+            a "free_space" dimension, and this dimension is appended to only
+            builderless builders.
         override_builder_dimension: a string to assign to the "builder"
             dimension. Ignores any other "builder" and "builderless" dimensions
             that would have been assigned.
@@ -604,6 +619,12 @@
         if builderless:
             dimensions["builderless"] = "1"
 
+            free_space = defaults.get_value("free_space", free_space)
+            if free_space:
+                dimensions["free_space"] = free_space
+        elif free_space and free_space != args.DEFAULT:
+            fail("\'free_space\' dimension can only be specified for builderless builders")
+
         auto_builder_dimension = defaults.get_value(
             "auto_builder_dimension",
             auto_builder_dimension,
@@ -812,4 +833,5 @@
     os = os,
     sheriff_rotations = sheriff_rotations,
     xcode = xcode,
+    free_space = free_space,
 )
diff --git a/infra/config/subprojects/chromium/ci.star b/infra/config/subprojects/chromium/ci.star
index 713cb5e..dee8b6a 100644
--- a/infra/config/subprojects/chromium/ci.star
+++ b/infra/config/subprojects/chromium/ci.star
@@ -3,7 +3,7 @@
 # found in the LICENSE file.
 
 load("//lib/branches.star", "branches")
-load("//lib/builders.star", "cpu")
+load("//lib/builders.star", "builders", "cpu")
 load("//lib/ci.star", "ci")
 load("//lib/consoles.star", "consoles")
 load("//project.star", "settings")
@@ -14,6 +14,7 @@
     build_numbers = True,
     cpu = cpu.X86_64,
     triggered_by = ["chromium-gitiles-trigger"],
+    free_space = builders.free_space.standard,
 )
 
 luci.bucket(
diff --git a/infra/config/subprojects/flakiness/flakiness.star b/infra/config/subprojects/flakiness/flakiness.star
index ee158bc9..c2b4fe8 100644
--- a/infra/config/subprojects/flakiness/flakiness.star
+++ b/infra/config/subprojects/flakiness/flakiness.star
@@ -2,7 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-load("//lib/builders.star", "os")
+load("//lib/builders.star", "builders", "os")
 load("//lib/ci.star", "ci")
 load("//lib/consoles.star", "consoles")
 
@@ -15,6 +15,7 @@
     # TODO(jeffyoon): replace with smaller scoped service account, and update
     # below for bucket ACL
     service_account = "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com",
+    free_space = builders.free_space.standard,
 )
 
 luci.bucket(
diff --git a/infra/config/subprojects/goma/goma.star b/infra/config/subprojects/goma/goma.star
index de0443d..4495169 100644
--- a/infra/config/subprojects/goma/goma.star
+++ b/infra/config/subprojects/goma/goma.star
@@ -3,7 +3,7 @@
 # found in the LICENSE file.
 
 load("//lib/builder_config.star", "builder_config")
-load("//lib/builders.star", "builder", "cpu", "defaults", "goma", "os", "xcode")
+load("//lib/builders.star", "builder", "builders", "cpu", "defaults", "goma", "os", "xcode")
 load("//lib/structs.star", "structs")
 
 luci.bucket(
@@ -32,6 +32,7 @@
 defaults.execution_timeout.set(3 * time.hour)
 defaults.os.set(os.LINUX_DEFAULT)
 defaults.pool.set("luci.chromium.ci")
+defaults.free_space.set(builders.free_space.standard)
 defaults.service_account.set(
     "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com",
 )
diff --git a/infra/config/subprojects/reclient/reclient.star b/infra/config/subprojects/reclient/reclient.star
index 8158db4..53dfacf 100644
--- a/infra/config/subprojects/reclient/reclient.star
+++ b/infra/config/subprojects/reclient/reclient.star
@@ -3,7 +3,7 @@
 # found in the LICENSE file.
 
 load("//lib/builder_config.star", "builder_config")
-load("//lib/builders.star", "cpu", "os")
+load("//lib/builders.star", "builders", "cpu", "os", "xcode")
 load("//lib/ci.star", "ci")
 load("//lib/consoles.star", "consoles")
 load("//lib/structs.star", "structs")
@@ -41,6 +41,7 @@
         "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
     ),
     triggered_by = ["chromium-gitiles-trigger"],
+    free_space = builders.free_space.standard,
 )
 
 consoles.console_view(
@@ -224,6 +225,7 @@
     os = os.MAC_DEFAULT,
     builderless = True,
     cores = None,
+    xcode = xcode.x13main,
 )
 
 fyi_reclient_staging_builder(
@@ -246,4 +248,5 @@
     os = os.MAC_DEFAULT,
     builderless = True,
     cores = None,
+    xcode = xcode.x13main,
 )
diff --git a/ios/chrome/browser/send_tab_to_self/send_tab_to_self_browser_agent.h b/ios/chrome/browser/send_tab_to_self/send_tab_to_self_browser_agent.h
index 9d04f22..d8c214a 100644
--- a/ios/chrome/browser/send_tab_to_self/send_tab_to_self_browser_agent.h
+++ b/ios/chrome/browser/send_tab_to_self/send_tab_to_self_browser_agent.h
@@ -36,10 +36,6 @@
  public:
   ~SendTabToSelfBrowserAgent() override;
 
-  // Add a new entry to the SendTabToSelfModel for the active web state of the
-  // browser.
-  void SendCurrentTabToDevice(NSString* target_device_id);
-
   // SendTabToSelfModelObserver::
   // Keeps track of when the model is loaded so that updates to the
   // model can be pushed afterwards.
diff --git a/ios/chrome/browser/send_tab_to_self/send_tab_to_self_browser_agent.mm b/ios/chrome/browser/send_tab_to_self/send_tab_to_self_browser_agent.mm
index 5e1554a..82f47aa 100644
--- a/ios/chrome/browser/send_tab_to_self/send_tab_to_self_browser_agent.mm
+++ b/ios/chrome/browser/send_tab_to_self/send_tab_to_self_browser_agent.mm
@@ -45,22 +45,6 @@
 
 SendTabToSelfBrowserAgent::~SendTabToSelfBrowserAgent() {}
 
-void SendTabToSelfBrowserAgent::SendCurrentTabToDevice(
-    NSString* target_device_id) {
-  web::WebState* web_state = browser_->GetWebStateList()->GetActiveWebState();
-  if (!web_state) {
-    return;
-  }
-
-  GURL url_to_share = web_state->GetLastCommittedURL();
-  if (url_to_share.is_empty()) {
-    return;
-  }
-
-  model_->AddEntry(url_to_share, base::UTF16ToUTF8(web_state->GetTitle()),
-                   base::SysNSStringToUTF8(target_device_id));
-}
-
 void SendTabToSelfBrowserAgent::SendTabToSelfModelLoaded() {
   // TODO(crbug.com/949756): Push changes that happened before the model was
   // loaded.
diff --git a/ios/chrome/browser/send_tab_to_self/send_tab_to_self_browser_agent_unittest.mm b/ios/chrome/browser/send_tab_to_self/send_tab_to_self_browser_agent_unittest.mm
index f2b3f8f..4e79eec3 100644
--- a/ios/chrome/browser/send_tab_to_self/send_tab_to_self_browser_agent_unittest.mm
+++ b/ios/chrome/browser/send_tab_to_self/send_tab_to_self_browser_agent_unittest.mm
@@ -159,19 +159,6 @@
   std::vector<infobars::InfoBarManager*> infobar_managers_;
 };
 
-TEST_F(SendTabToSelfBrowserAgentTest, TestSimpleSendCurrentTab) {
-  AppendNewWebState(GURL("http://www.test.com/test-1"));
-  agent_->SendCurrentTabToDevice(@"device1");
-  EXPECT_EQ(GURL("http://www.test.com/test-1"),
-            model_->GetLastEntry()->GetURL());
-  EXPECT_EQ("device1", model_->GetLastEntry()->GetTargetDeviceSyncCacheGuid());
-}
-
-TEST_F(SendTabToSelfBrowserAgentTest, TestNoActiveWebState) {
-  agent_->SendCurrentTabToDevice(@"device1");
-  EXPECT_EQ(nullptr, model_->GetLastEntry());
-}
-
 TEST_F(SendTabToSelfBrowserAgentTest, TestRemoteAddSimple) {
   web::WebState* web_state = AppendNewWebState(GURL("http://www.blank.com"));
   InfoBarManagerImpl* infobar_manager =
diff --git a/ios/chrome/browser/ui/activity_services/activities/send_tab_to_self_activity.mm b/ios/chrome/browser/ui/activity_services/activities/send_tab_to_self_activity.mm
index 7aafb28..30aa603 100644
--- a/ios/chrome/browser/ui/activity_services/activities/send_tab_to_self_activity.mm
+++ b/ios/chrome/browser/ui/activity_services/activities/send_tab_to_self_activity.mm
@@ -66,7 +66,7 @@
 
 - (void)performActivity {
   [self activityDidFinish:YES];
-  [self.handler showSendTabToSelfUI];
+  [self.handler showSendTabToSelfUI:self.data.shareURL title:self.data.title];
 }
 
 @end
diff --git a/ios/chrome/browser/ui/activity_services/activities/send_tab_to_self_activity_unittest.mm b/ios/chrome/browser/ui/activity_services/activities/send_tab_to_self_activity_unittest.mm
index fc600b2b..ac996d0 100644
--- a/ios/chrome/browser/ui/activity_services/activities/send_tab_to_self_activity_unittest.mm
+++ b/ios/chrome/browser/ui/activity_services/activities/send_tab_to_self_activity_unittest.mm
@@ -65,9 +65,10 @@
 
 // Tests that executing the activity triggers the right handler method.
 TEST_F(SendTabToSelfActivityTest, ExecuteActivity_CallsHandler) {
-  [[mocked_handler_ expect] showSendTabToSelfUI];
-
   ShareToData* data = CreateData(true);
+
+  [[mocked_handler_ expect] showSendTabToSelfUI:data.shareURL title:data.title];
+
   SendTabToSelfActivity* activity =
       [[SendTabToSelfActivity alloc] initWithData:data handler:mocked_handler_];
 
diff --git a/ios/chrome/browser/ui/authentication/signin_sync/signin_sync_view_controller.mm b/ios/chrome/browser/ui/authentication/signin_sync/signin_sync_view_controller.mm
index dafec41..9405ec8d 100644
--- a/ios/chrome/browser/ui/authentication/signin_sync/signin_sync_view_controller.mm
+++ b/ios/chrome/browser/ui/authentication/signin_sync/signin_sync_view_controller.mm
@@ -13,6 +13,7 @@
 #import "ios/chrome/common/ui/colors/semantic_color_names.h"
 #import "ios/chrome/common/ui/elements/popover_label_view_controller.h"
 #import "ios/chrome/common/ui/util/constraints_ui_util.h"
+#import "ios/chrome/common/ui/util/text_view_util.h"
 #include "ios/chrome/grit/ios_google_chrome_strings.h"
 #include "ios/chrome/grit/ios_strings.h"
 #import "net/base/mac/url_conversions.h"
@@ -242,7 +243,7 @@
 
 - (UITextView*)learnMoreTextView {
   if (!_learnMoreTextView) {
-    _learnMoreTextView = [[UITextView alloc] init];
+    _learnMoreTextView = CreateUITextViewWithTextKit1();
     _learnMoreTextView.backgroundColor = UIColor.clearColor;
     _learnMoreTextView.scrollEnabled = NO;
     _learnMoreTextView.editable = NO;
diff --git a/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_view_controller.mm b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_view_controller.mm
index e7abfe891..d8b1855e 100644
--- a/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_view_controller.mm
+++ b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_view_controller.mm
@@ -21,6 +21,7 @@
 #include "ios/chrome/common/string_util.h"
 #import "ios/chrome/common/ui/colors/semantic_color_names.h"
 #import "ios/chrome/common/ui/util/constraints_ui_util.h"
+#import "ios/chrome/common/ui/util/text_view_util.h"
 #include "ios/chrome/grit/ios_chromium_strings.h"
 #include "ios/chrome/grit/ios_strings.h"
 #import "net/base/mac/url_conversions.h"
@@ -195,7 +196,7 @@
   [container addSubview:separator];
 
   // Sync settings description.
-  self.syncSettingsTextView = [[UITextView alloc] init];
+  self.syncSettingsTextView = CreateUITextViewWithTextKit1();
   self.syncSettingsTextView.scrollEnabled = NO;
   self.syncSettingsTextView.editable = NO;
   self.syncSettingsTextView.delegate = self;
@@ -375,7 +376,7 @@
   if (_managementNoticeTextView)
     return _managementNoticeTextView;
 
-  _managementNoticeTextView = [[UITextView alloc] init];
+  _managementNoticeTextView = CreateUITextViewWithTextKit1();
   _managementNoticeTextView.scrollEnabled = NO;
   _managementNoticeTextView.editable = NO;
   _managementNoticeTextView.delegate = self;
diff --git a/ios/chrome/browser/ui/browser_view/BUILD.gn b/ios/chrome/browser/ui/browser_view/BUILD.gn
index 83ef9d44..d9f408c 100644
--- a/ios/chrome/browser/ui/browser_view/BUILD.gn
+++ b/ios/chrome/browser/ui/browser_view/BUILD.gn
@@ -275,7 +275,6 @@
     "//ios/chrome/browser/ui/fullscreen/test",
     "//ios/chrome/browser/ui/incognito_reauth:incognito_reauth_scene_agent",
     "//ios/chrome/browser/ui/main:scene_state_header",
-    "//ios/chrome/browser/ui/popup_menu",
     "//ios/chrome/browser/ui/sharing",
     "//ios/chrome/browser/ui/side_swipe",
     "//ios/chrome/browser/ui/tab_switcher/tab_strip",
diff --git a/ios/chrome/browser/ui/browser_view/browser_coordinator.mm b/ios/chrome/browser/ui/browser_view/browser_coordinator.mm
index fb9cb6c12..df00d38d 100644
--- a/ios/chrome/browser/ui/browser_view/browser_coordinator.mm
+++ b/ios/chrome/browser/ui/browser_view/browser_coordinator.mm
@@ -93,7 +93,6 @@
 #import "ios/chrome/browser/ui/passwords/password_breach_coordinator.h"
 #import "ios/chrome/browser/ui/passwords/password_protection_coordinator.h"
 #import "ios/chrome/browser/ui/passwords/password_suggestion_coordinator.h"
-#import "ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.h"
 #import "ios/chrome/browser/ui/presenters/vertical_animation_container.h"
 #import "ios/chrome/browser/ui/print/print_controller.h"
 #import "ios/chrome/browser/ui/qr_generator/qr_generator_coordinator.h"
@@ -310,10 +309,6 @@
 
 // The coordinator used for the Text Fragments feature.
 @property(nonatomic, strong) TextFragmentsCoordinator* textFragmentsCoordinator;
-
-// The coordinator for the popup menu.
-@property(nonatomic, strong) PopupMenuCoordinator* popupMenuCoordinator;
-
 @end
 
 @implementation BrowserCoordinator {
@@ -611,16 +606,6 @@
   // coordinators.
   DCHECK(self.dispatcher);
 
-  self.popupMenuCoordinator = [[PopupMenuCoordinator alloc]
-      initWithBaseViewController:self.viewController
-                         browser:self.browser];
-  self.popupMenuCoordinator.bubblePresenter = _bubblePresenter;
-  self.popupMenuCoordinator.UIUpdater = _toolbarCoordinatorAdaptor;
-  self.popupMenuCoordinator.popupMenuAppearanceDelegate = self.viewController;
-  [self.popupMenuCoordinator start];
-
-  _legacyTabStripCoordinator.longPressDelegate = self.popupMenuCoordinator;
-
   self.ARQuickLookCoordinator = [[ARQuickLookCoordinator alloc]
       initWithBaseViewController:self.viewController
                          browser:self.browser];
@@ -834,9 +819,6 @@
 
   [self.netExportCoordinator stop];
   self.netExportCoordinator = nil;
-
-  [self.popupMenuCoordinator stop];
-  self.popupMenuCoordinator = nil;
 }
 
 // Starts mediators owned by this coordinator.
@@ -885,6 +867,7 @@
   dependencies.bubblePresenter = _bubblePresenter;
   dependencies.downloadManagerCoordinator = self.downloadManagerCoordinator;
   dependencies.toolbarInterface = _toolbarCoordinatorAdaptor;
+  dependencies.UIUpdater = _toolbarCoordinatorAdaptor;
   dependencies.primaryToolbarCoordinator = _primaryToolbarCoordinator;
   dependencies.secondaryToolbarCoordinator = _secondaryToolbarCoordinator;
   dependencies.tabStripCoordinator = _tabStripCoordinator;
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller.h b/ios/chrome/browser/ui/browser_view/browser_view_controller.h
index 6d23338..825195a 100644
--- a/ios/chrome/browser/ui/browser_view/browser_view_controller.h
+++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.h
@@ -13,7 +13,6 @@
 #import "ios/chrome/browser/ui/incognito_reauth/incognito_reauth_consumer.h"
 #import "ios/chrome/browser/ui/ntp/logo_animation_controller.h"
 #import "ios/chrome/browser/ui/page_info/requirements/page_info_presentation.h"
-#import "ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.h"
 #import "ios/chrome/browser/ui/print/print_controller.h"
 #import "ios/chrome/browser/ui/settings/sync/utils/sync_presenter.h"
 #import "ios/chrome/browser/ui/thumb_strip/thumb_strip_supporting.h"
@@ -35,6 +34,7 @@
 @class DownloadManagerCoordinator;
 @class KeyCommandsProvider;
 // TODO(crbug.com/1328039): Remove all use of the prerender service from BVC
+@protocol PopupMenuUIUpdating;
 class PrerenderService;
 @class PrimaryToolbarCoordinator;
 @class SecondaryToolbarCoordinator;
@@ -53,6 +53,7 @@
   BubblePresenter* bubblePresenter;
   DownloadManagerCoordinator* downloadManagerCoordinator;
   id<ToolbarCoordinating> toolbarInterface;
+  id<PopupMenuUIUpdating> UIUpdater;
   PrimaryToolbarCoordinator* primaryToolbarCoordinator;
   SecondaryToolbarCoordinator* secondaryToolbarCoordinator;
   TabStripCoordinator* tabStripCoordinator;
@@ -68,7 +69,6 @@
                         LogoAnimationControllerOwnerOwner,
                         PageInfoPresentation,
                         PrintControllerDelegate,
-                        PopupMenuAppearanceDelegate,
                         SigninPresenter,
                         SyncPresenter,
                         ThumbStripSupporting,
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
index 696e97b1f..e38dedd 100644
--- a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
@@ -95,6 +95,7 @@
 #import "ios/chrome/browser/ui/ntp/new_tab_page_coordinator.h"
 #import "ios/chrome/browser/ui/ntp/ntp_util.h"
 #import "ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.h"
+#import "ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.h"
 #import "ios/chrome/browser/ui/send_tab_to_self/send_tab_to_self_coordinator.h"
 #import "ios/chrome/browser/ui/settings/sync/utils/sync_util.h"
 #import "ios/chrome/browser/ui/side_swipe/side_swipe_controller.h"
@@ -337,6 +338,9 @@
   // The updater that adjusts the toolbar's layout for fullscreen events.
   std::unique_ptr<FullscreenUIUpdater> _fullscreenUIUpdater;
 
+  // Popup Menu UI Updater.
+  id<PopupMenuUIUpdating> _UIUpdater;
+
   // TODO(crbug.com/1331229): Remove all use of the download manager coordinator
   // from BVC Coordinator for the Download Manager UI.
   DownloadManagerCoordinator* _downloadManagerCoordinator;
@@ -366,8 +370,6 @@
   // one single drag gesture.  When NO, full screen disabler is reset when
   // the thumb strip animation ends.
   BOOL _deferEndFullscreenDisabler;
-
-  BOOL _isShowingPopupMenu;
 }
 
 // Activates/deactivates the object. This will enable/disable the ability for
@@ -428,6 +430,9 @@
 // ones that cannot be scrolled off screen by full screen.
 @property(nonatomic, strong, readonly) NSArray<HeaderDefinition*>* headerViews;
 
+// Coordinator for the popup menus.
+@property(nonatomic, strong) PopupMenuCoordinator* popupMenuCoordinator;
+
 @property(nonatomic, strong) BubblePresenter* bubblePresenter;
 
 // Command handler for text zoom commands
@@ -529,6 +534,7 @@
     // TODO(crbug.com/1331229): Remove all use of the download manager
     // coordinator from BVC
     _downloadManagerCoordinator = dependencies.downloadManagerCoordinator;
+    _UIUpdater = dependencies.UIUpdater;
     _sideSwipeController = dependencies.sideSwipeController;
     [_sideSwipeController setSnapshotDelegate:self];
     [_sideSwipeController setSwipeDelegate:self];
@@ -1088,6 +1094,8 @@
   for (int index = 0; index < webStateList->count(); ++index)
     [self uninstallDelegatesForWebState:webStateList->GetWebStateAt(index)];
 
+  // Disconnect child coordinators.
+  [self.popupMenuCoordinator stop];
   if (base::FeatureList::IsEnabled(kModernTabStrip)) {
     [self.tabStripCoordinator stop];
     self.tabStripCoordinator = nil;
@@ -1736,10 +1744,22 @@
   _locationBarModel = std::make_unique<LocationBarModelImpl>(
       _locationBarModelDelegate.get(), kMaxURLDisplayChars);
 
+  // TODO(crbug.com/1329094): Move this coordinator to BrowserCoordinator
+  self.popupMenuCoordinator =
+      [[PopupMenuCoordinator alloc] initWithBaseViewController:self
+                                                       browser:self.browser];
+  self.popupMenuCoordinator.bubblePresenter = _bubblePresenter;
+  self.popupMenuCoordinator.UIUpdater = _UIUpdater;
+  [self.popupMenuCoordinator start];
+
   self.primaryToolbarCoordinator.delegate = self;
   self.primaryToolbarCoordinator.popupPresenterDelegate = self;
+  self.primaryToolbarCoordinator.longPressDelegate = self.popupMenuCoordinator;
   [self.primaryToolbarCoordinator start];
 
+  self.secondaryToolbarCoordinator.longPressDelegate =
+      self.popupMenuCoordinator;
+
   // TODO(crbug.com/880672): Finish ToolbarContainer work.
   if (base::FeatureList::IsEnabled(
           toolbar_container::kToolbarContainerEnabled)) {
@@ -1769,6 +1789,8 @@
       [self.tabStripCoordinator start];
     } else {
       self.legacyTabStripCoordinator.presentationProvider = self;
+      self.legacyTabStripCoordinator.longPressDelegate =
+          self.popupMenuCoordinator;
 
       [self.legacyTabStripCoordinator start];
     }
@@ -1960,6 +1982,13 @@
   self.helpHandler =
       HandlerForProtocol(self.browser->GetCommandDispatcher(), HelpCommands);
 
+  // TODO(crbug.com/1329098): Assuming all of the coordinators are in
+  // BrowserCoordinator, move this setup there as well.
+  if (!base::FeatureList::IsEnabled(kModernTabStrip)) {
+    self.legacyTabStripCoordinator.longPressDelegate =
+        self.popupMenuCoordinator;
+  }
+
   // TODO(crbug.com/1329089): Inject this handler.
   self.omniboxHandler =
       HandlerForProtocol(self.browser->GetCommandDispatcher(), OmniboxCommands);
@@ -3771,10 +3800,12 @@
 
 // TODO(crbug.com/972114) Move showSendTabToSelfUI or reroute to
 // browserCoordinator.
-- (void)showSendTabToSelfUI {
-  self.sendTabToSelfCoordinator = [[SendTabToSelfCoordinator alloc]
-      initWithBaseViewController:self
-                         browser:self.browser];
+- (void)showSendTabToSelfUI:(const GURL&)url title:(NSString*)title {
+  self.sendTabToSelfCoordinator =
+      [[SendTabToSelfCoordinator alloc] initWithBaseViewController:self
+                                                           browser:self.browser
+                                                               url:url
+                                                             title:title];
   [self.sendTabToSelfCoordinator start];
 }
 
@@ -4219,7 +4250,7 @@
 
 // TODO(crbug.com/1329105): Federate side swipe logic.
 - (BOOL)preventSideSwipe {
-  if (_isShowingPopupMenu)
+  if ([self.popupMenuCoordinator isShowingPopupMenu])
     return YES;
 
   if (_voiceSearchController.visible)
@@ -4442,16 +4473,6 @@
   return self;
 }
 
-#pragma mark - PopupMenuAppearanceDelegate
-
-- (void)popupMenuDidAppear {
-  _isShowingPopupMenu = YES;
-}
-
-- (void)popupMenuDidDisappear {
-  _isShowingPopupMenu = NO;
-}
-
 #pragma mark - Getters
 
 - (NewTabPageCoordinator*)ntpCoordinator {
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm
index 34a41ab..6ece410c 100644
--- a/ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm
@@ -229,11 +229,6 @@
                    keyCommandsProvider:key_commands_provider_
                           dependencies:dependencies];
 
-    popup_menu_coordinator_ = [[PopupMenuCoordinator alloc]
-        initWithBaseViewController:bvc_
-                           browser:browser_.get()];
-    [popup_menu_coordinator_ start];
-
     // Force the view to load.
     UIWindow* window = [[UIWindow alloc] initWithFrame:CGRectZero];
     [window addSubview:[bvc_ view]];
@@ -276,7 +271,6 @@
   SecondaryToolbarCoordinator* secondary_toolbar_coordinator_;
   TabStripCoordinator* tab_strip_coordinator_;
   TabStripLegacyCoordinator* legacy_tab_strip_coordinator_;
-  PopupMenuCoordinator* popup_menu_coordinator_;
   SideSwipeController* side_swipe_controller_;
 };
 
diff --git a/ios/chrome/browser/ui/commands/browser_commands.h b/ios/chrome/browser/ui/commands/browser_commands.h
index 3e20f48d9..2933026 100644
--- a/ios/chrome/browser/ui/commands/browser_commands.h
+++ b/ios/chrome/browser/ui/commands/browser_commands.h
@@ -65,8 +65,9 @@
 // Shows the bookmarks manager.
 - (void)showBookmarksManager;
 
-// Shows the dialog for sending the current tab between a user's devices.
-- (void)showSendTabToSelfUI;
+// Shows the dialog for sending the page with |url| and |title| between a user's
+// devices.
+- (void)showSendTabToSelfUI:(const GURL&)url title:(NSString*)title;
 
 // Prepares the browser to display a popup menu.
 - (void)prepareForPopupMenuPresentation:(PopupMenuCommandType)type;
diff --git a/ios/chrome/browser/ui/first_run/legacy_signin/legacy_signin_screen_view_controller.mm b/ios/chrome/browser/ui/first_run/legacy_signin/legacy_signin_screen_view_controller.mm
index 34f2c3a..176517e8 100644
--- a/ios/chrome/browser/ui/first_run/legacy_signin/legacy_signin_screen_view_controller.mm
+++ b/ios/chrome/browser/ui/first_run/legacy_signin/legacy_signin_screen_view_controller.mm
@@ -13,6 +13,7 @@
 #import "ios/chrome/common/ui/colors/semantic_color_names.h"
 #import "ios/chrome/common/ui/elements/popover_label_view_controller.h"
 #import "ios/chrome/common/ui/util/constraints_ui_util.h"
+#import "ios/chrome/common/ui/util/text_view_util.h"
 #include "ios/chrome/grit/ios_google_chrome_strings.h"
 #include "ios/chrome/grit/ios_strings.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -190,7 +191,7 @@
 
 - (UITextView*)learnMoreTextView {
   if (!_learnMoreTextView) {
-    _learnMoreTextView = [[UITextView alloc] init];
+    _learnMoreTextView = CreateUITextViewWithTextKit1();
     _learnMoreTextView.backgroundColor = UIColor.clearColor;
     _learnMoreTextView.scrollEnabled = NO;
     _learnMoreTextView.editable = NO;
diff --git a/ios/chrome/browser/ui/first_run/sync/sync_screen_view_controller.mm b/ios/chrome/browser/ui/first_run/sync/sync_screen_view_controller.mm
index a87cca25..f7b143e 100644
--- a/ios/chrome/browser/ui/first_run/sync/sync_screen_view_controller.mm
+++ b/ios/chrome/browser/ui/first_run/sync/sync_screen_view_controller.mm
@@ -11,6 +11,7 @@
 #import "ios/chrome/common/ui/colors/semantic_color_names.h"
 #import "ios/chrome/common/ui/elements/popover_label_view_controller.h"
 #import "ios/chrome/common/ui/util/constraints_ui_util.h"
+#import "ios/chrome/common/ui/util/text_view_util.h"
 #include "ios/chrome/grit/ios_strings.h"
 #import "net/base/mac/url_conversions.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -116,7 +117,7 @@
 
 - (UITextView*)learnMoreTextView {
   if (!_learnMoreTextView) {
-    _learnMoreTextView = [[UITextView alloc] init];
+    _learnMoreTextView = CreateUITextViewWithTextKit1();
     _learnMoreTextView.scrollEnabled = NO;
     _learnMoreTextView.editable = NO;
     _learnMoreTextView.adjustsFontForContentSizeCategory = YES;
diff --git a/ios/chrome/browser/ui/first_run/welcome/welcome_screen_view_controller.mm b/ios/chrome/browser/ui/first_run/welcome/welcome_screen_view_controller.mm
index 3f1ced8..0865d5a 100644
--- a/ios/chrome/browser/ui/first_run/welcome/welcome_screen_view_controller.mm
+++ b/ios/chrome/browser/ui/first_run/welcome/welcome_screen_view_controller.mm
@@ -13,6 +13,7 @@
 #import "ios/chrome/common/string_util.h"
 #import "ios/chrome/common/ui/colors/semantic_color_names.h"
 #import "ios/chrome/common/ui/util/pointer_interaction_util.h"
+#import "ios/chrome/common/ui/util/text_view_util.h"
 #include "ios/chrome/grit/ios_chromium_strings.h"
 #import "ios/chrome/grit/ios_strings.h"
 #import "ui/base/device_form_factor.h"
@@ -265,7 +266,7 @@
     [footerString appendAttributedString:manageMetricsReported];
   }
 
-  UITextView* textView = [[UITextView alloc] init];
+  UITextView* textView = CreateUITextViewWithTextKit1();
   textView.scrollEnabled = NO;
   textView.editable = NO;
   textView.adjustsFontForContentSizeCategory = YES;
diff --git a/ios/chrome/browser/ui/ntp/revamped_incognito_view.mm b/ios/chrome/browser/ui/ntp/revamped_incognito_view.mm
index 803ce90..38ee6bf 100644
--- a/ios/chrome/browser/ui/ntp/revamped_incognito_view.mm
+++ b/ios/chrome/browser/ui/ntp/revamped_incognito_view.mm
@@ -20,6 +20,7 @@
 #import "ios/chrome/common/string_util.h"
 #import "ios/chrome/common/ui/colors/semantic_color_names.h"
 #import "ios/chrome/common/ui/util/constraints_ui_util.h"
+#import "ios/chrome/common/ui/util/text_view_util.h"
 #import "ios/web/public/navigation/navigation_manager.h"
 #include "ios/web/public/navigation/referrer.h"
 #import "net/base/mac/url_conversions.h"
@@ -355,7 +356,7 @@
   [self.stackView addArrangedSubview:doesNotSection];
 
   // Learn more.
-  UITextView* learnMore = [[UITextView alloc] initWithFrame:CGRectZero];
+  UITextView* learnMore = CreateUITextViewWithTextKit1();
   learnMore.scrollEnabled = NO;
   learnMore.editable = NO;
   learnMore.delegate = self;
diff --git a/ios/chrome/browser/ui/overlays/overlay_presentation_util_unittest.mm b/ios/chrome/browser/ui/overlays/overlay_presentation_util_unittest.mm
index 3bd12e78..4ad37e15 100644
--- a/ios/chrome/browser/ui/overlays/overlay_presentation_util_unittest.mm
+++ b/ios/chrome/browser/ui/overlays/overlay_presentation_util_unittest.mm
@@ -6,6 +6,7 @@
 
 #import "ios/chrome/browser/ui/infobars/presentation/infobar_modal_positioner.h"
 #import "ios/chrome/common/ui/util/constraints_ui_util.h"
+#import "ios/chrome/common/ui/util/text_view_util.h"
 #import "ios/web/common/uikit_ui_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/gtest_mac.h"
@@ -34,7 +35,8 @@
   TestModalPositioner* positioner = [[TestModalPositioner alloc] init];
 
   CGRect frame = CGRectMake(0, 0, 500, 500);
-  UITextView* text_view = [[UITextView alloc] initWithFrame:frame];
+  UITextView* text_view = CreateUITextViewWithTextKit1();
+  text_view.frame = frame;
   text_view.text = @"test";
 
   // The text_view must be added to the window so that its safe area is not
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.h b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.h
index 696cded..60a7cc5 100644
--- a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.h
+++ b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.h
@@ -13,16 +13,6 @@
 @class BubblePresenter;
 @protocol PopupMenuUIUpdating;
 
-// Delegate that noitfies about pop up menu appearance change.
-@protocol PopupMenuAppearanceDelegate
-
-// Noitfies delegate that pop up menu did appear.
-- (void)popupMenuDidAppear;
-// Noitfies delegate that pop up menu did disappear.
-- (void)popupMenuDidDisappear;
-
-@end
-
 // Coordinator for the popup menu, handling the commands.
 @interface PopupMenuCoordinator : ChromeCoordinator<PopupMenuLongPressDelegate>
 
@@ -31,8 +21,8 @@
 // Bubble view presenter for the incognito tip.
 @property(nonatomic, weak) BubblePresenter* bubblePresenter;
 
-@property(nonatomic, weak) id<PopupMenuAppearanceDelegate>
-    popupMenuAppearanceDelegate;
+// Returns whether this coordinator is showing a popup menu.
+- (BOOL)isShowingPopupMenu;
 
 @end
 
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm
index 9dbe5ed..638d8f6c 100644
--- a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm
+++ b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm
@@ -134,6 +134,12 @@
   self.viewController = nil;
 }
 
+#pragma mark - Public
+
+- (BOOL)isShowingPopupMenu {
+  return self.presenter != nil;
+}
+
 #pragma mark - PopupMenuCommands
 
 - (void)showNavigationHistoryBackPopupMenu {
@@ -206,7 +212,6 @@
   }
   [self.presenter dismissAnimated:animated];
   self.presenter = nil;
-  [self.popupMenuAppearanceDelegate popupMenuDidDisappear];
   [self.mediator disconnect];
   self.mediator = nil;
   self.viewController = nil;
@@ -482,8 +487,6 @@
   [self.presenter prepareForPresentation];
   [self.presenter presentAnimated:YES];
 
-  [self.popupMenuAppearanceDelegate popupMenuDidAppear];
-
   // Scrolls happen during prepareForPresentation, so only attach the metrics
   // handler after presentation is done.
   if (type == PopupMenuTypeToolsMenu) {
diff --git a/ios/chrome/browser/ui/sad_tab/sad_tab_view.mm b/ios/chrome/browser/ui/sad_tab/sad_tab_view.mm
index 0b39e0e..f235255b 100644
--- a/ios/chrome/browser/ui/sad_tab/sad_tab_view.mm
+++ b/ios/chrome/browser/ui/sad_tab/sad_tab_view.mm
@@ -19,6 +19,7 @@
 #import "ios/chrome/browser/ui/util/uikit_ui_util.h"
 #import "ios/chrome/common/ui/colors/semantic_color_names.h"
 #import "ios/chrome/common/ui/util/pointer_interaction_util.h"
+#import "ios/chrome/common/ui/util/text_view_util.h"
 #include "ios/web/public/browser_state.h"
 #include "ios/web/public/navigation/navigation_manager.h"
 #import "net/base/mac/url_conversions.h"
@@ -317,7 +318,7 @@
 
 - (UITextView*)footerLabel {
   if (!_footerLabel) {
-    _footerLabel = [[UITextView alloc] initWithFrame:CGRectZero];
+    _footerLabel = CreateUITextViewWithTextKit1();
     _footerLabel.backgroundColor = self.backgroundColor;
     _footerLabel.delegate = self;
 
@@ -534,7 +535,7 @@
 
 - (UITextView*)messageTextView {
   if (!_messageTextView) {
-    _messageTextView = [[UITextView alloc] initWithFrame:CGRectZero];
+    _messageTextView = CreateUITextViewWithTextKit1();
     [_messageTextView setBackgroundColor:self.backgroundColor];
     [_messageTextView setAttributedText:[self messageTextViewAttributedText]];
     _messageTextView.textContainer.lineFragmentPadding = 0.0f;
diff --git a/ios/chrome/browser/ui/send_tab_to_self/BUILD.gn b/ios/chrome/browser/ui/send_tab_to_self/BUILD.gn
index 02760f43..181b6af 100644
--- a/ios/chrome/browser/ui/send_tab_to_self/BUILD.gn
+++ b/ios/chrome/browser/ui/send_tab_to_self/BUILD.gn
@@ -60,6 +60,7 @@
     "//ios/chrome/common:string_util",
     "//ios/chrome/common/ui/colors",
     "//ios/chrome/common/ui/table_view:cells_constants",
+    "//ios/chrome/common/ui/util:util",
     "//ui/base",
   ]
 }
diff --git a/ios/chrome/browser/ui/send_tab_to_self/send_tab_to_self_coordinator.h b/ios/chrome/browser/ui/send_tab_to_self/send_tab_to_self_coordinator.h
index cdf39e48..99c73ac 100644
--- a/ios/chrome/browser/ui/send_tab_to_self/send_tab_to_self_coordinator.h
+++ b/ios/chrome/browser/ui/send_tab_to_self/send_tab_to_self_coordinator.h
@@ -7,11 +7,21 @@
 
 #import "ios/chrome/browser/ui/coordinators/chrome_coordinator.h"
 
+class GURL;
+
 // Displays the send tab to self UI for all device form factors. Will show a
 // modal dialog popup on both platforms. Once this coordinator is stopped, the
 // underlying dialog is dismissed.
 @interface SendTabToSelfCoordinator : ChromeCoordinator
 
+- (id)initWithBaseViewController:(UIViewController*)baseViewController
+                         browser:(Browser*)browser
+                             url:(const GURL&)url
+                           title:(NSString*)title NS_DESIGNATED_INITIALIZER;
+
+- (id)initWithBaseViewController:(UIViewController*)baseViewController
+                         browser:(Browser*)browser NS_UNAVAILABLE;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_COORDINATOR_H_
diff --git a/ios/chrome/browser/ui/send_tab_to_self/send_tab_to_self_coordinator.mm b/ios/chrome/browser/ui/send_tab_to_self/send_tab_to_self_coordinator.mm
index e8199be4..bcac0ec09 100644
--- a/ios/chrome/browser/ui/send_tab_to_self/send_tab_to_self_coordinator.mm
+++ b/ios/chrome/browser/ui/send_tab_to_self/send_tab_to_self_coordinator.mm
@@ -52,6 +52,9 @@
                                         InfobarModalPositioner,
                                         SendTabToSelfModalDelegate>
 
+@property(nonatomic, assign, readonly) GURL url;
+@property(nonatomic, copy, readonly) NSString* title;
+
 // The TableViewController that shows the Send Tab To Self UI.
 @property(nonatomic, strong)
     SendTabToSelfTableViewController* sendTabToSelfViewController;
@@ -60,6 +63,22 @@
 
 @implementation SendTabToSelfCoordinator
 
+#pragma mark - Public
+
+- (id)initWithBaseViewController:(UIViewController*)baseViewController
+                         browser:(Browser*)browser
+                             url:(const GURL&)url
+                           title:(NSString*)title {
+  self = [super initWithBaseViewController:baseViewController browser:browser];
+  if (!self) {
+    return nil;
+  }
+
+  _url = url;
+  _title = title;
+  return self;
+}
+
 #pragma mark - ChromeCoordinator Methods
 
 - (void)start {
@@ -104,7 +123,7 @@
   self.sendTabToSelfViewController = nil;
 }
 
-#pragma mark-- UIViewControllerTransitioningDelegate
+#pragma mark - UIViewControllerTransitioningDelegate
 
 - (UIPresentationController*)
     presentationControllerForPresentedViewController:
@@ -145,7 +164,7 @@
   return contentSize.height + navigationBarHeight;
 }
 
-#pragma mark-- SendTabToSelfModalDelegate
+#pragma mark - SendTabToSelfModalDelegate
 
 - (void)dismissViewControllerAnimated:(BOOL)animated
                            completion:(void (^)())completion {
@@ -163,8 +182,11 @@
       self.browser->GetCommandDispatcher(), SnackbarCommands);
 
   // TODO(crbug.com/970284) log histogram of send event.
-  SendTabToSelfBrowserAgent::FromBrowser(self.browser)
-      ->SendCurrentTabToDevice(cacheGUID);
+  SendTabToSelfSyncServiceFactory::GetForBrowserState(
+      self.browser->GetBrowserState())
+      ->GetSendTabToSelfModel()
+      ->AddEntry(self.url, base::SysNSStringToUTF8(self.title),
+                 base::SysNSStringToUTF8(cacheGUID));
 
   [toolbarHandler triggerToolsMenuButtonAnimation];
 
diff --git a/ios/chrome/browser/ui/send_tab_to_self/send_tab_to_self_manage_devices_item.mm b/ios/chrome/browser/ui/send_tab_to_self/send_tab_to_self_manage_devices_item.mm
index 3850e375..67ce9f1 100644
--- a/ios/chrome/browser/ui/send_tab_to_self/send_tab_to_self_manage_devices_item.mm
+++ b/ios/chrome/browser/ui/send_tab_to_self/send_tab_to_self_manage_devices_item.mm
@@ -12,6 +12,7 @@
 #import "ios/chrome/common/string_util.h"
 #import "ios/chrome/common/ui/colors/semantic_color_names.h"
 #import "ios/chrome/common/ui/table_view/table_view_cells_constants.h"
+#import "ios/chrome/common/ui/util/text_view_util.h"
 #import "ios/chrome/grit/ios_strings.h"
 #import "ui/base/l10n/l10n_util.h"
 
@@ -56,7 +57,7 @@
   _avatarBadge.clipsToBounds = YES;
   [self.contentView addSubview:_avatarBadge];
 
-  _linkAndEmailTextView = [[UITextView alloc] init];
+  _linkAndEmailTextView = CreateUITextViewWithTextKit1();
   _linkAndEmailTextView.translatesAutoresizingMaskIntoConstraints = NO;
   _linkAndEmailTextView.scrollEnabled = NO;
   _linkAndEmailTextView.editable = NO;
diff --git a/ios/chrome/browser/ui/settings/password/passwords_in_other_apps/passwords_in_other_apps_view_controller.mm b/ios/chrome/browser/ui/settings/password/passwords_in_other_apps/passwords_in_other_apps_view_controller.mm
index d4d0688..066b8d1e 100644
--- a/ios/chrome/browser/ui/settings/password/passwords_in_other_apps/passwords_in_other_apps_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/password/passwords_in_other_apps/passwords_in_other_apps_view_controller.mm
@@ -19,6 +19,7 @@
 #import "ios/chrome/common/ui/util/button_util.h"
 #import "ios/chrome/common/ui/util/image_util.h"
 #import "ios/chrome/common/ui/util/pointer_interaction_util.h"
+#import "ios/chrome/common/ui/util/text_view_util.h"
 #include "ios/chrome/grit/ios_google_chrome_strings.h"
 #include "ios/chrome/grit/ios_strings.h"
 #import "ios/public/provider/chrome/browser/password_auto_fill/password_auto_fill_api.h"
@@ -704,7 +705,7 @@
     NSLinkAttributeName : l10n_util::GetNSString(IDS_IOS_OPEN_SETTINGS),
   };
 
-  UITextView* captionTextView = [[UITextView alloc] init];
+  UITextView* captionTextView = CreateUITextViewWithTextKit1();
   captionTextView.attributedText =
       AttributedStringFromStringWithLink(text, textAttributes, linkAttributes);
   captionTextView.editable = NO;
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/disabled_tab_view_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/disabled_tab_view_controller.mm
index 253a5726..10e2d59a 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/disabled_tab_view_controller.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/disabled_tab_view_controller.mm
@@ -12,6 +12,7 @@
 #import "ios/chrome/common/string_util.h"
 #import "ios/chrome/common/ui/colors/semantic_color_names.h"
 #import "ios/chrome/common/ui/util/constraints_ui_util.h"
+#import "ios/chrome/common/ui/util/text_view_util.h"
 #include "ios/chrome/grit/ios_strings.h"
 #import "net/base/mac/url_conversions.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -113,7 +114,7 @@
   topLabel.numberOfLines = 0;
   topLabel.textAlignment = NSTextAlignmentCenter;
 
-  UITextView* bottomTextView = [[UITextView alloc] init];
+  UITextView* bottomTextView = CreateUITextViewWithTextKit1();
   bottomTextView.translatesAutoresizingMaskIntoConstraints = NO;
   bottomTextView.attributedText = GetBodyString(self.page);
   bottomTextView.scrollEnabled = NO;
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_attributed_string_header_footer_item.mm b/ios/chrome/browser/ui/table_view/cells/table_view_attributed_string_header_footer_item.mm
index 54cefcad..f900a762 100644
--- a/ios/chrome/browser/ui/table_view/cells/table_view_attributed_string_header_footer_item.mm
+++ b/ios/chrome/browser/ui/table_view/cells/table_view_attributed_string_header_footer_item.mm
@@ -13,6 +13,7 @@
 #import "ios/chrome/common/string_util.h"
 #import "ios/chrome/common/ui/colors/semantic_color_names.h"
 #import "ios/chrome/common/ui/table_view/table_view_cells_constants.h"
+#import "ios/chrome/common/ui/util/text_view_util.h"
 #import "net/base/mac/url_conversions.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -52,7 +53,7 @@
 - (instancetype)initWithReuseIdentifier:(NSString*)reuseIdentifier {
   self = [super initWithReuseIdentifier:reuseIdentifier];
   if (self) {
-    _textView = [[UITextView alloc] init];
+    _textView = CreateUITextViewWithTextKit1();
     _textView.scrollEnabled = NO;
     _textView.editable = NO;
     _textView.delegate = self;
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_link_header_footer_item.mm b/ios/chrome/browser/ui/table_view/cells/table_view_link_header_footer_item.mm
index 6afdcd1..1abd147 100644
--- a/ios/chrome/browser/ui/table_view/cells/table_view_link_header_footer_item.mm
+++ b/ios/chrome/browser/ui/table_view/cells/table_view_link_header_footer_item.mm
@@ -13,6 +13,7 @@
 #import "ios/chrome/common/string_util.h"
 #import "ios/chrome/common/ui/colors/semantic_color_names.h"
 #import "ios/chrome/common/ui/table_view/table_view_cells_constants.h"
+#import "ios/chrome/common/ui/util/text_view_util.h"
 #import "net/base/mac/url_conversions.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -82,7 +83,7 @@
   self = [super initWithReuseIdentifier:reuseIdentifier];
   if (self) {
     urls_ = @[];
-    _textView = [[UITextView alloc] init];
+    _textView = CreateUITextViewWithTextKit1();
     _textView.scrollEnabled = NO;
     _textView.editable = NO;
     _textView.delegate = self;
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_text_link_item.mm b/ios/chrome/browser/ui/table_view/cells/table_view_text_link_item.mm
index 4a7eb4bd..eded0baf 100644
--- a/ios/chrome/browser/ui/table_view/cells/table_view_text_link_item.mm
+++ b/ios/chrome/browser/ui/table_view/cells/table_view_text_link_item.mm
@@ -12,6 +12,7 @@
 #import "ios/chrome/common/string_util.h"
 #import "ios/chrome/common/ui/colors/semantic_color_names.h"
 #import "ios/chrome/common/ui/table_view/table_view_cells_constants.h"
+#import "ios/chrome/common/ui/util/text_view_util.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
@@ -60,7 +61,7 @@
   self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
   if (self) {
     // Text Label, set font sizes using dynamic type.
-    _textView = [[UITextView alloc] init];
+    _textView = CreateUITextViewWithTextKit1();
     _textView.scrollEnabled = NO;
     _textView.editable = NO;
     _textView.delegate = self;
diff --git a/ios/chrome/common/BUILD.gn b/ios/chrome/common/BUILD.gn
index 5ff1ea4..ef22e073 100644
--- a/ios/chrome/common/BUILD.gn
+++ b/ios/chrome/common/BUILD.gn
@@ -71,6 +71,7 @@
     "//base",
     "//base/test:test_support",
     "//ios/chrome/common/ui/colors",
+    "//ios/chrome/common/ui/util:util",
     "//testing/gtest",
   ]
   configs += [ "//build/config/compiler:enable_arc" ]
diff --git a/ios/chrome/common/string_util_unittest.mm b/ios/chrome/common/string_util_unittest.mm
index 5bf5a25a..37c0425 100644
--- a/ios/chrome/common/string_util_unittest.mm
+++ b/ios/chrome/common/string_util_unittest.mm
@@ -9,6 +9,7 @@
 #include "base/ios/ns_range.h"
 #include "base/test/gtest_util.h"
 #import "ios/chrome/common/ui/colors/semantic_color_names.h"
+#import "ios/chrome/common/ui/util/text_view_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/gtest_mac.h"
 #include "testing/platform_test.h"
@@ -433,7 +434,7 @@
 
 // Verifies when it should return CGRectNull and when it shouldn't.
 TEST_F(StringUtilTest, TextViewLinkBound) {
-  UITextView* text_view = [[UITextView alloc] init];
+  UITextView* text_view = CreateUITextViewWithTextKit1();
   text_view.text = @"Some text.";
 
   // Returns CGRectNull for empty NSRange.
diff --git a/ios/chrome/common/ui/elements/popover_label_view_controller.mm b/ios/chrome/common/ui/elements/popover_label_view_controller.mm
index 130d735..9e25cb26 100644
--- a/ios/chrome/common/ui/elements/popover_label_view_controller.mm
+++ b/ios/chrome/common/ui/elements/popover_label_view_controller.mm
@@ -6,6 +6,7 @@
 
 #import "ios/chrome/common/ui/colors/semantic_color_names.h"
 #import "ios/chrome/common/ui/util/constraints_ui_util.h"
+#import "ios/chrome/common/ui/util/text_view_util.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
@@ -122,7 +123,7 @@
   [_scrollView addSubview:textContainerView];
   AddSameConstraints(textContainerView, _scrollView);
 
-  UITextView* textView = [[UITextView alloc] init];
+  UITextView* textView = CreateUITextViewWithTextKit1();
   textView.scrollEnabled = NO;
   textView.editable = NO;
   textView.delegate = self;
@@ -144,7 +145,7 @@
   // Only create secondary TextView when |secondaryAttributedString| is not nil
   // or empty. Set the constraint accordingly.
   if (self.secondaryAttributedString.length) {
-    UITextView* secondaryTextView = [[UITextView alloc] init];
+    UITextView* secondaryTextView = CreateUITextViewWithTextKit1();
     secondaryTextView.scrollEnabled = NO;
     secondaryTextView.editable = NO;
     secondaryTextView.delegate = self;
diff --git a/ios/chrome/common/ui/promo_style/promo_style_view_controller.mm b/ios/chrome/common/ui/promo_style/promo_style_view_controller.mm
index 7d413445..b07ab4c 100644
--- a/ios/chrome/common/ui/promo_style/promo_style_view_controller.mm
+++ b/ios/chrome/common/ui/promo_style/promo_style_view_controller.mm
@@ -17,6 +17,7 @@
 #include "ios/chrome/common/ui/util/dynamic_type_util.h"
 #include "ios/chrome/common/ui/util/image_util.h"
 #import "ios/chrome/common/ui/util/pointer_interaction_util.h"
+#import "ios/chrome/common/ui/util/text_view_util.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
@@ -506,7 +507,7 @@
   }
   if (!_disclaimerView) {
     // Set up disclaimer view.
-    _disclaimerView = [[UITextView alloc] init];
+    _disclaimerView = CreateUITextViewWithTextKit1();
     _disclaimerView.accessibilityIdentifier =
         kPromoStyleDisclaimerViewAccessibilityIdentifier;
     _disclaimerView.textContainerInset = UIEdgeInsetsMake(0, 0, 0, 0);
diff --git a/ios/chrome/common/ui/util/BUILD.gn b/ios/chrome/common/ui/util/BUILD.gn
index c20ed57..c3328aa 100644
--- a/ios/chrome/common/ui/util/BUILD.gn
+++ b/ios/chrome/common/ui/util/BUILD.gn
@@ -17,6 +17,8 @@
     "device_util.mm",
     "pointer_interaction_util.h",
     "pointer_interaction_util.mm",
+    "text_view_util.h",
+    "text_view_util.mm",
   ]
   deps = [
     "//base",
diff --git a/ios/chrome/common/ui/util/text_view_util.h b/ios/chrome/common/ui/util/text_view_util.h
new file mode 100644
index 0000000..bc166eb
--- /dev/null
+++ b/ios/chrome/common/ui/util/text_view_util.h
@@ -0,0 +1,13 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_COMMON_UI_UTIL_TEXT_VIEW_UTIL_H_
+#define IOS_CHROME_COMMON_UI_UTIL_TEXT_VIEW_UTIL_H_
+
+#import <UIKit/UIKit.h>
+
+// Creates a UITextView with TextKit1 by disabling TextKit2.
+UITextView* CreateUITextViewWithTextKit1();
+
+#endif  // IOS_CHROME_COMMON_UI_UTIL_TEXT_VIEW_UTIL_H_
diff --git a/ios/chrome/common/ui/util/text_view_util.mm b/ios/chrome/common/ui/util/text_view_util.mm
new file mode 100644
index 0000000..24bbb4b
--- /dev/null
+++ b/ios/chrome/common/ui/util/text_view_util.mm
@@ -0,0 +1,17 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/common/ui/util/text_view_util.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+UITextView* CreateUITextViewWithTextKit1() {
+#if defined(__IPHONE_16_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_16_0
+  if (@available(iOS 16, *))
+    return [UITextView textViewUsingTextLayoutManager:NO];
+#endif
+  return [[UITextView alloc] init];
+}
diff --git a/media/audio/alsa/alsa_output.cc b/media/audio/alsa/alsa_output.cc
index a05f60d..2e7ca86 100644
--- a/media/audio/alsa/alsa_output.cc
+++ b/media/audio/alsa/alsa_output.cc
@@ -541,10 +541,13 @@
     next_fill_time = base::Milliseconds(10);
   }
 
-  task_runner_->PostDelayedTask(FROM_HERE,
-                                base::BindOnce(&AlsaPcmOutputStream::WriteTask,
-                                               weak_factory_.GetWeakPtr()),
-                                next_fill_time);
+  task_runner_->PostDelayedTaskAt(
+      base::subtle::PostDelayedTaskPassKey(), FROM_HERE,
+      base::BindOnce(&AlsaPcmOutputStream::WriteTask,
+                     weak_factory_.GetWeakPtr()),
+      next_fill_time.is_zero() ? base::TimeTicks()
+                               : base::TimeTicks::Now() + next_fill_time,
+      base::subtle::DelayPolicy::kPrecise);
 }
 
 std::string AlsaPcmOutputStream::FindDeviceForChannels(uint32_t channels) {
diff --git a/media/base/fake_audio_worker.cc b/media/base/fake_audio_worker.cc
index 2d10aeae..505ea02 100644
--- a/media/base/fake_audio_worker.cc
+++ b/media/base/fake_audio_worker.cc
@@ -185,8 +185,10 @@
                                             frames_elapsed_, sample_rate_);
   }
 
-  worker_task_runner_->PostDelayedTask(FROM_HERE, worker_task_cb_.callback(),
-                                       next_read_time - now);
+  worker_task_runner_->PostDelayedTaskAt(base::subtle::PostDelayedTaskPassKey(),
+                                         FROM_HERE, worker_task_cb_.callback(),
+                                         next_read_time,
+                                         base::subtle::DelayPolicy::kPrecise);
 }
 
 }  // namespace media
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc
index e1d2e141..566f175 100644
--- a/media/base/media_switches.cc
+++ b/media/base/media_switches.cc
@@ -786,6 +786,11 @@
 #endif  // BUILDFLAG(IS_ANDROID)
 
 #if BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION)
+// Enable Variable Bitrate encoding with hardware accelerated encoders on
+// ChromeOS.
+const base::Feature kChromeOSHWVBREncoding{"ChromeOSHWVBREncoding",
+                                           base::FEATURE_DISABLED_BY_DEFAULT};
+
 // Enable the hardware-accelerated direct video decoder instead of the one
 // needing the VdaVideoDecoder adapter. This flag is used mainly as a
 // chrome:flag for developers debugging issues as well as to be able to
diff --git a/media/base/media_switches.h b/media/base/media_switches.h
index 1125dbc..54842af2 100644
--- a/media/base/media_switches.h
+++ b/media/base/media_switches.h
@@ -239,6 +239,7 @@
 #endif  // BUILDFLAG(IS_ANDROID)
 
 #if BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION)
+MEDIA_EXPORT extern const base::Feature kChromeOSHWVBREncoding;
 MEDIA_EXPORT extern const base::Feature kUseChromeOSDirectVideoDecoder;
 MEDIA_EXPORT extern const base::Feature kLimitConcurrentDecoderInstances;
 #if defined(ARCH_CPU_ARM_FAMILY)
diff --git a/media/gpu/test/video_encoder/video_encoder_test_environment.cc b/media/gpu/test/video_encoder/video_encoder_test_environment.cc
index 3c8cf5e..de3cea3 100644
--- a/media/gpu/test/video_encoder/video_encoder_test_environment.cc
+++ b/media/gpu/test/video_encoder/video_encoder_test_environment.cc
@@ -174,6 +174,10 @@
   combined_enabled_features.push_back(media::kVaapiVideoEncodeLinux);
 #endif
 
+#if BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION)
+  combined_enabled_features.push_back(media::kChromeOSHWVBREncoding);
+#endif
+
   const uint32_t target_bitrate = encode_bitrate.value_or(
       GetDefaultTargetBitrate(video->Resolution(), video->FrameRate()));
   // TODO(b/181797390): Reconsider if this peak bitrate is reasonable.
diff --git a/media/gpu/vaapi/vaapi_video_encode_accelerator.cc b/media/gpu/vaapi/vaapi_video_encode_accelerator.cc
index e0e98c1..40247ca 100644
--- a/media/gpu/vaapi/vaapi_video_encode_accelerator.cc
+++ b/media/gpu/vaapi/vaapi_video_encode_accelerator.cc
@@ -249,11 +249,16 @@
     return false;
   }
 
-  if (codec != VideoCodec::kH264 &&
-      config.bitrate.mode() == Bitrate::Mode::kVariable) {
-    MEDIA_LOG(ERROR, media_log.get())
-        << "Variable bitrate is only supported with H264 encoding.";
-    return false;
+  if (config.bitrate.mode() == Bitrate::Mode::kVariable) {
+    if (!base::FeatureList::IsEnabled(kChromeOSHWVBREncoding)) {
+      MEDIA_LOG(ERROR, media_log.get()) << "Variable bitrate is disabled.";
+      return false;
+    }
+    if (codec != VideoCodec::kH264) {
+      MEDIA_LOG(ERROR, media_log.get())
+          << "Variable bitrate is only supported with H264 encoding.";
+      return false;
+    }
   }
 
   if (config.input_format != PIXEL_FORMAT_I420 &&
diff --git a/media/gpu/vaapi/vaapi_wrapper.cc b/media/gpu/vaapi/vaapi_wrapper.cc
index 958da0f6..d0b49a19 100644
--- a/media/gpu/vaapi/vaapi_wrapper.cc
+++ b/media/gpu/vaapi/vaapi_wrapper.cc
@@ -627,17 +627,6 @@
                       }) != profiles.end();
 }
 
-bool IsImplementedVbr(VideoCodecProfile codec_profile) {
-  switch (codec_profile) {
-    case H264PROFILE_BASELINE:
-    case H264PROFILE_MAIN:
-    case H264PROFILE_HIGH:
-      return true;
-    default:
-      return false;
-  }
-}
-
 bool IsBlockedDriver(VaapiWrapper::CodecMode mode, VAProfile va_profile) {
   if (!IsModeEncoding(mode)) {
     return va_profile == VAProfileAV1Profile0 &&
@@ -1597,6 +1586,24 @@
   return false;
 }
 
+bool IsVBREncodingSupported(VAProfile va_profile) {
+  if (!base::FeatureList::IsEnabled(kChromeOSHWVBREncoding))
+    return false;
+
+  auto mode = VaapiWrapper::CodecMode::kCodecModeMax;
+  switch (va_profile) {
+    case VAProfileH264ConstrainedBaseline:
+    case VAProfileH264Main:
+    case VAProfileH264High:
+      mode = VaapiWrapper::CodecMode::kEncodeVariableBitrate;
+      break;
+    default:
+      return false;
+  }
+
+  return VASupportedProfiles::Get().IsProfileSupported(mode, va_profile);
+}
+
 }  // namespace
 
 NativePixmapAndSizeInfo::NativePixmapAndSizeInfo() = default;
@@ -1717,9 +1724,7 @@
     profile.rate_control_modes = media::VideoEncodeAccelerator::kConstantMode;
     // This code assumes that the resolutions are the same between CBR and VBR.
     // This is checked in a test in vaapi_unittest.cc: VbrAndCbrResolutionsMatch
-    if (IsImplementedVbr(media_profile) &&
-        VASupportedProfiles::Get().IsProfileSupported(kEncodeVariableBitrate,
-                                                      va_profile)) {
+    if (IsVBREncodingSupported(va_profile)) {
       profile.rate_control_modes |=
           media::VideoEncodeAccelerator::kVariableMode;
     }
diff --git a/net/http/http_cache_transaction.cc b/net/http/http_cache_transaction.cc
index d397ee5a98..5f4450b7 100644
--- a/net/http/http_cache_transaction.cc
+++ b/net/http/http_cache_transaction.cc
@@ -325,7 +325,9 @@
 
   DCHECK_EQ(next_state_, STATE_NONE);
   DCHECK(buf);
-  DCHECK_GT(buf_len, 0);
+  // TODO(https://crbug.com/1335423): Change to DCHECK_GT() or remove after bug
+  // is fixed.
+  CHECK_GT(buf_len, 0);
   DCHECK(!callback.is_null());
 
   DCHECK(callback_.is_null());
diff --git a/net/http/http_cache_writers.cc b/net/http/http_cache_writers.cc
index 9a9b3b9..35f236a 100644
--- a/net/http/http_cache_writers.cc
+++ b/net/http/http_cache_writers.cc
@@ -81,7 +81,9 @@
                              CompletionOnceCallback callback,
                              Transaction* transaction) {
   DCHECK(buf);
-  DCHECK_GT(buf_len, 0);
+  // TODO(https://crbug.com/1335423): Change to DCHECK_GT() or remove after bug
+  // is fixed.
+  CHECK_GT(buf_len, 0);
   DCHECK(!callback.is_null());
   DCHECK(transaction);
 
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom
index cd28ac0..7f1c4dd 100644
--- a/services/network/public/mojom/network_context.mojom
+++ b/services/network/public/mojom/network_context.mojom
@@ -775,16 +775,18 @@
 // Implemented by the browser process.
 interface NetworkContextClient {
   // Called when file uploading was requested.
-  // If the process that requested the uploads has permission to read all of
-  // the files referenced by |file_paths|, the callback arguments will be
-  // net::OK, along with an array of open file handles. The array will contain
-  // exactly one handle for each path in |file_paths|, in the same order.
-  // If any files referenced by |file_paths| cannot be read, a net::ERROR will
-  // be returned, and |files| will be an empty list. If the |async| parameter
-  // is true, the files will be opened with FLAG_ASYNC.
+  // If the process that requested the uploads to |destination_url| has
+  // permission to read all of the files referenced by |file_paths|,
+  // the callback arguments will be net::OK, along with an array of open file
+  // handles. The array will contain exactly one handle for each path in
+  // |file_paths|, in the same order. If any files referenced by |file_paths|
+  // cannot be read, a net::ERROR will be returned, and |files| will be an empty
+  // list. If the |async| parameter is true, the files will be opened with
+  // FLAG_ASYNC.
   OnFileUploadRequested(int32 process_id,
                         bool async,
-                        array<mojo_base.mojom.FilePath> file_paths) =>
+                        array<mojo_base.mojom.FilePath> file_paths,
+                        url.mojom.Url destination_url) =>
       (int32 net_error, array<mojo_base.mojom.ReadOnlyFile> files);
 
   // Checks if network error reports could be sent for the given origins.
diff --git a/services/network/test/test_network_context_client.cc b/services/network/test/test_network_context_client.cc
index b4db9c7..e1ecf4a 100644
--- a/services/network/test/test_network_context_client.cc
+++ b/services/network/test/test_network_context_client.cc
@@ -24,6 +24,7 @@
     int32_t process_id,
     bool async,
     const std::vector<base::FilePath>& file_paths,
+    const GURL& destination_url,
     OnFileUploadRequestedCallback callback) {
   if (upload_files_invalid_) {
     std::move(callback).Run(net::ERR_ACCESS_DENIED, std::vector<base::File>());
diff --git a/services/network/test/test_network_context_client.h b/services/network/test/test_network_context_client.h
index d72b968..af8682b 100644
--- a/services/network/test/test_network_context_client.h
+++ b/services/network/test/test_network_context_client.h
@@ -34,6 +34,7 @@
   void OnFileUploadRequested(int32_t process_id,
                              bool async,
                              const std::vector<base::FilePath>& file_paths,
+                             const GURL& destination_url,
                              OnFileUploadRequestedCallback callback) override;
   void OnCanSendReportingReports(
       const std::vector<url::Origin>& origins,
diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc
index 47b7359..c1f5c1e8 100644
--- a/services/network/url_loader.cc
+++ b/services/network/url_loader.cc
@@ -912,6 +912,7 @@
 
     network_context_client_->OnFileUploadRequested(
         process_id_, /*async=*/true, batch_paths,
+        url_loader_->url_request_->url(),
         base::BindOnce(&FileOpenerForUpload::OnFilesForUploadOpened,
                        weak_ptr_factory_.GetWeakPtr(), num_files_to_request));
   }
diff --git a/services/network/url_loader_unittest.cc b/services/network/url_loader_unittest.cc
index 4b0c20f..600602d 100644
--- a/services/network/url_loader_unittest.cc
+++ b/services/network/url_loader_unittest.cc
@@ -2985,6 +2985,7 @@
   void OnFileUploadRequested(int32_t process_id,
                              bool async,
                              const std::vector<base::FilePath>& file_paths,
+                             const GURL& destination_url,
                              OnFileUploadRequestedCallback callback) override {
     file_upload_requested_callback_ = std::move(callback);
     if (quit_closure_for_on_file_upload_requested_)
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json
index aeb9656..663fd1f 100644
--- a/testing/buildbot/chromium.android.fyi.json
+++ b/testing/buildbot/chromium.android.fyi.json
@@ -8325,15 +8325,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
-          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
-          "--client-outdir",
-          "../../weblayer_instrumentation_test_M103/out/Release",
           "--implementation-outdir",
           ".",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/SystemWebView.apk",
+          "--client-outdir",
+          "../../weblayer_instrumentation_test_M103/out/Release",
           "--client-version=103",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -8410,15 +8410,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
-          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
-          "--client-outdir",
-          "../../weblayer_instrumentation_test_M104/out/Release",
           "--implementation-outdir",
           ".",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/SystemWebView.apk",
+          "--client-outdir",
+          "../../weblayer_instrumentation_test_M104/out/Release",
           "--client-version=104",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -8835,15 +8835,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
-          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
           "--test-runner-outdir",
           ".",
           "--client-outdir",
           ".",
-          "--implementation-outdir",
-          "../../weblayer_instrumentation_test_M103/out/Release",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
+          "--implementation-outdir",
+          "../../weblayer_instrumentation_test_M103/out/Release",
           "--impl-version=103",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -8920,15 +8920,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
-          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
           "--test-runner-outdir",
           ".",
           "--client-outdir",
           ".",
-          "--implementation-outdir",
-          "../../weblayer_instrumentation_test_M104/out/Release",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
+          "--implementation-outdir",
+          "../../weblayer_instrumentation_test_M104/out/Release",
           "--impl-version=104",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json
index 9cd3a2c..8b59a0d 100644
--- a/testing/buildbot/chromium.android.json
+++ b/testing/buildbot/chromium.android.json
@@ -46453,15 +46453,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
-          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
-          "--client-outdir",
-          "../../weblayer_instrumentation_test_M103/out/Release",
           "--implementation-outdir",
           ".",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/SystemWebView.apk",
+          "--client-outdir",
+          "../../weblayer_instrumentation_test_M103/out/Release",
           "--client-version=103",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -46538,15 +46538,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
-          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
-          "--client-outdir",
-          "../../weblayer_instrumentation_test_M104/out/Release",
           "--implementation-outdir",
           ".",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/SystemWebView.apk",
+          "--client-outdir",
+          "../../weblayer_instrumentation_test_M104/out/Release",
           "--client-version=104",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -46963,15 +46963,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
-          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
           "--test-runner-outdir",
           ".",
           "--client-outdir",
           ".",
-          "--implementation-outdir",
-          "../../weblayer_instrumentation_test_M103/out/Release",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
+          "--implementation-outdir",
+          "../../weblayer_instrumentation_test_M103/out/Release",
           "--impl-version=103",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -47048,15 +47048,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
-          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
           "--test-runner-outdir",
           ".",
           "--client-outdir",
           ".",
-          "--implementation-outdir",
-          "../../weblayer_instrumentation_test_M104/out/Release",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
+          "--implementation-outdir",
+          "../../weblayer_instrumentation_test_M104/out/Release",
           "--impl-version=104",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -47477,15 +47477,15 @@
       {
         "args": [
           "--additional-apk=apks/ChromePublic.apk",
-          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
-          "--client-outdir",
-          "../../weblayer_instrumentation_test_M103/out/Release",
           "--implementation-outdir",
           ".",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/SystemWebView.apk",
+          "--client-outdir",
+          "../../weblayer_instrumentation_test_M103/out/Release",
           "--client-version=103",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -47562,15 +47562,15 @@
       {
         "args": [
           "--additional-apk=apks/ChromePublic.apk",
-          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
-          "--client-outdir",
-          "../../weblayer_instrumentation_test_M104/out/Release",
           "--implementation-outdir",
           ".",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/SystemWebView.apk",
+          "--client-outdir",
+          "../../weblayer_instrumentation_test_M104/out/Release",
           "--client-version=104",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -47987,15 +47987,15 @@
       {
         "args": [
           "--additional-apk=apks/ChromePublic.apk",
-          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
           "--test-runner-outdir",
           ".",
           "--client-outdir",
           ".",
-          "--implementation-outdir",
-          "../../weblayer_instrumentation_test_M103/out/Release",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
+          "--implementation-outdir",
+          "../../weblayer_instrumentation_test_M103/out/Release",
           "--impl-version=103",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -48072,15 +48072,15 @@
       {
         "args": [
           "--additional-apk=apks/ChromePublic.apk",
-          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
           "--test-runner-outdir",
           ".",
           "--client-outdir",
           ".",
-          "--implementation-outdir",
-          "../../weblayer_instrumentation_test_M104/out/Release",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
+          "--implementation-outdir",
+          "../../weblayer_instrumentation_test_M104/out/Release",
           "--impl-version=104",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -48569,15 +48569,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
-          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
-          "--client-outdir",
-          "../../weblayer_instrumentation_test_M103/out/Release",
           "--implementation-outdir",
           ".",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/SystemWebView.apk",
+          "--client-outdir",
+          "../../weblayer_instrumentation_test_M103/out/Release",
           "--client-version=103",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -48654,15 +48654,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
-          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
-          "--client-outdir",
-          "../../weblayer_instrumentation_test_M104/out/Release",
           "--implementation-outdir",
           ".",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/SystemWebView.apk",
+          "--client-outdir",
+          "../../weblayer_instrumentation_test_M104/out/Release",
           "--client-version=104",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -49079,15 +49079,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
-          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
           "--client-outdir",
           ".",
-          "--implementation-outdir",
-          "../../weblayer_instrumentation_test_M103/out/Release",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/SystemWebView.apk",
+          "--implementation-outdir",
+          "../../weblayer_instrumentation_test_M103/out/Release",
           "--impl-version=103",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -49164,15 +49164,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
-          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
           "--client-outdir",
           ".",
-          "--implementation-outdir",
-          "../../weblayer_instrumentation_test_M104/out/Release",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/SystemWebView.apk",
+          "--implementation-outdir",
+          "../../weblayer_instrumentation_test_M104/out/Release",
           "--impl-version=104",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -49661,15 +49661,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
-          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
-          "--client-outdir",
-          "../../weblayer_instrumentation_test_M103/out/Release",
           "--implementation-outdir",
           ".",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/SystemWebView.apk",
+          "--client-outdir",
+          "../../weblayer_instrumentation_test_M103/out/Release",
           "--client-version=103",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -49746,15 +49746,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
-          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
-          "--client-outdir",
-          "../../weblayer_instrumentation_test_M104/out/Release",
           "--implementation-outdir",
           ".",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/SystemWebView.apk",
+          "--client-outdir",
+          "../../weblayer_instrumentation_test_M104/out/Release",
           "--client-version=104",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -50171,15 +50171,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
-          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
           "--client-outdir",
           ".",
-          "--implementation-outdir",
-          "../../weblayer_instrumentation_test_M103/out/Release",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/SystemWebView.apk",
+          "--implementation-outdir",
+          "../../weblayer_instrumentation_test_M103/out/Release",
           "--impl-version=103",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -50256,15 +50256,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
-          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
           "--client-outdir",
           ".",
-          "--implementation-outdir",
-          "../../weblayer_instrumentation_test_M104/out/Release",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--webview-apk-path=apks/SystemWebView.apk",
+          "--implementation-outdir",
+          "../../weblayer_instrumentation_test_M104/out/Release",
           "--impl-version=104",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl
index 0779afc..8c535e2 100644
--- a/testing/buildbot/variants.pyl
+++ b/testing/buildbot/variants.pyl
@@ -493,16 +493,16 @@
   },
   'WEBLAYER_10_AND_M_IMPL_SKEW_TESTS_NTH_MILESTONE': {
     'args': [
-      '--webview-apk-path=apks/AOSP_SystemWebView.apk',
       '--test-runner-outdir',
       '.',
       '--client-outdir',
       '.',
-      '--implementation-outdir',
-      '../../weblayer_instrumentation_test_M104/out/Release',
       '--test-expectations',
       '../../weblayer/browser/android/javatests/skew/expectations.txt',
-      '--impl-version=104',
+      '--webview-apk-path=apks/AOSP_SystemWebView.apk',
+      '--implementation-outdir',
+      '../../weblayer_instrumentation_test_M104/out/Release',
+      '--impl-version=104'
     ],
     'identifier': 'with_impl_from_104',
     'swarming': {
@@ -510,23 +510,23 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M104',
-          'revision': 'version:104.0.5112.12',
+          'revision': 'version:104.0.5112.12'
         }
-      ],
-    },
+      ]
+    }
   },
   'WEBLAYER_10_AND_M_IMPL_SKEW_TESTS_NTH_MINUS_ONE_MILESTONE': {
     'args': [
-      '--webview-apk-path=apks/AOSP_SystemWebView.apk',
       '--test-runner-outdir',
       '.',
       '--client-outdir',
       '.',
-      '--implementation-outdir',
-      '../../weblayer_instrumentation_test_M103/out/Release',
       '--test-expectations',
       '../../weblayer/browser/android/javatests/skew/expectations.txt',
-      '--impl-version=103',
+      '--webview-apk-path=apks/AOSP_SystemWebView.apk',
+      '--implementation-outdir',
+      '../../weblayer_instrumentation_test_M103/out/Release',
+      '--impl-version=103'
     ],
     'identifier': 'with_impl_from_103',
     'swarming': {
@@ -534,10 +534,10 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M103',
-          'revision': 'version:103.0.5060.56',
+          'revision': 'version:103.0.5060.56'
         }
-      ],
-    },
+      ]
+    }
   },
   'WEBLAYER_10_AND_M_IMPL_SKEW_TESTS_NTH_MINUS_TWO_MILESTONE': {
     'args': [
@@ -637,16 +637,16 @@
   },
   'WEBLAYER_IMPL_SKEW_TESTS_NTH_MILESTONE': {
     'args': [
-      '--webview-apk-path=apks/SystemWebView.apk',
       '--test-runner-outdir',
       '.',
       '--client-outdir',
       '.',
-      '--implementation-outdir',
-      '../../weblayer_instrumentation_test_M104/out/Release',
       '--test-expectations',
       '../../weblayer/browser/android/javatests/skew/expectations.txt',
-      '--impl-version=104',
+      '--webview-apk-path=apks/SystemWebView.apk',
+      '--implementation-outdir',
+      '../../weblayer_instrumentation_test_M104/out/Release',
+      '--impl-version=104'
     ],
     'identifier': 'with_impl_from_104',
     'swarming': {
@@ -654,23 +654,23 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M104',
-          'revision': 'version:104.0.5112.12',
+          'revision': 'version:104.0.5112.12'
         }
-      ],
-    },
+      ]
+    }
   },
   'WEBLAYER_IMPL_SKEW_TESTS_NTH_MINUS_ONE_MILESTONE': {
     'args': [
-      '--webview-apk-path=apks/SystemWebView.apk',
       '--test-runner-outdir',
       '.',
       '--client-outdir',
       '.',
-      '--implementation-outdir',
-      '../../weblayer_instrumentation_test_M103/out/Release',
       '--test-expectations',
       '../../weblayer/browser/android/javatests/skew/expectations.txt',
-      '--impl-version=103',
+      '--webview-apk-path=apks/SystemWebView.apk',
+      '--implementation-outdir',
+      '../../weblayer_instrumentation_test_M103/out/Release',
+      '--impl-version=103'
     ],
     'identifier': 'with_impl_from_103',
     'swarming': {
@@ -678,10 +678,10 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M103',
-          'revision': 'version:103.0.5060.56',
+          'revision': 'version:103.0.5060.56'
         }
-      ],
-    },
+      ]
+    }
   },
   'WEBLAYER_IMPL_SKEW_TESTS_NTH_MINUS_TWO_MILESTONE': {
     'args': [
@@ -781,16 +781,16 @@
   },
   'WEBLAYER_CLIENT_SKEW_TESTS_NTH_MILESTONE': {
     'args': [
-      '--webview-apk-path=apks/SystemWebView.apk',
       '--test-runner-outdir',
       '.',
-      '--client-outdir',
-      '../../weblayer_instrumentation_test_M104/out/Release',
       '--implementation-outdir',
       '.',
       '--test-expectations',
       '../../weblayer/browser/android/javatests/skew/expectations.txt',
-      '--client-version=104',
+      '--webview-apk-path=apks/SystemWebView.apk',
+      '--client-outdir',
+      '../../weblayer_instrumentation_test_M104/out/Release',
+      '--client-version=104'
     ],
     'identifier': 'with_client_from_104',
     'swarming': {
@@ -798,23 +798,23 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M104',
-          'revision': 'version:104.0.5112.12',
+          'revision': 'version:104.0.5112.12'
         }
-      ],
-    },
+      ]
+    }
   },
   'WEBLAYER_CLIENT_SKEW_TESTS_NTH_MINUS_ONE_MILESTONE': {
     'args': [
-      '--webview-apk-path=apks/SystemWebView.apk',
       '--test-runner-outdir',
       '.',
-      '--client-outdir',
-      '../../weblayer_instrumentation_test_M103/out/Release',
       '--implementation-outdir',
       '.',
       '--test-expectations',
       '../../weblayer/browser/android/javatests/skew/expectations.txt',
-      '--client-version=103',
+      '--webview-apk-path=apks/SystemWebView.apk',
+      '--client-outdir',
+      '../../weblayer_instrumentation_test_M103/out/Release',
+      '--client-version=103'
     ],
     'identifier': 'with_client_from_103',
     'swarming': {
@@ -822,10 +822,10 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M103',
-          'revision': 'version:103.0.5060.56',
+          'revision': 'version:103.0.5060.56'
         }
-      ],
-    },
+      ]
+    }
   },
   'WEBLAYER_CLIENT_SKEW_TESTS_NTH_MINUS_TWO_MILESTONE': {
     'args': [
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc
index 1f951b669..9058f30 100644
--- a/third_party/blink/common/features.cc
+++ b/third_party/blink/common/features.cc
@@ -1535,6 +1535,10 @@
 const base::Feature kLocalFrameRootPrePostFCPMetrics{
     "LocalFrameRootPrePostFCPMetrics", base::FEATURE_DISABLED_BY_DEFAULT};
 
+// TODO(mahesh.ma): Enable for supported Android versions once feature is ready.
+const base::Feature kStylusWritingToInput{"StylusWritingToInput",
+                                          base::FEATURE_DISABLED_BY_DEFAULT};
+
 const base::Feature kDisableArrayBufferSizeLimitsForTesting{
     "DisableArrayBufferSizeLimitsForTesting",
     base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h
index d2525a1..11d4b4ab7 100644
--- a/third_party/blink/public/common/features.h
+++ b/third_party/blink/public/common/features.h
@@ -782,6 +782,9 @@
 // See https://crbug.com/1330675.
 BLINK_COMMON_EXPORT extern const base::Feature kLocalFrameRootPrePostFCPMetrics;
 
+// Stylus handwriting recognition to text input feature.
+BLINK_COMMON_EXPORT extern const base::Feature kStylusWritingToInput;
+
 // TODO(https://crbug.com/1201109): temporary flag to disable new ArrayBuffer
 // size limits, so that tests can be written against code receiving these
 // buffers. Remove when the bindings code instituting these limits is removed.
diff --git a/third_party/blink/public/mojom/page/widget.mojom b/third_party/blink/public/mojom/page/widget.mojom
index 57015ef6..08cc8e0e 100644
--- a/third_party/blink/public/mojom/page/widget.mojom
+++ b/third_party/blink/public/mojom/page/widget.mojom
@@ -76,6 +76,12 @@
   // Notifies the Widget that the system drag and drop operation has ended.
   DragSourceSystemDragEnded();
 
+  // Notifies the Widget that stylus writing has started. This is used primarily
+  // to focus the input element where writing was detected to allow committing
+  // recognized text. Stylus writing ends with a Ime commit and we do not need
+  // another message that writing has ended.
+  OnStartStylusWriting();
+
   // Makes the Widget background transparent or opaque.
   SetBackgroundOpaque(bool opaque);
 
diff --git a/third_party/blink/public/web/web_element.h b/third_party/blink/public/web/web_element.h
index af80bdb8..f795f64 100644
--- a/third_party/blink/public/web/web_element.h
+++ b/third_party/blink/public/web/web_element.h
@@ -116,12 +116,6 @@
   // Returns the original image size.
   gfx::Size GetImageSize();
 
-  // Returns {clientWidth, clientHeight}.
-  gfx::Size GetClientSize();
-
-  // Returns {scrollWidth, scrollHeight}.
-  gfx::Size GetScrollSize();
-
   // ComputedStyle property values. The following exposure is of CSS property
   // values are part of the ComputedStyle set which is usually exposed through
   // the Window object in WebIDL as window.getComputedStyle(element). Exposing
diff --git a/third_party/blink/renderer/core/css/css_properties.json5 b/third_party/blink/renderer/core/css/css_properties.json5
index 6ba0f7c3..01aa2d18 100644
--- a/third_party/blink/renderer/core/css/css_properties.json5
+++ b/third_party/blink/renderer/core/css/css_properties.json5
@@ -4752,7 +4752,7 @@
       name: "touch-action",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
       field_group: "*",
-      field_size: 7, // FIXME: Make this use "kTouchActionBits".
+      field_size: 8, // FIXME: Make this use "kTouchActionBits".
       field_template: "primitive",
       include_paths: ["third_party/blink/renderer/platform/graphics/touch_action.h"],
       default_value: "TouchAction::kAuto",
diff --git a/third_party/blink/renderer/core/css/resolver/style_adjuster.cc b/third_party/blink/renderer/core/css/resolver/style_adjuster.cc
index 25373d0..729b6bd 100644
--- a/third_party/blink/renderer/core/css/resolver/style_adjuster.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_adjuster.cc
@@ -101,8 +101,11 @@
   }
   bool is_child_document = element && element == document_element &&
                            element->GetDocument().LocalOwner();
-  if (scrolls_overflow || is_child_document)
-    return touch_action | TouchAction::kPan | TouchAction::kInternalPanXScrolls;
+  if (scrolls_overflow || is_child_document) {
+    return touch_action | TouchAction::kPan |
+           TouchAction::kInternalPanXScrolls |
+           TouchAction::kInternalNotWritable;
+  }
   return touch_action;
 }
 
@@ -630,6 +633,16 @@
   return false;
 }
 
+bool StyleAdjuster::IsPasswordFieldWithUnrevealedPassword(Element* element) {
+  if (!element)
+    return false;
+  if (auto* input = DynamicTo<HTMLInputElement>(element)) {
+    return (input->type() == input_type_names::kPassword) &&
+           !input->ShouldRevealPassword();
+  }
+  return false;
+}
+
 void StyleAdjuster::AdjustEffectiveTouchAction(
     ComputedStyle& style,
     const ComputedStyle& parent_style,
@@ -662,6 +675,12 @@
     if ((element_touch_action & TouchAction::kPanX) != TouchAction::kNone) {
       element_touch_action |= TouchAction::kInternalPanXScrolls;
     }
+
+    // kInternalNotWritable is only for internal usage, GetTouchAction()
+    // doesn't contain this bit. We set this bit when kPan is set so it can be
+    // cleared for eligible non-password editable areas later on.
+    if ((element_touch_action & TouchAction::kPan) != TouchAction::kNone)
+      element_touch_action |= TouchAction::kInternalNotWritable;
   }
 
   if (!element) {
@@ -675,6 +694,7 @@
   if (is_child_document && element->GetDocument().GetFrame()) {
     inherited_action &=
         TouchAction::kPan | TouchAction::kInternalPanXScrolls |
+        TouchAction::kInternalNotWritable |
         element->GetDocument().GetFrame()->InheritedEffectiveTouchAction();
   }
 
@@ -696,6 +716,13 @@
     element_touch_action &= ~TouchAction::kInternalPanXScrolls;
   }
 
+  if (base::FeatureList::IsEnabled(blink::features::kStylusWritingToInput) &&
+      (element_touch_action & TouchAction::kPan) == TouchAction::kPan &&
+      IsEditableElement(element, style) &&
+      !IsPasswordFieldWithUnrevealedPassword(element)) {
+    element_touch_action &= ~TouchAction::kInternalNotWritable;
+  }
+
   // Apply the adjusted parent effective touch actions.
   style.SetEffectiveTouchAction((element_touch_action & inherited_action) |
                                 enforced_by_policy);
diff --git a/third_party/blink/renderer/core/css/resolver/style_adjuster.h b/third_party/blink/renderer/core/css/resolver/style_adjuster.h
index 307c39e..9023062 100644
--- a/third_party/blink/renderer/core/css/resolver/style_adjuster.h
+++ b/third_party/blink/renderer/core/css/resolver/style_adjuster.h
@@ -47,6 +47,7 @@
 
  private:
   static bool IsEditableElement(Element*, const ComputedStyle&);
+  static bool IsPasswordFieldWithUnrevealedPassword(Element*);
   static void AdjustEffectiveTouchAction(ComputedStyle& style,
                                          const ComputedStyle& parent_style,
                                          Element* element,
diff --git a/third_party/blink/renderer/core/css/resolver/style_adjuster_test.cc b/third_party/blink/renderer/core/css/resolver/style_adjuster_test.cc
index 0783d5c0..630dcc2 100644
--- a/third_party/blink/renderer/core/css/resolver/style_adjuster_test.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_adjuster_test.cc
@@ -4,6 +4,7 @@
 
 #include "base/test/scoped_feature_list.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/features.h"
 #include "third_party/blink/renderer/core/dom/node_computed_style.h"
 #include "third_party/blink/renderer/core/frame/event_handler_registry.h"
 #include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
@@ -56,7 +57,8 @@
   UpdateAllLifecyclePhasesForTest();
 
   Element* target = GetDocument().getElementById("target");
-  EXPECT_EQ(TouchAction::kManipulation | TouchAction::kInternalPanXScrolls,
+  EXPECT_EQ(TouchAction::kManipulation | TouchAction::kInternalPanXScrolls |
+                TouchAction::kInternalNotWritable,
             target->GetComputedStyle()->GetEffectiveTouchAction());
 }
 
@@ -72,20 +74,22 @@
   UpdateAllLifecyclePhasesForTest();
 
   Element* target = GetDocument().getElementById("target");
-  EXPECT_EQ(TouchAction::kPanX | TouchAction::kInternalPanXScrolls,
+  EXPECT_EQ(TouchAction::kPanX | TouchAction::kInternalPanXScrolls |
+                TouchAction::kInternalNotWritable,
             target->GetComputedStyle()->GetEffectiveTouchAction());
 
   Element* ancestor = GetDocument().getElementById("ancestor");
   ancestor->setAttribute(html_names::kStyleAttr, "touch-action: pan-y");
   UpdateAllLifecyclePhasesForTest();
-  EXPECT_EQ(TouchAction::kPanY,
+  EXPECT_EQ(TouchAction::kPanY | TouchAction::kInternalNotWritable,
             target->GetComputedStyle()->GetEffectiveTouchAction());
 
   Element* potential_scroller =
       GetDocument().getElementById("potential-scroller");
   potential_scroller->setAttribute(html_names::kStyleAttr, "overflow: scroll");
   UpdateAllLifecyclePhasesForTest();
-  EXPECT_EQ(TouchAction::kPan | TouchAction::kInternalPanXScrolls,
+  EXPECT_EQ(TouchAction::kPan | TouchAction::kInternalPanXScrolls |
+                TouchAction::kInternalNotWritable,
             target->GetComputedStyle()->GetEffectiveTouchAction());
 }
 
@@ -100,13 +104,15 @@
   UpdateAllLifecyclePhasesForTest();
 
   Element* target = GetDocument().getElementById("target");
-  EXPECT_EQ(TouchAction::kPanRight | TouchAction::kInternalPanXScrolls,
+  EXPECT_EQ(TouchAction::kPanRight | TouchAction::kInternalPanXScrolls |
+                TouchAction::kInternalNotWritable,
             target->GetComputedStyle()->GetEffectiveTouchAction());
 
   Element* parent = GetDocument().getElementById("parent");
   parent->setAttribute(html_names::kStyleAttr, "touch-action: auto");
   UpdateAllLifecyclePhasesForTest();
-  EXPECT_EQ(TouchAction::kPanX | TouchAction::kInternalPanXScrolls,
+  EXPECT_EQ(TouchAction::kPanX | TouchAction::kInternalPanXScrolls |
+                TouchAction::kInternalNotWritable,
             target->GetComputedStyle()->GetEffectiveTouchAction());
 }
 
@@ -175,12 +181,96 @@
   UpdateAllLifecyclePhasesForTest();
 
   Element* target = GetDocument().getElementById("target");
-  EXPECT_EQ(TouchAction::kPanY,
+  EXPECT_EQ(TouchAction::kPanY | TouchAction::kInternalNotWritable,
             target->GetComputedStyle()->GetEffectiveTouchAction());
 
   target->setAttribute(html_names::kContenteditableAttr, "true");
   UpdateAllLifecyclePhasesForTest();
-  EXPECT_EQ(TouchAction::kPanY,
+  EXPECT_EQ(TouchAction::kPanY | TouchAction::kInternalNotWritable,
+            target->GetComputedStyle()->GetEffectiveTouchAction());
+}
+
+TEST_F(StyleAdjusterTest, TouchActionNotWritableReEnabledByScrollers) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitWithFeatures({blink::features::kStylusWritingToInput}, {});
+  GetDocument().SetBaseURLOverride(KURL("http://test.com"));
+  SetBodyInnerHTML(R"HTML(
+    <style>#ancestor { margin: 0; touch-action: none; }
+    #scroller { overflow: auto; width: 100px; height: 100px; }
+    #target { width: 200px; height: 200px; } </style>
+    <div id='ancestor'><div id='scroller'><div id='target'>
+    </div></div></div>
+  )HTML");
+  UpdateAllLifecyclePhasesForTest();
+
+  Element* target = GetDocument().getElementById("target");
+  EXPECT_TRUE((target->GetComputedStyle()->GetEffectiveTouchAction() &
+               TouchAction::kInternalNotWritable) != TouchAction::kNone);
+}
+
+TEST_F(StyleAdjusterTest, TouchActionWritableArea) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitWithFeatures({blink::features::kStylusWritingToInput}, {});
+
+  GetDocument().SetBaseURLOverride(KURL("http://test.com"));
+  SetBodyInnerHTML(R"HTML(
+    <div id='editable1' contenteditable='false'></div>
+    <input type="text" id='input1' disabled>
+    <input type="password" id='password1' disabled>
+    <textarea id="textarea1" readonly></textarea>
+    <div id='editable2' contenteditable='true'></div>
+    <input type="text" id='input2'>
+    <input type="password" id='password2'>
+    <textarea id="textarea2"></textarea>
+  )HTML");
+  UpdateAllLifecyclePhasesForTest();
+
+  EXPECT_EQ(TouchAction::kAuto, GetDocument()
+                                    .getElementById("editable1")
+                                    ->GetComputedStyle()
+                                    ->GetEffectiveTouchAction());
+  EXPECT_EQ(TouchAction::kAuto, GetDocument()
+                                    .getElementById("input1")
+                                    ->GetComputedStyle()
+                                    ->GetEffectiveTouchAction());
+  EXPECT_EQ(TouchAction::kAuto, GetDocument()
+                                    .getElementById("password1")
+                                    ->GetComputedStyle()
+                                    ->GetEffectiveTouchAction());
+  EXPECT_EQ(TouchAction::kAuto, GetDocument()
+                                    .getElementById("textarea1")
+                                    ->GetComputedStyle()
+                                    ->GetEffectiveTouchAction());
+
+  TouchAction expected_input_action =
+      (TouchAction::kAuto & ~TouchAction::kInternalNotWritable);
+  TouchAction expected_pwd_action = TouchAction::kAuto;
+  if (::features::IsSwipeToMoveCursorEnabled()) {
+    expected_input_action &= ~TouchAction::kInternalPanXScrolls;
+    expected_pwd_action &= ~TouchAction::kInternalPanXScrolls;
+  }
+
+  EXPECT_EQ(expected_input_action, GetDocument()
+                                       .getElementById("editable2")
+                                       ->GetComputedStyle()
+                                       ->GetEffectiveTouchAction());
+  EXPECT_EQ(expected_input_action, GetDocument()
+                                       .getElementById("input2")
+                                       ->GetComputedStyle()
+                                       ->GetEffectiveTouchAction());
+  EXPECT_EQ(expected_pwd_action, GetDocument()
+                                     .getElementById("password2")
+                                     ->GetComputedStyle()
+                                     ->GetEffectiveTouchAction());
+  EXPECT_EQ(expected_input_action, GetDocument()
+                                       .getElementById("textarea2")
+                                       ->GetComputedStyle()
+                                       ->GetEffectiveTouchAction());
+
+  Element* target = GetDocument().getElementById("editable1");
+  target->setAttribute(html_names::kContenteditableAttr, "true");
+  UpdateAllLifecyclePhasesForTest();
+  EXPECT_EQ(expected_input_action,
             target->GetComputedStyle()->GetEffectiveTouchAction());
 }
 
diff --git a/third_party/blink/renderer/core/exported/web_element.cc b/third_party/blink/renderer/core/exported/web_element.cc
index 5e11ef9..3fbf2ef 100644
--- a/third_party/blink/renderer/core/exported/web_element.cc
+++ b/third_party/blink/renderer/core/exported/web_element.cc
@@ -196,16 +196,6 @@
   return gfx::Size(image->width(), image->height());
 }
 
-gfx::Size WebElement::GetClientSize() {
-  Element* element = Unwrap<Element>();
-  return gfx::Size(element->clientWidth(), element->clientHeight());
-}
-
-gfx::Size WebElement::GetScrollSize() {
-  Element* element = Unwrap<Element>();
-  return gfx::Size(element->scrollWidth(), element->scrollHeight());
-}
-
 WebString WebElement::GetComputedValue(const WebString& property_name) {
   if (IsNull())
     return WebString();
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
index fe775337..5527d41 100644
--- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
+++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
@@ -88,6 +88,7 @@
 #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
 #include "third_party/blink/renderer/core/html/fenced_frame/document_fenced_frames.h"
 #include "third_party/blink/renderer/core/html/fenced_frame/html_fenced_frame_element.h"
+#include "third_party/blink/renderer/core/html/forms/text_control_element.h"
 #include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
 #include "third_party/blink/renderer/core/html/html_plugin_element.h"
 #include "third_party/blink/renderer/core/html/portal/document_portals.h"
@@ -489,6 +490,26 @@
   CancelDrag();
 }
 
+void WebFrameWidgetImpl::OnStartStylusWriting() {
+  // Focus the stylus writable element for current touch sequence as we have
+  // detected writing has started.
+  LocalFrame* frame = GetPage()->GetFocusController().FocusedFrame();
+  if (!frame)
+    return;
+  Element* stylus_writable_element =
+      frame->GetEventHandler().CurrentTouchDownElement();
+  if (!stylus_writable_element)
+    return;
+  if (auto* text_control = EnclosingTextControl(stylus_writable_element)) {
+    text_control->Focus();
+  } else if (auto* html_element =
+                 DynamicTo<HTMLElement>(stylus_writable_element)) {
+    html_element->Focus();
+  }
+  // TODO(rbug.com/1330821): If we are unable to focus writable element for any
+  // reason, notify browser about the same.
+}
+
 void WebFrameWidgetImpl::SetBackgroundOpaque(bool opaque) {
   View()->SetBaseBackgroundColorOverrideTransparent(!opaque);
 }
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.h b/third_party/blink/renderer/core/frame/web_frame_widget_impl.h
index 9360e14..7851aef 100644
--- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.h
+++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.h
@@ -726,6 +726,7 @@
                       uint32_t key_modifiers,
                       base::OnceClosure callback) override;
   void DragSourceSystemDragEnded() override;
+  void OnStartStylusWriting() override;
   void SetBackgroundOpaque(bool opaque) override;
   void SetActive(bool active) override;
   // For both mainframe and childframe change the text direction of the
diff --git a/third_party/blink/renderer/core/input/event_handler.cc b/third_party/blink/renderer/core/input/event_handler.cc
index 7f137a4e..c1ddef7 100644
--- a/third_party/blink/renderer/core/input/event_handler.cc
+++ b/third_party/blink/renderer/core/input/event_handler.cc
@@ -1413,6 +1413,10 @@
   return mouse_event_manager_->GetElementUnderMouse();
 }
 
+Element* EventHandler::CurrentTouchDownElement() {
+  return pointer_event_manager_->CurrentTouchDownElement();
+}
+
 bool EventHandler::IsPointerIdActiveOnFrame(PointerId pointer_id,
                                             LocalFrame* frame) const {
   DCHECK(frame_ == &frame_->LocalFrameRoot() || frame_ == frame);
diff --git a/third_party/blink/renderer/core/input/event_handler.h b/third_party/blink/renderer/core/input/event_handler.h
index f9b8c39..203a602 100644
--- a/third_party/blink/renderer/core/input/event_handler.h
+++ b/third_party/blink/renderer/core/input/event_handler.h
@@ -284,6 +284,8 @@
 
   Element* GetElementUnderMouse();
 
+  Element* CurrentTouchDownElement();
+
  private:
   WebInputEventResult HandleMouseMoveOrLeaveEvent(
       const WebMouseEvent&,
diff --git a/third_party/blink/renderer/core/input/pointer_event_manager.cc b/third_party/blink/renderer/core/input/pointer_event_manager.cc
index 185c636..91135bad 100644
--- a/third_party/blink/renderer/core/input/pointer_event_manager.cc
+++ b/third_party/blink/renderer/core/input/pointer_event_manager.cc
@@ -1171,4 +1171,8 @@
   return pointer_event_factory_.GetPointerEventId(web_pointer_properties);
 }
 
+Element* PointerEventManager::CurrentTouchDownElement() {
+  return touch_event_manager_->CurrentTouchDownElement();
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/input/pointer_event_manager.h b/third_party/blink/renderer/core/input/pointer_event_manager.h
index 059bc9bb..438e465e 100644
--- a/third_party/blink/renderer/core/input/pointer_event_manager.h
+++ b/third_party/blink/renderer/core/input/pointer_event_manager.h
@@ -113,6 +113,8 @@
   int GetPointerEventId(
       const WebPointerProperties& web_pointer_properties) const;
 
+  Element* CurrentTouchDownElement();
+
  private:
   class EventTargetAttributes : public GarbageCollected<EventTargetAttributes> {
    public:
diff --git a/third_party/blink/renderer/core/input/touch_action_test.cc b/third_party/blink/renderer/core/input/touch_action_test.cc
index c34f845..833b137a 100644
--- a/third_party/blink/renderer/core/input/touch_action_test.cc
+++ b/third_party/blink/renderer/core/input/touch_action_test.cc
@@ -363,23 +363,28 @@
           EXPECT_EQ(TouchAction::kAuto, widget->LastTouchAction())
               << failure_context_pos;
         } else if (expected_action == "none") {
-          EXPECT_EQ(TouchAction::kNone, widget->LastTouchAction())
+          EXPECT_EQ(TouchAction::kNone, widget->LastTouchAction() &
+                                            ~TouchAction::kInternalNotWritable)
               << failure_context_pos;
         } else if (expected_action == "pan-x") {
           EXPECT_EQ(TouchAction::kPanX, widget->LastTouchAction() &
-                                            ~TouchAction::kInternalPanXScrolls)
+                                            ~TouchAction::kInternalPanXScrolls &
+                                            ~TouchAction::kInternalNotWritable)
               << failure_context_pos;
         } else if (expected_action == "pan-y") {
-          EXPECT_EQ(TouchAction::kPanY, widget->LastTouchAction())
+          EXPECT_EQ(TouchAction::kPanY, widget->LastTouchAction() &
+                                            ~TouchAction::kInternalNotWritable)
               << failure_context_pos;
         } else if (expected_action == "pan-x-y") {
           EXPECT_EQ(TouchAction::kPan, widget->LastTouchAction() &
-                                           ~TouchAction::kInternalPanXScrolls)
+                                           ~TouchAction::kInternalPanXScrolls &
+                                           ~TouchAction::kInternalNotWritable)
               << failure_context_pos;
         } else if (expected_action == "manipulation") {
-          EXPECT_EQ(
-              TouchAction::kManipulation,
-              widget->LastTouchAction() & ~TouchAction::kInternalPanXScrolls)
+          EXPECT_EQ(TouchAction::kManipulation,
+                    widget->LastTouchAction() &
+                        ~TouchAction::kInternalPanXScrolls &
+                        ~TouchAction::kInternalNotWritable)
               << failure_context_pos;
         } else {
           FAIL() << "Unrecognized expected-action " << expected_action << " "
diff --git a/third_party/blink/renderer/core/input/touch_event_manager.cc b/third_party/blink/renderer/core/input/touch_event_manager.cc
index 9b9ce13d..092a7c35 100644
--- a/third_party/blink/renderer/core/input/touch_event_manager.cc
+++ b/third_party/blink/renderer/core/input/touch_event_manager.cc
@@ -575,6 +575,16 @@
     }
   }
 
+  // Re-enable not writable bit if effective touch action does not allow panning
+  // in all directions as writing can be started in any direction. Also, enable
+  // this bit if pointer type is not stylus.
+  if ((effective_touch_action & TouchAction::kPan) != TouchAction::kNone &&
+      ((event.pointer_type != WebPointerProperties::PointerType::kPen &&
+        event.pointer_type != WebPointerProperties::PointerType::kEraser) ||
+       (effective_touch_action & TouchAction::kPan) != TouchAction::kPan)) {
+    effective_touch_action |= TouchAction::kInternalNotWritable;
+  }
+
   should_enforce_vertical_scroll_ =
       touch_sequence_document_->IsVerticalScrollEnforced();
   if (should_enforce_vertical_scroll_ &&
@@ -698,6 +708,13 @@
   return !touch_attribute_map_.IsEmpty();
 }
 
+Element* TouchEventManager::CurrentTouchDownElement() {
+  if (touch_attribute_map_.IsEmpty() || touch_attribute_map_.size() > 1)
+    return nullptr;
+  Node* touch_node = touch_attribute_map_.begin()->value->target_;
+  return touch_node ? DynamicTo<Element>(*touch_node) : nullptr;
+}
+
 WebInputEventResult TouchEventManager::EnsureVerticalScrollIsPossible(
     WebInputEventResult event_result) {
   bool prevent_defaulted =
diff --git a/third_party/blink/renderer/core/input/touch_event_manager.h b/third_party/blink/renderer/core/input/touch_event_manager.h
index 8843365..1f199dd 100644
--- a/third_party/blink/renderer/core/input/touch_event_manager.h
+++ b/third_party/blink/renderer/core/input/touch_event_manager.h
@@ -56,6 +56,9 @@
       const WebPointerEvent&,
       const event_handling_util::PointerEventTarget&);
 
+  // Return the touch down element of current touch sequence.
+  Element* CurrentTouchDownElement();
+
  private:
   // Class represending one touch point event with its coalesced events and
   // related attributes.
diff --git a/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc b/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc
index 351f70a..7889cf1 100644
--- a/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc
+++ b/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc
@@ -514,7 +514,7 @@
   const auto* cc_layer = ScrollingContentsLayerByDOMElementId("scrollable");
   cc::Region region = cc_layer->touch_action_region().GetRegionForTouchAction(
       TouchAction::kPanX | TouchAction::kPanDown |
-      TouchAction::kInternalPanXScrolls);
+      TouchAction::kInternalPanXScrolls | TouchAction::kInternalNotWritable);
   EXPECT_EQ(region.GetRegionComplexity(), 1);
   EXPECT_EQ(region.bounds(), gfx::Rect(0, 0, 1000, 1000));
 }
@@ -526,18 +526,18 @@
 
   cc::Region region = cc_layer->touch_action_region().GetRegionForTouchAction(
       TouchAction::kPanDown | TouchAction::kPanX |
-      TouchAction::kInternalPanXScrolls);
+      TouchAction::kInternalPanXScrolls | TouchAction::kInternalNotWritable);
   EXPECT_EQ(region.GetRegionComplexity(), 1);
   EXPECT_EQ(region.bounds(), gfx::Rect(0, 0, 100, 100));
 
   region = cc_layer->touch_action_region().GetRegionForTouchAction(
       TouchAction::kPanDown | TouchAction::kPanRight |
-      TouchAction::kInternalPanXScrolls);
+      TouchAction::kInternalPanXScrolls | TouchAction::kInternalNotWritable);
   EXPECT_EQ(region.GetRegionComplexity(), 1);
   EXPECT_EQ(region.bounds(), gfx::Rect(0, 0, 50, 50));
 
   region = cc_layer->touch_action_region().GetRegionForTouchAction(
-      TouchAction::kPanDown);
+      TouchAction::kPanDown | TouchAction::kInternalNotWritable);
   EXPECT_EQ(region.GetRegionComplexity(), 1);
   EXPECT_EQ(region.bounds(), gfx::Rect(0, 100, 100, 100));
 }
@@ -574,7 +574,8 @@
   const auto* cc_layer = ScrollingContentsLayerByDOMElementId("scrollable");
 
   cc::Region region = cc_layer->touch_action_region().GetRegionForTouchAction(
-      TouchAction::kPanX | TouchAction::kInternalPanXScrolls);
+      TouchAction::kPanX | TouchAction::kInternalPanXScrolls |
+      TouchAction::kInternalNotWritable);
   EXPECT_EQ(region.GetRegionComplexity(), 2);
   EXPECT_EQ(region.bounds(), gfx::Rect(5, 5, 150, 100));
 }
@@ -611,7 +612,8 @@
   const auto* cc_layer = ScrollingContentsLayerByDOMElementId("scrollable");
 
   cc::Region region = cc_layer->touch_action_region().GetRegionForTouchAction(
-      TouchAction::kPanX | TouchAction::kInternalPanXScrolls);
+      TouchAction::kPanX | TouchAction::kInternalPanXScrolls |
+      TouchAction::kInternalNotWritable);
   EXPECT_EQ(region.GetRegionComplexity(), 2);
   EXPECT_EQ(region.bounds(), gfx::Rect(5, 5, 150, 100));
 
@@ -619,7 +621,8 @@
   scrollable->setAttribute("style", "touch-action: none", ASSERT_NO_EXCEPTION);
   ForceFullCompositingUpdate();
   region = cc_layer->touch_action_region().GetRegionForTouchAction(
-      TouchAction::kPanX | TouchAction::kInternalPanXScrolls);
+      TouchAction::kPanX | TouchAction::kInternalPanXScrolls |
+      TouchAction::kInternalNotWritable);
   EXPECT_TRUE(region.IsEmpty());
 }
 
@@ -648,7 +651,8 @@
   const auto* cc_layer = MainFrameScrollingContentsLayer();
 
   cc::Region region = cc_layer->touch_action_region().GetRegionForTouchAction(
-      TouchAction::kPanX | TouchAction::kInternalPanXScrolls);
+      TouchAction::kPanX | TouchAction::kInternalPanXScrolls |
+      TouchAction::kInternalNotWritable);
   EXPECT_EQ(region.bounds(), gfx::Rect(8, 8, 150, 50));
   region = cc_layer->touch_action_region().GetRegionForTouchAction(
       TouchAction::kNone);
@@ -659,13 +663,15 @@
   ForceFullCompositingUpdate();
 
   region = cc_layer->touch_action_region().GetRegionForTouchAction(
-      TouchAction::kPanY);
+      TouchAction::kPanY | TouchAction::kInternalNotWritable);
   EXPECT_EQ(region.bounds(), gfx::Rect(8, 8, 100, 100));
   region = cc_layer->touch_action_region().GetRegionForTouchAction(
-      TouchAction::kPanX | TouchAction::kInternalPanXScrolls);
+      TouchAction::kPanX | TouchAction::kInternalPanXScrolls |
+      TouchAction::kInternalNotWritable);
   EXPECT_TRUE(region.IsEmpty());
+  // kInternalNotWritable is set when any of the pans are allowed.
   region = cc_layer->touch_action_region().GetRegionForTouchAction(
-      TouchAction::kNone);
+      TouchAction::kNone | TouchAction::kInternalNotWritable);
   EXPECT_EQ(region.bounds(), gfx::Rect(8, 8, 150, 50));
 }
 
@@ -691,7 +697,7 @@
   ForceFullCompositingUpdate();
   const auto* cc_layer = MainFrameScrollingContentsLayer();
   cc::Region region = cc_layer->touch_action_region().GetRegionForTouchAction(
-      TouchAction::kManipulation);
+      TouchAction::kManipulation | TouchAction::kInternalNotWritable);
   EXPECT_EQ(region.bounds(), gfx::Rect(8, 8, 100, 50));
   region = cc_layer->touch_action_region().GetRegionForTouchAction(
       TouchAction::kNone);
@@ -705,7 +711,8 @@
 
   cc_layer = ScrollingContentsLayerByDOMElementId("touchaction");
   region = cc_layer->touch_action_region().GetRegionForTouchAction(
-      TouchAction::kManipulation | TouchAction::kInternalPanXScrolls);
+      TouchAction::kManipulation | TouchAction::kInternalPanXScrolls |
+      TouchAction::kInternalNotWritable);
   EXPECT_EQ(region.bounds(), gfx::Rect(0, 0, 1000, 100));
   region = cc_layer->touch_action_region().GetRegionForTouchAction(
       TouchAction::kNone);
@@ -784,7 +791,7 @@
   EXPECT_EQ(region.bounds(), gfx::Rect(0, 0, 100, 100));
 
   region = cc_layer->touch_action_region().GetRegionForTouchAction(
-      TouchAction::kPanY);
+      TouchAction::kPanY | TouchAction::kInternalNotWritable);
   EXPECT_EQ(region.GetRegionComplexity(), 2);
   EXPECT_EQ(region.bounds(), gfx::Rect(0, 0, 1000, 1000));
 }
@@ -816,12 +823,12 @@
       ScrollingContentsLayerByDOMElementId("scrollable");
   cc::Region region =
       scrolling_contents_layer->touch_action_region().GetRegionForTouchAction(
-          TouchAction::kPanY);
+          TouchAction::kPanY | TouchAction::kInternalNotWritable);
   EXPECT_EQ(region.bounds(), gfx::Rect(0, 0, 50, 150));
 
   const auto* container_layer = MainFrameScrollingContentsLayer();
   region = container_layer->touch_action_region().GetRegionForTouchAction(
-      TouchAction::kPanY);
+      TouchAction::kPanY | TouchAction::kInternalNotWritable);
   EXPECT_EQ(region.bounds(), gfx::Rect(8, 8, 100, 100));
 }
 
diff --git a/third_party/blink/renderer/core/paint/ng/ng_text_painter.cc b/third_party/blink/renderer/core/paint/ng/ng_text_painter.cc
index f766e26..d4968345 100644
--- a/third_party/blink/renderer/core/paint/ng/ng_text_painter.cc
+++ b/third_party/blink/renderer/core/paint/ng/ng_text_painter.cc
@@ -340,9 +340,14 @@
                                  gfx::PointF(text_origin_), node_id,
                                  auto_dark_mode);
     }
-    // TODO(npm): Check that there are non-whitespace characters. See
-    // crbug.com/788444.
-    graphics_context_.GetPaintController().SetTextPainted();
+
+    // TODO(sohom): SubstringContainsOnlyWhitespaceOrEmpty() does not check
+    // for all whitespace characters as defined in the spec definition of
+    // whitespace. See https://w3c.github.io/paint-timing/#non-empty
+    // In particular 0xb and 0xc are not checked.
+    if (!fragment_paint_info_.text.SubstringContainsOnlyWhitespaceOrEmpty(from,
+                                                                          to))
+      graphics_context_.GetPaintController().SetTextPainted();
 
     if (!font_.ShouldSkipDrawing())
       PaintTimingDetector::NotifyTextPaint(visual_rect_);
diff --git a/third_party/blink/renderer/core/style/computed_style_extra_fields.json5 b/third_party/blink/renderer/core/style/computed_style_extra_fields.json5
index 86b1e5c..07334afb 100644
--- a/third_party/blink/renderer/core/style/computed_style_extra_fields.json5
+++ b/third_party/blink/renderer/core/style/computed_style_extra_fields.json5
@@ -479,7 +479,7 @@
       field_template: "primitive",
       include_paths: ["third_party/blink/renderer/platform/graphics/touch_action.h"],
       type_name: "TouchAction",
-      field_size: 7,
+      field_size: 8,
       default_value: "TouchAction::kAuto",
       field_group: "*",
       computed_style_custom_functions: ["getter", "setter"],
diff --git a/third_party/blink/renderer/platform/fonts/font_metrics.h b/third_party/blink/renderer/platform/fonts/font_metrics.h
index f2506e84..fec88c4 100644
--- a/third_party/blink/renderer/platform/fonts/font_metrics.h
+++ b/third_party/blink/renderer/platform/fonts/font_metrics.h
@@ -39,19 +39,6 @@
   DISALLOW_NEW();
 
  public:
-  FontMetrics()
-      : units_per_em_(kGDefaultUnitsPerEm),
-        float_ascent_(0),
-        float_descent_(0),
-        line_gap_(0),
-        line_spacing_(0),
-        x_height_(0),
-        zero_width_(0),
-        int_ascent_(0),
-        int_descent_(0),
-        has_x_height_(false),
-        has_zero_width_(false) {}
-
   unsigned UnitsPerEm() const { return units_per_em_; }
   void SetUnitsPerEm(unsigned units_per_em) { units_per_em_ = units_per_em; }
 
@@ -206,19 +193,19 @@
   PLATFORM_EXPORT float FloatAscentInternal(FontBaseline baseline_type) const;
   PLATFORM_EXPORT int IntAscentInternal(FontBaseline baseline_type) const;
 
-  unsigned units_per_em_;
-  float float_ascent_;
-  float float_descent_;
-  float line_gap_;
-  float line_spacing_;
-  float x_height_;
-  float zero_width_;
-  absl::optional<float> underline_thickness_ = absl::nullopt;
-  absl::optional<float> underline_position_ = absl::nullopt;
-  int int_ascent_;
-  int int_descent_;
-  bool has_x_height_;
-  bool has_zero_width_;
+  unsigned units_per_em_ = kGDefaultUnitsPerEm;
+  float float_ascent_ = 0;
+  float float_descent_ = 0;
+  float line_gap_ = 0;
+  float line_spacing_ = 0;
+  float x_height_ = 0;
+  float zero_width_ = 0;
+  absl::optional<float> underline_thickness_;
+  absl::optional<float> underline_position_;
+  int int_ascent_ = 0;
+  int int_descent_ = 0;
+  bool has_x_height_ = false;
+  bool has_zero_width_ = false;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/loader/DEPS b/third_party/blink/renderer/platform/loader/DEPS
index 786672c..4e75f7f 100644
--- a/third_party/blink/renderer/platform/loader/DEPS
+++ b/third_party/blink/renderer/platform/loader/DEPS
@@ -51,22 +51,6 @@
   "resource_error\.cc": [
     "+net/base/net_errors.h"
   ],
-  "ftp_directory_listing.cc": [
-    "+base/i18n/encoding_detection.h",
-    "+base/i18n/icu_string_conversions.h",
-    "+base/strings/string_util.h",
-    "+base/strings/sys_string_conversions.h",
-    "+base/strings/utf_string_conversions.h",
-    "+net/base/directory_listing.h",
-    "+base/strings/escape.h",
-    "+net/base/net_errors.h",
-    "+net/ftp/ftp_directory_listing_parser.h",
-    "+net/net_buildflags.h",
-  ],
-  "ftp_directory_listing_test.cc": [
-    "+net/net_buildflags.h",
-    "+third_party/icu/source/i18n/unicode/timezone.h"
-  ],
   "replaying_web_data_consumer_handle.h": [
       "+third_party/blink/renderer/platform/waitable_event.h",
   ],
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index e8a140c..5fd1cf87 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1355,6 +1355,11 @@
       implied_by: ["LayoutNGPrinting"],
     },
     {
+      // crbug.com/1335309
+      name: "LayoutNGVTTCue",
+      depends_on: ["LayoutNG"],
+    },
+    {
       name: "LazyFrameLoading",
       status: "stable",
     },
diff --git a/third_party/blink/renderer/platform/text/platform_locale.cc b/third_party/blink/renderer/platform/text/platform_locale.cc
index c62d0c5d..46f975a 100644
--- a/third_party/blink/renderer/platform/text/platform_locale.cc
+++ b/third_party/blink/renderer/platform/text/platform_locale.cc
@@ -368,6 +368,7 @@
                                         bool& is_negative,
                                         unsigned& start_index,
                                         unsigned& end_index) {
+  DCHECK_EQ(input.Find(IsASCIISpace), WTF::kNotFound);
   start_index = 0;
   end_index = input.length();
   if (negative_prefix_.IsEmpty() && negative_suffix_.IsEmpty()) {
@@ -380,11 +381,18 @@
       is_negative = true;
     }
   } else {
-    if (input.StartsWith(negative_prefix_) &&
-        input.EndsWith(negative_suffix_)) {
+    // For some locales the negative prefix and/or suffix are preceded or
+    // followed by whitespace. Exclude that for the purposes of this search
+    // since the input string has already been stripped of whitespace.
+    const String negative_prefix_without_whitespace =
+        negative_prefix_.StripWhiteSpace();
+    const String negative_suffix_without_whitespace =
+        negative_suffix_.StripWhiteSpace();
+    if (input.StartsWith(negative_prefix_without_whitespace) &&
+        input.EndsWith(negative_suffix_without_whitespace)) {
       is_negative = true;
-      start_index = negative_prefix_.length();
-      end_index -= negative_suffix_.length();
+      start_index = negative_prefix_without_whitespace.length();
+      end_index -= negative_suffix_without_whitespace.length();
     } else {
       is_negative = false;
       if (input.StartsWith(positive_prefix_) &&
diff --git a/third_party/blink/renderer/platform/wtf/text/string_view.cc b/third_party/blink/renderer/platform/wtf/text/string_view.cc
index 7b5be31..8a40502 100644
--- a/third_party/blink/renderer/platform/wtf/text/string_view.cc
+++ b/third_party/blink/renderer/platform/wtf/text/string_view.cc
@@ -157,6 +157,29 @@
   return attrs.contains_only_ascii;
 }
 
+bool StringView::SubstringContainsOnlyWhitespaceOrEmpty(unsigned from,
+                                                        unsigned to) const {
+  SECURITY_DCHECK(from <= length());
+  SECURITY_DCHECK(to <= length());
+  DCHECK(from <= to);
+
+  if (Is8Bit()) {
+    for (wtf_size_t i = from; i < to; ++i) {
+      if (!IsASCIISpace(Characters8()[i]))
+        return false;
+    }
+
+    return true;
+  }
+
+  for (wtf_size_t i = from; i < to; ++i) {
+    if (!IsASCIISpace(Characters16()[i]))
+      return false;
+  }
+
+  return true;
+}
+
 String StringView::ToString() const {
   if (IsNull())
     return String();
diff --git a/third_party/blink/renderer/platform/wtf/text/string_view.h b/third_party/blink/renderer/platform/wtf/text/string_view.h
index 2b15989..fd7ed08d 100644
--- a/third_party/blink/renderer/platform/wtf/text/string_view.h
+++ b/third_party/blink/renderer/platform/wtf/text/string_view.h
@@ -165,6 +165,8 @@
 
   bool ContainsOnlyASCIIOrEmpty() const;
 
+  bool SubstringContainsOnlyWhitespaceOrEmpty(unsigned from, unsigned to) const;
+
   void Clear();
 
   UChar operator[](unsigned i) const {
diff --git a/third_party/blink/renderer/platform/wtf/text/string_view_test.cc b/third_party/blink/renderer/platform/wtf/text/string_view_test.cc
index 1240862..95ac2d6b 100644
--- a/third_party/blink/renderer/platform/wtf/text/string_view_test.cc
+++ b/third_party/blink/renderer/platform/wtf/text/string_view_test.cc
@@ -308,6 +308,23 @@
   EXPECT_EQ("3", StringView(view16_bit, 2, 1));
 }
 
+TEST(StringViewTest, SubstringContainsOnlyWhitespaceOrEmpty) {
+  EXPECT_TRUE(StringView("  ").SubstringContainsOnlyWhitespaceOrEmpty(0, 1));
+  EXPECT_TRUE(StringView("  ").SubstringContainsOnlyWhitespaceOrEmpty(0, 2));
+  EXPECT_TRUE(StringView("\x20\x09\x0A\x0D")
+                  .SubstringContainsOnlyWhitespaceOrEmpty(0, 4));
+  EXPECT_FALSE(StringView(" a").SubstringContainsOnlyWhitespaceOrEmpty(0, 2));
+  EXPECT_TRUE(StringView(" ").SubstringContainsOnlyWhitespaceOrEmpty(1, 1));
+  EXPECT_TRUE(StringView("").SubstringContainsOnlyWhitespaceOrEmpty(0, 0));
+  EXPECT_TRUE(
+      StringView("  \nABC").SubstringContainsOnlyWhitespaceOrEmpty(0, 3));
+  EXPECT_FALSE(StringView(" \u090A\n")
+                   .SubstringContainsOnlyWhitespaceOrEmpty(
+                       0, StringView(" \u090A\n").length()));
+  EXPECT_FALSE(
+      StringView("\n\x08\x1B").SubstringContainsOnlyWhitespaceOrEmpty(0, 3));
+}
+
 TEST(StringViewTest, ConstructionLiteral8) {
   // StringView(const LChar* chars);
   ASSERT_TRUE(StringView(kChars8).Is8Bit());
diff --git a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
index 6436ba4b..45c9740 100644
--- a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
+++ b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
@@ -1772,6 +1772,9 @@
 # https://chromium-review.googlesource.com/c/chromium/src/+/3422590
 crbug.com/591099 fast/forms/text/input-appearance-scroll-size-mocked.html [ Failure ]
 
+# https://chromium-review.googlesource.com/c/chromium/src/+/3697708
+crbug.com/1337210 external/wpt/paint-timing/fcp-only/fcp-text-input.html [ Failure ]
+
 # HighlightOverlayPainting is only implemented in ng
 crbug.com/1147859 virtual/css-highlight-overlay-painting/* [ Skip ]
 
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 4390f3f..23d94fcd 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -28,6 +28,8 @@
 
 # Temporarily disabled for DevTools.
 crbug.com/1304217 http/tests/devtools/text-source-map.js [ Skip ]
+crbug.com/1304217 http/tests/devtools/runtime/runtime-getProperties.js [ Skip ] # Bug 1325812
+crbug.com/1304217 http/tests/devtools/runtime/runtime-localStorage-getProperties.js [ Skip ] # Bug 1325812
 
 # Expected to time out.
 external/wpt/infrastructure/expected-fail/timeout.html [ Timeout ]
@@ -4806,7 +4808,6 @@
 
 # Paint Timing failures
 crbug.com/1062984 external/wpt/paint-timing/fcp-only/fcp-gradient.html [ Failure ]
-crbug.com/1062984 external/wpt/paint-timing/fcp-only/fcp-text-input.html [ Failure ]
 
 # Contentful First Paint failures
 crbug.com/1322629 external/wpt/paint-timing/fcp-only/fcp-invisible-3d-rotate.html [ Failure ]
diff --git a/third_party/blink/web_tests/external/Version b/third_party/blink/web_tests/external/Version
index f23e75d..e87e072 100644
--- a/third_party/blink/web_tests/external/Version
+++ b/third_party/blink/web_tests/external/Version
@@ -1 +1 @@
-Version: 93a98d6ac4785d3c78b57845d91c78e2bf12c6eb
+Version: d3d0aa492ab758a9b0ab55a27bd3957301071644
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
index 6572308..bf1ff0aa 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -484987,6 +484987,13 @@
       {}
      ]
     ],
+    "clip-path.html": [
+     "a43d3fb7b0a5bc0133233fd060b3a8cb1ce118d8",
+     [
+      null,
+      {}
+     ]
+    ],
     "containing-block.html": [
      "f7ce6fa7246f006883b39479ad9bdda9ed84978c",
      [
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/column-spanner-in-container.html b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/column-spanner-in-container.html
new file mode 100644
index 0000000..d494e285
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/column-spanner-in-container.html
@@ -0,0 +1,41 @@
+<!doctype html>
+<title>CSS Container Queries Test: Column-spanner depending on container in column</title>
+<link rel="help" href="https://drafts.csswg.org/css-contain-3/#size-container">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/cq-testcommon.js"></script>
+<style>
+  #multicol {
+    container-type: inline-size;
+    width: 600px;
+    columns: 2;
+    column-gap: 0;
+    height: 200px;
+  }
+  #spanner { height: 100px; }
+  @container (width = 600px) {
+    #spanner {
+      column-span: all;
+    }
+  }
+</style>
+<div id="multicol">
+  <div id="spanner"></div>
+</div>
+<script>
+  setup(() => assert_implements_container_queries());
+
+  test(() => {
+    assert_equals(getComputedStyle(spanner).width, "600px");
+  }, "#spanner matching container with column-width 300px, getting column-span:all");
+
+  test(() => {
+    multicol.style.width = "500px";
+    assert_equals(getComputedStyle(spanner).width, "250px");
+  }, "Reducing #multicol width means #spanner no longer gets column-span:all");
+
+  test(() => {
+    multicol.style.width = "";
+    assert_equals(getComputedStyle(spanner).width, "600px");
+  }, "Back to matching 300px and column-span:all");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/grid-container.html b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/grid-container.html
new file mode 100644
index 0000000..60278e0
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/grid-container.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<title>CSS Container Queries Test: Grid container</title>
+<link rel="help" href="https://drafts.csswg.org/css-contain-3/#size-container">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/cq-testcommon.js"></script>
+<style>
+  #grid {
+    display: grid;
+    container-type: inline-size;
+    width: 400px;
+    grid-template-columns: 1fr 1fr;
+  }
+  @container (width = 400px) {
+    #grid div { color: green }
+  }
+</style>
+<div id="grid">
+  <div id="item1"></div>
+  <div id="item2"></div>
+</div>
+<script>
+  setup(() => assert_implements_container_queries());
+
+  test(() => {
+    assert_equals(getComputedStyle(item1).color, "rgb(0, 128, 0)");
+    assert_equals(getComputedStyle(item2).color, "rgb(0, 128, 0)");
+  }, "Check that grid items can query grid container");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/grid-item-container.html b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/grid-item-container.html
new file mode 100644
index 0000000..f1c66ef
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/grid-item-container.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<title>CSS Container Queries Test: Grid item container</title>
+<link rel="help" href="https://drafts.csswg.org/css-contain-3/#size-container">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/cq-testcommon.js"></script>
+<style>
+  #grid {
+    width: 300px;
+    display: grid;
+    grid-template-columns: 2fr 1fr;
+  }
+  .item {
+    container-type: inline-size;
+  }
+  @container (width > 50px) {
+    .item div { color: lime; }
+  }
+  @container (width > 150px) {
+    .item div { color: green; }
+  }
+</style>
+<div id="grid">
+  <div class="item">
+    <div id="target1"></div>
+  </div>
+  <div class="item">
+    <div id="target2"></div>
+  </div>
+</div>
+<script>
+  setup(() => assert_implements_container_queries());
+
+  test(() => {
+    assert_equals(getComputedStyle(target1).color, "rgb(0, 128, 0)", "First item container should be 200px wide");
+    assert_equals(getComputedStyle(target2).color, "rgb(0, 255, 0)", "Second item container should be 100px wide");
+  }, "Check that children can query grid item containers");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/intersection-observer/clip-path.html b/third_party/blink/web_tests/external/wpt/intersection-observer/clip-path.html
new file mode 100644
index 0000000..a43d3fb
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/intersection-observer/clip-path.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<meta name="viewport" content="width=device-width,initial-scale=1">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="./resources/intersection-observer-test-utils.js"></script>
+
+<style>
+body { margin: 0 }
+pre, #log {
+  position: absolute;
+  top: 0;
+  left: 200px;
+}
+#target {
+  background-color: green;
+  width: 100px;
+  height: 100px;
+}
+#container {
+  padding: 8px;
+  width: 0px;
+  height: 0px;
+}
+</style>
+
+<div id="container">
+  <div id="target"></div>
+</div>
+
+<script>
+var vw = document.documentElement.clientWidth;
+var vh = document.documentElement.clientHeight;
+
+var entries = [];
+
+promise_test(async function(t) {
+  var target = document.getElementById("target");
+  var container = document.getElementById("container");
+  var root = document.getElementById("root");
+  var observer = new IntersectionObserver(function(changes) {
+    entries = entries.concat(changes)
+  });
+  observer.observe(target);
+  entries = entries.concat(observer.takeRecords());
+  assert_equals(entries.length, 0, "No initial notifications.");
+
+  await waitForNotification();
+
+  checkLastEntry(
+    entries,
+    0,
+    [8, 108, 8, 108, 8, 108, 8, 108, 0, vw, 0, vh, true],
+    "IntersectionObserver notification after first rAF",
+  );
+  container.style.clipPath = "inset(1000px)";
+
+  await waitForNotification();
+
+  checkLastEntry(
+    entries,
+    1,
+    [8, 108, 8, 108, 0, 0, 0, 0, 0, vw, 0, vh, false],
+    "IntersectionObserver should send a not-intersecting notification for a target that gets fully clipped by clip-path.",
+  );
+
+  container.style.clipPath = "";
+
+  await waitForNotification();
+
+  checkLastEntry(
+    entries,
+    2,
+    [8, 108, 8, 108, 8, 108, 8, 108, 0, vw, 0, vh, true],
+    "Intersecting notification after removing display:none on target.",
+  );
+});
+</script>
diff --git a/third_party/blink/web_tests/fast/forms/number/number-validity-badinput.html b/third_party/blink/web_tests/fast/forms/number/number-validity-badinput.html
index d4f7d4a3..cb674fb 100644
--- a/third_party/blink/web_tests/fast/forms/number/number-validity-badinput.html
+++ b/third_party/blink/web_tests/fast/forms/number/number-validity-badinput.html
@@ -19,6 +19,7 @@
 <input type=number id=number>
 <input id=another>
 <input type="number" lang="ar-eg" id="number_ar">
+<input type="number" lang="hr" id="number_hr" step="0.01" value="-0.03">
 </div>
 <script>
 description('A number input fields with a bad input string should make validity.badInput true and have :invalid style.');
@@ -121,6 +122,10 @@
 shouldBeTrue('number_ar.validity.badInput');
 shouldBeEqualToString('number_ar.value', '');
 
+let croatianInput = document.querySelector("#number_hr");
+debug("Croatian number with negative decimal value is valid.");
+shouldBeTrue('croatianInput.checkValidity()');
+
 document.getElementById('parent').innerHTML = '';
 </script>
 </body>
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/paint-timing/with-first-paint/sibling-painting-first-image-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/paint-timing/with-first-paint/sibling-painting-first-image-expected.txt
deleted file mode 100644
index b9a01ca..0000000
--- a/third_party/blink/web_tests/platform/generic/external/wpt/paint-timing/with-first-paint/sibling-painting-first-image-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Frame ignores paint-timing events fired from sibling frame. assert_equals: expected 1 but got 2
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/generic/fast/forms/number/number-validity-badinput-expected.txt b/third_party/blink/web_tests/platform/generic/fast/forms/number/number-validity-badinput-expected.txt
index a18b7ee..5baee0c 100644
--- a/third_party/blink/web_tests/platform/generic/fast/forms/number/number-validity-badinput-expected.txt
+++ b/third_party/blink/web_tests/platform/generic/fast/forms/number/number-validity-badinput-expected.txt
@@ -53,6 +53,8 @@
 Arabic number with two decimal separators is a badInput.
 PASS number_ar.validity.badInput is true
 PASS number_ar.value is ""
+Croatian number with negative decimal value is valid.
+PASS croatianInput.checkValidity() is true
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/third_party/freetype/README.chromium b/third_party/freetype/README.chromium
index a2a5f43..8a13fc98 100644
--- a/third_party/freetype/README.chromium
+++ b/third_party/freetype/README.chromium
@@ -1,7 +1,7 @@
 Name: FreeType
 URL: http://www.freetype.org/
-Version: VER-2-12-1-24-g9c706dcca
-Revision: 9c706dcca71607c9b88fd241eab89320914c78b0
+Version: VER-2-12-1-25-gd9b8a69e9
+Revision: d9b8a69e9a8ba5ac999e721d50c231fe2e01d0bd
 CPEPrefix: cpe:/a:freetype:freetype:2.11.1
 License: Custom license "inspired by the BSD, Artistic, and IJG (Independent
          JPEG Group) licenses"
diff --git a/third_party/webrtc_overrides/metrics.cc b/third_party/webrtc_overrides/metrics.cc
index 6028c256..6c205934 100644
--- a/third_party/webrtc_overrides/metrics.cc
+++ b/third_party/webrtc_overrides/metrics.cc
@@ -25,12 +25,6 @@
       base::HistogramBase::kUmaTargetedHistogramFlag));
 }
 
-Histogram* HistogramFactoryGetCounts(
-    const std::string& name, int min, int max, int bucket_count) {
-  return HistogramFactoryGetCounts(absl::string_view(name), min, max,
-                                   bucket_count);
-}
-
 Histogram* HistogramFactoryGetCountsLinear(absl::string_view name,
                                            int min,
                                            int max,
@@ -40,12 +34,6 @@
       base::HistogramBase::kUmaTargetedHistogramFlag));
 }
 
-Histogram* HistogramFactoryGetCountsLinear(
-    const std::string& name, int min, int max, int bucket_count) {
-  return HistogramFactoryGetCountsLinear(absl::string_view(name), min, max,
-                                         bucket_count);
-}
-
 Histogram* HistogramFactoryGetEnumeration(absl::string_view name,
                                           int boundary) {
   return reinterpret_cast<Histogram*>(base::LinearHistogram::FactoryGet(
@@ -53,23 +41,12 @@
       base::HistogramBase::kUmaTargetedHistogramFlag));
 }
 
-Histogram* HistogramFactoryGetEnumeration(
-    const std::string& name, int boundary) {
-  return HistogramFactoryGetEnumeration(absl::string_view(name), boundary);
-}
-
 Histogram* SparseHistogramFactoryGetEnumeration(absl::string_view name,
                                                 int boundary) {
   return reinterpret_cast<Histogram*>(base::SparseHistogram::FactoryGet(
       std::string(name), base::HistogramBase::kUmaTargetedHistogramFlag));
 }
 
-Histogram* SparseHistogramFactoryGetEnumeration(const std::string& name,
-                                                int boundary) {
-  return SparseHistogramFactoryGetEnumeration(absl::string_view(name),
-                                              boundary);
-}
-
 const char* GetHistogramName(Histogram* histogram_pointer) {
   base::HistogramBase* ptr =
       reinterpret_cast<base::HistogramBase*>(histogram_pointer);
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index e9ee3462..d16004d 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -55125,6 +55125,7 @@
   <int value="-1992999120" label="composite-after-paint"/>
   <int value="-1992488524" label="AutofillAcrossIframes:disabled"/>
   <int value="-1990614981" label="StoragePressureUI:disabled"/>
+  <int value="-1990238241" label="ChromeOSHWVBREncoding:enabled"/>
   <int value="-1989747818" label="TabStripKeyboardFocus:disabled"/>
   <int value="-1989134646" label="PhoneHubUseBle:disabled"/>
   <int value="-1989024058" label="SystemEmojiPickerSearchExtension:disabled"/>
@@ -57201,6 +57202,7 @@
   <int value="-681535143"
       label="UserCloudSigninRestrictionPolicyFetcher:enabled"/>
   <int value="-681434111" label="WebFeed:disabled"/>
+  <int value="-681160117" label="ChromeOSHWVBREncoding:disabled"/>
   <int value="-680787130" label="ExperimentalVRFeatures:disabled"/>
   <int value="-680589442" label="MacRTL:disabled"/>
   <int value="-679585025" label="CaptureModeSelfieCamera:disabled"/>
@@ -77312,6 +77314,7 @@
     to update the enums.
   </summary>
   <int value="-2012727489" label="device.mojom.ScreenOrientation"/>
+  <int value="-71187962" label="supervised_user.mojom.SupervisedUserCommands"/>
   <int value="191605727" label="content.mojom.PepperHost"/>
   <int value="1984681860"
       label="chrome.mojom.OpenSearchDescriptionDocumentHandler"/>
@@ -98728,6 +98731,14 @@
   <int value="927" label="ERROR_VOLLEY_TIMEOUT"/>
   <int value="961" label="ERROR_INSTALL_APK_VERIFICATION_OTHER"/>
   <int value="963" label="ERROR_INSTALL_APK_COPY_FAILURE"/>
+  <int value="1008" label="ERROR_DOWNLOAD_INTERNAL_FREE_SPACE"/>
+  <int value="1010" label="ERROR_DELIVERY_RESPONSE_NOT_FOUND"/>
+  <int value="1148" label="ERROR_INSTALLER_NO_ACTIVE_DOWNLOADDATA"/>
+  <int value="1149" label="ERROR_INSTALLER_TASK_START_FAILED"/>
+  <int value="1402" label="ERROR_VOLLEY_DFE_SERVER"/>
+  <int value="1404" label="ERROR_VOLLEY_NO_CONNECTION"/>
+  <int value="1407" label="ERROR_VOLLEY_TIMEOUT"/>
+  <int value="5200" label="ERROR_DOWNLOAD_FAILED"/>
 </enum>
 
 <enum name="WebApkInstallInfoBarShown">
diff --git a/tools/metrics/histograms/metadata/gcm/histograms.xml b/tools/metrics/histograms/metadata/gcm/histograms.xml
index d6abda9..5f1d01b 100644
--- a/tools/metrics/histograms/metadata/gcm/histograms.xml
+++ b/tools/metrics/histograms/metadata/gcm/histograms.xml
@@ -276,7 +276,7 @@
 </histogram>
 
 <histogram name="GCM.RegistrationCacheStatus" enum="GCMRegistrationCacheStatus"
-    expires_after="2022-07-31">
+    expires_after="2022-11-27">
   <owner>nator@chromium.org</owner>
   <owner>peter@chromium.org</owner>
   <owner>rayankans@chromium.org</owner>
@@ -287,7 +287,7 @@
 </histogram>
 
 <histogram name="GCM.RegistrationRequest" units="requests"
-    expires_after="2018-08-30">
+    expires_after="2022-11-27">
   <owner>peter@chromium.org</owner>
   <summary>
     Number of registration requests sent to Google Cloud Messaging. Recorded
@@ -296,7 +296,7 @@
 </histogram>
 
 <histogram name="GCM.RegistrationRequest.NetErrorCode" enum="NetErrorCodes"
-    expires_after="2021-04-11">
+    expires_after="2022-11-27">
   <owner>peter@chromium.org</owner>
   <owner>platform-capabilities@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/navigation/histograms.xml b/tools/metrics/histograms/metadata/navigation/histograms.xml
index 1a9d350..85c65e8 100644
--- a/tools/metrics/histograms/metadata/navigation/histograms.xml
+++ b/tools/metrics/histograms/metadata/navigation/histograms.xml
@@ -1275,7 +1275,7 @@
 
 <histogram
     name="Navigation.UrlParamFilter.ApplicableClassificationCount{UrlParamFilterClassificationRole}"
-    units="ms" expires_after="2023-01-02">
+    units="count" expires_after="2023-01-02">
   <owner>mreichhoff@chromium.org</owner>
   <owner>wanderview@chromium.org</owner>
   <owner>bcl@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/sharing/histograms.xml b/tools/metrics/histograms/metadata/sharing/histograms.xml
index 24ad5477..206c8a8 100644
--- a/tools/metrics/histograms/metadata/sharing/histograms.xml
+++ b/tools/metrics/histograms/metadata/sharing/histograms.xml
@@ -563,7 +563,7 @@
 </histogram>
 
 <histogram name="Sharing.SharingHubAndroid.{DetailedContentType}.{ShareStatus}"
-    enum="LinkToggleState" expires_after="M105">
+    enum="LinkToggleState" expires_after="M110">
   <owner>sophey@chromium.org</owner>
   <owner>src/chrome/browser/share/OWNERS</owner>
   <summary>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml
index 0c7a68a..c03ece7 100644
--- a/tools/metrics/ukm/ukm.xml
+++ b/tools/metrics/ukm/ukm.xml
@@ -16688,6 +16688,15 @@
       specific to the preloading type.
     </summary>
   </metric>
+  <metric name="HoldbackStatus">
+    <summary>
+      The outcome of the holdback check. This is not part of eligibility status
+      to make clarify that this check needs to happen after we are done
+      verifying the eligibility of a preloading attempt. In general, eligibility
+      checks can be reordered, but the holdback check always needs to come after
+      verifying that the preloading attempt was eligible.
+    </summary>
+  </metric>
   <metric name="PreloadingPredictor">
     <summary>
       The type of preloading predictor which made the prediction. Values are
@@ -16742,6 +16751,15 @@
       Reason why the preloading operation failed.
     </summary>
   </metric>
+  <metric name="HoldbackStatus">
+    <summary>
+      The outcome of the holdback check. This is not part of eligibility status
+      to make clarify that this check needs to happen after we are done
+      verifying the eligibility of a preloading attempt. In general, eligibility
+      checks can be reordered, but the holdback check always needs to come after
+      verifying that the preloading attempt was eligible.
+    </summary>
+  </metric>
   <metric name="PreloadingPredictor">
     <summary>
       The type of predictor that made the prediction. Values are from either
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index 49b37d91..a8783ff 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -5,24 +5,24 @@
             "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux_arm64/49b4b5dcbc312d8d2c3751cf29238b8efeb4e494/trace_processor_shell"
         },
         "win": {
-            "hash": "869cd1975316850fa093fa3d15d24f2098188f5c",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/678b18cbe3b1730876323237279bd80b135c2046/trace_processor_shell.exe"
+            "hash": "5ed4a7273e494c6195c6b7435767d9639a258bc5",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/b9f4805cadbde30a1bc094e6c55a4084a0dc4f44/trace_processor_shell.exe"
         },
         "linux_arm": {
             "hash": "58893933be305d3bfe0a72ebebcacde2ac3ca893",
             "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux_arm/49b4b5dcbc312d8d2c3751cf29238b8efeb4e494/trace_processor_shell"
         },
         "mac": {
-            "hash": "5a0bac1af5327f347e97a7f23113f3dbd29c9f97",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/678b18cbe3b1730876323237279bd80b135c2046/trace_processor_shell"
+            "hash": "2a02892e088a5b55c04f79aad1ac20b88a6980ab",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/b9f4805cadbde30a1bc094e6c55a4084a0dc4f44/trace_processor_shell"
         },
         "mac_arm64": {
             "hash": "e1ad4861384b06d911a65f035317914b8cc975c6",
             "full_remote_path": "perfetto-luci-artifacts/v25.0/mac-arm64/trace_processor_shell"
         },
         "linux": {
-            "hash": "418a14c8312bd337ea62268025dcdba6a51011a1",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/678b18cbe3b1730876323237279bd80b135c2046/trace_processor_shell"
+            "hash": "15b4bb7e4fac0925d0d4ebb25ac4dda1ad650f49",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/b9f4805cadbde30a1bc094e6c55a4084a0dc4f44/trace_processor_shell"
         }
     },
     "power_profile.sql": {
diff --git a/ui/gl/init/create_gr_gl_interface.cc b/ui/gl/init/create_gr_gl_interface.cc
index 7ea63cf..cdf895d 100644
--- a/ui/gl/init/create_gr_gl_interface.cc
+++ b/ui/gl/init/create_gr_gl_interface.cc
@@ -325,6 +325,7 @@
   BIND(CompileShader, Slow);
   BIND(CompressedTexImage2D, Slow, NeedFlushOnMac);
   BIND(CompressedTexSubImage2D, Slow);
+  BIND(CopyBufferSubData);
   BIND(CopyTexSubImage2D, Slow);
 #if BUILDFLAG(IS_APPLE)
   functions->fCreateProgram = [func = gl->glCreateProgramFn]() {